Simplified way MCS files are allocated.
This commit is contained in:
parent
7c90619ffe
commit
6f52a704de
|
@ -85,6 +85,9 @@ int g1m_fopen(g1m_t **handle, const char *path, FILE *stream,
|
|||
g1m_type_t expected_type);
|
||||
#endif
|
||||
|
||||
/* make an MCS file out of a head */
|
||||
int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead);
|
||||
|
||||
/* open MCS head for decoding, correct it for encoding */
|
||||
int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
|
||||
int raw_type, const unsigned char *groupname,
|
||||
|
@ -111,7 +114,7 @@ int g1m_decode_casfile_data(g1m_mcsfile_t **handle,
|
|||
/* open newer CAS protocol file head, make file, read content */
|
||||
int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
int g1m_make_caspro_file(g1m_mcsfile_t **file, const g1m_mcshead_t *head);
|
||||
int g1m_decode_caspro_part(g1m_mcsfile_t **file, g1m_buffer_t *buffer);
|
||||
int g1m_decode_caspro_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer);
|
||||
|
||||
/* free handles */
|
||||
void g1m_free(g1m_t *handle);
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
# include <stdlib.h>
|
||||
# include <stdint.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* 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);
|
||||
|
@ -48,4 +51,42 @@ typedef struct {
|
|||
g1m_buffer_announce_t announce;
|
||||
} g1m_buffer_t;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Memory buffer definition */
|
||||
/* ************************************************************************** */
|
||||
/* Cookie structure */
|
||||
typedef struct {
|
||||
const unsigned char *p;
|
||||
size_t left;
|
||||
} g1m_cursor_t;
|
||||
|
||||
/* Related callbacks and functions */
|
||||
int g1m_membuffer_read(void *cookie, unsigned char *dest, size_t size);
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Limited buffer definition */
|
||||
/* ************************************************************************** */
|
||||
/* Cookie structure */
|
||||
typedef struct {
|
||||
g1m_buffer_t *buffer;
|
||||
size_t 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);
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Buffer macros */
|
||||
/* ************************************************************************** */
|
||||
/* Initialize a memory buffer */
|
||||
# define g1m_membuffer(P, SZ) (g1m_buffer_t){ \
|
||||
.cookie = (g1m_cursor_t[]){{.p = (P), .left = (SZ)}}, \
|
||||
.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}
|
||||
|
||||
#endif /* LIBG1M_BUFFER_H */
|
||||
|
|
|
@ -47,8 +47,8 @@ struct caspro_header {
|
|||
uint8_t aux[8]; /* variable: "R\x0A"/"C\x0A", editor: password */
|
||||
|
||||
/* something else (?) */
|
||||
uint8_t nl[2]; /* 'NL' */
|
||||
uint8_t _ffs[11];
|
||||
uint8_t nl[2]; /* 'NL'? */
|
||||
uint8_t _reserved[11];
|
||||
|
||||
/* end of packet */
|
||||
uint8_t checksum;
|
||||
|
|
|
@ -28,21 +28,28 @@
|
|||
# define LIBG1M_FORMATUTILS_H
|
||||
# include <libg1m/format.h>
|
||||
|
||||
/* get type */
|
||||
/* ************************************************************************** */
|
||||
/* General types (`g1m_t`) */
|
||||
/* ************************************************************************** */
|
||||
int g1m_maketype_std(const char *path,
|
||||
unsigned char *main_id, unsigned char *subtype,
|
||||
const char **info, int *check_one, int *check_two,
|
||||
unsigned int *platform, g1m_type_t *type);
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* MCS types (`g1m_mcshead_t`/`g1m_mcsfile_t`) */
|
||||
/* ************************************************************************** */
|
||||
/* get mcs type data */
|
||||
int g1m_maketype_mcs(const char *groupname, const char *filename,
|
||||
unsigned int rawtype, g1m_mcstype_t *type, int *id);
|
||||
int g1m_maketype_mcs(g1m_mcshead_t *head,
|
||||
const char *groupname, const char *dirname,
|
||||
const char *filename, unsigned int rawtype);
|
||||
|
||||
/* get cas type data */
|
||||
int g1m_maketype_cas(const char *datatype, g1m_mcstype_t *type);
|
||||
int g1m_maketype_cas(g1m_mcshead_t *head,
|
||||
const char *datatype);
|
||||
|
||||
/* get caspro type data */
|
||||
int g1m_maketype_caspro(const char *maintype,
|
||||
const char *datatype, g1m_mcstype_t *type);
|
||||
int g1m_maketype_caspro(g1m_mcshead_t *head,
|
||||
const char *maintype, const char *datatype);
|
||||
|
||||
#endif /* LIBG1M_FORMATUTILS_H */
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <libg1m/internals/endian.h>
|
||||
# define MEMBUFFER(P, SZ) g1m_membuffer(P, SZ)
|
||||
# define LIMBUFFER(BUFFER, SZ) g1m_limbuffer(BUFFER, SZ)
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Macros and platform-specific functions */
|
||||
|
@ -86,43 +88,6 @@
|
|||
if (SKIP_err) return (SKIP_err); \
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Memory buffer-related */
|
||||
/* ************************************************************************** */
|
||||
/* Structure */
|
||||
typedef struct {
|
||||
const unsigned char *p;
|
||||
size_t left;
|
||||
} g1m_cursor_t;
|
||||
|
||||
/* Callbacks */
|
||||
int g1m_membuffer_read(void *cookie, unsigned char *dest, size_t size);
|
||||
|
||||
/* Management functions */
|
||||
int g1m_empty_limbuffer(g1m_buffer_t *limbuffer);
|
||||
|
||||
/* Initialize a memory buffer */
|
||||
# define MEMBUFFER(P, SZ) (g1m_buffer_t){ \
|
||||
.cookie = (g1m_cursor_t[]){{.p = (P), .left = (SZ)}}, \
|
||||
.read = g1m_membuffer_read}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Limited buffer */
|
||||
/* ************************************************************************** */
|
||||
/* Structure */
|
||||
typedef struct {
|
||||
g1m_buffer_t *buffer;
|
||||
size_t left;
|
||||
} g1m_limited_t;
|
||||
|
||||
/* Callbacks */
|
||||
int g1m_limbuffer_read(void *cookie, unsigned char *dest, size_t size);
|
||||
|
||||
/* Initialize a limited buffer */
|
||||
# define LIMBUFFER(BUFFER, SZ) (g1m_buffer_t){ \
|
||||
.cookie = (g1m_limited_t[]){{.buffer = (BUFFER), .left = (SZ)}}, \
|
||||
.read = g1m_limbuffer_read}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Decoding functions */
|
||||
/* ************************************************************************** */
|
||||
|
@ -158,10 +123,10 @@ int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer,
|
|||
/* MCS-specific decoding functions */
|
||||
/* ************************************************************************** */
|
||||
# define G1M_MCSFUNC(NAME) \
|
||||
int g1m_decode_mcs_##NAME(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, \
|
||||
uint_fast32_t length);
|
||||
int g1m_decode_mcs_##NAME(g1m_mcsfile_t **handle, g1m_buffer_t *buffer, \
|
||||
g1m_mcshead_t *head);
|
||||
|
||||
G1M_MCSFUNC(alphamem)
|
||||
G1M_MCSFUNC(var)
|
||||
G1M_MCSFUNC(list)
|
||||
G1M_MCSFUNC(matrix)
|
||||
G1M_MCSFUNC(picture)
|
||||
|
@ -178,7 +143,7 @@ G1M_MCSFUNC(string)
|
|||
malloc(sizeof(uint32_t*) * (H) + sizeof(uint32_t) * (W) * (H))
|
||||
# define prepare_pixels(I, W, H) { \
|
||||
uint32_t *PIXPREP_line = (uint32_t*)&(I)[(H)]; \
|
||||
for (int PIXPREP_y = 0; PIXPREP_y < (H); PIXPREP_y++) { \
|
||||
for (unsigned int PIXPREP_y = 0; PIXPREP_y < (H); PIXPREP_y++) { \
|
||||
(I)[PIXPREP_y] = PIXPREP_line; \
|
||||
PIXPREP_line += (W); \
|
||||
}}
|
||||
|
|
|
@ -43,23 +43,26 @@ typedef g1m_mcsfile_type_t g1m_mcstype_t;
|
|||
# define g1m_mcstype_ssheet 0x00000020
|
||||
# define g1m_mcstype_string 0x00000040
|
||||
# define g1m_mcstype_setup 0x00000080
|
||||
# define g1m_mcstype_alphamem 0x00000100
|
||||
# define g1m_mcstype_var 0x00000100
|
||||
# define g1m_mcstype_vct 0x00000200
|
||||
# define g1m_mcstype_variable 0x00000400
|
||||
# define g1m_mcstype_end 0x00000800
|
||||
# define g1m_mcstype_end 0x00000400
|
||||
|
||||
/* MCS file type aliases */
|
||||
# define g1m_mcstype_matrix g1m_mcstype_mat
|
||||
# define g1m_mcstype_pic g1m_mcstype_pict
|
||||
# define g1m_mcstype_picture g1m_mcstype_pict
|
||||
# define g1m_mcstype_capture g1m_mcstype_capt
|
||||
# define g1m_mcstype_spreadsheet g1m_mcstype_ssheet
|
||||
# define g1m_mcstype_vector g1m_mcstype_vct
|
||||
# define g1m_mcstype_alphamem g1m_mcstype_var
|
||||
# define g1m_mcstype_variable g1m_mcstype_var
|
||||
# define g1m_mcstype_variables g1m_mcstype_var
|
||||
|
||||
/* Macros to check if the type uses the ID, and to interact with it */
|
||||
# define g1m_mcstype_uses_id(T) ((T) & (\
|
||||
# define g1m_mcshead_uses_id(H) (((H)->type & (\
|
||||
g1m_mcstype_list | g1m_mcstype_mat | g1m_mcstype_vct | \
|
||||
g1m_mcstype_pict | g1m_mcstype_capt | g1m_mcstype_string | \
|
||||
g1m_mcstype_variable))
|
||||
g1m_mcstype_pict | g1m_mcstype_capt | g1m_mcstype_string) || \
|
||||
((H)->type == g1m_mcstype_var && (H)->count == 1)))
|
||||
# define g1m_get_id_major(I) ((I) >> 5)
|
||||
# define g1m_get_id_minor(I) ((I) & 31)
|
||||
|
||||
|
@ -77,8 +80,16 @@ typedef struct g1m_mcs_cell_s {
|
|||
/* Main structures */
|
||||
/* ************************************************************************** */
|
||||
/* mcs file head flags */
|
||||
# define g1m_mcsflag_last 0x8000 /* was the last part to be received */
|
||||
# define g1m_mcsflag_complex 0x0001 /* is a complex variable */
|
||||
# define g1m_mcsflag_unfinished 0x8000 /* is there still parts to read? */
|
||||
# define g1m_mcsflag_complex 0x0001 /* is a complex variable */
|
||||
|
||||
/* mcs file type -- what type of raw information is there
|
||||
* e.g. `head.flags & g1m_mcsmask_info == g1m_mcsinfo_g1m` */
|
||||
# define g1m_mcsmask_info 0x6000
|
||||
# define g1m_mcsinfo_none 0x0000
|
||||
# define g1m_mcsinfo_mcs 0x2000
|
||||
# define g1m_mcsinfo_cas 0x4000
|
||||
# define g1m_mcsinfo_caspro 0x6000
|
||||
|
||||
/* mcs file head */
|
||||
typedef struct g1m_mcshead_s {
|
||||
|
@ -105,8 +116,8 @@ typedef struct g1m_mcshead_s {
|
|||
} g1m_mcshead_t;
|
||||
|
||||
/* mcs file */
|
||||
# define g1m_has_password(F) (F)->password[0]
|
||||
# define g1m_remove_password(F) (F)->password[0] = 0
|
||||
# define g1m_has_password(F) (F)->head.password[0]
|
||||
# define g1m_remove_password(F) (F)->head.password[0] = 0
|
||||
typedef struct g1m_mcsfile_s {
|
||||
/* head */
|
||||
g1m_mcshead_t head;
|
||||
|
@ -114,16 +125,14 @@ typedef struct g1m_mcsfile_s {
|
|||
/* content (useful when not read) */
|
||||
char *content;
|
||||
|
||||
/* for spreadsheets, lists and matrixes */
|
||||
g1m_mcs_cell_t **cells;
|
||||
|
||||
/* variables */
|
||||
g1m_mcs_cell_t var;
|
||||
g1m_mcs_cell_t *vars;
|
||||
g1m_mcs_cell_t **cells;
|
||||
|
||||
/* for pictures and captures */
|
||||
uint32_t **image; /* 0x0RGB */
|
||||
uint32_t **second_image; /* 0x0RGB */
|
||||
uint32_t **pic; /* 0x0RGB */
|
||||
uint32_t ***pics;
|
||||
} g1m_mcsfile_t;
|
||||
|
||||
#endif /* LIBG1M_MCS_H */
|
||||
|
|
|
@ -65,14 +65,16 @@ void g1m_free_mcsfile_content(g1m_mcsfile_t *handle)
|
|||
}
|
||||
|
||||
/* free the images */
|
||||
if (type & (g1m_mcstype_pict | g1m_mcstype_capt)) {
|
||||
free(handle->image);
|
||||
if (type & g1m_mcstype_pict)
|
||||
free(handle->second_image);
|
||||
if (type & g1m_mcstype_pict) {
|
||||
for (int i = 0; i < handle->head.count; i++)
|
||||
free(handle->pics[i]);
|
||||
if (handle->pics != &handle->pic)
|
||||
free(handle->pics);
|
||||
}
|
||||
|
||||
/* free the vars */
|
||||
if (type & g1m_mcstype_alphamem)
|
||||
if ((type & g1m_mcstype_alphamem)
|
||||
&& handle->vars != &handle->var)
|
||||
free(handle->vars);
|
||||
|
||||
/* free the content */
|
||||
|
|
|
@ -42,7 +42,7 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, const char *datatype,
|
|||
if (!head) return (-1);
|
||||
|
||||
/* check the data type */
|
||||
if (g1m_maketype_cas(datatype, &head->type))
|
||||
if (g1m_maketype_cas(head, datatype))
|
||||
return (g1m_error_unrecognized);
|
||||
|
||||
/* fill the handle */
|
||||
|
|
|
@ -138,31 +138,22 @@ static int read_picture(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
uint8_t rawpx[total]; READ(rawpx, total)
|
||||
uint8_t *px = rawpx;
|
||||
|
||||
/* allocate the file */
|
||||
g1m_mcsfile_t *file = malloc(sizeof(g1m_mcsfile_t));
|
||||
if (!file) return (g1m_error_alloc);
|
||||
memset(file, 0, sizeof(g1m_mcsfile_t));
|
||||
|
||||
/* make the pixels */
|
||||
int width = pct.width, height = pct.height;
|
||||
uint32_t **img = alloc_pixels(width, height);
|
||||
if (!img) { free(file); return (g1m_error_alloc); }
|
||||
|
||||
/* set the head */
|
||||
file->head.type = g1m_mcstype_capt;
|
||||
memcpy(file->head.name, name, strlen(name) + 1);
|
||||
/* make the head and allocate file */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_capture,
|
||||
.width = pct.width, .height = pct.height,
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
/* TODO: id */
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* set the pixels */
|
||||
prepare_pixels(img, width, height)
|
||||
file->head.width = width;
|
||||
file->head.height = height;
|
||||
file->image = img;
|
||||
for (int x = 0; x < width; x++) for (int y = 0; y < height; y++)
|
||||
uint32_t **img = (*pfile)->pics[0];
|
||||
for (int x = 0; x < pct.width; x++) for (int y = 0; y < pct.height; y++)
|
||||
img[y][x] = colours[*px++];
|
||||
|
||||
/* finish */
|
||||
*pfile = file;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -179,8 +170,7 @@ static int read_picture(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
||||
int big_endian)
|
||||
{
|
||||
int err;
|
||||
|
||||
int err; *pfile = NULL;
|
||||
/* general record things */
|
||||
char name[13]; uint_fast32_t record_length;
|
||||
if ((err = read_top(buffer, name, &record_length))
|
||||
|
@ -198,52 +188,38 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
double tab[total]; READ(tab, total * sizeof(double))
|
||||
double *raw = tab;
|
||||
|
||||
/* allocate handle */
|
||||
g1m_mcsfile_t *file = malloc(sizeof(g1m_mcsfile_t));
|
||||
if (!file) return (g1m_error_alloc);
|
||||
memset(file, 0, sizeof(g1m_mcsfile_t));
|
||||
|
||||
/* allocate matrix */
|
||||
file->cells = malloc(sizeof(g1m_mcs_cell_t*) * height);
|
||||
if (!file->cells) { free(file); return (g1m_error_alloc); }
|
||||
g1m_mcs_cell_t *rws = malloc(sizeof(g1m_mcs_cell_t) * height * width);
|
||||
if (!rws) { free(file); free(file->cells); return (g1m_error_alloc); }
|
||||
|
||||
/* set the information */
|
||||
file->head.type = g1m_mcstype_mat;
|
||||
memcpy(file->head.name, name, strlen(name) + 1);
|
||||
/* make the head and allocate file */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_matrix,
|
||||
.width = width, .height = height,
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
/* TODO: id */
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* read the matrix */
|
||||
file->head.width = width;
|
||||
file->head.height = height;
|
||||
for (int y = 0; y < height; y++) {
|
||||
/* correct offset in matrix */
|
||||
file->cells[y] = &rws[width * y];
|
||||
|
||||
/* read column */
|
||||
for (int x = 0; x < width; x++) {
|
||||
/* read the bcd */
|
||||
g1m_bcd_t bcd; g1m_bcd_fromdouble(*raw++, &bcd);
|
||||
g1m_mcs_cell_t **cells = (*pfile)->cells;
|
||||
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) {
|
||||
/* read the bcd */
|
||||
g1m_bcd_t bcd; g1m_bcd_fromdouble(*raw++, &bcd);
|
||||
|
||||
#if LOGLEVEL <= ll_info
|
||||
/* log the bcd */
|
||||
char buf[G1M_BCD_GOODBUFSIZE];
|
||||
g1m_bcdtoa(&bcd, buf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%d][%d] %s", y, x, buf);
|
||||
/* log the bcd */
|
||||
char buf[G1M_BCD_GOODBUFSIZE];
|
||||
g1m_bcdtoa(&bcd, buf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%d][%d] %s", y, x, buf);
|
||||
#endif
|
||||
|
||||
/* make the cell */
|
||||
file->cells[y][x] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
};
|
||||
}
|
||||
/* make the cell */
|
||||
cells[y][x] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
};
|
||||
}
|
||||
|
||||
/* no error */
|
||||
*pfile = file;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -260,8 +236,7 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
||||
int big_endian)
|
||||
{
|
||||
int err;
|
||||
|
||||
int err; *pfile = NULL;
|
||||
/* general record things */
|
||||
char name[13]; uint_fast32_t record_length;
|
||||
if ((err = read_top(buffer, name, &record_length))
|
||||
|
@ -277,28 +252,20 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
double tab[len]; READ(tab, len * sizeof(double))
|
||||
double *raw = tab;
|
||||
|
||||
/* allocate handle */
|
||||
g1m_mcsfile_t *file = malloc(sizeof(g1m_mcsfile_t));
|
||||
if (!file) return (g1m_error_alloc);
|
||||
memset(file, 0, sizeof(g1m_mcsfile_t));
|
||||
|
||||
/* allocate matrix */
|
||||
file->cells = malloc(sizeof(g1m_mcs_cell_t*) * len);
|
||||
if (!file->cells) { free(file); return (g1m_error_alloc); }
|
||||
g1m_mcs_cell_t *rws = malloc(sizeof(g1m_mcs_cell_t) * len);
|
||||
if (!rws) { free(file->cells); free(file); return (g1m_error_alloc); }
|
||||
|
||||
/* set the information */
|
||||
file->head.type = g1m_mcstype_list;
|
||||
memcpy(file->head.name, name, strlen(name) + 1);
|
||||
/* make head */
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_list,
|
||||
.width = 1, .height = len
|
||||
};
|
||||
memcpy(head.name, name, strlen(name) + 1);
|
||||
/* TODO: id */
|
||||
err = g1m_make_mcsfile(pfile, &head);
|
||||
if (err) return (err);
|
||||
|
||||
/* read the list */
|
||||
file->head.width = 1;
|
||||
file->head.height = len;
|
||||
g1m_mcs_cell_t **cells = (*pfile)->cells;
|
||||
for (int x = 0; x < len; x++) {
|
||||
/* correct matrix, read bcd */
|
||||
file->cells[x] = &rws[x];
|
||||
/* read bcd */
|
||||
g1m_bcd_t bcd; g1m_bcd_fromdouble(*raw++, &bcd);
|
||||
|
||||
#if LOGLEVEL <= ll_info
|
||||
|
@ -309,7 +276,7 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
#endif
|
||||
|
||||
/* set the cell */
|
||||
file->cells[x][0] = (g1m_mcs_cell_t){
|
||||
cells[x][0] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
|
@ -317,7 +284,6 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
}
|
||||
|
||||
/* no error */
|
||||
*pfile = file;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Head decoding function */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_decode_caspro_head:
|
||||
* Decode a CASIOLINK Protocol header.
|
||||
|
@ -32,10 +35,28 @@
|
|||
|
||||
int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* read header, get type */
|
||||
DREAD(hd, caspro_header)
|
||||
hd.length = be16toh(hd.length);
|
||||
if (g1m_maketype_caspro(head, (char*)hd.type, (char*)hd.data))
|
||||
return (g1m_error_unknown);
|
||||
|
||||
/* read specific data */
|
||||
if (head->type == g1m_mcstype_program) {
|
||||
/* copy password */
|
||||
char *endp = memchr(hd.aux, 0xFF, 8);
|
||||
size_t plen = endp ? (size_t)(endp - (char*)hd.aux) : 8;
|
||||
memcpy(head->password, hd.aux, plen);
|
||||
head->password[plen] = 0;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
return (g1m_error_unknown);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Part decoding function */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_decode_caspro_part:
|
||||
* Decode a CASIOLINK Protocol content part.
|
||||
|
@ -47,8 +68,7 @@ int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
|||
* @return if there was an error, or not.
|
||||
*/
|
||||
|
||||
int g1m_decode_caspro_part(g1m_mcsfile_t **file,
|
||||
const g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
||||
int g1m_decode_caspro_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* TODO */
|
||||
return (g1m_error_unknown);
|
|
@ -22,94 +22,68 @@
|
|||
* g1m_decode_mcs_list:
|
||||
* Decode an List.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg size the length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_list(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t size)
|
||||
int g1m_decode_mcs_list(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* read header */
|
||||
DREAD(hd, mcs_listheader)
|
||||
|
||||
/* correct endianess */
|
||||
uint_fast16_t elcount = be16toh(hd.element_count);
|
||||
|
||||
/* log */
|
||||
log_info("Title is '%.8s'", hd.title);
|
||||
|
||||
/* prepare browsing */
|
||||
size -= sizeof(struct mcs_listheader);
|
||||
/* make final head */
|
||||
head->width = 1;
|
||||
head->height = elcount;
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* make tabs */
|
||||
g1m_bcd_t real[elcount], imgn[elcount];
|
||||
if (elcount) {
|
||||
int one_imgn = 0;
|
||||
mcs_bcd_t tab[elcount];
|
||||
/* read the real parts */
|
||||
size_t elsize = sizeof(mcs_bcd_t) * elcount;
|
||||
size -= elsize; {
|
||||
/* read reals */
|
||||
READ(tab, elsize)
|
||||
/* main copying loop */
|
||||
g1m_mcs_cell_t **tab = (*handle)->cells; int one_imgn = 0;
|
||||
for (uint_fast32_t y = 0; y < elcount; y++) {
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
one_imgn |= g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
|
||||
/* convert them */
|
||||
for (uint_fast16_t i = 0; i < elcount; i++)
|
||||
one_imgn |= g1m_bcd_frommcs(&tab[i], &real[i]);
|
||||
}
|
||||
/* prepare index and store */
|
||||
tab[y][0] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
};
|
||||
}
|
||||
|
||||
/* read the imaginary parts */
|
||||
if (one_imgn) {
|
||||
READ(tab, elsize)
|
||||
|
||||
/* convert */
|
||||
for (uint_fast16_t i = 0; i < elcount; i++)
|
||||
g1m_bcd_frommcs(&tab[i], &imgn[i]);
|
||||
/* main copying loop for imaginary parts */
|
||||
if (one_imgn) for (uint_fast32_t y = 0; y < elcount; y++) {
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
if (g1m_bcd_has_special(&tab[y][0].real)) {
|
||||
g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
tab[y][0].imgn = bcd;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill final tab */
|
||||
handle->head.height = elcount;
|
||||
handle->head.width = 1;
|
||||
handle->cells = NULL;
|
||||
if (elcount) {
|
||||
#if LOGLEVEL >= ll_info
|
||||
char rbuf[G1M_BCD_GOODBUFSIZE], ibuf[G1M_BCD_GOODBUFSIZE];
|
||||
#endif
|
||||
|
||||
/* allocate final tab */
|
||||
g1m_mcs_cell_t **tab = malloc(sizeof(g1m_mcs_cell_t*) * elcount);
|
||||
if (!tab) return (g1m_error_alloc);
|
||||
g1m_mcs_cell_t *rws = malloc(sizeof(g1m_mcs_cell_t) * elcount);
|
||||
if (!tab) { free(tab); return (g1m_error_alloc); }
|
||||
|
||||
/* main copying loop */
|
||||
for (uint_fast32_t y = 0; y < elcount; y++) {
|
||||
int has_complex = g1m_bcd_has_special(&real[y]);
|
||||
|
||||
/* prepare index and store */
|
||||
tab[y] = &rws[y];
|
||||
tab[y][0] = (g1m_mcs_cell_t){
|
||||
.used = 1,
|
||||
.real = real[y],
|
||||
.imgn = has_complex ? imgn[y] : (g1m_bcd_t){}
|
||||
};
|
||||
|
||||
#if LOGLEVEL >= ll_info
|
||||
g1m_bcdtoa(&tab[y][0].real, rbuf, G1M_BCD_GOODBUFSIZE);
|
||||
if (has_complex) {
|
||||
g1m_bcdtoa(&tab[y][0].imgn, ibuf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%" PRIuFAST32 "] %si + %s", y, ibuf, rbuf);
|
||||
} else
|
||||
log_info("[%" PRIuFAST32 "] %s", y, rbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* don't forget your baguette! */
|
||||
handle->cells = tab;
|
||||
#if LOGLEVEL <= ll_info
|
||||
/* logging loop */
|
||||
char rbuf[G1M_BCD_GOODBUFSIZE], ibuf[G1M_BCD_GOODBUFSIZE];
|
||||
for (uint_fast32_t y = 0; y < elcount; y++) {
|
||||
g1m_bcdtoa(&tab[y][0].real, rbuf, G1M_BCD_GOODBUFSIZE);
|
||||
if (g1m_bcd_has_special(&tab[y][0].real)) {
|
||||
g1m_bcdtoa(&tab[y][0].imgn, ibuf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%" PRIuFAST32 "] %si + %s", y, ibuf, rbuf);
|
||||
} else
|
||||
log_info("[%" PRIuFAST32 "] %s", y, rbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
||||
/* in case */
|
||||
fail:
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
|
|
@ -22,22 +22,19 @@
|
|||
* g1m_decode_mcs_matrix:
|
||||
* Decode a matrix.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_matrix(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
g1m_mcs_cell_t **tab, *rws;
|
||||
int err = g1m_error_alloc;
|
||||
|
||||
/* read header */
|
||||
DREAD(hd, mcs_matheader)
|
||||
|
||||
/* correct endianess */
|
||||
hd.width = be16toh(hd.width);
|
||||
hd.height = be16toh(hd.height);
|
||||
|
||||
|
@ -45,62 +42,58 @@ int g1m_decode_mcs_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
uint_fast32_t w = hd.width, h = hd.height;
|
||||
log_info("Matrix size is %" PRIuFAST32 "*%" PRIuFAST32, w, h);
|
||||
|
||||
/* store dimensions */
|
||||
handle->head.width = w;
|
||||
handle->head.height = h;
|
||||
handle->cells = NULL;
|
||||
/* make final head */
|
||||
head->width = w;
|
||||
head->height = h;
|
||||
if ((err = g1m_make_mcsfile(handle, head)))
|
||||
return (err);
|
||||
|
||||
if (w && h) {
|
||||
/* alloc real matrix */
|
||||
tab = malloc(sizeof(g1m_mcs_cell_t*) * h);
|
||||
if (!tab) return (g1m_error_alloc);
|
||||
rws = malloc(sizeof(g1m_mcs_cell_t) * h * w);
|
||||
if (!rws) { free(tab); return (g1m_error_alloc); }
|
||||
/* main copying loop */
|
||||
g1m_mcs_cell_t **tab = (*handle)->cells; int one_imgn = 0;
|
||||
for (uint_fast32_t y = 0; y < h; y++)
|
||||
for (uint_fast32_t x = 0; x < w; x++) {
|
||||
/* read the cell */
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
one_imgn |= g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
|
||||
/* copy */
|
||||
int one_imgn = 0;
|
||||
g1m_bcd_t bcd;
|
||||
for (uint_fast32_t y = 0; y < h; y++) {
|
||||
/* prepare index */
|
||||
tab[y] = &rws[y * w];
|
||||
|
||||
/* read squares */
|
||||
for (uint_fast32_t x = 0; x < w; x++) {
|
||||
/* read the cell */
|
||||
GDREAD(rawbcd, bcd)
|
||||
one_imgn |= g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
|
||||
/* store it */
|
||||
tab[y][x] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* check imaginary parts */
|
||||
if (one_imgn) {
|
||||
for (uint_fast32_t y = 0; y < h; y++)
|
||||
for (uint_fast32_t x = 0; x < w; x++) {
|
||||
GDREAD(rawbcd, bcd)
|
||||
if (g1m_bcd_has_special(&tab[y][x].real)) {
|
||||
g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
tab[y][x].imgn = bcd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* your sandwich, monsieur. */
|
||||
handle->cells = tab;
|
||||
/* store it */
|
||||
tab[y][x] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
.used = 1
|
||||
};
|
||||
}
|
||||
|
||||
/* check imaginary parts */
|
||||
if (one_imgn) for (uint_fast32_t y = 0; y < h; y++)
|
||||
for (uint_fast32_t x = 0; x < w; x++) {
|
||||
g1m_bcd_t bcd; GDREAD(rawbcd, bcd)
|
||||
if (g1m_bcd_has_special(&tab[y][x].real)) {
|
||||
g1m_bcd_frommcs(&rawbcd, &bcd);
|
||||
tab[y][x].imgn = bcd;
|
||||
}
|
||||
}
|
||||
|
||||
#if LOGLEVEL <= ll_info
|
||||
/* logging loop */
|
||||
char rbuf[G1M_BCD_GOODBUFSIZE], ibuf[G1M_BCD_GOODBUFSIZE];
|
||||
for (uint_fast32_t y = 0; y < h; y++)
|
||||
for (uint_fast32_t x = 0; x < w; x++) {
|
||||
g1m_bcdtoa(&tab[y][x].real, rbuf, G1M_BCD_GOODBUFSIZE);
|
||||
if (g1m_bcd_has_special(&tab[y][x].real)) {
|
||||
g1m_bcdtoa(&tab[y][x].imgn, ibuf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%" PRIuFAST32 "] %si + %s", y, ibuf, rbuf);
|
||||
} else
|
||||
log_info("[%" PRIuFAST32 "] %s", y, rbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
||||
/* in case of unexpected EOF */
|
||||
fail:
|
||||
free(tab);
|
||||
free(rws);
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* @arg height the image height.
|
||||
*/
|
||||
|
||||
static int get_image(g1m_buffer_t *buffer, uint32_t ***img,
|
||||
static int get_image(g1m_buffer_t *buffer, uint32_t **image,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
/* get raw pixels */
|
||||
|
@ -40,18 +40,8 @@ static int get_image(g1m_buffer_t *buffer, uint32_t ***img,
|
|||
uint8_t buf[bufsize];
|
||||
READ(buf, bufsize)
|
||||
|
||||
/* alloc */
|
||||
*img = malloc(height * (sizeof(uint32_t*))
|
||||
+ width * height * sizeof(uint32_t));
|
||||
if (!*img)
|
||||
return (g1m_error_alloc);
|
||||
|
||||
/* fill */
|
||||
uint32_t **image = *img;
|
||||
for (uint_fast16_t y = 0; y < height; y++) {
|
||||
/* setup index */
|
||||
image[y] = (uint32_t*)&image[height] + y * width;
|
||||
|
||||
/* init vars for monochrome with fill bits image browsing */
|
||||
uint8_t *b = &buf[y * linesize];
|
||||
int bit = 1 << 7;
|
||||
|
@ -78,65 +68,72 @@ static int get_image(g1m_buffer_t *buffer, uint32_t ***img,
|
|||
* g1m_decode_mcs_capture:
|
||||
* Decode a capture.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_capture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_capture(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* read header */
|
||||
DREAD(hd, mcs_captureheader)
|
||||
|
||||
/* correct endianess */
|
||||
hd.width = be16toh(hd.width);
|
||||
hd.height = be16toh(hd.height);
|
||||
|
||||
/* store */
|
||||
handle->head.width = hd.width;
|
||||
handle->head.height = hd.height;
|
||||
/* make final head and file */
|
||||
head->width = hd.width;
|
||||
head->height = hd.height;
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* print info */
|
||||
log_info("capture is %dx%d sized", handle->head.width, handle->head.height);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
log_info("capture is %dx%d sized", h->head.width, h->head.height);
|
||||
|
||||
/* get the image and return */
|
||||
return (get_image(buffer, &handle->image,
|
||||
handle->head.width, handle->head.height));
|
||||
err = get_image(buffer, h->pics[0], h->head.width, h->head.height);
|
||||
if (err) { g1m_free_mcsfile(*handle); free(*handle); }
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_decode_mcs_picture:
|
||||
* Decode a picture.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_picture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_picture(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* store some dimensions, in case. */
|
||||
handle->head.width = 128;
|
||||
handle->head.height = 64;
|
||||
/* make final head */
|
||||
head->width = 128;
|
||||
head->height = 64;
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* get the first image */
|
||||
if ((err = get_image(buffer, &handle->image, 128, 64))) {
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
if ((err = get_image(buffer, h->pics[0], 128, 64))) {
|
||||
log_fatal("Failed to get the first image.");
|
||||
return (err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* and the second */
|
||||
if ((err = get_image(buffer, &handle->second_image, 128, 64))) {
|
||||
if ((err = get_image(buffer, h->pics[1], 128, 64))) {
|
||||
log_fatal("Failed to get the second image.");
|
||||
return (err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
fail:
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
|
|
@ -22,34 +22,39 @@
|
|||
* g1m_decode_mcs_program:
|
||||
* Decode a program.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_program(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_program(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* read header */
|
||||
DREAD(hd, mcs_programheader)
|
||||
|
||||
/* print header data */
|
||||
log_info("Program password is '%.8s'.", hd.password);
|
||||
|
||||
/* store info */
|
||||
strncpy(handle->head.password, (char*)hd.password, 8);
|
||||
handle->head.password[8] = 0;
|
||||
/* 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? */
|
||||
err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* get content */
|
||||
size_t content_size = length - sizeof(struct mcs_programheader);
|
||||
log_info("Getting program content (%" PRIuSIZE "o)", content_size);
|
||||
handle->content = malloc(content_size + 1);
|
||||
handle->head.size = content_size + 1;
|
||||
if (!handle->content) return (g1m_error_alloc);
|
||||
READ(handle->content, content_size);
|
||||
handle->content[content_size] = 0;
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
log_info("Getting program content (%" PRIuSIZE "o)", head->size);
|
||||
GREAD(h->content, head->size - 1);
|
||||
h->content[head->size] = 0;
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
fail:
|
||||
g1m_free_mcsfile(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
|
|
@ -22,18 +22,18 @@
|
|||
* g1m_decode_mcs_setup:
|
||||
* Decode settings.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_setup(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_setup(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
(void)handle;
|
||||
log_info("Settings MCS file is not managed yet.");
|
||||
/* TODO */
|
||||
SKIP(length)
|
||||
return (0);
|
||||
SKIP(head->size)
|
||||
return (g1m_make_mcsfile(handle, head));
|
||||
}
|
||||
|
|
|
@ -22,26 +22,22 @@
|
|||
* g1m_decode_mcs_spreadsheet:
|
||||
* Decode a spreadsheet.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* read header */
|
||||
DREAD(hd, mcs_spreadsheetheader)
|
||||
|
||||
/* check if the spreadsheet type is known */
|
||||
if (hd.has_subheader != 0x01)
|
||||
return (0);
|
||||
|
||||
/* read subheader */
|
||||
DREAD(shd, mcs_spreadsheet_subheader)
|
||||
|
||||
/* correct endianness */
|
||||
uint_fast32_t colcount = hd.column_count;
|
||||
colcount = be32toh(colcount << 8);
|
||||
shd.defs_size = be32toh(shd.defs_size);
|
||||
|
@ -108,32 +104,16 @@ int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
rows++, cols++;
|
||||
|
||||
/* create final tab */
|
||||
handle->cells = NULL;
|
||||
handle->head.width = 0;
|
||||
handle->head.height = 0;
|
||||
if (cells_count) {
|
||||
handle->head.width = cols;
|
||||
handle->head.height = rows;
|
||||
head->width = 0; head->height = 0;
|
||||
if (cells_count) { head->width = cols; head->height = rows; }
|
||||
int err = g1m_make_mcsfile(handle, head);
|
||||
if (err) return (err);
|
||||
|
||||
/* alloc */
|
||||
g1m_mcs_cell_t **tab = malloc(sizeof(g1m_mcs_cell_t*) * cols);
|
||||
if (!tab) return (g1m_error_alloc);
|
||||
g1m_mcs_cell_t *rws = malloc(sizeof(g1m_mcs_cell_t) * cols * rows);
|
||||
if (!rws) { free(tab); return (g1m_error_alloc); }
|
||||
|
||||
/* main copying loop */
|
||||
for (uint_fast32_t y = 0; y < cols; y++) {
|
||||
/* prepare index */
|
||||
tab[y] = &rws[y * rows];
|
||||
|
||||
/* copy each cell */
|
||||
for (uint_fast32_t x = 0; x < rows; x++)
|
||||
tab[y][x] = cells[x * 1000 + y];
|
||||
}
|
||||
|
||||
/* i used to be a cow. */
|
||||
handle->cells = tab;
|
||||
}
|
||||
/* main copying loop */
|
||||
g1m_mcs_cell_t **tab = (*handle)->cells;
|
||||
for (uint_fast32_t y = 0; y < head->height; y++)
|
||||
for (uint_fast32_t x = 0; x < head->width; x++)
|
||||
tab[y][x] = cells[x * 1000 + y];
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
|
|
@ -22,20 +22,22 @@
|
|||
* g1m_decode_mcs_string:
|
||||
* Decode an MCS string.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_string(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_string(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
(void)handle;
|
||||
|
||||
/* print content */
|
||||
log_info("String MCS file is not managed yet. Content:");
|
||||
uint8_t str[length];
|
||||
READ(str, length);
|
||||
uint_fast32_t length = head->size;
|
||||
uint8_t str[length]; READ(str, length);
|
||||
logm_info(str, length);
|
||||
/* TODO */
|
||||
return (0);
|
||||
|
||||
return (g1m_make_mcsfile(handle, head));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* *****************************************************************************
|
||||
* decode/mcs/alphamem.c -- decode an MCS alpha memory file.
|
||||
* decode/mcs/var.c -- decode an MCS variable/alpha memory file.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
|
@ -19,50 +19,37 @@
|
|||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* g1m_decode_mcs_alphamem:
|
||||
* g1m_decode_mcs_var:
|
||||
* Decode alpha memory (variables).
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg handle the handle to make.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @arg length the data length.
|
||||
* @arg head the pre-filled head to complete and use.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_decode_mcs_alphamem(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
||||
uint_fast32_t length)
|
||||
int g1m_decode_mcs_var(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
|
||||
g1m_mcshead_t *head)
|
||||
{
|
||||
/* read the data */
|
||||
uint_fast32_t length = head->size;
|
||||
uint8_t buf[length];
|
||||
READ(buf, length)
|
||||
|
||||
/* count number of vars, act if there is a single variable */
|
||||
int count = length / (2 * sizeof(mcs_bcd_t));
|
||||
handle->head.count = count;
|
||||
if (count == 1) {
|
||||
mcs_bcd_t *b = (void*)buf;
|
||||
g1m_bcd_frommcs(b++, &handle->var.real);
|
||||
g1m_bcd_frommcs(b++, &handle->var.imgn);
|
||||
handle->var.used = 1;
|
||||
handle->vars = &handle->var; /* compatibility */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* allocate the vars table */
|
||||
handle->vars = malloc(handle->head.count * sizeof(g1m_mcs_cell_t));
|
||||
if (!handle->vars) return (g1m_error_alloc);
|
||||
/* complete header */
|
||||
head->count = length / (2 * sizeof(mcs_bcd_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 (int i = 0; i < count; i++) {
|
||||
g1m_bcd_frommcs(b++, &handle->vars[i].real);
|
||||
g1m_bcd_frommcs(b++, &handle->vars[i].imgn);
|
||||
handle->vars[i].used = 1;
|
||||
for (int 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].used = 1;
|
||||
}
|
||||
|
||||
/* copy */
|
||||
size_t tocopy = length - length % sizeof(g1m_mcs_cell_t);
|
||||
memcpy(handle->vars, buf, tocopy);
|
||||
|
||||
/* no problem, woop woop */
|
||||
return (0);
|
||||
}
|
|
@ -24,7 +24,8 @@
|
|||
/* Type correspondance list */
|
||||
/* ************************************************************************** */
|
||||
/* MCS file parsing function type */
|
||||
typedef int (*mcs_decode_func_t)(g1m_mcsfile_t*, g1m_buffer_t*, uint_fast32_t);
|
||||
typedef int (*mcs_decode_func_t)(g1m_mcsfile_t**, g1m_buffer_t*,
|
||||
g1m_mcshead_t*);
|
||||
|
||||
/* Correspondance type */
|
||||
struct mcs_corresp {
|
||||
|
@ -43,8 +44,7 @@ static struct mcs_corresp mcs_types[] = {
|
|||
{g1m_mcstype_capt, FUNC(capture)},
|
||||
{g1m_mcstype_string, FUNC(string)},
|
||||
{g1m_mcstype_setup, FUNC(setup)},
|
||||
{g1m_mcstype_alphamem, FUNC(alphamem)},
|
||||
{g1m_mcstype_variable, FUNC(alphamem)},
|
||||
{g1m_mcstype_alphamem, FUNC(var)},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -93,30 +93,19 @@ int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
|
|||
{
|
||||
/* check that we have a head, lol */
|
||||
if (!head) return (-1);
|
||||
head->size = filesize;
|
||||
|
||||
/* look for the raw type */
|
||||
if (g1m_maketype_mcs((char*)groupname, (char*)filename, raw_type,
|
||||
&head->type, &head->id))
|
||||
head->type = g1m_mcstype_unknown;
|
||||
g1m_maketype_mcs(head, (char*)groupname, (char*)dirname,
|
||||
(char*)filename, raw_type);
|
||||
log_info("libg1m file type is 0x%08" PRIXMCSTYPE, head->type);
|
||||
#if LOGLEVEL <= ll_info
|
||||
if (g1m_mcstype_uses_id(head->type)) {
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* copy the name and size */
|
||||
memcpy(head->name, filename, 8); head->name[8] = 0;
|
||||
head->size = filesize;
|
||||
|
||||
/* save raw data */
|
||||
head->_rawtype = raw_type;
|
||||
memcpy(head->_group, groupname, 16); head->_group[16] = 0;
|
||||
if (dirname) {
|
||||
memcpy(head->_dirname, dirname, 8); head->_dirname[8] = 0;
|
||||
} else memset(head->_dirname, 0, 9);
|
||||
|
||||
/* everything went well! */
|
||||
return (0);
|
||||
}
|
||||
|
@ -144,15 +133,7 @@ int g1m_decode_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *head,
|
|||
|
||||
/* check that the head is there */
|
||||
if (!head) return (g1m_error_op);
|
||||
|
||||
/* create handle */
|
||||
*handle = malloc(sizeof(g1m_mcsfile_t));
|
||||
if (!handle) return (g1m_error_alloc);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
memset(h, 0, sizeof(g1m_mcsfile_t));
|
||||
|
||||
/* copy the head */
|
||||
memcpy(&h->head, head, sizeof(g1m_mcshead_t));
|
||||
g1m_mcshead_t h = *head;
|
||||
|
||||
/* look for the parsing function */
|
||||
mcs_decode_func_t decode = lookup_mcsfile_decode(head->type);
|
||||
|
@ -161,42 +142,35 @@ int g1m_decode_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *head,
|
|||
goto notparsing;
|
||||
}
|
||||
|
||||
/* read the buffer (safer) */
|
||||
uint8_t *buf = malloc(head->size);
|
||||
if (!buf) return (g1m_error_alloc);
|
||||
READ(buf, head->size)
|
||||
|
||||
/* decode */
|
||||
g1m_buffer_t membuf = MEMBUFFER(buf, head->size);
|
||||
err = (*decode)(h, &membuf, head->size);
|
||||
free(buf);
|
||||
if (err) goto fail;
|
||||
if (!head->size) err = (*decode)(handle, buffer, &h);
|
||||
else {
|
||||
g1m_buffer_t lbuf = LIMBUFFER(buffer, head->size);
|
||||
err = (*decode)(handle, &lbuf, &h);
|
||||
if (lbuf._offset < head->size) SKIP(head->size - lbuf._offset)
|
||||
}
|
||||
|
||||
/* no error :D */
|
||||
/* oh yeah, and go away. */
|
||||
if (err) goto fail;
|
||||
return (0);
|
||||
|
||||
notparsing:
|
||||
/* allocate enough space */
|
||||
h->content = malloc(head->size);
|
||||
err = g1m_error_alloc;
|
||||
if (!h->content) goto fail;
|
||||
if ((err = g1m_make_mcsfile(handle, &h)))
|
||||
return (err);
|
||||
|
||||
/* read the content */
|
||||
GREAD(h->content, head->size)
|
||||
GREAD((*handle)->content, h.size)
|
||||
|
||||
/* log */
|
||||
log_info("File content:");
|
||||
logm_info(h->content, head->size);
|
||||
logm_info((*handle)->content, h.size);
|
||||
|
||||
/* saved normally */
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
if (h) {
|
||||
if (h->content) free(h->content);
|
||||
free(h);
|
||||
}
|
||||
*handle = NULL;
|
||||
g1m_free_mcsfile(*handle);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -263,8 +237,6 @@ int g1m_decode_std_mcs(g1m_t *handle, g1m_buffer_t *buffer,
|
|||
for (uint_fast32_t i = 0; i < hd.subcount; i++) {
|
||||
/* get the part header */
|
||||
GDREAD(fhd, mcs_fileheader)
|
||||
|
||||
/* correct endianess */
|
||||
fhd.datalength = be32toh(fhd.datalength);
|
||||
|
||||
/* log info about the subpart */
|
||||
|
|
|
@ -122,7 +122,7 @@ int g1m_decode_std_g3p(g1m_t *handle, g1m_buffer_t *buffer,
|
|||
}
|
||||
|
||||
/* allocate picture in handle */
|
||||
int w = ihd.width, h = ihd.height;
|
||||
unsigned int w = ihd.width, h = ihd.height;
|
||||
handle->width = w;
|
||||
handle->height = h;
|
||||
handle->pixels = alloc_pixels(w, h);
|
||||
|
|
|
@ -19,6 +19,108 @@
|
|||
#include <libg1m/internals.h>
|
||||
#define MCS_CHUNK_SIZE 16
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Allocate files and content */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_make_mcsfile:
|
||||
* Make an MCS file out of a head.
|
||||
*
|
||||
* Will allocate all of the required parts of the MCS file for it to be
|
||||
* filled later.
|
||||
*
|
||||
* @arg handle the file to allocate.
|
||||
* @arg rawhead the head to use.
|
||||
* @return the error (if any).
|
||||
*/
|
||||
|
||||
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);
|
||||
g1m_mcsfile_t *h = *handle;
|
||||
memset(h, 0, sizeof(g1m_mcsfile_t));
|
||||
|
||||
/* copy the head */
|
||||
memcpy(&h->head, rawhead, sizeof(g1m_mcshead_t));
|
||||
g1m_mcshead_t *head = &h->head;
|
||||
|
||||
/* act differently according to the context */
|
||||
switch (head->type) {
|
||||
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;
|
||||
if (wd && ht) {
|
||||
h->cells = malloc(sizeof(g1m_mcs_cell_t*) * ht);
|
||||
if (!h->cells) goto fail;
|
||||
h->cells[0] = malloc(sizeof(g1m_mcs_cell_t) * wd * ht);
|
||||
if (!h->cells[0]) { free(h->cells); goto fail; }
|
||||
|
||||
for (int y = 1; y < ht; y++)
|
||||
h->cells[y] = &h->cells[0][h->head.width * y];
|
||||
}
|
||||
break;
|
||||
|
||||
case g1m_mcstype_var:
|
||||
if (head->count <= 1) h->vars = &h->var;
|
||||
else {
|
||||
h->vars = malloc(sizeof(g1m_mcs_cell_t) * head->count);
|
||||
if (!h->vars) goto fail;
|
||||
memset(h->vars, 0, sizeof(g1m_mcs_cell_t) * head->count);
|
||||
}
|
||||
break;
|
||||
|
||||
case g1m_mcstype_pict: case g1m_mcstype_capt:
|
||||
/* set count */
|
||||
head->count = (head->type == g1m_mcstype_pict) ? 2 : 1;
|
||||
|
||||
/* allocate directory */
|
||||
if (head->count <= 1) h->pics = &h->pic;
|
||||
else {
|
||||
h->pics = malloc(sizeof(uint32_t**) * head->count);
|
||||
if (!h->pics) goto fail;
|
||||
}
|
||||
|
||||
/* allocate */
|
||||
for (int i = 0; i < head->count; i++) {
|
||||
h->pics[i] = alloc_pixels(head->width, head->height);
|
||||
if (!h->pics[i]) {
|
||||
for (int j = 0; j < i; j++)
|
||||
free(h->pics[j]);
|
||||
if (h->pics != &h->pic)
|
||||
free(h->pics);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare */
|
||||
for (int i = 0; i < head->count; i++)
|
||||
prepare_pixels(h->pics[i], head->width, head->height)
|
||||
break;
|
||||
|
||||
case g1m_mcstype_end:
|
||||
break;
|
||||
|
||||
/* those are TEMPORARY XXX */
|
||||
case g1m_mcstype_setup: case g1m_mcstype_string:
|
||||
break;
|
||||
|
||||
default:
|
||||
h->content = malloc(head->size);
|
||||
if (!h->content) goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
/* finish */
|
||||
return (0);
|
||||
fail:
|
||||
free(h);
|
||||
*handle = NULL;
|
||||
return (g1m_error_alloc);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Internal functions */
|
||||
/* ************************************************************************** */
|
||||
|
@ -27,18 +129,16 @@
|
|||
* Find space for some element function.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg type the type.
|
||||
* @arg name the name.
|
||||
* @arg id the ID.
|
||||
* @arg head the head.
|
||||
* @return the mcs file (NULL if allocation error).
|
||||
*/
|
||||
|
||||
static g1m_mcsfile_t *find_space_for_file(g1m_t *handle,
|
||||
unsigned int type, char *name, int id)
|
||||
static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head)
|
||||
{
|
||||
g1m_mcsfile_t **pfile = NULL;
|
||||
|
||||
/* look if this file isn't already in the tab */
|
||||
int istyp = g1m_mcshead_uses_id(head);
|
||||
for (int i = 0; i < handle->count; i++) {
|
||||
g1m_mcsfile_t *file = handle->files[i];
|
||||
if (!file) {
|
||||
|
@ -46,9 +146,9 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((file->head.type & type)
|
||||
&& (id ? file->head.id == id : !strcmp(file->head.name, name))) {
|
||||
g1m_free_mcsfile_content(file);
|
||||
if ((file->head.type == head->type) && (istyp ?
|
||||
file->head.id == head->id : !strcmp(file->head.name, head->name))) {
|
||||
g1m_free_mcsfile(file);
|
||||
pfile = &handle->files[i];
|
||||
goto found;
|
||||
}
|
||||
|
@ -65,25 +165,17 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle,
|
|||
pfile = &handle->files[handle->count++];
|
||||
}
|
||||
|
||||
/* allocate the file */
|
||||
if (!(*pfile = malloc(sizeof(g1m_mcsfile_t)))) return (NULL);
|
||||
|
||||
found:;
|
||||
/* don't forget to copy basic things */
|
||||
g1m_mcsfile_t *file = *pfile;
|
||||
if (name) sprintf(file->head.name, "%.8s", name);
|
||||
file->head.type = type;
|
||||
file->head.id = id;
|
||||
|
||||
/* and use mcstype utilities to copy other info */
|
||||
g1m_correct_mcsfile_head(&file->head);
|
||||
/* make the file */
|
||||
int err = g1m_make_mcsfile(pfile, head);
|
||||
if (err) return (NULL);
|
||||
|
||||
/* return it */
|
||||
return (file);
|
||||
return (*pfile);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Public functions */
|
||||
/* Create files in archive */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_putmcs_program:
|
||||
|
@ -103,19 +195,19 @@ int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile,
|
|||
if (~handle->type & g1m_type_mcs) return (g1m_error_op);
|
||||
|
||||
/* find the file */
|
||||
g1m_mcsfile_t *file =
|
||||
find_space_for_file(handle, g1m_mcstype_program, name, 0);
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_program,
|
||||
.size = strlen(content)
|
||||
};
|
||||
strncpy(head.name, name, 8); head.name[8] = 0;
|
||||
if (password) strncpy(head.password, password, 8);
|
||||
else head.password[0] = 0;
|
||||
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
|
||||
if (!file) return (g1m_error_alloc);
|
||||
|
||||
/* set content */
|
||||
file->head.size = strlen(content);
|
||||
if (!(file->content = malloc(file->head.size))) return (g1m_error_alloc);
|
||||
memcpy(file->content, content, file->head.size);
|
||||
|
||||
/* set password */
|
||||
if (password) strncpy(file->password, password, 8);
|
||||
else g1m_remove_password(file);
|
||||
|
||||
/* no error */
|
||||
if (pfile) *pfile = file;
|
||||
return (0);
|
||||
|
@ -142,22 +234,15 @@ int g1m_putmcs_capture(g1m_t *handle, g1m_mcsfile_t **pfile,
|
|||
return (g1m_error_op);
|
||||
|
||||
/* find the file */
|
||||
g1m_mcsfile_t *file =
|
||||
find_space_for_file(handle, g1m_mcstype_capture, NULL, id);
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_capture, .id = id,
|
||||
.width = width, .height = height
|
||||
};
|
||||
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
|
||||
if (!file) return (g1m_error_alloc);
|
||||
|
||||
/* prepare picture */
|
||||
file->width = width;
|
||||
file->height = height;
|
||||
file->image = NULL;
|
||||
|
||||
/* allocate */
|
||||
file->image = alloc_pixels(width, height);
|
||||
if (!file->image) return (g1m_error_alloc);
|
||||
prepare_pixels(file->image, width, height);
|
||||
|
||||
/* copy pixels */
|
||||
uint32_t *pix = &file->image[0][0];
|
||||
uint32_t *pix = &file->pic[0][0];
|
||||
for (int y = 0; y < height; y++) {
|
||||
uint32_t *line = *pic++;
|
||||
for (int x = 0; x < width; x++)
|
||||
|
@ -189,32 +274,16 @@ int g1m_putmcs_picture(g1m_t *handle, g1m_mcsfile_t **pfile,
|
|||
return (g1m_error_op);
|
||||
|
||||
/* find the file */
|
||||
g1m_mcsfile_t *file =
|
||||
find_space_for_file(handle, g1m_mcstype_picture, NULL, id);
|
||||
g1m_mcshead_t head = {
|
||||
.type = g1m_mcstype_picture, .id = id,
|
||||
.width = 128, .height = 64
|
||||
};
|
||||
g1m_mcsfile_t *file = find_space_for_file(handle, &head);
|
||||
if (!file) return (g1m_error_alloc);
|
||||
|
||||
/* prepare pictures */
|
||||
file->width = 128;
|
||||
file->height = 64;
|
||||
file->image = NULL;
|
||||
file->second_image = NULL;
|
||||
|
||||
/* allocate */
|
||||
file->image = alloc_pixels(128, 64);
|
||||
if (!file->image) return (g1m_error_alloc);
|
||||
file->second_image = alloc_pixels(128, 64);
|
||||
if (!file->second_image) {
|
||||
free(file->image); file->image = NULL;
|
||||
return (g1m_error_alloc);
|
||||
}
|
||||
|
||||
/* prepare */
|
||||
prepare_pixels(file->image, 128, 64)
|
||||
prepare_pixels(file->second_image, 128, 64)
|
||||
|
||||
/* copy pixels */
|
||||
uint32_t *one = &file->image[0][0];
|
||||
uint32_t *two = &file->second_image[0][0];
|
||||
uint32_t *one = &file->pics[0][0][0];
|
||||
uint32_t *two = &file->pics[1][0][0];
|
||||
for (int y = 0; y < 64; y++) {
|
||||
uint32_t *line_one = *pic_one++;
|
||||
uint32_t *line_two = *pic_two++;
|
|
@ -75,13 +75,19 @@ static struct type_corresp cas_groups[] = {
|
|||
* g1m_maketype_cas:
|
||||
* Get the libg1m MCS type from raw CAS identification data.
|
||||
*
|
||||
* @arg head the head to fill.
|
||||
* @arg datatype the data type string.
|
||||
* @arg type[out] the libg1m MCS type.
|
||||
* @return the error (if any).
|
||||
*/
|
||||
|
||||
int g1m_maketype_cas(const char *datatype, g1m_mcstype_t *type)
|
||||
int g1m_maketype_cas(g1m_mcshead_t *head, const char *datatype)
|
||||
{
|
||||
/* copy information */
|
||||
head->flags |= g1m_mcsinfo_cas;
|
||||
memcpy(head->_datatype, datatype, 2);
|
||||
head->_datatype[2] = 0;
|
||||
|
||||
/* look for correspondance */
|
||||
struct type_corresp *c = cas_groups - 1;
|
||||
while ((++c)->datatype) {
|
||||
if (c->datatype && strncmp(datatype, c->datatype, 4))
|
||||
|
@ -91,12 +97,12 @@ int g1m_maketype_cas(const char *datatype, g1m_mcstype_t *type)
|
|||
if (!c->type) goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
if (type) *type = c->type;
|
||||
head->type = c->type;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%.4s' data string was not implemented or not "
|
||||
"recognized.", datatype);
|
||||
if (type) *type = 0;
|
||||
head->type = 0;
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -54,29 +54,38 @@ static struct type_corresp cas_types[] = {
|
|||
* g1m_maketype_caspro:
|
||||
* Get the libg1m MCS type from raw CAS identification data.
|
||||
*
|
||||
* @arg head the head to fill.
|
||||
* @arg maintype the main type string.
|
||||
* @arg datatype the data type string.
|
||||
* @arg type[out] the libg1m MCS type.
|
||||
* @return the error (if any).
|
||||
*/
|
||||
|
||||
int g1m_maketype_caspro(const char *maintype,
|
||||
const char *datatype, g1m_mcstype_t *type)
|
||||
int g1m_maketype_caspro(g1m_mcshead_t *head,
|
||||
const char *maintype, const char *datatype)
|
||||
{
|
||||
/* copy raw information */
|
||||
head->flags |= g1m_mcsinfo_caspro;
|
||||
memcpy(head->_maintype, maintype, 3);
|
||||
head->_maintype[3] = 0;
|
||||
memcpy(head->_datatype, datatype, 2);
|
||||
head->_datatype[2] = 0;
|
||||
|
||||
/* look for correspondance */
|
||||
struct type_corresp *c;
|
||||
for (c = cas_types; c->datatype; c++) {
|
||||
if ((!c->maintype || !strncmp(maintype, c->maintype, 3)) /* 4? */
|
||||
&& (!c->datatype || !strncmp(datatype, c->datatype, 2))) /* 4? */
|
||||
if ((!c->maintype || !strncmp(maintype, c->maintype, 3))
|
||||
&& (!c->datatype || !strncmp(datatype, c->datatype, 2)))
|
||||
break;
|
||||
}
|
||||
if (!c->maintype) goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
if (type) *type = c->type;
|
||||
head->type = c->type;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%.4s' data string was not implemented or not "
|
||||
"recognized.", datatype);
|
||||
if (type) *type = 0;
|
||||
head->type = 0;
|
||||
return (1);
|
||||
}
|
||||
|
|
|
@ -228,21 +228,35 @@ static int get_number(const char *s, int *num, int isnum)
|
|||
* g1m_maketype_mcs:
|
||||
* Get libg1m type from rawtype.
|
||||
*
|
||||
* @arg gname the MCS group name.
|
||||
* @arg head the head to fill.
|
||||
* @arg gname the group name.
|
||||
* @arg dname the directory name.
|
||||
* @arg fname the filename.
|
||||
* @arg rawtype the raw number type.
|
||||
* @arg type pointer to the real type field to fill.
|
||||
* @arg id pointer to the ID to fill.
|
||||
* @arg rawtype the raw numerical type.
|
||||
* @return if the type was not found (0 if yes).
|
||||
*/
|
||||
|
||||
int g1m_maketype_mcs(const char *gname, const char *fname,
|
||||
unsigned int rawtype, g1m_mcstype_t *type, int *id)
|
||||
int g1m_maketype_mcs(g1m_mcshead_t *head,
|
||||
const char *gname, const char *dname,
|
||||
const char *fname, unsigned int rawtype)
|
||||
{
|
||||
/* log what we're looking for */
|
||||
log_info("Looking for type with '%.8s' group, '%.8s' name and "
|
||||
"0x%02X raw type", gname, fname, rawtype);
|
||||
|
||||
/* copy raw information */
|
||||
head->flags |= g1m_mcsinfo_mcs;
|
||||
memcpy(head->name, fname, 8);
|
||||
head->name[8] = 0;
|
||||
memcpy(head->_group, gname, 16);
|
||||
head->_group[16] = 0;
|
||||
head->_rawtype = rawtype;
|
||||
if (dname) {
|
||||
memcpy(head->_dirname, dname, 8);
|
||||
head->_dirname[8] = 0;
|
||||
} else
|
||||
memset(head->_dirname, 0, 9);
|
||||
|
||||
/* look for group correspondance */
|
||||
int gid = 0;
|
||||
struct group_corresp *g = mcs_groups - 1;
|
||||
|
@ -284,15 +298,15 @@ int g1m_maketype_mcs(const char *gname, const char *fname,
|
|||
goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
if (type) *type = t->type;
|
||||
if (id) *id = fid;
|
||||
head->type = t->type;
|
||||
head->id = fid;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%s' group, '%s' name and 0x%02x type "
|
||||
"wasn't recognized.", gname, fname, rawtype);
|
||||
if (type) *type = 0;
|
||||
if (id) *id = 0;
|
||||
head->type = 0;
|
||||
head->id = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum)
|
|||
/* read that much */
|
||||
size_t curlen = min(size, 1024);
|
||||
size -= curlen;
|
||||
buffer->_offset += curlen;
|
||||
if ((err = (*buffer->read)(buffer->cookie, buf, curlen))) {
|
||||
log_error("Skipping has failed after %" PRIuSIZE " bytes",
|
||||
orig - size);
|
||||
|
|
Reference in New Issue