cake
/
libg1m
Archived
1
0
Fork 0

Corrected things, added logging for casemul

This commit is contained in:
Thomas Touhey 2017-03-05 19:55:26 +01:00
parent 81b041b5f0
commit 01f4ac7ba8
5 changed files with 118 additions and 21 deletions

View File

@ -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);

View File

@ -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));

View File

@ -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);

55
src/decode/caspro.c Normal file
View File

@ -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);
}

View File

@ -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);
}
/**