Mercurial > hg > dmlib
diff tools/lib64fmts.c @ 1707:a0986cfd6f9d
More consistently use DMGrowBuf in the lib64gfx APIs, and implement
"backwards" RLE decoding and encoding (optionally regards input/output).
Not tested very much yet, there may be bugs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 05 Jun 2018 21:58:10 +0300 |
parents | 1036b0dcccb5 |
children | 4fd94bf558b3 |
line wrap: on
line diff
--- a/tools/lib64fmts.c Tue Jun 05 19:57:08 2018 +0300 +++ b/tools/lib64fmts.c Tue Jun 05 21:58:10 2018 +0300 @@ -31,7 +31,6 @@ }; - static int fmtProbeKoalaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) { // Attempt to prevent misprobes of unpacked Koala and Run Paint @@ -45,7 +44,7 @@ } -static int fmtDecodeKoalaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeKoalaPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; DMGrowBuf mem; @@ -54,10 +53,11 @@ cfg.type = DM_COMP_RLE_MARKER; cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2; cfg.rleMarkerB = 0xfe; - if ((res = dmDecodeGenericRLEAlloc(&mem, buf, buf + len, &cfg)) != DMERR_OK) + + if ((res = dmDecodeGenericRLEAlloc(&mem, buf, &cfg)) != DMERR_OK) goto out; - res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + res = dmC64DecodeGenericBMP(img, &mem, fmt); out: dmGrowBufFree(&mem); @@ -81,7 +81,7 @@ cfg.rleMarkerB = 0xfe; cfg.rleMinCountB = 3; cfg.rleMaxCountB = 255; - res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); + res = dmEncodeGenericRLE(buf, &tmp, &cfg); out: dmGrowBufFree(&tmp); @@ -105,20 +105,21 @@ } -static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeDrazPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf mem; + DMGrowBuf mem, tmp; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; - cfg.rleMarkerB = buf[0x0d]; + cfg.rleMarkerB = buf->data[0x0d]; - if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, &cfg)) != DMERR_OK) + if ((res = dmDecodeGenericRLEAlloc(&mem, + dmGrowBufCreateFromOffs(&tmp, buf, 0x0e), &cfg)) != DMERR_OK) goto out; - res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + res = dmC64DecodeGenericBMP(img, &mem, fmt); out: dmGrowBufFree(&mem); @@ -143,7 +144,7 @@ cfg.rleMinCountB = 3; cfg.rleMaxCountB = 255; - dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); + dmGenericRLEAnalyze(&tmp, &cfg); // Add the header bits if (!dmGrowBufPut(buf, (Uint8 *) magicID, strlen(magicID)) || @@ -154,7 +155,7 @@ } // And now RLE compress the data to the existing buffer - res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); + res = dmEncodeGenericRLE(buf, &tmp, &cfg); out: dmGrowBufFree(&tmp); @@ -174,11 +175,10 @@ static BOOL fmtDrazLaceGetLaceType(DMC64Image *img, const DMC64EncDecOp *op, - const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) + const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { - (void) len; (void) fmt; - img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR; + img->laceType = buf->data[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR; return TRUE; } @@ -205,21 +205,22 @@ } -static int fmtDecodeBDP5Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeBDP5Packed(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf mem; + DMGrowBuf mem, tmp; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1; - cfg.rleMarkerB = buf[8]; - cfg.rleMarkerW = buf[9]; + cfg.rleMarkerB = buf->data[8]; + cfg.rleMarkerW = buf->data[9]; - if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 10, buf + len, &cfg)) != DMERR_OK) + if ((res = dmDecodeGenericRLEAlloc(&mem, + dmGrowBufCreateFromOffs(&tmp, buf, 10), &cfg)) != DMERR_OK) goto out; - res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + res = dmC64DecodeGenericBMP(img, &mem, fmt); out: dmGrowBufFree(&mem); @@ -230,11 +231,11 @@ static int fmtEncodeBDP5Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf tmp; + DMGrowBuf mem; DMCompParams cfg; // Encode the data to temp buffer - if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) + if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK) goto out; // Analyze and setup RLE @@ -245,7 +246,7 @@ cfg.rleMinCountW = 256; cfg.rleMaxCountW = 1024; - dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); + dmGenericRLEAnalyze(&mem, &cfg); // Add the header bits if (!dmGrowBufPut(buf, (Uint8 *) fmtBDP5MagicID, strlen(fmtBDP5MagicID)) || @@ -257,10 +258,10 @@ } // And now RLE compress the data to the existing buffer - res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); + res = dmEncodeGenericRLE(buf, &mem, &cfg); out: - dmGrowBufFree(&tmp); + dmGrowBufFree(&mem); return res; } @@ -302,7 +303,7 @@ } -static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; DMGrowBuf mem, tmp; @@ -310,22 +311,22 @@ // Amica Paint apparently is broken and stores one byte less than it should // so we need to do some crappy buffer expansion here .. - if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK) + if ((res = dmGrowBufAlloc(&tmp, buf->len + 4, 4)) != DMERR_OK) return res; - memcpy(tmp.data, buf, len); - tmp.len = len + 1; + memcpy(tmp.data, buf->data, buf->len); + tmp.len = buf->len + 1; // Now do an RLE decode on the enlarged buffer cfg.type = DM_COMP_RLE_MARKER; cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; cfg.rleMarkerB = 0xC2; - if ((res = dmDecodeGenericRLEAlloc(&mem, tmp.data, tmp.data + tmp.len, &cfg)) != DMERR_OK) + if ((res = dmDecodeGenericRLEAlloc(&mem, &tmp, &cfg)) != DMERR_OK) goto out; // And finally decode to bitmap struct - res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + res = dmC64DecodeGenericBMP(img, &mem, fmt); out: dmGrowBufFree(&tmp); @@ -337,11 +338,11 @@ static int fmtEncodeAmicaPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf tmp; + DMGrowBuf mem; DMCompParams cfg; // Encode the data to temp buffer - if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) + if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK) goto out; // And now RLE compress the data to the existing buffer @@ -351,10 +352,10 @@ cfg.rleMinCountB = 3; cfg.rleMaxCountB = 255; - res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); + res = dmEncodeGenericRLE(buf, &mem, &cfg); out: - dmGrowBufFree(&tmp); + dmGrowBufFree(&mem); return res; } @@ -370,11 +371,10 @@ static BOOL fmtTruePaintGetLaceType(DMC64Image *img, const DMC64EncDecOp *op, - const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) + const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { (void) op; (void) buf; - (void) len; (void) fmt; img->laceType = D64_ILACE_RES; return TRUE; @@ -427,10 +427,11 @@ } -static int fmtDecodeTruePaintPacked(DMC64Image *img, const Uint8 *src, const size_t srcLen, const DMC64ImageFormat *fmt) +static int fmtDecodeTruePaintPacked(DMC64Image *img, const DMGrowBuf *src, const DMC64ImageFormat *fmt) { int res = DMERR_OK; Uint8 *dst = NULL; + DMGrowBuf dstTmp; const Uint8 *codeBook1, *codeBook2; size_t srcOffs, dstOffs, @@ -439,8 +440,8 @@ // 1c00-67e8 is the actual area used tho // Codebooks: #1 is trampoline table markers, #2 is RLE data table - codeBook1 = src + 0x81 - 2; - codeBook2 = src + 0x85 - 2; + codeBook1 = src->data + 0x81 - 2; + codeBook2 = src->data + 0x85 - 2; // Allocate output buffer if ((dst = dmMalloc0(dstLen)) == NULL) @@ -451,7 +452,7 @@ } // Begin decompression - srcOffs = srcLen; + srcOffs = src->len; dstOffs = dstLen; while (srcOffs > 0 && dstOffs > 0) @@ -460,7 +461,7 @@ int count = 1, scount; BOOL found = FALSE; - if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, -1)) + if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, -1)) goto out; for (int n = 0; n < 8; n++) @@ -470,7 +471,7 @@ switch (n) { case 4: // Y = 4, JTO = $0B - if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) + if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) goto out; count = data; @@ -484,12 +485,12 @@ // fallthrough case 0: // Y = 0, JTO = $19 - if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) + if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) goto out; break; case 2: // Y = 2, JTO = $07 - if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) + if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) goto out; count = data; @@ -520,7 +521,7 @@ } finish: - res = dmC64DecodeGenericBMP(img, dst, dstLen, fmt); + res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFrom(&dstTmp, dst, dstLen), fmt); out: dmFree(dst); @@ -545,20 +546,21 @@ } -static int fmtDecodeFormatXX2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeFormatXX2(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; + DMGrowBuf tmp; // If there is only data for less than XX2_MIN_SIZE bytes, // allocate a buffer of that size and copy data there. // Otherwise allocate len bytes. - size_t nlen = len < XX2_MIN_SIZE ? XX2_MIN_SIZE : len; + size_t nlen = buf->len < XX2_MIN_SIZE ? XX2_MIN_SIZE : buf->len; Uint8 *mem = dmMalloc0(nlen); if (mem == NULL) return DMERR_MALLOC; - memcpy(mem, buf, len); - res = dmC64DecodeGenericBMP(img, mem, nlen, fmt); + memcpy(mem, buf->data, buf->len); + res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFrom(&tmp, mem, nlen), fmt); dmFree(mem); return res; @@ -580,29 +582,30 @@ } -static int fmtDecodeFunPaint2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) +static int fmtDecodeFunPaint2(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) { int res; + DMGrowBuf tmp; // Check if the data is compressed - if (buf[14]) + if (buf->data[14]) { DMGrowBuf mem; DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; - cfg.rleMarkerB = buf[15]; + cfg.rleMarkerB = buf->data[15]; if ((res = dmDecodeGenericRLEAlloc( - &mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, &cfg)) == DMERR_OK) - res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); + &mem, dmGrowBufCreateFromOffs(&tmp, buf, FUNPAINT2_HEADER_SIZE), &cfg)) == DMERR_OK) + res = dmC64DecodeGenericBMP(img, &mem, fmt); dmGrowBufFree(&mem); } else { - res = dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt); + res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFromOffs(&tmp, buf, FUNPAINT2_HEADER_SIZE), fmt); } return res; @@ -623,11 +626,11 @@ static int fmtEncodeFunPaint2Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf tmp; + DMGrowBuf mem; DMCompParams cfg; // Encode the data to temp buffer - if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) + if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK) goto out; // Analyze and setup RLE @@ -636,7 +639,7 @@ cfg.rleMinCountB = 3; cfg.rleMaxCountB = 255; - dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); + dmGenericRLEAnalyze(&mem, &cfg); // Add the header bits if (!dmGrowBufPut(buf, (Uint8 *) fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || @@ -647,10 +650,10 @@ } // And now RLE compress the data to the existing buffer - res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); + res = dmEncodeGenericRLE(buf, &mem, &cfg); out: - dmGrowBufFree(&tmp); + dmGrowBufFree(&mem); return res; } @@ -1173,6 +1176,7 @@ { DO_COPY , DS_SCREEN_RAM , 0x2000, 0, 0, NULL, NULL }, { DO_COPY , DS_COLOR_RAM , 0x2400, 0, 0, NULL, NULL }, { DO_SET_OP , DS_BGCOL , 0x00 , 0, 0, NULL, NULL }, + { DO_SET_OP , DS_EXTRA_DATA , 10240 , 0, 0, NULL, NULL }, { DO_LAST , 0 , 0 , 0, 0, NULL, NULL }, }, NULL