diff --git a/configure.ac b/configure.ac index cfacf3d..f936a4d 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,9 @@ AC_INIT([captdriver], [0.1.3]) AC_CONFIG_SRCDIR([src/std.h]) -AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-xz tar-ustar]) +AM_INIT_AUTOMAKE([1.9 no-dist-gzip dist-xz tar-ustar subdir-objects]) +AM_SILENT_RULES([yes]) + AC_LANG([C]) AC_PROG_CC @@ -18,5 +20,6 @@ AC_SUBST(CUPS_LIBS) AC_CONFIG_FILES([Makefile src/Makefile + tests/Makefile ]) AC_OUTPUT diff --git a/tests/captdefilter.c b/tests/captdefilter.c index 4e6e8da..a6b0894 100644 --- a/tests/captdefilter.c +++ b/tests/captdefilter.c @@ -1,5 +1,6 @@ -#include "word.h" +#include "../src/word.h" +#include "scoa-decompress.h" #include "hiscoa-decompress.h" #include @@ -18,6 +19,7 @@ static struct page page; static bool hi_mode = false; static unsigned line_size; +static uint8_t *buffer_line; static struct hiscoa_params hiscoa_params; static uint8_t *page_reserve(size_t size) @@ -96,14 +98,16 @@ static void decode_hiscoa_band_data(const uint8_t *buf, size_t size, unsigned li static void decode_hiscoa_band(const uint8_t *buf, size_t size) { - unsigned lines = WORD(buf[2], buf[3]); - decode_hiscoa_band_data(buf + 4, size - 4, lines); + unsigned lines = WORD(buf[0], buf[1]); + decode_hiscoa_band_data(buf + 2, size - 2, lines); } -static void decode_hiscoa_band2(const uint8_t *buf, size_t size) + +static void decode_hiscoa_band3(const uint8_t *buf, size_t size) { - unsigned lines = WORD_(buf[2], buf[3]); - decode_hiscoa_band_data(buf + 8, size - 8, lines); + unsigned lines = WORD(buf[0], buf[1]); + decode_hiscoa_band_data(buf + 6, size - 6, lines); } + static void dispatch(uint16_t cmd, const uint8_t *buf, size_t size) { switch (cmd) { @@ -122,6 +126,9 @@ static void dispatch(uint16_t cmd, const uint8_t *buf, size_t size) dump(buf, size); line_size = WORD(buf[26], buf[27]); fprintf(stderr, " decoded: L=%u bytes, %u pixels\n", line_size, line_size * 8); + buffer_line=calloc(line_size, sizeof(uint8_t)); + if (! buffer_line) + abort(); break; case 0xD0A4: fprintf(stderr, " -(Hi-SCoA parameters)-\n"); @@ -135,23 +142,22 @@ static void dispatch(uint16_t cmd, const uint8_t *buf, size_t size) break; case 0xC0A0: if (! hi_mode) { - fprintf(stderr, " -(SCoA data)-\n"); dump(buf, 16); } else { fprintf(stderr, " -(Hi-SCoA data from printer debug)-\n"); - dump(buf, 4); + dump(buf, 16); decode_hiscoa_band_data(buf, size, 70); } break; case 0x8000: fprintf(stderr, " -(Hi-SCoA data)-\n"); - dump(buf, 4); + dump(buf + 2, 4); decode_hiscoa_band(buf, size); break; case 0x8200: - fprintf(stderr, " -(Hi-SCoA data 0x8200)-\n"); - dump(buf, 4); - decode_hiscoa_band2(buf, size); + fprintf(stderr, " -(Hi-SCoA data)-\n"); + dump(buf + 6, 4); + decode_hiscoa_band3(buf, size); break; case 0xC0A4: fprintf(stderr, " --end--\n"); @@ -197,14 +203,19 @@ int main(int argc, char **argv) pos = 4; cmd = WORD(buf[0], buf[1]); switch (cmd) { + case 0x8000: + fread(buf + pos, 1, 2, input); + pos += 2; + len = WORD(buf[4], buf[5]); + len <<= 16; + len += WORD(buf[2], buf[3]); + break; case 0x8200: fread(buf + pos, 1, 4, input); pos += 4; len = WORD(buf[6], buf[7]); len <<= 16; len += WORD(buf[4], buf[5]); - pos=0; - fseek(input, -8, SEEK_CUR); break; default: len = WORD(buf[2], buf[3]); @@ -212,15 +223,28 @@ int main(int argc, char **argv) } fprintf(stderr, "CMD %04X len=%u\n", cmd, len); if (fread(buf + pos, 1, len - pos, input) != len - pos) { - fprintf(stderr, "! unable to read %u bytes\n", len - pos); + fprintf(stderr, "! unable to read %li bytes\n", len - pos); + break; + } + switch (cmd) { + case 0x8000: + dispatch(cmd, buf + pos, len - pos); + break; + case 0x8200: + dispatch(cmd, buf + pos - 6, len - pos + 6); + break; + default: + dispatch(cmd, buf + pos, len - pos); break; } - dispatch(cmd, buf + pos, len - pos); } if (page.size) page_output(); + if (buffer_line) + free(buffer_line); + if (argc > 1) fclose(input); return 0; diff --git a/tests/captdefilter.c.orig b/tests/captdefilter.c.orig new file mode 100644 index 0000000..4e6e8da --- /dev/null +++ b/tests/captdefilter.c.orig @@ -0,0 +1,227 @@ + +#include "word.h" +#include "hiscoa-decompress.h" + +#include +#include +#include +#include +#include + +struct page { + size_t reserve; + size_t size; + uint8_t *data; +}; + +static struct page page; + +static bool hi_mode = false; +static unsigned line_size; +static struct hiscoa_params hiscoa_params; + +static uint8_t *page_reserve(size_t size) +{ + size_t reserve = page.reserve; + while (page.size + size > reserve) + reserve *= 2; + if (reserve != page.reserve) { + page.reserve = reserve; + page.data = realloc(page.data, page.reserve); + if (! page.data) + abort(); + } + return page.data + page.size; +} + +static void page_add(const uint8_t *buf, size_t size) +{ + memcpy(page_reserve(size), buf, size); + page.size += size; +} + +static void page_output(void) +{ + unsigned w = line_size * 8; + unsigned h = page.size / line_size; + printf("P4\n#\n%u %u\n", w, h); + fwrite(page.data, line_size, h, stdout); + fprintf(stderr, "output page %ux%u px\n", w, h); + page.size = 0; +} + +static void dump(const uint8_t *buf, size_t size) +{ + size_t i; + for (i = 1; i <= size; ++i) { + fprintf(stderr, " %02x", buf[i - 1]); + if (i % 16 == 0 || i == size) + fprintf(stderr, "\n"); + } +} + +static void decode_hiscoa_params(const uint8_t *buf, size_t size) +{ + hiscoa_params.origin_3 = (int8_t)buf[0]; + hiscoa_params.origin_5 = (int8_t)buf[1]; + /* buf[2] - ??? */ + /* buf[3] - ??? */ + hiscoa_params.origin_0 = (int8_t) buf[4]; /* ??? */ + hiscoa_params.origin_2 = (int8_t) buf[5]; + hiscoa_params.origin_4 = (int16_t) WORD(buf[6], buf[7]); +} + +static void decode_hiscoa_band_data(const uint8_t *buf, size_t size, unsigned lines) +{ + const uint8_t *src; + size_t srcsize; + uint8_t *dest; + size_t destsize = 0; + unsigned type; + src = buf; + srcsize = size; + hiscoa_decompress_band((const void **)&src, &srcsize, + NULL, &destsize, line_size, &hiscoa_params); + dest = page_reserve(destsize); + src = buf; + srcsize = size; + type = hiscoa_decompress_band((const void **)&src, &srcsize, + dest, &destsize, line_size, &hiscoa_params); + page.size += destsize; + fprintf(stderr, " eob = %u, lines = %u, expected bytes = %u\n", + type, lines, lines * line_size); + fprintf(stderr, " unconsumed size = %u, decompressed size = %u\n", + (unsigned) srcsize, (unsigned) destsize); +} + +static void decode_hiscoa_band(const uint8_t *buf, size_t size) +{ + unsigned lines = WORD(buf[2], buf[3]); + decode_hiscoa_band_data(buf + 4, size - 4, lines); +} +static void decode_hiscoa_band2(const uint8_t *buf, size_t size) +{ + unsigned lines = WORD_(buf[2], buf[3]); + decode_hiscoa_band_data(buf + 8, size - 8, lines); +} +static void dispatch(uint16_t cmd, const uint8_t *buf, size_t size) +{ + switch (cmd) { + case 0xD0A9: + fprintf(stderr, " --(multi-command)--\n"); + while (size) { + uint16_t cc = WORD(buf[0], buf[1]); + unsigned cs = WORD(buf[2], buf[3]); + dispatch(cc, buf + 4, cs - 4); + buf += cs; + size -= cs; + } + break; + case 0xD0A0: + fprintf(stderr, " -(compression parameters)-\n"); + dump(buf, size); + line_size = WORD(buf[26], buf[27]); + fprintf(stderr, " decoded: L=%u bytes, %u pixels\n", line_size, line_size * 8); + break; + case 0xD0A4: + fprintf(stderr, " -(Hi-SCoA parameters)-\n"); + dump(buf, size); + decode_hiscoa_params(buf, size); + hi_mode = true; + fprintf(stderr, " decoded: [0]=%i+L [2]=%i+L [4]=%i [3]=%i [5]=%i\n", + hiscoa_params.origin_0, hiscoa_params.origin_2, + hiscoa_params.origin_4, + hiscoa_params.origin_3, hiscoa_params.origin_5); + break; + case 0xC0A0: + if (! hi_mode) { + fprintf(stderr, " -(SCoA data)-\n"); + dump(buf, 16); + } else { + fprintf(stderr, " -(Hi-SCoA data from printer debug)-\n"); + dump(buf, 4); + decode_hiscoa_band_data(buf, size, 70); + } + break; + case 0x8000: + fprintf(stderr, " -(Hi-SCoA data)-\n"); + dump(buf, 4); + decode_hiscoa_band(buf, size); + break; + case 0x8200: + fprintf(stderr, " -(Hi-SCoA data 0x8200)-\n"); + dump(buf, 4); + decode_hiscoa_band2(buf, size); + break; + case 0xC0A4: + fprintf(stderr, " --end--\n"); + page_output(); + break; + default: + dump(buf, size); + break; + } +} + +int main(int argc, char **argv) +{ + unsigned iband; + static uint8_t buf[1<<20]; + + FILE *input = stdin; + + if (argc > 1) { + input = fopen(argv[1], "r"); + if (! input) + abort(); + } + + page.reserve = 1024; + page.size = 0; + page.data = malloc(page.reserve); + if (! page.data) + abort(); + + while (1) { + int s; + uint16_t cmd; + uint32_t len; + size_t pos; + s = fread(buf, 1, 4, input); + if (s == 0) + break; + if (s != 4) { + fprintf(stderr, "! unable to read header\n"); + break; + } + pos = 4; + cmd = WORD(buf[0], buf[1]); + switch (cmd) { + case 0x8200: + fread(buf + pos, 1, 4, input); + pos += 4; + len = WORD(buf[6], buf[7]); + len <<= 16; + len += WORD(buf[4], buf[5]); + pos=0; + fseek(input, -8, SEEK_CUR); + break; + default: + len = WORD(buf[2], buf[3]); + break; + } + fprintf(stderr, "CMD %04X len=%u\n", cmd, len); + if (fread(buf + pos, 1, len - pos, input) != len - pos) { + fprintf(stderr, "! unable to read %u bytes\n", len - pos); + break; + } + dispatch(cmd, buf + pos, len - pos); + } + + if (page.size) + page_output(); + + if (argc > 1) + fclose(input); + return 0; +} diff --git a/tests/hiscoa-decompress.c b/tests/hiscoa-decompress.c index 003dd16..e7bad7c 100644 --- a/tests/hiscoa-decompress.c +++ b/tests/hiscoa-decompress.c @@ -1,7 +1,9 @@ +#include +#include #include "hiscoa-decompress.h" -#include "std.h" -#include "hiscoa-common.h" +#include "../src/std.h" +#include "../src/hiscoa-common.h" struct state { const uint8_t xorval; @@ -108,6 +110,7 @@ static inline void output_byte(struct state *state, uint8_t byte) static void copy_block(struct state *state, unsigned origin) { unsigned len = state->prefix + read_long_number(state); + fprintf(stderr, " len=%u (prefix=%u, N=%u)\n", len, state->prefix, len-state->prefix); unsigned i; for (i = 0; i < len; ++i) { uint8_t byte = (state->output_buf @@ -143,7 +146,8 @@ unsigned hiscoa_decompress_band( .origin_2 = params->origin_2 + line_size, .origin_4 = params->origin_4, }; - +int i; +unsigned n; unsigned ret = (unsigned) -1; bool end = false; while (! end && state.bitpos < 8 * state.input_size) { @@ -151,42 +155,82 @@ unsigned hiscoa_decompress_band( unsigned group = read_n10(&state, 8); switch (group) { case 0: + fprintf(stderr, " LONGREP0 (LINESIZE=%u, L0=%u) ", line_size, state.origin_0); copy_block(&state, state.origin_0); break; case 1: - output_byte(&state, get_byte(&state, 15 - read_number(&state, 4))); + n = read_number(&state, 4); + { + fprintf(stderr, " REPBYTE (%u) stash={", n); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } + output_byte(&state, get_byte(&state, 15 - n)); + { + fprintf(stderr, " stash={"); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } break; case 2: if (read_bit(&state)) { - output_byte(&state, save_byte(&state, read_number(&state, 8))); + n = read_number(&state, 8); + { + fprintf(stderr, " BYTE (%.2x) stash={", n); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } + output_byte(&state, save_byte(&state, n)); + { + fprintf(stderr, " stash={"); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } } else { + fprintf(stderr, " LONGREP2 (LINESIZE=%u, L2=%u)", line_size, state.origin_2); copy_block(&state, state.origin_2); swap(&state.origin_2, &state.origin_0); } break; case 3: + fprintf(stderr, " LONGREP3 (L3=%u) ", state.origin_3); copy_block(&state, state.origin_3); break; case 4: + fprintf(stderr, " LONGREP4 (L4=%u) ", state.origin_4); copy_block(&state, state.origin_4); break; case 5: + fprintf(stderr, " LONGREP5 (L5=%u) ", state.origin_5); copy_block(&state, state.origin_5); swap(&state.origin_5, &state.origin_3); break; case 6: if (read_bit(&state)) { + { + fprintf(stderr, " ZEROBYTE (8) stash={"); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } output_byte(&state, save_byte(&state, 0)); + { + fprintf(stderr, " stash={"); + for (i=0; i<16; i++) fprintf(stderr, " %.2x", state.bytes[i]); + fprintf(stderr, " }\n"); + } } else { state.prefix = read_prefix(&state); no_reset_prefix = true; + fprintf(stderr, " PREFIX (%u)\n", state.prefix); } break; case 7: ret = read_number(&state, 2); end = true; + fprintf(stderr, " END (%u)\n", ret); break; case 8: + fprintf(stderr, " NOP\n"); break; } if (! no_reset_prefix) diff --git a/tests/hiscoa-decompress.h b/tests/hiscoa-decompress.h index 24715f3..b3fb51f 100644 --- a/tests/hiscoa-decompress.h +++ b/tests/hiscoa-decompress.h @@ -1,7 +1,7 @@ #pragma once -#include "std.h" -#include "hiscoa-common.h" +#include "../src/std.h" +#include "../src/hiscoa-common.h" unsigned hiscoa_decompress_band( const void **band, size_t *size, diff --git a/tests/test-hiscoa.c b/tests/test-hiscoa.c index 20aaeab..ec5a45c 100644 --- a/tests/test-hiscoa.c +++ b/tests/test-hiscoa.c @@ -1,10 +1,11 @@ -#include "std.h" -#include "hiscoa-compress.h" +#include "../src/std.h" +#include "../src/hiscoa-compress.h" #include "hiscoa-decompress.h" #include #include #include +#include static const unsigned band_size = 70; @@ -64,7 +65,7 @@ int main(int argc, char **argv) size_t bl = s / (width / 8); size_t bs = hiscoa_compress_band(bandbuf, 2 * bsize, buf, width / 8, bl, - (s < bsize) ? HISCOA_EOB_LAST : HISCOA_EOB_NORMAL, + (s < (int)bsize) ? HISCOA_EOB_LAST : HISCOA_EOB_NORMAL, ¶ms); memset(dcbuf, 0xAA, bsize); tmps = bs; @@ -81,7 +82,7 @@ int main(int argc, char **argv) fprintf(stderr, "! band compressed INCORRECTLY\n"); bad = true; } - if (dcsize != s) { + if ((int)dcsize != s) { fprintf(stderr, "! band size incorrect: %u instead of %u\n", (unsigned) dcsize, (unsigned) s); bad = true; @@ -89,7 +90,7 @@ int main(int argc, char **argv) if (bad) errors += 1; } - if (s < bsize) + if (s < (int)bsize) break; }