diff options
author | Johannes Schickel | 2012-07-14 03:07:48 +0200 |
---|---|---|
committer | Johannes Schickel | 2012-07-14 03:07:48 +0200 |
commit | f1a1938253cb6f0fb5db77627eed2cff0734d371 (patch) | |
tree | baf1bf1c501f58fdabc347e8862f2a0349da4493 /graphics | |
parent | 856f9326179e186f08abc0163039f51ad31e9afb (diff) | |
download | scummvm-rg350-f1a1938253cb6f0fb5db77627eed2cff0734d371.tar.gz scummvm-rg350-f1a1938253cb6f0fb5db77627eed2cff0734d371.tar.bz2 scummvm-rg350-f1a1938253cb6f0fb5db77627eed2cff0734d371.zip |
GRAPHICS: Serialize PixelFormat for thumbnails and allow 4Bpp surfaces.
This allows any 2Bpp/4Bpp Surfaces to be written via saveThumbnail
and loadThumbnail now. It furthermore will preserve the loaded Surface
in loadThumbnail.
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/thumbnail.cpp | 96 | ||||
-rw-r--r-- | graphics/thumbnail.h | 2 |
2 files changed, 73 insertions, 25 deletions
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index db61d828d2..ddb377306d 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -30,17 +30,17 @@ namespace Graphics { namespace { -#define THMB_VERSION 1 +#define THMB_VERSION 2 struct ThumbnailHeader { uint32 type; uint32 size; byte version; uint16 width, height; - byte bpp; + PixelFormat format; }; -#define ThumbnailHeaderSize (4+4+1+2+2+1) +#define ThumbnailHeaderSize (4+4+1+2+2+(1+4+4)) bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool outputWarnings) { header.type = in.readUint32BE(); @@ -64,7 +64,22 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou header.width = in.readUint16BE(); header.height = in.readUint16BE(); - header.bpp = in.readByte(); + header.format.bytesPerPixel = in.readByte(); + // Starting from version 2 on we serialize the whole PixelFormat. + if (header.version >= 2) { + header.format.rLoss = in.readByte(); + header.format.gLoss = in.readByte(); + header.format.bLoss = in.readByte(); + header.format.aLoss = in.readByte(); + + header.format.rShift = in.readByte(); + header.format.gShift = in.readByte(); + header.format.bShift = in.readByte(); + header.format.aShift = in.readByte(); + } else { + // Version 1 used a hardcoded RGB565. + header.format = createPixelFormat<565>(); + } return true; } @@ -100,23 +115,32 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { if (!loadHeader(in, header, true)) return 0; - if (header.bpp != 2) { - warning("trying to load thumbnail with unsupported bit depth %d", header.bpp); + if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) { + warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel); return 0; } - Graphics::PixelFormat format = g_system->getOverlayFormat(); Graphics::Surface *const to = new Graphics::Surface(); - to->create(header.width, header.height, format); + to->create(header.width, header.height, header.format); - OverlayColor *pixels = (OverlayColor *)to->pixels; for (int y = 0; y < to->h; ++y) { - for (int x = 0; x < to->w; ++x) { - uint8 r, g, b; - colorToRGB<ColorMasks<565> >(in.readUint16BE(), r, g, b); - - // converting to current OSystem Color - *pixels++ = format.RGBToColor(r, g, b); + switch (header.format.bytesPerPixel) { + case 2: { + uint16 *pixels = (uint16 *)to->getBasePtr(0, y); + for (uint x = 0; x < to->w; ++x) { + *pixels++ = in.readUint16BE(); + } + } break; + + case 4: { + uint32 *pixels = (uint32 *)to->getBasePtr(0, y); + for (uint x = 0; x < to->w; ++x) { + *pixels++ = in.readUint32BE(); + } + } break; + + default: + assert(0); } } @@ -138,8 +162,8 @@ bool saveThumbnail(Common::WriteStream &out) { } bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb) { - if (thumb.format.bytesPerPixel != 2) { - warning("trying to save thumbnail with bpp different than 2"); + if (thumb.format.bytesPerPixel != 2 && thumb.format.bytesPerPixel != 4) { + warning("trying to save thumbnail with bpp %u", thumb.format.bytesPerPixel); return false; } @@ -149,19 +173,45 @@ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb) { header.version = THMB_VERSION; header.width = thumb.w; header.height = thumb.h; - header.bpp = thumb.format.bytesPerPixel; out.writeUint32BE(header.type); out.writeUint32BE(header.size); out.writeByte(header.version); out.writeUint16BE(header.width); out.writeUint16BE(header.height); - out.writeByte(header.bpp); - // TODO: for later this shouldn't be casted to uint16... - uint16 *pixels = (uint16 *)thumb.pixels; - for (uint16 p = 0; p < thumb.w*thumb.h; ++p, ++pixels) - out.writeUint16BE(*pixels); + // Serialize the PixelFormat + out.writeByte(thumb.format.bytesPerPixel); + out.writeByte(thumb.format.rLoss); + out.writeByte(thumb.format.gLoss); + out.writeByte(thumb.format.bLoss); + out.writeByte(thumb.format.aLoss); + out.writeByte(thumb.format.rShift); + out.writeByte(thumb.format.gShift); + out.writeByte(thumb.format.bShift); + out.writeByte(thumb.format.aShift); + + // Serialize the pixel data + for (uint y = 0; y < thumb.h; ++y) { + switch (thumb.format.bytesPerPixel) { + case 2: { + const uint16 *pixels = (const uint16 *)thumb.getBasePtr(0, y); + for (uint x = 0; x < thumb.w; ++x) { + out.writeUint16BE(*pixels++); + } + } break; + + case 4: { + const uint32 *pixels = (const uint32 *)thumb.getBasePtr(0, y); + for (uint x = 0; x < thumb.w; ++x) { + out.writeUint32BE(*pixels++); + } + } break; + + default: + assert(0); + } + } return true; } diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index df99568f42..45a0fdbf07 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -50,8 +50,6 @@ bool skipThumbnail(Common::SeekableReadStream &in); /** * Loads a thumbnail from the given input stream. - * The loaded thumbnail will be automatically converted to the - * current overlay pixelformat. */ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in); |