diff options
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/iff.cpp | 313 | ||||
-rw-r--r-- | graphics/iff.h | 139 | ||||
-rw-r--r-- | graphics/ilbm.cpp | 482 | ||||
-rw-r--r-- | graphics/ilbm.h | 165 | ||||
-rw-r--r-- | graphics/module.mk | 1 |
5 files changed, 453 insertions, 647 deletions
diff --git a/graphics/iff.cpp b/graphics/iff.cpp new file mode 100644 index 0000000000..d4595a724c --- /dev/null +++ b/graphics/iff.cpp @@ -0,0 +1,313 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + */ + + +#include "graphics/iff.h" +#include "graphics/surface.h" + + +namespace Common { + +// this really belongs to iff_container.cpp, but we don't want +// to put only this in a source file +char *ID2string(Common::IFF_ID id) { + static char str[] = "abcd"; + + str[0] = (char)(id >> 24 & 0xff); + str[1] = (char)(id >> 16 & 0xff); + str[2] = (char)(id >> 8 & 0xff); + str[3] = (char)(id >> 0 & 0xff); + + return str; +} + +} + + +namespace Graphics { + + +void fillBMHD(BMHD &bitmapHeader, Common::ReadStream &stream) { + + bitmapHeader.width = stream.readUint16BE(); + bitmapHeader.height = stream.readUint16BE(); + bitmapHeader.x = stream.readUint16BE(); + bitmapHeader.y = stream.readUint16BE(); + bitmapHeader.depth = stream.readByte(); + bitmapHeader.masking = stream.readByte(); + bitmapHeader.pack = stream.readByte(); + bitmapHeader.flags = stream.readByte(); + bitmapHeader.transparentColor = stream.readUint16BE(); + bitmapHeader.xAspect = stream.readByte(); + bitmapHeader.yAspect = stream.readByte(); + bitmapHeader.pageWidth = stream.readUint16BE(); + bitmapHeader.pageHeight = stream.readUint16BE(); + +} + + +ILBMDecoder::ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) { + if (_typeId != ID_ILBM) + error("unsupported IFF subtype '%s'", Common::ID2string(_typeId)); +} + +void ILBMDecoder::decode() { + + Common::IFFChunk *chunk; + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_BMHD: + readBMHD(*chunk); + break; + + case ID_CMAP: + readCMAP(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + } + } + + return; +} + +void ILBMDecoder::readBMHD(Common::IFFChunk &chunk) { + + fillBMHD(_bitmapHeader, chunk); + + _colorCount = 1 << _bitmapHeader.depth; + *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); + _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); + +} + +void ILBMDecoder::readCMAP(Common::IFFChunk &chunk) { + if (*_colors == NULL) { + error("wrong input chunk sequence"); + } + for (uint32 i = 0; i < _colorCount; i++) { + (*_colors)[i * 3 + 0] = chunk.readByte(); + (*_colors)[i * 3 + 1] = chunk.readByte(); + (*_colors)[i * 3 + 2] = chunk.readByte(); + } +} + +void ILBMDecoder::readBODY(Common::IFFChunk& chunk) { + + switch (_bitmapHeader.pack) { + case 0: + error("unpacked ILBM files are not supported"); + break; + + case 1: { + uint32 scanWidth = _bitmapHeader.width >> 3; + byte *scan = (byte*)malloc(scanWidth); + byte *out = (byte*)_surface->pixels; + + PackBitsReadStream stream(chunk); + + for (uint32 i = 0; i < _bitmapHeader.height; i++) { + + for (uint32 j = 0; j < _bitmapHeader.depth; j++) { + stream.read(scan, scanWidth); + fillPlane(out, scan, scanWidth, j); + } + + out += _bitmapHeader.width; + } + break; + } + + } +} + +void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) { + + byte src, idx, set; + byte mask = 1 << plane; + + for (uint32 j = 0; j < _bitmapHeader.width; j++) { + src = buf[j >> 3]; + idx = 7 - (j & 7); + set = src & (1 << idx); + + if (set) + out[j] |= mask; + } + +} + + + + +PBMDecoder::PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) { + if (_typeId != ID_PBM) + error("unsupported IFF subtype '%s'", Common::ID2string(_typeId)); +} + +void PBMDecoder::decode() { + + Common::IFFChunk *chunk; + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_BMHD: + readBMHD(*chunk); + break; + + case ID_CMAP: + readCMAP(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + } + } + + return; +} + +void PBMDecoder::readBMHD(Common::IFFChunk &chunk) { + + fillBMHD(_bitmapHeader, chunk); + + _colorCount = 1 << _bitmapHeader.depth; + *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); + _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); + +} + +void PBMDecoder::readCMAP(Common::IFFChunk &chunk) { + if (*_colors == NULL) { + error("wrong input chunk sequence"); + } + for (uint32 i = 0; i < _colorCount; i++) { + (*_colors)[i * 3 + 0] = chunk.readByte(); + (*_colors)[i * 3 + 1] = chunk.readByte(); + (*_colors)[i * 3 + 2] = chunk.readByte(); + } +} + +void PBMDecoder::readBODY(Common::IFFChunk& chunk) { + + uint si = 0; + + switch (_bitmapHeader.pack) { + case 0: + while (!chunk.eos()) { + ((byte*)_surface->pixels)[si++] = chunk.readByte(); + } + break; + + case 1: { + PackBitsReadStream stream(chunk); + stream.read((byte*)_surface->pixels, _surface->w * _surface->h); + break; + } + + } +} + + + + + + +PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input), _wStoragePos(_storage), _rStoragePos(_storage) { +} + +PackBitsReadStream::~PackBitsReadStream() { +} + +bool PackBitsReadStream::eos() const { + return _input->eos() & (_rStoragePos == _wStoragePos); +} + +uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) { + _outSize = (int32)dataSize; + _out = (byte*)dataPtr; + + feed(); + unpack(); + return _fed + _unpacked; +} + +void PackBitsReadStream::store(byte b) { + if (_outSize > 0) { + *_out++ = b; + _unpacked++; + _wStoragePos = _storage; + } else { + assert(_wStoragePos < _storage + 257); + *_wStoragePos++ = b; + } + + _rStoragePos = _storage; + _outSize--; +} + +void PackBitsReadStream::feed() { + _fed = 0; + + int len = MIN(_wStoragePos - _rStoragePos, _outSize); + if (len == 0) return; + + for (int i = 0; i < len; i++) + *_out++ = *_rStoragePos++; + + _fed = len; + _outSize -= len; +} + +void PackBitsReadStream::unpack() { + byte byteRun; + byte idx; + + uint32 i, j; + _unpacked = 0; + + while (_outSize > 0 && !_input->eos()) { + byteRun = _input->readByte(); + if (byteRun <= 127) { + i = byteRun + 1; + for (j = 0; j < i; j++) { + idx = _input->readByte(); + store(idx); + } + } else if (byteRun != 128) { + i = (256 - byteRun) + 1; + idx = _input->readByte(); + for (j = 0; j < i; j++) { + store(idx); + } + } + } +} + + +void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors) { + PBMDecoder decoder(input, surface, colors); + decoder.decode(); +} + +} diff --git a/graphics/iff.h b/graphics/iff.h new file mode 100644 index 0000000000..d716418f8f --- /dev/null +++ b/graphics/iff.h @@ -0,0 +1,139 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + */ + + +#ifndef GRAPHICS_IFF_H +#define GRAPHICS_IFF_H + +#include "common/iff_container.h" + +namespace Graphics { + +class Surface; + + +struct BMHD { + uint16 width, height; + uint16 x, y; + byte depth; + byte masking; + byte pack; + byte flags; + uint16 transparentColor; + byte xAspect, yAspect; + uint16 pageWidth, pageHeight; + + BMHD() { + memset(this, 0, sizeof(*this)); + } +}; + + +// handles ILBM subtype of IFF FORM files +// +class ILBMDecoder : public Common::IFFParser { + +protected: + void readBMHD(Common::IFFChunk &chunk); + void readCMAP(Common::IFFChunk &chunk); + void readBODY(Common::IFFChunk &chunk); + + BMHD _bitmapHeader; + uint32 _colorCount; + + Surface *_surface; + byte **_colors; + + void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane); + +public: + ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors); + virtual ~ILBMDecoder() { } + void decode(); +}; + + +// handles PBM subtype of IFF FORM files +// +class PBMDecoder : public Common::IFFParser { + +protected: + void readBMHD(Common::IFFChunk &chunk); + void readCMAP(Common::IFFChunk &chunk); + void readBODY(Common::IFFChunk &chunk); + + BMHD _bitmapHeader; + uint32 _colorCount; + + Surface *_surface; + byte **_colors; + +public: + PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors); + virtual ~PBMDecoder() { } + void decode(); +}; + +/* + TODO: rename this routine to decodePBM, and update the SAGA code that's + using it. The routine has already been implemented using the above PBMDecoder. +*/ +void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors); + + +/* + PackBits is a RLE compression algorithm introduced + by Apple. It is also used to encode ILBM and PBM + subtypes of IFF files, and some flavours of TIFF. + + The following implementation uses a static storage + and is buffered, that means you can't destroy the + input stream before you are done with it. +*/ +class PackBitsReadStream : public Common::ReadStream { + +protected: + Common::ReadStream *_input; + + byte _storage[257]; + byte *_wStoragePos; + byte *_rStoragePos; + + int32 _outSize; + byte* _out; + int32 _fed; + int32 _unpacked; + + void store(byte b); + void feed(); + void unpack(); + +public: + PackBitsReadStream(Common::ReadStream &input); + ~PackBitsReadStream(); + + virtual bool eos() const; + uint32 read(void *dataPtr, uint32 dataSize); +}; + +} + +#endif diff --git a/graphics/ilbm.cpp b/graphics/ilbm.cpp deleted file mode 100644 index c237dd0f92..0000000000 --- a/graphics/ilbm.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2005-2006 The ScummVM project - * - * 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. - * - * $URL$ - * $Id$ - */ - -#include "common/stdafx.h" -#include "common/endian.h" -#include "common/stream.h" -#include "graphics/surface.h" -#include "graphics/ilbm.h" - -namespace Graphics { - -static char * ID2string(IFF_ID id) { - static char str[] = "abcd"; - - str[0] = (char)(id >> 24 & 0xff); - str[1] = (char)(id >> 16 & 0xff); - str[2] = (char)(id >> 8 & 0xff); - str[3] = (char)(id >> 0 & 0xff); - - return str; -} - -#define ID_FORM MKID_BE('FORM') -/* EA IFF 85 group identifier */ -#define ID_CAT MKID_BE('CAT ') -/* EA IFF 85 group identifier */ -#define ID_LIST MKID_BE('LIST') -/* EA IFF 85 group identifier */ -#define ID_PROP MKID_BE('PROP') -/* EA IFF 85 group identifier */ -#define ID_END MKID_BE('END ') -/* unofficial END-of-FORM identifier (see Amiga RKM Devices Ed.3 -page 376) */ -#define ID_ILBM MKID_BE('ILBM') -/* EA IFF 85 raster bitmap form */ -#define ID_DEEP MKID_BE('DEEP') -/* Chunky pixel image files (Used in TV Paint) */ -#define ID_RGB8 MKID_BE('RGB8') -/* RGB image forms, Turbo Silver (Impulse) */ -#define ID_RGBN MKID_BE('RGBN') -/* RGB image forms, Turbo Silver (Impulse) */ -#define ID_PBM MKID_BE('PBM ') -/* 256-color chunky format (DPaint 2 ?) */ -#define ID_ACBM MKID_BE('ACBM') -/* Amiga Contiguous Bitmap (AmigaBasic) */ - -/* generic */ - -#define ID_FVER MKID_BE('FVER') -/* AmigaOS version string */ -#define ID_JUNK MKID_BE('JUNK') -/* always ignore this chunk */ -#define ID_ANNO MKID_BE('ANNO') -/* EA IFF 85 Generic Annotation chunk */ -#define ID_AUTH MKID_BE('AUTH') -/* EA IFF 85 Generic Author chunk */ -#define ID_CHRS MKID_BE('CHRS') -/* EA IFF 85 Generic character string chunk */ -#define ID_NAME MKID_BE('NAME') -/* EA IFF 85 Generic Name of art, music, etc. chunk */ -#define ID_TEXT MKID_BE('TEXT') -/* EA IFF 85 Generic unformatted ASCII text chunk */ -#define ID_copy MKID_BE('(c) ') -/* EA IFF 85 Generic Copyright text chunk */ - -/* ILBM chunks */ - -#define ID_BMHD MKID_BE('BMHD') -/* ILBM BitmapHeader */ -#define ID_CMAP MKID_BE('CMAP') -/* ILBM 8bit RGB colormap */ -#define ID_GRAB MKID_BE('GRAB') -/* ILBM "hotspot" coordiantes */ -#define ID_DEST MKID_BE('DEST') -/* ILBM destination image info */ -#define ID_SPRT MKID_BE('SPRT') -/* ILBM sprite identifier */ -#define ID_CAMG MKID_BE('CAMG') -/* Amiga viewportmodes */ -#define ID_BODY MKID_BE('BODY') -/* ILBM image data */ -#define ID_CRNG MKID_BE('CRNG') -/* color cycling */ -#define ID_CCRT MKID_BE('CCRT') -/* color cycling */ -#define ID_CLUT MKID_BE('CLUT') -/* Color Lookup Table chunk */ -#define ID_DPI MKID_BE('DPI ') -/* Dots per inch chunk */ -#define ID_DPPV MKID_BE('DPPV') -/* DPaint perspective chunk (EA) */ -#define ID_DRNG MKID_BE('DRNG') -/* DPaint IV enhanced color cycle chunk (EA) */ -#define ID_EPSF MKID_BE('EPSF') -/* Encapsulated Postscript chunk */ -#define ID_CMYK MKID_BE('CMYK') -/* Cyan, Magenta, Yellow, & Black color map (Soft-Logik) */ -#define ID_CNAM MKID_BE('CNAM') -/* Color naming chunk (Soft-Logik) */ -#define ID_PCHG MKID_BE('PCHG') -/* Line by line palette control information (Sebastiano Vigna) */ -#define ID_PRVW MKID_BE('PRVW') -/* A mini duplicate ILBM used for preview (Gary Bonham) */ -#define ID_XBMI MKID_BE('XBMI') -/* eXtended BitMap Information (Soft-Logik) */ -#define ID_CTBL MKID_BE('CTBL') -/* Newtek Dynamic Ham color chunk */ -#define ID_DYCP MKID_BE('DYCP') -/* Newtek Dynamic Ham chunk */ -#define ID_SHAM MKID_BE('SHAM') -/* Sliced HAM color chunk */ -#define ID_ABIT MKID_BE('ABIT') -/* ACBM body chunk */ -#define ID_DCOL MKID_BE('DCOL') -/* unofficial direct color */ -#define ID_DPPS MKID_BE('DPPS') -/* ? */ -#define ID_TINY MKID_BE('TINY') -/* ? */ -#define ID_DPPV MKID_BE('DPPV') -/* ? */ - -void IFFDecoder::readBMHD() { - - _bitmapHeader.width = _chunk.readUint16(); - _bitmapHeader.height = _chunk.readUint16(); - _bitmapHeader.x = _chunk.readUint16(); - _bitmapHeader.y = _chunk.readUint16(); - - _bitmapHeader.depth = _chunk.readByte(); - _bitmapHeader.masking = _chunk.readByte(); - _bitmapHeader.pack = _chunk.readByte(); - _bitmapHeader.flags = _chunk.readByte(); - _bitmapHeader.transparentColor = _chunk.readUint16(); - _bitmapHeader.xAspect = _chunk.readByte(); - _bitmapHeader.yAspect = _chunk.readByte(); - _bitmapHeader.pageWidth = _chunk.readUint16(); - _bitmapHeader.pageHeight = _chunk.readUint16(); - - - _colorCount = 1 << _bitmapHeader.depth; - *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); - _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); - -} - -void IFFDecoder::readCRNG() { -} - -void IFFDecoder::readCMAP() { - if (*_colors == NULL) { - error("wrong input chunk sequence"); - } - for (uint32 i = 0; i < _colorCount; i++) { - (*_colors)[i * 3 + 0] = _chunk.readByte(); - (*_colors)[i * 3 + 1] = _chunk.readByte(); - (*_colors)[i * 3 + 2] = _chunk.readByte(); - } -} - -IFFDecoder::IFFDecoder(Common::ReadStream &input) : _formChunk(&input), _chunk(&input), _colorCount(0) { - _formChunk.readHeader(); - if (_formChunk.id != ID_FORM) { - error("IFFDecoder input is not a FORM type IFF file"); - } -} - -void IFFDecoder::decode(Surface &surface, byte *&colors) { - _surface = &surface; - _colors = &colors; - *_colors = 0; - - if (!isTypeSupported(_formChunk.readUint32())) { - error( "IFFDecoder input is not a valid subtype"); - } - - while (!_formChunk.eos()) { - _formChunk.incBytesRead(8); - _chunk.readHeader(); - - switch (_chunk.id) { - case ID_BMHD: - readBMHD(); - break; - - case ID_CMAP: - readCMAP(); - break; - - case ID_BODY: - readBODY(); - break; - - case ID_CRNG: - readCRNG(); - break; - - case ID_GRAB: case ID_TINY: case ID_DPPS: case ID_DPPV: case ID_CAMG: - break; - - default: - error("unknown chunk : %s\n", ID2string(_chunk.id)); - } - - _chunk.feed(); - _formChunk.incBytesRead(_chunk.size); - } -} - -bool PBMDecoder::isTypeSupported(IFF_ID type) { - return type == ID_PBM; -} - -void PBMDecoder::readBODY() { - byte byteRun; - byte idx; - uint32 si = 0, i, j; - - if (_bitmapHeader.depth > 8) { - error("PBMDecoder depth > 8"); - } - - if ((_bitmapHeader.pack != 0) && (_bitmapHeader.pack != 1)) { - error("PBMDecoder unsupported pack"); - } - - switch (_bitmapHeader.pack) { - case 0: - while (!_chunk.eos()) { - idx = _chunk.readByte(); - ((byte*)_surface->pixels)[si++] = idx; - } - break; - case 1: - while (!_chunk.eos()) { - byteRun = _chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = _chunk.readByte(); - ((byte*)_surface->pixels)[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _chunk.readByte(); - for (j = 0; j < i; j++) { - ((byte*)_surface->pixels)[si++] = idx; - } - } - } - break; - } - -} - - -bool ILBMDecoder::isTypeSupported(IFF_ID type) { - return type == ID_ILBM; -} - -void ILBMDecoder::expandLine(byte *buf, uint32 width) { - - byte byteRun; - byte idx; - - uint32 si = 0, i, j; - - while (si != width) { - byteRun = _chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = _chunk.readByte(); - buf[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _chunk.readByte(); - for (j = 0; j < i; j++) { - buf[si++] = idx; - } - } - } - -} - -void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) { - - byte src, idx, set; - byte mask = 1 << plane; - - for (uint32 j = 0; j < _bitmapHeader.width; j++) { - src = buf[j >> 3]; - idx = 7 - (j & 7); - set = src & (1 << idx); - - if (set) - out[j] |= mask; - } - -} - -void ILBMDecoder::readBODY() { - - if (_bitmapHeader.depth > 8) { - error("ILBMDecoder depth > 8"); - } - - if (_bitmapHeader.pack != 1) { - error("ILBMDecoder unsupported pack"); - } - - if (_bitmapHeader.masking == 1) { - error("ILBMDecoder mask not supported"); - } - - uint32 scanWidth = _bitmapHeader.width >> 3; - byte *scan = (byte*)malloc(scanWidth); - byte *out = (byte*)_surface->pixels; - - switch (_bitmapHeader.pack) { -// case 0: -// while (!_chunk.eos()) { -// idx = _chunk.readByte(); -// ((byte*)_surface->pixels)[si++] = idx; -// } -// break; - case 1: - for (uint32 line = 0; line < _bitmapHeader.height; line++) { - - for (uint32 plane = 0; plane < _bitmapHeader.depth; plane++) { - expandLine(scan, scanWidth); - fillPlane(out, scan, scanWidth, plane); - } - - out += _bitmapHeader.width; - } - break; - } - - free(scan); - -} - -void ILBMDecoder::readCRNG() { - // TODO: implement this. May require changing decode(), too, or adding - // another parameter to ILBMDecoder constructor -} - -ILBMDecoder::ILBMDecoder(Common::ReadStream &input) : IFFDecoder(input) { - -} - -ILBMDecoder::~ILBMDecoder() { - -} - - - -void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors) { - IFF_ID typeId; - BMHD bitmapHeader; - Chunk formChunk(&input); - Chunk chunk(&input); - uint32 colorCount = 0, i, j, si; - byte byteRun; - byte idx; - colors = 0; - si = 0; - - formChunk.readHeader(); - if (formChunk.id != ID_FORM) { - error("decodeILBM() input is not a FORM type IFF file"); - } - - typeId = formChunk.readUint32(); - if (typeId != ID_PBM) { - error( "decodeILBM() input is not an PBM "); - } - - while (!formChunk.eos()) { - formChunk.incBytesRead(8); - chunk.readHeader(); - - switch (chunk.id) { - case ID_BMHD: - bitmapHeader.width = chunk.readUint16(); - bitmapHeader.height = chunk.readUint16(); - bitmapHeader.x = chunk.readUint16(); - bitmapHeader.y = chunk.readUint16(); - - bitmapHeader.depth = chunk.readByte(); - if (bitmapHeader.depth > 8) { - error("decodeILBM() depth > 8"); - } - bitmapHeader.masking = chunk.readByte(); - bitmapHeader.pack = chunk.readByte(); - if ((bitmapHeader.pack != 0) && (bitmapHeader.pack != 1)) { - error("decodeILBM() unsupported pack"); - } - bitmapHeader.flags = chunk.readByte(); - bitmapHeader.transparentColor = chunk.readUint16(); - bitmapHeader.xAspect = chunk.readByte(); - bitmapHeader.yAspect = chunk.readByte(); - bitmapHeader.pageWidth = chunk.readUint16(); - bitmapHeader.pageHeight = chunk.readUint16(); - - - colorCount = 1 << bitmapHeader.depth; - colors = (byte*)malloc(sizeof(*colors) * colorCount * 3); - surface.create(bitmapHeader.width, bitmapHeader.height, 1); - break; - case ID_CMAP: - if (colors == NULL) { - error("wrong input chunk sequence"); - } - for (i = 0; i < colorCount; i++) { - colors[i * 3 + 0] = chunk.readByte(); - colors[i * 3 + 1] = chunk.readByte(); - colors[i * 3 + 2] = chunk.readByte(); - } - break; - - case ID_BODY: - switch (bitmapHeader.pack) { - case 0: - while (!chunk.eos()) { - idx = chunk.readByte(); - ((byte*)surface.pixels)[si++] = idx; - } - break; - case 1: - while (!chunk.eos()) { - byteRun = chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = chunk.readByte(); - ((byte*)surface.pixels)[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = chunk.readByte(); - for (j = 0; j < i; j++) { - ((byte*)surface.pixels)[si++] = idx; - } - } - } - break; - } - break; - case ID_GRAB: case ID_CRNG: case ID_TINY: case ID_DPPS: - break; - default: - error("unknown chunk : %s\n", ID2string(chunk.id)); - } - - chunk.feed(); - formChunk.incBytesRead(chunk.size); - } -} - -} // End of namespace Graphics - diff --git a/graphics/ilbm.h b/graphics/ilbm.h deleted file mode 100644 index 8c50d9fe5e..0000000000 --- a/graphics/ilbm.h +++ /dev/null @@ -1,165 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2002-2006 The ScummVM project - * - * 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. - * - * $URL$ - * $Id$ - */ - -#ifndef GRAPHICS_ILBM_H -#define GRAPHICS_ILBM_H - -namespace Graphics { - -void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors); - -typedef uint32 IFF_ID; - -struct Chunk { - IFF_ID id; - uint32 size; - uint32 bytesRead; - Common::ReadStream *_input; - - Chunk(Common::ReadStream *input): _input(input) { - size = bytesRead = 0; - } - - void incBytesRead(uint32 inc) { - bytesRead += inc; - if (bytesRead > size) { - error("Chunk overead"); - } - } - - void readHeader() { - id = _input->readUint32BE(); - size = _input->readUint32BE(); - bytesRead = 0; - } - - bool eos() { - return (size - bytesRead) == 0; - } - - void feed() { - if (size % 2) { - size++; - } - while (!_input->eos() && !eos()) { - readByte(); - } - } - - byte readByte() { - incBytesRead(1); - return _input->readByte(); - } - - int8 readSByte() { - incBytesRead(1); - return _input->readSByte(); - } - - uint16 readUint16() { - incBytesRead(2); - return _input->readUint16BE(); - } - - uint32 readUint32() { - incBytesRead(4); - return _input->readUint32BE(); - } - - int16 readSint16() { - return (int16)readUint16(); - } - - int32 readSint32() { - return (int32)readUint32(); - } -}; - -struct BMHD { - uint16 width, height; - uint16 x, y; - byte depth; - byte masking; - byte pack; - byte flags; - uint16 transparentColor; - byte xAspect, yAspect; - uint16 pageWidth, pageHeight; - - BMHD() { - memset(this, 0, sizeof(*this)); - } -}; - -class IFFDecoder { -public: - IFFDecoder(Common::ReadStream &input); - virtual ~IFFDecoder() {} - - virtual void decode(Surface &surface, byte *&colors); - -protected: - Chunk _formChunk; - Chunk _chunk; - - IFF_ID _typeId; - BMHD _bitmapHeader; - uint32 _colorCount; - - Surface *_surface; - byte **_colors; - - virtual bool isTypeSupported(IFF_ID type) = 0; - virtual void readBODY() = 0; - - virtual void readBMHD(); - virtual void readCMAP(); - virtual void readCRNG(); -}; - -class PBMDecoder : public IFFDecoder { -public: - PBMDecoder(Common::ReadStream &input) : IFFDecoder(input) {} -protected: - bool isTypeSupported(IFF_ID type); - void readBODY(); -}; - - - -class ILBMDecoder : public IFFDecoder { - -protected: - bool isTypeSupported(IFF_ID type); - void readBODY(); - void readCRNG(); - void expandLine(byte *buf, uint32 width); - void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane); - -public: - ILBMDecoder(Common::ReadStream &input); - ~ILBMDecoder(); -}; - -} // End of namespace Graphics - -#endif - diff --git a/graphics/module.mk b/graphics/module.mk index 44c118668f..84b76154b4 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -9,6 +9,7 @@ MODULE_OBJS := \ fonts/newfont_big.o \ fonts/newfont.o \ fonts/scummfont.o \ + iff.o \ ilbm.o \ imagedec.o \ imageman.o \ |