diff options
Diffstat (limited to 'graphics')
61 files changed, 369 insertions, 3115 deletions
diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index 491a9d7f42..a9594f7dd2 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -620,7 +620,10 @@ applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle) { template<typename PixelType> inline void VectorRendererSpec<PixelType>:: blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { - if (sizeof(PixelType) == 4) { + if (alpha == 0xff) { + // fully opaque pixel, don't blend + *ptr = color | _alphaMask; + } else if (sizeof(PixelType) == 4) { const byte sR = (color & _redMask) >> _format.rShift; const byte sG = (color & _greenMask) >> _format.gShift; const byte sB = (color & _blueMask) >> _format.bShift; @@ -628,15 +631,17 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { byte dR = (*ptr & _redMask) >> _format.rShift; byte dG = (*ptr & _greenMask) >> _format.gShift; byte dB = (*ptr & _blueMask) >> _format.bShift; + byte dA = (*ptr & _alphaMask) >> _format.aShift; dR += ((sR - dR) * alpha) >> 8; dG += ((sG - dG) * alpha) >> 8; dB += ((sB - dB) * alpha) >> 8; + dA += ((0xff - dA) * alpha) >> 8; *ptr = ((dR << _format.rShift) & _redMask) | ((dG << _format.gShift) & _greenMask) | ((dB << _format.bShift) & _blueMask) - | (*ptr & _alphaMask); + | ((dA << _format.aShift) & _alphaMask); } else if (sizeof(PixelType) == 2) { int idst = *ptr; int isrc = color; @@ -651,7 +656,9 @@ blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha) { (_blueMask & ((idst & _blueMask) + ((int)(((int)(isrc & _blueMask) - (int)(idst & _blueMask)) * alpha) >> 8))) | - (idst & _alphaMask)); + (_alphaMask & ((idst & _alphaMask) + + ((int)(((int)(_alphaMask) - + (int)(idst & _alphaMask)) * alpha) >> 8)))); } else { error("Unsupported BPP format: %u", (uint)sizeof(PixelType)); } @@ -691,11 +698,10 @@ darkenFill(PixelType *ptr, PixelType *end) { // assuming at least 3 alpha bits mask |= 3 << _format.aShift; - PixelType addA = (PixelType)(255 >> _format.aLoss) << _format.aShift; - addA -= (addA >> 2); + PixelType addA = (PixelType)(3 << (_format.aShift + 6 - _format.aLoss)); while (ptr != end) { - // Darken the colour, and increase the alpha + // Darken the color, and increase the alpha // (0% -> 75%, 100% -> 100%) *ptr = (PixelType)(((*ptr & ~mask) >> 2) + addA); ++ptr; @@ -1266,51 +1272,50 @@ template<typename PixelType> void VectorRendererSpec<PixelType>:: drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color, bool fill) { int pitch = _activeSurface->pitch / _activeSurface->format.bytesPerPixel; + int i, j; + PixelType *ptr_left; - int height = h; - PixelType *ptr_fill = (PixelType *)_activeSurface->getBasePtr(x, y); - + // Fill Background + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); + i = h; if (fill) { assert((_bgColor & ~_alphaMask) == 0); // only support black - while (height--) { - darkenFill(ptr_fill, ptr_fill + w); - ptr_fill += pitch; + while (i--) { + darkenFill(ptr_left, ptr_left + w); + ptr_left += pitch; } } - int i, j; - x = MAX(x - bevel, 0); y = MAX(y - bevel, 0); w = MIN(w + (bevel * 2), (int)_activeSurface->w); h = MIN(h + (bevel * 2), (int)_activeSurface->h); - PixelType *ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); - + ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y); i = bevel; while (i--) { colorFill<PixelType>(ptr_left, ptr_left + w, top_color); ptr_left += pitch; } - i = h - bevel; ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + bevel); + i = h - bevel; while (i--) { colorFill<PixelType>(ptr_left, ptr_left + bevel, top_color); ptr_left += pitch; } - i = bevel; ptr_left = (PixelType *)_activeSurface->getBasePtr(x, y + h - bevel); + i = bevel; while (i--) { colorFill<PixelType>(ptr_left + i, ptr_left + w, bottom_color); ptr_left += pitch; } + ptr_left = (PixelType *)_activeSurface->getBasePtr(x + w - bevel, y); i = h - bevel; j = bevel - 1; - ptr_left = (PixelType *)_activeSurface->getBasePtr(x + w - bevel, y); while (i--) { colorFill<PixelType>(ptr_left + j, ptr_left + bevel, bottom_color); if (j > 0) j--; diff --git a/graphics/colormasks.h b/graphics/colormasks.h index 2a2523f4b3..eebfc13213 100644 --- a/graphics/colormasks.h +++ b/graphics/colormasks.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/conversion.cpp b/graphics/conversion.cpp index 2da8b6f0ce..27180b80ad 100644 --- a/graphics/conversion.cpp +++ b/graphics/conversion.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/conversion.h" diff --git a/graphics/conversion.h b/graphics/conversion.h index 28e64a94fb..33d57f7a4f 100644 --- a/graphics/conversion.h +++ b/graphics/conversion.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/cursor.h b/graphics/cursor.h index b04d9c04e2..354d981de6 100644 --- a/graphics/cursor.h +++ b/graphics/cursor.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 133ee5fd71..5fcd2a3602 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/cursorman.h" diff --git a/graphics/cursorman.h b/graphics/cursorman.h index b4d8ad94ce..f4a0ebbd82 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_CURSORMAN_H diff --git a/graphics/decoders/bmp.cpp b/graphics/decoders/bmp.cpp deleted file mode 100644 index 2eabbb7631..0000000000 --- a/graphics/decoders/bmp.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* 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. - */ - -#include "common/stream.h" -#include "common/textconsole.h" - -#include "graphics/pixelformat.h" -#include "graphics/surface.h" -#include "graphics/decoders/bmp.h" - -namespace Graphics { - -BitmapDecoder::BitmapDecoder() { - _surface = 0; - _palette = 0; - _paletteColorCount = 0; -} - -BitmapDecoder::~BitmapDecoder() { - destroy(); -} - -void BitmapDecoder::destroy() { - if (_surface) { - _surface->free(); - delete _surface; _surface = 0; - } - - delete[] _palette; _palette = 0; - _paletteColorCount = 0; -} - -bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) { - destroy(); - - if (stream.readByte() != 'B') - return false; - - if (stream.readByte() != 'M') - return false; - - /* uint32 fileSize = */ stream.readUint32LE(); - /* uint16 res1 = */ stream.readUint16LE(); - /* uint16 res2 = */ stream.readUint16LE(); - uint32 imageOffset = stream.readUint32LE(); - - uint32 infoSize = stream.readUint32LE(); - if (infoSize != 40) { - warning("Only Windows v3 bitmaps are supported"); - return false; - } - - uint32 width = stream.readUint32LE(); - int32 height = stream.readSint32LE(); - - if (width == 0 || height == 0) - return false; - - if (height < 0) { - warning("Right-side up bitmaps not supported"); - return false; - } - - /* uint16 planes = */ stream.readUint16LE(); - uint16 bitsPerPixel = stream.readUint16LE(); - - if (bitsPerPixel != 8 && bitsPerPixel != 24 && bitsPerPixel != 32) { - warning("%dbpp bitmaps not supported", bitsPerPixel); - return false; - } - - uint32 compression = stream.readUint32LE(); - - if (compression != 0) { - warning("Compressed bitmaps not supported"); - return false; - } - - /* uint32 imageSize = */ stream.readUint32LE(); - /* uint32 pixelsPerMeterX = */ stream.readUint32LE(); - /* uint32 pixelsPerMeterY = */ stream.readUint32LE(); - _paletteColorCount = stream.readUint32LE(); - /* uint32 colorsImportant = */ stream.readUint32LE(); - - if (bitsPerPixel == 8) { - if (_paletteColorCount == 0) - _paletteColorCount = 256; - - // Read the palette - _palette = new byte[_paletteColorCount * 3]; - for (uint16 i = 0; i < _paletteColorCount; i++) { - _palette[i * 3 + 2] = stream.readByte(); - _palette[i * 3 + 1] = stream.readByte(); - _palette[i * 3 + 0] = stream.readByte(); - stream.readByte(); - } - } - - // Start us at the beginning of the image - stream.seek(imageOffset); - - Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8(); - - // BGRA for 24bpp and 32 bpp - if (bitsPerPixel == 24 || bitsPerPixel == 32) - format = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0); - - _surface = new Graphics::Surface(); - _surface->create(width, height, format); - - int srcPitch = width * (bitsPerPixel >> 3); - const int extraDataLength = (srcPitch % 4) ? 4 - (srcPitch % 4) : 0; - - if (bitsPerPixel == 8) { - byte *dst = (byte *)_surface->getPixels(); - - for (int32 i = 0; i < height; i++) { - stream.read(dst + (height - i - 1) * width, width); - stream.skip(extraDataLength); - } - } else if (bitsPerPixel == 24) { - byte *dst = (byte *)_surface->getBasePtr(0, height - 1); - - for (int32 i = 0; i < height; i++) { - for (uint32 j = 0; j < width; j++) { - byte b = stream.readByte(); - byte g = stream.readByte(); - byte r = stream.readByte(); - uint32 color = format.RGBToColor(r, g, b); - - *((uint32 *)dst) = color; - dst += format.bytesPerPixel; - } - - stream.skip(extraDataLength); - dst -= _surface->pitch * 2; - } - } else { // 32 bpp - byte *dst = (byte *)_surface->getBasePtr(0, height - 1); - - for (int32 i = 0; i < height; i++) { - for (uint32 j = 0; j < width; j++) { - byte b = stream.readByte(); - byte g = stream.readByte(); - byte r = stream.readByte(); - // Ignore the last byte, as in v3 it is unused - // and should thus NOT be used as alpha. - // ref: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx - stream.readByte(); - uint32 color = format.RGBToColor(r, g, b); - - *((uint32 *)dst) = color; - dst += format.bytesPerPixel; - } - - stream.skip(extraDataLength); - dst -= _surface->pitch * 2; - } - } - - return true; -} - -} // End of namespace Graphics diff --git a/graphics/decoders/bmp.h b/graphics/decoders/bmp.h deleted file mode 100644 index 779da352be..0000000000 --- a/graphics/decoders/bmp.h +++ /dev/null @@ -1,66 +0,0 @@ -/* 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. - */ - -/** - * @file - * Image decoder used in engines: - * - hugo - * - mohawk - * - wintermute - */ - -#ifndef GRAPHICS_DECODERS_BMP_H -#define GRAPHICS_DECODERS_BMP_H - -#include "common/scummsys.h" -#include "common/str.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common{ -class SeekableReadStream; -} - -namespace Graphics { - -struct PixelFormat; -struct Surface; - -class BitmapDecoder : public ImageDecoder { -public: - BitmapDecoder(); - virtual ~BitmapDecoder(); - - // ImageDecoder API - void destroy(); - virtual bool loadStream(Common::SeekableReadStream &stream); - virtual const Surface *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } - uint16 getPaletteColorCount() const { return _paletteColorCount; } - -private: - Surface *_surface; - byte *_palette; - uint16 _paletteColorCount; -}; - -} // End of namespace Graphics - -#endif diff --git a/graphics/decoders/iff.cpp b/graphics/decoders/iff.cpp deleted file mode 100644 index 7b37969fc1..0000000000 --- a/graphics/decoders/iff.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* 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. - */ - -#include "common/iff_container.h" -#include "common/stream.h" -#include "common/util.h" - -#include "graphics/decoders/iff.h" - -namespace Graphics { - -IFFDecoder::IFFDecoder() { - _surface = 0; - _palette = 0; - - destroy(); -} - -IFFDecoder::~IFFDecoder() { - destroy(); -} - -void IFFDecoder::destroy() { - if (_surface) { - _surface->free(); - delete _surface; - _surface = 0; - } - - if (_palette) { - delete[] _palette; - _palette = 0; - } - - memset(&_header, 0, sizeof(Header)); - _paletteRanges.clear(); - _type = TYPE_UNKNOWN; - _paletteColorCount = 0; - _numRelevantPlanes = 8; - _pixelPacking = false; -} - -bool IFFDecoder::loadStream(Common::SeekableReadStream &stream) { - destroy(); - - const uint32 form = stream.readUint32BE(); - - if (form != ID_FORM) { - warning("Failed reading IFF-file"); - return false; - } - - stream.skip(4); - - const uint32 type = stream.readUint32BE(); - - switch (type) { - case ID_ILBM: - _type = TYPE_ILBM; - break; - case ID_PBM: - _type = TYPE_PBM; - break; - } - - if (type == TYPE_UNKNOWN) { - warning("Failed reading IFF-file"); - return false; - } - - while (1) { - const uint32 chunkType = stream.readUint32BE(); - const uint32 chunkSize = stream.readUint32BE(); - - if (stream.eos()) - break; - - switch (chunkType) { - case ID_BMHD: - loadHeader(stream); - break; - case ID_CMAP: - loadPalette(stream, chunkSize); - break; - case ID_CRNG: - loadPaletteRange(stream, chunkSize); - break; - case ID_BODY: - loadBitmap(stream); - break; - default: - stream.skip(chunkSize); - } - } - - return true; -} - -void IFFDecoder::loadHeader(Common::SeekableReadStream &stream) { - _header.width = stream.readUint16BE(); - _header.height = stream.readUint16BE(); - _header.x = stream.readUint16BE(); - _header.y = stream.readUint16BE(); - _header.numPlanes = stream.readByte(); - _header.masking = stream.readByte(); - _header.compression = stream.readByte(); - _header.flags = stream.readByte(); - _header.transparentColor = stream.readUint16BE(); - _header.xAspect = stream.readByte(); - _header.yAspect = stream.readByte(); - _header.pageWidth = stream.readUint16BE(); - _header.pageHeight = stream.readUint16BE(); - - assert(_header.width >= 1); - assert(_header.height >= 1); - assert(_header.numPlanes >= 1 && _header.numPlanes <= 8 && _header.numPlanes != 7); -} - -void IFFDecoder::loadPalette(Common::SeekableReadStream &stream, const uint32 size) { - _palette = new byte[size]; - stream.read(_palette, size); - _paletteColorCount = size / 3; -} - -void IFFDecoder::loadPaletteRange(Common::SeekableReadStream &stream, const uint32 size) { - PaletteRange range; - - range.timer = stream.readSint16BE(); - range.step = stream.readSint16BE(); - range.flags = stream.readSint16BE(); - range.first = stream.readByte(); - range.last = stream.readByte(); - - _paletteRanges.push_back(range); -} - -void IFFDecoder::loadBitmap(Common::SeekableReadStream &stream) { - _numRelevantPlanes = MIN(_numRelevantPlanes, _header.numPlanes); - - if (_numRelevantPlanes != 1 && _numRelevantPlanes != 2 && _numRelevantPlanes != 4) - _pixelPacking = false; - - uint16 outPitch = _header.width; - - if (_pixelPacking) - outPitch /= (8 / _numRelevantPlanes); - - // FIXME: CLUT8 is not a proper format for packed bitmaps but there is no way to tell it to use 1, 2 or 4 bits per pixel - _surface = new Graphics::Surface(); - _surface->create(outPitch, _header.height, Graphics::PixelFormat::createFormatCLUT8()); - - if (_type == TYPE_ILBM) { - uint32 scanlinePitch = ((_header.width + 15) >> 4) << 1; - byte *scanlines = new byte[scanlinePitch * _header.numPlanes]; - byte *data = (byte *)_surface->getPixels(); - - for (uint16 i = 0; i < _header.height; ++i) { - byte *scanline = scanlines; - - for (uint16 j = 0; j < _header.numPlanes; ++j) { - uint16 outSize = scanlinePitch; - - if (_header.compression) { - Common::PackBitsReadStream packStream(stream); - packStream.read(scanline, outSize); - } else { - stream.read(scanline, outSize); - } - - scanline += outSize; - } - - packPixels(scanlines, data, scanlinePitch, outPitch); - data += outPitch; - } - - delete[] scanlines; - } else if (_type == TYPE_PBM) { - byte *data = (byte *)_surface->getPixels(); - uint32 outSize = _header.width * _header.height; - - if (_header.compression) { - Common::PackBitsReadStream packStream(stream); - packStream.read(data, outSize); - } else { - stream.read(data, outSize); - } - } -} - -void IFFDecoder::packPixels(byte *scanlines, byte *data, const uint16 scanlinePitch, const uint16 outPitch) { - uint32 numPixels = _header.width; - - if (_pixelPacking) - numPixels = outPitch * (8 / _numRelevantPlanes); - - for (uint32 x = 0; x < numPixels; ++x) { - byte *scanline = scanlines; - byte pixel = 0; - byte offset = x >> 3; - byte bit = 0x80 >> (x & 7); - - // first build a pixel by scanning all the usable planes in the input - for (uint32 plane = 0; plane < _numRelevantPlanes; ++plane) { - if (scanline[offset] & bit) - pixel |= (1 << plane); - - scanline += scanlinePitch; - } - - // then output the pixel according to the requested packing - if (!_pixelPacking) - data[x] = pixel; - else if (_numRelevantPlanes == 1) - data[x / 8] |= (pixel << (x & 7)); - else if (_numRelevantPlanes == 2) - data[x / 4] |= (pixel << ((x & 3) << 1)); - else if (_numRelevantPlanes == 4) - data[x / 2] |= (pixel << ((x & 1) << 2)); - } -} - -} // End of namespace Graphics diff --git a/graphics/decoders/iff.h b/graphics/decoders/iff.h deleted file mode 100644 index beac62e519..0000000000 --- a/graphics/decoders/iff.h +++ /dev/null @@ -1,119 +0,0 @@ -/* 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. - */ - -/** - * @file - * Image decoder used in engines: - * - gob - * - parallaction - * - queen - * - saga - */ - -#ifndef GRAPHICS_DECODERS_IFF_H -#define GRAPHICS_DECODERS_IFF_H - -#include "common/array.h" -#include "common/endian.h" - -#include "graphics/surface.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { - -struct Surface; - -class IFFDecoder : public ImageDecoder { -public: - struct Header { - uint16 width, height; - uint16 x, y; - byte numPlanes; - byte masking; - byte compression; - byte flags; - uint16 transparentColor; - byte xAspect, yAspect; - uint16 pageWidth, pageHeight; - }; - - struct PaletteRange { - int16 timer, step, flags; - byte first, last; - }; - - enum Type { - TYPE_UNKNOWN = 0, - TYPE_ILBM, - TYPE_PBM - }; - - IFFDecoder(); - virtual ~IFFDecoder(); - - // ImageDecoder API - void destroy(); - bool loadStream(Common::SeekableReadStream &stream); - const Header *getHeader() const { return &_header; } - const Surface *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } - const Common::Array<PaletteRange> &getPaletteRanges() const { return _paletteRanges; } - uint16 getPaletteColorCount() const { return _paletteColorCount; } - - /** - * The number of planes to decode, also determines the pixel packing if _packPixels is true. - * 8 == decode all planes, map 1 pixel in 1 byte. (default, no packing even if _packPixels is true) - */ - void setNumRelevantPlanes(const uint8 numRelevantPlanes) { _numRelevantPlanes = numRelevantPlanes; } - - /** - * Enables pixel packing, the amount of packing is determined by _numRelevantPlanes - * 1 == decode first plane, pack 8 pixels in 1 byte. This makes _surface->w 1/8th of _header.width - * 2 == decode first 2 planes, pack 4 pixels in 1 byte. This makes _surface->w 1/4th of _header.width - * 4 == decode first 4 planes, pack 2 pixels in 1 byte. This makes _surface->w half of _header.width - * Packed bitmaps won't have a proper surface format since there is no way to tell it to use 1, 2 or 4 bits per pixel - */ - void setPixelPacking(const bool pixelPacking) { _pixelPacking = pixelPacking; } -private: - - Header _header; - Surface *_surface; - byte *_palette; - Common::Array<PaletteRange> _paletteRanges; - Type _type; - uint16 _paletteColorCount; - uint8 _numRelevantPlanes; - bool _pixelPacking; - - void loadHeader(Common::SeekableReadStream &stream); - void loadPalette(Common::SeekableReadStream &stream, const uint32 size); - void loadPaletteRange(Common::SeekableReadStream &stream, const uint32 size); - void loadBitmap(Common::SeekableReadStream &stream); - void packPixels(byte *scanlines, byte *data, const uint16 scanlinePitch, const uint16 outPitch); -}; - -} // End of namespace Graphics - -#endif // GRAPHICS_DECODERS_IFF_H diff --git a/graphics/decoders/image_decoder.h b/graphics/decoders/image_decoder.h deleted file mode 100644 index 49e31c6e3a..0000000000 --- a/graphics/decoders/image_decoder.h +++ /dev/null @@ -1,98 +0,0 @@ -/* 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 GRAPHICS_DECODERS_IMAGEDECODER_H -#define GRAPHICS_DECODERS_IMAGEDECODER_H - -#include "common/scummsys.h" -#include "common/str.h" - -namespace Common{ -class SeekableReadStream; -} - -namespace Graphics { - -struct PixelFormat; -struct Surface; - -/** - * A representation of an image decoder that maintains ownership of the surface - * and palette it decodes to. - */ -class ImageDecoder { -public: - virtual ~ImageDecoder() {} - - /** - * Load an image from the specified stream - * - * @param stream the input stream - * @return whether loading the file succeeded - * @see getSurface - * @see getPalette - */ - virtual bool loadStream(Common::SeekableReadStream &stream) = 0; - - /** - * Destroy this decoder's surface and palette - */ - virtual void destroy() = 0; - - /** - * Get the decoded surface - * - * This surface is owned by this ImageDecoder and will remain valid - * until destroy() or loadStream() is called, or until this ImageDecoder's - * destructor is called. - * - * @return the decoded surface, or 0 if no surface is present - */ - virtual const Surface *getSurface() const = 0; - - /** - * Get the decoded palette - * - * This palette is owned by this ImageDecoder and will remain valid - * until destroy() or loadStream() is called, or until this ImageDecoder's - * destructor is called. - * - * The palette's format is the same as PaletteManager's palette - * (interleaved RGB values). - * - * @return the decoded palette, or undefined if no palette is present - */ - virtual const byte *getPalette() const { return 0; } - - /** - * Query if the decoded image has a palette. - */ - virtual bool hasPalette() const { return getPaletteColorCount() != 0; } - - /** Return the starting index of the palette. */ - virtual byte getPaletteStartIndex() const { return 0; } - /** Return the number of colors in the palette. */ - virtual uint16 getPaletteColorCount() const { return 0; } -}; - -} // End of namespace Graphics - -#endif diff --git a/graphics/decoders/jpeg.cpp b/graphics/decoders/jpeg.cpp deleted file mode 100644 index c858884095..0000000000 --- a/graphics/decoders/jpeg.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* 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. - * - */ - -// libjpeg uses forbidden symbols in its header. Thus, we need to allow them -// here. -#define FORBIDDEN_SYMBOL_ALLOW_ALL - -#include "graphics/pixelformat.h" -#include "graphics/decoders/jpeg.h" - -#include "common/debug.h" -#include "common/endian.h" -#include "common/stream.h" -#include "common/textconsole.h" - -#ifdef USE_JPEG -// The original release of libjpeg v6b did not contain any extern "C" in case -// its header files are included in a C++ environment. To avoid any linking -// issues we need to add it on our own. -extern "C" { -#include <jpeglib.h> -#include <jerror.h> -} -#endif - -namespace Graphics { - -JPEGDecoder::JPEGDecoder() : ImageDecoder(), _surface(), _colorSpace(kColorSpaceRGBA) { -} - -JPEGDecoder::~JPEGDecoder() { - destroy(); -} - -const Surface *JPEGDecoder::getSurface() const { - return &_surface; -} - -void JPEGDecoder::destroy() { - _surface.free(); -} - -#ifdef USE_JPEG -namespace { - -#define JPEG_BUFFER_SIZE 4096 - -struct StreamSource : public jpeg_source_mgr { - Common::SeekableReadStream *stream; - bool startOfFile; - JOCTET buffer[JPEG_BUFFER_SIZE]; -}; - -void initSource(j_decompress_ptr cinfo) { - StreamSource *source = (StreamSource *)cinfo->src; - source->startOfFile = true; -} - -boolean fillInputBuffer(j_decompress_ptr cinfo) { - StreamSource *source = (StreamSource *)cinfo->src; - - uint32 bufferSize = source->stream->read((byte *)source->buffer, sizeof(source->buffer)); - if (bufferSize == 0) { - if (source->startOfFile) { - // An empty file is a fatal error - ERREXIT(cinfo, JERR_INPUT_EMPTY); - } else { - // Otherwise we insert an EOF marker - WARNMS(cinfo, JWRN_JPEG_EOF); - source->buffer[0] = (JOCTET)0xFF; - source->buffer[1] = (JOCTET)JPEG_EOI; - bufferSize = 2; - } - } - - source->next_input_byte = source->buffer; - source->bytes_in_buffer = bufferSize; - source->startOfFile = false; - - return TRUE; -} - -void skipInputData(j_decompress_ptr cinfo, long numBytes) { - StreamSource *source = (StreamSource *)cinfo->src; - - if (numBytes > 0) { - if (numBytes > (long)source->bytes_in_buffer) { - // In case we need to skip more bytes than there are in the buffer - // we will skip the remaining data and fill the buffer again - numBytes -= (long)source->bytes_in_buffer; - - // Skip the remaining bytes - source->stream->skip(numBytes); - - // Fill up the buffer again - (*source->fill_input_buffer)(cinfo); - } else { - source->next_input_byte += (size_t)numBytes; - source->bytes_in_buffer -= (size_t)numBytes; - } - - } -} - -void termSource(j_decompress_ptr cinfo) { -} - -void jpeg_scummvm_src(j_decompress_ptr cinfo, Common::SeekableReadStream *stream) { - StreamSource *source; - - // Initialize the source in case it has not been done yet. - if (cinfo->src == NULL) { - cinfo->src = (jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(StreamSource)); - } - - source = (StreamSource *)cinfo->src; - source->init_source = &initSource; - source->fill_input_buffer = &fillInputBuffer; - source->skip_input_data = &skipInputData; - source->resync_to_restart = &jpeg_resync_to_restart; - source->term_source = &termSource; - source->bytes_in_buffer = 0; - source->next_input_byte = NULL; - - source->stream = stream; -} - -void errorExit(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - // This function is not allowed to return to the caller, thus we simply - // error out with our error handling here. - error("%s", buffer); -} - -void outputMessage(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - // Is using debug here a good idea? Or do we want to ignore all libjpeg - // messages? - debug(3, "libjpeg: %s", buffer); -} - -} // End of anonymous namespace -#endif - -bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) { -#ifdef USE_JPEG - // Reset member variables from previous decodings - destroy(); - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - // Initialize error handling callbacks - cinfo.err = jpeg_std_error(&jerr); - cinfo.err->error_exit = &errorExit; - cinfo.err->output_message = &outputMessage; - - // Initialize the decompression structure - jpeg_create_decompress(&cinfo); - - // Initialize our buffer handling - jpeg_scummvm_src(&cinfo, &stream); - - // Read the file header - jpeg_read_header(&cinfo, TRUE); - - // We can request YUV output because Groovie requires it - switch (_colorSpace) { - case kColorSpaceRGBA: - cinfo.out_color_space = JCS_RGB; - break; - - case kColorSpaceYUV: - cinfo.out_color_space = JCS_YCbCr; - break; - } - - // Actually start decompressing the image - jpeg_start_decompress(&cinfo); - - // Allocate buffers for the output data - switch (_colorSpace) { - case kColorSpaceRGBA: - // We use RGBA8888 in this scenario - _surface.create(cinfo.output_width, cinfo.output_height, Graphics::PixelFormat(4, 8, 8, 8, 0, 24, 16, 8, 0)); - break; - - case kColorSpaceYUV: - // We use YUV with 3 bytes per pixel otherwise. - // This is pretty ugly since our PixelFormat cannot express YUV... - _surface.create(cinfo.output_width, cinfo.output_height, Graphics::PixelFormat(3, 0, 0, 0, 0, 0, 0, 0, 0)); - break; - } - - // Allocate buffer for one scanline - assert(cinfo.output_components == 3); - JDIMENSION pitch = cinfo.output_width * cinfo.output_components; - assert(_surface.pitch >= pitch); - JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, pitch, 1); - - // Go through the image data scanline by scanline - while (cinfo.output_scanline < cinfo.output_height) { - byte *dst = (byte *)_surface.getBasePtr(0, cinfo.output_scanline); - - jpeg_read_scanlines(&cinfo, buffer, 1); - - const byte *src = buffer[0]; - switch (_colorSpace) { - case kColorSpaceRGBA: { - for (int remaining = cinfo.output_width; remaining > 0; --remaining) { - byte r = *src++; - byte g = *src++; - byte b = *src++; - // We need to insert a alpha value of 255 (opaque) here. -#ifdef SCUMM_BIG_ENDIAN - *dst++ = r; - *dst++ = g; - *dst++ = b; - *dst++ = 0xFF; -#else - *dst++ = 0xFF; - *dst++ = b; - *dst++ = g; - *dst++ = r; -#endif - } - } break; - - case kColorSpaceYUV: - memcpy(dst, src, pitch); - break; - } - } - - // We are done with decompressing, thus free all the data - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - return true; -#else - return false; -#endif -} - -} // End of Graphics namespace diff --git a/graphics/decoders/jpeg.h b/graphics/decoders/jpeg.h deleted file mode 100644 index 8460bc2698..0000000000 --- a/graphics/decoders/jpeg.h +++ /dev/null @@ -1,95 +0,0 @@ -/* 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. - * - */ - -/** - * @file - * Image decoder used in engines: - * - groovie - * - mohawk - * - wintermute - */ - -#ifndef GRAPHICS_JPEG_H -#define GRAPHICS_JPEG_H - -#include "graphics/surface.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { - -class JPEGDecoder : public ImageDecoder { -public: - JPEGDecoder(); - ~JPEGDecoder(); - - // ImageDecoder API - virtual void destroy(); - virtual bool loadStream(Common::SeekableReadStream &str); - virtual const Surface *getSurface() const; - - // Special API for JPEG - enum ColorSpace { - /** - * Output 32bit RGBA data. - * - * This is the default output. - */ - kColorSpaceRGBA, - - /** - * Output (interleaved) YUV data. - * - * Be aware that some images cannot be output in YUV mode. - * These are (non-standard) JPEG images which are in RGB colorspace. - * - * The resulting Surface will have a PixelFormat with 3 bytes per - * pixel and the remaining entries are completely zeroed. This works - * around the fact that PixelFormat can only describe RGB formats. - * - * You should only use this when you are really aware of what you are - * doing! - */ - kColorSpaceYUV - }; - - /** - * Request the output color space. This can be used to obtain raw YUV - * data from the JPEG file. But this might not work for all files! - * - * The decoder itself defaults to RGBA. - * - * @param outSpace The color space to output. - */ - void setOutputColorSpace(ColorSpace outSpace) { _colorSpace = outSpace; } - -private: - Graphics::Surface _surface; - ColorSpace _colorSpace; -}; - -} // End of Graphics namespace - -#endif // GRAPHICS_JPEG_H diff --git a/graphics/decoders/pcx.cpp b/graphics/decoders/pcx.cpp deleted file mode 100644 index eb9b4c997d..0000000000 --- a/graphics/decoders/pcx.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* 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. - */ - -#include "common/stream.h" -#include "common/textconsole.h" - -#include "graphics/pixelformat.h" -#include "graphics/surface.h" -#include "graphics/decoders/pcx.h" - -/** - * Based on the PCX specs: - * http://www.fileformat.info/format/pcx/spec/a10e75307b3a4cc49c3bbe6db4c41fa2/view.htm - * and the PCX decoder of FFmpeg (libavcodec/pcx.c): - * http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavcodec/pcx.c - */ - -namespace Graphics { - -PCXDecoder::PCXDecoder() { - _surface = 0; - _palette = 0; - _paletteColorCount = 0; -} - -PCXDecoder::~PCXDecoder() { - destroy(); -} - -void PCXDecoder::destroy() { - if (_surface) { - _surface->free(); - delete _surface; - _surface = 0; - } - - delete[] _palette; - _palette = 0; - _paletteColorCount = 0; -} - -bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) { - destroy(); - - if (stream.readByte() != 0x0a) // ZSoft PCX - return false; - - byte version = stream.readByte(); // 0 - 5 - if (version > 5) - return false; - - bool compressed = stream.readByte(); // encoding, 1 = run length encoding - byte bitsPerPixel = stream.readByte(); // 1, 2, 4 or 8 - - // Window - uint16 xMin = stream.readUint16LE(); - uint16 yMin = stream.readUint16LE(); - uint16 xMax = stream.readUint16LE(); - uint16 yMax = stream.readUint16LE(); - - uint16 width = xMax - xMin + 1; - uint16 height = yMax - yMin + 1; - - if (xMax < xMin || yMax < yMin) { - warning("Invalid PCX image dimensions"); - return false; - } - - stream.skip(4); // HDpi, VDpi - - // Read the EGA palette (colormap) - _palette = new byte[16 * 3]; - for (uint16 i = 0; i < 16; i++) { - _palette[i * 3 + 0] = stream.readByte(); - _palette[i * 3 + 1] = stream.readByte(); - _palette[i * 3 + 2] = stream.readByte(); - } - - if (stream.readByte() != 0) // reserved, should be set to 0 - return false; - - byte nPlanes = stream.readByte(); - uint16 bytesPerLine = stream.readUint16LE(); - uint16 bytesPerscanLine = nPlanes * bytesPerLine; - - if (bytesPerscanLine < width * bitsPerPixel * nPlanes / 8) { - warning("PCX data is corrupted"); - return false; - } - - stream.skip(60); // PaletteInfo, HscreenSize, VscreenSize, Filler - - _surface = new Graphics::Surface(); - - byte *scanLine = new byte[bytesPerscanLine]; - byte *dst; - int x, y; - - if (nPlanes == 3 && bitsPerPixel == 8) { // 24bpp - Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); - _surface->create(width, height, format); - dst = (byte *)_surface->getPixels(); - _paletteColorCount = 0; - - for (y = 0; y < height; y++) { - decodeRLE(stream, scanLine, bytesPerscanLine, compressed); - - for (x = 0; x < width; x++) { - byte b = scanLine[x]; - byte g = scanLine[x + bytesPerLine]; - byte r = scanLine[x + (bytesPerLine << 1)]; - uint32 color = format.RGBToColor(r, g, b); - - *((uint32 *)dst) = color; - dst += format.bytesPerPixel; - } - } - } else if (nPlanes == 1 && bitsPerPixel == 8) { // 8bpp indexed - _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - dst = (byte *)_surface->getPixels(); - _paletteColorCount = 16; - - for (y = 0; y < height; y++, dst += _surface->pitch) { - decodeRLE(stream, scanLine, bytesPerscanLine, compressed); - memcpy(dst, scanLine, width); - } - - if (version == 5) { - if (stream.readByte() != 12) { - warning("Expected a palette after the PCX image data"); - delete[] scanLine; - return false; - } - - // Read the VGA palette - delete[] _palette; - _palette = new byte[256 * 3]; - for (uint16 i = 0; i < 256; i++) { - _palette[i * 3 + 0] = stream.readByte(); - _palette[i * 3 + 1] = stream.readByte(); - _palette[i * 3 + 2] = stream.readByte(); - } - - _paletteColorCount = 256; - } - } else if ((nPlanes == 2 || nPlanes == 3 || nPlanes == 4) && bitsPerPixel == 1) { // planar, 4, 8 or 16 colors - _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - dst = (byte *)_surface->getPixels(); - _paletteColorCount = 16; - - for (y = 0; y < height; y++, dst += _surface->pitch) { - decodeRLE(stream, scanLine, bytesPerscanLine, compressed); - - for (x = 0; x < width; x++) { - int m = 0x80 >> (x & 7), v = 0; - for (int i = nPlanes - 1; i >= 0; i--) { - v <<= 1; - v += (scanLine[i * bytesPerLine + (x >> 3)] & m) == 0 ? 0 : 1; - } - dst[x] = v; - } - } - } else { - // Known unsupported case: 1 plane and bpp < 8 (1, 2 or 4) - warning("Invalid PCX file (%d planes, %d bpp)", nPlanes, bitsPerPixel); - delete[] scanLine; - return false; - } - - delete[] scanLine; - - return true; -} - -void PCXDecoder::decodeRLE(Common::SeekableReadStream &stream, byte *dst, uint32 bytesPerscanLine, bool compressed) { - uint32 i = 0; - byte run, value; - - if (compressed) { - while (i < bytesPerscanLine) { - run = 1; - value = stream.readByte(); - if (value >= 0xc0) { - run = value & 0x3f; - value = stream.readByte(); - } - while (i < bytesPerscanLine && run--) - dst[i++] = value; - } - } else { - stream.read(dst, bytesPerscanLine); - } -} - -} // End of namespace Graphics diff --git a/graphics/decoders/pcx.h b/graphics/decoders/pcx.h deleted file mode 100644 index b25166b3d9..0000000000 --- a/graphics/decoders/pcx.h +++ /dev/null @@ -1,68 +0,0 @@ -/* 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. - */ - -/** - * PCX decoder used in engines: - * - dreamweb - * - hugo - * - queen - * - tucker - */ - -#ifndef GRAPHICS_DECODERS_PCX_H -#define GRAPHICS_DECODERS_PCX_H - -#include "common/scummsys.h" -#include "common/str.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common{ -class SeekableReadStream; -} - -namespace Graphics { - -struct PixelFormat; -struct Surface; - -class PCXDecoder : public ImageDecoder { -public: - PCXDecoder(); - virtual ~PCXDecoder(); - - // ImageDecoder API - void destroy(); - virtual bool loadStream(Common::SeekableReadStream &stream); - virtual const Surface *getSurface() const { return _surface; } - const byte *getPalette() const { return _palette; } - uint16 getPaletteColorCount() const { return _paletteColorCount; } - -private: - void decodeRLE(Common::SeekableReadStream &stream, byte *dst, uint32 bytesPerScanline, bool compressed); - - Surface *_surface; - byte *_palette; - uint16 _paletteColorCount; -}; - -} // End of namespace Graphics - -#endif diff --git a/graphics/decoders/pict.cpp b/graphics/decoders/pict.cpp deleted file mode 100644 index f3e17b33e2..0000000000 --- a/graphics/decoders/pict.cpp +++ /dev/null @@ -1,580 +0,0 @@ -/* 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. - * - */ - -#include "common/debug.h" -#include "common/endian.h" -#include "common/stream.h" -#include "common/substream.h" -#include "common/textconsole.h" - -#include "graphics/surface.h" -#include "graphics/decoders/jpeg.h" -#include "graphics/decoders/pict.h" - -namespace Graphics { - -// The PICT code is based off of the QuickDraw specs: -// http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-461.html -// http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-269.html - -PICTDecoder::PICTDecoder() { - _outputSurface = 0; - _paletteColorCount = 0; -} - -PICTDecoder::~PICTDecoder() { - destroy(); -} - -void PICTDecoder::destroy() { - if (_outputSurface) { - _outputSurface->free(); - delete _outputSurface; - _outputSurface = 0; - } - - _paletteColorCount = 0; -} - -#define OPCODE(a, b, c) _opcodes.push_back(PICTOpcode(a, &PICTDecoder::b, c)) - -void PICTDecoder::setupOpcodesCommon() { - OPCODE(0x0000, o_nop, "NOP"); - OPCODE(0x0001, o_clip, "Clip"); - OPCODE(0x0003, o_txFont, "TxFont"); - OPCODE(0x0004, o_txFace, "TxFace"); - OPCODE(0x0007, o_pnSize, "PnSize"); - OPCODE(0x000D, o_txSize, "TxSize"); - OPCODE(0x0010, o_txRatio, "TxRatio"); - OPCODE(0x0011, o_versionOp, "VersionOp"); - OPCODE(0x001E, o_nop, "DefHilite"); - OPCODE(0x0028, o_longText, "LongText"); - OPCODE(0x00A1, o_longComment, "LongComment"); - OPCODE(0x00FF, o_opEndPic, "OpEndPic"); - OPCODE(0x0C00, o_headerOp, "HeaderOp"); -} - -void PICTDecoder::setupOpcodesNormal() { - setupOpcodesCommon(); - OPCODE(0x0098, on_packBitsRect, "PackBitsRect"); - OPCODE(0x009A, on_directBitsRect, "DirectBitsRect"); - OPCODE(0x8200, on_compressedQuickTime, "CompressedQuickTime"); -} - -void PICTDecoder::setupOpcodesQuickTime() { - setupOpcodesCommon(); - OPCODE(0x0098, oq_packBitsRect, "PackBitsRect"); - OPCODE(0x009A, oq_directBitsRect, "DirectBitsRect"); - OPCODE(0x8200, oq_compressedQuickTime, "CompressedQuickTime"); -} - -#undef OPCODE - -void PICTDecoder::o_nop(Common::SeekableReadStream &) { - // Nothing to do -} - -void PICTDecoder::o_clip(Common::SeekableReadStream &stream) { - // Ignore - stream.skip(stream.readUint16BE() - 2); -} - -void PICTDecoder::o_txFont(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); -} - -void PICTDecoder::o_txFace(Common::SeekableReadStream &stream) { - // Ignore - stream.readByte(); -} - -void PICTDecoder::o_pnSize(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); - stream.readUint16BE(); -} - -void PICTDecoder::o_txSize(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); -} - -void PICTDecoder::o_txRatio(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); - stream.readUint16BE(); - stream.readUint16BE(); - stream.readUint16BE(); -} - -void PICTDecoder::o_versionOp(Common::SeekableReadStream &stream) { - // We only support v2 extended - if (stream.readUint16BE() != 0x02FF) - error("Unknown PICT version"); -} - -void PICTDecoder::o_longText(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); - stream.readUint16BE(); - stream.skip(stream.readByte()); -} - -void PICTDecoder::o_longComment(Common::SeekableReadStream &stream) { - // Ignore - stream.readUint16BE(); - stream.skip(stream.readUint16BE()); -} - -void PICTDecoder::o_opEndPic(Common::SeekableReadStream &stream) { - // We've reached the end of the picture - _continueParsing = false; -} - -void PICTDecoder::o_headerOp(Common::SeekableReadStream &stream) { - // Read the basic header, but we don't really have to do anything with it - /* uint16 version = */ stream.readUint16BE(); - stream.readUint16BE(); // Reserved - /* uint32 hRes = */ stream.readUint32BE(); - /* uint32 vRes = */ stream.readUint32BE(); - Common::Rect origResRect; - origResRect.top = stream.readUint16BE(); - origResRect.left = stream.readUint16BE(); - origResRect.bottom = stream.readUint16BE(); - origResRect.right = stream.readUint16BE(); - stream.readUint32BE(); // Reserved -} - -void PICTDecoder::on_packBitsRect(Common::SeekableReadStream &stream) { - // Unpack data (8bpp or lower) - unpackBitsRect(stream, true); -} - -void PICTDecoder::on_directBitsRect(Common::SeekableReadStream &stream) { - // Unpack data (16bpp or higher) - unpackBitsRect(stream, false); -} - -void PICTDecoder::on_compressedQuickTime(Common::SeekableReadStream &stream) { - // OK, here's the fun. We get to completely change how QuickDraw draws - // the data in PICT files. - - // Swap out the opcodes to the new ones - _opcodes.clear(); - setupOpcodesQuickTime(); - - // We'll decode the first QuickTime data from here, but the QuickTime-specific - // opcodes will take over from here on out. Normal opcodes, signing off. - decodeCompressedQuickTime(stream); -} - -void PICTDecoder::oq_packBitsRect(Common::SeekableReadStream &stream) { - // Skip any data here (8bpp or lower) - skipBitsRect(stream, true); -} - -void PICTDecoder::oq_directBitsRect(Common::SeekableReadStream &stream) { - // Skip any data here (16bpp or higher) - skipBitsRect(stream, false); -} - -void PICTDecoder::oq_compressedQuickTime(Common::SeekableReadStream &stream) { - // Just pass the data along - decodeCompressedQuickTime(stream); -} - -bool PICTDecoder::loadStream(Common::SeekableReadStream &stream) { - destroy(); - - // Initialize opcodes to their normal state - _opcodes.clear(); - setupOpcodesNormal(); - - _continueParsing = true; - memset(_palette, 0, sizeof(_palette)); - - uint16 fileSize = stream.readUint16BE(); - - // If we have no file size here, we probably have a PICT from a file - // and not a resource. The other two bytes are the fileSize which we - // don't actually need (and already read if from a resource). - if (!fileSize) - stream.seek(512 + 2); - - _imageRect.top = stream.readUint16BE(); - _imageRect.left = stream.readUint16BE(); - _imageRect.bottom = stream.readUint16BE(); - _imageRect.right = stream.readUint16BE(); - _imageRect.debugPrint(0, "PICT Rect:"); - - // NOTE: This is only a subset of the full PICT format. - // - Only V2 (Extended) Images Supported - // - CompressedQuickTime (JPEG) compressed data is supported - // - DirectBitsRect/PackBitsRect compressed data is supported - for (uint32 opNum = 0; !stream.eos() && !stream.err() && stream.pos() < stream.size() && _continueParsing; opNum++) { - // PICT v2 opcodes are two bytes - uint16 opcode = stream.readUint16BE(); - - if (opNum == 0 && opcode != 0x0011) { - warning("Cannot find PICT version opcode"); - return false; - } else if (opNum == 1 && opcode != 0x0C00) { - warning("Cannot find PICT header opcode"); - return false; - } - - // Since opcodes are word-aligned, we need to mark our starting - // position here. - uint32 startPos = stream.pos(); - - for (uint32 i = 0; i < _opcodes.size(); i++) { - if (_opcodes[i].op == opcode) { - debug(4, "Running PICT opcode %04x '%s'", opcode, _opcodes[i].desc); - (this->*(_opcodes[i].proc))(stream); - break; - } else if (i == _opcodes.size() - 1) { - // Unknown opcode; attempt to continue forward - warning("Unknown PICT opcode %04x", opcode); - } - } - - // Align - stream.skip((stream.pos() - startPos) & 1); - } - - return _outputSurface; -} - -PICTDecoder::PixMap PICTDecoder::readPixMap(Common::SeekableReadStream &stream, bool hasBaseAddr) { - PixMap pixMap; - pixMap.baseAddr = hasBaseAddr ? stream.readUint32BE() : 0; - pixMap.rowBytes = stream.readUint16BE() & 0x3fff; - pixMap.bounds.top = stream.readUint16BE(); - pixMap.bounds.left = stream.readUint16BE(); - pixMap.bounds.bottom = stream.readUint16BE(); - pixMap.bounds.right = stream.readUint16BE(); - pixMap.pmVersion = stream.readUint16BE(); - pixMap.packType = stream.readUint16BE(); - pixMap.packSize = stream.readUint32BE(); - pixMap.hRes = stream.readUint32BE(); - pixMap.vRes = stream.readUint32BE(); - pixMap.pixelType = stream.readUint16BE(); - pixMap.pixelSize = stream.readUint16BE(); - pixMap.cmpCount = stream.readUint16BE(); - pixMap.cmpSize = stream.readUint16BE(); - pixMap.planeBytes = stream.readUint32BE(); - pixMap.pmTable = stream.readUint32BE(); - pixMap.pmReserved = stream.readUint32BE(); - return pixMap; -} - -struct PackBitsRectData { - PICTDecoder::PixMap pixMap; - Common::Rect srcRect; - Common::Rect dstRect; - uint16 mode; -}; - -void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool withPalette) { - PackBitsRectData packBitsData; - packBitsData.pixMap = readPixMap(stream, !withPalette); - - // Read in the palette if there is one present - if (withPalette) { - // See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-267.html - stream.readUint32BE(); // seed - stream.readUint16BE(); // flags - _paletteColorCount = stream.readUint16BE() + 1; - - for (uint32 i = 0; i < _paletteColorCount; i++) { - stream.readUint16BE(); - _palette[i * 3] = stream.readUint16BE() >> 8; - _palette[i * 3 + 1] = stream.readUint16BE() >> 8; - _palette[i * 3 + 2] = stream.readUint16BE() >> 8; - } - } - - packBitsData.srcRect.top = stream.readUint16BE(); - packBitsData.srcRect.left = stream.readUint16BE(); - packBitsData.srcRect.bottom = stream.readUint16BE(); - packBitsData.srcRect.right = stream.readUint16BE(); - packBitsData.dstRect.top = stream.readUint16BE(); - packBitsData.dstRect.left = stream.readUint16BE(); - packBitsData.dstRect.bottom = stream.readUint16BE(); - packBitsData.dstRect.right = stream.readUint16BE(); - packBitsData.mode = stream.readUint16BE(); - - uint16 width = packBitsData.srcRect.width(); - uint16 height = packBitsData.srcRect.height(); - - byte bytesPerPixel = 0; - - if (packBitsData.pixMap.pixelSize <= 8) - bytesPerPixel = 1; - else if (packBitsData.pixMap.pixelSize == 32) - bytesPerPixel = packBitsData.pixMap.cmpCount; - else - bytesPerPixel = packBitsData.pixMap.pixelSize / 8; - - // Ensure we have enough space in the buffer to hold an entire line's worth of pixels - uint32 lineSize = MAX<int>(width * bytesPerPixel + (8 * 2 / packBitsData.pixMap.pixelSize), packBitsData.pixMap.rowBytes); - byte *buffer = new byte[lineSize * height]; - - // Read in amount of data per row - for (uint16 i = 0; i < packBitsData.pixMap.bounds.height(); i++) { - // NOTE: Compression 0 is "default". The format in SCI games is packed when 0. - // In the future, we may need to have something to set the "default" packing - // format, but this is good for now. - - if (packBitsData.pixMap.packType == 1 || packBitsData.pixMap.rowBytes < 8) { // Unpacked, Pad-Byte (on 24-bit) - // TODO: Finish this. Hasn't been needed (yet). - error("Unpacked DirectBitsRect data (padded)"); - } else if (packBitsData.pixMap.packType == 2) { // Unpacked, No Pad-Byte (on 24-bit) - // TODO: Finish this. Hasn't been needed (yet). - error("Unpacked DirectBitsRect data (not padded)"); - } else if (packBitsData.pixMap.packType == 0 || packBitsData.pixMap.packType > 2) { // Packed - uint16 byteCount = (packBitsData.pixMap.rowBytes > 250) ? stream.readUint16BE() : stream.readByte(); - unpackBitsLine(buffer + i * width * bytesPerPixel, packBitsData.pixMap.rowBytes, stream.readStream(byteCount), packBitsData.pixMap.pixelSize, bytesPerPixel); - } - } - - _outputSurface = new Graphics::Surface(); - - switch (bytesPerPixel) { - case 1: - // Just copy to the image - _outputSurface->create(width, height, PixelFormat::createFormatCLUT8()); - memcpy(_outputSurface->getPixels(), buffer, _outputSurface->w * _outputSurface->h); - break; - case 2: - // We have a 16-bit surface - _outputSurface->create(width, height, PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); - for (uint16 y = 0; y < _outputSurface->h; y++) - for (uint16 x = 0; x < _outputSurface->w; x++) - WRITE_UINT16(_outputSurface->getBasePtr(x, y), READ_UINT16(buffer + (y * _outputSurface->w + x) * 2)); - break; - case 3: - // We have a planar 24-bit surface - _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); - for (uint16 y = 0; y < _outputSurface->h; y++) { - for (uint16 x = 0; x < _outputSurface->w; x++) { - byte r = *(buffer + y * _outputSurface->w * 3 + x); - byte g = *(buffer + y * _outputSurface->w * 3 + _outputSurface->w + x); - byte b = *(buffer + y * _outputSurface->w * 3 + _outputSurface->w * 2 + x); - *((uint32 *)_outputSurface->getBasePtr(x, y)) = _outputSurface->format.RGBToColor(r, g, b); - } - } - break; - case 4: - // We have a planar 32-bit surface - // Note that we ignore the alpha channel since it seems to not be correct - // Mac OS X does not ignore it, but then displays it incorrectly. Photoshop - // does ignore it and displays it correctly. - _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); - for (uint16 y = 0; y < _outputSurface->h; y++) { - for (uint16 x = 0; x < _outputSurface->w; x++) { - byte a = 0xFF; - byte r = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w + x); - byte g = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w * 2 + x); - byte b = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w * 3 + x); - *((uint32 *)_outputSurface->getBasePtr(x, y)) = _outputSurface->format.ARGBToColor(a, r, g, b); - } - } - break; - } - - delete[] buffer; -} - -void PICTDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel) { - uint32 dataDecoded = 0; - byte bytesPerDecode = (bytesPerPixel == 2) ? 2 : 1; - - while (data->pos() < data->size() && dataDecoded < length) { - byte op = data->readByte(); - - if (op & 0x80) { - uint32 runSize = (op ^ 255) + 2; - uint16 value = (bytesPerDecode == 2) ? data->readUint16BE() : data->readByte(); - - for (uint32 i = 0; i < runSize; i++) { - if (bytesPerDecode == 2) { - WRITE_UINT16(out, value); - out += 2; - } else { - outputPixelBuffer(out, value, bitsPerPixel); - } - } - dataDecoded += runSize * bytesPerDecode; - } else { - uint32 runSize = op + 1; - - if (bytesPerDecode == 1) { - for (uint32 i = 0; i < runSize; i++) - outputPixelBuffer(out, data->readByte(), bitsPerPixel); - } else { - for (uint32 i = 0; i < runSize; i++) { - WRITE_UINT16(out, data->readUint16BE()); - out += 2; - } - } - - dataDecoded += runSize * bytesPerDecode; - } - } - - // HACK: Even if the data is 24-bit, rowBytes is still 32-bit - if (bytesPerPixel == 3) - dataDecoded += length / 4; - - if (length != dataDecoded) - warning("Mismatched PackBits read (%d/%d)", dataDecoded, length); - - delete data; -} - -void PICTDecoder::outputPixelBuffer(byte *&out, byte value, byte bitsPerPixel) { - switch (bitsPerPixel) { - case 1: - for (int i = 7; i >= 0; i--) - *out++ = (value >> i) & 1; - break; - case 2: - for (int i = 6; i >= 0; i -= 2) - *out++ = (value >> i) & 3; - break; - case 4: - *out++ = (value >> 4) & 0xf; - *out++ = value & 0xf; - break; - default: - *out++ = value; - } -} - -void PICTDecoder::skipBitsRect(Common::SeekableReadStream &stream, bool withPalette) { - // Step through a PackBitsRect/DirectBitsRect function - - if (!withPalette) - stream.readUint32BE(); - - uint16 rowBytes = stream.readUint16BE(); - uint16 height = stream.readUint16BE(); - stream.readUint16BE(); - height = stream.readUint16BE() - height; - stream.readUint16BE(); - - uint16 packType; - - // Top two bits signify PixMap vs BitMap - if (rowBytes & 0xC000) { - // PixMap - stream.readUint16BE(); - packType = stream.readUint16BE(); - stream.skip(14); - stream.readUint16BE(); // pixelSize - stream.skip(16); - - if (withPalette) { - stream.readUint32BE(); - stream.readUint16BE(); - stream.skip((stream.readUint16BE() + 1) * 8); - } - - rowBytes &= 0x3FFF; - } else { - // BitMap - packType = 0; - } - - stream.skip(18); - - for (uint16 i = 0; i < height; i++) { - if (packType == 1 || packType == 2 || rowBytes < 8) - error("Unpacked PackBitsRect data"); - else if (packType == 0 || packType > 2) - stream.skip((rowBytes > 250) ? stream.readUint16BE() : stream.readByte()); - } -} - -// Compressed QuickTime details can be found here: -// http://developer.apple.com/legacy/mac/library/#documentation/QuickTime/Rm/CompressDecompress/ImageComprMgr/B-Chapter/2TheImageCompression.html -// http://developer.apple.com/legacy/mac/library/#documentation/QuickTime/Rm/CompressDecompress/ImageComprMgr/F-Chapter/6WorkingwiththeImage.html -void PICTDecoder::decodeCompressedQuickTime(Common::SeekableReadStream &stream) { - // First, read all the fields from the opcode - uint32 dataSize = stream.readUint32BE(); - uint32 startPos = stream.pos(); - - /* uint16 version = */ stream.readUint16BE(); - - // Read in the display matrix - uint32 matrix[3][3]; - for (uint32 i = 0; i < 3; i++) - for (uint32 j = 0; j < 3; j++) - matrix[i][j] = stream.readUint32BE(); - - // We currently only support offseting images vertically from the matrix - uint16 xOffset = 0; - uint16 yOffset = matrix[2][1] >> 16; - - uint32 matteSize = stream.readUint32BE(); - stream.skip(8); // matte rect - /* uint16 transferMode = */ stream.readUint16BE(); - stream.skip(8); // src rect - /* uint32 accuracy = */ stream.readUint32BE(); - uint32 maskSize = stream.readUint32BE(); - - // Skip the matte and mask - stream.skip(matteSize + maskSize); - - // Now we've reached the image descriptor, so read the relevant data from that - uint32 idStart = stream.pos(); - uint32 idSize = stream.readUint32BE(); - uint32 codec = stream.readUint32BE(); - stream.skip(36); // miscellaneous stuff - uint32 jpegSize = stream.readUint32BE(); - stream.skip(idSize - (stream.pos() - idStart)); // more useless stuff - - if (codec != MKTAG('j', 'p', 'e', 'g')) - error("Unhandled CompressedQuickTime format '%s'", tag2str(codec)); - - Common::SeekableSubReadStream jpegStream(&stream, stream.pos(), stream.pos() + jpegSize); - - JPEGDecoder jpeg; - if (!jpeg.loadStream(jpegStream)) - error("PICTDecoder::decodeCompressedQuickTime(): Could not decode JPEG data"); - - const Graphics::Surface *jpegSurface = jpeg.getSurface(); - - if (!_outputSurface) { - _outputSurface = new Graphics::Surface(); - _outputSurface->create(_imageRect.width(), _imageRect.height(), jpegSurface->format); - } - - for (uint16 y = 0; y < jpegSurface->h; y++) - memcpy(_outputSurface->getBasePtr(0 + xOffset, y + yOffset), jpegSurface->getBasePtr(0, y), jpegSurface->w * jpegSurface->format.bytesPerPixel); - - stream.seek(startPos + dataSize); -} - -} // End of namespace Graphics diff --git a/graphics/decoders/pict.h b/graphics/decoders/pict.h deleted file mode 100644 index 6f0d86c7a1..0000000000 --- a/graphics/decoders/pict.h +++ /dev/null @@ -1,140 +0,0 @@ -/* 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. - * - */ - -/** - * @file - * Image decoder used in engines: - * - mohawk - * - pegasus - * - sci - */ - -#ifndef GRAPHICS_PICT_H -#define GRAPHICS_PICT_H - -#include "common/array.h" -#include "common/rect.h" -#include "common/scummsys.h" - -#include "graphics/decoders/image_decoder.h" -#include "graphics/pixelformat.h" - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { - -struct Surface; - -#define DECLARE_OPCODE(x) void x(Common::SeekableReadStream &stream) - -class PICTDecoder : public ImageDecoder { -public: - PICTDecoder(); - ~PICTDecoder(); - - // ImageDecoder API - bool loadStream(Common::SeekableReadStream &stream); - void destroy(); - const Surface *getSurface() const { return _outputSurface; } - const byte *getPalette() const { return _palette; } - uint16 getPaletteColorCount() const { return _paletteColorCount; } - - struct PixMap { - uint32 baseAddr; - uint16 rowBytes; - Common::Rect bounds; - uint16 pmVersion; - uint16 packType; - uint32 packSize; - uint32 hRes; - uint32 vRes; - uint16 pixelType; - uint16 pixelSize; - uint16 cmpCount; - uint16 cmpSize; - uint32 planeBytes; - uint32 pmTable; - uint32 pmReserved; - }; - - static PixMap readPixMap(Common::SeekableReadStream &stream, bool hasBaseAddr = true); - -private: - Common::Rect _imageRect; - byte _palette[256 * 3]; - uint16 _paletteColorCount; - Graphics::Surface *_outputSurface; - bool _continueParsing; - - // Utility Functions - void unpackBitsRect(Common::SeekableReadStream &stream, bool withPalette); - void unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *stream, byte bitsPerPixel, byte bytesPerPixel); - void skipBitsRect(Common::SeekableReadStream &stream, bool withPalette); - void decodeCompressedQuickTime(Common::SeekableReadStream &stream); - void outputPixelBuffer(byte *&out, byte value, byte bitsPerPixel); - - // Opcodes - typedef void (PICTDecoder::*OpcodeProcPICT)(Common::SeekableReadStream &stream); - struct PICTOpcode { - PICTOpcode() { op = 0; proc = 0; desc = 0; } - PICTOpcode(uint16 o, OpcodeProcPICT p, const char *d) { op = o; proc = p; desc = d; } - uint16 op; - OpcodeProcPICT proc; - const char *desc; - }; - Common::Array<PICTOpcode> _opcodes; - - // Common Opcodes - void setupOpcodesCommon(); - DECLARE_OPCODE(o_nop); - DECLARE_OPCODE(o_clip); - DECLARE_OPCODE(o_txFont); - DECLARE_OPCODE(o_txFace); - DECLARE_OPCODE(o_pnSize); - DECLARE_OPCODE(o_txSize); - DECLARE_OPCODE(o_txRatio); - DECLARE_OPCODE(o_versionOp); - DECLARE_OPCODE(o_longText); - DECLARE_OPCODE(o_longComment); - DECLARE_OPCODE(o_opEndPic); - DECLARE_OPCODE(o_headerOp); - - // Regular-mode Opcodes - void setupOpcodesNormal(); - DECLARE_OPCODE(on_packBitsRect); - DECLARE_OPCODE(on_directBitsRect); - DECLARE_OPCODE(on_compressedQuickTime); - - // QuickTime-mode Opcodes - void setupOpcodesQuickTime(); - DECLARE_OPCODE(oq_packBitsRect); - DECLARE_OPCODE(oq_directBitsRect); - DECLARE_OPCODE(oq_compressedQuickTime); -}; - -#undef DECLARE_OPCODE - -} // End of namespace Graphics - -#endif diff --git a/graphics/decoders/png.cpp b/graphics/decoders/png.cpp deleted file mode 100644 index 5acb7b36f7..0000000000 --- a/graphics/decoders/png.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* 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. - * - */ - -// Since we need to work with libpng here, we need to allow all symbols -// to avoid compilation issues. -#define FORBIDDEN_SYMBOL_ALLOW_ALL -#include "common/scummsys.h" - -#ifdef USE_PNG -#include <png.h> -#endif - -#include "graphics/decoders/png.h" - -#include "graphics/pixelformat.h" -#include "graphics/surface.h" - -#include "common/stream.h" - -namespace Graphics { - -PNGDecoder::PNGDecoder() : _outputSurface(0), _palette(0), _paletteColorCount(0), _stream(0) { -} - -PNGDecoder::~PNGDecoder() { - destroy(); -} - -void PNGDecoder::destroy() { - if (_outputSurface) { - _outputSurface->free(); - delete _outputSurface; - _outputSurface = 0; - } - delete[] _palette; - _palette = NULL; -} - -#ifdef USE_PNG -// libpng-error-handling: -void pngError(png_structp pngptr, png_const_charp errorMsg) { - error("%s", errorMsg); -} - -void pngWarning(png_structp pngptr, png_const_charp warningMsg) { - warning("%s", warningMsg); -} - -// libpng-I/O-helper: -void pngReadFromStream(png_structp pngPtr, png_bytep data, png_size_t length) { - void *readIOptr = png_get_io_ptr(pngPtr); - Common::SeekableReadStream *stream = (Common::SeekableReadStream *)readIOptr; - stream->read(data, length); -} -#endif - -/* - * This code is based on Broken Sword 2.5 engine - * - * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer - * - * Licensed under GNU GPL v2 - * - */ - -bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) { -#ifdef USE_PNG - destroy(); - - _stream = &stream; - - // First, check the PNG signature - if (_stream->readUint32BE() != MKTAG(0x89, 'P', 'N', 'G')) { - delete _stream; - return false; - } - if (_stream->readUint32BE() != MKTAG(0x0d, 0x0a, 0x1a, 0x0a)) { - delete _stream; - return false; - } - - // The following is based on the guide provided in: - //http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3 - //http://www.libpng.org/pub/png/libpng-1.4.0-manual.pdf - // along with the png-loading code used in the sword25-engine. - png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!pngPtr) { - delete _stream; - return false; - } - png_infop infoPtr = png_create_info_struct(pngPtr); - if (!infoPtr) { - png_destroy_read_struct(&pngPtr, NULL, NULL); - delete _stream; - return false; - } - png_infop endInfo = png_create_info_struct(pngPtr); - if (!endInfo) { - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - delete _stream; - return false; - } - - png_set_error_fn(pngPtr, NULL, pngError, pngWarning); - // TODO: The manual says errors should be handled via setjmp - - png_set_read_fn(pngPtr, _stream, pngReadFromStream); - png_set_crc_action(pngPtr, PNG_CRC_DEFAULT, PNG_CRC_WARN_USE); - // We already verified the PNG-header - png_set_sig_bytes(pngPtr, 8); - - // Read PNG header - png_read_info(pngPtr, infoPtr); - - // No handling for unknown chunks yet. - int bitDepth, colorType, width, height, interlaceType; - png_uint_32 w, h; - png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL); - width = w; - height = h; - - // Allocate memory for the final image data. - // To keep memory framentation low this happens before allocating memory for temporary image data. - _outputSurface = new Graphics::Surface(); - - // Images of all color formats except PNG_COLOR_TYPE_PALETTE - // will be transformed into ARGB images - if (colorType == PNG_COLOR_TYPE_PALETTE && !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) { - int numPalette = 0; - png_colorp palette = NULL; - uint32 success = png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette); - if (success != PNG_INFO_PLTE) { - png_destroy_read_struct(&pngPtr, &infoPtr, NULL); - return false; - } - _paletteColorCount = numPalette; - _palette = new byte[_paletteColorCount * 3]; - for (int i = 0; i < _paletteColorCount; i++) { - _palette[(i * 3)] = palette[i].red; - _palette[(i * 3) + 1] = palette[i].green; - _palette[(i * 3) + 2] = palette[i].blue; - - } - _outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - png_set_packing(pngPtr); - } else { - _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); - if (!_outputSurface->getPixels()) { - error("Could not allocate memory for output image."); - } - if (bitDepth == 16) - png_set_strip_16(pngPtr); - if (bitDepth < 8) - png_set_expand(pngPtr); - if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) - png_set_expand(pngPtr); - if (colorType == PNG_COLOR_TYPE_GRAY || - colorType == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(pngPtr); - - // PNGs are Big-Endian: -#ifdef SCUMM_LITTLE_ENDIAN - png_set_bgr(pngPtr); - png_set_swap_alpha(pngPtr); - if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) - png_set_filler(pngPtr, 0xff, PNG_FILLER_BEFORE); -#else - if (colorType != PNG_COLOR_TYPE_RGB_ALPHA) - png_set_filler(pngPtr, 0xff, PNG_FILLER_AFTER); -#endif - - } - - // After the transformations have been registered, the image data is read again. - png_set_interlace_handling(pngPtr); - png_read_update_info(pngPtr, infoPtr); - png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL); - width = w; - height = h; - - if (interlaceType == PNG_INTERLACE_NONE) { - // PNGs without interlacing can simply be read row by row. - for (int i = 0; i < height; i++) { - png_read_row(pngPtr, (png_bytep)_outputSurface->getBasePtr(0, i), NULL); - } - } else { - // PNGs with interlacing require us to allocate an auxillary - // buffer with pointers to all row starts. - - // Allocate row pointer buffer - png_bytep *rowPtr = new png_bytep[height]; - if (!rowPtr) { - error("Could not allocate memory for row pointers."); - } - - // Initialize row pointers - for (int i = 0; i < height; i++) - rowPtr[i] = (png_bytep)_outputSurface->getBasePtr(0, i); - - // Read image data - png_read_image(pngPtr, rowPtr); - - // Free row pointer buffer - delete[] rowPtr; - } - - // Read additional data at the end. - png_read_end(pngPtr, NULL); - - // Destroy libpng structures - png_destroy_read_struct(&pngPtr, &infoPtr, &endInfo); - - // We no longer need the file stream, thus close it here - _stream = 0; - - return true; -#else - return false; -#endif -} - -} // End of Graphics namespace diff --git a/graphics/decoders/png.h b/graphics/decoders/png.h deleted file mode 100644 index 5e608eb7b1..0000000000 --- a/graphics/decoders/png.h +++ /dev/null @@ -1,67 +0,0 @@ -/* 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. - * - */ - -/* - * PNG decoder used in engines: - * - sword25 - * - wintermute - * Dependencies: - * - libpng - */ - -#ifndef GRAPHICS_PNG_H -#define GRAPHICS_PNG_H - -#include "common/scummsys.h" -#include "common/textconsole.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { - -struct Surface; -struct PixelFormat; - -class PNGDecoder : public ImageDecoder { -public: - PNGDecoder(); - ~PNGDecoder(); - - bool loadStream(Common::SeekableReadStream &stream); - void destroy(); - const Graphics::Surface *getSurface() const { return _outputSurface; } - const byte *getPalette() const { return _palette; } - uint16 getPaletteColorCount() const { return _paletteColorCount; } -private: - Common::SeekableReadStream *_stream; - byte *_palette; - uint16 _paletteColorCount; - - Graphics::Surface *_outputSurface; -}; - -} // End of namespace Graphics - -#endif // GRAPHICS_PNG_H diff --git a/graphics/decoders/tga.cpp b/graphics/decoders/tga.cpp deleted file mode 100644 index a9f136d238..0000000000 --- a/graphics/decoders/tga.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* 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. - */ - -/* Based on code from xoreos https://github.com/DrMcCoy/xoreos/ - * relicensed under GPLv2+ with permission from DrMcCoy and clone2727 - */ - -#include "common/util.h" -#include "common/stream.h" -#include "common/textconsole.h" -#include "common/error.h" - -#include "graphics/decoders/tga.h" - -namespace Graphics { - -TGADecoder::TGADecoder() { - _colorMapSize = 0; - _colorMapOrigin = 0; - _colorMapLength = 0; - _colorMapEntryLength = 0; - _colorMap = NULL; -} - -TGADecoder::~TGADecoder() { - destroy(); -} - -void TGADecoder::destroy() { - _surface.free(); - delete[] _colorMap; -} - -bool TGADecoder::loadStream(Common::SeekableReadStream &tga) { - byte imageType, pixelDepth; - bool success; - success = readHeader(tga, imageType, pixelDepth); - if (success) { - switch (imageType) { - case TYPE_BW: - case TYPE_TRUECOLOR: - success = readData(tga, imageType, pixelDepth); - break; - case TYPE_RLE_BW: - case TYPE_RLE_TRUECOLOR: - case TYPE_RLE_CMAP: - success = readDataRLE(tga, imageType, pixelDepth); - break; - case TYPE_CMAP: - success = readDataColorMapped(tga, imageType, pixelDepth); - break; - default: - success = false; - break; - } - } - if (tga.err() || !success) { - warning("Failed reading TGA-file"); - return false; - } - return success; -} - -bool TGADecoder::readHeader(Common::SeekableReadStream &tga, byte &imageType, byte &pixelDepth) { - if (!tga.seek(0)) { - warning("Failed reading TGA-file"); - return false; - } - - // TGAs have an optional "id" string in the header - uint32 idLength = tga.readByte(); - - // Number of colors in the color map / palette - int hasColorMap = tga.readByte(); - - // Image type. See header for numeric constants - imageType = tga.readByte(); - - switch (imageType) { - case TYPE_CMAP: - case TYPE_TRUECOLOR: - case TYPE_BW: - case TYPE_RLE_CMAP: - case TYPE_RLE_TRUECOLOR: - case TYPE_RLE_BW: - break; - default: - warning("Unsupported image type: %d", imageType); - return false; - } - - // Color map specifications - if (hasColorMap == 0) { - tga.skip(5); - } else { - _colorMapOrigin = tga.readUint16LE(); - _colorMapLength = tga.readUint16LE(); - _colorMapEntryLength = tga.readByte(); - } - // Origin-defintions - tga.skip(2 + 2); - - // Image dimensions - _surface.w = tga.readUint16LE(); - _surface.h = tga.readUint16LE(); - - // Bits per pixel - pixelDepth = tga.readByte(); - _surface.format.bytesPerPixel = pixelDepth / 8; - - // Image descriptor - byte imgDesc = tga.readByte(); - int attributeBits = imgDesc & 0x0F; - assert((imgDesc & 0x10) == 0); - _originTop = (imgDesc & 0x20); - - // Interleaving is not handled at this point - //int interleave = (imgDesc & 0xC); - if (imageType == TYPE_CMAP || imageType == TYPE_RLE_CMAP) { - if (pixelDepth == 8) { - _format = PixelFormat::createFormatCLUT8(); - } else { - warning("Unsupported index-depth: %d", pixelDepth); - return false; - } - } else if (imageType == TYPE_TRUECOLOR || imageType == TYPE_RLE_TRUECOLOR) { - if (pixelDepth == 24) { - _format = PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0); - } else if (pixelDepth == 32) { - // HACK: According to the spec, attributeBits should determine the amount - // of alpha-bits, however, as the game files that use this decoder seems - // to ignore that fact, we force the amount to 8 for 32bpp files for now. - _format = PixelFormat(4, 8, 8, 8, /* attributeBits */ 8, 16, 8, 0, 24); - } else if (pixelDepth == 16 && imageType == TYPE_TRUECOLOR) { - // 16bpp TGA is ARGB1555 - _format = PixelFormat(2, 5, 5, 5, attributeBits, 10, 5, 0, 15); - } else { - warning("Unsupported pixel depth: %d, %d", imageType, pixelDepth); - return false; - } - } else if (imageType == TYPE_BW || TYPE_RLE_BW) { - if (pixelDepth == 8) { - _format = PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0); - } else { - warning("Unsupported pixel depth: %d, %d", imageType, pixelDepth); - return false; - } - - } else { - warning("Unsupported image type: %d", imageType); - return false; - } - - // Skip the id string - tga.skip(idLength); - - if (hasColorMap) { - return readColorMap(tga, imageType, pixelDepth); - } - return true; -} - -bool TGADecoder::readColorMap(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth) { - _colorMap = new byte[3 * _colorMapLength]; - for (int i = 0; i < _colorMapLength * 3; i += 3) { - byte r, g, b; - if (_colorMapEntryLength == 32) { - byte a; - PixelFormat format(4, 8, 8, 8, 0, 16, 8, 0, 24); - uint32 color = tga.readUint32LE(); - format.colorToARGB(color, a, r, g, b); - } else if (_colorMapEntryLength == 24) { - r = tga.readByte(); - g = tga.readByte(); - b = tga.readByte(); - } else if (_colorMapEntryLength == 16) { - byte a; - PixelFormat format(2, 5, 5, 5, 0, 10, 5, 0, 15); - uint16 color = tga.readUint16LE(); - format.colorToARGB(color, a, r, g, b); - } else { - warning("Unsupported image type: %d", imageType); - r = g = b = 0; - } -#ifdef SCUMM_LITTLE_ENDIAN - _colorMap[i] = r; - _colorMap[i + 1] = g; - _colorMap[i + 2] = b; -#else - _colorMap[i] = b; - _colorMap[i + 1] = g; - _colorMap[i + 2] = r; -#endif - } - return true; -} - -// Additional information found from http://paulbourke.net/dataformats/tga/ -// With some details from the link referenced in the header. -bool TGADecoder::readData(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth) { - // TrueColor - if (imageType == TYPE_TRUECOLOR) { - _surface.create(_surface.w, _surface.h, _format); - - if (pixelDepth == 16) { - for (int i = 0; i < _surface.h; i++) { - uint16 *dst; - if (!_originTop) { - dst = (uint16 *)_surface.getBasePtr(0, _surface.h - i - 1); - } else { - dst = (uint16 *)_surface.getBasePtr(0, i); - } - for (int j = 0; j < _surface.w; j++) { - *dst++ = tga.readUint16LE(); - } - } - } else if (pixelDepth == 32) { - for (int i = 0; i < _surface.h; i++) { - uint32 *dst; - if (!_originTop) { - dst = (uint32 *)_surface.getBasePtr(0, _surface.h - i - 1); - } else { - dst = (uint32 *)_surface.getBasePtr(0, i); - } - for (int j = 0; j < _surface.w; j++) { - *dst++ = tga.readUint32LE(); - } - } - } else if (pixelDepth == 24) { - for (int i = 0; i < _surface.h; i++) { - byte *dst; - if (!_originTop) { - dst = (byte *)_surface.getBasePtr(0, _surface.h - i - 1); - } else { - dst = (byte *)_surface.getBasePtr(0, i); - } - for (int j = 0; j < _surface.w; j++) { - byte r = tga.readByte(); - byte g = tga.readByte(); - byte b = tga.readByte(); -#ifdef SCUMM_LITTLE_ENDIAN - *dst++ = r; - *dst++ = g; - *dst++ = b; -#else - *dst++ = b; - *dst++ = g; - *dst++ = r; -#endif - } - } - } - // Black/White - } else if (imageType == TYPE_BW) { - _surface.create(_surface.w, _surface.h, _format); - - byte *data = (byte *)_surface.getPixels(); - uint32 count = _surface.w * _surface.h; - - while (count-- > 0) { - byte g = tga.readByte(); - *data++ = g; - *data++ = g; - *data++ = g; - *data++ = g; - } - } - return true; -} - -bool TGADecoder::readDataColorMapped(Common::SeekableReadStream &tga, byte imageType, byte indexDepth) { - // Color-mapped - if (imageType == TYPE_CMAP) { - _surface.create(_surface.w, _surface.h, _format); - if (indexDepth == 8) { - for (int i = 0; i < _surface.h; i++) { - byte *dst; - if (!_originTop) { - dst = (byte *)_surface.getBasePtr(0, _surface.h - i - 1); - } else { - dst = (byte *)_surface.getBasePtr(0, i); - } - for (int j = 0; j < _surface.w; j++) { - byte index = tga.readByte(); - *dst++ = index; - } - } - } else if (indexDepth == 16) { - warning("16 bit indexes not supported"); - return false; - } - } else { - return false; - } - return true; -} - -bool TGADecoder::readDataRLE(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth) { - // RLE-TrueColor / RLE-Black/White - if (imageType == TYPE_RLE_TRUECOLOR || imageType == TYPE_RLE_BW || imageType == TYPE_RLE_CMAP) { - _surface.create(_surface.w, _surface.h, _format); - uint32 count = _surface.w * _surface.h; - byte *data = (byte *)_surface.getPixels(); - - while (count > 0) { - uint32 header = tga.readByte(); - byte type = (header & 0x80) >> 7; - uint32 rleCount = (header & 0x7F) + 1; - - // RLE-packet - if (type == 1) { - if (pixelDepth == 32 && imageType == TYPE_RLE_TRUECOLOR) { - uint32 color = tga.readUint32LE(); - while (rleCount-- > 0) { - *((uint32 *)data) = color; - data += 4; - count--; - } - } else if (pixelDepth == 24 && imageType == TYPE_RLE_TRUECOLOR) { - byte r = tga.readByte(); - byte g = tga.readByte(); - byte b = tga.readByte(); - while (rleCount-- > 0) { -#ifdef SCUMM_LITTLE_ENDIAN - *data++ = r; - *data++ = g; - *data++ = b; -#else - *data++ = b; - *data++ = g; - *data++ = r; -#endif - count--; - } - } else if (pixelDepth == 8 && imageType == TYPE_RLE_BW) { - byte color = tga.readByte(); - while (rleCount-- > 0) { - *data++ = color; - *data++ = color; - *data++ = color; - *data++ = color; - count--; - } - } else if (pixelDepth == 8 && imageType == TYPE_RLE_CMAP) { - byte index = tga.readByte(); - while (rleCount-- > 0) { - *data++ = index; - count--; - } - } else { - warning("Unhandled pixel-depth for image-type 10"); - return false; - } - // Raw-packet - } else if (type == 0) { - if (pixelDepth == 32 && imageType == TYPE_RLE_TRUECOLOR) { - while (rleCount-- > 0) { - uint32 color = tga.readUint32LE(); - *((uint32 *)data) = color; - data += 4; - count--; - } - } else if (pixelDepth == 24 && imageType == TYPE_RLE_TRUECOLOR) { - while (rleCount-- > 0) { - byte r = tga.readByte(); - byte g = tga.readByte(); - byte b = tga.readByte(); -#ifdef SCUMM_LITTLE_ENDIAN - *data++ = r; - *data++ = g; - *data++ = b; -#else - *data++ = b; - *data++ = g; - *data++ = r; -#endif - count--; - } - } else if (pixelDepth == 8 && imageType == TYPE_RLE_BW) { - while (rleCount-- > 0) { - byte color = tga.readByte(); - *data++ = color; - *data++ = color; - *data++ = color; - *data++ = color; - count--; - } - } else if (pixelDepth == 8 && imageType == TYPE_RLE_CMAP) { - while (rleCount-- > 0) { - byte index = tga.readByte(); - *data++ = index; - count--; - } - } else { - warning("Unhandled pixel-depth for image-type 10"); - return false; - } - } else { - warning("Unknown header for RLE-packet %d", type); - return false; - } - } - } else { - return false; - } - return true; -} - -} // End of namespace Graphics diff --git a/graphics/decoders/tga.h b/graphics/decoders/tga.h deleted file mode 100644 index d8ccf8f766..0000000000 --- a/graphics/decoders/tga.h +++ /dev/null @@ -1,98 +0,0 @@ -/* 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. - */ - -/* Based on code from eos https://github.com/DrMcCoy/xoreos/ - * relicensed under GPLv2+ with permission from DrMcCoy and clone2727 - */ - -/* - * TGA decoder used in engines: - * - wintermute - */ - -#ifndef GRAPHICS_DECODERS_TGA_H -#define GRAPHICS_DECODERS_TGA_H - -#include "graphics/surface.h" -#include "graphics/decoders/image_decoder.h" - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { - -/** TarGa image-decoder - * The following variations of TGA are supported: - * - Type 1 - Color-mapped images in 16/24/32 bpp with 8 bit indexes - * - Type 2 - 16/24/32 bpp Top AND Bottom origined. - * - Type 3 - Black/White images, 8bpp. - * - Type 9 - RLE-encoded color-mapped images. (8 bit indexes only) - * - Type 10 - RLE-encoded TrueColor, 24/32bpp. - * - Type 11 - RLE-encoded Black/White, 8bpp. - * - * No images are returned with a palette, instead they are converted - * to 16 bpp for Type 1, or 32 bpp for Black/White-images. - */ -class TGADecoder : public ImageDecoder { -public: - TGADecoder(); - virtual ~TGADecoder(); - virtual void destroy(); - virtual const Surface *getSurface() const { return &_surface; } - virtual const byte *getPalette() const { return _colorMap; } - virtual uint16 getPaletteColorCount() const { return _colorMapLength; } - virtual bool loadStream(Common::SeekableReadStream &stream); -private: - // Format-spec from: - //http://www.ludorg.net/amnesia/TGA_File_Format_Spec.html - enum { - TYPE_CMAP = 1, - TYPE_TRUECOLOR = 2, - TYPE_BW = 3, - TYPE_RLE_CMAP = 9, - TYPE_RLE_TRUECOLOR = 10, - TYPE_RLE_BW = 11 - }; - - // Color-map: - bool _colorMapSize; - byte *_colorMap; - int16 _colorMapOrigin; - int16 _colorMapLength; - byte _colorMapEntryLength; - - // Origin may be at the top, or bottom - bool _originTop; - - PixelFormat _format; - Surface _surface; - // Loading helpers - bool readHeader(Common::SeekableReadStream &tga, byte &imageType, byte &pixelDepth); - bool readData(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth); - bool readDataColorMapped(Common::SeekableReadStream &tga, byte imageType, byte indexDepth); - bool readDataRLE(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth); - bool readColorMap(Common::SeekableReadStream &tga, byte imageType, byte pixelDepth); -}; - -} // End of namespace Graphics - -#endif // GRAPHICS_DECODERS_TGA_H diff --git a/graphics/font.cpp b/graphics/font.cpp index a852274b06..1ed67fa169 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/font.h" @@ -26,93 +27,32 @@ namespace Graphics { -int Font::getKerningOffset(byte left, byte right) const { +int Font::getKerningOffset(uint32 left, uint32 right) const { return 0; } -int Font::getStringWidth(const Common::String &str) const { +namespace { + +template<class StringType> +int getStringWidthImpl(const Font &font, const StringType &str) { int space = 0; - uint last = 0; + typename StringType::unsigned_type last = 0; for (uint i = 0; i < str.size(); ++i) { - const uint cur = str[i]; - space += getCharWidth(cur) + getKerningOffset(last, cur); + const typename StringType::unsigned_type cur = str[i]; + space += font.getCharWidth(cur) + font.getKerningOffset(last, cur); last = cur; } return space; } -void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const { +template<class StringType> +void drawStringImpl(const Font &font, Surface *dst, const StringType &str, int x, int y, int w, uint32 color, TextAlign align, int deltax) { assert(dst != 0); - const int leftX = x, rightX = x + w; - uint i; - Common::String s = sOld; - int width = getStringWidth(s); - Common::String str; - - if (useEllipsis && width > w && s.hasSuffix("...")) { - // String is too wide. Check whether it ends in an ellipsis - // ("..."). If so, remove that and try again! - s.deleteLastChar(); - s.deleteLastChar(); - s.deleteLastChar(); - width = getStringWidth(s); - } - - if (useEllipsis && width > w) { - // String is too wide. So we shorten it "intelligently" by - // replacing parts of the string by an ellipsis. There are - // three possibilities for this: replace the start, the end, or - // the middle of the string. What is best really depends on the - // context; but unless we want to make this configurable, - // replacing the middle seems to be a good compromise. - - const int ellipsisWidth = getStringWidth("..."); - // SLOW algorithm to remove enough of the middle. But it is good enough - // for now. - const int halfWidth = (w - ellipsisWidth) / 2; - int w2 = 0; - uint last = 0; - - for (i = 0; i < s.size(); ++i) { - const uint cur = s[i]; - int charWidth = getCharWidth(cur) + getKerningOffset(last, cur); - if (w2 + charWidth > halfWidth) - break; - last = cur; - w2 += charWidth; - str += cur; - } - - // At this point we know that the first 'i' chars are together 'w2' - // pixels wide. We took the first i-1, and add "..." to them. - str += "..."; - last = '.'; - - // The original string is width wide. Of those we already skipped past - // w2 pixels, which means (width - w2) remain. - // The new str is (w2+ellipsisWidth) wide, so we can accommodate about - // (w - (w2+ellipsisWidth)) more pixels. - // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) = - // (width + ellipsisWidth - w) - int skip = width + ellipsisWidth - w; - for (; i < s.size() && skip > 0; ++i) { - const uint cur = s[i]; - skip -= getCharWidth(cur) + getKerningOffset(last, cur); - last = cur; - } - - // Append the remaining chars, if any - for (; i < s.size(); ++i) { - str += s[i]; - } - - width = getStringWidth(str); - } else { - str = s; - } + const int leftX = x, rightX = x + w; + int width = font.getStringWidth(str); if (align == kTextAlignCenter) x = x + (w - width)/2; @@ -120,29 +60,29 @@ void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, in x = x + w - width; x += deltax; - uint last = 0; - for (i = 0; i < str.size(); ++i) { - const uint cur = str[i]; - x += getKerningOffset(last, cur); + typename StringType::unsigned_type last = 0; + for (typename StringType::const_iterator i = str.begin(), end = str.end(); i != end; ++i) { + const typename StringType::unsigned_type cur = *i; + x += font.getKerningOffset(last, cur); last = cur; - w = getCharWidth(cur); + w = font.getCharWidth(cur); if (x+w > rightX) break; if (x+w >= leftX) - drawChar(dst, str[i], x, y, color); + font.drawChar(dst, cur, x, y, color); x += w; } } - +template<class StringType> struct WordWrapper { - Common::Array<Common::String> &lines; + Common::Array<StringType> &lines; int actualMaxLineWidth; - WordWrapper(Common::Array<Common::String> &l) : lines(l), actualMaxLineWidth(0) { + WordWrapper(Common::Array<StringType> &l) : lines(l), actualMaxLineWidth(0) { } - void add(Common::String &line, int &w) { + void add(StringType &line, int &w) { if (actualMaxLineWidth < w) actualMaxLineWidth = w; @@ -153,10 +93,11 @@ struct WordWrapper { } }; -int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const { - WordWrapper wrapper(lines); - Common::String line; - Common::String tmpStr; +template<class StringType> +int wordWrapTextImpl(const Font &font, const StringType &str, int maxWidth, Common::Array<StringType> &lines) { + WordWrapper<StringType> wrapper(lines); + StringType line; + StringType tmpStr; int lineWidth = 0; int tmpWidth = 0; @@ -173,10 +114,10 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co // of a line. If we encounter such a word, we have to wrap it over multiple // lines. - uint last = 0; - for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) { - const byte c = *x; - const int w = getCharWidth(c) + getKerningOffset(last, c); + typename StringType::unsigned_type last = 0; + for (typename StringType::const_iterator x = str.begin(); x != str.end(); ++x) { + const typename StringType::unsigned_type c = *x; + const int w = font.getCharWidth(c) + font.getKerningOffset(last, c); last = c; const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth); @@ -212,7 +153,7 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co tmpStr.deleteChar(0); // This is not very fast, but it is the simplest way to // assure we do not mess something up because of kerning. - tmpWidth = getStringWidth(tmpStr); + tmpWidth = font.getStringWidth(tmpStr); } } else { wrapper.add(tmpStr, tmpWidth); @@ -232,5 +173,98 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co return wrapper.actualMaxLineWidth; } +} // End of anonymous namespace + +int Font::getStringWidth(const Common::String &str) const { + return getStringWidthImpl(*this, str); +} + +int Font::getStringWidth(const Common::U32String &str) const { + return getStringWidthImpl(*this, str); +} + +void Font::drawString(Surface *dst, const Common::String &sOld, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const { + Common::String s = sOld; + int width = getStringWidth(s); + Common::String str; + + if (useEllipsis && width > w && s.hasSuffix("...")) { + // String is too wide. Check whether it ends in an ellipsis + // ("..."). If so, remove that and try again! + s.deleteLastChar(); + s.deleteLastChar(); + s.deleteLastChar(); + width = getStringWidth(s); + } + + if (useEllipsis && width > w) { + // String is too wide. So we shorten it "intelligently" by + // replacing parts of the string by an ellipsis. There are + // three possibilities for this: replace the start, the end, or + // the middle of the string. What is best really depends on the + // context; but unless we want to make this configurable, + // replacing the middle seems to be a good compromise. + + const int ellipsisWidth = getStringWidth("..."); + + // SLOW algorithm to remove enough of the middle. But it is good enough + // for now. + const int halfWidth = (w - ellipsisWidth) / 2; + int w2 = 0; + Common::String::unsigned_type last = 0; + uint i; + + for (i = 0; i < s.size(); ++i) { + const Common::String::unsigned_type cur = s[i]; + int charWidth = getCharWidth(cur) + getKerningOffset(last, cur); + if (w2 + charWidth > halfWidth) + break; + last = cur; + w2 += charWidth; + str += cur; + } + + // At this point we know that the first 'i' chars are together 'w2' + // pixels wide. We took the first i-1, and add "..." to them. + str += "..."; + last = '.'; + + // The original string is width wide. Of those we already skipped past + // w2 pixels, which means (width - w2) remain. + // The new str is (w2+ellipsisWidth) wide, so we can accommodate about + // (w - (w2+ellipsisWidth)) more pixels. + // Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) = + // (width + ellipsisWidth - w) + int skip = width + ellipsisWidth - w; + for (; i < s.size() && skip > 0; ++i) { + const Common::String::unsigned_type cur = s[i]; + skip -= getCharWidth(cur) + getKerningOffset(last, cur); + last = cur; + } + + // Append the remaining chars, if any + for (; i < s.size(); ++i) { + str += s[i]; + } + + width = getStringWidth(str); + } else { + str = s; + } + + drawStringImpl(*this, dst, str, x, y, w, color, align, deltax); +} + +void Font::drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align) const { + drawStringImpl(*this, dst, str, x, y, w, color, align, 0); +} + +int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const { + return wordWrapTextImpl(*this, str, maxWidth, lines); +} + +int Font::wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const { + return wordWrapTextImpl(*this, str, maxWidth, lines); +} } // End of namespace Graphics diff --git a/graphics/font.h b/graphics/font.h index 6819b42f52..f333107780 100644 --- a/graphics/font.h +++ b/graphics/font.h @@ -17,12 +17,14 @@ * 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 GRAPHICS_FONT_H #define GRAPHICS_FONT_H #include "common/str.h" +#include "common/ustr.h" namespace Common { template<class T> class Array; @@ -70,7 +72,7 @@ public: * @param chr The character to query the width of. * @return The character's width. */ - virtual int getCharWidth(byte chr) const = 0; + virtual int getCharWidth(uint32 chr) const = 0; /** * Query the kerning offset between two characters. @@ -79,7 +81,7 @@ public: * @param right The right character. May be 0. * @return The horizontal displacement. */ - virtual int getKerningOffset(byte left, byte right) const; + virtual int getKerningOffset(uint32 left, uint32 right) const; /** * Draw a character at a specific point on a surface. @@ -96,15 +98,17 @@ public: * @param y The y coordinate where to draw the character. * @param color The color of the character. */ - virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0; + virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const = 0; // TODO: Add doxygen comments to this void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const; + void drawString(Surface *dst, const Common::U32String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft) const; /** * Compute and return the width the string str has when rendered using this font. */ int getStringWidth(const Common::String &str) const; + int getStringWidth(const Common::U32String &str) const; /** * Take a text (which may contain newline characters) and word wrap it so that @@ -120,6 +124,7 @@ public: * @return the maximal width of any of the lines added to lines */ int wordWrapText(const Common::String &str, int maxWidth, Common::Array<Common::String> &lines) const; + int wordWrapText(const Common::U32String &str, int maxWidth, Common::Array<Common::U32String> &lines) const; }; } // End of namespace Graphics diff --git a/graphics/fontman.cpp b/graphics/fontman.cpp index 99dd3d664f..5cf52416cf 100644 --- a/graphics/fontman.cpp +++ b/graphics/fontman.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/fontman.h" diff --git a/graphics/fontman.h b/graphics/fontman.h index b06ddea860..b3de92f547 100644 --- a/graphics/fontman.h +++ b/graphics/fontman.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_FONTMAN_H diff --git a/graphics/fonts/bdf.cpp b/graphics/fonts/bdf.cpp index e523a36ad5..3476838911 100644 --- a/graphics/fonts/bdf.cpp +++ b/graphics/fonts/bdf.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/fonts/bdf.h" @@ -51,7 +52,7 @@ int BdfFont::getMaxCharWidth() const { return _data.maxAdvance; } -int BdfFont::getCharWidth(byte chr) const { +int BdfFont::getCharWidth(uint32 chr) const { // In case all font have the same advance value, we use the maximum. if (!_data.advances) return _data.maxAdvance; @@ -85,9 +86,9 @@ void drawCharIntern(byte *ptr, uint pitch, const byte *src, int h, int width, in } } -int BdfFont::mapToIndex(byte ch) const { +int BdfFont::mapToIndex(uint32 ch) const { // Check whether the character is included - if (_data.firstCharacter <= ch && ch <= _data.firstCharacter + _data.numCharacters) { + if (_data.firstCharacter <= (int)ch && (int)ch <= _data.firstCharacter + _data.numCharacters) { if (_data.bitmaps[ch - _data.firstCharacter]) return ch - _data.firstCharacter; } @@ -95,7 +96,7 @@ int BdfFont::mapToIndex(byte ch) const { return _data.defaultCharacter - _data.firstCharacter; } -void BdfFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const { +void BdfFont::drawChar(Surface *dst, uint32 chr, const int tx, const int ty, const uint32 color) const { assert(dst != 0); // TODO: Where is the relation between the max advance being smaller or diff --git a/graphics/fonts/bdf.h b/graphics/fonts/bdf.h index b0166a2095..b91834785f 100644 --- a/graphics/fonts/bdf.h +++ b/graphics/fonts/bdf.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_FONTS_BDF_H @@ -61,14 +62,14 @@ public: virtual int getFontHeight() const; virtual int getMaxCharWidth() const; - virtual int getCharWidth(byte chr) const; - virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; + virtual int getCharWidth(uint32 chr) const; + virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const; static BdfFont *loadFont(Common::SeekableReadStream &stream); static bool cacheFontData(const BdfFont &font, const Common::String &filename); static BdfFont *loadFromCache(Common::SeekableReadStream &stream); private: - int mapToIndex(byte ch) const; + int mapToIndex(uint32 ch) const; const BdfFontData _data; const DisposeAfterUse::Flag _dispose; diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp index b9e9610d77..09a00672e3 100644 --- a/graphics/fonts/ttf.cpp +++ b/graphics/fonts/ttf.cpp @@ -101,17 +101,17 @@ public: TTFFont(); virtual ~TTFFont(); - bool load(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping); + bool load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping); virtual int getFontHeight() const; virtual int getMaxCharWidth() const; - virtual int getCharWidth(byte chr) const; + virtual int getCharWidth(uint32 chr) const; - virtual int getKerningOffset(byte left, byte right) const; + virtual int getKerningOffset(uint32 left, uint32 right) const; - virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; + virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const; private: bool _initialized; FT_Face _face; @@ -126,21 +126,24 @@ private: Surface image; int xOffset, yOffset; int advance; + FT_UInt slot; }; - bool cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr); - typedef Common::HashMap<byte, Glyph> GlyphCache; - GlyphCache _glyphs; + bool cacheGlyph(Glyph &glyph, uint32 chr) const; + typedef Common::HashMap<uint32, Glyph> GlyphCache; + mutable GlyphCache _glyphs; + bool _allowLateCaching; + void assureCached(uint32 chr) const; - FT_UInt _glyphSlots[256]; - - bool _monochrome; + FT_Int32 _loadFlags; + FT_Render_Mode _renderMode; bool _hasKerning; }; TTFFont::TTFFont() : _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0), - _descent(0), _glyphs(), _glyphSlots(), _monochrome(false), _hasKerning(false) { + _descent(0), _glyphs(), _loadFlags(FT_LOAD_TARGET_NORMAL), _renderMode(FT_RENDER_MODE_NORMAL), + _hasKerning(false), _allowLateCaching(false) { } TTFFont::~TTFFont() { @@ -157,7 +160,7 @@ TTFFont::~TTFFont() { } } -bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) { +bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) { if (!g_ttf.isInitialized()) return false; @@ -202,7 +205,22 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool return false; } - _monochrome = monochrome; + switch (renderMode) { + case kTTFRenderModeNormal: + _loadFlags = FT_LOAD_TARGET_NORMAL; + _renderMode = FT_RENDER_MODE_NORMAL; + break; + + case kTTFRenderModeLight: + _loadFlags = FT_LOAD_TARGET_LIGHT; + _renderMode = FT_RENDER_MODE_LIGHT; + break; + + case kTTFRenderModeMonochrome: + _loadFlags = FT_LOAD_TARGET_MONO; + _renderMode = FT_RENDER_MODE_MONO; + break; + } FT_Fixed yScale = _face->size->metrics.y_scale; _ascent = ftCeil26_6(FT_MulFix(_face->ascender, yScale)); @@ -212,19 +230,26 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool _height = _ascent - _descent + 1; if (!mapping) { + // Allow loading of all unicode characters. + _allowLateCaching = true; + // Load all ISO-8859-1 characters. for (uint i = 0; i < 256; ++i) { - if (!cacheGlyph(_glyphs[i], _glyphSlots[i], i)) - _glyphSlots[i] = 0; + if (!cacheGlyph(_glyphs[i], i)) { + _glyphs.erase(i); + } } } else { + // We have a fixed map of characters do not load more later. + _allowLateCaching = false; + for (uint i = 0; i < 256; ++i) { const uint32 unicode = mapping[i] & 0x7FFFFFFF; const bool isRequired = (mapping[i] & 0x80000000) != 0; // Check whether loading an important glyph fails and error out if // that is the case. - if (!cacheGlyph(_glyphs[i], _glyphSlots[i], unicode)) { - _glyphSlots[i] = 0; + if (!cacheGlyph(_glyphs[i], unicode)) { + _glyphs.erase(i); if (isRequired) return false; } @@ -243,7 +268,8 @@ int TTFFont::getMaxCharWidth() const { return _width; } -int TTFFont::getCharWidth(byte chr) const { +int TTFFont::getCharWidth(uint32 chr) const { + assureCached(chr); GlyphCache::const_iterator glyphEntry = _glyphs.find(chr); if (glyphEntry == _glyphs.end()) return 0; @@ -251,12 +277,29 @@ int TTFFont::getCharWidth(byte chr) const { return glyphEntry->_value.advance; } -int TTFFont::getKerningOffset(byte left, byte right) const { +int TTFFont::getKerningOffset(uint32 left, uint32 right) const { if (!_hasKerning) return 0; - FT_UInt leftGlyph = _glyphSlots[left]; - FT_UInt rightGlyph = _glyphSlots[right]; + assureCached(left); + assureCached(right); + + FT_UInt leftGlyph, rightGlyph; + GlyphCache::const_iterator glyphEntry; + + glyphEntry = _glyphs.find(left); + if (glyphEntry != _glyphs.end()) { + leftGlyph = glyphEntry->_value.slot; + } else { + return 0; + } + + glyphEntry = _glyphs.find(right); + if (glyphEntry != _glyphs.end()) { + rightGlyph = glyphEntry->_value.slot; + } else { + return 0; + } if (!leftGlyph || !rightGlyph) return 0; @@ -304,7 +347,8 @@ void renderGlyph(uint8 *dstPos, const int dstPitch, const uint8 *srcPos, const i } // End of anonymous namespace -void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const { +void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const { + assureCached(chr); GlyphCache::const_iterator glyphEntry = _glyphs.find(chr); if (glyphEntry == _glyphs.end()) return; @@ -376,18 +420,20 @@ void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const } } -bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) { - slot = FT_Get_Char_Index(_face, chr); +bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const { + FT_UInt slot = FT_Get_Char_Index(_face, chr); if (!slot) return false; + glyph.slot = slot; + // We use the light target and render mode to improve the looks of the // glyphs. It is most noticable in FreeSansBold.ttf, where otherwise the // 't' glyph looks like it is cut off on the right side. - if (FT_Load_Glyph(_face, slot, (_monochrome ? FT_LOAD_TARGET_MONO : FT_LOAD_TARGET_LIGHT))) + if (FT_Load_Glyph(_face, slot, _loadFlags)) return false; - if (FT_Render_Glyph(_face->glyph, (_monochrome ? FT_RENDER_MODE_MONO : FT_RENDER_MODE_LIGHT))) + if (FT_Render_Glyph(_face->glyph, _renderMode)) return false; if (_face->glyph->format != FT_GLYPH_FORMAT_BITMAP) @@ -456,16 +502,28 @@ bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) { default: warning("TTFFont::cacheGlyph: Unsupported pixel mode %d", bitmap.pixel_mode); + glyph.image.free(); return false; } return true; } -Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) { +void TTFFont::assureCached(uint32 chr) const { + if (!chr || !_allowLateCaching || _glyphs.contains(chr)) { + return; + } + + Glyph newGlyph; + if (cacheGlyph(newGlyph, chr)) { + _glyphs[chr] = newGlyph; + } +} + +Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) { TTFFont *font = new TTFFont(); - if (!font->load(stream, size, dpi, monochrome, mapping)) { + if (!font->load(stream, size, dpi, renderMode, mapping)) { delete font; return 0; } diff --git a/graphics/fonts/ttf.h b/graphics/fonts/ttf.h index e1464b1f45..bd25b69f21 100644 --- a/graphics/fonts/ttf.h +++ b/graphics/fonts/ttf.h @@ -32,7 +32,46 @@ namespace Graphics { class Font; -Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi = 0, bool monochrome = false, const uint32 *mapping = 0); + +/** + * This specifies the mode in which TTF glyphs are rendered. This, for example, + * allows to render glyphs fully monochrome, i.e. without any anti-aliasing. + */ +enum TTFRenderMode { + /** + * Standard render mode. Equivalent of FreeType2's FT_RENDER_MODE_NORMAL. + */ + kTTFRenderModeNormal, + + /** + * Use lighter hinting. Equivalent of FreeType2's FT_RENDER_MODE_LIGHT. + */ + kTTFRenderModeLight, + + /** + * Render fully monochrome. This makes glyph pixels either be fully opaque + * or fully transparent. + */ + kTTFRenderModeMonochrome +}; + +/** + * Loads a TTF font file from a given data stream object. + * + * @param stream Stream object to load font data from. + * @param size The point size to load. + * @param dpi The dpi to use for size calculations, by default 72dpi + * are used. + * @param renderMode FreeType2 mode used to render glyphs. @see TTFRenderMode + * @param mapping A mapping from code points 0-255 into UTF-32 code points. + * This can be used to support various 8bit character sets. + * In case the msb of the UTF-32 code point is set the font + * loading fails in case no glyph for it is found. When this + * is non-null only characters given in the mapping are + * supported. + * @return 0 in case loading fails, otherwise a pointer to the Font object. + */ +Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0); void shutdownTTF(); diff --git a/graphics/fonts/winfont.cpp b/graphics/fonts/winfont.cpp index 3bad92236d..141fc243e1 100644 --- a/graphics/fonts/winfont.cpp +++ b/graphics/fonts/winfont.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "common/file.h" @@ -200,7 +201,7 @@ char WinFont::indexToCharacter(uint16 index) const { return index + _firstChar; } -uint16 WinFont::characterToIndex(byte character) const { +uint16 WinFont::characterToIndex(uint32 character) const { // Go to the default character if we didn't find a mapping if (character < _firstChar || character > _lastChar) character = _defaultChar; @@ -208,7 +209,7 @@ uint16 WinFont::characterToIndex(byte character) const { return character - _firstChar; } -int WinFont::getCharWidth(byte chr) const { +int WinFont::getCharWidth(uint32 chr) const { return _glyphs[characterToIndex(chr)].charWidth; } @@ -324,7 +325,7 @@ bool WinFont::loadFromFNT(Common::SeekableReadStream &stream) { return true; } -void WinFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const { +void WinFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const { assert(dst); assert(dst->format.bytesPerPixel == 1 || dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4); assert(_glyphs); diff --git a/graphics/fonts/winfont.h b/graphics/fonts/winfont.h index 4382d7ed6b..3354fc2381 100644 --- a/graphics/fonts/winfont.h +++ b/graphics/fonts/winfont.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_WINFONT_H @@ -62,8 +63,8 @@ public: // Font API int getFontHeight() const { return _pixHeight; } int getMaxCharWidth() const { return _maxWidth; } - int getCharWidth(byte chr) const; - void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; + int getCharWidth(uint32 chr) const; + void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const; private: bool loadFromPE(const Common::String &fileName, const WinFontDirEntry &dirEntry); @@ -72,7 +73,7 @@ private: uint32 getFontIndex(Common::SeekableReadStream &stream, const WinFontDirEntry &dirEntry); bool loadFromFNT(Common::SeekableReadStream &stream); char indexToCharacter(uint16 index) const; - uint16 characterToIndex(byte character) const; + uint16 characterToIndex(uint32 character) const; uint16 _pixHeight; uint16 _maxWidth; diff --git a/graphics/maccursor.cpp b/graphics/maccursor.cpp index 8ad6c95961..a66a9104f3 100644 --- a/graphics/maccursor.cpp +++ b/graphics/maccursor.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/maccursor.h b/graphics/maccursor.h index f5efc20655..1ae38f8aa9 100644 --- a/graphics/maccursor.h +++ b/graphics/maccursor.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/module.mk b/graphics/module.mk index 8b63435905..5918775240 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -21,14 +21,7 @@ MODULE_OBJS := \ VectorRenderer.o \ VectorRendererSpec.o \ wincursor.o \ - yuv_to_rgb.o \ - decoders/bmp.o \ - decoders/iff.o \ - decoders/jpeg.o \ - decoders/pcx.o \ - decoders/pict.o \ - decoders/png.o \ - decoders/tga.o + yuv_to_rgb.o ifdef USE_SCALERS MODULE_OBJS += \ diff --git a/graphics/palette.h b/graphics/palette.h index 77891c3fdc..2884bef7f4 100644 --- a/graphics/palette.h +++ b/graphics/palette.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/pixelformat.h b/graphics/pixelformat.h index ca4ef11c17..792833a8e3 100644 --- a/graphics/pixelformat.h +++ b/graphics/pixelformat.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/primitives.cpp b/graphics/primitives.cpp index c140dc8644..564bdb9673 100644 --- a/graphics/primitives.cpp +++ b/graphics/primitives.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "common/util.h" diff --git a/graphics/primitives.h b/graphics/primitives.h index f4a92683ab..a3e8ab1565 100644 --- a/graphics/primitives.h +++ b/graphics/primitives.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_PRIMITIVES_H diff --git a/graphics/scaler.cpp b/graphics/scaler.cpp index 3325fd4db2..745988cbd9 100644 --- a/graphics/scaler.cpp +++ b/graphics/scaler.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler.h b/graphics/scaler.h index 1e5b796631..cf9a98a240 100644 --- a/graphics/scaler.h +++ b/graphics/scaler.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_SCALER_H diff --git a/graphics/scaler/2xsai.cpp b/graphics/scaler/2xsai.cpp index 2afdd9385d..757c1cf8de 100644 --- a/graphics/scaler/2xsai.cpp +++ b/graphics/scaler/2xsai.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/Normal2xARM.s b/graphics/scaler/Normal2xARM.s index e3592295e0..c5684c30e6 100644 --- a/graphics/scaler/Normal2xARM.s +++ b/graphics/scaler/Normal2xARM.s @@ -28,6 +28,7 @@ @ Assumes dst is aligned (so did the C) @ Assumes 16bit (so did the C) + .align 2 Normal2xARM: @ r0 = src @ r1 = srcPitch @@ -92,6 +93,7 @@ thin: @ Assumes dst is aligned (so did the C) @ Assumes 16bit (so did the C) + .align 2 Normal2xAspectMask: @ r0 = src @ r1 = srcPitch diff --git a/graphics/scaler/aspect.cpp b/graphics/scaler/aspect.cpp index 92d6c5777e..b923442163 100644 --- a/graphics/scaler/aspect.cpp +++ b/graphics/scaler/aspect.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/aspect.h b/graphics/scaler/aspect.h index bb354c79ac..30e13c93cd 100644 --- a/graphics/scaler/aspect.h +++ b/graphics/scaler/aspect.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_SCALER_ASPECT_H diff --git a/graphics/scaler/downscaler.cpp b/graphics/scaler/downscaler.cpp index 65400ccd46..3f4f81a228 100644 --- a/graphics/scaler/downscaler.cpp +++ b/graphics/scaler/downscaler.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/downscaler.h b/graphics/scaler/downscaler.h index 97e55dc3d5..ca1137e78b 100644 --- a/graphics/scaler/downscaler.h +++ b/graphics/scaler/downscaler.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/downscalerARM.s b/graphics/scaler/downscalerARM.s index e4662522aa..4c09381457 100644 --- a/graphics/scaler/downscalerARM.s +++ b/graphics/scaler/downscalerARM.s @@ -29,6 +29,7 @@ @ dstPtr. srcPitch and dstPitch identify how to reach subsequent @ lines. redblueMask and round allow for one routine to do both @ 565 and 555 formats. + .align 2 DownscaleAllByHalfARM: @ r0 = srcPtr @ r1 = srcPitch diff --git a/graphics/scaler/hq2x.cpp b/graphics/scaler/hq2x.cpp index 246e8f62d7..74ceebd611 100644 --- a/graphics/scaler/hq2x.cpp +++ b/graphics/scaler/hq2x.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/hq3x.cpp b/graphics/scaler/hq3x.cpp index 7f7867d5a6..f6c86b3017 100644 --- a/graphics/scaler/hq3x.cpp +++ b/graphics/scaler/hq3x.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/intern.h b/graphics/scaler/intern.h index 255cc1a511..0f3f874675 100644 --- a/graphics/scaler/intern.h +++ b/graphics/scaler/intern.h @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/scaler/scale2xARM.s b/graphics/scaler/scale2xARM.s index 563a22eeb1..a56e78447f 100644 --- a/graphics/scaler/scale2xARM.s +++ b/graphics/scaler/scale2xARM.s @@ -37,6 +37,7 @@ @ We hold: r10 B @ r8 r14 r7 D E F @ r12 H + .align 2 scale2x_8_arm: STMFD r13!,{r4-r5,r7-r8,r10-r11,r14} LDR r4, [r13,#4*7] @@ -85,6 +86,7 @@ end8: LDMFD r13!,{r4-r5,r7-r8,r10-r11,PC} + .align 2 scale2x_16_arm: STMFD r13!,{r4-r5,r7-r8,r10-r11,r14} LDR r4, [r13,#4*7] @@ -133,6 +135,7 @@ end16: LDMFD r13!,{r4-r5,r7-r8,r10-r11,PC} + .align 2 scale2x_32_arm: STMFD r13!,{r4-r5,r7-r8,r10-r11,r14} LDR r4, [r13,#4*7] diff --git a/graphics/scaler/thumbnail_intern.cpp b/graphics/scaler/thumbnail_intern.cpp index c30fc3b6fd..65e327f9c2 100644 --- a/graphics/scaler/thumbnail_intern.cpp +++ b/graphics/scaler/thumbnail_intern.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index 33f0e562cb..45cf1cee90 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "common/scummsys.h" @@ -40,31 +41,25 @@ FontSJIS *FontSJIS::createFont(const Common::Platform platform) { // Try the font ROM of the specified platform if (platform == Common::kPlatformFMTowns) { ret = new FontTowns(); - if (ret) { - if (ret->loadData()) - return ret; - } + if (ret->loadData()) + return ret; delete ret; } else if (platform == Common::kPlatformPCEngine) { ret = new FontPCEngine(); - if (ret) { - if (ret->loadData()) - return ret; - } + if (ret->loadData()) + return ret; delete ret; } // TODO: PC98 font rom support /* else if (platform == Common::kPlatformPC98) { ret = new FontPC98(); - if (ret) { - if (ret->loadData()) - return ret; - } + if (ret->loadData()) + return ret; delete ret; }*/ // Try ScummVM's font. ret = new FontSjisSVM(platform); - if (ret && ret->loadData()) + if (ret->loadData()) return ret; delete ret; diff --git a/graphics/sjis.h b/graphics/sjis.h index 928332f712..4c5b2797c5 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -17,6 +17,7 @@ * 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. + * */ // The code in this file is currently only used in KYRA and SCI. diff --git a/graphics/surface.cpp b/graphics/surface.cpp index 777c1058fb..67ed942b0b 100644 --- a/graphics/surface.cpp +++ b/graphics/surface.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "common/algorithm.h" diff --git a/graphics/surface.h b/graphics/surface.h index 07e289b0bb..d083449854 100644 --- a/graphics/surface.h +++ b/graphics/surface.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_SURFACE_H @@ -334,7 +335,9 @@ public: */ struct SharedPtrSurfaceDeleter { void operator()(Surface *ptr) { - ptr->free(); + if (ptr) { + ptr->free(); + } delete ptr; } }; diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index e3f368dffa..802ad09cbb 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -17,6 +17,7 @@ * 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. + * */ #include "graphics/thumbnail.h" diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index c857809c91..cec3d02800 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -17,6 +17,7 @@ * 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 GRAPHICS_THUMBNAIL_H diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp index 1d599f7130..1d96114673 100644 --- a/graphics/wincursor.cpp +++ b/graphics/wincursor.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/graphics/wincursor.h b/graphics/wincursor.h index 9e73e3a12f..2780b23a90 100644 --- a/graphics/wincursor.h +++ b/graphics/wincursor.h @@ -8,12 +8,12 @@ * 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. |