Add basic code for wizImage compression type 5.

svn-id: r35568
This commit is contained in:
Travis Howell 2008-12-27 06:11:56 +00:00
parent 6187ec38fb
commit f5b61ffd03
2 changed files with 189 additions and 31 deletions

View File

@ -353,6 +353,30 @@ static bool calcClipRects(int dst_w, int dst_h, int src_x, int src_y, int src_w,
return srcRect.isValidRect() && dstRect.isValidRect();
}
void Wiz::copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
// TODO: Compressed 16 bits in 555 format
Common::Rect r1, r2;
if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
dst += r2.left + r2.top * dstw;
if (flags & kWIFFlipY) {
const int dy = (srcy < 0) ? srcy : (srch - r1.height());
r1.translate(0, dy);
}
if (flags & kWIFFlipX) {
const int dx = (srcx < 0) ? srcx : (srcw - r1.width());
r1.translate(dx, 0);
}
if (xmapPtr) {
decompress16BitWizImage<kWizXMap>(dst, dstw, src, r1, flags, palPtr, xmapPtr);
} else if (palPtr) {
decompress16BitWizImage<kWizRMap>(dst, dstw, src, r1, flags, palPtr);
} else {
decompress16BitWizImage<kWizCopy>(dst, dstw, src, r1, flags);
}
}
}
void Wiz::copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
Common::Rect r1, r2;
if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
@ -528,7 +552,6 @@ void Wiz::copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int
void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor) {
// TODO: RAW 16 bits in 555 format
// HACK: Skip every second bit for now
Common::Rect r1, r2;
if (calcClipRects(dstw, dsth, srcx, srcy, srcw, srch, rect, r1, r2)) {
if (flags & (kWIFFlipY | kWIFFlipX)) {
@ -547,7 +570,7 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth,
dst += r2.left + r2.top * dstw;
while (h--) {
for (int i = 0; i < w; ++i) {
uint8 col = src[2 * i];
uint16 col = READ_LE_UINT16(src + 2 * i) / 256;
if (transColor == -1 || transColor != col) {
dst[i] = palPtr[col];
}
@ -558,6 +581,129 @@ void Wiz::copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth,
}
}
template <int type>
void Wiz::decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
const uint8 *dataPtr, *dataPtrNext;
uint8 code, *dstPtr, *dstPtrNext;
int h, w, xoff, dstInc;
if (type == kWizXMap) {
assert(xmapPtr != 0);
}
if (type == kWizRMap) {
assert(palPtr != 0);
}
dstPtr = dst;
dataPtr = src;
// Skip over the first 'srcRect->top' lines in the data
h = srcRect.top;
while (h--) {
dataPtr += READ_LE_UINT16(dataPtr) + 2;
}
h = srcRect.height();
w = srcRect.width();
if (h <= 0 || w <= 0)
return;
if (flags & kWIFFlipY) {
dstPtr += (h - 1) * dstPitch;
dstPitch = -dstPitch;
}
dstInc = 1;
if (flags & kWIFFlipX) {
dstPtr += w - 1;
dstInc = -1;
}
while (h--) {
xoff = srcRect.left;
w = srcRect.width();
uint16 lineSize = READ_LE_UINT16(dataPtr); dataPtr += 2;
dstPtrNext = dstPtr + dstPitch;
dataPtrNext = dataPtr + lineSize;
if (lineSize != 0) {
while (w > 0) {
code = *dataPtr++;
if (code & 1) {
code >>= 1;
if (xoff > 0) {
xoff -= code;
if (xoff >= 0)
continue;
code = -xoff;
}
dstPtr += dstInc * code;
w -= code;
} else if (code & 2) {
code = (code >> 2) + 1;
if (xoff > 0) {
xoff -= code;
++dataPtr;
if (xoff >= 0)
continue;
code = -xoff;
--dataPtr;
}
w -= code;
if (w < 0) {
code += w;
}
while (code--) {
uint16 col = READ_LE_UINT16(dataPtr) / 256;
if (type == kWizXMap) {
*dstPtr = xmapPtr[col * 256 + *dstPtr];
}
if (type == kWizRMap) {
*dstPtr = palPtr[col];
}
if (type == kWizCopy) {
*dstPtr = col;
}
dstPtr += dstInc;
}
dataPtr+= 2;
} else {
code = (code >> 2) + 1;
if (xoff > 0) {
xoff -= code;
dataPtr += code;
if (xoff >= 0)
continue;
code = -xoff;
dataPtr += xoff;
}
w -= code;
if (w < 0) {
code += w;
}
while (code--) {
uint16 col = READ_LE_UINT16(dataPtr) / 256;
if (type == kWizXMap) {
*dstPtr = xmapPtr[col * 256 + *dstPtr];
}
if (type == kWizRMap) {
*dstPtr = palPtr[col];
}
if (type == kWizCopy) {
*dstPtr = col;
}
dataPtr += 2;
dstPtr += dstInc;
}
}
}
}
dataPtr = dataPtrNext;
dstPtr = dstPtrNext;
}
}
template <int type>
void Wiz::decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr, const uint8 *xmapPtr) {
const uint8 *dataPtr, *dataPtrNext;
@ -703,7 +849,7 @@ void Wiz::decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int
}
}
int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h) {
int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint bitDepth) {
if (x < 0 || x >= w || y < 0 || y >= h) {
return 0;
}
@ -729,20 +875,24 @@ int Wiz::isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h)
return 1;
}
x -= code;
++data;
data += (bitDepth == 16) ? 2 : 1;
} else {
code = (code >> 2) + 1;
if (code > x) {
return 1;
}
x -= code;
data += code;
data += (bitDepth == 16) ? code * 2 : code;
}
}
return (~data[0]) & 1;
if (bitDepth == 16)
return (~READ_LE_UINT16(data)) & 1;
else
return (~data[0]) & 1;
}
uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color) {
if (x < 0 || x >= w || y < 0 || y >= h) {
return color;
}
@ -765,27 +915,35 @@ uint8 Wiz::getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8
} else if (code & 2) {
code = (code >> 2) + 1;
if (code > x) {
return data[0];
return (bitDepth == 16) ? READ_LE_UINT16(data) : data[0];
}
x -= code;
++data;
data += (bitDepth == 16) ? 2 : 1;
} else {
code = (code >> 2) + 1;
if (code > x) {
return data[x];
return (bitDepth == 16) ? READ_LE_UINT16(data + x) : data[x];
}
x -= code;
data += code;
data += (bitDepth == 16) ? code * 2 : code;
}
}
return (data[0] & 1) ? color : data[1];
if (bitDepth == 16)
return (READ_LE_UINT16(data) & 1) ? color : READ_LE_UINT16(data + 1);
else
return (data[0] & 1) ? color : data[1];
}
uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint8 color) {
uint8 Wiz::getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color) {
if (x < 0 || x >= w || y < 0 || y >= h) {
return color;
}
return data[y * w + x];
if (bitDepth == 16)
return READ_LE_UINT16(data + y * w + x * 2);
else
return data[y * w + x];
}
void Wiz::computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect &rCapt) {
@ -1243,6 +1401,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int x1, int y1, int zorder, int
break;
case 5:
// TODO: 16bit color compressed image
copy16BitWizImage(dst, wizd, cw, ch, x1, y1, width, height, &rScreen, flags, palPtr, xmapPtr);
break;
default:
error("drawWizImage: Unhandled wiz compression type %d", comp);
@ -1634,7 +1793,8 @@ void Wiz::displayWizComplexImage(const WizParameters *params) {
++_imagesNum;
} else {
if (sourceImage != 0) {
// TODO
// TODO: Add support for kWPFMaskImg
drawWizImage(params->sourceImage, state, po_x, po_y, params->img.zorder, shadow, field_390, r, flags, dstResNum, palette);
} else if (params->processFlags & (kWPFScaled | kWPFRotate)) {
drawWizComplexPolygon(params->img.resNum, state, po_x, po_y, shadow, rotationAngle, scale, r, flags, dstResNum, palette);
} else {
@ -2102,32 +2262,30 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags
switch (c) {
case 0:
if (_vm->_game.heversion >= 99) {
ret = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
ret = getRawWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
} else {
ret = 0;
}
break;
case 1:
ret = isWizPixelNonTransparent(wizd, x, y, w, h);
ret = isWizPixelNonTransparent(wizd, x, y, w, h, 8);
break;
case 2:
// TODO: 16bit color uncompressed image type
debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
ret = getRawWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR)) != _vm->VAR(_vm->VAR_WIZ_TCOLOR) ? 1 : 0;
break;
case 4:
// TODO: Unknown image type
debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
break;
case 5:
// TODO: 16bit color compressed image type
debug(0, "isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
ret = isWizPixelNonTransparent(wizd, x, y, w, h, 16);
break;
default:
error("isWizPixelNonTransparent: Unhandled wiz compression type %d", c);
break;
}
}
return ret;
return 1;
}
uint8 Wiz::getWizPixelColor(int resNum, int state, int x, int y, int flags) {
@ -2144,25 +2302,23 @@ uint8 Wiz::getWizPixelColor(int resNum, int state, int x, int y, int flags) {
switch (c) {
case 0:
if (_vm->_game.heversion >= 99) {
color = getRawWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
color = getRawWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
} else {
color = _vm->VAR(_vm->VAR_WIZ_TCOLOR);
}
break;
case 1:
color = getWizPixelColor(wizd, x, y, w, h, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
color = getWizPixelColor(wizd, x, y, w, h, 8, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
break;
case 2:
// TODO: 16bit color uncompressed image type
debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c);
color = getRawWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
break;
case 4:
// TODO: Unknown image type
debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c);
break;
case 5:
// TODO: 16bit color compressed image type
debug(0, "getWizPixelColor: Unhandled wiz compression type %d", c);
color = getWizPixelColor(wizd, x, y, w, h, 16, _vm->VAR(_vm->VAR_WIZ_TCOLOR));
break;
default:
error("getWizPixelColor: Unhandled wiz compression type %d", c);

View File

@ -203,13 +203,15 @@ public:
static void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch);
static void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
static void copyWizImageWithMask(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int maskT, int maskP);
static void copy16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags = 0, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
static void copyRawWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
static void copyRaw16BitWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, const Common::Rect *rect, int flags, const uint8 *palPtr, int transColor);
template<int type> static void decompressWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
template<int type> static void decompress16BitWizImage(uint8 *dst, int dstPitch, const uint8 *src, const Common::Rect &srcRect, int flags, const uint8 *palPtr = NULL, const uint8 *xmapPtr = NULL);
template<int type> static void decompressRawWizImage(uint8 *dst, int dstPitch, const uint8 *src, int srcPitch, int w, int h, int transColor, const uint8 *palPtr = NULL);
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);
int isWizPixelNonTransparent(const uint8 *data, int x, int y, int w, int h, uint bitdepth);
uint8 getWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color);
uint8 getRawWizPixelColor(const uint8 *data, int x, int y, int w, int h, uint bitDepth, uint8 color);
void computeWizHistogram(uint32 *histogram, const uint8 *data, const Common::Rect& rCapt);
void computeRawWizHistogram(uint32 *histogram, const uint8 *data, int srcPitch, const Common::Rect& rCapt);