aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2007-03-25 19:36:24 +0000
committerNicola Mettifogo2007-03-25 19:36:24 +0000
commit4d56036d4d18fa6af1cb3b92fb2ef6fe8a2bfecc (patch)
tree39a3b604f511b3b692eacb096c09d014df2bc962
parent645a9c71d045f3ace8321025f2102cc4f11ace23 (diff)
downloadscummvm-rg350-4d56036d4d18fa6af1cb3b92fb2ef6fe8a2bfecc.tar.gz
scummvm-rg350-4d56036d4d18fa6af1cb3b92fb2ef6fe8a2bfecc.tar.bz2
scummvm-rg350-4d56036d4d18fa6af1cb3b92fb2ef6fe8a2bfecc.zip
Added new base class Graphics::IFFDecoder and subclass Graphics::PBMDecoder as a reimplementation of Graphics::decodeILBM. Old function will be removed when engines are updated.
svn-id: r26302
-rw-r--r--graphics/ilbm.cpp227
-rw-r--r--graphics/ilbm.h127
2 files changed, 273 insertions, 81 deletions
diff --git a/graphics/ilbm.cpp b/graphics/ilbm.cpp
index b44d3799b2..e0c53ac0be 100644
--- a/graphics/ilbm.cpp
+++ b/graphics/ilbm.cpp
@@ -23,75 +23,10 @@
#include "common/endian.h"
#include "common/stream.h"
#include "graphics/surface.h"
+#include "graphics/ilbm.h"
namespace Graphics {
-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();
- }
-};
static char * ID2string(IFF_ID id) {
static char str[] = "abcd";
@@ -105,21 +40,6 @@ static char * ID2string(IFF_ID id) {
}
-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));
- }
-};
-
#define ID_FORM MKID_BE('FORM')
/* EA IFF 85 group identifier */
#define ID_CAT MKID_BE('CAT ')
@@ -219,6 +139,151 @@ page 376) */
/* ? */
+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::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");
+ }
+}
+
+IFFDecoder::~IFFDecoder() {
+}
+
+void IFFDecoder::decode(Surface &surface, byte *&colors) {
+ _surface = &surface;
+ _colors = colors;
+
+ 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:
+ 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;
+ }
+
+}
+
+PBMDecoder::PBMDecoder(Common::ReadStream &input) : IFFDecoder(input) {
+
+}
+
+PBMDecoder::~PBMDecoder() {
+
+}
+
+
+
void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors) {
IFF_ID typeId;
BMHD bitmapHeader;
diff --git a/graphics/ilbm.h b/graphics/ilbm.h
index c95dc3504b..7d1f06767b 100644
--- a/graphics/ilbm.h
+++ b/graphics/ilbm.h
@@ -26,6 +26,133 @@ 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 {
+
+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();
+
+public:
+ IFFDecoder(Common::ReadStream &input);
+ virtual ~IFFDecoder();
+
+ virtual void decode(Surface &surface, byte *&colors);
+
+};
+
+
+
+class PBMDecoder : public IFFDecoder {
+
+protected:
+ bool isTypeSupported(IFF_ID type);
+ void readBody();
+
+public:
+ PBMDecoder(Common::ReadStream &input);
+ ~PBMDecoder();
+
+};
+
} // End of namespace Graphics
#endif