GRAPHICS: Add a getSurface() function to JPEG to automatically convert to RGB
svn-id: r55301
This commit is contained in:
parent
5da1718beb
commit
503fdb6147
6 changed files with 69 additions and 40 deletions
|
@ -30,9 +30,8 @@
|
||||||
#include "mohawk/livingbooks.h"
|
#include "mohawk/livingbooks.h"
|
||||||
|
|
||||||
#include "common/substream.h"
|
#include "common/substream.h"
|
||||||
|
|
||||||
#include "engines/util.h"
|
#include "engines/util.h"
|
||||||
|
#include "graphics/jpeg.h"
|
||||||
#include "graphics/primitives.h"
|
#include "graphics/primitives.h"
|
||||||
#include "gui/message.h"
|
#include "gui/message.h"
|
||||||
|
|
||||||
|
@ -253,7 +252,7 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
|
||||||
error("Myst requires greater than 256 colors to run");
|
error("Myst requires greater than 256 colors to run");
|
||||||
|
|
||||||
if (_vm->getFeatures() & GF_ME) {
|
if (_vm->getFeatures() & GF_ME) {
|
||||||
_jpegDecoder = new Graphics::JPEGDecoder();
|
_jpegDecoder = new Graphics::JPEG();
|
||||||
_pictDecoder = new Graphics::PictDecoder(_pixelFormat);
|
_pictDecoder = new Graphics::PictDecoder(_pixelFormat);
|
||||||
} else {
|
} else {
|
||||||
_jpegDecoder = NULL;
|
_jpegDecoder = NULL;
|
||||||
|
@ -327,9 +326,13 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
|
||||||
for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
|
for (uint32 i = 0; i < _pictureFile.pictureCount; i++)
|
||||||
if (_pictureFile.entries[i].id == id) {
|
if (_pictureFile.entries[i].id == id) {
|
||||||
if (_pictureFile.entries[i].type == 0) {
|
if (_pictureFile.entries[i].type == 0) {
|
||||||
Graphics::Surface *surface = new Graphics::Surface();
|
Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
|
||||||
surface->copyFrom(*_jpegDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
|
|
||||||
mhkSurface = new MohawkSurface(surface);
|
if (!_jpegDecoder->read(stream))
|
||||||
|
error("Could not decode Myst ME Mac JPEG");
|
||||||
|
|
||||||
|
mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
|
||||||
|
delete stream;
|
||||||
} else if (_pictureFile.entries[i].type == 1) {
|
} else if (_pictureFile.entries[i].type == 1) {
|
||||||
mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
|
mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -31,7 +31,12 @@
|
||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
#include "common/hashmap.h"
|
#include "common/hashmap.h"
|
||||||
#include "graphics/pict.h"
|
#include "graphics/pict.h"
|
||||||
#include "graphics/video/codecs/mjpeg.h"
|
|
||||||
|
namespace Graphics {
|
||||||
|
|
||||||
|
class JPEG;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace Mohawk {
|
namespace Mohawk {
|
||||||
|
|
||||||
|
@ -132,7 +137,7 @@ private:
|
||||||
MohawkEngine_Myst *_vm;
|
MohawkEngine_Myst *_vm;
|
||||||
MystBitmap *_bmpDecoder;
|
MystBitmap *_bmpDecoder;
|
||||||
Graphics::PictDecoder *_pictDecoder;
|
Graphics::PictDecoder *_pictDecoder;
|
||||||
Graphics::JPEGDecoder *_jpegDecoder;
|
Graphics::JPEG *_jpegDecoder;
|
||||||
|
|
||||||
struct PictureFile {
|
struct PictureFile {
|
||||||
uint32 pictureCount;
|
uint32 pictureCount;
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "graphics/conversion.h"
|
||||||
#include "graphics/jpeg.h"
|
#include "graphics/jpeg.h"
|
||||||
|
#include "graphics/pixelformat.h"
|
||||||
|
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
@ -73,6 +75,37 @@ JPEG::~JPEG() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Surface *JPEG::getSurface(const PixelFormat &format) {
|
||||||
|
// Make sure we have loaded data
|
||||||
|
if (!isLoaded())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Only accept >8bpp surfaces
|
||||||
|
if (format.bytesPerPixel == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Get our component surfaces
|
||||||
|
Graphics::Surface *yComponent = getComponent(1);
|
||||||
|
Graphics::Surface *uComponent = getComponent(2);
|
||||||
|
Graphics::Surface *vComponent = getComponent(3);
|
||||||
|
|
||||||
|
Graphics::Surface *output = new Graphics::Surface();
|
||||||
|
output->create(yComponent->w, yComponent->h, format.bytesPerPixel);
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < output->h; i++) {
|
||||||
|
for (uint16 j = 0; j < output->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void JPEG::reset() {
|
void JPEG::reset() {
|
||||||
// Reset member variables
|
// Reset member variables
|
||||||
_str = NULL;
|
_str = NULL;
|
||||||
|
|
|
@ -34,6 +34,8 @@ class SeekableReadStream;
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
|
struct PixelFormat;
|
||||||
|
|
||||||
#define JPEG_MAX_QUANT_TABLES 4
|
#define JPEG_MAX_QUANT_TABLES 4
|
||||||
#define JPEG_MAX_HUFF_TABLES 2
|
#define JPEG_MAX_HUFF_TABLES 2
|
||||||
|
|
||||||
|
@ -43,7 +45,12 @@ public:
|
||||||
~JPEG();
|
~JPEG();
|
||||||
|
|
||||||
bool read(Common::SeekableReadStream *str);
|
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 *getComponent(uint c);
|
||||||
|
Surface *getSurface(const PixelFormat &format);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -334,23 +334,7 @@ void PictDecoder::decodeCompressedQuickTime(Common::SeekableReadStream *stream)
|
||||||
if (!_jpeg->read(jpegStream))
|
if (!_jpeg->read(jpegStream))
|
||||||
error("PictDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
|
error("PictDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
|
||||||
|
|
||||||
Surface *yComponent = _jpeg->getComponent(1);
|
_outputSurface = _jpeg->getSurface(_pixelFormat);
|
||||||
Surface *uComponent = _jpeg->getComponent(2);
|
|
||||||
Surface *vComponent = _jpeg->getComponent(3);
|
|
||||||
|
|
||||||
_outputSurface = new Graphics::Surface();
|
|
||||||
_outputSurface->create(yComponent->w, yComponent->h, _pixelFormat.bytesPerPixel);
|
|
||||||
|
|
||||||
for (uint16 i = 0; i < _outputSurface->h; i++) {
|
|
||||||
for (uint16 j = 0; j < _outputSurface->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 (_pixelFormat.bytesPerPixel == 2)
|
|
||||||
*((uint16 *)_outputSurface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
|
|
||||||
else
|
|
||||||
*((uint32 *)_outputSurface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->seek(startPos + dataSize);
|
stream->seek(startPos + dataSize);
|
||||||
delete jpegStream;
|
delete jpegStream;
|
||||||
|
|
|
@ -46,26 +46,23 @@ JPEGDecoder::~JPEGDecoder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream* stream) {
|
const Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream* stream) {
|
||||||
_jpeg->read(stream);
|
if (!_jpeg->read(stream)) {
|
||||||
Surface *ySurface = _jpeg->getComponent(1);
|
warning("Failed to decode JPEG frame");
|
||||||
Surface *uSurface = _jpeg->getComponent(2);
|
return 0;
|
||||||
Surface *vSurface = _jpeg->getComponent(3);
|
}
|
||||||
|
|
||||||
if (!_surface) {
|
if (!_surface) {
|
||||||
_surface = new Surface();
|
_surface = new Surface();
|
||||||
_surface->create(ySurface->w, ySurface->h, _pixelFormat.bytesPerPixel);
|
_surface->create(_jpeg->getWidth(), _jpeg->getHeight(), _pixelFormat.bytesPerPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16 i = 0; i < _surface->h; i++) {
|
Graphics::Surface *frame = _jpeg->getSurface(_pixelFormat);
|
||||||
for (uint16 j = 0; j < _surface->w; j++) {
|
assert(frame);
|
||||||
byte r = 0, g = 0, b = 0;
|
|
||||||
YUV2RGB(*((byte *)ySurface->getBasePtr(j, i)), *((byte *)uSurface->getBasePtr(j, i)), *((byte *)vSurface->getBasePtr(j, i)), r, g, b);
|
_surface->copyFrom(*frame);
|
||||||
if (_pixelFormat.bytesPerPixel == 2)
|
|
||||||
*((uint16 *)_surface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
|
frame->free();
|
||||||
else
|
delete frame;
|
||||||
*((uint32 *)_surface->getBasePtr(j, i)) = _pixelFormat.RGBToColor(r, g, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue