Introduced incompatibilities for CAS formats
This commit is contained in:
parent
01f4ac7ba8
commit
7c90619ffe
20
AUTHORS.md
20
AUTHORS.md
|
@ -2,9 +2,19 @@
|
|||
Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
|
||||
The documentation comes from a lot of places in the CASIO community, but mainly
|
||||
from **Casiopeia** (mainly with Simon Lothar's documentation), **Cemetech**
|
||||
(Prizm-related formats) and the **Casetta project documentation**
|
||||
(reunion of five to twenty years old documentation).
|
||||
from **Casiopeia**, **Cemetech** (Prizm-related), the **Universal Casio Forum**
|
||||
and the **Casetta** project website (where some information about legacy
|
||||
thingies have been regrouped).
|
||||
|
||||
Thanks to Simon Lothar, Teamfx and KermMartian for their help!
|
||||
Thanks to the people on **Planète Casio** for their support!
|
||||
Thanks to:
|
||||
- Simon Lothar (mainly on Casiopeia) for its reverse engineering and
|
||||
documentation (**fxReverse project documentation** with Andreas Bertheussen,
|
||||
and `fx_calculators_SuperH_based.chm`);
|
||||
- Teamfx for complementary information;
|
||||
- KermMartian (from Cemetech) for its reverse engineering on Prizm-related
|
||||
formats and test files;
|
||||
- Florian Birée for its regrouped documentation (Casetta), like for tokens;
|
||||
- Yves-Marie Morgan for opening Casemul's source code;
|
||||
- Tom Wheeley for making CaS a free software;
|
||||
- Him and Tom Lynn for documenting the legacy protocol (9700);
|
||||
- Other people at **Planète Casio** for their support!
|
||||
|
|
|
@ -90,7 +90,7 @@ 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_mcstype_correct(g1m_mcshead_t *head);
|
||||
int g1m_correct_mcsfile_head(g1m_mcshead_t *head);
|
||||
|
||||
/* open and decode MCS file */
|
||||
int g1m_decode_mcsfile(g1m_mcsfile_t **handle,
|
||||
|
@ -108,10 +108,10 @@ 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 */
|
||||
/* 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_decode_caspro_part(g1m_mcsfile_t **file,
|
||||
const 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);
|
||||
|
||||
/* free handles */
|
||||
void g1m_free(g1m_t *handle);
|
||||
|
|
|
@ -27,15 +27,21 @@
|
|||
/* ************************************************************************** */
|
||||
/* The CASIOLINK (CAS) format */
|
||||
/* ************************************************************************** */
|
||||
/* This is the basic file format that CASIO used until around 2004, when the
|
||||
* fx-9860G (Graph 85) came out. It is linked with the legacy protocol, which
|
||||
* cannot be implemented with a good management of this format.
|
||||
/* This is the first file format used by the CASIO community; it was
|
||||
* more or less a dump of the communications protocol CASIO used until
|
||||
* the fx-9860G (Graph 85) was announced, around 2004.
|
||||
* It was managed by the CaS software, made by Tom Wheeler with the help of
|
||||
* other people like Tom Lynn. This software was developed around 1997.
|
||||
*
|
||||
* All of the useful structures and constants are in the specific header.
|
||||
* The function to get the libg1m MCS type out of the string types is in
|
||||
* `libg1m/formatutils.h`. */
|
||||
* There were two main versions of this protocol, leading to two different
|
||||
* versions of the CAS file specification: the original protocol, used on the
|
||||
* CFX-9700G (called cas in libg1m), and the newer protocol, used on the
|
||||
* CFX-9850 (called caspro in libg1m).
|
||||
*
|
||||
* Here are the two headers: */
|
||||
|
||||
# include <libg1m/format/cas.h>
|
||||
# include <libg1m/format/caspro.h>
|
||||
/* ************************************************************************** */
|
||||
/* The FXI format */
|
||||
/* ************************************************************************** */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* *****************************************************************************
|
||||
* libg1m/format/cas.h -- the CAS file format description.
|
||||
* libg1m/format/cas.h -- the older CAS file format description.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
|
@ -18,22 +18,26 @@
|
|||
* ************************************************************************** */
|
||||
#ifndef LIBG1M_FORMAT_CAS_H
|
||||
# define LIBG1M_FORMAT_CAS_H
|
||||
# include <libg1m.h>
|
||||
# include <stdint.h>
|
||||
# pragma pack(1)
|
||||
|
||||
/* The CASIOLINK format looks a lot like the legacy communication protocol,
|
||||
* but the two are to distinguish. A CASIOLINK-encoded file is basically
|
||||
* a set of one or more MCS files of the same type.
|
||||
/* This is the first CASIOLINK format. It is more or less a raw dump of the
|
||||
* communications protocol the 9700 uses. It is basically an MCS file.
|
||||
*
|
||||
* The file has two parts, each starting with a 0x3A (':').
|
||||
* It starts with a header: */
|
||||
* A CASIOLINK-encoded file is made of one header and one or more parts.
|
||||
* Each element is preceded by a 0x3A, and is a packet in the communications
|
||||
* protocol interpretation. */
|
||||
/* ************************************************************************** */
|
||||
/* Header */
|
||||
/* ************************************************************************** */
|
||||
/* The header is the following: */
|
||||
|
||||
struct casiolink_header {
|
||||
struct cas_header {
|
||||
uint8_t data[2];
|
||||
uint8_t _specific[5]; /* type-specific subheader */
|
||||
uint8_t filename[12]; /* unused chars are filled with 0xFFs. */
|
||||
uint8_t _unused[19]; /* 0xFFs. */
|
||||
uint8_t misc[5]; /* type-specific subheader (miscallaneous data) */
|
||||
uint8_t filename[12]; /* editor filename. */
|
||||
uint8_t password[12]; /* editor password. */
|
||||
uint8_t _reserved[7]; /* 0xFFs */
|
||||
uint8_t checksum;
|
||||
};
|
||||
|
||||
|
@ -48,7 +52,7 @@ struct casiolink_header {
|
|||
# define casiolink_program_basen 0x40 /* base-n mode */
|
||||
# define casiolink_program_drawst 0x80 /* draw stats graph */
|
||||
|
||||
struct casiolink_spe_program {
|
||||
struct cas_spe_program {
|
||||
uint8_t _unknown;
|
||||
uint16_t length;
|
||||
uint8_t flags;
|
||||
|
@ -60,7 +64,7 @@ struct casiolink_spe_program {
|
|||
*
|
||||
* Now, here are the specific bytes for a screenshot: */
|
||||
|
||||
struct casiolink_spe_screenshot {
|
||||
struct cas_spe_screenshot {
|
||||
uint8_t height;
|
||||
uint8_t width;
|
||||
uint8_t _unused[3];
|
||||
|
@ -68,28 +72,10 @@ struct casiolink_spe_screenshot {
|
|||
|
||||
/* The specific bytes for a number start with either "RA" or "CA", 'R' or 'C'
|
||||
* meaning the number is complex or not. */
|
||||
|
||||
/* This should be put somewhere else, as it represents the packets in
|
||||
* a legacy protocol communication. (FIXME: maybe the new CAS header?) */
|
||||
|
||||
struct casiolink_new_header {
|
||||
/* types */
|
||||
uint8_t type[4];
|
||||
uint8_t data[4];
|
||||
|
||||
/* data length */
|
||||
uint16_t length;
|
||||
uint8_t name[8];
|
||||
|
||||
/* variable-related data */
|
||||
uint8_t prefix[8]; /* "Variable"? */
|
||||
uint8_t real; /* 'R' for real, 'C' for complex */
|
||||
uint8_t magic; /* 0x0A */
|
||||
|
||||
/* alignment */
|
||||
uint8_t _ffs[21];
|
||||
uint8_t checksum;
|
||||
};
|
||||
/* ************************************************************************** */
|
||||
/* Content (parts) */
|
||||
/* ************************************************************************** */
|
||||
/* TODO */
|
||||
|
||||
# pragma pack()
|
||||
#endif /* LIBG1M_FORMAT_CAS_H */
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* *****************************************************************************
|
||||
* libg1m/format/caspro.h -- the newer CAS file format description.
|
||||
* 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/>.
|
||||
* ************************************************************************** */
|
||||
#ifndef LIBG1M_FORMAT_CASPRO_H
|
||||
# define LIBG1M_FORMAT_CASPRO_H
|
||||
# include <stdint.h>
|
||||
# pragma pack(1)
|
||||
|
||||
/* This is the later CASIOLINK format. It is more or less a raw dump of the
|
||||
* communications protocol the 9850 uses. It is basically an MCS file.
|
||||
*
|
||||
* A CASIOLINK-encoded file is made of one header and one or more parts.
|
||||
* Each element is preceded by a 0x3A, and is a packet in the communications
|
||||
* protocol interpretation. */
|
||||
/* ************************************************************************** */
|
||||
/* Header (first element) */
|
||||
/* ************************************************************************** */
|
||||
/* The header is the following: */
|
||||
|
||||
struct caspro_header {
|
||||
/* types */
|
||||
uint8_t type[4];
|
||||
uint8_t data[3];
|
||||
|
||||
/* data length */
|
||||
uint8_t used; /* 0x00 if is reset/unused, 0x01 if used */
|
||||
uint16_t length; /* for a variable: same value as in `used` */
|
||||
uint8_t name[8];
|
||||
|
||||
/* variable-related data */
|
||||
uint8_t prefix[8]; /* "Variable" for vars, 0xFFs otherwise */
|
||||
uint8_t aux[8]; /* variable: "R\x0A"/"C\x0A", editor: password */
|
||||
|
||||
/* something else (?) */
|
||||
uint8_t nl[2]; /* 'NL' */
|
||||
uint8_t _ffs[11];
|
||||
|
||||
/* end of packet */
|
||||
uint8_t checksum;
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Variable/number */
|
||||
/* ************************************************************************** */
|
||||
/* Variable has the following structure (described in a comment):
|
||||
*
|
||||
* uint8_t magic[4];
|
||||
* Four bytes, always {0x00, 0x01, 0x00, 0x01} for a variable;
|
||||
* cas_bcd_t real;
|
||||
* The real part of the variable.
|
||||
*
|
||||
* If the real part has the complex flag enabled, then the following is there:
|
||||
*
|
||||
* cas_bcd_t imgn;
|
||||
* The imaginary part of the variable.
|
||||
*
|
||||
* Then finally, everytime:
|
||||
*
|
||||
* uint8_t checksum;
|
||||
* The checksum (calculated as for the header). */
|
||||
|
||||
/* TODO: other file formats */
|
||||
# pragma pack()
|
||||
#endif /* LIBG1M_FORMAT_CASPRO_H */
|
|
@ -29,16 +29,20 @@
|
|||
# include <libg1m/format.h>
|
||||
|
||||
/* get type */
|
||||
int g1m_get_type_info(const char *path,
|
||||
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, unsigned int *type);
|
||||
unsigned int *platform, g1m_type_t *type);
|
||||
|
||||
/* get mcs type data */
|
||||
int g1m_mcstype_get(const char *groupname, const char *filename,
|
||||
unsigned int rawtype, unsigned int *type, int *id);
|
||||
int g1m_maketype_mcs(const char *groupname, const char *filename,
|
||||
unsigned int rawtype, g1m_mcstype_t *type, int *id);
|
||||
|
||||
/* get cas type data */
|
||||
int g1m_castype_get(const char *datatype, unsigned int *type);
|
||||
int g1m_maketype_cas(const char *datatype, g1m_mcstype_t *type);
|
||||
|
||||
/* get caspro type data */
|
||||
int g1m_maketype_caspro(const char *maintype,
|
||||
const char *datatype, g1m_mcstype_t *type);
|
||||
|
||||
#endif /* LIBG1M_FORMATUTILS_H */
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef LIBG1M_MCS_H
|
||||
# define LIBG1M_MCS_H
|
||||
# include <libg1m/bcd.h>
|
||||
# include <inttypes.h>
|
||||
# define g1m_theta 27
|
||||
# define g1m_r 28
|
||||
# define g1m_ans 29
|
||||
|
@ -27,20 +28,25 @@
|
|||
/* Main Memory Types */
|
||||
/* ************************************************************************** */
|
||||
/* MCS file type */
|
||||
typedef unsigned int g1m_mcsfile_type_t;
|
||||
typedef unsigned int g1m_mcstype_t;
|
||||
# define g1m_mcstype_unknown 0x0000
|
||||
# define g1m_mcstype_program 0x0001
|
||||
# define g1m_mcstype_list 0x0002
|
||||
# define g1m_mcstype_mat 0x0004
|
||||
# define g1m_mcstype_pict 0x0008
|
||||
# define g1m_mcstype_capt 0x0010
|
||||
# define g1m_mcstype_ssheet 0x0020
|
||||
# define g1m_mcstype_string 0x0040
|
||||
# define g1m_mcstype_setup 0x0080
|
||||
# define g1m_mcstype_alphamem 0x0100
|
||||
# define g1m_mcstype_vct 0x0200
|
||||
# define g1m_mcstype_variable 0x0400
|
||||
# define PRIXMCSTYPE "lX"
|
||||
# define PRIxMCSTYPE "lx"
|
||||
# define PRIuMCSTYPE "lu"
|
||||
typedef long unsigned int g1m_mcsfile_type_t;
|
||||
typedef g1m_mcsfile_type_t g1m_mcstype_t;
|
||||
|
||||
# define g1m_mcstype_unknown 0x00000000
|
||||
# define g1m_mcstype_program 0x00000001
|
||||
# define g1m_mcstype_list 0x00000002
|
||||
# define g1m_mcstype_mat 0x00000004
|
||||
# define g1m_mcstype_pict 0x00000008
|
||||
# define g1m_mcstype_capt 0x00000010
|
||||
# define g1m_mcstype_ssheet 0x00000020
|
||||
# define g1m_mcstype_string 0x00000040
|
||||
# define g1m_mcstype_setup 0x00000080
|
||||
# define g1m_mcstype_alphamem 0x00000100
|
||||
# define g1m_mcstype_vct 0x00000200
|
||||
# define g1m_mcstype_variable 0x00000400
|
||||
# define g1m_mcstype_end 0x00000800
|
||||
|
||||
/* MCS file type aliases */
|
||||
# define g1m_mcstype_matrix g1m_mcstype_mat
|
||||
|
@ -71,6 +77,7 @@ 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 */
|
||||
|
||||
/* mcs file head */
|
||||
|
@ -81,6 +88,8 @@ typedef struct g1m_mcshead_s {
|
|||
unsigned int flags;
|
||||
|
||||
/* content size */
|
||||
int count;
|
||||
unsigned int width, height;
|
||||
uint_fast32_t size;
|
||||
|
||||
/* mcs-related raw data */
|
||||
|
@ -88,7 +97,11 @@ typedef struct g1m_mcshead_s {
|
|||
unsigned char _group[17], _dirname[9];
|
||||
|
||||
/* cas-related raw data */
|
||||
unsigned char _data[3];
|
||||
unsigned char _maintype[4];
|
||||
unsigned char _datatype[3];
|
||||
|
||||
/* the program password */
|
||||
char password[9];
|
||||
} g1m_mcshead_t;
|
||||
|
||||
/* mcs file */
|
||||
|
@ -101,19 +114,14 @@ typedef struct g1m_mcsfile_s {
|
|||
/* content (useful when not read) */
|
||||
char *content;
|
||||
|
||||
/* for programs: the password */
|
||||
char password[9];
|
||||
|
||||
/* for spreadsheets, lists and matrixes */
|
||||
unsigned int columns, rows;
|
||||
g1m_mcs_cell_t **cells;
|
||||
|
||||
/* variables */
|
||||
int count;
|
||||
g1m_mcs_cell_t var;
|
||||
g1m_mcs_cell_t *vars;
|
||||
|
||||
/* for pictures and captures */
|
||||
unsigned int width, height;
|
||||
uint32_t **image; /* 0x0RGB */
|
||||
uint32_t **second_image; /* 0x0RGB */
|
||||
} g1m_mcsfile_t;
|
||||
|
|
|
@ -59,7 +59,7 @@ void g1m_free_mcsfile_content(g1m_mcsfile_t *handle)
|
|||
/* free cells */
|
||||
if (type & (g1m_mcstype_mat | g1m_mcstype_vct | g1m_mcstype_list
|
||||
| g1m_mcstype_spreadsheet)
|
||||
&& handle->columns && handle->rows) {
|
||||
&& handle->head.width && handle->head.height) {
|
||||
free(handle->cells[0]);
|
||||
free(handle->cells);
|
||||
}
|
||||
|
|
|
@ -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_castype_get(datatype, &head->type))
|
||||
if (g1m_maketype_cas(datatype, &head->type))
|
||||
return (g1m_error_unrecognized);
|
||||
|
||||
/* fill the handle */
|
||||
|
@ -52,7 +52,7 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, const char *datatype,
|
|||
|
||||
/* type specific */
|
||||
if (head->type == g1m_mcstype_program) {
|
||||
struct casiolink_spe_program *spe = (void*)specific;
|
||||
struct cas_spe_program *spe = (void*)specific;
|
||||
head->size = be16toh(spe->length);
|
||||
/* TODO: store flags? */
|
||||
}
|
||||
|
@ -86,14 +86,14 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
|
|||
int err;
|
||||
|
||||
/* read the header */
|
||||
DREAD(hd, casiolink_header)
|
||||
if (g1m_checksum8(&hd, sizeof(struct casiolink_header) - 1) != hd.checksum)
|
||||
DREAD(hd, cas_header)
|
||||
if (g1m_checksum8(&hd, sizeof(struct cas_header) - 1) != hd.checksum)
|
||||
return (g1m_error_checksum);
|
||||
|
||||
/* decrypt it */
|
||||
g1m_mcshead_t head;
|
||||
if ((err = g1m_decode_casfile_head(&head, (char*)hd.data,
|
||||
(char*)hd.filename, (char*)hd._specific)))
|
||||
(char*)hd.filename, (char*)hd.misc)))
|
||||
return (err);
|
||||
|
||||
/* TODO: decode it */
|
||||
|
|
|
@ -155,8 +155,8 @@ static int read_picture(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
|
||||
/* set the pixels */
|
||||
prepare_pixels(img, width, height)
|
||||
file->width = width;
|
||||
file->height = 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++)
|
||||
img[y][x] = colours[*px++];
|
||||
|
@ -215,8 +215,8 @@ static int read_matrix(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
/* TODO: id */
|
||||
|
||||
/* read the matrix */
|
||||
file->columns = width;
|
||||
file->rows = height;
|
||||
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];
|
||||
|
@ -294,7 +294,8 @@ static int read_list(g1m_mcsfile_t **pfile, g1m_buffer_t *buffer,
|
|||
/* TODO: id */
|
||||
|
||||
/* read the list */
|
||||
file->columns = 1; file->rows = len;
|
||||
file->head.width = 1;
|
||||
file->head.height = len;
|
||||
for (int x = 0; x < len; x++) {
|
||||
/* correct matrix, read bcd */
|
||||
file->cells[x] = &rws[x];
|
||||
|
|
|
@ -35,16 +35,25 @@ int g1m_decode_mcs_alphamem(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
uint8_t buf[length];
|
||||
READ(buf, length)
|
||||
|
||||
/* count number of vars */
|
||||
handle->count = length / (2 * sizeof(mcs_bcd_t));
|
||||
/* 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->count * sizeof(g1m_mcs_cell_t));
|
||||
handle->vars = malloc(handle->head.count * sizeof(g1m_mcs_cell_t));
|
||||
if (!handle->vars) return (g1m_error_alloc);
|
||||
|
||||
/* copy */
|
||||
const mcs_bcd_t *b = (void*)buf;
|
||||
for (int i = 0; i < handle->count; i++) {
|
||||
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;
|
||||
|
|
|
@ -70,8 +70,8 @@ int g1m_decode_mcs_list(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
}
|
||||
|
||||
/* fill final tab */
|
||||
handle->rows = elcount;
|
||||
handle->columns = 1;
|
||||
handle->head.height = elcount;
|
||||
handle->head.width = 1;
|
||||
handle->cells = NULL;
|
||||
if (elcount) {
|
||||
#if LOGLEVEL >= ll_info
|
||||
|
|
|
@ -46,8 +46,8 @@ int g1m_decode_mcs_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
log_info("Matrix size is %" PRIuFAST32 "*%" PRIuFAST32, w, h);
|
||||
|
||||
/* store dimensions */
|
||||
handle->rows = w;
|
||||
handle->columns = h;
|
||||
handle->head.width = w;
|
||||
handle->head.height = h;
|
||||
handle->cells = NULL;
|
||||
|
||||
if (w && h) {
|
||||
|
|
|
@ -95,14 +95,15 @@ int g1m_decode_mcs_capture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
hd.height = be16toh(hd.height);
|
||||
|
||||
/* store */
|
||||
handle->width = hd.width;
|
||||
handle->height = hd.height;
|
||||
handle->head.width = hd.width;
|
||||
handle->head.height = hd.height;
|
||||
|
||||
/* print info */
|
||||
log_info("capture is %dx%d sized", handle->width, handle->height);
|
||||
log_info("capture is %dx%d sized", handle->head.width, handle->head.height);
|
||||
|
||||
/* get the image and return */
|
||||
return (get_image(buffer, &handle->image, handle->width, handle->height));
|
||||
return (get_image(buffer, &handle->image,
|
||||
handle->head.width, handle->head.height));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,8 +122,8 @@ int g1m_decode_mcs_picture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
int err;
|
||||
|
||||
/* store some dimensions, in case. */
|
||||
handle->width = 128;
|
||||
handle->height = 64;
|
||||
handle->head.width = 128;
|
||||
handle->head.height = 64;
|
||||
|
||||
/* get the first image */
|
||||
if ((err = get_image(buffer, &handle->image, 128, 64))) {
|
||||
|
|
|
@ -38,8 +38,8 @@ int g1m_decode_mcs_program(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
log_info("Program password is '%.8s'.", hd.password);
|
||||
|
||||
/* store info */
|
||||
strncpy(handle->password, (char*)hd.password, 8);
|
||||
handle->password[8] = 0;
|
||||
strncpy(handle->head.password, (char*)hd.password, 8);
|
||||
handle->head.password[8] = 0;
|
||||
|
||||
/* get content */
|
||||
size_t content_size = length - sizeof(struct mcs_programheader);
|
||||
|
|
|
@ -109,11 +109,11 @@ int g1m_decode_mcs_spreadsheet(g1m_mcsfile_t *handle, g1m_buffer_t *buffer,
|
|||
|
||||
/* create final tab */
|
||||
handle->cells = NULL;
|
||||
handle->columns = 0;
|
||||
handle->rows = 0;
|
||||
handle->head.width = 0;
|
||||
handle->head.height = 0;
|
||||
if (cells_count) {
|
||||
handle->columns = cols;
|
||||
handle->rows = rows;
|
||||
handle->head.width = cols;
|
||||
handle->head.height = rows;
|
||||
|
||||
/* alloc */
|
||||
g1m_mcs_cell_t **tab = malloc(sizeof(g1m_mcs_cell_t*) * cols);
|
||||
|
|
|
@ -90,10 +90,11 @@ static int find_decode_function(g1m_t *handle, const char *path,
|
|||
struct standard_header *std, decode_func *rd)
|
||||
{
|
||||
/* get the type */
|
||||
unsigned int platform, type;
|
||||
unsigned int platform;
|
||||
g1m_type_t type;
|
||||
const char *type_string;
|
||||
int check_one, check_two;
|
||||
if (g1m_get_type_info(path, std->main_id, std->subtype, &type_string,
|
||||
if (g1m_maketype_std(path, std->main_id, std->subtype, &type_string,
|
||||
&check_one, &check_two, &platform, &type))
|
||||
return (g1m_error_magic);
|
||||
log_info("Standard Header type is '%s'.", type_string);
|
||||
|
|
|
@ -95,10 +95,10 @@ int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
|
|||
if (!head) return (-1);
|
||||
|
||||
/* look for the raw type */
|
||||
if (g1m_mcstype_get((char*)groupname, (char*)filename, raw_type,
|
||||
if (g1m_maketype_mcs((char*)groupname, (char*)filename, raw_type,
|
||||
&head->type, &head->id))
|
||||
head->type = g1m_mcstype_unknown;
|
||||
log_info("libg1m file type is 0x%04X", head->type);
|
||||
log_info("libg1m file type is 0x%08" PRIXMCSTYPE, head->type);
|
||||
#if LOGLEVEL <= ll_info
|
||||
if (g1m_mcstype_uses_id(head->type)) {
|
||||
log_info("libg1m file id is (%d, %d)", g1m_get_id_major(head->id),
|
||||
|
|
|
@ -76,7 +76,7 @@ found:;
|
|||
file->head.id = id;
|
||||
|
||||
/* and use mcstype utilities to copy other info */
|
||||
g1m_mcstype_correct(&file->head);
|
||||
g1m_correct_mcsfile_head(&file->head);
|
||||
|
||||
/* return it */
|
||||
return (file);
|
|
@ -27,7 +27,7 @@ struct type_corresp {
|
|||
const char *datatype;
|
||||
|
||||
/* libg1m MCS file type */
|
||||
unsigned int type;
|
||||
g1m_mcstype_t type;
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
@ -39,8 +39,6 @@ struct type_corresp {
|
|||
|
||||
#define TTERM {NULL, 0}
|
||||
static struct type_corresp cas_groups[] = {
|
||||
{"PG", g1m_mcstype_program},
|
||||
|
||||
/* not implemented yet types, described by Tom Wheeley and Tom Lynn */
|
||||
{"AA", 0}, // dynamic graph functions
|
||||
{"AD", 0}, // variable memory
|
||||
|
@ -66,19 +64,6 @@ static struct type_corresp cas_groups[] = {
|
|||
{"SR", 0}, // linear regression data
|
||||
{"SS", 0}, // standard deviation data
|
||||
|
||||
/* not implemented yet types, described in libcafix */
|
||||
{"FT", 0}, // ???
|
||||
{"GM", 0}, // G-Mem?
|
||||
{"LT", 0}, // List
|
||||
{"MT", 0}, // Matrix
|
||||
{"PC", 0}, // Picture
|
||||
{"RF", 0}, // ???
|
||||
{"RR", 0}, // ???
|
||||
{"SE", 0}, // Equation?
|
||||
{"TR", 0}, // ???
|
||||
{"VM", 0}, // Variable (A-Z, etc)
|
||||
{"WD", 0}, // window data
|
||||
|
||||
/* terminating entry */
|
||||
TTERM
|
||||
};
|
||||
|
@ -87,7 +72,7 @@ static struct type_corresp cas_groups[] = {
|
|||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_castype_get:
|
||||
* g1m_maketype_cas:
|
||||
* Get the libg1m MCS type from raw CAS identification data.
|
||||
*
|
||||
* @arg datatype the data type string.
|
||||
|
@ -95,7 +80,7 @@ static struct type_corresp cas_groups[] = {
|
|||
* @return the error (if any).
|
||||
*/
|
||||
|
||||
int g1m_castype_get(const char *datatype, unsigned int *type)
|
||||
int g1m_maketype_cas(const char *datatype, g1m_mcstype_t *type)
|
||||
{
|
||||
struct type_corresp *c = cas_groups - 1;
|
||||
while ((++c)->datatype) {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* *****************************************************************************
|
||||
* type/caspro.c -- get the newer CAS type out of raw identification data.
|
||||
* 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/>.
|
||||
* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Local types */
|
||||
/* ************************************************************************** */
|
||||
/* Correspondance type */
|
||||
struct type_corresp {
|
||||
/* identification */
|
||||
const char *maintype;
|
||||
const char *datatype;
|
||||
|
||||
/* libg1m MCS file type */
|
||||
g1m_mcstype_t type;
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Correspondances */
|
||||
/* ************************************************************************** */
|
||||
/* All correspondances. Remarks:
|
||||
* - Correspondances with a NULL data type means the data type isn't to be
|
||||
* read. */
|
||||
|
||||
#define TTERM {NULL, NULL, 0}
|
||||
static struct type_corresp cas_types[] = {
|
||||
{"TXT", "PG", g1m_mcstype_program},
|
||||
{"VAL", "MT", g1m_mcstype_variable},
|
||||
|
||||
/* terminating entry */
|
||||
TTERM
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_maketype_caspro:
|
||||
* Get the libg1m MCS type from raw CAS identification data.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
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? */
|
||||
break;
|
||||
}
|
||||
if (!c->maintype) goto notfound;
|
||||
|
||||
/* fill in info and return */
|
||||
if (type) *type = c->type;
|
||||
return (0);
|
||||
|
||||
notfound:
|
||||
log_info("Type with '%.4s' data string was not implemented or not "
|
||||
"recognized.", datatype);
|
||||
if (type) *type = 0;
|
||||
return (1);
|
||||
}
|
|
@ -40,7 +40,7 @@ struct type_corresp {
|
|||
const char *info;
|
||||
|
||||
/* libg1m information */
|
||||
unsigned int type;
|
||||
g1m_mcstype_t type;
|
||||
};
|
||||
|
||||
/* Group correspondance type */
|
||||
|
@ -225,7 +225,7 @@ static int get_number(const char *s, int *num, int isnum)
|
|||
|
||||
|
||||
/**
|
||||
* g1m_mcstype_get:
|
||||
* g1m_maketype_mcs:
|
||||
* Get libg1m type from rawtype.
|
||||
*
|
||||
* @arg gname the MCS group name.
|
||||
|
@ -236,8 +236,8 @@ static int get_number(const char *s, int *num, int isnum)
|
|||
* @return if the type was not found (0 if yes).
|
||||
*/
|
||||
|
||||
int g1m_mcstype_get(const char *gname, const char *fname,
|
||||
unsigned int rawtype, unsigned int *type, int *id)
|
||||
int g1m_maketype_mcs(const char *gname, const char *fname,
|
||||
unsigned int rawtype, g1m_mcstype_t *type, int *id)
|
||||
{
|
||||
/* log what we're looking for */
|
||||
log_info("Looking for type with '%.8s' group, '%.8s' name and "
|
||||
|
@ -297,14 +297,14 @@ notfound:
|
|||
}
|
||||
|
||||
/**
|
||||
* g1m_mcstype_correct:
|
||||
* g1m_correct_mcsfile_head:
|
||||
* Correct information.
|
||||
*
|
||||
* @arg head the mcs head to correct.
|
||||
* @return if an error was encountered.
|
||||
*/
|
||||
|
||||
int g1m_mcstype_correct(g1m_mcshead_t *head)
|
||||
int g1m_correct_mcsfile_head(g1m_mcshead_t *head)
|
||||
{
|
||||
/* check if there is a type */
|
||||
if (!head || !head->type)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* *****************************************************************************
|
||||
* type/main.c -- extract the G1M file type out of raw identification data.
|
||||
* type/std.c -- extract the STD file type out of raw identification data.
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libg1m.
|
||||
|
@ -173,7 +173,7 @@ static void get_extension(const char *path, char *extbuf)
|
|||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_get_type_info:
|
||||
* g1m_maketype_std:
|
||||
* Get type info.
|
||||
*
|
||||
* @arg path Path of the file.
|
||||
|
@ -187,10 +187,10 @@ static void get_extension(const char *path, char *extbuf)
|
|||
* @return If there was an error.
|
||||
*/
|
||||
|
||||
int g1m_get_type_info(const char *path,
|
||||
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, unsigned int *type)
|
||||
unsigned int *platform, g1m_type_t *type)
|
||||
{
|
||||
/* look if blank */
|
||||
if (!memcmp(main_id, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8)
|
Reference in New Issue