aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-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
4 files changed, 78 insertions, 70 deletions
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