cake
/
libg1m
Archived
1
0
Fork 0

Corrected picture decoding, added fx add-in encoding

This commit is contained in:
Thomas Touhey 2017-03-20 02:25:11 +01:00
parent b252212d59
commit 022e083a50
10 changed files with 205 additions and 7 deletions

View File

@ -154,9 +154,11 @@ extern int g1m_mcs_insert(g1m_t *handle, g1m_mcsfile_t **tofile,
/* ************************************************************************** */
/* Version decoding/encoding */
extern int g1m_decode_version(const char *raw, g1m_version_t *version);
extern int g1m_encode_version(const g1m_version_t *version, char *raw);
/* Date decoding/encoding */
extern int g1m_decode_date(const char *raw, time_t *date);
extern int g1m_encode_date(const time_t *date, char *raw);
# ifdef __cplusplus
}

View File

@ -92,8 +92,10 @@
if (err) goto fail;
/* write */
# define WRITE(BUF, SZ) \
(*buffer->write)(buffer->cookie, (unsigned char*)(BUF), (SZ));
# define WRITE(BUF, SZ) { \
int WRITE_err = (*buffer->write)(buffer->cookie, \
(unsigned char*)(BUF), (SZ)); \
if (WRITE_err) return (WRITE_err); }
# define DWRITE(S) WRITE(&(S), sizeof(S))
/* ************************************************************************** */
/* Decoding functions */
@ -172,6 +174,14 @@ G1M_CASHFUNC(program)
G1M_CASFUNC(matrix)
G1M_CASFUNC(capture)
/* ************************************************************************** */
/* Handle encoding functions */
/* ************************************************************************** */
# define G1M_ENCFUNC(NAME) \
extern int g1m_announce_##NAME(g1m_t *handle, size_t *size); \
extern int g1m_encode_##NAME(g1m_t *handle, g1m_buffer_t *buffer);
G1M_ENCFUNC(addin)
/* ************************************************************************** */
/* Picture utilities */
/* ************************************************************************** */
# define alloc_pixels(W, H) \

View File

@ -25,6 +25,7 @@ extern "C" {
/* picture format */
typedef int g1m_pictureformat_t;
# define g1m_pictureformat_1bit 0x0100
# define g1m_pictureformat_1bit_r 0x0101
# define g1m_pictureformat_1bit_packed 0x0110
# define g1m_pictureformat_1bit_packed_r 0x0111
# define g1m_pictureformat_1bit_packed_old 0x0120

View File

@ -65,9 +65,9 @@ int g1m_decode_std_addin(g1m_t **h, g1m_buffer_t *buffer,
log_info("creation date is: %.24s", ctime(&handle->creation_date));
/* fill icon */
g1m_decode_picture(handle->icon_unsel, g1m_pictureformat_1bit_packed,
g1m_decode_picture(handle->icon_unsel, g1m_pictureformat_1bit,
hd.icon, handle->width, handle->height);
g1m_decode_picture(handle->icon_sel, g1m_pictureformat_1bit_packed_r,
g1m_decode_picture(handle->icon_sel, g1m_pictureformat_1bit_r,
hd.icon, handle->width, handle->height);
/* read content */

82
src/encode/addin.c Normal file
View File

@ -0,0 +1,82 @@
/* *****************************************************************************
* encode/addin.c -- encode an addin.
* 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>
/**
* g1m_announce_addin:
* Announce an add-in's size.
*
* @arg handle the handle.
* @arg size the size to feed.
* @return the error code (0 if ok).
*/
int g1m_announce_addin(g1m_t *handle, size_t *size)
{
*size += sizeof(struct standard_header) + sizeof(struct g1a_subheader);
*size += handle->size;
return (0);
}
/**
* g1m_encode_addin:
* Encode an add-in.
*
* @arg handle the handle.
* @arg buffer the buffer to which to write to.
* @return the error code (0 if ok).
*/
int g1m_encode_addin(g1m_t *handle, g1m_buffer_t *buffer)
{
/* make the StandardHeader up */
size_t filesize; g1m_announce_addin(handle, &filesize);
struct standard_header std = {
.main_id = "USBPower",
.subtype = "\xF3\x00\x10\x00\x10\x00",
.filesize = htobe32((uint32_t)filesize),
.control = (filesize + 0x41) & 0xFF,
.control2 = (filesize + 0xB8) & 0xFF,
.number = 0xFFFF};
/* reverse it and output it */
uint8_t *b = (void*)&std;
for (size_t i = 0; i < sizeof(struct standard_header); i++) b[i] = ~b[i];
DWRITE(std)
/* make the add-in subheader up and output it */
filesize -= sizeof(struct standard_header);
struct g1a_subheader sub = {
.estrips_count = 0,
.filesize = htobe32(filesize)};
strncpy((char*)sub.title, handle->title, 8);
strncpy((char*)sub.internal_name, handle->intname, 8);
g1m_encode_version(&handle->version, (char*)sub.version);
g1m_encode_date(&handle->creation_date, (char*)sub.creation_date);
g1m_encode_picture((const uint32_t**)handle->icon_unsel,
g1m_pictureformat_1bit, sub.icon,
G1A_ICON_WIDTH, G1A_ICON_HEIGHT);
DWRITE(sub)
/* output the content */
WRITE(handle->content, handle->size)
/* no error! */
return (0);
}

View File

@ -17,8 +17,7 @@
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************** */
#include <libg1m/internals.h>
#define A(NAME) g1m_announce_##NAME
#define E(NAME) g1m_encode_##NAME
#define FUNCS(NAME) g1m_announce_##NAME, g1m_encode_##NAME
/* ************************************************************************** */
/* Correspondances */
@ -38,6 +37,9 @@ struct corresp {
/* All correspondances */
static const struct corresp encodings[] = {
/* add-in types */
{g1m_type_addin, g1m_platform_fx, FUNCS(addin)},
/* sentinel */
{0, 0, NULL, NULL}
};
@ -71,7 +73,7 @@ int g1m_encode(g1m_t *handle, g1m_buffer_t *buffer)
/* announce, if necessary */
if (buffer->announce) {
size_t size;
size_t size = 0;
if ((err = (*c->announce)(handle, &size))
|| (err = (*buffer->announce)(buffer->cookie, size)))
return (err);

View File

@ -231,6 +231,8 @@ int g1m_make_addin(g1m_t **h, g1m_platform_t platform, size_t size,
if (!handle->icon_sel) goto fail;
/* prepare pictures */
handle->width = width;
handle->height = height;
prepare_pixels(handle->icon_unsel, width, height)
prepare_pixels(handle->icon_sel, width, height)

View File

@ -48,3 +48,23 @@ int g1m_decode_date(const char *c, time_t *t)
*t = mktime(&date);
return (0);
}
/**
* g1m_encode_date:
* Encode a date from a string.
*
* @arg t the source timestamp.
* @arg c the destination string.
* @return the error code (0 if ok).
*/
int g1m_encode_date(const time_t *t, char *c)
{
/* helper values */
struct tm *date = gmtime(t);
char buf[15]; sprintf(buf, "%04u.%02u%02u.%02u%02u",
min(date->tm_year + 1900, 9999), date->tm_mon + 1, date->tm_mday,
date->tm_hour, date->tm_min);
memcpy(c, buf, 14);
return (0);
}

View File

@ -58,6 +58,36 @@ int g1m_decode_picture(uint32_t **pixels, g1m_pictureformat_t format,
int msk; const unsigned char *o, *g, *b, *r2; size_t off;
switch (format) {
case g1m_pictureformat_1bit:
for (unsigned int y = 0; y < height; y++) {
msk = 0x80;
for (unsigned int x = 0; x < width; x++) {
/* get pixel */
pixels[y][x] = (*raw & msk) ? 0x000000 : 0xFFFFFF;
/* go to next */
raw += msk & 1;
msk = (msk >> 1) | ((msk & 1) << 7);
}
if (width & 0x7) raw++;
}
break;
case g1m_pictureformat_1bit_r:
for (unsigned int y = 0; y < height; y++) {
msk = 0x80;
for (unsigned int x = 0; x < width; x++) {
/* get pixel */
pixels[y][x] = (*raw & msk) ? 0xFFFFFF : 0x000000;
/* go to next */
raw += msk & 1;
msk = (msk >> 1) | ((msk & 1) << 7);
}
if (width & 0x7) raw++;
}
break;
case g1m_pictureformat_4bit_mono:
raw = &raw[(height * width / 2) * 2];
case g1m_pictureformat_1bit_packed:
@ -214,6 +244,38 @@ int g1m_encode_picture(const uint32_t **pixels, g1m_pictureformat_t format,
int msk;
switch (format) {
case g1m_pictureformat_1bit:
memset(raw, 0, g1m_picturesize_1bit(width, height));
for (unsigned int y = 0; y < height; y++) {
msk = 0x80;
for (unsigned int x = 0; x < width; x++) {
/* get pixel */
if (!pixels[y][x]) *raw |= msk;
/* go to next */
raw += msk & 1;
msk = (msk >> 1) | ((msk & 1) << 7);
}
if (width & 0x7) raw++;
}
break;
case g1m_pictureformat_1bit_r:
memset(raw, 0, g1m_picturesize_1bit(width, height));
for (unsigned int y = 0; y < height; y++) {
msk = 0x80;
for (unsigned int x = 0; x < width; x++) {
/* get pixel */
if (pixels[y][x]) *raw |= msk;
/* go to next */
raw += msk & 1;
msk = (msk >> 1) | ((msk & 1) << 7);
}
if (width & 0x7) raw++;
}
break;
case g1m_pictureformat_1bit_packed:
msk = 0x80;
for (unsigned int y = 0; y < height; y++)

View File

@ -45,3 +45,20 @@ int g1m_decode_version(const char *raw, g1m_version_t *version)
/* no error */
return (0);
}
/**
* g1m_encode_version:
* Encode a version into an 'MM.mm.ffff' formatted version string.
*
* @arg version the version to encode.
* @arg the string to encode into.
* @return the error code (if any).
*/
int g1m_encode_version(const g1m_version_t *version, char *raw)
{
char buf[11]; sprintf(buf, "%02u.%02u.%04u",
version->major, version->minor, version->revision);
memcpy(raw, buf, 10);
return (0);
}