diff options
Diffstat (limited to 'graphics/png.cpp')
| -rw-r--r-- | graphics/png.cpp | 91 | 
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)  | 
