From 7fc8ba70881b376543d4ffa5d309c5926fc55f5b Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Fri, 28 Oct 2022 00:27:03 -0400 Subject: [PATCH] hiti: Major improvements in parsing v2 heattable data files. * Properly decode length * Handle secondary/embedded tables * Document the known field types --- backend_hiti.c | 138 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 113 insertions(+), 25 deletions(-) diff --git a/backend_hiti.c b/backend_hiti.c index 6985625..429c2c4 100644 --- a/backend_hiti.c +++ b/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; + 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; } - 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; - 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. */