# HG changeset patch # User Matti Hamalainen # Date 1559649658 -10800 # Node ID b4fbb90937f792fafa02a986fe74fb364720df05 # Parent 810fc98d9003acc3a20fd4020ebdfb21f3bcaf58 Fix Cosmos Designs Hires Manager unpacker. What a mess. Ugh. diff -r 810fc98d9003 -r b4fbb90937f7 tools/lib64fmts.c --- a/tools/lib64fmts.c Sun Jun 02 23:37:35 2019 +0300 +++ b/tools/lib64fmts.c Tue Jun 04 15:00:58 2019 +0300 @@ -981,84 +981,79 @@ static int fmtDecodeCosmosDesignsHiresManagerPacked(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt) { int res; - DMGrowBuf src, tmp; - DMCompParams cfg; - Uint8 data, count, *dstBuf; - const size_t dstSize = 0x7ff2 - 0x4000; - size_t dstOffs; - BOOL getByte = TRUE; - - // Setup the RLE config, only for input - cfg.func = fmt->name; - cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_BACKWARDS_INPUT; + DMGrowBuf tmp; + Uint8 data, *dstBuf; + const size_t baseAddr = 0x4000; + const size_t dstSize = 0x8000 - baseAddr; + size_t dstOffs, srcOffs; // Allocate output buffer if ((dstBuf = dmMalloc0(dstSize)) == NULL) { return dmError(DMERR_MALLOC, - "%s: Could not allocate memory for RLE decoding buffer.\n", - cfg.func); + "Could not allocate memory for RLE decoding buffer.\n"); } // Setup input buffer - dmGrowBufConstCopy(&src, psrc); - dmSetupRLEBuffers(NULL, &src, &cfg); - dstOffs = dstSize; + dstOffs = 0x7ff2 - baseAddr - 1; + srcOffs = psrc->len - 1; - while (dstOffs > 0 && src.offs > 0) + while (dstOffs > 0 && srcOffs > 0) { - if (getByte && !dmGrowBufGetU8(&src, &data)) - { - res = dmError(DMERR_INVALID_DATA, - "%s: RLE: Invalid data/out of data for literal sequence.\n", - cfg.func); - goto out; - } + data = psrc->data[srcOffs]; - // A simple marker byte RLE variant: [Marker] [count] [data] + + // Current data byte tells us the mode if (data == 0) { - if (!dmGrowBufGetU8(&src, &count) || - !dmGrowBufGetU8(&src, &data)) + // RLE run + if (srcOffs < 3) { res = dmError(DMERR_INVALID_DATA, - "%s: RLE: Invalid data/out of data for run sequence.\n", - cfg.func); + "RLE: Invalid data/out of data for run sequence.\n"); goto out; } - int ncount = (int) count; - for (int n = 1; n < ncount && dstOffs > 0; n++) - dstBuf[--dstOffs] = data; + size_t ncount = psrc->data[--srcOffs]; + data = psrc->data[--srcOffs]; + + srcOffs--; - getByte = TRUE; + if (dstOffs < ncount) + goto finish; + + dstOffs -= ncount; + ncount++; + for (size_t n = 0; n < ncount; n++) + dstBuf[dstOffs + n] = data; } else - // Literal run of data bytes { - int ncount = (int) data; - for (int n = 0; n < ncount; n++) + // Literal run of data bytes + size_t ncount = data; + if (srcOffs < ncount) + ncount = srcOffs; + + if (dstOffs < ncount) + ncount = dstOffs; + + srcOffs -= ncount; + dstOffs -= ncount - 1; + + for (size_t n = 0; n < ncount; n++) { - if (!dmGrowBufGetU8(&src, &data)) - goto finish; - - if (dstOffs > 0) - dstBuf[--dstOffs] = data; - else - goto finish; + data = psrc->data[srcOffs + n]; + dstBuf[dstOffs + n] = data; } - getByte = FALSE; } } finish: - dmGrowBufConstCreateFrom(&tmp, dstBuf, 0x3fff); + dmGrowBufConstCreateFrom(&tmp, dstBuf, dstSize); res = dmC64DecodeGenericBMP(img, &tmp, fmt); out: - dmGrowBufFree(&src); dmFree(dstBuf); return res; }