219 lines
7.8 KiB
C
219 lines
7.8 KiB
C
/* *****************************************************************************
|
|
* libg1m/internals.h -- the libg1m internals.
|
|
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
|
*
|
|
* This file is part of libg1m.
|
|
* libg1m is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 3.0 of the License,
|
|
* or (at your option) any later version.
|
|
*
|
|
* libg1m is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
* See the GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* This is the root of the libg1m internal headers. All source files shall
|
|
* include this one to include all the headers (so they don't have to do
|
|
* it themselves).
|
|
* ************************************************************************** */
|
|
#ifndef LIBG1M_INTERNALS_H
|
|
# define LIBG1M_INTERNALS_H
|
|
# include <libg1m.h>
|
|
# include <libg1m/formatutils.h>
|
|
# include <libg1m/internals/log.h>
|
|
# include <stdlib.h>
|
|
# include <string.h>
|
|
# include <libg1m/internals/endian.h>
|
|
|
|
/* ************************************************************************** */
|
|
/* Macros and platform-specific functions */
|
|
/* ************************************************************************** */
|
|
/* MS-Windows <3 (srsly) */
|
|
# if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) \
|
|
&& !defined(__WINDOWS__)
|
|
# define __WINDOWS__
|
|
# endif
|
|
|
|
/* Macros */
|
|
# ifndef min
|
|
# define min(A, B) ((A) < (B) ? (A) : (B))
|
|
# endif
|
|
# ifndef max
|
|
# define max(A, B) ((A) > (B) ? (A) : (B))
|
|
# endif
|
|
|
|
/* Platform-specific functions */
|
|
# ifdef __WINDOWS__
|
|
# define bzero(B, LEN) ((void)memset((B), 0, (LEN)))
|
|
# endif
|
|
|
|
/* ************************************************************************** */
|
|
/* Macros and functions for parsing */
|
|
/* ************************************************************************** */
|
|
/* read from buffer */
|
|
# define READ(TO, SZ) /* normal read */ { \
|
|
int READ_err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)); \
|
|
buffer->_offset += SZ; \
|
|
if (READ_err) return (READ_err); }
|
|
# define FREAD(TO, SZ) /* fail-less read */ \
|
|
err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)); \
|
|
buffer->_offset += SZ;
|
|
# define GREAD(TO, SZ) /* read with goto fail */ { \
|
|
if ((err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)))) \
|
|
goto fail; \
|
|
buffer->_offset += SZ; }
|
|
|
|
/* read from buffer, declare var before */
|
|
# define DREAD(NAM, STRUCT) /* D read (I don't remember where D comes from) */ \
|
|
struct STRUCT NAM; \
|
|
READ(&NAM, sizeof(struct STRUCT))
|
|
# define GDREAD(NAM, STRUCT) /* D read with goto fail */ \
|
|
struct STRUCT NAM; \
|
|
GREAD(&NAM, sizeof(struct STRUCT))
|
|
|
|
/* read from buffer, declare tab before */
|
|
# define TREAD(NAM, TYPE, NUM) /* Tableau (list) read */ \
|
|
TYPE NAM[NUM]; \
|
|
READ(NAM, sizeof(TYPE))
|
|
|
|
/* skip */
|
|
# define SKIP(SZ) { \
|
|
int SKIP_err = g1m_skip(buffer, SZ, NULL); \
|
|
if (SKIP_err) return (SKIP_err); \
|
|
}
|
|
|
|
/* ************************************************************************** */
|
|
/* Memory buffer-related */
|
|
/* ************************************************************************** */
|
|
/* Structure */
|
|
typedef struct {
|
|
const unsigned char *p;
|
|
size_t left;
|
|
} g1m_cursor_t;
|
|
|
|
/* Callbacks */
|
|
int g1m_membuffer_read(void *cookie, unsigned char *dest, size_t size);
|
|
|
|
/* Management functions */
|
|
int g1m_empty_limbuffer(g1m_buffer_t *limbuffer);
|
|
|
|
/* Initialize a memory buffer */
|
|
# define MEMBUFFER(P, SZ) (g1m_buffer_t){ \
|
|
.cookie = (g1m_cursor_t[]){{.p = (P), .left = (SZ)}}, \
|
|
.read = g1m_membuffer_read}
|
|
|
|
/* ************************************************************************** */
|
|
/* Limited buffer */
|
|
/* ************************************************************************** */
|
|
/* Structure */
|
|
typedef struct {
|
|
g1m_buffer_t *buffer;
|
|
size_t left;
|
|
} g1m_limited_t;
|
|
|
|
/* Callbacks */
|
|
int g1m_limbuffer_read(void *cookie, unsigned char *dest, size_t size);
|
|
|
|
/* Initialize a limited buffer */
|
|
# define LIMBUFFER(BUFFER, SZ) (g1m_buffer_t){ \
|
|
.cookie = (g1m_limited_t[]){{.buffer = (BUFFER), .left = (SZ)}}, \
|
|
.read = g1m_limbuffer_read}
|
|
|
|
/* ************************************************************************** */
|
|
/* Decoding functions */
|
|
/* ************************************************************************** */
|
|
int g1m_decode_std(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
|
|
struct standard_header*, g1m_type_t expected_types);
|
|
int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
|
|
g1m_type_t expected_types);
|
|
|
|
/* ************************************************************************** */
|
|
/* "Std"-specific decoding functions */
|
|
/* ************************************************************************** */
|
|
# define G1M_STDFUNC(NAME) \
|
|
int g1m_decode_std_##NAME(g1m_t *handle, g1m_buffer_t *buffer, \
|
|
struct standard_header *std);
|
|
|
|
G1M_STDFUNC(g3p)
|
|
G1M_STDFUNC(c2p)
|
|
G1M_STDFUNC(mcs)
|
|
G1M_STDFUNC(eact)
|
|
G1M_STDFUNC(addin)
|
|
G1M_STDFUNC(addin_cg)
|
|
G1M_STDFUNC(lang)
|
|
G1M_STDFUNC(lang_cg)
|
|
G1M_STDFUNC(fkey)
|
|
G1M_STDFUNC(storage)
|
|
|
|
/* others */
|
|
int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer,
|
|
uint_fast32_t zonesize, uint32_t *pchecksum);
|
|
|
|
/* ************************************************************************** */
|
|
/* MCS-specific decoding functions */
|
|
/* ************************************************************************** */
|
|
# define G1M_MCSFUNC(NAME) \
|
|
int g1m_decode_mcs_##NAME(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, \
|
|
uint_fast32_t length);
|
|
|
|
G1M_MCSFUNC(alphamem)
|
|
G1M_MCSFUNC(list)
|
|
G1M_MCSFUNC(matrix)
|
|
G1M_MCSFUNC(picture)
|
|
G1M_MCSFUNC(capture)
|
|
G1M_MCSFUNC(program)
|
|
G1M_MCSFUNC(setup)
|
|
G1M_MCSFUNC(spreadsheet)
|
|
G1M_MCSFUNC(string)
|
|
|
|
/* ************************************************************************** */
|
|
/* Picture utilities */
|
|
/* ************************************************************************** */
|
|
# define alloc_pixels(W, H) \
|
|
malloc(sizeof(uint32_t*) * (H) + sizeof(uint32_t) * (W) * (H))
|
|
# define prepare_pixels(I, W, H) { \
|
|
uint32_t *PIXPREP_line = (uint32_t*)&(I)[(H)]; \
|
|
for (int PIXPREP_y = 0; PIXPREP_y < (H); PIXPREP_y++) { \
|
|
(I)[PIXPREP_y] = PIXPREP_line; \
|
|
PIXPREP_line += (W); \
|
|
}}
|
|
|
|
/* just wanted to do this macro for fun. */
|
|
# define G1M_PROTOTYPE_PIX(NATURE) \
|
|
void g1m_pixels_from_##NATURE(uint32_t **pixels, unsigned char *raw, \
|
|
int width, int height); \
|
|
void g1m_pixels_to_##NATURE(unsigned char *dest, uint32_t **pixels, \
|
|
int width, int height);
|
|
|
|
G1M_PROTOTYPE_PIX(packed1bit)
|
|
G1M_PROTOTYPE_PIX(packed4bits)
|
|
G1M_PROTOTYPE_PIX(16bits)
|
|
|
|
/* ************************************************************************** */
|
|
/* Utilities */
|
|
/* ************************************************************************** */
|
|
/* Making */
|
|
int g1m_make_mcs(g1m_t **h);
|
|
|
|
/* Free-ing */
|
|
void g1m_free_content(g1m_t *handle);
|
|
void g1m_free_mcsfile_content(g1m_mcsfile_t *handle);
|
|
void g1m_free_mcs(g1m_t *handle);
|
|
void g1m_free_line_content(g1m_line_t *line);
|
|
|
|
/* Skipping */
|
|
int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum);
|
|
|
|
/* Checksum-ing */
|
|
uint8_t g1m_checksum8(void *mem, size_t size);
|
|
uint32_t g1m_checksum32(void *mem, size_t size, uint32_t checksum);
|
|
|
|
/* File buffer */
|
|
int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size);
|
|
|
|
#endif /* LIBG1M_INTERNALS_H */
|