aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/groovie/roq.cpp6
-rw-r--r--engines/mohawk/myst_graphics.cpp17
-rw-r--r--engines/mohawk/myst_graphics.h5
-rw-r--r--graphics/decoders/jpeg.cpp (renamed from graphics/jpeg.cpp)110
-rw-r--r--graphics/decoders/jpeg.h (renamed from graphics/jpeg.h)24
-rw-r--r--graphics/decoders/pict.cpp12
-rw-r--r--graphics/module.mk2
-rw-r--r--video/codecs/mjpeg.cpp25
-rw-r--r--video/codecs/mjpeg.h3
9 files changed, 96 insertions, 108 deletions
diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp
index 53f335ce68..8da8671b5d 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -30,8 +30,8 @@
#include "common/debug.h"
#include "common/textconsole.h"
-#include "graphics/jpeg.h"
#include "graphics/palette.h"
+#include "graphics/decoders/jpeg.h"
#ifdef USE_RGB_COLOR
// Required for the YUV to RGB conversion
@@ -435,8 +435,8 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
warning("Groovie::ROQ: JPEG frame (unfinshed)");
- Graphics::JPEG *jpg = new Graphics::JPEG();
- jpg->read(_file);
+ Graphics::JPEGDecoder *jpg = new Graphics::JPEGDecoder();
+ jpg->loadStream(*_file);
byte *y = (byte *)jpg->getComponent(1)->getBasePtr(0, 0);
byte *u = (byte *)jpg->getComponent(2)->getBasePtr(0, 0);
byte *v = (byte *)jpg->getComponent(3)->getBasePtr(0, 0);
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 86eb4f2b1b..484e49d529 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -28,7 +28,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "engines/util.h"
-#include "graphics/jpeg.h"
+#include "graphics/decoders/jpeg.h"
#include "graphics/decoders/pict.h"
namespace Mohawk {
@@ -49,12 +49,6 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
if (_pixelFormat.bytesPerPixel == 1)
error("Myst requires greater than 256 colors to run");
- if (_vm->getFeatures() & GF_ME) {
- _jpegDecoder = new Graphics::JPEG();
- } else {
- _jpegDecoder = NULL;
- }
-
_pictureFile.entries = NULL;
// Initialize our buffer
@@ -67,7 +61,6 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
MystGraphics::~MystGraphics() {
delete _bmpDecoder;
- delete _jpegDecoder;
delete[] _pictureFile.entries;
_backBuffer->free();
@@ -127,13 +120,13 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
if (_pictureFile.entries[i].id == id) {
if (_pictureFile.entries[i].type == 0) {
- Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
+ Graphics::JPEGDecoder jpeg;
+ Common::SeekableSubReadStream subStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
- if (!_jpegDecoder->read(stream))
+ if (!jpeg.loadStream(subStream))
error("Could not decode Myst ME Mac JPEG");
- mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
- delete stream;
+ mhkSurface = new MohawkSurface(jpeg.getSurface()->convertTo(_pixelFormat));
} else if (_pictureFile.entries[i].type == 1) {
Graphics::PICTDecoder pict;
Common::SeekableSubReadStream subStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
index 8074c9828b..20fd46c5b9 100644
--- a/engines/mohawk/myst_graphics.h
+++ b/engines/mohawk/myst_graphics.h
@@ -27,10 +27,6 @@
#include "common/file.h"
-namespace Graphics {
-class JPEG;
-}
-
namespace Mohawk {
class MystBitmap;
@@ -69,7 +65,6 @@ protected:
private:
MohawkEngine_Myst *_vm;
MystBitmap *_bmpDecoder;
- Graphics::JPEG *_jpegDecoder;
struct PictureFile {
uint32 pictureCount;
diff --git a/graphics/jpeg.cpp b/graphics/decoders/jpeg.cpp
index 53e693a045..0cd2388d52 100644
--- a/graphics/jpeg.cpp
+++ b/graphics/decoders/jpeg.cpp
@@ -21,8 +21,8 @@
*/
#include "graphics/conversion.h"
-#include "graphics/jpeg.h"
#include "graphics/pixelformat.h"
+#include "graphics/decoders/jpeg.h"
#include "common/debug.h"
#include "common/endian.h"
@@ -43,9 +43,9 @@ static const uint8 _zigZagOrder[64] = {
53, 60, 61, 54, 47, 55, 62, 63
};
-JPEG::JPEG() :
+JPEGDecoder::JPEGDecoder() : ImageDecoder(),
_stream(NULL), _w(0), _h(0), _numComp(0), _components(NULL), _numScanComp(0),
- _scanComp(NULL), _currentComp(NULL) {
+ _scanComp(NULL), _currentComp(NULL), _rgbSurface(0) {
// Initialize the quantization tables
for (int i = 0; i < JPEG_MAX_QUANT_TABLES; i++)
@@ -60,42 +60,39 @@ JPEG::JPEG() :
}
}
-JPEG::~JPEG() {
- reset();
+JPEGDecoder::~JPEGDecoder() {
+ destroy();
}
-Surface *JPEG::getSurface(const PixelFormat &format) {
+const Surface *JPEGDecoder::getSurface() const {
// Make sure we have loaded data
if (!isLoaded())
return 0;
- // Only accept >8bpp surfaces
- if (format.bytesPerPixel == 1)
- return 0;
+ if (_rgbSurface)
+ return _rgbSurface;
- // Get our component surfaces
- Graphics::Surface *yComponent = getComponent(1);
- Graphics::Surface *uComponent = getComponent(2);
- Graphics::Surface *vComponent = getComponent(3);
+ // Create an RGBA8888 surface
+ _rgbSurface = new Graphics::Surface();
+ _rgbSurface->create(_w, _h, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
- Graphics::Surface *output = new Graphics::Surface();
- output->create(yComponent->w, yComponent->h, format);
+ // Get our component surfaces
+ const Graphics::Surface *yComponent = getComponent(1);
+ const Graphics::Surface *uComponent = getComponent(2);
+ const Graphics::Surface *vComponent = getComponent(3);
- for (uint16 i = 0; i < output->h; i++) {
- for (uint16 j = 0; j < output->w; j++) {
+ for (uint16 i = 0; i < _h; i++) {
+ for (uint16 j = 0; j < _w; j++) {
byte r = 0, g = 0, b = 0;
- YUV2RGB(*((byte *)yComponent->getBasePtr(j, i)), *((byte *)uComponent->getBasePtr(j, i)), *((byte *)vComponent->getBasePtr(j, i)), r, g, b);
- if (format.bytesPerPixel == 2)
- *((uint16 *)output->getBasePtr(j, i)) = format.RGBToColor(r, g, b);
- else
- *((uint32 *)output->getBasePtr(j, i)) = format.RGBToColor(r, g, b);
+ YUV2RGB(*((const byte *)yComponent->getBasePtr(j, i)), *((const byte *)uComponent->getBasePtr(j, i)), *((const byte *)vComponent->getBasePtr(j, i)), r, g, b);
+ *((uint32 *)_rgbSurface->getBasePtr(j, i)) = _rgbSurface->format.RGBToColor(r, g, b);
}
}
- return output;
+ return _rgbSurface;
}
-void JPEG::reset() {
+void JPEGDecoder::destroy() {
// Reset member variables
_stream = NULL;
_w = _h = 0;
@@ -125,14 +122,19 @@ void JPEG::reset() {
delete[] _huff[i].sizes; _huff[i].sizes = NULL;
delete[] _huff[i].codes; _huff[i].codes = NULL;
}
+
+ if (_rgbSurface) {
+ _rgbSurface->free();
+ delete _rgbSurface;
+ }
}
-bool JPEG::read(Common::SeekableReadStream *stream) {
+bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
// Reset member variables and tables from previous reads
- reset();
+ destroy();
// Save the input stream
- _stream = stream;
+ _stream = &stream;
bool ok = true;
bool done = false;
@@ -211,41 +213,41 @@ bool JPEG::read(Common::SeekableReadStream *stream) {
}
}
}
+
+ _stream = 0;
return ok;
}
-bool JPEG::readJFIF() {
+bool JPEGDecoder::readJFIF() {
uint16 length = _stream->readUint16BE();
uint32 tag = _stream->readUint32BE();
if (tag != MKTAG('J', 'F', 'I', 'F')) {
- warning("JPEG::readJFIF() tag mismatch");
+ warning("JPEGDecoder::readJFIF() tag mismatch");
return false;
}
if (_stream->readByte() != 0) { // NULL
- warning("JPEG::readJFIF() NULL mismatch");
+ warning("JPEGDecoder::readJFIF() NULL mismatch");
return false;
}
byte majorVersion = _stream->readByte();
byte minorVersion = _stream->readByte();
-
- if (majorVersion != 1 || (minorVersion != 1 && minorVersion != 2))
- warning("JPEG::readJFIF() Non-v1.1/1.2 JPEGs may not be handled correctly");
-
- /* byte densityUnits = */ _stream->readByte();
- /* uint16 xDensity = */ _stream->readUint16BE();
- /* uint16 yDensity = */ _stream->readUint16BE();
+ if (majorVersion != 1 || minorVersion != 1)
+ warning("JPEGDecoder::readJFIF() Non-v1.1 JPEGs may not be handled correctly");
+ /* byte densityUnits = */_stream->readByte();
+ /* uint16 xDensity = */_stream->readUint16BE();
+ /* uint16 yDensity = */_stream->readUint16BE();
byte thumbW = _stream->readByte();
byte thumbH = _stream->readByte();
_stream->seek(thumbW * thumbH * 3, SEEK_CUR); // Ignore thumbnail
if (length != (thumbW * thumbH * 3) + 16) {
- warning("JPEG::readJFIF() length mismatch");
+ warning("JPEGDecoder::readJFIF() length mismatch");
return false;
}
return true;
}
// Marker 0xC0 (Start Of Frame, Baseline DCT)
-bool JPEG::readSOF0() {
+bool JPEGDecoder::readSOF0() {
debug(5, "JPEG: readSOF0");
uint16 size = _stream->readUint16BE();
@@ -284,7 +286,7 @@ bool JPEG::readSOF0() {
}
// Marker 0xC4 (Define Huffman Tables)
-bool JPEG::readDHT() {
+bool JPEGDecoder::readDHT() {
debug(5, "JPEG: readDHT");
uint16 size = _stream->readUint16BE() - 2;
uint32 pos = _stream->pos();
@@ -346,7 +348,7 @@ bool JPEG::readDHT() {
}
// Marker 0xDA (Start Of Scan)
-bool JPEG::readSOS() {
+bool JPEGDecoder::readSOS() {
debug(5, "JPEG: readSOS");
uint16 size = _stream->readUint16BE();
@@ -473,7 +475,7 @@ bool JPEG::readSOS() {
}
// Marker 0xDB (Define Quantization Tables)
-bool JPEG::readDQT() {
+bool JPEGDecoder::readDQT() {
debug(5, "JPEG: readDQT");
uint16 size = _stream->readUint16BE() - 2;
uint32 pos = _stream->pos();
@@ -503,7 +505,7 @@ bool JPEG::readDQT() {
}
// Marker 0xDD (Define Restart Interval)
-bool JPEG::readDRI() {
+bool JPEGDecoder::readDRI() {
debug(5, "JPEG: readDRI");
uint16 size = _stream->readUint16BE() - 2;
@@ -517,7 +519,7 @@ bool JPEG::readDRI() {
return true;
}
-bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
+bool JPEGDecoder::readMCU(uint16 xMCU, uint16 yMCU) {
bool ok = true;
for (int c = 0; ok && (c < _numComp); c++) {
// Set the current component
@@ -549,7 +551,7 @@ bool JPEG::readMCU(uint16 xMCU, uint16 yMCU) {
xb = (n - (k2 + k1) * p) >> sh;
// IDCT based on public domain code from http://halicery.com/jpeg/idct.html
-void JPEG::idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half) {
+void JPEGDecoder::idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half) {
int p, n;
src[0] <<= 9;
@@ -578,7 +580,7 @@ void JPEG::idct1D8x8(int32 src[8], int32 dest[64], int32 ps, int32 half) {
dest[7 * 8] = (src[0] - src[1]) >> ps;
}
-void JPEG::idct2D8x8(int32 block[64]) {
+void JPEGDecoder::idct2D8x8(int32 block[64]) {
int32 tmp[64];
// Apply 1D IDCT to rows
@@ -590,7 +592,7 @@ void JPEG::idct2D8x8(int32 block[64]) {
idct1D8x8(&tmp[i * 8], &block[i], 12, 1 << 11);
}
-bool JPEG::readDataUnit(uint16 x, uint16 y) {
+bool JPEGDecoder::readDataUnit(uint16 x, uint16 y) {
// Prepare an empty data array
int16 readData[64];
for (int i = 1; i < 64; i++)
@@ -654,7 +656,7 @@ bool JPEG::readDataUnit(uint16 x, uint16 y) {
return true;
}
-int16 JPEG::readDC() {
+int16 JPEGDecoder::readDC() {
// DC is type 0
uint8 tableNum = _currentComp->DCentropyTableSelector << 1;
@@ -665,7 +667,7 @@ int16 JPEG::readDC() {
return readSignedBits(numBits);
}
-void JPEG::readAC(int16 *out) {
+void JPEGDecoder::readAC(int16 *out) {
// AC is type 1
uint8 tableNum = (_currentComp->ACentropyTableSelector << 1) + 1;
@@ -695,7 +697,7 @@ void JPEG::readAC(int16 *out) {
}
}
-int16 JPEG::readSignedBits(uint8 numBits) {
+int16 JPEGDecoder::readSignedBits(uint8 numBits) {
uint16 ret = 0;
if (numBits > 16)
error("requested %d bits", numBits); //XXX
@@ -713,7 +715,7 @@ int16 JPEG::readSignedBits(uint8 numBits) {
}
// TODO: optimize?
-uint8 JPEG::readHuff(uint8 table) {
+uint8 JPEGDecoder::readHuff(uint8 table) {
bool foundCode = false;
uint8 val = 0;
@@ -743,7 +745,7 @@ uint8 JPEG::readHuff(uint8 table) {
return val;
}
-uint8 JPEG::readBit() {
+uint8 JPEGDecoder::readBit() {
// Read a whole byte if necessary
if (_bitsNumber == 0) {
_bitsData = _stream->readByte();
@@ -773,12 +775,12 @@ uint8 JPEG::readBit() {
return (_bitsData & (1 << _bitsNumber)) ? 1 : 0;
}
-Surface *JPEG::getComponent(uint c) {
+const Surface *JPEGDecoder::getComponent(uint c) const {
for (int i = 0; i < _numComp; i++)
if (_components[i].id == c) // We found the desired component
return &_components[i].surface;
- error("JPEG::getComponent: No component %d present", c);
+ error("JPEGDecoder::getComponent: No component %d present", c);
return NULL;
}
diff --git a/graphics/jpeg.h b/graphics/decoders/jpeg.h
index b87791470f..c566d5ad21 100644
--- a/graphics/jpeg.h
+++ b/graphics/decoders/jpeg.h
@@ -24,6 +24,7 @@
#define GRAPHICS_JPEG_H
#include "graphics/surface.h"
+#include "graphics/decoders/image_decoder.h"
namespace Common {
class SeekableReadStream;
@@ -36,26 +37,31 @@ struct PixelFormat;
#define JPEG_MAX_QUANT_TABLES 4
#define JPEG_MAX_HUFF_TABLES 2
-class JPEG {
+class JPEGDecoder : public ImageDecoder {
public:
- JPEG();
- ~JPEG();
+ JPEGDecoder();
+ ~JPEGDecoder();
+
+ // ImageDecoder API
+ void destroy();
+ bool loadStream(Common::SeekableReadStream &str);
+ const Surface *getSurface() const;
- bool read(Common::SeekableReadStream *str);
bool isLoaded() const { return _numComp && _w && _h; }
uint16 getWidth() const { return _w; }
uint16 getHeight() const { return _h; }
-
- Surface *getComponent(uint c);
- Surface *getSurface(const PixelFormat &format);
+ const Surface *getComponent(uint c) const;
private:
- void reset();
-
Common::SeekableReadStream *_stream;
uint16 _w, _h;
uint16 _restartInterval;
+ // mutable so that we can convert to RGB only during
+ // a getSurface() call while still upholding the
+ // const requirement in other ImageDecoders
+ mutable Graphics::Surface *_rgbSurface;
+
// Image components
uint8 _numComp;
struct Component {
diff --git a/graphics/decoders/pict.cpp b/graphics/decoders/pict.cpp
index 9b28f4352e..f8b2553ea0 100644
--- a/graphics/decoders/pict.cpp
+++ b/graphics/decoders/pict.cpp
@@ -27,7 +27,7 @@
#include "common/textconsole.h"
#include "graphics/surface.h"
-#include "graphics/jpeg.h"
+#include "graphics/decoders/jpeg.h"
#include "graphics/decoders/pict.h"
namespace Graphics {
@@ -512,20 +512,20 @@ void PICTDecoder::skipBitsRect(Common::SeekableReadStream &stream, bool hasPalet
// 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) {
- JPEG jpeg;
+ JPEGDecoder jpeg;
uint32 dataSize = stream.readUint32BE();
uint32 startPos = stream.pos();
- Common::SeekableReadStream *jpegStream = new Common::SeekableSubReadStream(&stream, stream.pos() + 156, stream.pos() + dataSize);
+ Common::SeekableSubReadStream jpegStream(&stream, stream.pos() + 156, stream.pos() + dataSize);
- if (!jpeg.read(jpegStream))
+ if (!jpeg.loadStream(jpegStream))
error("PICTDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
- _outputSurface = jpeg.getSurface(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+ _outputSurface = new Graphics::Surface();
+ _outputSurface->copyFrom(*jpeg.getSurface());
stream.seek(startPos + dataSize);
- delete jpegStream;
}
} // End of namespace Graphics
diff --git a/graphics/module.mk b/graphics/module.mk
index 08f6d0b1ec..d9f3802a68 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -12,7 +12,6 @@ MODULE_OBJS := \
fonts/ttf.o \
fonts/winfont.o \
iff.o \
- jpeg.o \
maccursor.o \
png.o \
primitives.o \
@@ -26,6 +25,7 @@ MODULE_OBJS := \
wincursor.o \
yuv_to_rgb.o \
decoders/bmp.o \
+ decoders/jpeg.o \
decoders/pict.o
ifdef USE_SCALERS
diff --git a/video/codecs/mjpeg.cpp b/video/codecs/mjpeg.cpp
index 248a80d714..10fd9d7c50 100644
--- a/video/codecs/mjpeg.cpp
+++ b/video/codecs/mjpeg.cpp
@@ -22,8 +22,8 @@
#include "common/system.h"
#include "common/textconsole.h"
-#include "graphics/jpeg.h"
#include "graphics/surface.h"
+#include "graphics/decoders/jpeg.h"
#include "video/codecs/mjpeg.h"
@@ -34,38 +34,31 @@ class SeekableReadStream;
namespace Video {
JPEGDecoder::JPEGDecoder() : Codec() {
- _jpeg = new Graphics::JPEG();
_pixelFormat = g_system->getScreenFormat();
_surface = NULL;
}
JPEGDecoder::~JPEGDecoder() {
- delete _jpeg;
-
if (_surface) {
_surface->free();
delete _surface;
}
}
-const Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream* stream) {
- if (!_jpeg->read(stream)) {
+const Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
+ Graphics::JPEGDecoder jpeg;
+
+ if (!jpeg.loadStream(*stream)) {
warning("Failed to decode JPEG frame");
return 0;
}
- if (!_surface) {
- _surface = new Graphics::Surface();
- _surface->create(_jpeg->getWidth(), _jpeg->getHeight(), _pixelFormat);
+ if (_surface) {
+ _surface->free();
+ delete _surface;
}
- Graphics::Surface *frame = _jpeg->getSurface(_pixelFormat);
- assert(frame);
-
- _surface->copyFrom(*frame);
-
- frame->free();
- delete frame;
+ _surface = jpeg.getSurface()->convertTo(_pixelFormat);
return _surface;
}
diff --git a/video/codecs/mjpeg.h b/video/codecs/mjpeg.h
index 45cb57dea2..0c3b668a74 100644
--- a/video/codecs/mjpeg.h
+++ b/video/codecs/mjpeg.h
@@ -31,7 +31,7 @@ class SeekableReadStream;
}
namespace Graphics {
-class JPEG;
+struct Surface;
}
namespace Video {
@@ -50,7 +50,6 @@ public:
private:
Graphics::PixelFormat _pixelFormat;
- Graphics::JPEG *_jpeg;
Graphics::Surface *_surface;
};