Corrected things, added logging for casemul
This commit is contained in:
parent
81b041b5f0
commit
01f4ac7ba8
|
@ -108,6 +108,11 @@ int g1m_decode_casfile(g1m_mcsfile_t **handle,
|
|||
int g1m_decode_casfile_data(g1m_mcsfile_t **handle,
|
||||
const g1m_mcshead_t *head, const unsigned char *data, size_t size);
|
||||
|
||||
/* open CAS protocol file head and content */
|
||||
int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
int g1m_decode_caspro_part(g1m_mcsfile_t **file,
|
||||
const g1m_mcshead_t *head, g1m_buffer_t *buffer);
|
||||
|
||||
/* free handles */
|
||||
void g1m_free(g1m_t *handle);
|
||||
void g1m_free_mcsfile(g1m_mcsfile_t *handle);
|
||||
|
|
|
@ -47,11 +47,12 @@ int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
|
|||
READ(&buf[1], 3)
|
||||
if (!memcmp(buf, "CAFS", 4)) {
|
||||
handle->platform |= g1m_platflag_be;
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
} else if (!memcmp(buf, "ACFS", 4))
|
||||
return (g1m_decode_casemul(handle, buffer));
|
||||
|
||||
/* identify a standard header (send a _copy_) */
|
||||
READ(&buf[1], 0x1C)
|
||||
READ(&buf[4], 0x1C)
|
||||
uint8_t altbuf[0x20]; memcpy(altbuf, buf, 0x20);
|
||||
return (g1m_decode_std(handle, path, buffer,
|
||||
(struct standard_header*)altbuf, expected_types));
|
||||
|
|
|
@ -57,7 +57,6 @@ static int read_internal(g1m_buffer_t *buffer, uint32_t signature,
|
|||
|
||||
/* check version */
|
||||
if (le32toh(hd.version) != version) {
|
||||
log_error("version mismatch!");
|
||||
log_error("version mismatch!");
|
||||
log_error("epxected %08" PRIxFAST32 ", got %08" PRIx32,
|
||||
version, hd.version);
|
||||
|
@ -90,7 +89,6 @@ static int read_top(g1m_buffer_t *buffer, char *name, uint_fast32_t *length)
|
|||
name_length = max(name_length, 8);
|
||||
memcpy(name, buf, name_length);
|
||||
name[name_length] = 0;
|
||||
logm_info(name, name_length);
|
||||
|
||||
/* read the length and correct */
|
||||
READ(length, sizeof(uint32_t))
|
||||
|
@ -133,6 +131,7 @@ static int read_picture(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* specific things */
|
||||
DREAD(pct, casemul_pict_header)
|
||||
log_info("picture dimension is %d*%dpx", pct.width, pct.height);
|
||||
|
||||
/* read all of the pixels */
|
||||
unsigned int total = pct.width * pct.height;
|
||||
|
@ -190,10 +189,11 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* read specific things */
|
||||
DREAD(mtx, casemul_mtrx_header)
|
||||
|
||||
/* read double tab */
|
||||
int width = le32toh(mtx.lines) & 0x7FFF,
|
||||
height = le32toh(mtx.columns) & 0x7FFF;
|
||||
log_info("%d*%d elements in matrix", width, height);
|
||||
|
||||
/* read double tab */
|
||||
unsigned int total = width * height;
|
||||
double tab[total]; READ(tab, total * sizeof(double))
|
||||
double *raw = tab;
|
||||
|
@ -218,9 +218,22 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
file->columns = width;
|
||||
file->rows = 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);
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
/* make the cell */
|
||||
file->cells[y][x] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
|
@ -257,9 +270,10 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* read specific things */
|
||||
DREAD(lst, casemul_list_header)
|
||||
int len = le32toh(lst.lines) & 0x7FFF;
|
||||
log_info("%d elements in list", len);
|
||||
|
||||
/* read double tab */
|
||||
int len = le32toh(lst.lines) & 0x7FFF;
|
||||
double tab[len]; READ(tab, len * sizeof(double))
|
||||
double *raw = tab;
|
||||
|
||||
|
@ -282,8 +296,18 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
/* read the list */
|
||||
file->columns = 1; file->rows = len;
|
||||
for (int x = 0; x < len; x++) {
|
||||
/* correct matrix, read bcd */
|
||||
file->cells[x] = &rws[x];
|
||||
g1m_bcd_t bcd; g1m_bcd_fromdouble(*raw++, &bcd);
|
||||
|
||||
#if LOGLEVEL <= ll_info
|
||||
/* log information */
|
||||
char buf[G1M_BCD_GOODBUFSIZE];
|
||||
g1m_bcdtoa(&bcd, buf, G1M_BCD_GOODBUFSIZE);
|
||||
log_info("[%d] %s", x, buf);
|
||||
#endif
|
||||
|
||||
/* set the cell */
|
||||
file->cells[x][0] = (g1m_mcs_cell_t){
|
||||
.real = bcd,
|
||||
.imgn = {},
|
||||
|
@ -321,13 +345,20 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
|
||||
/* read the overall (global) header */
|
||||
DREAD(glb, casemul_header)
|
||||
#if LOGLEVEL <= ll_info
|
||||
glb.source_offset = e32toh(glb.source_offset);
|
||||
glb.compiled_offset = e32toh(glb.compiled_offset);
|
||||
log_info("Header source offset is: 0x%08X", glb.source_offset);
|
||||
if (glb.flags & casemul_compiled)
|
||||
log_info("Header compiled offset is: 0x%08X", glb.compiled_offset);
|
||||
else
|
||||
log_info("The file has got no compiled part.");
|
||||
#endif
|
||||
|
||||
/* read the source header */
|
||||
if ((err = read_internal(buffer, MAKELONG('SR', 'CE'), VER)))
|
||||
return (err);
|
||||
DREAD(src, casemul_source_header)
|
||||
log_info("%d program(s), %d pic(s), %d matrix(es), %d list(s)",
|
||||
src.programs, src.pictures, src.matrixes, src.lists);
|
||||
|
||||
/* prepare the tab */
|
||||
handle->type = g1m_type_mcs;
|
||||
|
@ -341,6 +372,8 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
/* read each program; TODO: put this in a function when token parsing
|
||||
* is managed. */
|
||||
for (int i = 0; i < src.programs; i++) {
|
||||
log_info("Reading program #%d", i + 1);
|
||||
log_warn("Program content will be skipped!");
|
||||
/* general record things */
|
||||
char name[13]; uint_fast32_t record_length;
|
||||
if ((err = read_top(buffer, name, &record_length))
|
||||
|
@ -357,6 +390,7 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
|
||||
/* 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;
|
||||
|
@ -365,6 +399,7 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
|
||||
/* 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;
|
||||
|
@ -373,6 +408,7 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
|
||||
/* 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;
|
||||
|
@ -380,6 +416,7 @@ int g1m_decode_casemul(g1m_t *handle, g1m_buffer_t *buffer)
|
|||
}
|
||||
|
||||
/* TODO: skip compiled part? */
|
||||
log_warn("Should read compiled part here!");
|
||||
|
||||
/* no error! */
|
||||
return (0);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/* *****************************************************************************
|
||||
* decode/caspro.c -- decode legacy CASIO protocol 'file'.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
* libg1m is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libg1m is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Based on the Casetta project documentation:
|
||||
* https://casetta.tuxfamily.org/formats/cas
|
||||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* g1m_decode_caspro_head:
|
||||
* Decode a CASIOLINK Protocol header.
|
||||
*
|
||||
* @arg head the head to fill.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @return if there was an error, or not.
|
||||
*/
|
||||
|
||||
int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
|
||||
{
|
||||
/* TODO */
|
||||
return (g1m_error_unknown);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_decode_caspro_part:
|
||||
* Decode a CASIOLINK Protocol content part.
|
||||
*
|
||||
* @arg file the file to make
|
||||
* (or double pointer to the one to contribute to).
|
||||
* @arg head the head to fill.
|
||||
* @arg buffer the buffer to read from.
|
||||
* @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)
|
||||
{
|
||||
/* TODO */
|
||||
return (g1m_error_unknown);
|
||||
}
|
|
@ -47,10 +47,7 @@ static int eact_decode_content_eact(g1m_line_t *handle, uint8_t *buf,
|
|||
handle->lines = NULL;
|
||||
|
||||
/* check if the buffer is non-empty */
|
||||
if (!bufsize) {
|
||||
log_info("Content was name-only.");
|
||||
return (0);
|
||||
}
|
||||
if (!bufsize) return (0);
|
||||
|
||||
/* get e-act subheader */
|
||||
if (bufsize < sizeof(struct eact_eactheader)) return (g1m_error_eof);
|
||||
|
@ -187,18 +184,20 @@ static int eact_decode_line_content(g1m_line_t *handle, uint8_t *buf,
|
|||
break ;
|
||||
ctype++;
|
||||
}
|
||||
if (!ctype->decode) {
|
||||
log_error("Unknown content type: '%.8s'", hd.type);
|
||||
return (0);
|
||||
|
||||
/* print the content */
|
||||
#if LOGLEVEL <= ll_info
|
||||
if (!ctype->decode) log_error("Type is unmanaged!");
|
||||
|
||||
if (!size) log_info("Content was name-only.");
|
||||
else if (!ctype->decode) {
|
||||
log_info("Content was:");
|
||||
logm_info(buf, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* then decode */
|
||||
int err;
|
||||
if ((err = (*ctype->decode)(handle, buf, size)))
|
||||
return (err);
|
||||
|
||||
/* otherwise, no error. */
|
||||
return (0);
|
||||
return (ctype->decode ? (*ctype->decode)(handle, buf, size) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Reference in New Issue