diff options
Diffstat (limited to 'graphics/decoders/jpeg.cpp')
-rw-r--r-- | graphics/decoders/jpeg.cpp | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/graphics/decoders/jpeg.cpp b/graphics/decoders/jpeg.cpp deleted file mode 100644 index c858884095..0000000000 --- a/graphics/decoders/jpeg.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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. - * - */ - -// libjpeg uses forbidden symbols in its header. Thus, we need to allow them -// here. -#define FORBIDDEN_SYMBOL_ALLOW_ALL - -#include "graphics/pixelformat.h" -#include "graphics/decoders/jpeg.h" - -#include "common/debug.h" -#include "common/endian.h" -#include "common/stream.h" -#include "common/textconsole.h" - -#ifdef USE_JPEG -// The original release of libjpeg v6b did not contain any extern "C" in case -// its header files are included in a C++ environment. To avoid any linking -// issues we need to add it on our own. -extern "C" { -#include <jpeglib.h> -#include <jerror.h> -} -#endif - -namespace Graphics { - -JPEGDecoder::JPEGDecoder() : ImageDecoder(), _surface(), _colorSpace(kColorSpaceRGBA) { -} - -JPEGDecoder::~JPEGDecoder() { - destroy(); -} - -const Surface *JPEGDecoder::getSurface() const { - return &_surface; -} - -void JPEGDecoder::destroy() { - _surface.free(); -} - -#ifdef USE_JPEG -namespace { - -#define JPEG_BUFFER_SIZE 4096 - -struct StreamSource : public jpeg_source_mgr { - Common::SeekableReadStream *stream; - bool startOfFile; - JOCTET buffer[JPEG_BUFFER_SIZE]; -}; - -void initSource(j_decompress_ptr cinfo) { - StreamSource *source = (StreamSource *)cinfo->src; - source->startOfFile = true; -} - -boolean fillInputBuffer(j_decompress_ptr cinfo) { - StreamSource *source = (StreamSource *)cinfo->src; - - uint32 bufferSize = source->stream->read((byte *)source->buffer, sizeof(source->buffer)); - if (bufferSize == 0) { - if (source->startOfFile) { - // An empty file is a fatal error - ERREXIT(cinfo, JERR_INPUT_EMPTY); - } else { - // Otherwise we insert an EOF marker - WARNMS(cinfo, JWRN_JPEG_EOF); - source->buffer[0] = (JOCTET)0xFF; - source->buffer[1] = (JOCTET)JPEG_EOI; - bufferSize = 2; - } - } - - source->next_input_byte = source->buffer; - source->bytes_in_buffer = bufferSize; - source->startOfFile = false; - - return TRUE; -} - -void skipInputData(j_decompress_ptr cinfo, long numBytes) { - StreamSource *source = (StreamSource *)cinfo->src; - - if (numBytes > 0) { - if (numBytes > (long)source->bytes_in_buffer) { - // In case we need to skip more bytes than there are in the buffer - // we will skip the remaining data and fill the buffer again - numBytes -= (long)source->bytes_in_buffer; - - // Skip the remaining bytes - source->stream->skip(numBytes); - - // Fill up the buffer again - (*source->fill_input_buffer)(cinfo); - } else { - source->next_input_byte += (size_t)numBytes; - source->bytes_in_buffer -= (size_t)numBytes; - } - - } -} - -void termSource(j_decompress_ptr cinfo) { -} - -void jpeg_scummvm_src(j_decompress_ptr cinfo, Common::SeekableReadStream *stream) { - StreamSource *source; - - // Initialize the source in case it has not been done yet. - if (cinfo->src == NULL) { - cinfo->src = (jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(StreamSource)); - } - - source = (StreamSource *)cinfo->src; - source->init_source = &initSource; - source->fill_input_buffer = &fillInputBuffer; - source->skip_input_data = &skipInputData; - source->resync_to_restart = &jpeg_resync_to_restart; - source->term_source = &termSource; - source->bytes_in_buffer = 0; - source->next_input_byte = NULL; - - source->stream = stream; -} - -void errorExit(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - // This function is not allowed to return to the caller, thus we simply - // error out with our error handling here. - error("%s", buffer); -} - -void outputMessage(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - // Is using debug here a good idea? Or do we want to ignore all libjpeg - // messages? - debug(3, "libjpeg: %s", buffer); -} - -} // End of anonymous namespace -#endif - -bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) { -#ifdef USE_JPEG - // Reset member variables from previous decodings - destroy(); - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - // Initialize error handling callbacks - cinfo.err = jpeg_std_error(&jerr); - cinfo.err->error_exit = &errorExit; - cinfo.err->output_message = &outputMessage; - - // Initialize the decompression structure - jpeg_create_decompress(&cinfo); - - // Initialize our buffer handling - jpeg_scummvm_src(&cinfo, &stream); - - // Read the file header - jpeg_read_header(&cinfo, TRUE); - - // We can request YUV output because Groovie requires it - switch (_colorSpace) { - case kColorSpaceRGBA: - cinfo.out_color_space = JCS_RGB; - break; - - case kColorSpaceYUV: - cinfo.out_color_space = JCS_YCbCr; - break; - } - - // Actually start decompressing the image - jpeg_start_decompress(&cinfo); - - // Allocate buffers for the output data - switch (_colorSpace) { - case kColorSpaceRGBA: - // We use RGBA8888 in this scenario - _surface.create(cinfo.output_width, cinfo.output_height, Graphics::PixelFormat(4, 8, 8, 8, 0, 24, 16, 8, 0)); - break; - - case kColorSpaceYUV: - // We use YUV with 3 bytes per pixel otherwise. - // This is pretty ugly since our PixelFormat cannot express YUV... - _surface.create(cinfo.output_width, cinfo.output_height, Graphics::PixelFormat(3, 0, 0, 0, 0, 0, 0, 0, 0)); - break; - } - - // Allocate buffer for one scanline - assert(cinfo.output_components == 3); - JDIMENSION pitch = cinfo.output_width * cinfo.output_components; - assert(_surface.pitch >= pitch); - JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, pitch, 1); - - // Go through the image data scanline by scanline - while (cinfo.output_scanline < cinfo.output_height) { - byte *dst = (byte *)_surface.getBasePtr(0, cinfo.output_scanline); - - jpeg_read_scanlines(&cinfo, buffer, 1); - - const byte *src = buffer[0]; - switch (_colorSpace) { - case kColorSpaceRGBA: { - for (int remaining = cinfo.output_width; remaining > 0; --remaining) { - byte r = *src++; - byte g = *src++; - byte b = *src++; - // We need to insert a alpha value of 255 (opaque) here. -#ifdef SCUMM_BIG_ENDIAN - *dst++ = r; - *dst++ = g; - *dst++ = b; - *dst++ = 0xFF; -#else - *dst++ = 0xFF; - *dst++ = b; - *dst++ = g; - *dst++ = r; -#endif - } - } break; - - case kColorSpaceYUV: - memcpy(dst, src, pitch); - break; - } - } - - // We are done with decompressing, thus free all the data - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - - return true; -#else - return false; -#endif -} - -} // End of Graphics namespace |