diff options
author | Gregory Montoir | 2005-10-18 19:16:17 +0000 |
---|---|---|
committer | Gregory Montoir | 2005-10-18 19:16:17 +0000 |
commit | e7c8dc025acde517dce149c97a314ae874e213dd (patch) | |
tree | a81530043ad13f360824197d1d103ad79b7ec00e /scumm | |
parent | 953b35a8c349200a2c25e58db1ec226e7de89755 (diff) | |
download | scummvm-rg350-e7c8dc025acde517dce149c97a314ae874e213dd.tar.gz scummvm-rg350-e7c8dc025acde517dce149c97a314ae874e213dd.tar.bz2 scummvm-rg350-e7c8dc025acde517dce149c97a314ae874e213dd.zip |
Fixed wiz TRLE encoding
svn-id: r19157
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/wiz_he.cpp | 254 | ||||
-rw-r--r-- | scumm/wiz_he.h | 6 |
2 files changed, 113 insertions, 147 deletions
diff --git a/scumm/wiz_he.cpp b/scumm/wiz_he.cpp index 8a253b44e9..a045370023 100644 --- a/scumm/wiz_he.cpp +++ b/scumm/wiz_he.cpp @@ -601,19 +601,19 @@ uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, ui return data[y * w + x]; } -void Wiz::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect *srcRect) { - int y = srcRect->top; +void Wiz::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect &rCapt) { + int y = rCapt.top; while (y != 0) { data += READ_LE_UINT16(data) + 2; --y; } - int ih = srcRect->height(); + int ih = rCapt.height(); while (ih--) { uint16 off = READ_LE_UINT16(data); data += 2; if (off != 0) { const uint8 *p = data; - int x1 = srcRect->left; - int x2 = srcRect->right; + int x1 = rCapt.left; + int x2 = rCapt.right; uint8 code; while (x1 > 0) { code = *p++; @@ -673,10 +673,10 @@ dec_sub3: x2 -= code; } } -void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect *srcRect) { - data += srcRect->top * srcPitch + srcRect->left; - int iw = srcRect->width(); - int ih = srcRect->height(); +void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect &rCapt) { + data += rCapt.top * srcPitch + rCapt.left; + int iw = rCapt.width(); + int ih = rCapt.height(); while (ih--) { for (int i = 0; i < iw; ++i) { ++histogram[data[i]]; @@ -685,161 +685,127 @@ void Wiz::computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPi } } -struct wizPackCtx { - uint32 len; - uint8 saveCode; - uint8 saveBuf[256]; -}; - -static void wizPackType1Helper1(uint8 *&dst, int len, byte newColor, byte prevColor, wizPackCtx *ctx) { - assert(len > 0); - if (newColor == prevColor) { - do { - int blockLen = MIN(len, 0x7F); - len -= blockLen; - if (dst) { - *dst++ = (blockLen * 2) | 1; - } - ++ctx->len; - } while (len > 0); - } else { - do { - int blockLen = MIN(len, 0x40); - len -= blockLen; - if (dst) { - *dst++ = ((blockLen - 1) * 4) | 2; - } - ++ctx->len; - if (dst) { - *dst++ = newColor; - } - ++ctx->len; - } while (len > 0); - } -} - -static void wizPackType1Helper2(uint8 *&dst, int len, wizPackCtx *ctx) { - assert(len > 0); - const uint8 *src = ctx->saveBuf; - do { - int blockLen = MIN(len, 0x40); - len -= blockLen; - if (dst) { - *dst++ = (blockLen - 1) * 4; - } - ++ctx->len; - while (blockLen--) { - if (dst) { - *dst++ = *src++; - } - ++ctx->len; - } - } while (len > 0); -} - static int wizPackType1(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 tColor) { - debug(1, "wizPackType1(%d, [%d,%d,%d,%d])", tColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom); - wizPackCtx ctx; - memset(&ctx, 0, sizeof(ctx)); - + debug(9, "wizPackType1(%d, [%d,%d,%d,%d])", tColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom); src += rCapt.top * srcPitch + rCapt.left; int w = rCapt.width(); int h = rCapt.height(); - - uint8 *nextDstPtr, *curDstPtr; - uint8 curColor, prevColor; - int saveBufPos; - - nextDstPtr = curDstPtr = 0; - int dataSize = 0; while (h--) { + uint8 *dstLine = dst; if (dst) { - curDstPtr = dst; - nextDstPtr = dst; dst += 2; } - dataSize += 2; - int numBytes = 0; - - int i, code; - for (i = 0; i < w; ++i) { - if (src[i] != tColor) - break; - } - if (i != w) { - curDstPtr = dst; - ctx.len = 0; - prevColor = ctx.saveBuf[0] = *src; - const uint8 *curSrcPtr = src + 1; - saveBufPos = 1; - code = (tColor - ctx.saveBuf[0] == 0) ? 1 : 0; - int curw = w; - while (curw--) { - ctx.saveBuf[saveBufPos] = curColor = *curSrcPtr++; - ++saveBufPos; - if (code == 0) { - if (curColor == tColor) { - --saveBufPos; - wizPackType1Helper2(curDstPtr, saveBufPos, &ctx); - code = saveBufPos = 1; - ctx.saveBuf[0] = curColor; - numBytes = 0; - prevColor = curColor; - continue; + uint8 diffBuffer[0x40]; + int runCountSame = 0; + int runCountDiff = 0; + uint8 prevColor = src[0]; + for (int i = 1; i < w; ) { + uint8 color = src[i++]; + if (i == 2) { + if (prevColor == color) { + runCountSame = 1; + } else { + diffBuffer[0] = prevColor; + runCountDiff = 1; + } + } + if (prevColor == color) { + if (runCountDiff != 0) { + runCountSame = 1; + if (runCountDiff > 1) { + --runCountDiff; + if (dst) { + *dst++ = ((runCountDiff - 1) << 2) | 0; + memcpy(dst, diffBuffer, runCountDiff); + dst += runCountDiff; + } + dataSize += runCountDiff + 1; } - if (saveBufPos > 0x80) { - --saveBufPos; - wizPackType1Helper2(curDstPtr, saveBufPos, &ctx); - saveBufPos = 1; - ctx.saveBuf[0] = curColor; - numBytes = 0; - prevColor = curColor; - continue; + runCountDiff = 0; + } + ++runCountSame; + if (prevColor == tColor) { + if (runCountSame == 0x7F) { + if (dst) { + *dst++ = (runCountSame << 1) | 1; + } + ++dataSize; + runCountSame = 0; } - if (prevColor != curColor) { - numBytes = saveBufPos - 1; - prevColor = curColor; - continue; + } else { + if (runCountSame == 0x40) { + if (dst) { + *dst++ = ((runCountSame - 1) << 2) | 2; + *dst++ = prevColor; + } + dataSize += 2; + runCountSame = 0; } - code = 1; - if (numBytes != 0) { - if (saveBufPos - numBytes < 3) { - code = 0; - } else { - wizPackType1Helper2(curDstPtr, numBytes, &ctx); + } + } else { + if (runCountSame != 0) { + if (prevColor == tColor) { + if (dst) { + *dst++ = (runCountSame << 1) | 1; } + ++dataSize; + } else { + if (dst) { + *dst++ = ((runCountSame - 1) << 2) | 2; + *dst++ = prevColor; + } + dataSize += 2; } + runCountSame = 0; } - if (prevColor != curColor || saveBufPos - numBytes > 0x80) { - saveBufPos -= numBytes; - --saveBufPos; - wizPackType1Helper1(curDstPtr, saveBufPos, prevColor, tColor, &ctx); - saveBufPos = 1; - numBytes = 0; - ctx.saveBuf[0] = curColor; - code = (tColor - ctx.saveBuf[0] == 0) ? 1 : 0; + assert(runCountDiff < ARRAYSIZE(diffBuffer)); + diffBuffer[runCountDiff++] = color; + if (runCountDiff == 0x40) { + if (dst) { + *dst++ = ((runCountDiff - 1) << 2) | 0; + memcpy(dst, diffBuffer, runCountDiff); + dst += runCountDiff + 1; + } + dataSize += runCountDiff + 1; + runCountDiff = 0; } - prevColor = curColor; } - if (code == 0) { - wizPackType1Helper2(curDstPtr, saveBufPos, &ctx); + prevColor = color; + } + if (runCountSame != 0) { + if (prevColor == tColor) { + if (dst) { + *dst++ = (runCountSame << 1) | 1; + } + ++dataSize; } else { - saveBufPos -= numBytes; - wizPackType1Helper1(curDstPtr, saveBufPos, prevColor, tColor, &ctx); + if (dst) { + *dst++ = ((runCountSame - 1) << 2) | 2; + *dst++ = prevColor; + } + dataSize += 2; } - dataSize += ctx.len; - src += srcPitch; + } + if (runCountDiff != 0) { if (dst) { - dst += ctx.len; - *(uint16 *)nextDstPtr = TO_LE_16(ctx.len); + *dst++ = ((runCountDiff - 1) << 2) | 0; + memcpy(dst, diffBuffer, runCountDiff); + dst += runCountDiff; } + dataSize += runCountDiff + 1; + } + if (dst) { + WRITE_LE_UINT16(dstLine, dst - dstLine - 2); } + dataSize += 2; + src += srcPitch; } return dataSize; } static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common::Rect& rCapt, uint8 tColor) { + debug(9, "wizPackType0(%d, [%d,%d,%d,%d])", tColor, rCapt.left, rCapt.top, rCapt.right, rCapt.bottom); int w = rCapt.width(); int h = rCapt.height(); int size = w * h; @@ -855,7 +821,7 @@ static int wizPackType0(uint8 *dst, const uint8 *src, int srcPitch, const Common } void Wiz::captureWizImage(int resNum, const Common::Rect& r, bool backBuffer, int compType) { - debug(1, "ScummEngine_v72he::captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom); + debug(5, "ScummEngine_v72he::captureWizImage(%d, %d, [%d,%d,%d,%d])", resNum, compType, r.left, r.top, r.right, r.bottom); uint8 *src = NULL; VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen]; if (backBuffer) { @@ -987,6 +953,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); + uint8 *wizh = _vm->findWrappedBlock(MKID('WIZH'), dataPtr, state, 0); assert(wizh); uint32 comp = READ_LE_UINT32(wizh + 0x0); @@ -1032,7 +999,6 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int _vm->res.lock(rtImage, dstResNum); dst = _vm->findWrappedBlock(MKID('WIZD'), dstPtr, 0, 0); assert(dst); - getWizImageDim(dstResNum, 0, cw, ch); } else { VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen]; @@ -1994,7 +1960,7 @@ int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y, writeVar(0, 0); defineArray(0, kDwordArray, 0, 0, 0, 255); if (readVar(0) != 0) { - Common::Rect rCap(x, y, w + 1, h + 1); + Common::Rect rCapt(x, y, w + 1, h + 1); uint8 *data = getResourceAddress(rtImage, resNum); assert(data); uint8 *wizh = findWrappedBlock(MKID('WIZH'), data, state, 0); @@ -2005,16 +1971,16 @@ int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y, Common::Rect rWiz(w, h); uint8 *wizd = findWrappedBlock(MKID('WIZD'), data, state, 0); assert(wizd); - if (rCap.intersects(rWiz)) { - rCap.clip(rWiz); + if (rCapt.intersects(rWiz)) { + rCapt.clip(rWiz); uint32 histogram[256]; memset(histogram, 0, sizeof(histogram)); switch (c) { case 0: - _wiz->computeRawWizHistogram(histogram, wizd, w, &rCap); + _wiz->computeRawWizHistogram(histogram, wizd, w, rCapt); break; case 1: - _wiz->computeWizHistogram(histogram, wizd, &rCap); + _wiz->computeWizHistogram(histogram, wizd, rCapt); break; default: error("computeWizHistogram: Unhandled wiz compression type %d", c); diff --git a/scumm/wiz_he.h b/scumm/wiz_he.h index fcbc135323..d11f69677c 100644 --- a/scumm/wiz_he.h +++ b/scumm/wiz_he.h @@ -166,7 +166,7 @@ public: void fillWizLine(const WizParameters *params); void fillWizPixel(const WizParameters *params); - void getWizImageDim(int resNum, int state, int32 &w, int32 &h); + void getWizImageDim(int resNum, int state, int32 &w, int32 &h); int getWizImageStates(int resnum); int isWizPixelNonTransparent(int resnum, int state, int x, int y, int flags); uint8 getWizPixelColor(int resnum, int state, int x, int y, int flags); @@ -193,8 +193,8 @@ public: int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h); uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color); uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color); - void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect *srcRect); - void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect *srcRect); + void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect& rCapt); + void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect& rCapt); private: ScummEngine_v70he *_vm; |