From 7d7696272177c9d6b2840d5acfee68c4204b9fb5 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Thu, 16 Jun 2011 23:33:26 +0300 Subject: GRAPHICS: Fix decoding of 4bpp PNGs Fixes checkbox in options menu in Sword25. --- graphics/png.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'graphics/png.cpp') diff --git a/graphics/png.cpp b/graphics/png.cpp index e6dceab3fa..c250433222 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -202,7 +202,7 @@ Graphics::Surface *PNG::getSurface(const PixelFormat &format) { } // The surface is a whole scanline wide, skip the rest of it. if (_header.bitDepth == 4) - src += output->w / 2; + src += output->w / 2 + output->w % 2; } } -- cgit v1.2.3 From abf26b0614581f2725f65621d0403255884a9cc2 Mon Sep 17 00:00:00 2001 From: eriktorbjorn Date: Fri, 17 Jun 2011 05:56:23 +0200 Subject: GRAPHICS: Fix Valgrind warning The stream class uses free() to automatically dispose of the buffer so it must be allocated with malloc(), not "new". --- graphics/png.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'graphics/png.cpp') diff --git a/graphics/png.cpp b/graphics/png.cpp index c250433222..a1cf266227 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -236,7 +236,7 @@ bool PNG::read(Common::SeekableReadStream *str) { case kChunkIDAT: if (_compressedBufferSize == 0) { _compressedBufferSize += chunkLength; - _compressedBuffer = new byte[_compressedBufferSize]; + _compressedBuffer = (byte *)malloc(_compressedBufferSize); _stream->read(_compressedBuffer, chunkLength); } else { // Expand the buffer @@ -244,8 +244,8 @@ bool PNG::read(Common::SeekableReadStream *str) { _compressedBufferSize += chunkLength; byte *tmp = new byte[prevSize]; memcpy(tmp, _compressedBuffer, prevSize); - delete[] _compressedBuffer; - _compressedBuffer = new byte[_compressedBufferSize]; + free(_compressedBuffer); + _compressedBuffer = (byte *)malloc(_compressedBufferSize); memcpy(_compressedBuffer, tmp, prevSize); delete[] tmp; _stream->read(_compressedBuffer + prevSize, chunkLength); -- cgit v1.2.3 From 88913c0139ac6d1dfb356d3048702b7bc8ef4079 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 20 Jun 2011 00:59:48 +0200 Subject: ALL: Remove trailing whitespaces This tries to make our code a bit more compliant with our code formatting conventions. For future use, this is the command I used: git ls-files "*.cpp" "*.h" | xargs sed -i -e 's/[ \t]*$//' --- graphics/png.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'graphics/png.cpp') diff --git a/graphics/png.cpp b/graphics/png.cpp index a1cf266227..6eff4b1e47 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -100,7 +100,7 @@ enum PNGFilters { kFilterPaeth = 4 }; -PNG::PNG() : _compressedBuffer(0), _compressedBufferSize(0), +PNG::PNG() : _compressedBuffer(0), _compressedBufferSize(0), _unfilteredSurface(0), _transparentColorSpecified(false) { } @@ -282,7 +282,7 @@ bool PNG::read(Common::SeekableReadStream *str) { // Unpack the compressed buffer Common::MemoryReadStream *compData = new Common::MemoryReadStream(_compressedBuffer, _compressedBufferSize, DisposeAfterUse::YES); _imageData = Common::wrapCompressedReadStream(compData); - + // Construct the final image constructImage(); @@ -306,7 +306,7 @@ byte PNG::paethPredictor(int16 a, int16 b, int16 c) { int16 pa = ABS(b - c); int16 pb = ABS(a - c); int16 pc = ABS(a + b - c - c); - + if (pa <= MIN(pb, pc)) return (byte)a; else if (pb <= pc) -- cgit v1.2.3 From 784180ef68a6dca2734bc240991e464ae21f1de9 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 20 Jun 2011 21:32:19 +0300 Subject: GRAPHICS: Cleanup and simplification of some PNG decoder code --- graphics/png.cpp | 77 ++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 42 deletions(-) (limited to 'graphics/png.cpp') diff --git a/graphics/png.cpp b/graphics/png.cpp index 6eff4b1e47..6ffc53bd92 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -116,59 +116,52 @@ Graphics::Surface *PNG::getSurface(const PixelFormat &format) { output->create(_unfilteredSurface->w, _unfilteredSurface->h, format); byte *src = (byte *)_unfilteredSurface->pixels; byte a = 0xFF; + byte bpp = _unfilteredSurface->format.bytesPerPixel; if (_header.colorType != kIndexed) { - if (_header.colorType == kTrueColor || _header.colorType == kTrueColorWithAlpha) { - if (_unfilteredSurface->format.bytesPerPixel != 3 && _unfilteredSurface->format.bytesPerPixel != 4) + if (_header.colorType == kTrueColor || + _header.colorType == kTrueColorWithAlpha) { + if (bpp != 3 && bpp != 4) error("Unsupported truecolor PNG format"); - } else if (_header.colorType == kGrayScale || _header.colorType == kGrayScaleWithAlpha) { - if (_unfilteredSurface->format.bytesPerPixel != 1 && _unfilteredSurface->format.bytesPerPixel != 2) + } else if (_header.colorType == kGrayScale || + _header.colorType == kGrayScaleWithAlpha) { + if (bpp != 1 && bpp != 2) error("Unsupported grayscale PNG format"); } for (uint16 i = 0; i < output->h; i++) { for (uint16 j = 0; j < output->w; j++) { - if (format.bytesPerPixel == 2) { // 2bpp - uint16 *dest = ((uint16 *)output->getBasePtr(j, i)); - if (_unfilteredSurface->format.bytesPerPixel == 1) { // Grayscale - if (_transparentColorSpecified) - a = (src[0] == _transparentColor[0]) ? 0 : 0xFF; - *dest = format.ARGBToColor( a, src[0], src[0], src[0]); - } else if (_unfilteredSurface->format.bytesPerPixel == 2) { // Grayscale + alpha - *dest = format.ARGBToColor(src[1], src[0], src[0], src[0]); - } else if (_unfilteredSurface->format.bytesPerPixel == 3) { // RGB - if (_transparentColorSpecified) { - bool isTransparentColor = (src[0] == _transparentColor[0] && - src[1] == _transparentColor[1] && - src[2] == _transparentColor[2]); - a = isTransparentColor ? 0 : 0xFF; - } - *dest = format.ARGBToColor( a, src[0], src[1], src[2]); - } else if (_unfilteredSurface->format.bytesPerPixel == 4) { // RGBA - *dest = format.ARGBToColor(src[3], src[0], src[1], src[2]); - } - } else { // 4bpp - uint32 *dest = ((uint32 *)output->getBasePtr(j, i)); - if (_unfilteredSurface->format.bytesPerPixel == 1) { // Grayscale - if (_transparentColorSpecified) - a = (src[0] == _transparentColor[0]) ? 0 : 0xFF; - *dest = format.ARGBToColor( a, src[0], src[0], src[0]); - } else if (_unfilteredSurface->format.bytesPerPixel == 2) { // Grayscale + alpha - *dest = format.ARGBToColor(src[1], src[0], src[0], src[0]); - } else if (_unfilteredSurface->format.bytesPerPixel == 3) { // RGB - if (_transparentColorSpecified) { - bool isTransparentColor = (src[0] == _transparentColor[0] && - src[1] == _transparentColor[1] && - src[2] == _transparentColor[2]); - a = isTransparentColor ? 0 : 0xFF; - } - *dest = format.ARGBToColor( a, src[0], src[1], src[2]); - } else if (_unfilteredSurface->format.bytesPerPixel == 4) { // RGBA - *dest = format.ARGBToColor(src[3], src[0], src[1], src[2]); + uint32 result = 0; + + switch (bpp) { + case 1: // Grayscale + if (_transparentColorSpecified) + a = (src[0] == _transparentColor[0]) ? 0 : 0xFF; + result = format.ARGBToColor( a, src[0], src[0], src[0]); + break; + case 2: // Grayscale + alpha + result = format.ARGBToColor(src[1], src[0], src[0], src[0]); + break; + case 3: // RGB + if (_transparentColorSpecified) { + bool isTransparentColor = (src[0] == _transparentColor[0] && + src[1] == _transparentColor[1] && + src[2] == _transparentColor[2]); + a = isTransparentColor ? 0 : 0xFF; } + result = format.ARGBToColor( a, src[0], src[1], src[2]); + break; + case 4: // RGBA + result = format.ARGBToColor(src[3], src[0], src[1], src[2]); + break; } - src += _unfilteredSurface->format.bytesPerPixel; + if (format.bytesPerPixel == 2) // 2bpp + *((uint16 *)output->getBasePtr(j, i)) = (uint16)result; + else // 4bpp + *((uint32 *)output->getBasePtr(j, i)) = result; + + src += bpp; } } } else { -- cgit v1.2.3 From d2962531cbdfdfc3cdec7af2487add21a056295b Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 26 Jun 2011 21:17:28 +0300 Subject: GRAPHICS: Generalized arbitrary bit depth images processing in PNG decoder. This fixes 1bpp image rengering. --- graphics/png.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'graphics/png.cpp') diff --git a/graphics/png.cpp b/graphics/png.cpp index 6ffc53bd92..2189fd333f 100644 --- a/graphics/png.cpp +++ b/graphics/png.cpp @@ -166,18 +166,26 @@ Graphics::Surface *PNG::getSurface(const PixelFormat &format) { } } else { byte index, r, g, b; + uint32 mask = (0xff >> (8 - _header.bitDepth)) << (8 - _header.bitDepth); // Convert the indexed surface to the target pixel format for (uint16 i = 0; i < output->h; i++) { - bool otherPixel = false; + int data = 0; + int bitCount = 8; + byte *src1 = src; for (uint16 j = 0; j < output->w; j++) { - if (_header.bitDepth != 4) - index = *src; - else if (!otherPixel) - index = (*src) >> 4; - else - index = (*src) & 0xf; + if (bitCount == 8) { + data = *src; + src++; + } + + index = (data & mask) >> (8 - _header.bitDepth); + data = (data << _header.bitDepth) & 0xff; + bitCount -= _header.bitDepth; + + if (bitCount == 0) + bitCount = 8; r = _palette[index * 4 + 0]; g = _palette[index * 4 + 1]; @@ -188,14 +196,8 @@ Graphics::Surface *PNG::getSurface(const PixelFormat &format) { *((uint16 *)output->getBasePtr(j, i)) = format.ARGBToColor(a, r, g, b); else *((uint32 *)output->getBasePtr(j, i)) = format.ARGBToColor(a, r, g, b); - - if (_header.bitDepth != 4 || otherPixel) - src++; - otherPixel = !otherPixel; } - // The surface is a whole scanline wide, skip the rest of it. - if (_header.bitDepth == 4) - src += output->w / 2 + output->w % 2; + src = src1 + output->w; } } -- cgit v1.2.3