aboutsummaryrefslogtreecommitdiff
path: root/graphics/png.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/png.cpp')
-rw-r--r--graphics/png.cpp91
1 files changed, 42 insertions, 49 deletions
diff --git a/graphics/png.cpp b/graphics/png.cpp
index e6dceab3fa..6ffc53bd92 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) {
}
@@ -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 {
@@ -202,7 +195,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;
}
}
@@ -236,7 +229,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 +237,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);
@@ -282,7 +275,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 +299,7 @@ byte PNG::paethPredictor(int16 a, int16 b, int16 c) {
int16 pa = ABS<int16>(b - c);
int16 pb = ABS<int16>(a - c);
int16 pc = ABS<int16>(a + b - c - c);
-
+
if (pa <= MIN<int16>(pb, pc))
return (byte)a;
else if (pb <= pc)