[Scummvm-git-logs] scummvm master -> afd7a04d1e0cdf43316fab429d4e501dbda82564

aquadran noreply at scummvm.org
Sat Dec 18 21:42:39 UTC 2021


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
afd7a04d1e ICB: Replaced with modified NanoJpeg decoder


Commit: afd7a04d1e0cdf43316fab429d4e501dbda82564
    https://github.com/scummvm/scummvm/commit/afd7a04d1e0cdf43316fab429d4e501dbda82564
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2021-12-18T22:42:32+01:00

Commit Message:
ICB: Replaced with modified NanoJpeg decoder

Changed paths:
  A engines/icb/jpeg_decode.cpp
  A engines/icb/jpeg_decode.h
    engines/icb/module.mk
    engines/icb/set_pc.cpp


diff --git a/engines/icb/jpeg_decode.cpp b/engines/icb/jpeg_decode.cpp
new file mode 100644
index 0000000000..41d79a78a5
--- /dev/null
+++ b/engines/icb/jpeg_decode.cpp
@@ -0,0 +1,570 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+// NanoJPEG -- KeyJ's Tiny Baseline JPEG Decoder
+// version 1.3.5 (2016-11-14)
+// Copyright (c) 2009-2016 Martin J. Fiedler <martin.fiedler at gmx.net>
+// published under the terms of the MIT license
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include "common/scummsys.h"
+
+#include "engines/icb/jpeg_decode.h"
+
+namespace ICB {
+
+typedef enum _nj_result {
+	NJ_OK = 0,        // no error, decoding successful
+	NJ_NO_JPEG,       // not a JPEG file
+	NJ_UNSUPPORTED,   // unsupported format
+	NJ_OUT_OF_MEM,    // out of memory
+	NJ_INTERNAL_ERR,  // internal error
+	NJ_SYNTAX_ERROR,  // syntax error
+	NJ_FINISHED,      // used internally
+} nj_result_t;
+
+typedef struct _nj_code {
+	byte bits, code;
+} nj_vlc_code_t;
+
+typedef struct _nj_cmp {
+	int cid;
+	int ssx, ssy;
+	int width, height;
+	int stride;
+	int qtsel;
+	int actabsel, dctabsel;
+	int dcpred;
+	byte *pixels;
+} nj_component_t;
+
+typedef struct _nj_ctx {
+	nj_result_t error;
+	const byte *pos;
+	int size;
+	int length;
+	int width, height;
+	int mbwidth, mbheight;
+	int mbsizex, mbsizey;
+	int ncomp;
+	nj_component_t comp[3];
+	int curcomp;
+	int qtused, qtavail;
+	byte qtab[4][64];
+	nj_vlc_code_t vlctab[4][65536];
+	int buf, bufbits;
+	int block[64];
+} nj_context_t;
+
+static nj_context_t nj;
+
+static const char njZZ[64] = {
+	0,   1,  8, 16,  9,  2,  3, 10,
+	17, 24, 32, 25, 18, 11,  4,  5,
+	12, 19, 26, 33, 40, 48, 41, 34,
+	27, 20, 13,  6,  7, 14, 21, 28,
+	35, 42, 49, 56, 57, 50, 43, 36,
+	29, 22, 15, 23, 30, 37, 44, 51,
+	58, 59, 52, 45, 38, 31, 39, 46,
+	53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static FORCEINLINE byte njClip(const int x) {
+	return (x < 0) ? 0 : ((x > 0xFF) ? 0xFF : (byte)x);
+}
+
+#define W1 2841
+#define W2 2676
+#define W3 2408
+#define W5 1609
+#define W6 1108
+#define W7 565
+
+static FORCEINLINE void njRowIDCT(int *blk) {
+	int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+	if (!((x1 = blk[4] << 11) |
+	      (x2 = blk[6]) |
+	      (x3 = blk[2]) |
+	      (x4 = blk[1]) |
+	      (x5 = blk[7]) |
+	      (x6 = blk[5]) |
+	      (x7 = blk[3]))) {
+		blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = blk[0] << 3;
+		return;
+	}
+	x0 = (blk[0] << 11) + 128;
+	x8 = W7 * (x4 + x5);
+	x4 = x8 + (W1 - W7) * x4;
+	x5 = x8 - (W1 + W7) * x5;
+	x8 = W3 * (x6 + x7);
+	x6 = x8 - (W3 - W5) * x6;
+	x7 = x8 - (W3 + W5) * x7;
+	x8 = x0 + x1;
+	x0 -= x1;
+	x1 = W6 * (x3 + x2);
+	x2 = x1 - (W2 + W6) * x2;
+	x3 = x1 + (W2 - W6) * x3;
+	x1 = x4 + x6;
+	x4 -= x6;
+	x6 = x5 + x7;
+	x5 -= x7;
+	x7 = x8 + x3;
+	x8 -= x3;
+	x3 = x0 + x2;
+	x0 -= x2;
+	x2 = (181 * (x4 + x5) + 128) >> 8;
+	x4 = (181 * (x4 - x5) + 128) >> 8;
+	blk[0] = (x7 + x1) >> 8;
+	blk[1] = (x3 + x2) >> 8;
+	blk[2] = (x0 + x4) >> 8;
+	blk[3] = (x8 + x6) >> 8;
+	blk[4] = (x8 - x6) >> 8;
+	blk[5] = (x0 - x4) >> 8;
+	blk[6] = (x3 - x2) >> 8;
+	blk[7] = (x7 - x1) >> 8;
+}
+
+static FORCEINLINE void njColIDCT(const int *blk, byte *out, int stride) {
+	int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+	if (!((x1 = blk[8 * 4] << 8) |
+	      (x2 = blk[8 * 6]) |
+	      (x3 = blk[8 * 2]) |
+	      (x4 = blk[8 * 1]) |
+	      (x5 = blk[8 * 7]) |
+	      (x6 = blk[8 * 5]) |
+	      (x7 = blk[8 * 3]))) {
+		x1 = njClip(((blk[0] + 32) >> 6) + 128);
+		for (x0 = 8; x0; --x0) {
+			*out = (byte)x1;
+			out += stride;
+		}
+		return;
+	}
+	x0 = (blk[0] << 8) + 8192;
+	x8 = W7 * (x4 + x5) + 4;
+	x4 = (x8 + (W1 - W7) * x4) >> 3;
+	x5 = (x8 - (W1 + W7) * x5) >> 3;
+	x8 = W3 * (x6 + x7) + 4;
+	x6 = (x8 - (W3 - W5) * x6) >> 3;
+	x7 = (x8 - (W3 + W5) * x7) >> 3;
+	x8 = x0 + x1;
+	x0 -= x1;
+	x1 = W6 * (x3 + x2) + 4;
+	x2 = (x1 - (W2 + W6) * x2) >> 3;
+	x3 = (x1 + (W2 - W6) * x3) >> 3;
+	x1 = x4 + x6;
+	x4 -= x6;
+	x6 = x5 + x7;
+	x5 -= x7;
+	x7 = x8 + x3;
+	x8 -= x3;
+	x3 = x0 + x2;
+	x0 -= x2;
+	x2 = (181 * (x4 + x5) + 128) >> 8;
+	x4 = (181 * (x4 - x5) + 128) >> 8;
+	*out = njClip(((x7 + x1) >> 14) + 128); out += stride;
+	*out = njClip(((x3 + x2) >> 14) + 128); out += stride;
+	*out = njClip(((x0 + x4) >> 14) + 128); out += stride;
+	*out = njClip(((x8 + x6) >> 14) + 128); out += stride;
+	*out = njClip(((x8 - x6) >> 14) + 128); out += stride;
+	*out = njClip(((x0 - x4) >> 14) + 128); out += stride;
+	*out = njClip(((x3 - x2) >> 14) + 128); out += stride;
+	*out = njClip(((x7 - x1) >> 14) + 128);
+}
+
+#define njThrow(e) do { nj.error = e; return; } while (0)
+#define njCheckError() do { if (nj.error) return; } while (0)
+
+static int njShowBits(int bits) {
+	if (!bits)
+		return 0;
+
+	while (nj.bufbits < bits) {
+		if (nj.size <= 0) {
+			nj.buf = (nj.buf << 8) | 0xFF;
+			nj.bufbits += 8;
+			continue;
+		}
+		byte newbyte = *nj.pos++;
+		nj.size--;
+		nj.bufbits += 8;
+		nj.buf = (nj.buf << 8) | newbyte;
+	}
+
+	return (nj.buf >> (nj.bufbits - bits)) & ((1 << bits) - 1);
+}
+
+static void njResetBufBits() {
+	while ((nj.bufbits -= 8) > 0) {
+		nj.pos--;
+		nj.size++;
+	}
+	nj.buf = 0;
+	nj.bufbits = 0;
+}
+
+static FORCEINLINE void njSkipBits(int bits) {
+	if (nj.bufbits < bits)
+		njShowBits(bits);
+	nj.bufbits -= bits;
+}
+
+static FORCEINLINE int njGetBits(int bits) {
+	int res = njShowBits(bits);
+	njSkipBits(bits);
+	return res;
+}
+
+static void njSkip(int count) {
+	nj.pos += count;
+	nj.size -= count;
+	nj.length -= count;
+	if (nj.size < 0)
+		nj.error = NJ_SYNTAX_ERROR;
+}
+
+static FORCEINLINE uint16 njDecode16(const byte *pos) {
+	return (pos[1] << 8) | pos[0];
+}
+
+static void njDecodeLength() {
+	if (nj.size < 2)
+		njThrow(NJ_SYNTAX_ERROR);
+	nj.length = njDecode16(nj.pos);
+	if (nj.length > nj.size)
+		njThrow(NJ_SYNTAX_ERROR);
+	njSkip(2);
+}
+
+static void njDecodeSOF() {
+	int i, ssxmax = 0, ssymax = 0;
+	nj_component_t *c;
+
+	njDecodeLength();
+	njCheckError();
+	if (nj.length < 9)
+		njThrow(NJ_SYNTAX_ERROR);
+	if (nj.pos[0] != 8)
+		njThrow(NJ_UNSUPPORTED);
+
+	nj.height = 480;
+	nj.width = 640;
+	nj.ncomp = nj.pos[1];
+	njSkip(2);
+
+	switch (nj.ncomp) {
+	case 3:
+		break;
+	default:
+		njThrow(NJ_UNSUPPORTED);
+	}
+
+	if (nj.length < (nj.ncomp * 3))
+		njThrow(NJ_SYNTAX_ERROR);
+	for (i = 0, c = nj.comp; i < nj.ncomp; ++i, ++c) {
+		c->cid = nj.pos[0];
+	if (!(c->ssx = nj.pos[1] >> 4))
+		njThrow(NJ_SYNTAX_ERROR);
+	if (c->ssx & (c->ssx - 1))
+		njThrow(NJ_UNSUPPORTED);  // non-power of two
+	if (!(c->ssy = nj.pos[1] & 15))
+		njThrow(NJ_SYNTAX_ERROR);
+	if (c->ssy & (c->ssy - 1))
+		njThrow(NJ_UNSUPPORTED);  // non-power of two
+	if (c->ssx != 1 || c->ssy != 1)
+		njThrow(NJ_SYNTAX_ERROR);
+	if ((c->qtsel = nj.pos[2]) & 0xFC)
+		njThrow(NJ_SYNTAX_ERROR);
+	njSkip(3);
+	nj.qtused |= 1 << c->qtsel;
+	if (c->ssx > ssxmax)
+		ssxmax = c->ssx;
+	if (c->ssy > ssymax)
+		ssymax = c->ssy;
+	}
+	if (nj.ncomp == 1) {
+		c = nj.comp;
+		c->ssx = c->ssy = ssxmax = ssymax = 1;
+	}
+	nj.mbsizex = ssxmax << 3;
+	nj.mbsizey = ssymax << 3;
+	nj.mbwidth = (nj.width + nj.mbsizex - 1) / nj.mbsizex;
+	nj.mbheight = (nj.height + nj.mbsizey - 1) / nj.mbsizey;
+	for (i = 0, c = nj.comp; i < nj.ncomp;  ++i, ++c) {
+		c->width = (nj.width * c->ssx + ssxmax - 1) / ssxmax;
+		c->height = (nj.height * c->ssy + ssymax - 1) / ssymax;
+		c->stride = nj.mbwidth * c->ssx << 3;
+		if (((c->width < 3) && (c->ssx != ssxmax)) || ((c->height < 3) && (c->ssy != ssymax)))
+			njThrow(NJ_UNSUPPORTED);
+		if (!(c->pixels = (byte *)malloc(c->stride * nj.mbheight * c->ssy << 3)))
+			njThrow(NJ_OUT_OF_MEM);
+	}
+	njSkip(nj.length - 4);
+}
+
+static void njDecodeDHT() {
+	njDecodeLength();
+	njCheckError();
+
+	while (nj.length >= 17) {
+		byte counts[16];
+		int codelen;
+		int i = nj.pos[0];
+		if (i & 0xEC)
+			njThrow(NJ_SYNTAX_ERROR);
+		if (i & 0x02)
+			njThrow(NJ_UNSUPPORTED);
+		i = (i | (i >> 3)) & 3;  // combined DC/AC + tableid value
+		for (codelen = 1; codelen <= 16; ++codelen)
+			counts[codelen - 1] = nj.pos[codelen];
+		njSkip(17);
+		nj_vlc_code_t *vlc = &nj.vlctab[i][0];
+		int remain = 65536;
+		int spread = remain;
+		for (codelen = 1; codelen <= 16; ++codelen) {
+			spread >>= 1;
+			int currcnt = counts[codelen - 1];
+			if (!currcnt)
+				continue;
+			if (nj.length < currcnt)
+				njThrow(NJ_SYNTAX_ERROR);
+			remain -= currcnt << (16 - codelen);
+			if (remain < 0)
+				njThrow(NJ_SYNTAX_ERROR);
+			for (i = 0; i < currcnt; ++i) {
+				byte code = nj.pos[i];
+				for (int j = spread; j; --j) {
+					vlc->bits = (byte)codelen;
+					vlc->code = code;
+					++vlc;
+				}
+			}
+			njSkip(currcnt);
+		}
+		while (remain--) {
+			vlc->bits = 0;
+			++vlc;
+		}
+	}
+	if (nj.length)
+		njThrow(NJ_SYNTAX_ERROR);
+}
+
+static void njDecodeDQT() {
+	njDecodeLength();
+	njCheckError();
+
+	while (nj.length >= 65) {
+		int i = nj.pos[0];
+		if (i & 0xFC)
+			njThrow(NJ_SYNTAX_ERROR);
+		nj.qtavail |= 1 << i;
+		byte *t = &nj.qtab[i][0];
+		for (i = 0; i < 64; ++i)
+			t[i] = nj.pos[i + 1];
+		njSkip(65);
+	}
+	if (nj.length)
+		njThrow(NJ_SYNTAX_ERROR);
+}
+
+static int njGetVLC(nj_vlc_code_t *vlc, byte *code) {
+	int value = njShowBits(16);
+	int bits = vlc[value].bits;
+	if (!bits) {
+		nj.error = NJ_SYNTAX_ERROR;
+		return 0;
+	}
+	njSkipBits(bits);
+	value = vlc[value].code;
+	if (code)
+		*code = (byte)value;
+	bits = value & 15;
+	if (!bits)
+		return 0;
+	value = njGetBits(bits);
+	if (value < (1 << (bits - 1)))
+		value += ((-1) << bits) + 1;
+	return value;
+}
+
+static void njDecodeBlock(nj_component_t *c, byte *out) {
+	byte code = 0;
+	int value, coef = 0;
+
+	memset(nj.block, 0, sizeof(nj.block));
+	c->dcpred += njGetVLC(&nj.vlctab[c->dctabsel][0], nullptr);
+	nj.block[0] = (c->dcpred) * nj.qtab[c->qtsel][0];
+	do {
+		value = njGetVLC(&nj.vlctab[c->actabsel][0], &code);
+		if (!code)
+			break;  // EOB
+		if (!(code & 0x0F) && (code != 0xF0))
+			njThrow(NJ_SYNTAX_ERROR);
+		coef += (code >> 4) + 1;
+		if (coef > 63)
+			njThrow(NJ_SYNTAX_ERROR);
+		nj.block[njZZ[coef]] = value * nj.qtab[c->qtsel][coef];
+	} while (coef < 63);
+	for (coef = 0;  coef < 64;  coef += 8)
+		njRowIDCT(&nj.block[coef]);
+	for (coef = 0;  coef < 8;  ++coef)
+		njColIDCT(&nj.block[coef], &out[coef], c->stride);
+}
+
+static void njDecodeScan() {
+	nj_component_t *c = &nj.comp[nj.curcomp];
+
+	njDecodeLength();
+	njCheckError();
+	if (nj.pos[0] != 1)
+		njThrow(NJ_UNSUPPORTED);
+	if (nj.length < (4 + 2))
+		njThrow(NJ_SYNTAX_ERROR);
+	njSkip(1);
+
+	if (nj.pos[0] != c->cid)
+		njThrow(NJ_SYNTAX_ERROR);
+	if (nj.pos[1] & 0xEE)
+		njThrow(NJ_SYNTAX_ERROR);
+	c->dctabsel = nj.pos[1] >> 4;
+	c->actabsel = (nj.pos[1] & 1) | 2;
+	njSkip(2);
+
+	if (nj.pos[0] || (nj.pos[1] != 63) || nj.pos[2])
+		njThrow(NJ_UNSUPPORTED);
+	njSkip(nj.length);
+
+	for (int mby = 0; mby < nj.mbheight; mby++) {
+		for (int mbx = 0; mbx < nj.mbwidth; mbx++) {
+			njDecodeBlock(c, &c->pixels[(mby * c->stride + mbx) << 3]);
+			if (nj.error)
+				return;
+		}
+	}
+	njResetBufBits();
+	c->dcpred = 0;
+	nj.curcomp++;
+	nj.error = NJ_OK;
+}
+
+static nj_result_t njDecode(const byte *jpeg, const int size) {
+	memset(&nj, 0, sizeof(nj_context_t));
+	nj.pos = jpeg;
+	nj.size = size & 0x7FFFFFFF;
+	if (nj.size < 2)
+		return NJ_NO_JPEG;
+	if ((nj.pos[0] ^ 0xFF) | (nj.pos[1] ^ 0xD8))
+		return NJ_NO_JPEG;
+	njSkip(2);
+
+	while (!nj.error) {
+		if ((nj.size < 2) || (nj.pos[0] != 0xFF))
+			return NJ_SYNTAX_ERROR;
+		njSkip(2);
+		switch (nj.pos[-1]) {
+		case 0xC0:
+			njDecodeSOF();
+			break;
+		case 0xC4:
+			njDecodeDHT();
+			break;
+		case 0xDB:
+			njDecodeDQT();
+			break;
+		case 0xD9:
+			nj.error = NJ_FINISHED;
+			break;
+		case 0xDA:
+			njDecodeScan();
+			break;
+		default:
+			nj.error = NJ_UNSUPPORTED;
+			break;
+		}
+	}
+	if (nj.error != NJ_FINISHED)
+		return nj.error;
+	nj.error = NJ_OK;
+
+	return nj.error;
+}
+
+static void njDone() {
+	for (int i = 0; i < 3; ++i) {
+		if (nj.comp[i].pixels)
+			free(nj.comp[i].pixels);
+	}
+}
+
+static void njConvert(byte *dst) {
+	const byte *py  = nj.comp[0].pixels;
+	const byte *pcb = nj.comp[1].pixels;
+	const byte *pcr = nj.comp[2].pixels;
+	for (int yy = nj.height; yy; --yy) {
+		for (int x = 0; x < nj.width; ++x) {
+			int y = py[x] << 8;
+			int cb = pcb[x] - 128;
+			int cr = pcr[x] - 128;
+			*dst++ = njClip((y + 454 * cb            + 128) >> 8);
+			*dst++ = njClip((y -  88 * cb - 183 * cr + 128) >> 8);
+			*dst++ = njClip((y            + 359 * cr + 128) >> 8);
+			*dst++ = 255;
+		}
+		py += nj.comp[0].stride;
+		pcb += nj.comp[1].stride;
+		pcr += nj.comp[2].stride;
+	}
+}
+
+Graphics::Surface *JpegDecode(const byte *data, const int size) {
+	Graphics::Surface *surface = nullptr;
+	if (njDecode(data, size) == NJ_OK) {
+		surface = new Graphics::Surface();
+		surface->create(nj.width, nj.height, Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
+		njConvert((byte *)surface->getPixels());
+	}
+	njDone();
+
+	return surface;
+}
+
+} // End of namespace ICB
diff --git a/engines/icb/jpeg_decode.h b/engines/icb/jpeg_decode.h
new file mode 100644
index 0000000000..36790f8fca
--- /dev/null
+++ b/engines/icb/jpeg_decode.h
@@ -0,0 +1,34 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ICB_JPEG_DECODE_H
+#define ICB_JPEG_DECODE_H
+
+#include "graphics/surface.h"
+
+namespace ICB {
+
+Graphics::Surface *JpegDecode(const byte *data, const int size);
+
+} // End of namespace ICB
+
+#endif // ICB_JPEG_DECODE_H
diff --git a/engines/icb/module.mk b/engines/icb/module.mk
index 7a34a53e03..a865eebcc7 100644
--- a/engines/icb/module.mk
+++ b/engines/icb/module.mk
@@ -54,6 +54,7 @@ MODULE_OBJS := \
 	icon_list_manager.o \
 	icon_menu.o \
 	icon_menu_pc.o \
+	jpeg_decode.o \
 	keyboard.o \
 	light_pc.o \
 	line_of_sight.o \
diff --git a/engines/icb/set_pc.cpp b/engines/icb/set_pc.cpp
index 7292f7d283..7f265149a7 100644
--- a/engines/icb/set_pc.cpp
+++ b/engines/icb/set_pc.cpp
@@ -28,8 +28,6 @@
 #include "common/memstream.h"
 #include "common/random.h"
 
-#include "image/jpeg.h"
-
 #include "engines/icb/p4_generic.h"
 #include "engines/icb/set.h"
 #include "engines/icb/global_objects.h"
@@ -43,6 +41,7 @@
 #include "engines/icb/sound/direct_sound.h"
 #include "engines/icb/sound/fx_manager.h"
 #include "engines/icb/icb.h"
+#include "engines/icb/jpeg_decode.h"
 #include "engines/icb/direct_input.h"
 
 namespace ICB {
@@ -705,14 +704,11 @@ void _set::Init_base_bitmap_buffers() {
 	uint8 *ptr = bgPtr + shadowTable[0];
 
 	// Decode the jpeg background
-	Image::JPEGDecoder decoder;
-	decoder.setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
-	Common::SeekableReadStream *jpegStream = dynamic_cast<Common::SeekableReadStream *>(new Common::MemoryReadStream(ptr, 1024 * 1024, DisposeAfterUse::YES));
-	decoder.loadStream(*jpegStream);
-	const Graphics::Surface *jpegSurf = decoder.getSurface();
+	Graphics::Surface *jpegSurf = JpegDecode(ptr, 1024 * 1024);
+	assert(jpegSurf);
+	uint8 *surface_address = surface_manager->Lock_surface(bg_buffer_id);
 	int16 pitch = surface_manager->Get_pitch(bg_buffer_id);
 	uint32 height = surface_manager->Get_height(bg_buffer_id);
-	uint8 *surface_address = surface_manager->Lock_surface(bg_buffer_id);
 	for (int32 i = 0; i < jpegSurf->h; i++) {
 		if (i >= (int32)height) {
 			break;
@@ -720,7 +716,8 @@ void _set::Init_base_bitmap_buffers() {
 		memcpy(surface_address + i * pitch, jpegSurf->getBasePtr(0, i), MIN(jpegSurf->pitch, pitch));
 	}
 	surface_manager->Unlock_surface(bg_buffer_id);
-	delete jpegStream;
+	jpegSurf->free();
+	delete jpegSurf;
 
 	// find the start of the weather data
 	int32 *weatherPtr = (int32 *)(bgPtr + shadowTable[1]);




More information about the Scummvm-git-logs mailing list