Namespace, started correcting CAS set managing
This commit is contained in:
parent
1785ab6697
commit
264e8d5f66
|
@ -92,7 +92,7 @@ endif
|
|||
# - Specific linker flags
|
||||
LDFLAGS_Windows := -lws2_32 -Wl,--out-implib,lib$(NAME).dll.a
|
||||
LDFLAGS_Linux := $(if $(STATIC),,-Wl,-soname,$(SONAME) \
|
||||
-e __lib$(NAME)_version \
|
||||
-e $(NAME)__version \
|
||||
-Wl,-z,relro -Wl,-z,combreloc -Wl,-z,defs)
|
||||
# - Linker flags
|
||||
LDFLAGS := $(if $(STATIC),,-shared) \
|
||||
|
|
126
include/libg1m.h
126
include/libg1m.h
|
@ -80,112 +80,118 @@ extern const char *g1m_error_strings[];
|
|||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
/* open and free a handle */
|
||||
extern int g1m_decode(g1m_handle_t **handle, const char *path,
|
||||
g1m_buffer_t *buffer, g1m_type_t allowed_types);
|
||||
extern void g1m_free(g1m_handle_t *handle);
|
||||
extern int g1m_decode(g1m_handle_t **g1m_arg_handle, const char *g1m_arg_path,
|
||||
g1m_buffer_t *g1m_arg_buffer, g1m_type_t g1m_arg_allowed_types);
|
||||
extern void g1m_free(g1m_handle_t *g1m_arg_handle);
|
||||
|
||||
/* open a handle using FILEs */
|
||||
#ifndef G1M_DISABLED_FILE
|
||||
extern int g1m_open(g1m_handle_t **handle, const char *path,
|
||||
g1m_type_t allowed_types);
|
||||
extern int g1m_fopen(g1m_handle_t **handle, const char *path, FILE *stream,
|
||||
g1m_type_t allowed_types);
|
||||
extern int g1m_open(g1m_handle_t **g1m_arg_handle, const char *g1m_arg_path,
|
||||
g1m_type_t g1m_arg_allowed_types);
|
||||
extern int g1m_fopen(g1m_handle_t **g1m_arg_handle, const char *g1m_arg_path,
|
||||
FILE *g1m_arg_stream, g1m_type_t g1m_arg_allowed_types);
|
||||
#endif
|
||||
|
||||
/* Make a handle */
|
||||
extern int g1m_make_mcs(g1m_handle_t **handle, int count);
|
||||
extern int g1m_make_fkey(g1m_handle_t **handle, g1m_platform_t platform,
|
||||
int count);
|
||||
extern int g1m_make_lang(g1m_handle_t **handle, g1m_platform_t platform,
|
||||
int count);
|
||||
extern int g1m_make_picture(g1m_handle_t **handle,
|
||||
unsigned int width, unsigned int height);
|
||||
extern int g1m_make_addin(g1m_handle_t **h, g1m_platform_t platform,
|
||||
size_t size, const char *name, const char *internal_name,
|
||||
const g1m_version_t *version, const time_t *created);
|
||||
extern int g1m_make_mcs(g1m_handle_t **g1m_arg_handle, int g1m_arg_count);
|
||||
extern int g1m_make_fkey(g1m_handle_t **g1m_arg_handle,
|
||||
g1m_platform_t g1m_arg_platform, int g1m_arg_count);
|
||||
extern int g1m_make_lang(g1m_handle_t **g1m_arg_handle,
|
||||
g1m_platform_t g1m_arg_platform, int g1m_arg_count);
|
||||
extern int g1m_make_picture(g1m_handle_t **g1m_arg_handle,
|
||||
unsigned int g1m_arg_width, unsigned int g1m_arg_height);
|
||||
extern int g1m_make_addin(g1m_handle_t **g1m_arg_handle,
|
||||
g1m_platform_t g1m_arg_platform, size_t g1m_arg_size,
|
||||
const char *g1m_arg_name, const char *g1m_arg_internal_name,
|
||||
const g1m_version_t *g1m_arg_version, const time_t *g1m_arg_created);
|
||||
|
||||
/* encode a handle, get the extension */
|
||||
extern int g1m_encode(g1m_handle_t *handle, g1m_buffer_t *buffer);
|
||||
extern int g1m_encode(g1m_handle_t *g1m_arg_handle,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
|
||||
/* put into a FILE */
|
||||
#ifndef G1M_DISABLED_FILE
|
||||
extern int g1m_write(g1m_handle_t *handle, const char *path);
|
||||
extern int g1m_fwrite(g1m_handle_t *handle, FILE *stream);
|
||||
extern int g1m_write(g1m_handle_t *g1m_arg_handle, const char *g1m_arg_path);
|
||||
extern int g1m_fwrite(g1m_handle_t *g1m_arg_handle, FILE *g1m_arg_stream);
|
||||
#endif
|
||||
/* ************************************************************************** */
|
||||
/* Main MCS functions */
|
||||
/* ************************************************************************** */
|
||||
/* make an MCS file out of a head */
|
||||
extern int g1m_make_mcsfile(g1m_mcsfile_t **handle,
|
||||
const g1m_mcshead_t *rawhead);
|
||||
extern int g1m_prepare_mcsfile_heads(g1m_mcshead_t *head,
|
||||
g1m_mcshead_t *heads);
|
||||
extern void g1m_free_mcsfile(g1m_mcsfile_t *handle);
|
||||
extern int g1m_make_mcsfile(g1m_mcsfile_t **g1m_arg_handle,
|
||||
const g1m_mcshead_t *g1m_arg_rawhead);
|
||||
extern void g1m_free_mcsfile(g1m_mcsfile_t *g1m_arg_handle);
|
||||
|
||||
/* open MCS head for decoding, correct it for encoding */
|
||||
extern int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
|
||||
int raw_type, const unsigned char *groupname,
|
||||
const unsigned char *dirname, const unsigned char *filename,
|
||||
uint_fast32_t filesize);
|
||||
int g1m_correct_mcsfile_head(g1m_mcshead_t *head);
|
||||
extern int g1m_decode_mcsfile_head(g1m_mcshead_t *g1m_arg_head,
|
||||
int g1m_arg_raw, const unsigned char *g1m_arg_group,
|
||||
const unsigned char *g1m_arg_dirname, const unsigned char *g1m_arg_filename,
|
||||
uint_fast32_t g1m_arg_filesize);
|
||||
int g1m_correct_mcsfile_head(g1m_mcshead_t *g1m_arg_head);
|
||||
|
||||
/* open and decode MCS file */
|
||||
extern int g1m_decode_mcsfile(g1m_mcsfile_t **handle,
|
||||
const g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
extern int g1m_decode_mcsfile_data(g1m_mcsfile_t **handle,
|
||||
const g1m_mcshead_t *head, const unsigned char *data, size_t size);
|
||||
extern int g1m_decode_mcsfile(g1m_mcsfile_t **g1m_arg_handle,
|
||||
const g1m_mcshead_t *g1m_arg_head, g1m_buffer_t *g1m_arg_buffer);
|
||||
extern int g1m_decode_mcsfile_data(g1m_mcsfile_t **g1m_arg_handle,
|
||||
const g1m_mcshead_t *g1m_arg_head, const unsigned char *g1m_arg_data,
|
||||
size_t g1m_arg_size);
|
||||
|
||||
/* encode an MCS file */
|
||||
extern int g1m_encode_mcsfile(g1m_mcsfile_t *handle, g1m_buffer_t *buffer);
|
||||
extern int g1m_encode_mcsfile(g1m_mcsfile_t *g1m_arg_handle,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
# define g1m_announce_mcsfile(handle, size) \
|
||||
(g1m_encode_mcsfile(handle, (g1m_buffer_t[]){{ \
|
||||
.cookie = (size_t*)size, .announce = g1m_announce_callback }}))
|
||||
|
||||
/* open CAS head for decoding, correct it for encoding */
|
||||
extern int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
extern int g1m_decode_casfiles_part(g1m_mcshead_t *head, g1m_mcshead_t *heads,
|
||||
g1m_buffer_t *buffer);
|
||||
extern int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer);
|
||||
extern int g1m_correct_casfile_head(g1m_mcshead_t *head);
|
||||
extern int g1m_decode_casfile_head(g1m_mcshead_t *g1m_arg_head,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
extern int g1m_decode_casfile_part(g1m_mcsfile_t *g1m_arg_file,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
extern int g1m_correct_casfile_head(g1m_mcshead_t *g1m_arg_head);
|
||||
|
||||
/* announce, encode a CAS head */
|
||||
extern int g1m_encode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
extern int g1m_encode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer);
|
||||
extern int g1m_encode_casfile_head(g1m_mcshead_t *g1m_arg_head,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
extern int g1m_encode_casfile_part(g1m_mcsfile_t *g1m_arg_file,
|
||||
g1m_buffer_t *g1m_arg_buffer);
|
||||
/* ************************************************************************** */
|
||||
/* MCS archive management */
|
||||
/* ************************************************************************** */
|
||||
/* create and insert an MCS file into a MCS archive */
|
||||
extern int g1m_mcs_insert(g1m_handle_t *handle, g1m_mcsfile_t **tofile,
|
||||
const g1m_mcshead_t *head);
|
||||
extern int g1m_mcs_insert(g1m_handle_t *g1m_arg_handle,
|
||||
g1m_mcsfile_t **g1m_arg_tofile, const g1m_mcshead_t *g1m_arg_head);
|
||||
|
||||
/* sort an MCS archive for encoding,
|
||||
* compare two MCS files (utility function used by the first) */
|
||||
extern int g1m_mcs_sort(g1m_handle_t *handle);
|
||||
extern int g1m_compare_mcsfiles(const g1m_mcsfile_t *first_file,
|
||||
const g1m_mcsfile_t *second_file);
|
||||
extern int g1m_mcs_sort(g1m_handle_t *g1m_arg_handle);
|
||||
extern int g1m_compare_mcsfiles(const g1m_mcsfile_t *g1m_arg_first_file,
|
||||
const g1m_mcsfile_t *g1m_arg_second_file);
|
||||
/* ************************************************************************** */
|
||||
/* Miscallaneous utilities */
|
||||
/* ************************************************************************** */
|
||||
/* Picture decoding/encoding */
|
||||
extern int g1m_decode_picture(uint32_t **pixels,
|
||||
g1m_pictureformat_t format, const unsigned char *raw,
|
||||
unsigned int width, unsigned int height);
|
||||
extern int g1m_encode_picture(const uint32_t **pixels,
|
||||
g1m_pictureformat_t format, unsigned char *raw,
|
||||
unsigned int width, unsigned int height);
|
||||
extern int g1m_decode_picture(uint32_t **g1m_arg_pixels,
|
||||
g1m_pictureformat_t g1m_arg_format, const unsigned char *g1m_arg_raw,
|
||||
unsigned int g1m_arg_width, unsigned int g1m_arg_height);
|
||||
extern int g1m_encode_picture(const uint32_t **g1m_arg_pixels,
|
||||
g1m_pictureformat_t g1m_arg_format, unsigned char *g1m_arg_raw,
|
||||
unsigned int g1m_arg_width, unsigned int g1m_arg_height);
|
||||
|
||||
/* Version decoding/encoding */
|
||||
extern int g1m_check_version(const char *raw);
|
||||
extern int g1m_decode_version(const char *raw, g1m_version_t *version);
|
||||
extern int g1m_encode_version(const g1m_version_t *version, char *raw);
|
||||
extern int g1m_check_version(const char *g1m_arg_raw);
|
||||
extern int g1m_decode_version(const char *g1m_arg_raw,
|
||||
g1m_version_t *g1m_arg_version);
|
||||
extern int g1m_encode_version(const g1m_version_t *g1m_arg_version,
|
||||
char *g1m_arg_raw);
|
||||
|
||||
/* Date decoding/encoding */
|
||||
extern int g1m_check_date(const char *raw);
|
||||
extern int g1m_decode_date(const char *raw, time_t *date);
|
||||
extern int g1m_encode_date(const time_t *date, char *raw);
|
||||
extern int g1m_check_date(const char *g1m_arg_raw);
|
||||
extern int g1m_decode_date(const char *g1m_arg_raw, time_t *g1m_arg_date);
|
||||
extern int g1m_encode_date(const time_t *g1m_arg_date, char *g1m_arg_raw);
|
||||
|
||||
/* Announce callback that just contributes to a size_t. */
|
||||
extern int g1m_announce_callback(void *cookie, size_t size);
|
||||
extern int g1m_announce_callback(void *g1m_arg_cookie, size_t g1m_arg_size);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -60,18 +60,18 @@ extern "C" {
|
|||
# define g1m_bcdflag_neg 0x40
|
||||
# define g1m_bcdmask_pre 0x3F
|
||||
|
||||
# define g1m_bcd_has_special(B) ((B)->flags & g1m_bcdflag_spe)
|
||||
# define g1m_bcd_is_negative(B) ((B)->flags & g1m_bcdflag_neg)
|
||||
# define g1m_bcd_precision(B) ((B)->flags & g1m_bcdmask_pre)
|
||||
# define g1m_bcd_exponent(B) ((B)->exp)
|
||||
# define g1m_bcd_has_special(B) ((B)->g1m_bcd_flags & g1m_bcdflag_spe)
|
||||
# define g1m_bcd_is_negative(B) ((B)->g1m_bcd_flags & g1m_bcdflag_neg)
|
||||
# define g1m_bcd_precision(B) ((B)->g1m_bcd_flags & g1m_bcdmask_pre)
|
||||
# define g1m_bcd_exponent(B) ((B)->g1m_bcd_exp)
|
||||
# define g1m_make_bcdflags(SPE, NEG, PREC) \
|
||||
(((SPE) << 7) | ((NEG) << 6) | (PREC))
|
||||
|
||||
typedef struct g1m_bcd_s {
|
||||
unsigned char flags; char exp;
|
||||
char mant[G1M_BCD_MANTISSA_SIZE];
|
||||
unsigned char g1m_bcd_flags;
|
||||
char g1m_bcd_exp;
|
||||
char g1m_bcd_mant[G1M_BCD_MANTISSA_SIZE];
|
||||
} g1m_bcd_t;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Raw formats */
|
||||
/* ************************************************************************** */
|
||||
|
@ -85,14 +85,14 @@ typedef struct g1m_bcd_s {
|
|||
* The negative is two bits/flags (I don't know why).
|
||||
* `g1m_casbcd_pow_neg`, if there, means the power is negative. */
|
||||
|
||||
# define g1m_casbcd_special 0x80
|
||||
# define g1m_casbcd_negative 0x50
|
||||
# define g1m_casbcd_pow_neg 0x01
|
||||
typedef struct cas_bcd {
|
||||
unsigned char mantissa[8];
|
||||
unsigned char signinfo;
|
||||
unsigned char exponent;
|
||||
} cas_bcd_t;
|
||||
# define g1m_casbcdflag_special 0x80
|
||||
# define g1m_casbcdflag_negative 0x50
|
||||
# define g1m_casbcdflag_pow_neg 0x01
|
||||
typedef struct g1m_casbcd_s {
|
||||
unsigned char g1m_casbcd_mant[8];
|
||||
unsigned char g1m_casbcd_flags;
|
||||
unsigned char g1m_casbcd_exp;
|
||||
} g1m_casbcd_t;
|
||||
|
||||
/* MCS BCD -- the most recent BCD format.
|
||||
* Only the first 9 bytes are significant.
|
||||
|
@ -106,27 +106,28 @@ typedef struct cas_bcd {
|
|||
* The other values (from the fourth nibble) are the packed BCD mantissa.
|
||||
* It starts at 10^0. */
|
||||
|
||||
typedef struct bcd {
|
||||
unsigned char BCDval[9];
|
||||
unsigned char _align[3];
|
||||
} mcs_bcd_t;
|
||||
typedef struct g1m_mcsbcd_s {
|
||||
unsigned char g1m_mcsbcd_BCDval[9];
|
||||
unsigned char g1m_mcsbcd__align[3];
|
||||
} g1m_mcsbcd_t;
|
||||
/* ************************************************************************** */
|
||||
/* Conversion utilities */
|
||||
/* ************************************************************************** */
|
||||
/* From and to MCS BCD. */
|
||||
int g1m_bcd_frommcs(const mcs_bcd_t *raw, g1m_bcd_t *bcd);
|
||||
void g1m_bcd_tomcs(const g1m_bcd_t *bcd, mcs_bcd_t *raw);
|
||||
int g1m_bcd_frommcs(const g1m_mcsbcd_t *g1m_arg_raw, g1m_bcd_t *g1m_arg_bcd);
|
||||
void g1m_bcd_tomcs(const g1m_bcd_t *g1m_arg_bcd, g1m_mcsbcd_t *g1m_arg_raw);
|
||||
|
||||
/* From and to CAS BCD. */
|
||||
int g1m_bcd_fromcas(const cas_bcd_t *raw, g1m_bcd_t *bcd);
|
||||
void g1m_bcd_tocas(const g1m_bcd_t *bcd, cas_bcd_t *raw);
|
||||
int g1m_bcd_fromcas(const g1m_casbcd_t *g1m_arg_raw, g1m_bcd_t *g1m_arg_bcd);
|
||||
void g1m_bcd_tocas(const g1m_bcd_t *g1m_arg_bcd, g1m_casbcd_t *g1m_arg_raw);
|
||||
|
||||
/* From and to C-double */
|
||||
void g1m_bcd_fromdouble(double dbl, g1m_bcd_t *bcd);
|
||||
double g1m_bcd_todouble(const g1m_bcd_t *bcd);
|
||||
void g1m_bcd_fromdouble(double g1m_arg_dbl, g1m_bcd_t *g1m_arg_bcd);
|
||||
double g1m_bcd_todouble(const g1m_bcd_t *g1m_arg_bcd);
|
||||
|
||||
/* Make a string out of a BCD */
|
||||
size_t g1m_bcdtoa(const g1m_bcd_t *bcd, char *buf, size_t len);
|
||||
size_t g1m_bcdtoa(const g1m_bcd_t *g1m_arg_bcd, char *g1m_arg_buf,
|
||||
size_t g1m_arg_len);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -17,7 +17,17 @@
|
|||
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This interface is there so you can use a custom buffer for the library
|
||||
* to read. There are two use cases:
|
||||
* to read.
|
||||
* ************************************************************************** */
|
||||
#ifndef LIBG1M_BUFFER_H
|
||||
# define LIBG1M_BUFFER_H
|
||||
# include <stdlib.h>
|
||||
# include <stdint.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* General definition */
|
||||
/* ************************************************************************** */
|
||||
/* There are two use cases:
|
||||
* - you want to read data: the `size` of the element to read should be set,
|
||||
* and the `read` callback will be used;
|
||||
* - you want to receive data: if the `announce` callback is set, it will be
|
||||
|
@ -28,77 +38,77 @@
|
|||
* will be called in order to free any allocated buffer.
|
||||
*
|
||||
* In each case, the `cookie` is sent as the first argument to your callbacks.
|
||||
* ************************************************************************** */
|
||||
#ifndef LIBG1M_BUFFER_H
|
||||
# define LIBG1M_BUFFER_H
|
||||
# include <stdlib.h>
|
||||
# include <stdint.h>
|
||||
* Here are their types: */
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* General definition */
|
||||
/* ************************************************************************** */
|
||||
/* The callbacks types... */
|
||||
typedef int (*g1m_buffer_read_t)(void*, unsigned char*, size_t);
|
||||
typedef int (*g1m_buffer_write_t)(void*, const unsigned char*, size_t);
|
||||
typedef int (*g1m_buffer_announce_t)(void*, size_t);
|
||||
typedef void (*g1m_buffer_unannounce_t)(void*);
|
||||
|
||||
/* ... and the structure of a buffer. */
|
||||
typedef struct {
|
||||
void *cookie;
|
||||
size_t _offset;
|
||||
/* ... and the structure of a buffer: */
|
||||
|
||||
g1m_buffer_read_t read;
|
||||
g1m_buffer_write_t write;
|
||||
g1m_buffer_announce_t announce;
|
||||
g1m_buffer_unannounce_t unannounce;
|
||||
typedef struct {
|
||||
void *g1m_buffer_cookie;
|
||||
size_t g1m_buffer_offset;
|
||||
|
||||
/* callbacks */
|
||||
g1m_buffer_read_t g1m_buffer_read;
|
||||
g1m_buffer_write_t g1m_buffer_write;
|
||||
g1m_buffer_announce_t g1m_buffer_announce;
|
||||
g1m_buffer_unannounce_t g1m_buffer_unannounce;
|
||||
} g1m_buffer_t;
|
||||
/* ************************************************************************** */
|
||||
/* File buffer definition */
|
||||
/* ************************************************************************** */
|
||||
/* Callbacks (the cookie is the FILE* pointer) */
|
||||
extern int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size);
|
||||
extern int g1m_filebuffer_write(void *cookie, const unsigned char *dest,
|
||||
size_t size);
|
||||
extern int g1m_filebuffer_read(void *g1m_arg_cookie,
|
||||
unsigned char *g1m_arg_buf, size_t g1m_arg_size);
|
||||
extern int g1m_filebuffer_write(void *g1m_arg_cookie,
|
||||
const unsigned char *g1m_arg_dest, size_t g1m_arg_size);
|
||||
/* ************************************************************************** */
|
||||
/* Memory buffer definition */
|
||||
/* ************************************************************************** */
|
||||
/* Cookie structure */
|
||||
typedef struct {
|
||||
const unsigned char *p;
|
||||
size_t left;
|
||||
typedef struct g1m_cursor_s {
|
||||
const unsigned char *g1m_cursor_p;
|
||||
size_t g1m_cursor_left;
|
||||
} g1m_cursor_t;
|
||||
|
||||
/* Related callbacks and functions */
|
||||
extern int g1m_membuffer_read(void *cookie, unsigned char *dest, size_t size);
|
||||
extern int g1m_membuffer_read(void *g1m_arg_cookie,
|
||||
unsigned char *g1m_arg_dest, size_t g1m_arg_size);
|
||||
/* ************************************************************************** */
|
||||
/* Limited buffer definition */
|
||||
/* ************************************************************************** */
|
||||
/* Cookie structure */
|
||||
typedef struct {
|
||||
g1m_buffer_t *buffer;
|
||||
size_t left;
|
||||
typedef struct g1m_limited_s {
|
||||
g1m_buffer_t *g1m_limited_buffer;
|
||||
size_t g1m_limited_left;
|
||||
} g1m_limited_t;
|
||||
|
||||
/* Related functions and callbacks */
|
||||
int g1m_limbuffer_read(void *cookie, unsigned char *dest, size_t size);
|
||||
int g1m_empty_limbuffer(g1m_buffer_t *limbuffer);
|
||||
int g1m_limbuffer_read(void *g1m_arg_cookie,
|
||||
unsigned char *g1m_arg_dest, size_t g1m_arg_size);
|
||||
int g1m_empty_limbuffer(g1m_buffer_t *g1m_arg_limbuffer);
|
||||
/* ************************************************************************** */
|
||||
/* Buffer macros */
|
||||
/* ************************************************************************** */
|
||||
/* Initialize a file buffer */
|
||||
# define g1m_filebuffer(F) (g1m_filebuffer_t){ \
|
||||
.cookie = (void*)(F), .read = g1m_filebuffer_read, \
|
||||
.write = g1m_filebuffer_write}
|
||||
.g1m_buffer_cookie = (void*)(F), \
|
||||
.g1m_buffer_read = g1m_filebuffer_read, \
|
||||
.g1m_buffer_write = g1m_filebuffer_write}
|
||||
|
||||
/* Initialize a memory buffer */
|
||||
# define g1m_membuffer(P, SZ) (g1m_buffer_t){ \
|
||||
.cookie = (g1m_cursor_t[]){{.p = (P), .left = (SZ)}}, \
|
||||
.read = g1m_membuffer_read}
|
||||
.g1m_buffer_cookie = (g1m_cursor_t[]){{ \
|
||||
.g1m_cursor_p = (P), .g1m_cursor_left = (SZ)}}, \
|
||||
.g1m_buffer_read = g1m_membuffer_read}
|
||||
|
||||
/* Initialize a limited buffer */
|
||||
# define g1m_limbuffer(BUFFER, SZ) (g1m_buffer_t){ \
|
||||
.cookie = (g1m_limited_t[]){{.buffer = (BUFFER), .left = (SZ)}}, \
|
||||
.read = g1m_limbuffer_read}
|
||||
.g1m_buffer_cookie = (g1m_limited_t[]){{ \
|
||||
.g1m_limited_buffer = (BUFFER), .g1m_limited_left = (SZ)}}, \
|
||||
.g1m_buffer_read = g1m_limbuffer_read}
|
||||
|
||||
#endif /* LIBG1M_BUFFER_H */
|
||||
|
|
|
@ -37,18 +37,18 @@ typedef unsigned int g1m_eact_line_type_t;
|
|||
/* E-activities line structure */
|
||||
/* ************************************************************************** */
|
||||
typedef struct g1m_line_s {
|
||||
int type;
|
||||
|
||||
/* for subcontents */
|
||||
char name[17];
|
||||
int g1m_line_type;
|
||||
|
||||
/* content */
|
||||
char *content;
|
||||
char *g1m_line_content;
|
||||
|
||||
/* subcontents */
|
||||
int count;
|
||||
int _size;
|
||||
struct g1m_line_s **lines;
|
||||
int g1m_line_count;
|
||||
int g1m_line__size;
|
||||
struct g1m_line_s **g1m_line_lines;
|
||||
|
||||
/* for subcontents */
|
||||
char g1m_line_name[17];
|
||||
} g1m_line_t;
|
||||
|
||||
#endif /* LIBG1M_EACT_H */
|
||||
|
|
|
@ -30,18 +30,17 @@
|
|||
typedef unsigned int g1m_filetype_t;
|
||||
# define g1m_filetype_directory 0x01
|
||||
# define g1m_filetype_generic 0x02
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Storage file structure */
|
||||
/* ************************************************************************** */
|
||||
typedef struct g1m_file_s {
|
||||
/* meta info */
|
||||
unsigned int type;
|
||||
struct g1m_file_s *parent;
|
||||
int deleted;
|
||||
unsigned int g1m_file_type;
|
||||
struct g1m_file_s *g1m_file_parent;
|
||||
int g1m_file_deleted;
|
||||
|
||||
/* content */
|
||||
void *content;
|
||||
void *g1m_file_content;
|
||||
} g1m_file_t;
|
||||
|
||||
#endif /* LIBG1M_FILE_H */
|
||||
|
|
|
@ -39,6 +39,18 @@
|
|||
|
||||
# include <libg1m/format/cas.h>
|
||||
/* ************************************************************************** */
|
||||
/* The GraphCard (GRC) format */
|
||||
/* ************************************************************************** */
|
||||
/* The GraphCard is an external micro SD card reader for CASIO calculators,
|
||||
* made by Util Pocket (not sold anymore).
|
||||
*
|
||||
* It uses its own format, built above the CAS format/protocol.
|
||||
* Basically, before headers/parts (colons included), it inserts a 16-bit
|
||||
* size of the header/part which is following, and a zero 16-bit size in
|
||||
* the end.
|
||||
*
|
||||
* See the description of the CAS format above. */
|
||||
/* ************************************************************************** */
|
||||
/* The FXI format */
|
||||
/* ************************************************************************** */
|
||||
/* fx-Interface, an old but well done proprietary interface by CASIO, has its
|
||||
|
@ -58,7 +70,7 @@
|
|||
/* The Casemul format */
|
||||
/* ************************************************************************** */
|
||||
/* Casemul is a CASIO emulator for Microsoft Windows. It is an old software
|
||||
* which was not updated since 2005. It can import and export other files,
|
||||
* that has not been updated since 2005. It can import and export other files,
|
||||
* but save its files in its own format, which use the .cas extension
|
||||
* (like the CASIOLINK format, but the two formats are completely different).
|
||||
*
|
||||
|
@ -86,9 +98,11 @@
|
|||
/* Since around 2004/2005, CASIO has adopted a single "superformat"; we call it
|
||||
* CASIO's standard format, or the G1M format (it doesn't really have a
|
||||
* *public* name, other than its magics, like 'USBPower' or 'CASIO').
|
||||
* Basically, G1M, G2R, G1A, G3A, G3P, C2P, C1A, and others, are formats
|
||||
* defined under the standard format.
|
||||
*
|
||||
* It doesn't have a single magic string, but a few. But the standard header
|
||||
* has the same format, so we consider it as the same format. */
|
||||
* It doesn't have one single magic string, but a few, although the standard
|
||||
* header has the same format, so we consider it as the same format. */
|
||||
|
||||
# include <libg1m/format/std.h>
|
||||
#endif /* LIBG1M_FORMAT_H */
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
* the double-colon ':' (0x3A) -- then it is the beginning of something
|
||||
* that is more than one-byte long. CAS files do not include the one-byte
|
||||
* packets, or repeated headers/parts (because of bad checksum or timeouts,
|
||||
* for example).
|
||||
* for example) -- see the libp7 legacy protocol documentation for this.
|
||||
*
|
||||
* Actually, there are three main things that start with a ':'. The main type
|
||||
* is a header, that describes the content that follows. A content can have
|
||||
* no content part (e.g. END packet), one content part (e.g. programs), or
|
||||
* no data part (e.g. END packet), one data part (e.g. programs), or
|
||||
* more (e.g. width*height content parts for lists and matrixes, which
|
||||
* represent the individual cells). These content parts have different formats
|
||||
* according to the global content part.
|
||||
|
@ -115,11 +115,12 @@ struct _cas50 {
|
|||
uint8_t name[8];
|
||||
|
||||
/* variable-related data */
|
||||
uint8_t prefix[8]; /* "Variable" for vars, 0xFFs otherwise */
|
||||
uint8_t prefix[8]; /* "Variable" for vars, "PROG\x99" "0\xFF\xFF" for progs,
|
||||
* 0xFFs otherwise */
|
||||
uint8_t aux[8]; /* variable: "R\x0A"/"C\x0A", editor: password */
|
||||
|
||||
/* something else (?) */
|
||||
uint8_t nl[2]; /* 'NL'? */
|
||||
uint8_t nl[2]; /* 'NL'? "\xFF\xFF" for progs */
|
||||
uint8_t _reserved[12];
|
||||
|
||||
/* end of packet */
|
||||
|
|
|
@ -97,7 +97,7 @@ struct standard_subheader {
|
|||
uint32_t checksum;
|
||||
|
||||
/* file type:
|
||||
* - 0x00: picture;
|
||||
* - 0x00: picture (not used with this header);
|
||||
* - 0x01: add-in;
|
||||
* - 0x02: function keys;
|
||||
* - 0x04: language files; */
|
||||
|
|
|
@ -50,44 +50,68 @@ typedef unsigned int g1m_platform_t;
|
|||
# define g1m_platform_cas 0x0008
|
||||
# define g1m_platform_casemul 0x0010
|
||||
/* ************************************************************************** */
|
||||
/* Helpers */
|
||||
/* Version */
|
||||
/* ************************************************************************** */
|
||||
/* Zone (localization) */
|
||||
# define g1m_versionzone_none 0x00 /* (international) */
|
||||
# define g1m_versionzone_aus 0x01 /* Australia */
|
||||
# define g1m_versionzone_fr 0x02 /* France */
|
||||
# define g1m_versionzone_nam 0x03 /* North america */
|
||||
# define g1m_versionzone_ch 0x04 /* China */
|
||||
# define g1m_versionzone_sing 0x05 /* Singapour */
|
||||
|
||||
/* Math input/output features */
|
||||
# define g1m_versionmath_slim 0x01 /* Slim */
|
||||
# define g1m_versionmath_all 0x02 /* All features (e.g. fx-9860GII-2) */
|
||||
# define g1m_versionmath_reduced 0x03 /* Reduced features (fx-7400GII) */
|
||||
# define g1m_versionmath_none 0x07 /* No math features? */
|
||||
|
||||
/* Flags */
|
||||
# define g1m_versionflag_indev 0x01 /* is an in-development/special version */
|
||||
# define g1m_versionflag_spe 0x02 /* special OS builds (SH-4A) */
|
||||
|
||||
/* Version */
|
||||
typedef struct g1m_version_s {
|
||||
int major, minor, revision;
|
||||
int g1m_version_major;
|
||||
int g1m_version_minor;
|
||||
unsigned char g1m_version_zone;
|
||||
unsigned char g1m_version_math;
|
||||
unsigned char g1m_version_flags;
|
||||
} g1m_version_t;
|
||||
/* ************************************************************************** */
|
||||
/* Handle structure */
|
||||
/* ************************************************************************** */
|
||||
typedef struct {
|
||||
/* file type, the source destination platform */
|
||||
g1m_type_t type;
|
||||
g1m_platform_t platform;
|
||||
g1m_type_t g1m_handle_type;
|
||||
g1m_platform_t g1m_handle_platform;
|
||||
|
||||
/* Add-in related data */
|
||||
char title[17];
|
||||
char intname[12];
|
||||
g1m_version_t version;
|
||||
time_t creation_date;
|
||||
unsigned char *content;
|
||||
size_t size;
|
||||
char g1m_handle_title[17];
|
||||
char g1m_handle_intname[12];
|
||||
g1m_version_t g1m_handle_version;
|
||||
time_t g1m_handle_creation_date;
|
||||
unsigned char *g1m_handle_content;
|
||||
size_t g1m_handle_size;
|
||||
|
||||
/* Lists for various purposes */
|
||||
int count, _size;
|
||||
g1m_mcsfile_t **files;
|
||||
g1m_file_t **sfiles;
|
||||
char **messages;
|
||||
uint32_t ***fkeys;
|
||||
int g1m_handle_count;
|
||||
int g1m_handle__size;
|
||||
g1m_mcsfile_t **g1m_handle_files;
|
||||
g1m_file_t **g1m_handle_sfiles;
|
||||
char **g1m_handle_messages;
|
||||
uint32_t ***g1m_handle_fkeys;
|
||||
|
||||
/* Picture-related data (also used for add-in icons */
|
||||
int width, height;
|
||||
uint32_t **pixels; /* 0x0RGB */
|
||||
uint32_t **icon_unsel; /* 0x0RGB */
|
||||
uint32_t **icon_sel; /* 0x0RGB */
|
||||
int g1m_handle_width;
|
||||
int g1m_handle_height;
|
||||
uint32_t **g1m_handle_pixels; /* 0x0RGB */
|
||||
uint32_t **g1m_handle_icon_unsel; /* 0x0RGB */
|
||||
uint32_t **g1m_handle_icon_sel; /* 0x0RGB */
|
||||
|
||||
/* E-activities related data */
|
||||
g1m_line_t *line;
|
||||
g1m_line_t _linedata;
|
||||
g1m_line_t *g1m_handle_line;
|
||||
g1m_line_t g1m_handle__linedata;
|
||||
} g1m_handle_t;
|
||||
|
||||
#endif /* LIBG1M_HANDLE_H */
|
||||
|
|
|
@ -59,16 +59,19 @@
|
|||
/* ************************************************************************** */
|
||||
/* read from buffer */
|
||||
# define READ(TO, SZ) /* normal read */ { \
|
||||
int READ_err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)); \
|
||||
buffer->_offset += SZ; \
|
||||
int READ_err = (*buffer->g1m_buffer_read)(buffer->g1m_buffer_cookie, \
|
||||
(void*)(TO), (SZ)); \
|
||||
buffer->g1m_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;
|
||||
err = (*buffer->g1m_buffer_read)(buffer->g1m_buffer_cookie, \
|
||||
(void*)(TO), (SZ)); \
|
||||
buffer->g1m_buffer_offset += SZ;
|
||||
# define GREAD(TO, SZ) /* read with goto fail */ { \
|
||||
if ((err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)))) \
|
||||
if ((err = (*buffer->g1m_buffer_read)(buffer->g1m_buffer_cookie, \
|
||||
(void*)(TO), (SZ)))) \
|
||||
goto fail; \
|
||||
buffer->_offset += SZ; }
|
||||
buffer->g1m_buffer_offset += SZ; }
|
||||
|
||||
/* read from buffer, declare var before */
|
||||
# define DREAD(NAM, STRUCT) /* D read (I don't remember where D comes from) */ \
|
||||
|
@ -93,7 +96,7 @@
|
|||
|
||||
/* write */
|
||||
# define WRITE(BUF, SZ) { \
|
||||
int WRITE_err = (*buffer->write)(buffer->cookie, \
|
||||
int WRITE_err = (*buffer->g1m_buffer_write)(buffer->g1m_buffer_cookie, \
|
||||
(unsigned char*)(BUF), (SZ)); \
|
||||
if (WRITE_err) return (WRITE_err); }
|
||||
# define DWRITE(S) WRITE(&(S), sizeof(S))
|
||||
|
@ -169,13 +172,9 @@ G1M_MCSFUNC(string)
|
|||
# define G1M_CASFUNC(NAME) \
|
||||
extern int g1m_decode_caspart_##NAME(g1m_mcsfile_t *handle, \
|
||||
g1m_buffer_t *buffer);
|
||||
# define G1M_CASHFUNC(NAME) \
|
||||
extern int g1m_decode_cashpart_##NAME(g1m_mcshead_t *head, \
|
||||
g1m_mcshead_t *heads, g1m_buffer_t *buffer);
|
||||
|
||||
G1M_CASFUNC(var)
|
||||
G1M_CASFUNC(program)
|
||||
G1M_CASHFUNC(program)
|
||||
G1M_CASFUNC(matrix)
|
||||
G1M_CASFUNC(capture)
|
||||
/* ************************************************************************** */
|
||||
|
|
|
@ -73,10 +73,11 @@ typedef unsigned int g1m_mcsinfo_t;
|
|||
# define g1m_mcsinfo_graph100 g1m_mcsinfo_cas100
|
||||
|
||||
/* Macros to check if the type uses the ID, and to interact with it */
|
||||
# define g1m_mcshead_uses_id(H) (((H)->type & (\
|
||||
# define g1m_mcshead_uses_id(H) (((H)->g1m_mcshead_type & (\
|
||||
g1m_mcstype_list | g1m_mcstype_mat | g1m_mcstype_vct | \
|
||||
g1m_mcstype_pict | g1m_mcstype_capt | g1m_mcstype_string) || \
|
||||
((H)->type == g1m_mcstype_var && (H)->count == 1)))
|
||||
((H)->g1m_mcshead_type == g1m_mcstype_var && \
|
||||
(H)->g1m_mcshead_count == 1)))
|
||||
# define g1m_get_id_major(I) ((I) >> 6)
|
||||
# define g1m_get_id_minor(I) ((I) & 0x3F)
|
||||
/* ************************************************************************** */
|
||||
|
@ -86,9 +87,10 @@ typedef unsigned int g1m_mcsinfo_t;
|
|||
# define g1m_mcscellflag_used 0x0001
|
||||
|
||||
/* Main structure */
|
||||
typedef struct g1m_mcs_cell_s {
|
||||
g1m_bcd_t real, imgn;
|
||||
unsigned int flags;
|
||||
typedef struct g1m_mcscell_s {
|
||||
unsigned int g1m_mcscell_flags;
|
||||
g1m_bcd_t g1m_mcscell_real;
|
||||
g1m_bcd_t g1m_mcscell_imgn;
|
||||
} g1m_mcscell_t;
|
||||
/* ************************************************************************** */
|
||||
/* Setup */
|
||||
|
@ -126,12 +128,12 @@ typedef struct g1m_mcs_cell_s {
|
|||
# define g1m_setupmflag_dpemode 0x4000 /* Toggle /E-mode */
|
||||
|
||||
/* More complex values */
|
||||
# define g1m_setupval_number 0 /* 0 being comp, 2,8,10,16 being the base */
|
||||
# define g1m_setupval_function 1 /* -> 0x18 */
|
||||
# define g1m_setupval_listfile 2 /* List File 1-6, 0 being none */
|
||||
# define g1m_setupval_bg 3 /* Background picture ID, 0 being none */
|
||||
# define g1m_setupval_dispid 4 /* Display ID, see dpfix/dpnorm/dpemode */
|
||||
# define g1m_setupval_residlist 5 /* Resid List */
|
||||
# define g1m_setupval_number 0 /* 0 being comp, 2,8,10,16 being the base */
|
||||
# define g1m_setupval_function 1 /* -> 0x18 */
|
||||
# define g1m_setupval_listfile 2 /* List File 1-6, 0 being none */
|
||||
# define g1m_setupval_bg 3 /* Background picture ID, 0 being none */
|
||||
# define g1m_setupval_dispid 4 /* Display ID, see dpfix/dpnorm/dpemode */
|
||||
# define g1m_setupval_residlist 5 /* Resid List */
|
||||
|
||||
/* Function types */
|
||||
# define g1m_functype_yequ 0x00 /* Y= */
|
||||
|
@ -144,10 +146,12 @@ typedef struct g1m_mcs_cell_s {
|
|||
# define g1m_functype_yle 0x07 /* Y<= */
|
||||
|
||||
/* Main structure */
|
||||
# define g1m_setupvals 6
|
||||
# define g1m_setup_vals_count 6
|
||||
typedef struct g1m_setup_s {
|
||||
unsigned int iflags, wflags, mflags;
|
||||
unsigned char vals[g1m_setupvals];
|
||||
unsigned int g1m_setup_iflags;
|
||||
unsigned int g1m_setup_wflags;
|
||||
unsigned int g1m_setup_mflags;
|
||||
unsigned char g1m_setup_vals[g1m_setup_vals_count];
|
||||
} g1m_setup_t;
|
||||
/* ************************************************************************** */
|
||||
/* Main structures */
|
||||
|
@ -163,49 +167,55 @@ typedef struct g1m_setup_s {
|
|||
/* mcs file head */
|
||||
typedef struct g1m_mcshead_s {
|
||||
/* file main information */
|
||||
g1m_mcstype_t type;
|
||||
g1m_mcsinfo_t info;
|
||||
char name[13]; int id;
|
||||
unsigned int flags;
|
||||
g1m_mcstype_t g1m_mcshead_type;
|
||||
g1m_mcsinfo_t g1m_mcshead_info;
|
||||
unsigned int g1m_mcshead_flags;
|
||||
unsigned int g1m_mcshead_id;
|
||||
|
||||
/* content size */
|
||||
int count;
|
||||
unsigned int width, height;
|
||||
uint_fast32_t size;
|
||||
int g1m_mcshead_count;
|
||||
unsigned int g1m_mcshead_width;
|
||||
unsigned int g1m_mcshead_height;
|
||||
uint_fast32_t g1m_mcshead_size;
|
||||
|
||||
/* mcs-related raw data */
|
||||
unsigned int _rawtype;
|
||||
unsigned char _group[17], _dirname[9];
|
||||
/* raw data */
|
||||
unsigned int g1m_mcshead_rawtype;
|
||||
g1m_pictureformat_t g1m_mcshead_picformat;
|
||||
|
||||
/* cas-related raw data */
|
||||
unsigned char _appname[4], _datatype[3];
|
||||
g1m_pictureformat_t _picformat;
|
||||
/* strings */
|
||||
char g1m_mcshead_name[13];
|
||||
char g1m_mcshead_password[9];
|
||||
|
||||
/* the program password */
|
||||
char password[9];
|
||||
/* raw string data */
|
||||
unsigned char g1m_mcshead_group[17];
|
||||
unsigned char g1m_mcshead_dirname[9];
|
||||
unsigned char g1m_mcshead_appname[4];
|
||||
unsigned char g1m_mcshead_datatype[3];
|
||||
} g1m_mcshead_t;
|
||||
|
||||
/* mcs file */
|
||||
# define g1m_has_password(F) (F)->head.password[0]
|
||||
# define g1m_remove_password(F) (F)->head.password[0] = 0
|
||||
# define g1m_has_password(F) \
|
||||
(F)->g1m_mcsfile_head.g1m_mcshead_password[0]
|
||||
# define g1m_remove_password(F) \
|
||||
(F)->g1m_mcsfile_head.g1m_mcshead_password[0] = 0
|
||||
typedef struct g1m_mcsfile_s {
|
||||
/* head */
|
||||
g1m_mcshead_t head;
|
||||
g1m_mcshead_t g1m_mcsfile_head;
|
||||
|
||||
/* content (useful when not read) */
|
||||
char *content;
|
||||
char *g1m_mcsfile_content;
|
||||
|
||||
/* variables */
|
||||
g1m_mcscell_t var;
|
||||
g1m_mcscell_t *vars;
|
||||
g1m_mcscell_t **cells;
|
||||
g1m_mcscell_t g1m_mcsfile_var;
|
||||
g1m_mcscell_t *g1m_mcsfile_vars;
|
||||
g1m_mcscell_t **g1m_mcsfile_cells;
|
||||
|
||||
/* for pictures and captures */
|
||||
uint32_t **pic; /* 0x0RGB */
|
||||
uint32_t ***pics;
|
||||
uint32_t **g1m_mcsfile_pic; /* 0x0RGB */
|
||||
uint32_t ***g1m_mcsfile_pics;
|
||||
|
||||
/* for settings */
|
||||
g1m_setup_t setup;
|
||||
g1m_setup_t g1m_mcsfile_setup;
|
||||
} g1m_mcsfile_t;
|
||||
|
||||
#endif /* LIBG1M_MCS_H */
|
||||
|
|
|
@ -29,35 +29,38 @@
|
|||
* @return the special bit, for simplicity.
|
||||
*/
|
||||
|
||||
int g1m_bcd_fromcas(const cas_bcd_t *raw, g1m_bcd_t *bcd)
|
||||
int g1m_bcd_fromcas(const g1m_casbcd_t *raw, g1m_bcd_t *bcd)
|
||||
{
|
||||
const unsigned char *bytes = raw->mantissa;
|
||||
const unsigned char *bytes = raw->g1m_casbcd_mant;
|
||||
|
||||
/* get the exponent and sign */
|
||||
bcd->exp = (raw->exponent >> 4) * 10 + (raw->exponent & 0x0F);
|
||||
if (raw->signinfo & g1m_casbcd_pow_neg)
|
||||
bcd->exp = -bcd->exp;
|
||||
bcd->g1m_bcd_exp = (raw->g1m_casbcd_exp >> 4) * 10
|
||||
+ (raw->g1m_casbcd_exp & 0x0F);
|
||||
if (raw->g1m_casbcd_flags & g1m_casbcdflag_pow_neg)
|
||||
bcd->g1m_bcd_exp = -bcd->g1m_bcd_exp;
|
||||
|
||||
/* get the mantissa */
|
||||
bcd->mant[0] = lwr(0);
|
||||
bcd->mant[1] = upr(1);
|
||||
bcd->mant[2] = lwr(1);
|
||||
bcd->mant[3] = upr(2);
|
||||
bcd->mant[4] = lwr(2);
|
||||
bcd->mant[5] = upr(3);
|
||||
bcd->mant[6] = lwr(3);
|
||||
bcd->mant[7] = upr(4);
|
||||
bcd->mant[8] = lwr(4);
|
||||
bcd->mant[9] = upr(5);
|
||||
bcd->mant[10] = lwr(5);
|
||||
bcd->mant[11] = upr(6);
|
||||
bcd->mant[12] = lwr(6);
|
||||
bcd->mant[13] = upr(7);
|
||||
bcd->mant[14] = lwr(7);
|
||||
bcd->g1m_bcd_mant[0] = lwr(0);
|
||||
bcd->g1m_bcd_mant[1] = upr(1);
|
||||
bcd->g1m_bcd_mant[2] = lwr(1);
|
||||
bcd->g1m_bcd_mant[3] = upr(2);
|
||||
bcd->g1m_bcd_mant[4] = lwr(2);
|
||||
bcd->g1m_bcd_mant[5] = upr(3);
|
||||
bcd->g1m_bcd_mant[6] = lwr(3);
|
||||
bcd->g1m_bcd_mant[7] = upr(4);
|
||||
bcd->g1m_bcd_mant[8] = lwr(4);
|
||||
bcd->g1m_bcd_mant[9] = upr(5);
|
||||
bcd->g1m_bcd_mant[10] = lwr(5);
|
||||
bcd->g1m_bcd_mant[11] = upr(6);
|
||||
bcd->g1m_bcd_mant[12] = lwr(6);
|
||||
bcd->g1m_bcd_mant[13] = upr(7);
|
||||
bcd->g1m_bcd_mant[14] = lwr(7);
|
||||
|
||||
/* set the special things and return */
|
||||
bcd->flags = g1m_make_bcdflags(!!(raw->signinfo & g1m_casbcd_special),
|
||||
(raw->signinfo & g1m_casbcd_negative) == g1m_casbcd_negative, 15);
|
||||
bcd->g1m_bcd_flags = g1m_make_bcdflags(
|
||||
!!(raw->g1m_casbcd_flags & g1m_casbcdflag_special),
|
||||
(raw->g1m_casbcd_flags & g1m_casbcdflag_negative)
|
||||
== g1m_casbcdflag_negative, 15);
|
||||
return (g1m_bcd_has_special(bcd));
|
||||
}
|
||||
|
||||
|
@ -69,28 +72,29 @@ int g1m_bcd_fromcas(const cas_bcd_t *raw, g1m_bcd_t *bcd)
|
|||
* @arg raw the raw BCD.
|
||||
*/
|
||||
|
||||
void g1m_bcd_tocas(const g1m_bcd_t *bcd, cas_bcd_t *raw)
|
||||
# define g1m_bcd_m g1m_bcd_mant
|
||||
void g1m_bcd_tocas(const g1m_bcd_t *bcd, g1m_casbcd_t *raw)
|
||||
{
|
||||
/* put the exponent */
|
||||
div_t d = div(abs(bcd->exp), 10);
|
||||
raw->exponent = (d.quot << 4) | d.rem;
|
||||
div_t d = div(abs(bcd->g1m_bcd_exp), 10);
|
||||
raw->g1m_casbcd_exp = (d.quot << 4) | d.rem;
|
||||
|
||||
/* put the mantissa */
|
||||
raw->mantissa[0] = bcd->mant[0];
|
||||
raw->mantissa[1] = (bcd->mant[1] << 4) | bcd->mant[2];
|
||||
raw->mantissa[2] = (bcd->mant[3] << 4) | bcd->mant[4];
|
||||
raw->mantissa[3] = (bcd->mant[5] << 4) | bcd->mant[6];
|
||||
raw->mantissa[4] = (bcd->mant[7] << 4) | bcd->mant[8];
|
||||
raw->mantissa[5] = (bcd->mant[9] << 4) | bcd->mant[10];
|
||||
raw->mantissa[6] = (bcd->mant[11] << 4) | bcd->mant[12];
|
||||
raw->mantissa[7] = (bcd->mant[13] << 4) | bcd->mant[14];
|
||||
raw->g1m_casbcd_mant[0] = bcd->g1m_bcd_m[0];
|
||||
raw->g1m_casbcd_mant[1] = (bcd->g1m_bcd_m[1] << 4) | bcd->g1m_bcd_m[2];
|
||||
raw->g1m_casbcd_mant[2] = (bcd->g1m_bcd_m[3] << 4) | bcd->g1m_bcd_m[4];
|
||||
raw->g1m_casbcd_mant[3] = (bcd->g1m_bcd_m[5] << 4) | bcd->g1m_bcd_m[6];
|
||||
raw->g1m_casbcd_mant[4] = (bcd->g1m_bcd_m[7] << 4) | bcd->g1m_bcd_m[8];
|
||||
raw->g1m_casbcd_mant[5] = (bcd->g1m_bcd_m[9] << 4) | bcd->g1m_bcd_m[10];
|
||||
raw->g1m_casbcd_mant[6] = (bcd->g1m_bcd_m[11] << 4) | bcd->g1m_bcd_m[12];
|
||||
raw->g1m_casbcd_mant[7] = (bcd->g1m_bcd_m[13] << 4) | bcd->g1m_bcd_m[14];
|
||||
|
||||
/* put the flags */
|
||||
raw->signinfo = 0;
|
||||
if (bcd->exp < 0)
|
||||
raw->signinfo |= g1m_casbcd_pow_neg;
|
||||
raw->g1m_casbcd_flags = 0;
|
||||
if (bcd->g1m_bcd_exp < 0)
|
||||
raw->g1m_casbcd_flags |= g1m_casbcdflag_pow_neg;
|
||||
if (g1m_bcd_is_negative(bcd))
|
||||
raw->signinfo |= g1m_casbcd_negative;
|
||||
raw->g1m_casbcd_flags |= g1m_casbcdflag_negative;
|
||||
if (g1m_bcd_has_special(bcd))
|
||||
raw->signinfo |= g1m_casbcd_special;
|
||||
raw->g1m_casbcd_flags |= g1m_casbcdflag_special;
|
||||
}
|
||||
|
|
|
@ -50,13 +50,13 @@ void g1m_bcd_fromdouble(double dbl, g1m_bcd_t *bcd)
|
|||
/* get the mantissa */
|
||||
for (int i = 0; i < 15; i++) {
|
||||
double work = floor(dbl);
|
||||
bcd->mant[i] = (int)work;
|
||||
bcd->g1m_bcd_mant[i] = (int)work;
|
||||
dbl = (dbl - work) * 10;
|
||||
}
|
||||
|
||||
/* set the flags */
|
||||
bcd->flags = g1m_make_bcdflags(0, neg, 15);
|
||||
bcd->exp = exp;
|
||||
bcd->g1m_bcd_flags = g1m_make_bcdflags(0, neg, 15);
|
||||
bcd->g1m_bcd_exp = exp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,34 +29,34 @@
|
|||
* @return the special bit, for simplicity.
|
||||
*/
|
||||
|
||||
int g1m_bcd_frommcs(const mcs_bcd_t *raw, g1m_bcd_t *bcd)
|
||||
int g1m_bcd_frommcs(const g1m_mcsbcd_t *raw, g1m_bcd_t *bcd)
|
||||
{
|
||||
const unsigned char *bytes = raw->BCDval;
|
||||
const unsigned char *bytes = raw->g1m_mcsbcd_BCDval;
|
||||
|
||||
/* get the exponent and correct it */
|
||||
int exp = (upr(0) & 7) * 100 + lwr(0) * 10 + upr(1), neg = 0;
|
||||
if (exp >= 500) exp -= 500, neg = 1;
|
||||
bcd->exp = (char)(exp - 99);
|
||||
bcd->g1m_bcd_exp = (char)(exp - 99);
|
||||
|
||||
/* set the flags */
|
||||
bcd->flags = g1m_make_bcdflags((bytes[0] & 0x80) >> 7, neg, 15);
|
||||
bcd->g1m_bcd_flags = g1m_make_bcdflags((bytes[0] & 0x80) >> 7, neg, 15);
|
||||
|
||||
/* get the mantissa */
|
||||
bcd->mant[0] = lwr(1);
|
||||
bcd->mant[1] = upr(2);
|
||||
bcd->mant[2] = lwr(2);
|
||||
bcd->mant[3] = upr(3);
|
||||
bcd->mant[4] = lwr(3);
|
||||
bcd->mant[5] = upr(4);
|
||||
bcd->mant[6] = lwr(4);
|
||||
bcd->mant[7] = upr(5);
|
||||
bcd->mant[8] = lwr(5);
|
||||
bcd->mant[9] = upr(6);
|
||||
bcd->mant[10] = lwr(6);
|
||||
bcd->mant[11] = upr(7);
|
||||
bcd->mant[12] = lwr(7);
|
||||
bcd->mant[13] = upr(8);
|
||||
bcd->mant[14] = lwr(8);
|
||||
bcd->g1m_bcd_mant[0] = lwr(1);
|
||||
bcd->g1m_bcd_mant[1] = upr(2);
|
||||
bcd->g1m_bcd_mant[2] = lwr(2);
|
||||
bcd->g1m_bcd_mant[3] = upr(3);
|
||||
bcd->g1m_bcd_mant[4] = lwr(3);
|
||||
bcd->g1m_bcd_mant[5] = upr(4);
|
||||
bcd->g1m_bcd_mant[6] = lwr(4);
|
||||
bcd->g1m_bcd_mant[7] = upr(5);
|
||||
bcd->g1m_bcd_mant[8] = lwr(5);
|
||||
bcd->g1m_bcd_mant[9] = upr(6);
|
||||
bcd->g1m_bcd_mant[10] = lwr(6);
|
||||
bcd->g1m_bcd_mant[11] = upr(7);
|
||||
bcd->g1m_bcd_mant[12] = lwr(7);
|
||||
bcd->g1m_bcd_mant[13] = upr(8);
|
||||
bcd->g1m_bcd_mant[14] = lwr(8);
|
||||
|
||||
/* return the special bit */
|
||||
return (g1m_bcd_has_special(bcd));
|
||||
|
@ -70,28 +70,30 @@ int g1m_bcd_frommcs(const mcs_bcd_t *raw, g1m_bcd_t *bcd)
|
|||
* @arg raw the raw BCD.
|
||||
*/
|
||||
|
||||
void g1m_bcd_tomcs(const g1m_bcd_t *bcd, mcs_bcd_t *raw)
|
||||
# define g1m_bcd_m g1m_bcd_mant
|
||||
void g1m_bcd_tomcs(const g1m_bcd_t *bcd, g1m_mcsbcd_t *raw)
|
||||
{
|
||||
int exp = bcd->exp + 99;
|
||||
int exp = bcd->g1m_bcd_exp + 99;
|
||||
if (g1m_bcd_is_negative(bcd)) exp += 500;
|
||||
|
||||
/* put the exponent (and first digit of the mantissa) */
|
||||
div_t c = div(exp, 100);
|
||||
div_t d = div(c.rem, 10);
|
||||
raw->BCDval[0] = (c.quot << 4) | d.quot | (!!g1m_bcd_has_special(bcd) << 7);
|
||||
raw->BCDval[1] = (d.rem << 4) | bcd->mant[0];
|
||||
raw->g1m_mcsbcd_BCDval[0] = (c.quot << 4) | d.quot
|
||||
| (!!g1m_bcd_has_special(bcd) << 7);
|
||||
raw->g1m_mcsbcd_BCDval[1] = (d.rem << 4) | bcd->g1m_bcd_mant[0];
|
||||
|
||||
/* put the mantissa */
|
||||
raw->BCDval[2] = (bcd->mant[1] << 4) | bcd->mant[2];
|
||||
raw->BCDval[3] = (bcd->mant[3] << 4) | bcd->mant[4];
|
||||
raw->BCDval[4] = (bcd->mant[5] << 4) | bcd->mant[6];
|
||||
raw->BCDval[5] = (bcd->mant[7] << 4) | bcd->mant[8];
|
||||
raw->BCDval[6] = (bcd->mant[9] << 4) | bcd->mant[10];
|
||||
raw->BCDval[7] = (bcd->mant[11] << 4) | bcd->mant[12];
|
||||
raw->BCDval[8] = (bcd->mant[13] << 4) | bcd->mant[14];
|
||||
raw->g1m_mcsbcd_BCDval[2] = (bcd->g1m_bcd_m[1] << 4) | bcd->g1m_bcd_m[2];
|
||||
raw->g1m_mcsbcd_BCDval[3] = (bcd->g1m_bcd_m[3] << 4) | bcd->g1m_bcd_m[4];
|
||||
raw->g1m_mcsbcd_BCDval[4] = (bcd->g1m_bcd_m[5] << 4) | bcd->g1m_bcd_m[6];
|
||||
raw->g1m_mcsbcd_BCDval[5] = (bcd->g1m_bcd_m[7] << 4) | bcd->g1m_bcd_m[8];
|
||||
raw->g1m_mcsbcd_BCDval[6] = (bcd->g1m_bcd_m[9] << 4) | bcd->g1m_bcd_m[10];
|
||||
raw->g1m_mcsbcd_BCDval[7] = (bcd->g1m_bcd_m[11] << 4) | bcd->g1m_bcd_m[12];
|
||||
raw->g1m_mcsbcd_BCDval[8] = (bcd->g1m_bcd_m[13] << 4) | bcd->g1m_bcd_m[14];
|
||||
|
||||
/* set the align zone */
|
||||
raw->_align[0] = 0;
|
||||
raw->_align[1] = 0;
|
||||
raw->_align[2] = 0;
|
||||
raw->g1m_mcsbcd__align[0] = 0;
|
||||
raw->g1m_mcsbcd__align[1] = 0;
|
||||
raw->g1m_mcsbcd__align[2] = 0;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ size_t g1m_bcdtoa(const g1m_bcd_t *bcd, char *buf, size_t len)
|
|||
/* get base digit */
|
||||
int exp = g1m_bcd_exponent(bcd), offset = 0;
|
||||
int leftdigits = g1m_bcd_precision(bcd);
|
||||
const char *digits = bcd->mant;
|
||||
const char *digits = bcd->g1m_bcd_mant;
|
||||
for (; leftdigits > 0; leftdigits--) {
|
||||
if (*digits) break;
|
||||
exp--;
|
||||
|
|
|
@ -32,15 +32,15 @@ void g1m_free_line_content(g1m_line_t *line)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (line->type & (g1m_linetype_title | g1m_linetype_text
|
||||
if (line->g1m_line_type & (g1m_linetype_title | g1m_linetype_text
|
||||
| g1m_linetype_picture))
|
||||
free(line->content);
|
||||
free(line->g1m_line_content);
|
||||
|
||||
if (line->type & g1m_linetype_eact) {
|
||||
for (i = 0; i < line->count; i++) {
|
||||
g1m_free_line_content(line->lines[i]);
|
||||
free(line->lines[i]);
|
||||
if (line->g1m_line_type & g1m_linetype_eact) {
|
||||
for (i = 0; i < line->g1m_line_count; i++) {
|
||||
g1m_free_line_content(line->g1m_line_lines[i]);
|
||||
free(line->g1m_line_lines[i]);
|
||||
}
|
||||
free(line->lines);
|
||||
free(line->g1m_line_lines);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,9 +54,9 @@ static const char version_message[] =
|
|||
* Display version when the library is executed.
|
||||
*/
|
||||
|
||||
extern void __libg1m_version(void)
|
||||
extern void g1m__version(void)
|
||||
__attribute__((noreturn));
|
||||
void __libg1m_version(void)
|
||||
void g1m__version(void)
|
||||
{
|
||||
puts(version_message);
|
||||
_exit(0);
|
||||
|
|
164
src/decode/cas.c
164
src/decode/cas.c
|
@ -22,17 +22,6 @@
|
|||
#include <libg1m/internals.h>
|
||||
#define FUNC(NAME) g1m_decode_caspart_##NAME
|
||||
#define HFUNC(NAME) g1m_decode_cashpart_##NAME
|
||||
#define READGSIZE() if (grc) { \
|
||||
uint16_t size; READ(&size, 2) \
|
||||
log_info("GraphCard next buffer size was: 0x%04X", be16toh(size)); }
|
||||
#define READCOLON() { \
|
||||
READGSIZE() \
|
||||
uint8_t colon; GREAD(&colon, 1) \
|
||||
err = g1m_error_magic; \
|
||||
if (colon != ':') { \
|
||||
log_error("Expected ':', got '%c' (0x%02X)", colon, colon); \
|
||||
goto fail; \
|
||||
}}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type correspondance list */
|
||||
|
@ -53,7 +42,7 @@ struct cas_corresp {
|
|||
#define TTERM {0, NULL, NULL}
|
||||
static struct cas_corresp cas_types[] = {
|
||||
{g1m_mcstype_var, FUNC(var), NULL},
|
||||
{g1m_mcstype_program, FUNC(program), HFUNC(program)},
|
||||
{g1m_mcstype_program, FUNC(program), NULL},
|
||||
{g1m_mcstype_matrix, FUNC(matrix), NULL},
|
||||
{g1m_mcstype_list, FUNC(matrix), NULL},
|
||||
{g1m_mcstype_capture, FUNC(capture), NULL},
|
||||
|
@ -100,7 +89,7 @@ static int decode_cas50(g1m_mcshead_t *head, g1m_buffer_t *buffer, uint8_t csum)
|
|||
/* read the raw header */
|
||||
DREAD(hd, _cas50)
|
||||
log_info("Raw CAS50 (CASPRO) header content (app: '%.3s'):",
|
||||
head->_appname);
|
||||
head->g1m_mcshead_appname);
|
||||
logm_info(&hd, sizeof(struct _cas50));
|
||||
|
||||
/* check the checksum */
|
||||
|
@ -114,29 +103,32 @@ static int decode_cas50(g1m_mcshead_t *head, g1m_buffer_t *buffer, uint8_t csum)
|
|||
|
||||
/* copy the basic information */
|
||||
g1m_maketype_cas(head, (char*)hd.data);
|
||||
head->size = be16toh(hd.height) - 2 /* checksum, colon */;
|
||||
head->g1m_mcshead_size = be16toh(hd.height) - 2 /* checksum, colon */;
|
||||
char *end = memchr(hd.name, 0xFF, 8);
|
||||
size_t len = end ? (size_t)(end - (char*)hd.name) : 8;
|
||||
memcpy(head->name, hd.name, len); head->name[len] = 0;
|
||||
memcpy(head->g1m_mcshead_name, hd.name, len);
|
||||
head->g1m_mcshead_name[len] = 0;
|
||||
|
||||
/* read specific data */
|
||||
switch (head->type) {
|
||||
switch (head->g1m_mcshead_type) {
|
||||
case g1m_mcstype_program:;
|
||||
/* copy password */
|
||||
head->flags |= g1m_mcsflag_unfinished;
|
||||
head->g1m_mcshead_flags |= g1m_mcsflag_unfinished;
|
||||
end = memchr(hd.aux, 0xFF, 8);
|
||||
len = end ? (size_t)(end - (char*)hd.aux) : 8;
|
||||
memcpy(head->password, hd.aux, len); head->password[len] = 0;
|
||||
log_info("Is a program of %" PRIuFAST32 " bytes", head->size);
|
||||
memcpy(head->g1m_mcshead_password, hd.aux, len);
|
||||
head->g1m_mcshead_password[len] = 0;
|
||||
log_info("Is a program of %" PRIuFAST32 " bytes",
|
||||
head->g1m_mcshead_size);
|
||||
break;
|
||||
case g1m_mcstype_variable:
|
||||
case g1m_mcstype_matrix:
|
||||
case g1m_mcstype_list:
|
||||
head->height = be16toh(hd.height) & 0xFF;
|
||||
head->width = be16toh(hd.width) & 0xFF;
|
||||
head->count = head->height;
|
||||
if (head->width && head->height)
|
||||
head->flags |= g1m_mcsflag_unfinished;
|
||||
head->g1m_mcshead_height = be16toh(hd.height) & 0xFF;
|
||||
head->g1m_mcshead_width = be16toh(hd.width) & 0xFF;
|
||||
head->g1m_mcshead_count = head->g1m_mcshead_height;
|
||||
if (head->g1m_mcshead_width && head->g1m_mcshead_height)
|
||||
head->g1m_mcshead_flags |= g1m_mcsflag_unfinished;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -164,11 +156,12 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
|||
uint8_t csum = g1m_checksum8(buf, 4);
|
||||
struct casdyn *dhd = (void*)buf;
|
||||
if (!g1m_maketype_casapp(head, dhd->ext, (char*)dhd->app))
|
||||
switch (head->info) {
|
||||
switch (head->g1m_mcshead_info) {
|
||||
case g1m_mcsinfo_cas50: return (decode_cas50(head, buffer, csum));
|
||||
//case g1m_mcsinfo_cas100: return (decode_cas100(head, buffer));
|
||||
default:
|
||||
log_error("Platform 0x%04X isn't implemented yet.", head->info);
|
||||
log_error("Platform 0x%04X isn't implemented yet.",
|
||||
head->g1m_mcshead_info);
|
||||
return (g1m_error_op);
|
||||
}
|
||||
|
||||
|
@ -183,14 +176,15 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
|||
return (g1m_error_checksum);
|
||||
|
||||
/* fill the handle */
|
||||
memset(head, 0, sizeof(struct cas40));
|
||||
head->info = g1m_mcsinfo_cas40;
|
||||
memcpy(head->name, hd->filename, 12); head->name[12] = 0;
|
||||
memset(head, 0, sizeof(g1m_mcshead_t));
|
||||
head->g1m_mcshead_info = g1m_mcsinfo_cas40;
|
||||
memcpy(head->g1m_mcshead_name, hd->filename, 12);
|
||||
head->g1m_mcshead_name[12] = 0;
|
||||
|
||||
/* type specific things */
|
||||
if (head->type == g1m_mcstype_program) {
|
||||
if (head->g1m_mcshead_type == g1m_mcstype_program) {
|
||||
struct cas_spe_program *spe = (void*)hd->misc;
|
||||
head->size = be16toh(spe->length);
|
||||
head->g1m_mcshead_size = be16toh(spe->length);
|
||||
/* TODO: store flags? */
|
||||
}
|
||||
|
||||
|
@ -200,30 +194,6 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
|||
/* ************************************************************************** */
|
||||
/* Part decoding functions */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_decode_casfiles_part:
|
||||
* Decode the CASIOLINK group parts.
|
||||
*
|
||||
* @arg head the general head.
|
||||
* @arg heads the heads to contribute to.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @return the error that occurred (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_casfiles_part(g1m_mcshead_t *head, g1m_mcshead_t *heads,
|
||||
g1m_buffer_t *buffer)
|
||||
{
|
||||
/* look for the decoding function */
|
||||
cas_heads_decode_function decode = (void*)lookup_cas_decode(head->type, 1);
|
||||
if (!decode) {
|
||||
log_error("No dedicated decoding function was found for this type!");
|
||||
return (g1m_error_unknown);
|
||||
}
|
||||
|
||||
/* decode the part */
|
||||
return ((*decode)(head, heads, buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_decode_casfile_part:
|
||||
* Decode a CASIOLINK Protocol content part.
|
||||
|
@ -239,7 +209,8 @@ int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
|
|||
if (!file) return (g1m_error_op);
|
||||
|
||||
/* look for the decoding function */
|
||||
cas_decode_function decode = (void*)lookup_cas_decode(file->head.type, 0);
|
||||
cas_decode_function decode = (void*)lookup_cas_decode(
|
||||
file->g1m_mcsfile_head.g1m_mcshead_type, 0);
|
||||
if (!decode) {
|
||||
log_error("No dedicated decoding function was found for this type!");
|
||||
return (g1m_error_unknown);
|
||||
|
@ -248,10 +219,21 @@ int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
|
|||
/* decode the part */
|
||||
return ((*decode)(file, buffer));
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main file decoding function */
|
||||
/* ************************************************************************** */
|
||||
#define READGSIZE() if (grc) { \
|
||||
uint16_t size; READ(&size, 2) \
|
||||
log_info("GraphCard next buffer size was: 0x%04X", be16toh(size)); }
|
||||
#define READCOLON() { \
|
||||
READGSIZE() \
|
||||
uint8_t colon; GREAD(&colon, 1) \
|
||||
err = g1m_error_magic; \
|
||||
if (colon != ':') { \
|
||||
log_error("Expected ':', got '%c' (0x%02X)", colon, colon); \
|
||||
goto fail; \
|
||||
}}
|
||||
|
||||
/**
|
||||
* decode_cas:
|
||||
* Decode a CAS file.
|
||||
|
@ -272,58 +254,43 @@ static int decode_cas(g1m_handle_t **h, g1m_buffer_t *buffer, int grc)
|
|||
if (err) return (err);
|
||||
g1m_handle_t *handle = *h;
|
||||
|
||||
/* read first colon */
|
||||
if (grc) READCOLON() /* FIXME: read this in graphcard magic? */
|
||||
|
||||
/* read each */
|
||||
for (handle->count = 0;;) {
|
||||
for (handle->g1m_handle_count = 0;;) {
|
||||
/* read the head */
|
||||
log_info("Reading the next head.");
|
||||
g1m_mcshead_t head = {};
|
||||
if ((err = g1m_decode_casfile_head(&head, buffer))) goto fail;
|
||||
if (head.type == g1m_mcstype_end) break;
|
||||
if (head.g1m_mcshead_type == g1m_mcstype_end) break;
|
||||
|
||||
/* heads up! */
|
||||
int numheads = head.flags & g1m_mcsflag_multiple ? head.count : 1;
|
||||
g1m_mcshead_t heads[numheads];
|
||||
if (head.flags & g1m_mcsflag_multiple) {
|
||||
log_info("Is a head for multiple files!");
|
||||
g1m_prepare_mcsfile_heads(&head, heads);
|
||||
while (head.flags & g1m_mcsflag_unfinished) {
|
||||
READCOLON()
|
||||
/* prepare the file */
|
||||
log_info("Preparing the file.");
|
||||
g1m_mcsfile_t *file; err = g1m_mcs_insert(handle, &file, &head);
|
||||
if (err) goto fail;
|
||||
|
||||
/* decode a general part */
|
||||
err = g1m_decode_casfiles_part(&head, heads, buffer);
|
||||
if (err) goto fail;
|
||||
}
|
||||
} else heads[0] = head;
|
||||
|
||||
for (int i = 0; i < numheads; i++) {
|
||||
/* prepare the file */
|
||||
log_info("Preparing the group file #%d", i);
|
||||
g1m_mcsfile_t *file; err = g1m_mcs_insert(handle, &file, &heads[i]);
|
||||
if (err) goto fail;
|
||||
|
||||
/* read each part */
|
||||
/* read each part */
|
||||
#if LOGLEVEL <= ll_info
|
||||
for (int j = 1; file->head.flags & g1m_mcsflag_unfinished; j++) {
|
||||
for (int j = 1; file->g1m_mcsfile_head.g1m_mcshead_flags
|
||||
& g1m_mcsflag_unfinished; j++) {
|
||||
#else
|
||||
while (file->head.flags & g1m_mcsflag_unfinished) {
|
||||
while (file->g1m_mcsfile_head.g1m_mcshead_flags
|
||||
& g1m_mcsflag_unfinished) {
|
||||
#endif
|
||||
/* initialize */
|
||||
log_info("Reading part #%d", j);
|
||||
READCOLON()
|
||||
/* initialize */
|
||||
log_info("Reading part #%d", j);
|
||||
READCOLON()
|
||||
|
||||
/* read the part */
|
||||
err = g1m_decode_casfile_part(file, buffer);
|
||||
if (err) goto fail;
|
||||
}
|
||||
/* read the part */
|
||||
err = g1m_decode_casfile_part(file, buffer);
|
||||
if (err) goto fail;
|
||||
}
|
||||
|
||||
/* read first colon of the next part */
|
||||
READCOLON()
|
||||
}
|
||||
|
||||
/* read last size (check if zero?) */
|
||||
READGSIZE()
|
||||
|
||||
/* everything went well :) */
|
||||
return (0);
|
||||
|
||||
|
@ -361,16 +328,5 @@ int g1m_decode_cas(g1m_handle_t **handle, g1m_buffer_t *buffer)
|
|||
|
||||
int g1m_decode_grc(g1m_handle_t **handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* file decoding */
|
||||
int err = decode_cas(handle, buffer, 1);
|
||||
if (err) return (err);
|
||||
|
||||
/* read final size */
|
||||
uint16_t final; GREAD(&final, sizeof(uint16_t))
|
||||
if (final != 0) return (g1m_error_magic);
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
g1m_free(*handle); *handle = NULL;
|
||||
return (err);
|
||||
return (decode_cas(handle, buffer, 1));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ static int decode_cell(g1m_buffer_t *buffer, g1m_mcscell_t *cell,
|
|||
unsigned int *x, unsigned int *y)
|
||||
{
|
||||
uint8_t csum = 0;
|
||||
cell->flags = g1m_mcscellflag_used;
|
||||
cell->g1m_mcscell_flags = g1m_mcscellflag_used;
|
||||
|
||||
/* read position */
|
||||
uint16_t fx, fy;
|
||||
|
@ -46,12 +46,12 @@ static int decode_cell(g1m_buffer_t *buffer, g1m_mcscell_t *cell,
|
|||
csum += g1m_checksum8(&fy, sizeof(uint16_t));
|
||||
|
||||
/* read the parts */
|
||||
DREAD(wkg, cas_bcd)
|
||||
csum += g1m_checksum8(&wkg, sizeof(cas_bcd_t));
|
||||
if (g1m_bcd_fromcas(&wkg, &cell->real)) {
|
||||
READ(&wkg, sizeof(cas_bcd_t))
|
||||
csum += g1m_checksum8(&wkg, sizeof(cas_bcd_t));
|
||||
g1m_bcd_fromcas(&wkg, &cell->imgn);
|
||||
DREAD(wkg, g1m_casbcd_s)
|
||||
csum += g1m_checksum8(&wkg, sizeof(g1m_casbcd_t));
|
||||
if (g1m_bcd_fromcas(&wkg, &cell->g1m_mcscell_real)) {
|
||||
READ(&wkg, sizeof(g1m_casbcd_t))
|
||||
csum += g1m_checksum8(&wkg, sizeof(g1m_casbcd_t));
|
||||
g1m_bcd_fromcas(&wkg, &cell->g1m_mcscell_imgn);
|
||||
}
|
||||
|
||||
/* read and check the checksum */
|
||||
|
@ -83,12 +83,12 @@ int g1m_decode_caspart_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
if (err) return (err);
|
||||
|
||||
/* save the cell (FIXME: secure) */
|
||||
handle->cells[y][x] = cell;
|
||||
handle->g1m_mcsfile_cells[y][x] = cell;
|
||||
|
||||
/* check if its the last cell */
|
||||
if (y == handle->head.height - 1
|
||||
&& x == handle->head.width - 1)
|
||||
handle->head.flags &= ~g1m_mcsflag_unfinished;
|
||||
if (y == handle->g1m_mcsfile_head.g1m_mcshead_height - 1
|
||||
&& x == handle->g1m_mcsfile_head.g1m_mcshead_width - 1)
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_flags &= ~g1m_mcsflag_unfinished;
|
||||
|
||||
/* no error! */
|
||||
return (0);
|
||||
|
@ -107,11 +107,11 @@ int g1m_decode_caspart_var(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
{
|
||||
/* read and save the cell */
|
||||
unsigned int x, y;
|
||||
int err = decode_cell(buffer, &handle->var, &x, &y);
|
||||
int err = decode_cell(buffer, &handle->g1m_mcsfile_var, &x, &y);
|
||||
if (err) return (err);
|
||||
if (x != 1 || y != 1) return (g1m_error_magic);
|
||||
|
||||
/* no error! */
|
||||
handle->head.flags &= ~g1m_mcsflag_unfinished;
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_flags &= ~g1m_mcsflag_unfinished;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,44 +18,6 @@
|
|||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* g1m_decode_cashpart_program:
|
||||
* Decode a CAS heads program part.
|
||||
*
|
||||
* @arg head the general head.
|
||||
* @arg heads the heads to contribute to.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_cashpart_program(g1m_mcshead_t *head, g1m_mcshead_t *heads,
|
||||
g1m_buffer_t *buffer)
|
||||
{
|
||||
/* get content */
|
||||
struct cas_spe_program headers[head->count];
|
||||
READ(headers, sizeof(struct cas_spe_program) * head->count)
|
||||
|
||||
/* check the sum */
|
||||
uint8_t checksum; READ(&checksum, 1)
|
||||
uint8_t csum = ~g1m_checksum8(headers,
|
||||
sizeof(struct cas_spe_program) * head->count) + 1;
|
||||
if (csum != checksum) {
|
||||
log_error("Checksum mismatch: expected 0x%02X, got 0x%02X",
|
||||
csum, checksum);
|
||||
return (g1m_error_checksum);
|
||||
}
|
||||
|
||||
/* initialize */
|
||||
for (int i = 0; i < head->count; i++) {
|
||||
heads[i].size = be16toh(headers[i].length);
|
||||
/* program type? */
|
||||
}
|
||||
|
||||
/* everything went well :D */
|
||||
head->flags &= ~g1m_mcsflag_unfinished;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_decode_caspart_program:
|
||||
* Decode a CAS program part.
|
||||
|
@ -68,13 +30,15 @@ int g1m_decode_cashpart_program(g1m_mcshead_t *head, g1m_mcshead_t *heads,
|
|||
int g1m_decode_caspart_program(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* get content */
|
||||
READ(handle->content, handle->head.size)
|
||||
READ(handle->g1m_mcsfile_content, handle->g1m_mcsfile_head.g1m_mcshead_size)
|
||||
log_info("Program content is:");
|
||||
logm_info(handle->content, handle->head.size);
|
||||
logm_info(handle->g1m_mcsfile_content,
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_size);
|
||||
|
||||
/* check the sum */
|
||||
uint8_t checksum; READ(&checksum, 1)
|
||||
uint8_t csum = ~g1m_checksum8(handle->content, handle->head.size) + 1;
|
||||
uint8_t csum = ~g1m_checksum8(handle->g1m_mcsfile_content,
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_size) + 1;
|
||||
if (csum != checksum) {
|
||||
log_error("Checksum mismatch: expected 0x%02X, got 0x%02X",
|
||||
csum, checksum);
|
||||
|
@ -82,6 +46,6 @@ int g1m_decode_caspart_program(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
}
|
||||
|
||||
/* everything went well :) */
|
||||
handle->head.flags &= ~g1m_mcsflag_unfinished;
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_flags &= ~g1m_mcsflag_unfinished;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -30,16 +30,18 @@
|
|||
int g1m_decode_caspart_capture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* read the picture data */
|
||||
unsigned int width = handle->head.width, height = handle->head.height;
|
||||
unsigned int width = handle->g1m_mcsfile_head.g1m_mcshead_width;
|
||||
unsigned int height = handle->g1m_mcsfile_head.g1m_mcshead_height;
|
||||
size_t pic_size = g1m_picturesize_4bit_color(width, height);
|
||||
uint8_t pic_data[pic_size]; READ(pic_data, pic_size)
|
||||
|
||||
/* decode the picture data */
|
||||
int err = g1m_decode_picture(handle->pics[0], handle->head._picformat,
|
||||
int err = g1m_decode_picture(handle->g1m_mcsfile_pics[0],
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_picformat,
|
||||
pic_data, width, height);
|
||||
if (err) { g1m_free_mcsfile(handle); return (err); }
|
||||
|
||||
/* no error */
|
||||
handle->head.flags &= ~g1m_mcsflag_unfinished;
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_flags &= ~g1m_mcsflag_unfinished;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -146,16 +146,17 @@ static int read_picture(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* make the head and allocate file */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_capture,
|
||||
.width = pct.width, .height = pct.height,
|
||||
.g1m_mcshead_type = g1m_mcstype_capture,
|
||||
.g1m_mcshead_width = pct.width,
|
||||
.g1m_mcshead_height = pct.height,
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
head.id = name[7] - '0';
|
||||
memcpy(head.g1m_mcshead_name, name, strlen(name) + 1);
|
||||
head.g1m_mcshead_id = name[7] - '0';
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* set the pixels */
|
||||
uint32_t **img = (*pfile)->pics[0];
|
||||
uint32_t **img = (*pfile)->g1m_mcsfile_pics[0];
|
||||
for (int x = 0; x < pct.width; x++) for (int y = 0; y < pct.height; y++)
|
||||
img[y][x] = colours[*px++];
|
||||
|
||||
|
@ -195,16 +196,17 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* make the head and allocate file */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_matrix,
|
||||
.width = width, .height = height,
|
||||
.g1m_mcshead_type = g1m_mcstype_matrix,
|
||||
.g1m_mcshead_width = width,
|
||||
.g1m_mcshead_height = height,
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
head.id = name[4] - 'A' + 1;
|
||||
memcpy(head.g1m_mcshead_name, name, strlen(name) + 1);
|
||||
head.g1m_mcshead_id = name[4] - 'A' + 1;
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* read the matrix */
|
||||
g1m_mcscell_t **cells = (*pfile)->cells;
|
||||
g1m_mcscell_t **cells = (*pfile)->g1m_mcsfile_cells;
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
for (unsigned int x = 0; x < width; x++) {
|
||||
/* read the bcd */
|
||||
|
@ -219,9 +221,9 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* make the cell */
|
||||
cells[y][x] = (g1m_mcscell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.flags = g1m_mcscellflag_used
|
||||
.g1m_mcscell_real = bcd,
|
||||
.g1m_mcscell_imgn = {},
|
||||
.g1m_mcscell_flags = g1m_mcscellflag_used
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -260,16 +262,17 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* make head */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_list,
|
||||
.width = 1, .height = len
|
||||
.g1m_mcshead_type = g1m_mcstype_list,
|
||||
.g1m_mcshead_width = 1,
|
||||
.g1m_mcshead_height = len
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
head.id = name[5] - '0';
|
||||
memcpy(head.g1m_mcshead_name, name, strlen(name) + 1);
|
||||
head.g1m_mcshead_id = name[5] - '0';
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* read the list */
|
||||
g1m_mcscell_t **cells = (*pfile)->cells;
|
||||
g1m_mcscell_t **cells = (*pfile)->g1m_mcsfile_cells;
|
||||
for (int x = 0; x < len; x++) {
|
||||
/* read bcd */
|
||||
g1m_bcd_t bcd; g1m_bcd_fromdouble(*raw++, &bcd);
|
||||
|
@ -283,16 +286,15 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* set the cell */
|
||||
cells[x][0] = (g1m_mcscell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.flags = g1m_mcscellflag_used
|
||||
.g1m_mcscell_real = bcd,
|
||||
.g1m_mcscell_imgn = {},
|
||||
.g1m_mcscell_flags = g1m_mcscellflag_used
|
||||
};
|
||||
}
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main function */
|
||||
/* ************************************************************************** */
|
||||
|
@ -362,28 +364,28 @@ int g1m_decode_casemul(g1m_handle_t **h, g1m_buffer_t *buffer, int big_endian)
|
|||
/* read each picture */
|
||||
for (int i = 0; i < src.pictures; i++) {
|
||||
log_info("Reading picture #%d", i + 1);
|
||||
if ((err = read_picture(&handle->files[handle->count], buffer,
|
||||
big_endian)))
|
||||
goto fail;
|
||||
handle->count++;
|
||||
err = read_picture(&handle->g1m_handle_files[handle->g1m_handle_count],
|
||||
buffer, big_endian);
|
||||
if (err) goto fail;
|
||||
handle->g1m_handle_count++;
|
||||
}
|
||||
|
||||
/* read each matrix */
|
||||
for (int i = 0; i < src.matrixes; i++) {
|
||||
log_info("Reading matrix #%d", i + 1);
|
||||
if ((err = read_matrix(&handle->files[handle->count], buffer,
|
||||
big_endian)))
|
||||
goto fail;
|
||||
handle->count++;
|
||||
err = read_matrix(&handle->g1m_handle_files[handle->g1m_handle_count],
|
||||
buffer, big_endian);
|
||||
if (err) goto fail;
|
||||
handle->g1m_handle_count++;
|
||||
}
|
||||
|
||||
/* read each list */
|
||||
for (int i = 0; i < src.lists; i++) {
|
||||
log_info("Reading list #%d", i + 1);
|
||||
if ((err = read_list(&handle->files[handle->count], buffer,
|
||||
big_endian)))
|
||||
goto fail;
|
||||
handle->count++;
|
||||
err = read_list(&handle->g1m_handle_files[handle->g1m_handle_count],
|
||||
buffer, big_endian);
|
||||
if (err) goto fail;
|
||||
handle->g1m_handle_count++;
|
||||
}
|
||||
|
||||
/* TODO: skip compiled part? */
|
||||
|
|
|
@ -39,7 +39,6 @@ struct corresp {
|
|||
/* Correspondances */
|
||||
static struct corresp correspondances[] = {
|
||||
// {"g1s", g1m_type_storage, g1m_decode_storage},
|
||||
{"grc", g1m_type_mcs, g1m_decode_grc},
|
||||
|
||||
/* terminating entry */
|
||||
{NULL, 0, NULL}
|
||||
|
@ -107,8 +106,16 @@ int g1m_decode(g1m_handle_t **handle, const char *path, g1m_buffer_t *buffer,
|
|||
return (g1m_decode_cas(handle, buffer));
|
||||
}
|
||||
|
||||
/* identify a GraphCard file */
|
||||
READ(&buf[1], 2)
|
||||
if (!buf[0] && buf[1] == 0x32 && buf[2] == ':') {
|
||||
if (expected_types && !(expected_types & g1m_type_mcs))
|
||||
return (g1m_error_wrong_type);
|
||||
return (g1m_decode_grc(handle, buffer));
|
||||
}
|
||||
|
||||
/* identify a Casemul file */
|
||||
READ(&buf[1], 3)
|
||||
READ(&buf[3], 1)
|
||||
int casemul_be = !memcmp(buf, "CAFS", 4);
|
||||
if (casemul_be || !memcmp(buf, "ACFS", 4)) {
|
||||
if (expected_types && !(expected_types & g1m_type_mcs))
|
||||
|
|
|
@ -99,19 +99,19 @@ int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
|
|||
/* look for the raw type */
|
||||
g1m_maketype_mcs(head, (char*)groupname, (char*)dirname,
|
||||
(char*)filename, raw_type);
|
||||
head->size = filesize;
|
||||
log_info("libg1m file type is 0x%08" PRIXMCSTYPE, head->type);
|
||||
head->g1m_mcshead_size = filesize;
|
||||
log_info("libg1m file type is 0x%08" PRIXMCSTYPE, head->g1m_mcshead_type);
|
||||
#if LOGLEVEL <= ll_info
|
||||
if (g1m_mcshead_uses_id(head)) {
|
||||
log_info("libg1m file id is (%d, %d)", g1m_get_id_major(head->id),
|
||||
g1m_get_id_minor(head->id));
|
||||
log_info("libg1m file id is (%d, %d)",
|
||||
g1m_get_id_major(head->g1m_mcshead_id),
|
||||
g1m_get_id_minor(head->g1m_mcshead_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* everything went well! */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* File decoding functions */
|
||||
/* ************************************************************************** */
|
||||
|
@ -138,18 +138,19 @@ int g1m_decode_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *head,
|
|||
g1m_mcshead_t h = *head;
|
||||
|
||||
/* look for the decoding function */
|
||||
mcs_decode_func_t decode = lookup_mcsfile_decode(head->type);
|
||||
mcs_decode_func_t decode = lookup_mcsfile_decode(head->g1m_mcshead_type);
|
||||
if (!decode) {
|
||||
log_error("No dedicated decoding function for this type was found!");
|
||||
goto notparsing;
|
||||
}
|
||||
|
||||
/* decode */
|
||||
if (!head->size) err = (*decode)(handle, buffer, &h);
|
||||
if (!head->g1m_mcshead_size) err = (*decode)(handle, buffer, &h);
|
||||
else {
|
||||
g1m_buffer_t lbuf = LIMBUFFER(buffer, head->size);
|
||||
g1m_buffer_t lbuf = LIMBUFFER(buffer, head->g1m_mcshead_size);
|
||||
err = (*decode)(handle, &lbuf, &h);
|
||||
if (lbuf._offset < head->size) SKIP(head->size - lbuf._offset)
|
||||
if (lbuf.g1m_buffer_offset < head->g1m_mcshead_size)
|
||||
SKIP(head->g1m_mcshead_size - lbuf.g1m_buffer_offset)
|
||||
}
|
||||
|
||||
/* oh yeah, and go away. */
|
||||
|
@ -162,11 +163,11 @@ notparsing:
|
|||
return (err);
|
||||
|
||||
/* read the content */
|
||||
GREAD((*handle)->content, h.size)
|
||||
GREAD((*handle)->g1m_mcsfile_content, h.g1m_mcshead_size)
|
||||
|
||||
/* log */
|
||||
log_info("File content:");
|
||||
logm_info((*handle)->content, h.size);
|
||||
logm_info((*handle)->g1m_mcsfile_content, h.g1m_mcshead_size);
|
||||
|
||||
/* saved normally */
|
||||
return (0);
|
||||
|
|
|
@ -39,36 +39,37 @@ int g1m_decode_mcs_cells(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
|
||||
/* log info */
|
||||
uint_fast32_t w = be16toh(hd.width),
|
||||
h = (head->type & g1m_mcstype_list) ? 1 : be16toh(hd.height);
|
||||
h = (head->g1m_mcshead_type & g1m_mcstype_list)
|
||||
? 1 : be16toh(hd.height);
|
||||
log_info("Matrix size is %" PRIuFAST32 "*%" PRIuFAST32, w, h);
|
||||
|
||||
/* make final head */
|
||||
head->width = w;
|
||||
head->height = h;
|
||||
head->g1m_mcshead_width = w;
|
||||
head->g1m_mcshead_height = h;
|
||||
if ((err = g1m_make_mcsfile(handle, head)))
|
||||
return (err);
|
||||
|
||||
/* main copying loop */
|
||||
g1m_mcscell_t **tab = (*handle)->cells; int one_imgn = 0;
|
||||
g1m_mcscell_t **tab = (*handle)->g1m_mcsfile_cells; int one_imgn = 0;
|
||||
for (y = 0; y < h; y++) for (x = 0; x < w; x++) {
|
||||
/* read the cell */
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, g1m_mcsbcd_s)
|
||||
one_imgn |= g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
|
||||
/* store it */
|
||||
tab[y][x] = (g1m_mcscell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.flags = g1m_mcscellflag_used
|
||||
.g1m_mcscell_real = bcd,
|
||||
.g1m_mcscell_imgn = {},
|
||||
.g1m_mcscell_flags = g1m_mcscellflag_used
|
||||
};
|
||||
}
|
||||
|
||||
/* check imaginary parts */
|
||||
if (one_imgn) for (y = 0; y < h; y++) for (x = 0; x < w; x++) {
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
if (g1m_bcd_has_special(&tab[y][x].real)) {
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, g1m_mcsbcd_s)
|
||||
if (g1m_bcd_has_special(&tab[y][x].g1m_mcscell_real)) {
|
||||
g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
tab[y][x].imgn = bcd;
|
||||
tab[y][x].g1m_mcscell_imgn = bcd;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,12 +77,12 @@ int g1m_decode_mcs_cells(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
/* logging loop */
|
||||
char rbuf[G1M_BCD_GOODBUFSIZE], ibuf[G1M_BCD_GOODBUFSIZE];
|
||||
for (y = 0; y < h; y++) for (x = 0; x < w; x++) {
|
||||
g1m_bcdtoa(&tab[y][x].real, rbuf, G1M_BCD_GOODBUFSIZE);
|
||||
g1m_bcdtoa(&tab[y][x].g1m_mcscell_real, rbuf, G1M_BCD_GOODBUFSIZE);
|
||||
|
||||
if (g1m_bcd_has_special(&tab[y][x].real)) {
|
||||
g1m_bcd_t ibcd = tab[y][x].imgn;
|
||||
if (g1m_bcd_has_special(&tab[y][x].g1m_mcscell_real)) {
|
||||
g1m_bcd_t ibcd = tab[y][x].g1m_mcscell_imgn;
|
||||
int ch = g1m_bcd_is_negative(&ibcd) ? '-' : '+';
|
||||
ibcd.flags &= ~g1m_bcdflag_neg;
|
||||
ibcd.g1m_bcd_flags &= ~g1m_bcdflag_neg;
|
||||
|
||||
g1m_bcdtoa(&ibcd, ibuf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%" PRIuFAST32 "][%" PRIuFAST32 "] %s %c %si",
|
||||
|
|
|
@ -37,22 +37,25 @@ int g1m_decode_mcs_capture(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
hd.height = be16toh(hd.height);
|
||||
|
||||
/* make final head and file */
|
||||
head->width = hd.width;
|
||||
head->height = hd.height;
|
||||
head->g1m_mcshead_width = hd.width;
|
||||
head->g1m_mcshead_height = hd.height;
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
|
||||
/* print info */
|
||||
log_info("capture is %dx%d sized", h->head.width, h->head.height);
|
||||
log_info("capture is %dx%d sized", h->g1m_mcsfile_head.g1m_mcshead_width,
|
||||
h->g1m_mcsfile_head.g1m_mcshead_height);
|
||||
|
||||
/* read raw data */
|
||||
size_t pic_size = g1m_picturesize_1bit_packed(head->width, head->height);
|
||||
size_t pic_size = g1m_picturesize_1bit_packed(head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height);
|
||||
uint8_t pic_raw[pic_size]; READ(pic_raw, pic_size)
|
||||
|
||||
/* get the image and return */
|
||||
if ((err = g1m_decode_picture(h->pics[0], g1m_pictureformat_1bit_packed,
|
||||
pic_raw, head->width, head->height))) {
|
||||
if ((err = g1m_decode_picture(h->g1m_mcsfile_pics[0],
|
||||
g1m_pictureformat_1bit_packed, pic_raw,
|
||||
head->g1m_mcshead_width, head->g1m_mcshead_height))) {
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
|
@ -76,21 +79,24 @@ int g1m_decode_mcs_picture(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* make final head */
|
||||
head->width = 128;
|
||||
head->height = 64;
|
||||
head->g1m_mcshead_width = 128;
|
||||
head->g1m_mcshead_height = 64;
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
|
||||
/* get the images */
|
||||
size_t pic_size = g1m_picturesize_1bit_packed(head->width, head->height);
|
||||
size_t pic_size = g1m_picturesize_1bit_packed(head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height);
|
||||
uint8_t pics_raw[pic_size * 2]; READ(pics_raw, pic_size * 2)
|
||||
|
||||
/* decode the images */
|
||||
if ((err = g1m_decode_picture(h->pics[0], g1m_pictureformat_1bit_packed,
|
||||
pics_raw, head->width, head->height))
|
||||
|| (err = g1m_decode_picture(h->pics[1], g1m_pictureformat_1bit_packed,
|
||||
&pics_raw[pic_size], head->width, head->height))) {
|
||||
if ((err = g1m_decode_picture(h->g1m_mcsfile_pics[0],
|
||||
g1m_pictureformat_1bit_packed, pics_raw, head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height))
|
||||
|| (err = g1m_decode_picture(h->g1m_mcsfile_pics[1],
|
||||
g1m_pictureformat_1bit_packed, &pics_raw[pic_size],
|
||||
head->g1m_mcshead_width, head->g1m_mcshead_height))) {
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
|
|
|
@ -38,18 +38,19 @@ int g1m_decode_mcs_program(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
log_info("Program password is '%.8s'.", hd.password);
|
||||
|
||||
/* make final head and file */
|
||||
strncpy(head->password, (char*)hd.password, 8);
|
||||
head->password[8] = 0;
|
||||
head->size -= sizeof(struct mcs_programheader);
|
||||
head->size += 1; /* terminating zero - XXX: keep it? */
|
||||
strncpy(head->g1m_mcshead_password, (char*)hd.password, 8);
|
||||
head->g1m_mcshead_password[8] = 0;
|
||||
head->g1m_mcshead_size -= sizeof(struct mcs_programheader);
|
||||
head->g1m_mcshead_size += 1; /* terminating zero - XXX: keep it? */
|
||||
err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* get content */
|
||||
g1m_mcsfile_t *h = *handle; size_t content_size = head->size - 1;
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
size_t content_size = head->g1m_mcshead_size - 1;
|
||||
log_info("Getting program content (%" PRIuSIZE "o)", content_size);
|
||||
GREAD(h->content, content_size);
|
||||
h->content[content_size] = 0;
|
||||
GREAD(h->g1m_mcsfile_content, content_size);
|
||||
h->g1m_mcsfile_content[content_size] = 0;
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
|
|
@ -32,26 +32,26 @@ int g1m_decode_mcs_setup(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* read content */
|
||||
uint8_t content[head->size];
|
||||
READ(content, head->size)
|
||||
uint8_t content[head->g1m_mcshead_size];
|
||||
READ(content, head->g1m_mcshead_size)
|
||||
|
||||
/* make final head and file */
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
g1m_setup_t *sp = &(*handle)->setup;
|
||||
g1m_setup_t *sp = &(*handle)->g1m_mcsfile_setup;
|
||||
|
||||
/* get input flags */
|
||||
switch (content[0x14]) {
|
||||
case 0x84: sp->iflags |= g1m_setupiflag_alpha;
|
||||
case 0x01: sp->iflags |= g1m_setupiflag_shift; break;
|
||||
case 0x04: sp->iflags |= g1m_setupiflag_alpha; break; }
|
||||
if (content[0x15] == 0x02) sp->iflags |= g1m_setupiflag_insert;
|
||||
if (!content[0x53]) sp->iflags |= g1m_setupiflag_math;
|
||||
case 0x84: sp->g1m_setup_iflags |= g1m_setupiflag_alpha;
|
||||
case 0x01: sp->g1m_setup_iflags |= g1m_setupiflag_shift; break;
|
||||
case 0x04: sp->g1m_setup_iflags |= g1m_setupiflag_alpha; break; }
|
||||
if (content[0x15] == 0x02) sp->g1m_setup_iflags |= g1m_setupiflag_insert;
|
||||
if (content[0x53] == 0x00) sp->g1m_setup_iflags |= g1m_setupiflag_math;
|
||||
|
||||
/* get window flags */
|
||||
if (content[0x1C]) sp->wflags |= g1m_setupwflag_grid;
|
||||
if (content[0x1D]) sp->wflags |= g1m_setupwflag_axes;
|
||||
if (content[0x19]) sp->wflags |= g1m_setupwflag_plot;
|
||||
if (content[0x1C]) sp->g1m_setup_wflags |= g1m_setupwflag_grid;
|
||||
if (content[0x1D]) sp->g1m_setup_wflags |= g1m_setupwflag_axes;
|
||||
if (content[0x19]) sp->g1m_setup_wflags |= g1m_setupwflag_plot;
|
||||
|
||||
/* TODO: decode more options! */
|
||||
/* no error! */
|
||||
|
|
|
@ -77,14 +77,14 @@ int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
if (*rd & bit) {
|
||||
/* get cell */
|
||||
g1m_bcd_t cell;
|
||||
DREAD(rawcell, bcd)
|
||||
DREAD(rawcell, g1m_mcsbcd_s)
|
||||
g1m_bcd_frommcs(&rawcell, &cell);
|
||||
|
||||
/* store it */
|
||||
cells[c * 1000 + i] = (g1m_mcscell_t){
|
||||
.real = cell,
|
||||
.imgn = (g1m_bcd_t){},
|
||||
.flags = g1m_mcscellflag_used
|
||||
.g1m_mcscell_real = cell,
|
||||
.g1m_mcscell_imgn = (g1m_bcd_t){},
|
||||
.g1m_mcscell_flags = g1m_mcscellflag_used
|
||||
};
|
||||
|
||||
/* check things (max row, max col, cells count) */
|
||||
|
@ -104,15 +104,18 @@ int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
rows++, cols++;
|
||||
|
||||
/* create final tab */
|
||||
head->width = 0; head->height = 0;
|
||||
if (cells_count) { head->width = cols; head->height = rows; }
|
||||
head->g1m_mcshead_width = 0; head->g1m_mcshead_height = 0;
|
||||
if (cells_count) {
|
||||
head->g1m_mcshead_width = cols;
|
||||
head->g1m_mcshead_height = rows;
|
||||
}
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* main copying loop */
|
||||
g1m_mcscell_t **tab = (*handle)->cells;
|
||||
for (uint_fast32_t y = 0; y < head->height; y++)
|
||||
for (uint_fast32_t x = 0; x < head->width; x++)
|
||||
g1m_mcscell_t **tab = (*handle)->g1m_mcsfile_cells;
|
||||
for (uint_fast32_t y = 0; y < head->g1m_mcshead_height; y++)
|
||||
for (uint_fast32_t x = 0; x < head->g1m_mcshead_width; x++)
|
||||
tab[y][x] = cells[x * 1000 + y];
|
||||
|
||||
/* no error */
|
||||
|
|
|
@ -35,7 +35,7 @@ int g1m_decode_mcs_string(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
|
||||
/* print content */
|
||||
log_info("String MCS file is not managed yet. Content:");
|
||||
uint_fast32_t length = head->size;
|
||||
uint_fast32_t length = head->g1m_mcshead_size;
|
||||
uint8_t str[length]; READ(str, length);
|
||||
logm_info(str, length);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
int g1m_decode_mcs_var(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
uint_fast32_t length = head->size;
|
||||
uint_fast32_t length = head->g1m_mcshead_size;
|
||||
uint8_t *buf = alloca(length);
|
||||
int i;
|
||||
|
||||
|
@ -39,17 +39,17 @@ int g1m_decode_mcs_var(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
|||
READ(buf, length)
|
||||
|
||||
/* complete header */
|
||||
head->count = length / (2 * sizeof(mcs_bcd_t));
|
||||
head->g1m_mcshead_count = length / (2 * sizeof(g1m_mcsbcd_t));
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
|
||||
/* copy */
|
||||
const mcs_bcd_t *b = (void*)buf;
|
||||
for (i = 0; i < head->count; i++) {
|
||||
g1m_bcd_frommcs(b++, &h->vars[i].real);
|
||||
g1m_bcd_frommcs(b++, &h->vars[i].imgn);
|
||||
h->vars[i].flags = g1m_mcscellflag_used;
|
||||
const g1m_mcsbcd_t *b = (void*)buf;
|
||||
for (i = 0; i < head->g1m_mcshead_count; i++) {
|
||||
g1m_bcd_frommcs(b++, &h->g1m_mcsfile_vars[i].g1m_mcscell_real);
|
||||
g1m_bcd_frommcs(b++, &h->g1m_mcsfile_vars[i].g1m_mcscell_imgn);
|
||||
h->g1m_mcsfile_vars[i].g1m_mcscell_flags = g1m_mcscellflag_used;
|
||||
}
|
||||
|
||||
/* no problem, woop woop */
|
||||
|
|
|
@ -52,21 +52,25 @@ int g1m_decode_std_addin(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
g1m_handle_t *handle = *h;
|
||||
|
||||
/* log info about the subheader */
|
||||
log_info("title is '%s'", handle->title);
|
||||
log_info("internal name is '%s'", handle->intname);
|
||||
log_info("title is '%s'", handle->g1m_handle_title);
|
||||
log_info("internal name is '%s'", handle->g1m_handle_intname);
|
||||
log_info("estrips count is %" PRIu8, hd.estrips_count);
|
||||
log_info("version is %02u.%02u.%04u", handle->version.major,
|
||||
handle->version.minor, handle->version.revision);
|
||||
log_info("creation date is: %.24s", ctime(&handle->creation_date));
|
||||
log_info("version is %02u.%02u",
|
||||
handle->g1m_handle_version.g1m_version_major,
|
||||
handle->g1m_handle_version.g1m_version_minor);
|
||||
log_info("creation date is: %.24s",
|
||||
ctime(&handle->g1m_handle_creation_date));
|
||||
|
||||
/* fill icon */
|
||||
g1m_decode_picture(handle->icon_unsel, g1m_pictureformat_1bit,
|
||||
hd.icon, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->icon_sel, g1m_pictureformat_1bit_r,
|
||||
hd.icon, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_unsel,
|
||||
g1m_pictureformat_1bit, hd.icon,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_sel,
|
||||
g1m_pictureformat_1bit_r, hd.icon,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
|
||||
/* read content */
|
||||
GREAD(handle->content, handle->size)
|
||||
GREAD(handle->g1m_handle_content, handle->g1m_handle_size)
|
||||
|
||||
/* no errors */
|
||||
return (err);
|
||||
|
@ -112,21 +116,25 @@ int g1m_decode_std_cp_addin(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
g1m_handle_t *handle = *h;
|
||||
|
||||
/* decode pictures */
|
||||
g1m_decode_picture(handle->icon_unsel, g1m_pictureformat_1bit_packed,
|
||||
cphd.icon, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->icon_sel, g1m_pictureformat_1bit_packed_r,
|
||||
cphd.icon, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_unsel,
|
||||
g1m_pictureformat_1bit_packed, cphd.icon,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_sel,
|
||||
g1m_pictureformat_1bit_packed_r, cphd.icon,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
|
||||
/* log */
|
||||
log_info("title is '%s'", handle->title);
|
||||
log_info("internal name is '%s'", handle->intname);
|
||||
log_info("version is %02u.%02u.%04u", handle->version.major,
|
||||
handle->version.minor, handle->version.revision);
|
||||
log_info("timestamp is %.24s", ctime(&handle->creation_date));
|
||||
log_info("title is '%s'", handle->g1m_handle_title);
|
||||
log_info("internal name is '%s'", handle->g1m_handle_intname);
|
||||
log_info("version is %02u.%02u",
|
||||
handle->g1m_handle_version.g1m_version_major,
|
||||
handle->g1m_handle_version.g1m_version_minor);
|
||||
log_info("timestamp is %.24s", ctime(&handle->g1m_handle_creation_date));
|
||||
|
||||
/* get content */
|
||||
GREAD(handle->content, handle->size)
|
||||
*check = g1m_checksum32(handle->content, handle->size, *check);
|
||||
GREAD(handle->g1m_handle_content, handle->g1m_handle_size)
|
||||
*check = g1m_checksum32(handle->g1m_handle_content,
|
||||
handle->g1m_handle_size, *check);
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
@ -177,21 +185,25 @@ int g1m_decode_std_cg_addin(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
g1m_handle_t *handle = *h;
|
||||
|
||||
/* decode pictures */
|
||||
g1m_decode_picture(handle->icon_unsel, g1m_pictureformat_16bit,
|
||||
cghd.unselected_icon_image, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->icon_sel, g1m_pictureformat_16bit,
|
||||
cghd.selected_icon_image, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_unsel,
|
||||
g1m_pictureformat_16bit, cghd.unselected_icon_image,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
g1m_decode_picture(handle->g1m_handle_icon_sel,
|
||||
g1m_pictureformat_16bit, cghd.selected_icon_image,
|
||||
handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
|
||||
/* log */
|
||||
log_info("title is '%s'", handle->title);
|
||||
log_info("internal name is '%s'", handle->intname);
|
||||
log_info("version is %02u.%02u.%04u", handle->version.major,
|
||||
handle->version.minor, handle->version.revision);
|
||||
log_info("timestamp is %.24s", ctime(&handle->creation_date));
|
||||
log_info("title is '%s'", handle->g1m_handle_title);
|
||||
log_info("internal name is '%s'", handle->g1m_handle_intname);
|
||||
log_info("version is %02u.%02u",
|
||||
handle->g1m_handle_version.g1m_version_major,
|
||||
handle->g1m_handle_version.g1m_version_minor);
|
||||
log_info("timestamp is %.24s", ctime(&handle->g1m_handle_creation_date));
|
||||
|
||||
/* read content */
|
||||
GREAD(handle->content, handle->size)
|
||||
*check = g1m_checksum32(handle->content, handle->size, *check);
|
||||
GREAD(handle->g1m_handle_content, handle->g1m_handle_size)
|
||||
*check = g1m_checksum32(handle->g1m_handle_content,
|
||||
handle->g1m_handle_size, *check);
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
|
|
@ -42,10 +42,10 @@ static int eact_decode_content_eact(g1m_line_t *handle, uint8_t *buf,
|
|||
unsigned long int i;
|
||||
|
||||
/* initialize the handle */
|
||||
handle->type = g1m_linetype_eact;
|
||||
handle->count = 0;
|
||||
handle->_size = 0;
|
||||
handle->lines = NULL;
|
||||
handle->g1m_line_type = g1m_linetype_eact;
|
||||
handle->g1m_line_count = 0;
|
||||
handle->g1m_line__size = 0;
|
||||
handle->g1m_line_lines = NULL;
|
||||
|
||||
/* check if the buffer is non-empty */
|
||||
if (!bufsize) return (0);
|
||||
|
@ -67,11 +67,12 @@ static int eact_decode_content_eact(g1m_line_t *handle, uint8_t *buf,
|
|||
struct line_descriptor *lds = (void*)&buf[sizeof(struct eact_eactheader)];
|
||||
|
||||
/* prepare the handle */
|
||||
handle->count = 0;
|
||||
handle->_size = ehd.line_count;
|
||||
handle->lines = malloc(sizeof(g1m_line_t*) * handle->_size);
|
||||
if (!handle->lines) return (g1m_error_alloc);
|
||||
bzero(handle->lines, sizeof(g1m_line_t*) * handle->_size);
|
||||
handle->g1m_line_count = 0;
|
||||
handle->g1m_line__size = ehd.line_count;
|
||||
handle->g1m_line_lines =
|
||||
malloc(sizeof(g1m_line_t*) * handle->g1m_line__size);
|
||||
if (!handle->g1m_line_lines) return (g1m_error_alloc);
|
||||
bzero(handle->g1m_line_lines, sizeof(g1m_line_t*) * handle->g1m_line__size);
|
||||
|
||||
/* browse the lines */
|
||||
log_info("%" PRIu32 " lines to browse", ehd.line_count);
|
||||
|
@ -111,7 +112,7 @@ static int eact_decode_content_eact(g1m_line_t *handle, uint8_t *buf,
|
|||
if (err) goto loop_fail;
|
||||
|
||||
/* store and continue */
|
||||
handle->lines[handle->count++] = line;
|
||||
handle->g1m_line_lines[handle->g1m_line_count++] = line;
|
||||
continue;
|
||||
|
||||
loop_fail:
|
||||
|
@ -166,13 +167,13 @@ static int eact_decode_line_content(g1m_line_t *handle, uint8_t *buf,
|
|||
memcpy(&hd, buf, could_read);
|
||||
|
||||
/* store info */
|
||||
bzero(handle->name, 17);
|
||||
bzero(handle->g1m_line_name, 17);
|
||||
size_t namesize = max(could_read - 8, 16);
|
||||
strncpy(handle->name, (char*)hd.name, namesize);
|
||||
strncpy(handle->g1m_line_name, (char*)hd.name, namesize);
|
||||
|
||||
/* log info */
|
||||
log_info("Type is '%.8s'", hd.type);
|
||||
log_info("Name is '%s'", handle->name);
|
||||
log_info("Name is '%s'", handle->g1m_line_name);
|
||||
|
||||
/* prepare for next */
|
||||
buf += could_read;
|
||||
|
@ -264,9 +265,9 @@ static int eact_decode_line_stdheading(g1m_line_t *handle, uint8_t *buf,
|
|||
logm_info(buf, size);
|
||||
|
||||
/* set handle info */
|
||||
handle->type = g1m_linetype_text;
|
||||
handle->content = strdup((char*)buf);
|
||||
if (!handle->content) return (g1m_error_alloc);
|
||||
handle->g1m_line_type = g1m_linetype_text;
|
||||
handle->g1m_line_content = strdup((char*)buf);
|
||||
if (!handle->g1m_line_content) return (g1m_error_alloc);
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
@ -301,12 +302,12 @@ static int eact_decode_line_picture(g1m_line_t *handle, uint8_t *buf,
|
|||
if (sz == (size_t)-1) return (g1m_error_magic);
|
||||
|
||||
/* make the string */
|
||||
handle->content = malloc(sizeof(FONTCHARACTER) * (sz + 1));
|
||||
if (!handle->content) return (g1m_error_alloc);
|
||||
g1m_wcstombs(handle->content, s, 0);
|
||||
handle->g1m_line_content = malloc(sizeof(FONTCHARACTER) * (sz + 1));
|
||||
if (!handle->g1m_line_content) return (g1m_error_alloc);
|
||||
g1m_wcstombs(handle->g1m_line_content, s, 0);
|
||||
|
||||
/* don't forget to set the handle type! */
|
||||
handle->type = g1m_linetype_picture;
|
||||
handle->g1m_line_type = g1m_linetype_picture;
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
@ -331,9 +332,9 @@ static int eact_decode_line_text(g1m_line_t *handle, uint8_t *buf, size_t size)
|
|||
logm_info(buf, size);
|
||||
|
||||
/* set handle info */
|
||||
handle->type = g1m_linetype_text;
|
||||
handle->content = strdup((char*)buf);
|
||||
if (!handle->content) return (g1m_error_alloc);
|
||||
handle->g1m_line_type = g1m_linetype_text;
|
||||
handle->g1m_line_content = strdup((char*)buf);
|
||||
if (!handle->g1m_line_content) return (g1m_error_alloc);
|
||||
|
||||
/* TODO: manage text coloration */
|
||||
/* no error */
|
||||
|
@ -406,7 +407,7 @@ static int eact_decode_line(g1m_line_t *handle, uint8_t *buf, size_t size,
|
|||
uint_fast8_t type)
|
||||
{
|
||||
/* initialize handle */
|
||||
handle->type = 0x00;
|
||||
handle->g1m_line_type = 0x00;
|
||||
|
||||
/* look for the line type */
|
||||
struct eact_line_type_corresp *linetype = eact_line_types;
|
||||
|
@ -467,10 +468,10 @@ int g1m_decode_std_eact(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
SKIP(hd.setup_area_size)
|
||||
|
||||
/* prepare the handle */
|
||||
handle->type = g1m_type_eact;
|
||||
handle->platform = g1m_platform_fx;
|
||||
handle->g1m_handle_type = g1m_type_eact;
|
||||
handle->g1m_handle_platform = g1m_platform_fx;
|
||||
if (hd.eact_version == EACT_G3E) /* check if fx-CG */
|
||||
handle->platform = g1m_platform_cg;
|
||||
handle->g1m_handle_platform = g1m_platform_cg;
|
||||
|
||||
/* get content buffer */
|
||||
size_t bufsize = hd.filesize - sizeof(struct standard_header)
|
||||
|
@ -479,8 +480,8 @@ int g1m_decode_std_eact(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
GREAD(&buf, bufsize)
|
||||
|
||||
/* decode content */
|
||||
handle->line = &handle->_linedata;
|
||||
return (eact_decode_line_content(handle->line, buf, bufsize));
|
||||
handle->g1m_handle_line = &handle->g1m_handle__linedata;
|
||||
return (eact_decode_line_content(handle->g1m_handle_line, buf, bufsize));
|
||||
fail:
|
||||
g1m_free(*h); *h = NULL;
|
||||
return (err);
|
||||
|
|
|
@ -96,19 +96,20 @@ int g1m_decode_std_fkey(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
uint8_t *fkeys = (uint8_t*)(offsets + num);
|
||||
|
||||
/* read the function keys name */
|
||||
handle->title[16] = 0;
|
||||
strncpy(handle->title, (char*)fkeys, 16);
|
||||
handle->g1m_handle_title[16] = 0;
|
||||
strncpy(handle->g1m_handle_title, (char*)fkeys, 16);
|
||||
|
||||
/* read all */
|
||||
for (handle->count = 0; handle->count < (int)num; handle->count++) {
|
||||
int i = handle->count;
|
||||
for (handle->g1m_handle_count = 0; handle->g1m_handle_count < (int)num;
|
||||
handle->g1m_handle_count++) {
|
||||
int i = handle->g1m_handle_count;
|
||||
if (offsets[i] == (uint16_t)-1)
|
||||
continue ;
|
||||
offsets[i] = be16toh(offsets[i]);
|
||||
|
||||
/* store */
|
||||
handle->fkeys[i] = fkeydup(&fkeys[i]);
|
||||
if (!handle->fkeys[i]) goto fail;
|
||||
handle->g1m_handle_fkeys[i] = fkeydup(&fkeys[i]);
|
||||
if (!handle->g1m_handle_fkeys[i]) goto fail;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
@ -166,8 +167,9 @@ int g1m_decode_std_cg_fkey(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
uint8_t *messages = (uint8_t*)&offsets[num + 1];
|
||||
|
||||
/* read messages */
|
||||
for (handle->count = 0; handle->count < (int)num; handle->count++) {
|
||||
int i = handle->count;
|
||||
for (handle->g1m_handle_count = 0; handle->g1m_handle_count < (int)num;
|
||||
handle->g1m_handle_count++) {
|
||||
int i = handle->g1m_handle_count;
|
||||
if (offsets[i] == (uint32_t)-1) {
|
||||
log_info("[#%d] -", i);
|
||||
continue;
|
||||
|
@ -179,8 +181,8 @@ int g1m_decode_std_cg_fkey(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
&messages[offsets[i]], offsets[i]);
|
||||
|
||||
/* store */
|
||||
handle->fkeys[i] = fkeydup3((void*)&messages[offsets[i]]);
|
||||
if (!handle->fkeys[i]) goto fail;
|
||||
handle->g1m_handle_fkeys[i] = fkeydup3((void*)&messages[offsets[i]]);
|
||||
if (!handle->g1m_handle_fkeys[i]) goto fail;
|
||||
}
|
||||
|
||||
/* done */
|
||||
|
|
|
@ -58,8 +58,9 @@ int g1m_decode_std_lang(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
char *messages = (char*)(offsets + num);
|
||||
|
||||
/* read messages */
|
||||
for (handle->count = 0; handle->count < (int)num; handle->count++) {
|
||||
int i = handle->count;
|
||||
for (handle->g1m_handle_count = 0; handle->g1m_handle_count < (int)num;
|
||||
handle->g1m_handle_count++) {
|
||||
int i = handle->g1m_handle_count;
|
||||
if (offsets[i] == (uint16_t)-1) {
|
||||
log_info("[#%d] -", i);
|
||||
continue;
|
||||
|
@ -71,9 +72,9 @@ int g1m_decode_std_lang(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
&messages[offsets[i]], offsets[i]);
|
||||
|
||||
/* store */
|
||||
handle->messages[i] = strdup(&messages[offsets[i]]);
|
||||
if (!handle->messages[i]) goto fail;
|
||||
handle->count++;
|
||||
handle->g1m_handle_messages[i] = strdup(&messages[offsets[i]]);
|
||||
if (!handle->g1m_handle_messages[i]) goto fail;
|
||||
handle->g1m_handle_count++;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
@ -131,8 +132,9 @@ int g1m_decode_std_cg_lang(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
uint8_t *messages = (uint8_t*)&offsets[num + 1];
|
||||
|
||||
/* read messages */
|
||||
for (handle->count = 0; handle->count < (int)num; handle->count++) {
|
||||
int i = handle->count;
|
||||
for (handle->g1m_handle_count = 0; handle->g1m_handle_count < (int)num;
|
||||
handle->g1m_handle_count++) {
|
||||
int i = handle->g1m_handle_count;
|
||||
if (offsets[i] == (uint32_t)-1) {
|
||||
log_info("[#%d] -", i);
|
||||
continue;
|
||||
|
@ -144,8 +146,8 @@ int g1m_decode_std_cg_lang(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
&messages[offsets[i]], offsets[i]);
|
||||
|
||||
/* store */
|
||||
handle->messages[i] = strdup((char*)&messages[offsets[i]]);
|
||||
if (!handle->messages[i]) goto fail;
|
||||
handle->g1m_handle_messages[i] = strdup((char*)&messages[offsets[i]]);
|
||||
if (!handle->g1m_handle_messages[i]) goto fail;
|
||||
}
|
||||
|
||||
/* done */
|
||||
|
|
|
@ -44,7 +44,7 @@ int g1m_decode_std_mcs(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
|
||||
/* read all of the parts */
|
||||
log_info("%" PRIuFAST16 " total mcs files to browse", num);
|
||||
for (handle->count = 0; handle->count < (int)num;) {
|
||||
for (handle->g1m_handle_count = 0; handle->g1m_handle_count < (int)num;) {
|
||||
/* get the subheader */
|
||||
GDREAD(hd, mcs_subheader)
|
||||
|
||||
|
@ -74,11 +74,12 @@ int g1m_decode_std_mcs(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
fhd.dirname, fhd.filename, fhd.datalength);
|
||||
|
||||
/* decode */
|
||||
handle->files[handle->count] = NULL;
|
||||
err = g1m_decode_mcsfile(&handle->files[handle->count],
|
||||
handle->g1m_handle_files[handle->g1m_handle_count] = NULL;
|
||||
err = g1m_decode_mcsfile(
|
||||
&handle->g1m_handle_files[handle->g1m_handle_count],
|
||||
&head, buffer);
|
||||
if (err) goto fail;
|
||||
handle->count++;
|
||||
handle->g1m_handle_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,8 +126,8 @@ int g1m_decode_std_g3p(g1m_handle_t **h, g1m_buffer_t *buffer,
|
|||
g1m_handle_t *handle = *h;
|
||||
|
||||
/* then store it */
|
||||
g1m_decode_picture(handle->pixels, picfmt,
|
||||
infbuf, handle->width, handle->height);
|
||||
g1m_decode_picture(handle->g1m_handle_pixels, picfmt,
|
||||
infbuf, handle->g1m_handle_width, handle->g1m_handle_height);
|
||||
free(infbuf); infbuf = NULL;
|
||||
|
||||
/* TODO: footers? */
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
int g1m_announce_addin(g1m_handle_t *handle, size_t *size)
|
||||
{
|
||||
*size += sizeof(struct standard_header) + sizeof(struct g1a_subheader);
|
||||
*size += handle->size;
|
||||
*size += handle->g1m_handle_size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -67,17 +67,18 @@ int g1m_encode_addin(g1m_handle_t *handle, g1m_buffer_t *buffer)
|
|||
struct g1a_subheader sub = {
|
||||
.estrips_count = 0,
|
||||
.filesize = htobe32(filesize)};
|
||||
strncpy((char*)sub.title, handle->title, 8);
|
||||
strncpy((char*)sub.internal_name, handle->intname, 8);
|
||||
g1m_encode_version(&handle->version, (char*)sub.version);
|
||||
g1m_encode_date(&handle->creation_date, (char*)sub.creation_date);
|
||||
g1m_encode_picture((const uint32_t**)handle->icon_unsel,
|
||||
strncpy((char*)sub.title, handle->g1m_handle_title, 8);
|
||||
strncpy((char*)sub.internal_name, handle->g1m_handle_intname, 8);
|
||||
g1m_encode_version(&handle->g1m_handle_version, (char*)sub.version);
|
||||
g1m_encode_date(&handle->g1m_handle_creation_date,
|
||||
(char*)sub.creation_date);
|
||||
g1m_encode_picture((const uint32_t**)handle->g1m_handle_icon_unsel,
|
||||
g1m_pictureformat_1bit, sub.icon,
|
||||
G1A_ICON_WIDTH, G1A_ICON_HEIGHT);
|
||||
DWRITE(sub)
|
||||
|
||||
/* output the content */
|
||||
WRITE(handle->content, handle->size)
|
||||
WRITE(handle->g1m_handle_content, handle->g1m_handle_size)
|
||||
|
||||
/* no error! */
|
||||
return (0);
|
||||
|
|
|
@ -62,28 +62,28 @@ int g1m_encode(g1m_handle_t *handle, g1m_buffer_t *buffer)
|
|||
/* find the announcement and encoding function */
|
||||
const struct corresp *c = encodings - 1;
|
||||
while ((++c)->encode) {
|
||||
if (c->types && !(c->types & handle->type))
|
||||
if (c->types && !(c->types & handle->g1m_handle_type))
|
||||
continue;
|
||||
if (c->platforms && !(c->platforms & handle->platform))
|
||||
if (c->platforms && !(c->platforms & handle->g1m_handle_platform))
|
||||
continue;
|
||||
break;
|
||||
} if (!c->encode) return (g1m_error_op);
|
||||
|
||||
/* announce, if necessary */
|
||||
if (buffer->announce) {
|
||||
if (buffer->g1m_buffer_announce) {
|
||||
size_t size = 0;
|
||||
if ((err = (*c->announce)(handle, &size))
|
||||
|| (err = (*buffer->announce)(buffer->cookie, size)))
|
||||
|| (err = (*buffer->g1m_buffer_announce)(buffer->g1m_buffer_cookie,
|
||||
size)))
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* encode */
|
||||
if (buffer->write) {
|
||||
if (buffer->g1m_buffer_write) {
|
||||
err = (*c->encode)(handle, buffer);
|
||||
if (err && buffer->unannounce) {
|
||||
(*buffer->unannounce)(buffer->cookie);
|
||||
return (err);
|
||||
}
|
||||
if (err && buffer->g1m_buffer_unannounce)
|
||||
(*buffer->g1m_buffer_unannounce)(buffer->g1m_buffer_cookie);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* everything went well! */
|
||||
|
|
|
@ -57,7 +57,7 @@ static const struct corresp encodings[] = {
|
|||
|
||||
static int default_announce(const g1m_mcsfile_t *handle, size_t *sz)
|
||||
{
|
||||
*sz += handle->head.size;
|
||||
*sz += handle->g1m_mcsfile_head.g1m_mcshead_size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,8 @@ static int default_announce(const g1m_mcsfile_t *handle, size_t *sz)
|
|||
|
||||
static int default_encode(const g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
||||
{
|
||||
WRITE(handle->content, handle->head.size)
|
||||
WRITE(handle->g1m_mcsfile_content,
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -99,25 +100,27 @@ int g1m_encode_mcsfile(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
if (!c->types) c = &default_corresp;
|
||||
else {
|
||||
while ((++c)->encode) {
|
||||
if (c->types && !(c->types & handle->head.type))
|
||||
if (c->types && !(c->types & handle->g1m_mcsfile_head
|
||||
.g1m_mcshead_type))
|
||||
continue;
|
||||
break;
|
||||
} if (!c->encode) return (g1m_error_op);
|
||||
}
|
||||
|
||||
/* announce if necessary */
|
||||
if (buffer->announce) {
|
||||
if (buffer->g1m_buffer_announce) {
|
||||
size_t size = 0;
|
||||
if ((err = (*c->announce)(handle, &size))
|
||||
|| (err = (*buffer->announce)(buffer->cookie, size)))
|
||||
|| (err = (*buffer->g1m_buffer_announce)(buffer->g1m_buffer_cookie,
|
||||
size)))
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* encode */
|
||||
if (buffer->write) {
|
||||
if (buffer->g1m_buffer_write) {
|
||||
err = (*c->encode)(handle, buffer);
|
||||
if (err && buffer->unannounce) {
|
||||
(*buffer->unannounce)(buffer->cookie);
|
||||
if (err && buffer->g1m_buffer_unannounce) {
|
||||
(*buffer->g1m_buffer_unannounce)(buffer->g1m_buffer_cookie);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,14 +30,15 @@
|
|||
int g1m_announce_mcs_cells(const g1m_mcsfile_t *handle, size_t *sz)
|
||||
{
|
||||
unsigned int y, x;
|
||||
size_t content_size = handle->head.height * handle->head.width
|
||||
* sizeof(mcs_bcd_t);
|
||||
size_t content_size = handle->g1m_mcsfile_head.g1m_mcshead_height
|
||||
* handle->g1m_mcsfile_head.g1m_mcshead_width * sizeof(g1m_mcsbcd_t);
|
||||
*sz += sizeof(struct mcs_cellsheader) + content_size;
|
||||
|
||||
/* check if there's an imaginary part */
|
||||
for (y = 0; y < handle->head.height; y++)
|
||||
for (x = 0; x < handle->head.width; x++) {
|
||||
if (g1m_bcd_has_special(&handle->cells[y][x].real)) {
|
||||
for (y = 0; y < handle->g1m_mcsfile_head.g1m_mcshead_height; y++)
|
||||
for (x = 0; x < handle->g1m_mcsfile_head.g1m_mcshead_width; x++) {
|
||||
if (g1m_bcd_has_special(&handle->g1m_mcsfile_cells[y][x]
|
||||
.g1m_mcscell_real)) {
|
||||
*sz += content_size;
|
||||
return (0);
|
||||
}
|
||||
|
@ -60,9 +61,9 @@ int g1m_encode_mcs_cells(const g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
{
|
||||
unsigned int y, x;
|
||||
struct mcs_cellsheader hd = {
|
||||
.height = htobe16(handle->head.height),
|
||||
.width = (handle->head.type & g1m_mcstype_list) ? 1
|
||||
: htobe16(handle->head.width),
|
||||
.height = htobe16(handle->g1m_mcsfile_head.g1m_mcshead_height),
|
||||
.width = (handle->g1m_mcsfile_head.g1m_mcshead_type & g1m_mcstype_list)
|
||||
? 1 : htobe16(handle->g1m_mcsfile_head.g1m_mcshead_width),
|
||||
._undocumented = {0}};
|
||||
|
||||
/* write the header */
|
||||
|
@ -70,18 +71,23 @@ int g1m_encode_mcs_cells(const g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
|
||||
/* write the real parts */
|
||||
int one_imgn = 0;
|
||||
for (y = 0; y < handle->head.height; y++)
|
||||
for (x = 0; x < handle->head.width; x++) {
|
||||
mcs_bcd_t rawbcd; g1m_bcd_tomcs(&handle->cells[y][x].real, &rawbcd);
|
||||
for (y = 0; y < handle->g1m_mcsfile_head.g1m_mcshead_height; y++)
|
||||
for (x = 0; x < handle->g1m_mcsfile_head.g1m_mcshead_width; x++) {
|
||||
g1m_mcsbcd_t rawbcd; g1m_bcd_tomcs(&handle->g1m_mcsfile_cells[y][x]
|
||||
.g1m_mcscell_real, &rawbcd);
|
||||
DWRITE(rawbcd)
|
||||
|
||||
one_imgn |= g1m_bcd_has_special(&handle->cells[y][x].real);
|
||||
one_imgn |= g1m_bcd_has_special(&handle->g1m_mcsfile_cells[y][x]
|
||||
.g1m_mcscell_real);
|
||||
}
|
||||
|
||||
/* write the imaginary parts */
|
||||
if (one_imgn) for (y = 0; y < handle->head.height; y++)
|
||||
for (x = 0; x < handle->head.width; x++) {
|
||||
mcs_bcd_t rawbcd; g1m_bcd_tomcs(&handle->cells[y][x].imgn, &rawbcd);
|
||||
if (one_imgn)
|
||||
for (y = 0; y < handle->g1m_mcsfile_head.g1m_mcshead_height; y++)
|
||||
for (x = 0; x < handle->g1m_mcsfile_head.g1m_mcshead_width; x++) {
|
||||
g1m_mcsbcd_t rawbcd;
|
||||
g1m_bcd_tomcs(&handle->g1m_mcsfile_cells[y][x]
|
||||
.g1m_mcscell_imgn, &rawbcd);
|
||||
DWRITE(rawbcd)
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
int g1m_announce_mcs_program(const g1m_mcsfile_t *handle, size_t *sz)
|
||||
{
|
||||
*sz += sizeof(struct mcs_programheader) + handle->head.size;
|
||||
*sz += sizeof(struct mcs_programheader)
|
||||
+ handle->g1m_mcsfile_head.g1m_mcshead_size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -46,11 +47,13 @@ int g1m_encode_mcs_program(const g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
{
|
||||
/* write the header */
|
||||
struct mcs_programheader hd = {};
|
||||
memcpy(hd.password, handle->head.password, strlen(handle->head.password));
|
||||
memcpy(hd.password, handle->g1m_mcsfile_head.g1m_mcshead_password,
|
||||
strlen(handle->g1m_mcsfile_head.g1m_mcshead_password));
|
||||
DWRITE(hd)
|
||||
|
||||
/* write the program content */
|
||||
WRITE(handle->content, handle->head.size)
|
||||
WRITE(handle->g1m_mcsfile_content,
|
||||
handle->g1m_mcsfile_head.g1m_mcshead_size)
|
||||
|
||||
/* no error! */
|
||||
return (0);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
int g1m_announce_mcs_var(const g1m_mcsfile_t *handle, size_t *sz)
|
||||
{
|
||||
*sz += sizeof(mcs_bcd_t) * handle->head.count;
|
||||
*sz += sizeof(g1m_mcsbcd_t) * handle->g1m_mcsfile_head.g1m_mcshead_count;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -47,11 +47,13 @@ int g1m_encode_mcs_var(const g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
|
|||
int i;
|
||||
|
||||
/* encode each variable */
|
||||
for (i = 0; i < handle->head.count; i++) {
|
||||
for (i = 0; i < handle->g1m_mcsfile_head.g1m_mcshead_count; i++) {
|
||||
/* write real and imaginary part */
|
||||
mcs_bcd_t rawbcd;
|
||||
g1m_bcd_tomcs(&handle->vars[i].real, &rawbcd); DWRITE(rawbcd)
|
||||
g1m_bcd_tomcs(&handle->vars[i].imgn, &rawbcd); DWRITE(rawbcd)
|
||||
g1m_mcsbcd_t rawbcd;
|
||||
g1m_bcd_tomcs(&handle->g1m_mcsfile_vars[i].g1m_mcscell_real, &rawbcd);
|
||||
DWRITE(rawbcd)
|
||||
g1m_bcd_tomcs(&handle->g1m_mcsfile_vars[i].g1m_mcscell_imgn, &rawbcd);
|
||||
DWRITE(rawbcd)
|
||||
}
|
||||
|
||||
/* no error! */
|
||||
|
|
|
@ -39,12 +39,13 @@ int g1m_make_picture(g1m_handle_t **h, unsigned int width, unsigned int height)
|
|||
{
|
||||
/* make the handle */
|
||||
mkhandle();
|
||||
handle->type = g1m_type_picture;
|
||||
handle->width = width;
|
||||
handle->height = height;
|
||||
handle->pixels = alloc_pixels(width, height);
|
||||
if (!handle->pixels) { free(*h); *h = NULL; return (g1m_error_alloc); }
|
||||
prepare_pixels(handle->pixels, width, height)
|
||||
handle->g1m_handle_type = g1m_type_picture;
|
||||
handle->g1m_handle_width = width;
|
||||
handle->g1m_handle_height = height;
|
||||
handle->g1m_handle_pixels = alloc_pixels(width, height);
|
||||
if (!handle->g1m_handle_pixels) {
|
||||
free(*h); *h = NULL; return (g1m_error_alloc); }
|
||||
prepare_pixels(handle->g1m_handle_pixels, width, height)
|
||||
|
||||
/* everything went well! */
|
||||
return (0);
|
||||
|
@ -63,17 +64,18 @@ int g1m_make_mcs(g1m_handle_t **h, int count)
|
|||
{
|
||||
/* make the handle */
|
||||
mkhandle();
|
||||
handle->type = g1m_type_mcs;
|
||||
handle->platform = g1m_platform_fx;
|
||||
handle->count = 0; handle->_size = 0;
|
||||
handle->files = NULL;
|
||||
handle->g1m_handle_type = g1m_type_mcs;
|
||||
handle->g1m_handle_platform = g1m_platform_fx;
|
||||
handle->g1m_handle_count = 0;
|
||||
handle->g1m_handle__size = 0;
|
||||
handle->g1m_handle_files = NULL;
|
||||
|
||||
/* allocate space */
|
||||
if (count) {
|
||||
handle->files = malloc(sizeof(g1m_mcsfile_t*) * count);
|
||||
if (!handle->files) goto fail;
|
||||
memset(handle->files, 0, sizeof(g1m_mcsfile_t*) * count);
|
||||
handle->_size = count;
|
||||
handle->g1m_handle_files = malloc(sizeof(g1m_mcsfile_t*) * count);
|
||||
if (!handle->g1m_handle_files) goto fail;
|
||||
memset(handle->g1m_handle_files, 0, sizeof(g1m_mcsfile_t*) * count);
|
||||
handle->g1m_handle__size = count;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
@ -97,17 +99,18 @@ int g1m_make_fkey(g1m_handle_t **h, g1m_platform_t pf, int count)
|
|||
{
|
||||
/* make the handle */
|
||||
mkhandle();
|
||||
handle->type = g1m_type_fkey;
|
||||
handle->platform = pf;
|
||||
handle->count = 0; handle->_size = 0;
|
||||
handle->fkeys = NULL;
|
||||
handle->g1m_handle_type = g1m_type_fkey;
|
||||
handle->g1m_handle_platform = pf;
|
||||
handle->g1m_handle_count = 0;
|
||||
handle->g1m_handle__size = 0;
|
||||
handle->g1m_handle_fkeys = NULL;
|
||||
|
||||
/* allocate index */
|
||||
if (count) {
|
||||
handle->fkeys = malloc(sizeof(uint32_t**) * count);
|
||||
if (!handle->fkeys) goto fail;
|
||||
memset(handle->fkeys, 0, sizeof(uint32_t**) * count);
|
||||
handle->_size = count;
|
||||
handle->g1m_handle_fkeys = malloc(sizeof(uint32_t**) * count);
|
||||
if (!handle->g1m_handle_fkeys) goto fail;
|
||||
memset(handle->g1m_handle_fkeys, 0, sizeof(uint32_t**) * count);
|
||||
handle->g1m_handle__size = count;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
@ -131,17 +134,18 @@ int g1m_make_lang(g1m_handle_t **h, g1m_platform_t platform, int count)
|
|||
{
|
||||
/* make the handle */
|
||||
mkhandle();
|
||||
handle->type = g1m_type_lang;
|
||||
handle->platform = platform;
|
||||
handle->count = 0; handle->_size = 0;
|
||||
handle->messages = NULL;
|
||||
handle->g1m_handle_type = g1m_type_lang;
|
||||
handle->g1m_handle_platform = platform;
|
||||
handle->g1m_handle_count = 0;
|
||||
handle->g1m_handle__size = 0;
|
||||
handle->g1m_handle_messages = NULL;
|
||||
|
||||
/* allocate index */
|
||||
if (count) {
|
||||
handle->messages = malloc(sizeof(char*) * count);
|
||||
if (!handle->messages) goto fail;
|
||||
memset(handle->messages, 0, sizeof(char*) * count);
|
||||
handle->_size = count;
|
||||
handle->g1m_handle_messages = malloc(sizeof(char*) * count);
|
||||
if (!handle->g1m_handle_messages) goto fail;
|
||||
memset(handle->g1m_handle_messages, 0, sizeof(char*) * count);
|
||||
handle->g1m_handle__size = count;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
|
@ -182,15 +186,15 @@ int g1m_make_addin(g1m_handle_t **h, g1m_platform_t platform, size_t size,
|
|||
|
||||
/* make the handle */
|
||||
mkhandle();
|
||||
handle->type = g1m_type_addin;
|
||||
handle->platform = platform;
|
||||
handle->version = *version;
|
||||
handle->creation_date = *created;
|
||||
handle->size = size;
|
||||
handle->g1m_handle_type = g1m_type_addin;
|
||||
handle->g1m_handle_platform = platform;
|
||||
handle->g1m_handle_version = *version;
|
||||
handle->g1m_handle_creation_date = *created;
|
||||
handle->g1m_handle_size = size;
|
||||
|
||||
/* allocate the content */
|
||||
handle->content = malloc(size);
|
||||
if (!handle->content) goto fail;
|
||||
handle->g1m_handle_content = malloc(size);
|
||||
if (!handle->g1m_handle_content) goto fail;
|
||||
|
||||
/* check the platform */
|
||||
unsigned int width, height;
|
||||
|
@ -211,28 +215,29 @@ int g1m_make_addin(g1m_handle_t **h, g1m_platform_t platform, size_t size,
|
|||
/* copy the addin title */
|
||||
int i; for (i = 0; (isupper(name[i]) || isdigit(name[i]))
|
||||
&& i < titlesize; i++)
|
||||
handle->title[i] = name[i];
|
||||
handle->title[i] = 0;
|
||||
if (!handle->title[0]) strcpy(handle->title, "@ADDIN");
|
||||
handle->g1m_handle_title[i] = name[i];
|
||||
handle->g1m_handle_title[i] = 0;
|
||||
if (!handle->g1m_handle_title[0])
|
||||
strcpy(handle->g1m_handle_title, "@ADDIN");
|
||||
|
||||
/* copy the internal name */
|
||||
handle->intname[0] = '@';
|
||||
handle->g1m_handle_intname[0] = '@';
|
||||
for (i = 1; (isupper(internal[i]) || isdigit(internal[i]))
|
||||
&& i < intsize; i++)
|
||||
handle->intname[i] = internal[i];
|
||||
handle->intname[i] = 0;
|
||||
handle->g1m_handle_intname[i] = internal[i];
|
||||
handle->g1m_handle_intname[i] = 0;
|
||||
|
||||
/* allocate pictures */
|
||||
handle->icon_unsel = alloc_pixels(width, height);
|
||||
if (!handle->icon_unsel) goto fail;
|
||||
handle->icon_sel = alloc_pixels(width, height);
|
||||
if (!handle->icon_sel) goto fail;
|
||||
handle->g1m_handle_icon_unsel = alloc_pixels(width, height);
|
||||
if (!handle->g1m_handle_icon_unsel) goto fail;
|
||||
handle->g1m_handle_icon_sel = alloc_pixels(width, height);
|
||||
if (!handle->g1m_handle_icon_sel) goto fail;
|
||||
|
||||
/* prepare pictures */
|
||||
handle->width = width;
|
||||
handle->height = height;
|
||||
prepare_pixels(handle->icon_unsel, width, height)
|
||||
prepare_pixels(handle->icon_sel, width, height)
|
||||
handle->g1m_handle_width = width;
|
||||
handle->g1m_handle_height = height;
|
||||
prepare_pixels(handle->g1m_handle_icon_unsel, width, height)
|
||||
prepare_pixels(handle->g1m_handle_icon_sel, width, height)
|
||||
|
||||
/* end my suffering */
|
||||
return (0);
|
||||
|
@ -259,51 +264,52 @@ void g1m_free(g1m_handle_t *handle)
|
|||
if (!handle) return ;
|
||||
|
||||
/* addin time! */
|
||||
if (handle->type & g1m_type_addin) {
|
||||
free(handle->content);
|
||||
free(handle->icon_unsel);
|
||||
free(handle->icon_sel);
|
||||
if (handle->g1m_handle_type & g1m_type_addin) {
|
||||
free(handle->g1m_handle_content);
|
||||
free(handle->g1m_handle_icon_unsel);
|
||||
free(handle->g1m_handle_icon_sel);
|
||||
}
|
||||
|
||||
/* mcs time! */
|
||||
if (handle->type & g1m_type_mcs) {
|
||||
if (handle->g1m_handle_type & g1m_type_mcs) {
|
||||
/* check if mcs */
|
||||
if (!handle->files)
|
||||
if (!handle->g1m_handle_files)
|
||||
return ;
|
||||
|
||||
/* foreach file in mcs */
|
||||
g1m_mcsfile_t **files = handle->files;
|
||||
int file_count = handle->count;
|
||||
g1m_mcsfile_t **files = handle->g1m_handle_files;
|
||||
int file_count = handle->g1m_handle_count;
|
||||
for (i = 0; i < file_count; i++) {
|
||||
/* free the file if exists */
|
||||
if (files[i]) g1m_free_mcsfile(files[i]);
|
||||
}
|
||||
free(handle->files); handle->files = NULL;
|
||||
free(handle->g1m_handle_files);
|
||||
handle->g1m_handle_files = NULL;
|
||||
}
|
||||
|
||||
/* messages time! */
|
||||
if (handle->type & g1m_type_lang
|
||||
&& handle->messages) {
|
||||
for (i = 0; i < handle->count; i++)
|
||||
free(handle->messages[i]);
|
||||
free(handle->messages);
|
||||
if (handle->g1m_handle_type & g1m_type_lang
|
||||
&& handle->g1m_handle_messages) {
|
||||
for (i = 0; i < handle->g1m_handle_count; i++)
|
||||
free(handle->g1m_handle_messages[i]);
|
||||
free(handle->g1m_handle_messages);
|
||||
}
|
||||
|
||||
/* function keys time! */
|
||||
if (handle->type & g1m_type_fkey
|
||||
&& handle->fkeys) {
|
||||
for (i = 0; i < handle->count; i++)
|
||||
free(handle->fkeys[i]);
|
||||
free(handle->fkeys);
|
||||
if (handle->g1m_handle_type & g1m_type_fkey
|
||||
&& handle->g1m_handle_fkeys) {
|
||||
for (i = 0; i < handle->g1m_handle_count; i++)
|
||||
free(handle->g1m_handle_fkeys[i]);
|
||||
free(handle->g1m_handle_fkeys);
|
||||
}
|
||||
|
||||
/* picture time! */
|
||||
if (handle->type & g1m_type_picture)
|
||||
free(handle->pixels);
|
||||
if (handle->g1m_handle_type & g1m_type_picture)
|
||||
free(handle->g1m_handle_pixels);
|
||||
|
||||
/* e-activities time! */
|
||||
if (handle->type & g1m_type_eact)
|
||||
g1m_free_line_content(handle->line);
|
||||
if (handle->g1m_handle_type & g1m_type_eact)
|
||||
g1m_free_line_content(handle->g1m_handle_line);
|
||||
|
||||
/* free the handle itself! */
|
||||
free(handle);
|
||||
|
|
|
@ -37,39 +37,44 @@ int g1m_mcs_insert(g1m_handle_t *handle, g1m_mcsfile_t **tofile,
|
|||
const g1m_mcshead_t *head)
|
||||
{
|
||||
g1m_mcsfile_t **pfile = NULL; *tofile = NULL;
|
||||
int i, istyp, err;
|
||||
int i, err;
|
||||
|
||||
/* look if this file isn't already in the tab */
|
||||
istyp = g1m_mcshead_uses_id(head);
|
||||
for (i = 0; i < handle->count; i++) {
|
||||
g1m_mcsfile_t *file = handle->files[i];
|
||||
int istyp = g1m_mcshead_uses_id(head);
|
||||
for (i = 0; i < handle->g1m_handle_count; i++) {
|
||||
g1m_mcsfile_t *file = handle->g1m_handle_files[i];
|
||||
if (!file) {
|
||||
pfile = &handle->files[i];
|
||||
pfile = &handle->g1m_handle_files[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* loop assertions */
|
||||
if (file->head.type != head->type)
|
||||
if (file->g1m_mcsfile_head.g1m_mcshead_type != head->g1m_mcshead_type)
|
||||
continue;
|
||||
if (head->type) {
|
||||
if (head->g1m_mcshead_type) {
|
||||
if (istyp) {
|
||||
if (head->id != file->head.id)
|
||||
if (head->g1m_mcshead_id
|
||||
!= file->g1m_mcsfile_head.g1m_mcshead_id)
|
||||
continue;
|
||||
} else if (strcmp(file->head.name, head->name))
|
||||
} else if (strcmp(file->g1m_mcsfile_head.g1m_mcshead_name,
|
||||
head->g1m_mcshead_name))
|
||||
continue;
|
||||
} else switch (head->info) {
|
||||
} else switch (head->g1m_mcshead_info) {
|
||||
case g1m_mcsinfo_mcs:
|
||||
if (strncmp((char*)head->_group, (char*)file->head._group, 16))
|
||||
if (strncmp((char*)head->g1m_mcshead_group,
|
||||
(char*)file->g1m_mcsfile_head.g1m_mcshead_group, 16))
|
||||
continue;
|
||||
if (strncmp((char*)head->_dirname, (char*)file->head._dirname, 8))
|
||||
if (strncmp((char*)head->g1m_mcshead_dirname,
|
||||
(char*)file->g1m_mcsfile_head.g1m_mcshead_dirname, 8))
|
||||
continue;
|
||||
if (strncmp((char*)head->name, (char*)file->head.name, 8))
|
||||
if (strncmp((char*)head->g1m_mcshead_name,
|
||||
(char*)file->g1m_mcsfile_head.g1m_mcshead_name, 8))
|
||||
continue;
|
||||
break;
|
||||
case g1m_mcsinfo_cas:
|
||||
case g1m_mcsinfo_caspro:
|
||||
if (strncmp((char*)head->_datatype,
|
||||
(char*)file->head._datatype, 2))
|
||||
if (strncmp((char*)head->g1m_mcshead_datatype,
|
||||
(char*)file->g1m_mcsfile_head.g1m_mcshead_datatype, 2))
|
||||
continue;
|
||||
break;
|
||||
default: continue;
|
||||
|
@ -77,30 +82,30 @@ int g1m_mcs_insert(g1m_handle_t *handle, g1m_mcsfile_t **tofile,
|
|||
|
||||
/* slot was found! */
|
||||
g1m_free_mcsfile(file);
|
||||
pfile = &handle->files[i];
|
||||
pfile = &handle->g1m_handle_files[i];
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* if no empty space was found, take one at the end (allocate if needed) */
|
||||
if (!pfile) {
|
||||
if (handle->count >= handle->_size) {
|
||||
if (handle->g1m_handle_count >= handle->g1m_handle__size) {
|
||||
/* allocate new index */
|
||||
int newsize = handle->count + MCS_CHUNK_SIZE;
|
||||
int newsize = handle->g1m_handle_count + MCS_CHUNK_SIZE;
|
||||
g1m_mcsfile_t **newindex = malloc(newsize * sizeof(g1m_mcsfile_t*));
|
||||
if (!newindex) return (g1m_error_alloc);
|
||||
|
||||
/* copy the data from the old index */
|
||||
memcpy(newindex, handle->files,
|
||||
handle->_size * sizeof(g1m_mcsfile_t*));
|
||||
memset(&newindex[handle->_size], 0,
|
||||
(newsize - handle->_size) * sizeof(g1m_mcsfile_t*));
|
||||
memcpy(newindex, handle->g1m_handle_files,
|
||||
handle->g1m_handle__size * sizeof(g1m_mcsfile_t*));
|
||||
memset(&newindex[handle->g1m_handle__size], 0,
|
||||
(newsize - handle->g1m_handle__size) * sizeof(g1m_mcsfile_t*));
|
||||
|
||||
/* free old, assign new */
|
||||
free(handle->files);
|
||||
handle->files = newindex;
|
||||
handle->_size = newsize;
|
||||
free(handle->g1m_handle_files);
|
||||
handle->g1m_handle_files = newindex;
|
||||
handle->g1m_handle__size = newsize;
|
||||
}
|
||||
pfile = &handle->files[handle->count++];
|
||||
pfile = &handle->g1m_handle_files[handle->g1m_handle_count++];
|
||||
}
|
||||
|
||||
found:;
|
||||
|
@ -112,7 +117,6 @@ found:;
|
|||
*tofile = *pfile;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Reorganize an MCS handle for encoding */
|
||||
/* ************************************************************************** */
|
||||
|
@ -130,18 +134,21 @@ int g1m_mcs_sort(g1m_handle_t *handle)
|
|||
int i;
|
||||
|
||||
/* make checks */
|
||||
if (handle->type != g1m_type_mcs) return (g1m_error_op);
|
||||
if (handle->platform != g1m_platform_fx) return (g1m_error_op);
|
||||
if (handle->g1m_handle_type != g1m_type_mcs)
|
||||
return (g1m_error_op);
|
||||
if (handle->g1m_handle_platform != g1m_platform_fx)
|
||||
return (g1m_error_op);
|
||||
|
||||
/* correct each head */
|
||||
for (i = 0; i < handle->count; i++) {
|
||||
int err = g1m_correct_mcsfile_head(&handle->files[i]->head);
|
||||
for (i = 0; i < handle->g1m_handle_count; i++) {
|
||||
int err = g1m_correct_mcsfile_head(
|
||||
&handle->g1m_handle_files[i]->g1m_mcsfile_head);
|
||||
if (err) return (err);
|
||||
}
|
||||
|
||||
/* sort */
|
||||
qsort(handle->files, handle->count, sizeof(g1m_mcsfile_t*),
|
||||
(g1m_compare_mcsfiles_t)g1m_compare_mcsfiles);
|
||||
qsort(handle->g1m_handle_files, handle->g1m_handle_count,
|
||||
sizeof(g1m_mcsfile_t*), (g1m_compare_mcsfiles_t)g1m_compare_mcsfiles);
|
||||
|
||||
/* TODO: check for duplicates */
|
||||
return (0);
|
||||
|
|
|
@ -37,67 +37,80 @@ int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead)
|
|||
/* allocate the handle */
|
||||
*handle = malloc(sizeof(g1m_mcsfile_t));
|
||||
if (!handle) return (g1m_error_alloc);
|
||||
|
||||
/* initialize the handle, copy the head */
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
memset(h, 0, sizeof(g1m_mcsfile_t));
|
||||
memcpy(&h->g1m_mcsfile_head, rawhead, sizeof(g1m_mcshead_t));
|
||||
g1m_mcshead_t *head = &h->g1m_mcsfile_head;
|
||||
|
||||
/* copy the head */
|
||||
memcpy(&h->head, rawhead, sizeof(g1m_mcshead_t));
|
||||
g1m_mcshead_t *head = &h->head;
|
||||
|
||||
switch (head->type) {
|
||||
switch (head->g1m_mcshead_type) {
|
||||
/* allocate the cells */
|
||||
case g1m_mcstype_list: case g1m_mcstype_mat: case g1m_mcstype_vct:
|
||||
case g1m_mcstype_ssheet:
|
||||
log_info("Preparing %d*%d matrix", head->width, head->height);
|
||||
unsigned int wd = head->width, ht = head->height;
|
||||
log_info("Preparing %d*%d matrix", head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height);
|
||||
unsigned int wd = head->g1m_mcshead_width;
|
||||
unsigned int ht = head->g1m_mcshead_height;
|
||||
if (wd && ht) {
|
||||
h->cells = malloc(sizeof(g1m_mcscell_t*) * ht);
|
||||
if (!h->cells) goto fail;
|
||||
h->cells[0] = malloc(sizeof(g1m_mcscell_t) * wd * ht);
|
||||
if (!h->cells[0]) { free(h->cells); goto fail; }
|
||||
h->g1m_mcsfile_cells = malloc(sizeof(g1m_mcscell_t*) * ht);
|
||||
if (!h->g1m_mcsfile_cells) goto fail;
|
||||
h->g1m_mcsfile_cells[0] = malloc(sizeof(g1m_mcscell_t) * wd * ht);
|
||||
if (!h->g1m_mcsfile_cells[0]) {
|
||||
free(h->g1m_mcsfile_cells); goto fail;
|
||||
}
|
||||
|
||||
for (y = 1; y < ht; y++)
|
||||
h->cells[y] = &h->cells[0][h->head.width * y];
|
||||
h->g1m_mcsfile_cells[y] = &h->g1m_mcsfile_cells
|
||||
[0][h->g1m_mcsfile_head.g1m_mcshead_width * y];
|
||||
}
|
||||
break;
|
||||
|
||||
/* allocate the variables */
|
||||
case g1m_mcstype_alphamem:
|
||||
if (head->count <= 1) h->vars = &h->var;
|
||||
if (head->g1m_mcshead_count <= 1)
|
||||
h->g1m_mcsfile_vars = &h->g1m_mcsfile_var;
|
||||
else {
|
||||
h->vars = malloc(sizeof(g1m_mcscell_t) * head->count);
|
||||
if (!h->vars) goto fail;
|
||||
memset(h->vars, 0, sizeof(g1m_mcscell_t) * head->count);
|
||||
h->g1m_mcsfile_vars = malloc(sizeof(g1m_mcscell_t)
|
||||
* head->g1m_mcshead_count);
|
||||
if (!h->g1m_mcsfile_vars) goto fail;
|
||||
memset(h->g1m_mcsfile_vars, 0, sizeof(g1m_mcscell_t)
|
||||
* head->g1m_mcshead_count);
|
||||
}
|
||||
break;
|
||||
|
||||
/* allocate the set of pixels */
|
||||
case g1m_mcstype_pict: case g1m_mcstype_capt:
|
||||
/* set count */
|
||||
head->count = (head->type == g1m_mcstype_pict) ? 2 : 1;
|
||||
head->g1m_mcshead_count = (head->g1m_mcshead_type == g1m_mcstype_pict)
|
||||
? 2 : 1;
|
||||
|
||||
/* allocate directory */
|
||||
if (head->count <= 1) h->pics = &h->pic;
|
||||
if (head->g1m_mcshead_count <= 1)
|
||||
h->g1m_mcsfile_pics = &h->g1m_mcsfile_pic;
|
||||
else {
|
||||
h->pics = malloc(sizeof(uint32_t**) * head->count);
|
||||
if (!h->pics) goto fail;
|
||||
h->g1m_mcsfile_pics = malloc(sizeof(uint32_t**)
|
||||
* head->g1m_mcshead_count);
|
||||
if (!h->g1m_mcsfile_pics) goto fail;
|
||||
}
|
||||
|
||||
/* allocate */
|
||||
for (i = 0; i < head->count; i++) {
|
||||
h->pics[i] = alloc_pixels(head->width, head->height);
|
||||
if (!h->pics[i]) {
|
||||
for (i = 0; i < head->g1m_mcshead_count; i++) {
|
||||
h->g1m_mcsfile_pics[i] = alloc_pixels(head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height);
|
||||
if (!h->g1m_mcsfile_pics[i]) {
|
||||
for (j = 0; j < i; j++)
|
||||
free(h->pics[j]);
|
||||
if (h->pics != &h->pic)
|
||||
free(h->pics);
|
||||
free(h->g1m_mcsfile_pics[j]);
|
||||
if (h->g1m_mcsfile_pics != &h->g1m_mcsfile_pic)
|
||||
free(h->g1m_mcsfile_pics);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare */
|
||||
for (i = 0; i < head->count; i++)
|
||||
prepare_pixels(h->pics[i], head->width, head->height)
|
||||
for (i = 0; i < head->g1m_mcshead_count; i++)
|
||||
prepare_pixels(h->g1m_mcsfile_pics[i], head->g1m_mcshead_width,
|
||||
head->g1m_mcshead_height)
|
||||
break;
|
||||
|
||||
/* allocate nothing */
|
||||
|
@ -108,8 +121,8 @@ int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead)
|
|||
|
||||
/* allocate raw content */
|
||||
default:
|
||||
h->content = malloc(head->size);
|
||||
if (!h->content) goto fail;
|
||||
h->g1m_mcsfile_content = malloc(head->g1m_mcshead_size);
|
||||
if (!h->g1m_mcsfile_content) goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -120,32 +133,6 @@ fail:
|
|||
return (g1m_error_alloc);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_prepare_mcsfile_heads:
|
||||
* Prepare the heads from a general head.
|
||||
*
|
||||
* @arg head the main head.
|
||||
* @arg heads the heads to prepare.
|
||||
* @return the error (if any).
|
||||
*/
|
||||
|
||||
int g1m_prepare_mcsfile_heads(g1m_mcshead_t *head, g1m_mcshead_t *heads)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* check if the head is a multiple head */
|
||||
if (~head->flags & g1m_mcsflag_multiple) return (g1m_error_op);
|
||||
|
||||
/* copy the data in each head */
|
||||
for (i = 0; i < head->count; i++) {
|
||||
heads[i] = *head;
|
||||
heads[i].flags &= ~g1m_mcsflag_multiple;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_free_mcsfile:
|
||||
* Free an MCS file handle content.
|
||||
|
@ -160,28 +147,29 @@ void g1m_free_mcsfile(g1m_mcsfile_t *handle)
|
|||
/* check if exists */
|
||||
if (!handle) return ;
|
||||
|
||||
switch (handle->head.type) {
|
||||
switch (handle->g1m_mcsfile_head.g1m_mcshead_type) {
|
||||
/* free the cells */
|
||||
case g1m_mcstype_mat: case g1m_mcstype_vct: case g1m_mcstype_list:
|
||||
case g1m_mcstype_ssheet:
|
||||
if (handle->head.width && handle->head.height) {
|
||||
free(handle->cells[0]);
|
||||
free(handle->cells);
|
||||
if (handle->g1m_mcsfile_head.g1m_mcshead_width
|
||||
&& handle->g1m_mcsfile_head.g1m_mcshead_height) {
|
||||
free(handle->g1m_mcsfile_cells[0]);
|
||||
free(handle->g1m_mcsfile_cells);
|
||||
}
|
||||
break;
|
||||
|
||||
/* free the set of pixels */
|
||||
case g1m_mcstype_pict: case g1m_mcstype_capt:
|
||||
for (i = 0; i < handle->head.count; i++)
|
||||
free(handle->pics[i]);
|
||||
if (handle->pics != &handle->pic)
|
||||
free(handle->pics);
|
||||
for (i = 0; i < handle->g1m_mcsfile_head.g1m_mcshead_count; i++)
|
||||
free(handle->g1m_mcsfile_pics[i]);
|
||||
if (handle->g1m_mcsfile_pics != &handle->g1m_mcsfile_pic)
|
||||
free(handle->g1m_mcsfile_pics);
|
||||
break;
|
||||
|
||||
/* free the variables */
|
||||
case g1m_mcstype_alphamem:
|
||||
if (handle->vars != &handle->var)
|
||||
free(handle->vars);
|
||||
if (handle->g1m_mcsfile_vars != &handle->g1m_mcsfile_var)
|
||||
free(handle->g1m_mcsfile_vars);
|
||||
break;
|
||||
|
||||
/* free nothing */
|
||||
|
@ -192,7 +180,7 @@ void g1m_free_mcsfile(g1m_mcsfile_t *handle)
|
|||
|
||||
/* free the raw content */
|
||||
default:
|
||||
free(handle->content);
|
||||
free(handle->g1m_mcsfile_content);
|
||||
}
|
||||
|
||||
/* free the content */
|
||||
|
|
|
@ -124,10 +124,10 @@ int g1m_maketype_casapp(g1m_mcshead_t *head,
|
|||
|
||||
/* copy raw information */
|
||||
memset(head, 0, sizeof(g1m_mcshead_t));
|
||||
head->info = e->info; /* FIXME */
|
||||
head->g1m_mcshead_info = e->info; /* FIXME */
|
||||
log_info("Head info is 0x%04X", e->info);
|
||||
strncpy((char*)head->_appname, app, 3);
|
||||
head->_appname[3] = 0;
|
||||
strncpy((char*)head->g1m_mcshead_appname, app, 3);
|
||||
head->g1m_mcshead_appname[3] = 0;
|
||||
|
||||
/* fill in info and return */
|
||||
return (0);
|
||||
|
@ -135,6 +135,6 @@ int g1m_maketype_casapp(g1m_mcshead_t *head,
|
|||
notfound:
|
||||
log_error("Type with 0x%02X extension and '%.3s' app name was not "
|
||||
"implemented or recognized", ext, app);
|
||||
head->type = 0;
|
||||
head->g1m_mcshead_type = 0;
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -135,8 +135,8 @@ static int get_number(const char *s, int *num)
|
|||
int g1m_maketype_cas(g1m_mcshead_t *head, const char *datatype)
|
||||
{
|
||||
/* copy information */
|
||||
memcpy(head->_datatype, datatype, 2);
|
||||
head->_datatype[2] = 0;
|
||||
memcpy(head->g1m_mcshead_datatype, datatype, 2);
|
||||
head->g1m_mcshead_datatype[2] = 0;
|
||||
|
||||
/* look for correspondance */
|
||||
struct type_corresp *c = cas_groups - 1; int id = 0;
|
||||
|
@ -146,23 +146,24 @@ int g1m_maketype_cas(g1m_mcshead_t *head, const char *datatype)
|
|||
/* check if pattern is there */
|
||||
if (strncmp(c->datatype, datatype, pl))
|
||||
continue;
|
||||
if ((c->flags & arg) && get_number(&head->name[pl], &id))
|
||||
if ((c->flags & arg) && get_number(&head->g1m_mcshead_name[pl], &id))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (!c->type) goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
head->type = c->type;
|
||||
head->id = id;
|
||||
head->_picformat = c->picformat;
|
||||
if (c->flags & mult) head->flags |= g1m_mcsflag_multiple;
|
||||
head->g1m_mcshead_type = c->type;
|
||||
head->g1m_mcshead_id = id;
|
||||
head->g1m_mcshead_picformat = c->picformat;
|
||||
if (c->flags & mult)
|
||||
head->g1m_mcshead_flags |= g1m_mcsflag_multiple;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%.2s' data string was not implemented or not "
|
||||
"recognized.", datatype);
|
||||
head->type = 0;
|
||||
head->g1m_mcshead_type = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -179,7 +180,7 @@ int g1m_correct_casfile_head(g1m_mcshead_t *head)
|
|||
/* look for correspondance */
|
||||
struct type_corresp *c = cas_groups - 1;
|
||||
while ((++c)->type) {
|
||||
if (head->type == c->type) /* FIXME: picture format? */
|
||||
if (head->g1m_mcshead_type == c->type) /* FIXME: picture format? */
|
||||
goto found;
|
||||
break;
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ int g1m_correct_casfile_head(g1m_mcshead_t *head)
|
|||
|
||||
/* found :) */
|
||||
found:
|
||||
memcpy(head->_datatype, c->datatype, 2);
|
||||
memcpy(head->g1m_mcshead_datatype, c->datatype, 2);
|
||||
/* TODO: things with IDs, etc */
|
||||
/* TODO: add app? */
|
||||
return (0);
|
||||
|
|
|
@ -312,17 +312,17 @@ int g1m_maketype_mcs(g1m_mcshead_t *head,
|
|||
|
||||
/* copy raw information */
|
||||
memset(head, 0, sizeof(g1m_mcshead_t));
|
||||
head->info = g1m_mcsinfo_mcs;
|
||||
memcpy(head->name, fname, 8);
|
||||
head->name[8] = 0;
|
||||
memcpy(head->_group, gname, 16);
|
||||
head->_group[16] = 0;
|
||||
head->_rawtype = rawtype;
|
||||
head->g1m_mcshead_info = g1m_mcsinfo_mcs;
|
||||
memcpy(head->g1m_mcshead_name, fname, 8);
|
||||
head->g1m_mcshead_name[8] = 0;
|
||||
memcpy(head->g1m_mcshead_group, gname, 16);
|
||||
head->g1m_mcshead_group[16] = 0;
|
||||
head->g1m_mcshead_rawtype = rawtype;
|
||||
if (dname) {
|
||||
memcpy(head->_dirname, dname, 8);
|
||||
head->_dirname[8] = 0;
|
||||
memcpy(head->g1m_mcshead_dirname, dname, 8);
|
||||
head->g1m_mcshead_dirname[8] = 0;
|
||||
} else
|
||||
memset(head->_dirname, 0, 9);
|
||||
memset(head->g1m_mcshead_dirname, 0, 9);
|
||||
|
||||
/* look for group correspondance */
|
||||
int gid = 0;
|
||||
|
@ -366,15 +366,15 @@ int g1m_maketype_mcs(g1m_mcshead_t *head,
|
|||
goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
head->type = t->type;
|
||||
head->id = fid;
|
||||
head->g1m_mcshead_type = t->type;
|
||||
head->g1m_mcshead_id = fid;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%s' group, '%s' name and 0x%02x type "
|
||||
"wasn't recognized.", gname, fname, rawtype);
|
||||
head->type = 0;
|
||||
head->id = 0;
|
||||
head->g1m_mcshead_type = 0;
|
||||
head->g1m_mcshead_id = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -390,8 +390,8 @@ int g1m_correct_mcsfile_head(g1m_mcshead_t *head)
|
|||
{
|
||||
/* check if there is a type */
|
||||
if (!head) return (0);
|
||||
if (!head->type
|
||||
&& (!head->_group[0] || !head->name[0] || !head->_dirname[0]))
|
||||
if (!head->g1m_mcshead_type && (!head->g1m_mcshead_group[0]
|
||||
|| !head->g1m_mcshead_name[0] || !head->g1m_mcshead_dirname[0]))
|
||||
return (g1m_error_op);
|
||||
|
||||
/* find the group/type */
|
||||
|
@ -399,10 +399,10 @@ int g1m_correct_mcsfile_head(g1m_mcshead_t *head)
|
|||
struct type_corresp *t;
|
||||
for (g = mcs_groups; g->types; g++) for (t = g->types; t->dirname; t++) {
|
||||
/* check if the libg1m type corresponds */
|
||||
if (t->type != head->type) continue;
|
||||
if (t->type != head->g1m_mcshead_type) continue;
|
||||
|
||||
/* check if id is weighted by major */
|
||||
if (g1m_get_id_major(head->id)) {
|
||||
if (g1m_get_id_major(head->g1m_mcshead_id)) {
|
||||
if (~t->flags & weight_by_gid)
|
||||
continue;
|
||||
} else
|
||||
|
@ -417,11 +417,11 @@ int g1m_correct_mcsfile_head(g1m_mcshead_t *head)
|
|||
|
||||
found:;
|
||||
/* put the group name */
|
||||
char *gr = (char*)head->_group;
|
||||
char *gr = (char*)head->g1m_mcshead_group;
|
||||
if (g->flags & arg) {
|
||||
int grid = g1m_get_id_major(head->id);
|
||||
int grid = g1m_get_id_major(head->g1m_mcshead_id);
|
||||
if ((t->flags & arg) && ~t->flags & weight_by_gid)
|
||||
grid = g1m_get_id_minor(head->id);
|
||||
grid = g1m_get_id_minor(head->g1m_mcshead_id);
|
||||
|
||||
if (grid == g1m_ans)
|
||||
sprintf(gr, "%sAns", g->name);
|
||||
|
@ -437,12 +437,12 @@ found:;
|
|||
strcpy(gr, g->name);
|
||||
|
||||
/* put the directory name */
|
||||
strcpy((char*)head->_dirname, t->dirname);
|
||||
strcpy((char*)head->g1m_mcshead_dirname, t->dirname);
|
||||
|
||||
/* put the filename */
|
||||
char *nm = (char*)head->name;
|
||||
char *nm = (char*)head->g1m_mcshead_name;
|
||||
if (t->flags & arg) {
|
||||
int namid = g1m_get_id_minor(head->id);
|
||||
int namid = g1m_get_id_minor(head->g1m_mcshead_id);
|
||||
|
||||
if (namid == g1m_ans)
|
||||
sprintf(nm, "%sAns", t->name);
|
||||
|
@ -477,14 +477,14 @@ static int find_offset_in_group(struct group_corresp *g,
|
|||
const g1m_mcsfile_t *file)
|
||||
{
|
||||
/* group check */
|
||||
if (strcmp((char*)file->head._group, g->name))
|
||||
if (strcmp((char*)file->g1m_mcsfile_head.g1m_mcshead_group, g->name))
|
||||
return (-1);
|
||||
|
||||
/* file check */
|
||||
struct type_corresp *f; int i;
|
||||
for (f = g->types, i = 0; f->info; f++, i++) {
|
||||
if (strcmp((char*)file->head._group, f->name)
|
||||
|| file->head._rawtype != f->rawtype)
|
||||
if (strcmp((char*)file->g1m_mcsfile_head.g1m_mcshead_group, f->name)
|
||||
|| file->g1m_mcsfile_head.g1m_mcshead_rawtype != f->rawtype)
|
||||
continue;
|
||||
|
||||
return (i);
|
||||
|
|
|
@ -104,10 +104,10 @@ int g1m_membuffer_read(void *vcookie, unsigned char *dest, size_t size)
|
|||
{
|
||||
g1m_cursor_t *cursor = (void*)vcookie;
|
||||
|
||||
if (size > cursor->left)
|
||||
if (size > cursor->g1m_cursor_left)
|
||||
return (g1m_error_eof);
|
||||
memcpy(dest, cursor->p, size);
|
||||
cursor->p += size;
|
||||
memcpy(dest, cursor->g1m_cursor_p, size);
|
||||
cursor->g1m_cursor_p += size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -128,8 +128,8 @@ int g1m_limbuffer_read(void *vcookie, unsigned char *buf, size_t size)
|
|||
{
|
||||
/* check if the size is okay */
|
||||
g1m_limited_t *lim = (void*)vcookie;
|
||||
if (size > lim->left) return (g1m_error_eof);
|
||||
g1m_buffer_t *buffer = lim->buffer;
|
||||
if (size > lim->g1m_limited_left) return (g1m_error_eof);
|
||||
g1m_buffer_t *buffer = lim->g1m_limited_buffer;
|
||||
|
||||
/* read */
|
||||
READ(buf, size)
|
||||
|
@ -147,9 +147,9 @@ int g1m_limbuffer_read(void *vcookie, unsigned char *buf, size_t size)
|
|||
|
||||
int g1m_empty_limbuffer(g1m_buffer_t *limbuffer)
|
||||
{
|
||||
g1m_limited_t *lim = (void*)limbuffer->cookie;
|
||||
g1m_buffer_t *buffer = lim->buffer;
|
||||
SKIP(lim->left)
|
||||
g1m_limited_t *lim = (void*)limbuffer->g1m_buffer_cookie;
|
||||
g1m_buffer_t *buffer = lim->g1m_limited_buffer;
|
||||
SKIP(lim->g1m_limited_left)
|
||||
return (0);
|
||||
}
|
||||
/* ************************************************************************** */
|
||||
|
|
|
@ -69,8 +69,8 @@ int g1m_fopen(g1m_handle_t **handle, const char *path, FILE *stream,
|
|||
|
||||
/* make the buffer */
|
||||
g1m_buffer_t buffer = {
|
||||
.cookie = stream,
|
||||
.read = g1m_filebuffer_read
|
||||
.g1m_buffer_cookie = stream,
|
||||
.g1m_buffer_read = g1m_filebuffer_read
|
||||
};
|
||||
|
||||
/* decode opened file */
|
||||
|
@ -118,8 +118,8 @@ int g1m_fwrite(g1m_handle_t *handle, FILE *stream)
|
|||
|
||||
/* make the buffer */
|
||||
g1m_buffer_t buffer = {
|
||||
.cookie = stream,
|
||||
.write = g1m_filebuffer_write
|
||||
.g1m_buffer_cookie = stream,
|
||||
.g1m_buffer_write = g1m_filebuffer_write
|
||||
};
|
||||
|
||||
/* encode to file */
|
||||
|
|
|
@ -39,8 +39,9 @@ int g1m_skip(g1m_buffer_t *buffer, size_t size, uint32_t *checksum)
|
|||
/* read that much */
|
||||
size_t curlen = min(size, 1024);
|
||||
size -= curlen;
|
||||
buffer->_offset += curlen;
|
||||
if ((err = (*buffer->read)(buffer->cookie, buf, curlen))) {
|
||||
buffer->g1m_buffer_offset += curlen;
|
||||
if ((err = (*buffer->g1m_buffer_read)(buffer->g1m_buffer_cookie, buf,
|
||||
curlen))) {
|
||||
log_error("Skipping has failed after %" PRIuSIZE " bytes",
|
||||
orig - size);
|
||||
return (err);
|
||||
|
|
|
@ -56,14 +56,22 @@ int g1m_decode_version(const char *raw, g1m_version_t *version)
|
|||
{
|
||||
/* helper values */
|
||||
const int two = '0' + '0' * 10;
|
||||
const int four = two + '0' * 100 + '0' * 1000;
|
||||
|
||||
/* get the version data */
|
||||
/* get the basic version data */
|
||||
*version = (g1m_version_t){
|
||||
.major = raw[0] * 10 + raw[1] - two,
|
||||
.minor = raw[3] * 10 + raw[4] - two,
|
||||
.revision = raw[6] * 1000 + raw[7] * 100 + raw[8] * 10 + raw[9] - four
|
||||
};
|
||||
.g1m_version_major = raw[0] * 10 + raw[1] - two,
|
||||
.g1m_version_minor = raw[3] * 10 + raw[4] - two};
|
||||
|
||||
/* get normal values */
|
||||
version->g1m_version_zone = raw[6] - '0';
|
||||
version->g1m_version_math = raw[7] - '0';
|
||||
|
||||
/* get build flags */
|
||||
version->g1m_version_flags = 0;
|
||||
if (raw[8] != '0')
|
||||
version->g1m_version_flags |= g1m_versionflag_indev;
|
||||
if (raw[9] != '0')
|
||||
version->g1m_version_flags |= g1m_versionflag_spe;
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
@ -80,8 +88,16 @@ int g1m_decode_version(const char *raw, g1m_version_t *version)
|
|||
|
||||
int g1m_encode_version(const g1m_version_t *version, char *raw)
|
||||
{
|
||||
char buf[11]; sprintf(buf, "%02u.%02u.%04u",
|
||||
version->major, version->minor, version->revision);
|
||||
/* make buffer */
|
||||
char buf[11]; sprintf(buf, "%02u.%02u.%c%c%c%c",
|
||||
version->g1m_version_major,
|
||||
version->g1m_version_minor,
|
||||
version->g1m_version_zone + '0',
|
||||
version->g1m_version_math + '0',
|
||||
version->g1m_version_flags & g1m_versionflag_indev ? '1' : '0',
|
||||
version->g1m_version_flags & g1m_versionflag_spe ? '1' : '0');
|
||||
|
||||
/* copy final */
|
||||
memcpy(raw, buf, 10);
|
||||
return (0);
|
||||
}
|
||||
|
|
Reference in New Issue