[Scummvm-git-logs] scummvm master -> 0aedc770e43b25e8c1487552e66d1f2687ddc4d3
sev-
noreply at scummvm.org
Tue Dec 26 16:52:57 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
ff6c4424bd IMAGE: Added PackBitsRgn and BitsRgn opcodes to PICT decoder
0aedc770e4 SCUMM: Remove custom PICTv1 decoder in favor of general one
Commit: ff6c4424bd3ce34f367081921f5c7e5b10871b42
https://github.com/scummvm/scummvm/commit/ff6c4424bd3ce34f367081921f5c7e5b10871b42
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-12-26T17:52:52+01:00
Commit Message:
IMAGE: Added PackBitsRgn and BitsRgn opcodes to PICT decoder
Used in SCUMM Mac GUI
Changed paths:
image/pict.cpp
image/pict.h
diff --git a/image/pict.cpp b/image/pict.cpp
index 392a6f298b3..d4c79b1dadb 100644
--- a/image/pict.cpp
+++ b/image/pict.cpp
@@ -68,6 +68,9 @@ void PICTDecoder::setupOpcodesCommon() {
OPCODE(0x0011, o_versionOp, "VersionOp");
OPCODE(0x001E, o_nop, "DefHilite");
OPCODE(0x0028, o_longText, "LongText");
+ OPCODE(0x0091, o_bitsRgn, "BitsRgn");
+ OPCODE(0x0099, o_packBitsRgn, "PackBitsRgn");
+ OPCODE(0x00A0, o_shortComment, "ShortComment");
OPCODE(0x00A1, o_longComment, "LongComment");
OPCODE(0x00FF, o_opEndPic, "OpEndPic");
OPCODE(0x0C00, o_headerOp, "HeaderOp");
@@ -161,6 +164,20 @@ void PICTDecoder::o_longText(Common::SeekableReadStream &stream) {
stream.skip(stream.readByte());
}
+void PICTDecoder::o_bitsRgn(Common::SeekableReadStream &stream) {
+ // Copy unpacked data with clipped region (8bpp or lower)
+ unpackBitsRgn(stream, false);
+}
+
+void PICTDecoder::o_packBitsRgn(Common::SeekableReadStream &stream) {
+ unpackBitsRgn(stream, true);
+}
+
+void PICTDecoder::o_shortComment(Common::SeekableReadStream &stream) {
+ // Ignore
+ stream.readUint16BE();
+}
+
void PICTDecoder::o_longComment(Common::SeekableReadStream &stream) {
// Ignore
stream.readUint16BE();
@@ -452,6 +469,89 @@ void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool withPa
delete[] buffer;
}
+void PICTDecoder::unpackBitsRgn(Common::SeekableReadStream &stream, bool compressed) {
+ int x1, x2, y1, y2;
+ int size = 0;
+ stream.skip(2); // Skip rowBytes
+
+ if (!_outputSurface) {
+ _outputSurface = new Graphics::Surface();
+ _outputSurface->create(_imageRect.width(), _imageRect.height(), Graphics::PixelFormat::createFormatCLUT8());
+ }
+
+ y1 = stream.readSint16BE();
+ x1 = stream.readSint16BE();
+ y2 = stream.readSint16BE();
+ x2 = stream.readSint16BE();
+
+ stream.skip(8); // Skip srcRect
+ stream.skip(8); // Skip dstRect
+ stream.skip(2); // Skip mode
+ stream.skip(stream.readUint16BE() - 2);
+
+ int x = 0;
+ int y = 0;
+ byte value;
+
+ if (!compressed) {
+ for (y = y1; y < y2 && y < _imageRect.height(); y++) {
+ byte b = stream.readByte();
+ byte bit = 0x80;
+
+ for (x = x1; x < x2 && x < _imageRect.width(); x++) {
+ if (b & bit)
+ _outputSurface->setPixel(x, y, 0x0F);
+ else
+ _outputSurface->setPixel(x, y, 0x00);
+
+ bit >>= 1;
+
+ if (bit == 0) {
+ b = stream.readByte();
+ bit = 0x80;
+ }
+ }
+ }
+ } else {
+ for (y = y1; y < y2 && y < _imageRect.height(); y++) {
+ x = x1;
+ size = stream.readByte();
+
+ while (size > 0) {
+ byte count = stream.readByte();
+ size--;
+
+ bool repeat;
+
+ if (count >= 128) {
+ // Repeat value
+ count = 256 - count;
+ repeat = true;
+ value = stream.readByte();
+ size--;
+ } else {
+ // Copy values
+ repeat = false;
+ value = 0;
+ }
+
+ for (int j = 0; j <= count; j++) {
+ if (!repeat) {
+ value = stream.readByte();
+ size--;
+ }
+ for (int k = 7; k >= 0 && x < x2 && x < _imageRect.width(); k--, x++) {
+ if (value & (1 << k))
+ _outputSurface->setPixel(x, y, 0x0F);
+ else
+ _outputSurface->setPixel(x, y, 0x00);
+ }
+ }
+ }
+ }
+ }
+}
+
void PICTDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel) {
uint32 dataDecoded = 0;
byte bytesPerDecode = (bytesPerPixel == 2) ? 2 : 1;
diff --git a/image/pict.h b/image/pict.h
index bb0c1c4405e..0a38a96bc94 100644
--- a/image/pict.h
+++ b/image/pict.h
@@ -95,6 +95,7 @@ private:
int _version;
// Utility Functions
+ void unpackBitsRgn(Common::SeekableReadStream &stream, bool compressed);
void unpackBitsRect(Common::SeekableReadStream &stream, bool withPalette);
void unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *stream, byte bitsPerPixel, byte bytesPerPixel);
void skipBitsRect(Common::SeekableReadStream &stream, bool withPalette);
@@ -123,6 +124,9 @@ private:
DECLARE_OPCODE(o_txRatio);
DECLARE_OPCODE(o_versionOp);
DECLARE_OPCODE(o_longText);
+ DECLARE_OPCODE(o_bitsRgn);
+ DECLARE_OPCODE(o_packBitsRgn);
+ DECLARE_OPCODE(o_shortComment);
DECLARE_OPCODE(o_longComment);
DECLARE_OPCODE(o_opEndPic);
DECLARE_OPCODE(o_headerOp);
Commit: 0aedc770e43b25e8c1487552e66d1f2687ddc4d3
https://github.com/scummvm/scummvm/commit/0aedc770e43b25e8c1487552e66d1f2687ddc4d3
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-12-26T17:52:52+01:00
Commit Message:
SCUMM: Remove custom PICTv1 decoder in favor of general one
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 0ecc514fcd9..9281283237f 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -469,194 +469,66 @@ Graphics::Surface *MacGuiImpl::loadPict(int id) {
Common::SeekableReadStream *res = resource.getResource(MKTAG('P', 'I', 'C', 'T'), id);
// IQ logos are PICT v2
- if (id == 4000 || id == 4001) {
- Image::PICTDecoder pict;
- if (pict.loadStream(*res)) {
- const Graphics::Surface *s1 = pict.getSurface();
- const byte *palette = pict.getPalette();
-
- s = new Graphics::Surface();
- s->create(s1->w, s1->h, Graphics::PixelFormat::createFormatCLUT8());
-
- // The palette doesn't match the game's palette at all, so remap
- // the colors to the custom area of the palette. It's assumed that
- // only one such picture will be loaded at a time.
- //
- // But we still match black and white to 0 and 15 to make sure they
- // mach exactly.
-
- int black = -1;
- int white = -1;
-
- for (int i = 0; i < pict.getPaletteColorCount(); i++) {
- int r = palette[3 * i];
- int g = palette[3 * i + 1];
- int b = palette[3 * i + 2];
-
- if (r == 0 && g == 0 && b == 0)
- black = i;
- else if (r == 255 && g == 255 && b == 255)
- white = i;
- }
-
- if (palette) {
- _system->getPaletteManager()->setPalette(palette, kCustomColor, pict.getPaletteColorCount());
-
- for (int y = 0; y < s->h; y++) {
- for (int x = 0; x < s->w; x++) {
- int color = s1->getPixel(x, y);
+ Image::PICTDecoder pict;
+ if (pict.loadStream(*res)) {
+ warning("DECODED");
+ const Graphics::Surface *s1 = pict.getSurface();
+ const byte *palette = pict.getPalette();
+
+ s = new Graphics::Surface();
+ s->create(s1->w, s1->h, Graphics::PixelFormat::createFormatCLUT8());
+
+ // The palette doesn't match the game's palette at all, so remap
+ // the colors to the custom area of the palette. It's assumed that
+ // only one such picture will be loaded at a time.
+ //
+ // But we still match black and white to 0 and 15 to make sure they
+ // mach exactly.
- if (color == black)
- color = kBlack;
- else if (color == white)
- color = kWhite;
- else
- color = kCustomColor + color;
+ int black = -1;
+ int white = -1;
- s->setPixel(x, y, color);
- }
- }
- } else
- s->copyFrom(*s1);
+ for (int i = 0; i < pict.getPaletteColorCount(); i++) {
+ int r = palette[3 * i];
+ int g = palette[3 * i + 1];
+ int b = palette[3 * i + 2];
+ if (r == 0 && g == 0 && b == 0)
+ black = i;
+ else if (r == 255 && g == 255 && b == 255)
+ white = i;
}
- } else {
- s = decodePictV1(res);
- }
-
- delete res;
- resource.close();
-
- return s;
-}
-
-Graphics::Surface *MacGuiImpl::decodePictV1(Common::SeekableReadStream *res) {
- uint16 size = res->readUint16BE();
-
- uint16 top = res->readUint16BE();
- uint16 left = res->readUint16BE();
- uint16 bottom = res->readUint16BE();
- uint16 right = res->readUint16BE();
-
- int width = right - left;
- int height = bottom - top;
-
- Graphics::Surface *s = new Graphics::Surface();
- s->create(right - left, bottom - top, Graphics::PixelFormat::createFormatCLUT8());
- bool endOfPicture = false;
+ if (!pict.getPaletteColorCount()) {
+ black = 0xff;
+ white = 0x00;
+ }
- while (!endOfPicture) {
- byte opcode = res->readByte();
- byte value;
- int x1, x2, y1, y2;
+ if (palette) {
+ _system->getPaletteManager()->setPalette(palette, kCustomColor, pict.getPaletteColorCount());
- int x = 0;
- int y = 0;
- bool compressed = false;
+ for (int y = 0; y < s->h; y++) {
+ for (int x = 0; x < s->w; x++) {
+ int color = s1->getPixel(x, y);
- switch (opcode) {
- case 0x01: // clipRgn
- // The clip region is not important
- res->skip(res->readUint16BE() - 2);
- break;
+ if (color == black)
+ color = kBlack;
+ else if (color == white)
+ color = kWhite;
+ else
+ color = kCustomColor + color;
- case 0x11: // picVersion
- value = res->readByte();
- assert(value == 1);
- break;
-
- case 0x99: // PackBitsRgn
- compressed = true;
- // Fall through
-
- case 0x91: // BitsRgn
- res->skip(2); // Skip rowBytes
-
- y1 = res->readSint16BE();
- x1 = res->readSint16BE();
- y2 = res->readSint16BE();
- x2 = res->readSint16BE();
-
- res->skip(8); // Skip srcRect
- res->skip(8); // Skip dstRect
- res->skip(2); // Skip mode
- res->skip(res->readUint16BE() - 2); // Skip maskRgn
-
- if (!compressed) {
- for (y = y1; y < y2 && y < height; y++) {
- byte b = res->readByte();
- byte bit = 0x80;
-
- for (x = x1; x < x2 && x < width; x++) {
- if (b & bit)
- s->setPixel(x, y, kBlack);
- else
- s->setPixel(x, y, kWhite);
-
- bit >>= 1;
-
- if (bit == 0) {
- b = res->readByte();
- bit = 0x80;
- }
- }
- }
- } else {
- for (y = y1; y < y2 && y < height; y++) {
- x = x1;
- size = res->readByte();
-
- while (size > 0) {
- byte count = res->readByte();
- size--;
-
- bool repeat;
-
- if (count >= 128) {
- // Repeat value
- count = 256 - count;
- repeat = true;
- value = res->readByte();
- size--;
- } else {
- // Copy values
- repeat = false;
- value = 0;
- }
-
- for (int j = 0; j <= count; j++) {
- if (!repeat) {
- value = res->readByte();
- size--;
- }
- for (int k = 7; k >= 0 && x < x2 && x < width; k--, x++) {
- if (value & (1 << k))
- s->setPixel(x, y, kBlack);
- else
- s->setPixel(x, y, kWhite);
- }
- }
- }
+ s->setPixel(x, y, color);
}
}
+ } else
+ s->copyFrom(*s1);
- break;
-
- case 0xA0: // shortComment
- res->skip(2);
- break;
-
- case 0xFF: // EndOfPicture
- endOfPicture = true;
- break;
-
- default:
- warning("decodePictV1: Unknown opcode: 0x%02x", opcode);
- break;
- }
}
+ delete res;
+ resource.close();
+
return s;
}
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 8b2a1f739a1..6c9a4c8201b 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -612,7 +612,6 @@ public:
virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
Graphics::Surface *loadPict(int id);
- Graphics::Surface *decodePictV1(Common::SeekableReadStream *res);
virtual bool isVerbGuiActive() const { return false; }
virtual void reset() {}
More information about the Scummvm-git-logs
mailing list