diff options
author | Strangerke | 2011-06-29 16:15:41 +0200 |
---|---|---|
committer | Strangerke | 2011-06-29 16:15:41 +0200 |
commit | b0c9c9122fc678074aba30068e5b36d347208e65 (patch) | |
tree | 79a99db08ec985f2e5f1e216823b1104d5b753fb /graphics/png.cpp | |
parent | f2f3124246a77036f843dee2d83ad28084234ebc (diff) | |
parent | c32a3ea0d30336771bab460ecccb58c4614e6294 (diff) | |
download | scummvm-rg350-b0c9c9122fc678074aba30068e5b36d347208e65.tar.gz scummvm-rg350-b0c9c9122fc678074aba30068e5b36d347208e65.tar.bz2 scummvm-rg350-b0c9c9122fc678074aba30068e5b36d347208e65.zip |
Merge branch 'master' of github.com:scummvm/scummvm into soltys_wip2
Diffstat (limited to 'graphics/png.cpp')
-rw-r--r-- | graphics/png.cpp | 119 |
1 files changed, 57 insertions, 62 deletions
diff --git a/graphics/png.cpp b/graphics/png.cpp index e6dceab3fa..2189fd333f 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,75 +116,76 @@ 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 { 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]; @@ -195,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; + src = src1 + output->w; } } @@ -236,7 +231,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 +239,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 +277,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 +301,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) |