hiti: Major improvements in parsing v2 heattable data files.

* Properly decode length
 * Handle secondary/embedded tables
 * Document the known field types
master
Solomon Peachy 1 month ago
parent e5df30205c
commit 7fc8ba7088
  1. 138
      backend_hiti.c

@ -284,9 +284,8 @@ STATIC_ASSERT(sizeof(struct hiti_heattable_v1b) == 12917);
/* All fields are little endian */
struct hiti_heattable_entry_v2 {
uint16_t type;
uint8_t unknown;
uint16_t zero;
uint8_t type;
uint32_t len; /* in 16-bit words */
uint32_t offset;
} __attribute((packed));
@ -479,8 +478,8 @@ struct hiti_ctx {
uint8_t *heattable_buf;
struct hiti_heattable_v2 {
uint16_t type;
uint8_t *data;
uint8_t type;
uint8_t *data;
uint32_t len;
} *heattable_v2;
uint8_t num_heattable_entries;
@ -507,6 +506,7 @@ static int hiti_query_counter(struct hiti_ctx *ctx, uint8_t arg, uint32_t *resp,
static int hiti_query_markers(void *vctx, struct marker **markers, int *count);
static int hiti_query_serno(struct dyesub_connection *conn, char *buf, int buf_len);
static int hiti_read_heattable_v2(struct hiti_ctx *ctx, const char* fname);
static int hiti_docmd(struct hiti_ctx *ctx, uint16_t cmdid, uint8_t *buf, uint16_t buf_len, uint16_t *rsplen)
{
@ -1547,18 +1547,20 @@ static int hiti_send_heat_data(struct hiti_ctx *ctx, uint8_t mode, uint8_t matte
fname = hiti_get_heat_file(ctx, mode);
if (!fname) {
WARNING("Heattable filename missing, skipping?\n");
return CUPS_BACKEND_OK;
}
char full[2048];
snprintf(full, sizeof(full), "%s/%s", corrtable_path, fname);
WARNING("Heattable filename missing!\n");
len = 0;
memset(&table, 0, sizeof(table));
} else {
char full[2048];
snprintf(full, sizeof(full), "%s/%s", corrtable_path, fname);
ret = dyesub_read_file(full, (uint8_t*) &table, sizeof(table), &len);
if (ret)
return ret;
ret = dyesub_read_file(full, (uint8_t*) &table, sizeof(table), &len);
if (ret)
return ret;
}
switch(len) {
case 0: /* Ie "null table" */
case sizeof(struct hiti_heattable_v1a):
y = table.v1a.y;
m = table.v1a.m;
@ -2158,6 +2160,10 @@ static int hiti_main_loop(void *vctx, const void *vjob, int wait_for_return)
if (ret)
return CUPS_BACKEND_FAILED;
ret = hiti_read_heattable_v2(ctx, hiti_get_heat_file(ctx, job->hdr.quality));
if (ret)
return CUPS_BACKEND_FAILED;
// XXX send CMD_ESD_SHTPC (Heating Parameters & Tone Curve, ~7KB payload) instead?
}
@ -2715,12 +2721,14 @@ static int hiti_query_stats(void *vctx, struct printerstats *stats)
return CUPS_BACKEND_OK;
}
static int hiti_read_heattable_v2(struct hiti_ctx *ctx, char* fname) {
static int hiti_read_heattable_v2(struct hiti_ctx *ctx, const char* fname) {
int len = 0;
int ret;
char full[2048];
int i;
struct hiti_heattable_hdr_v2 *hdr;
uint32_t base = 0;
uint8_t match = 0x00; /* Or 0x20 when there's more than one? */
ctx->num_heattable_entries = 0;
if (ctx->heattable_buf) {
@ -2742,8 +2750,9 @@ static int hiti_read_heattable_v2(struct hiti_ctx *ctx, char* fname) {
if (ret) {
return ret;
}
hdr = (struct hiti_heattable_hdr_v2 *) ctx->heattable_buf;
restart:
hdr = (struct hiti_heattable_hdr_v2 *) ctx->heattable_buf;
ctx->heattable_v2 = malloc(hdr->num_headers * sizeof(struct hiti_heattable_v2));
if (!ctx->heattable_buf) {
ERROR("Memory allocation failed!\n");
@ -2753,22 +2762,36 @@ static int hiti_read_heattable_v2(struct hiti_ctx *ctx, char* fname) {
ctx->num_heattable_entries = hdr->num_headers;
for (i = 0 ; i < hdr->num_headers ; i++) {
DEBUG("Found: %04x %02x @ %d\n",
le16_to_cpu(hdr->entries[i].type),
hdr->entries[i].unknown,
ctx->heattable_v2[i].type = hdr->entries[i].type;
ctx->heattable_v2[i].data = ctx->heattable_buf + base + le32_to_cpu(hdr->entries[i].offset);
ctx->heattable_v2[i].len = le32_to_cpu(hdr->entries[i].len) * 2;
DEBUG("Found: %02x len %d @ %d\n",
ctx->heattable_v2[i].type,
ctx->heattable_v2[i].len,
le32_to_cpu(hdr->entries[i].offset));
ctx->heattable_v2[i].type = le16_to_cpu(hdr->entries[i].type);
ctx->heattable_v2[i].data = ctx->heattable_buf + hdr->entries[i].offset;
if (i > 0) {
ctx->heattable_v2[i-1].len = le32_to_cpu(hdr->entries[i].offset) - le32_to_cpu(hdr->entries[i-1].offset);
if (hdr->entries[i].type == match) {
DEBUG("Found embedded table type %0x02\n", match);
base = le32_to_cpu(hdr->entries[i].offset);
free(ctx->heattable_v2);
goto restart;
}
}
ctx->heattable_v2[i-1].len = len - le32_to_cpu(hdr->entries[i-1].offset);
return CUPS_BACKEND_OK;
};
static void hiti_teardown(void *vctx) {
struct hiti_ctx *ctx = vctx;
if (ctx->heattable_v2)
free(ctx->heattable_v2);
if (ctx->heattable_buf)
free(ctx->heattable_buf);
ctx->num_heattable_entries = 0;
free(ctx);
}
static const char *hiti_prefixes[] = {
"hiti", // Family name
"hiti-p52x", /* Just in case */
@ -2777,11 +2800,12 @@ static const char *hiti_prefixes[] = {
const struct dyesub_backend hiti_backend = {
.name = "HiTi Photo Printers",
.version = "0.46",
.version = "0.47",
.uri_prefixes = hiti_prefixes,
.cmdline_usage = hiti_cmdline,
.cmdline_arg = hiti_cmdline_arg,
.init = hiti_init,
.teardown = hiti_teardown,
.attach = hiti_attach,
.cleanup_job = hiti_cleanup_job,
.read_parse = hiti_read_parse,
@ -2848,5 +2872,69 @@ const struct dyesub_backend hiti_backend = {
- Incorporate changes for CS-series card printers
- More "Matrix table" decoding work
- Pull in updated heat tables & LUTs from windows drivers
- What's the difference bwtween ri/ri1 for P52x series?
- Figure out what to send from v2 heattables
Heattable v2 entires seen so far:
ID LEN Descr
---------------------
01 522 Y (256*be16+10?)
02 522 M
03 522 C
04 522 ? K maybe? (Card only)
10 522 ? (Card only)
11 522 ? (Card only)
13 522 ? (Card only)
14 522 ? (Card only)
15 522 ? (Card only)
20 522 OG
22 522 OM (Not on card)
40 582 CVD
50 4
51 4
80 2562 Y (256*double+256*u16+u16csum?)
81 2562 M
82 2562 C
90 26
a4 1540 ? Card only
a5 1540 ? Card only
a6 1540 ? Card only
a7 1540 M ?
a8 1540 C ?
a9 1540 ? Card only
aa 1540 ? Card only
ab 1540 ? Card only
ae 1540 Y ?
af 1540 Y+M+C (Only seen on its own)
b7 24 M ? (bX not seen on Card pirnters)
b8 24 C ?
be 24 Y ?
bf 24 Y+M+C ?
d4 98 ? Card only
d5 98 ? Card only
d6 98 ? Card only
d7 98 ? Card only
d9 98 ? Card only
da 90 ? Card only
db 98 ? card only
de 98 ? Card only
f0 2 Only seen with an embedded table.. Always 01 00
00 Varies Embedded table
20 Varies Embedded table 2
Question: how do we know which embedded table to use?
** embedded tables only seem present for CARD models.
*/

Loading…
Cancel
Save