cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/include/libg1m/format/picture.h

185 lines
4.9 KiB
C

/* *****************************************************************************
* libg1m/format/picture.h -- the G1M picture formats 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_PICTURE_H
# define LIBG1M_FORMAT_PICTURE_H
# include <stdint.h>
/* ************************************************************************** */
/* G3P: pictures for Prizm */
/* ************************************************************************** */
/* G3P are pictures for fx-CG. They only have one part.
* This mysteries over this format have been unraveled by many, but I'm using
* Simon Lothar's documentation and Kerm Martian's articles.
*
* Some color depth things: */
enum g3p_colorsize {
g3p_color_4bit = 0x03,
g3p_color_16bit = 0x10
};
/* So, after the header, here is the G3P subheader: */
struct g3p_subheader {
/* some magic sequence: "CP0100Ly755"
* "CP" is check by a syscall */
uint8_t magic[11];
/* unused */
uint8_t unused[5];
/* size of the file after standard header */
uint32_t g3p_size;
/* undocumented */
uint8_t unknown[4];
/* size of the image data + 0x18 bytes of header */
uint32_t image_size;
/* undocumented gap */
uint8_t undocumented_gap[124];
};
/* What is after the G3P subheader is the image (data).
*
* The image has a header, some data and a footer. Here is the header: */
struct g3p_imageheader {
/* magic sequence? is: 0x00, 0x01, 0x00, 0x00 */
uint8_t magic[4];
/* size of the image data + footer */
uint32_t df_size;
/* w0t */
uint16_t unknown2;
/* width */
uint16_t width;
/* height */
uint16_t height;
/* color depth - see `g3p_colorsize` */
uint16_t color_depth;
/* undocumented, again */
uint32_t undocumented;
/* length of image + footer */
uint32_t data_size;
};
/* Then there is the image data and the footer.
*
* At the beginning of the image data, there is a 2-byte ID.
* 0x3c1b is the ID for "Casio Provided" images with no footers (?).
*
* The image is deflated using the DEFLATE algorithm.
*
* For some images, CASIO added some obfuscation. To check if the image is
* encrypted, according to syscalls, you have to check standard header data.
* Image is encrypted if:
*
* [0x1C] != [0x08] + [0x12] + [0x13] + 0x7B
*
* Which, simplified and with our structures, is:
*
* (std.obfuscated + 8) & 0xff != (std.filesize & 0xff00) >> 8
*
* then the deflated image is encrypted.
*
* If this is the case, before passing the data to the INFLATE algorithm,
* you have to apply this on each byte of the deflated image:
*
* 0b76543210 -> 0b21076543,
* which, in C, is: (byte >> 3) | ((byte & 0x7) << 5)
*
* The footer contains the Adler32 checksum of the raw and unobfuscated data.
* Here it is: */
struct g3p_imagefooter {
/* checksum */
uint32_t checksum;
};
/* ************************************************************************** */
/* C2P: Images for Classpads */
/* ************************************************************************** */
/* C2P are images for fx-CP400 calculators. It starts of with this header: */
struct c2p_subheader {
/* magic field: "CC0100" */
uint8_t magic1[6];
/* second magic: "ColorCP\0\0\0" */
uint8_t color_cp[10];
/* filesize without standard header */
uint32_t c2p_size;
/* unknown */
uint32_t unknown;
/* filesize - 0x234 */
uint32_t unknown_size;
/* undocumented */
uint8_t undocumented[124];
/* "0100" */
uint8_t zero_one_zero_zero[4];
/* filesize - 0x254 */
uint32_t unknown_size2;
/* unknown */
uint16_t unknown2;
/* width (max for screen: 0x136 */
uint16_t width;
/* height (max for screen: 0x191) */
uint16_t height;
/* undocumented, again */
uint8_t undocumented2[18];
/* filesize - 0x258 */
uint32_t unknown_size3;
};
/* Then there is the zlib header with default compression.
* The pixels format is R5G6B5.
*
* After the image, there is a footer, which is mainly undocumented, but
* here is what we've got: */
struct c2p_footer {
/* "0100", again */
uint8_t zero_one_zero_zero[4];
/* and some undocumented stuff */
uint8_t undocumented[358];
};
# pragma pack()
#endif /* LIBG1M_FORMAT_PICTURE_H */