summaryrefslogtreecommitdiffstats
path: root/src/plugins/imageformats/jpeg
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-07-03 05:21:49 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-07-03 05:21:49 (GMT)
commitce01f19674923cb5144bb56fe76ecbe19865d3bd (patch)
tree2235ab6b1b469ca0232ccf621309e3a90d770e2a /src/plugins/imageformats/jpeg
parentdaeb81493aef4fd8f632ba4ea7f8d12ed80fa7be (diff)
parent1358c4b53cf4cec83ea6d9b0f886b99f76c4847e (diff)
downloadQt-ce01f19674923cb5144bb56fe76ecbe19865d3bd.zip
Qt-ce01f19674923cb5144bb56fe76ecbe19865d3bd.tar.gz
Qt-ce01f19674923cb5144bb56fe76ecbe19865d3bd.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: Consolidate zlib configuration redundancy Fixed whitespace formatting Fix incomplete support for built-in jpeg, mng, tiff and gif handlers Split image handler plugin project files No explicit link to zlib/jpeg for system mng/tiff Removed stray line continuations Long live else! qdoc: Added a solution for creating tables of contents for manuals. Doc: Fixed markup. Fixed size hint for combo box on windows
Diffstat (limited to 'src/plugins/imageformats/jpeg')
-rw-r--r--src/plugins/imageformats/jpeg/jpeg.pro60
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp901
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.h76
3 files changed, 2 insertions, 1035 deletions
diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro
index d4b0fef..c5671c3 100644
--- a/src/plugins/imageformats/jpeg/jpeg.pro
+++ b/src/plugins/imageformats/jpeg/jpeg.pro
@@ -3,10 +3,6 @@ include(../../qpluginbase.pri)
QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-jpeg)"
-HEADERS += qjpeghandler.h
-SOURCES += main.cpp \
- qjpeghandler.cpp
-
wince*: {
DEFINES += NO_GETENV
contains(CE_ARCH,x86):CONFIG -= stl exceptions
@@ -21,61 +17,9 @@ symbian: {
QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main
}
-contains(QT_CONFIG, system-jpeg) {
- unix|win32-g++*:LIBS += -ljpeg
- win32:!win32-g++*:LIBS += libjpeg.lib
-} else {
- INCLUDEPATH += ../../../3rdparty/libjpeg
- SOURCES += \
- ../../../3rdparty/libjpeg/jaricom.c \
- ../../../3rdparty/libjpeg/jcapimin.c \
- ../../../3rdparty/libjpeg/jcapistd.c \
- ../../../3rdparty/libjpeg/jcarith.c \
- ../../../3rdparty/libjpeg/jccoefct.c \
- ../../../3rdparty/libjpeg/jccolor.c \
- ../../../3rdparty/libjpeg/jcdctmgr.c \
- ../../../3rdparty/libjpeg/jchuff.c \
- ../../../3rdparty/libjpeg/jcinit.c \
- ../../../3rdparty/libjpeg/jcmainct.c \
- ../../../3rdparty/libjpeg/jcmarker.c \
- ../../../3rdparty/libjpeg/jcmaster.c \
- ../../../3rdparty/libjpeg/jcomapi.c \
- ../../../3rdparty/libjpeg/jcparam.c \
- ../../../3rdparty/libjpeg/jcprepct.c \
- ../../../3rdparty/libjpeg/jcsample.c \
- ../../../3rdparty/libjpeg/jctrans.c \
- ../../../3rdparty/libjpeg/jdapimin.c \
- ../../../3rdparty/libjpeg/jdapistd.c \
- ../../../3rdparty/libjpeg/jdarith.c \
- ../../../3rdparty/libjpeg/jdatadst.c \
- ../../../3rdparty/libjpeg/jdatasrc.c \
- ../../../3rdparty/libjpeg/jdcoefct.c \
- ../../../3rdparty/libjpeg/jdcolor.c \
- ../../../3rdparty/libjpeg/jddctmgr.c \
- ../../../3rdparty/libjpeg/jdhuff.c \
- ../../../3rdparty/libjpeg/jdinput.c \
- ../../../3rdparty/libjpeg/jdmainct.c \
- ../../../3rdparty/libjpeg/jdmarker.c \
- ../../../3rdparty/libjpeg/jdmaster.c \
- ../../../3rdparty/libjpeg/jdmerge.c \
- ../../../3rdparty/libjpeg/jdpostct.c \
- ../../../3rdparty/libjpeg/jdsample.c \
- ../../../3rdparty/libjpeg/jdtrans.c \
- ../../../3rdparty/libjpeg/jerror.c \
- ../../../3rdparty/libjpeg/jfdctflt.c \
- ../../../3rdparty/libjpeg/jfdctfst.c \
- ../../../3rdparty/libjpeg/jfdctint.c \
- ../../../3rdparty/libjpeg/jidctflt.c \
- ../../../3rdparty/libjpeg/jidctfst.c \
- ../../../3rdparty/libjpeg/jidctint.c \
- ../../../3rdparty/libjpeg/jquant1.c \
- ../../../3rdparty/libjpeg/jquant2.c \
- ../../../3rdparty/libjpeg/jutils.c \
- ../../../3rdparty/libjpeg/jmemmgr.c \
- ../../../3rdparty/libjpeg/jmemnobs.c
-}
+include(../../../gui/image/qjpeghandler.pri)
+SOURCES += main.cpp
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/imageformats
target.path += $$[QT_INSTALL_PLUGINS]/imageformats
INSTALLS += target
-
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
deleted file mode 100644
index 60e7cce..0000000
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ /dev/null
@@ -1,901 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qjpeghandler.h"
-
-#include <qimage.h>
-#include <qvariant.h>
-#include <qvector.h>
-#include <qbuffer.h>
-
-#include <stdio.h> // jpeglib needs this to be pre-included
-#include <setjmp.h>
-
-#ifdef FAR
-#undef FAR
-#endif
-
-// including jpeglib.h seems to be a little messy
-extern "C" {
-// mingw includes rpcndr.h but does not define boolean
-#if defined(Q_OS_WIN) && defined(Q_CC_GNU)
-# if defined(__RPCNDR_H__) && !defined(boolean)
- typedef unsigned char boolean;
-# define HAVE_BOOLEAN
-# endif
-#endif
-
-#define XMD_H // shut JPEGlib up
-#if defined(Q_OS_UNIXWARE)
-# define HAVE_BOOLEAN // libjpeg under Unixware seems to need this
-#endif
-#include <jpeglib.h>
-#ifdef const
-# undef const // remove crazy C hackery in jconfig.h
-#endif
-}
-
-QT_BEGIN_NAMESPACE
-
-struct my_error_mgr : public jpeg_error_mgr {
- jmp_buf setjmp_buffer;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static void my_error_exit (j_common_ptr cinfo)
-{
- my_error_mgr* myerr = (my_error_mgr*) cinfo->err;
- char buffer[JMSG_LENGTH_MAX];
- (*cinfo->err->format_message)(cinfo, buffer);
- qWarning("%s", buffer);
- longjmp(myerr->setjmp_buffer, 1);
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-
-static const int max_buf = 4096;
-
-struct my_jpeg_source_mgr : public jpeg_source_mgr {
- // Nothing dynamic - cannot rely on destruction over longjump
- QIODevice *device;
- JOCTET buffer[max_buf];
- const QBuffer *memDevice;
-
-public:
- my_jpeg_source_mgr(QIODevice *device);
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static void qt_init_source(j_decompress_ptr)
-{
-}
-
-static boolean qt_fill_input_buffer(j_decompress_ptr cinfo)
-{
- my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
- if (src->memDevice) {
- src->next_input_byte = (const JOCTET *)(src->memDevice->data().constData() + src->memDevice->pos());
- src->bytes_in_buffer = (size_t)(src->memDevice->data().size() - src->memDevice->pos());
- return true;
- }
- src->next_input_byte = src->buffer;
- int num_read = src->device->read((char*)src->buffer, max_buf);
- if (num_read <= 0) {
- // Insert a fake EOI marker - as per jpeglib recommendation
- src->buffer[0] = (JOCTET) 0xFF;
- src->buffer[1] = (JOCTET) JPEG_EOI;
- src->bytes_in_buffer = 2;
- } else {
- src->bytes_in_buffer = num_read;
- }
-#if defined(Q_OS_UNIXWARE)
- return B_TRUE;
-#else
- return true;
-#endif
-}
-
-static void qt_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
-{
- my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
-
- // `dumb' implementation from jpeglib
-
- /* Just a dumb implementation for now. Could use fseek() except
- * it doesn't work on pipes. Not clear that being smart is worth
- * any trouble anyway --- large skips are infrequent.
- */
- if (num_bytes > 0) {
- while (num_bytes > (long) src->bytes_in_buffer) { // Should not happen in case of memDevice
- num_bytes -= (long) src->bytes_in_buffer;
- (void) qt_fill_input_buffer(cinfo);
- /* note we assume that qt_fill_input_buffer will never return false,
- * so suspension need not be handled.
- */
- }
- src->next_input_byte += (size_t) num_bytes;
- src->bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-static void qt_term_source(j_decompress_ptr cinfo)
-{
- my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
- if (!src->device->isSequential())
- {
- // read() isn't used for memDevice, so seek past everything that was used
- if (src->memDevice)
- src->device->seek(src->device->pos() + (src->memDevice->data().size() - src->memDevice->pos() - src->bytes_in_buffer));
- else
- src->device->seek(src->device->pos() - src->bytes_in_buffer);
- }
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-inline my_jpeg_source_mgr::my_jpeg_source_mgr(QIODevice *device)
-{
- jpeg_source_mgr::init_source = qt_init_source;
- jpeg_source_mgr::fill_input_buffer = qt_fill_input_buffer;
- jpeg_source_mgr::skip_input_data = qt_skip_input_data;
- jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart;
- jpeg_source_mgr::term_source = qt_term_source;
- this->device = device;
- memDevice = qobject_cast<QBuffer *>(device);
- bytes_in_buffer = 0;
- next_input_byte = buffer;
-}
-
-
-inline static bool read_jpeg_size(int &w, int &h, j_decompress_ptr cinfo)
-{
- (void) jpeg_calc_output_dimensions(cinfo);
-
- w = cinfo->output_width;
- h = cinfo->output_height;
- return true;
-}
-
-#define HIGH_QUALITY_THRESHOLD 50
-
-inline static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cinfo)
-{
-
- bool result = true;
- switch (cinfo->output_components) {
- case 1:
- format = QImage::Format_Indexed8;
- break;
- case 3:
- case 4:
- format = QImage::Format_RGB32;
- break;
- default:
- result = false;
- break;
- }
- cinfo->output_scanline = cinfo->output_height;
- return result;
-}
-
-static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
- const QSize& size)
-{
- QImage::Format format;
- switch (info->output_components) {
- case 1:
- format = QImage::Format_Indexed8;
- break;
- case 3:
- case 4:
- format = QImage::Format_RGB32;
- break;
- default:
- return false; // unsupported format
- }
-
- if (dest->size() != size || dest->format() != format) {
- *dest = QImage(size, format);
-
- if (format == QImage::Format_Indexed8) {
- dest->setColorCount(256);
- for (int i = 0; i < 256; i++)
- dest->setColor(i, qRgb(i,i,i));
- }
- }
-
- return !dest->isNull();
-}
-
-static bool read_jpeg_image(QImage *outImage,
- QSize scaledSize, QRect scaledClipRect,
- QRect clipRect, int inQuality, j_decompress_ptr info, struct my_error_mgr* err )
-{
- if (!setjmp(err->setjmp_buffer)) {
- // -1 means default quality.
- int quality = inQuality;
- if (quality < 0)
- quality = 75;
-
- // If possible, merge the scaledClipRect into either scaledSize
- // or clipRect to avoid doing a separate scaled clipping pass.
- // Best results are achieved by clipping before scaling, not after.
- if (!scaledClipRect.isEmpty()) {
- if (scaledSize.isEmpty() && clipRect.isEmpty()) {
- // No clipping or scaling before final clip.
- clipRect = scaledClipRect;
- scaledClipRect = QRect();
- } else if (scaledSize.isEmpty()) {
- // Clipping, but no scaling: combine the clip regions.
- scaledClipRect.translate(clipRect.topLeft());
- clipRect = scaledClipRect.intersected(clipRect);
- scaledClipRect = QRect();
- } else if (clipRect.isEmpty()) {
- // No clipping, but scaling: if we can map back to an
- // integer pixel boundary, then clip before scaling.
- if ((info->image_width % scaledSize.width()) == 0 &&
- (info->image_height % scaledSize.height()) == 0) {
- int x = scaledClipRect.x() * info->image_width /
- scaledSize.width();
- int y = scaledClipRect.y() * info->image_height /
- scaledSize.height();
- int width = (scaledClipRect.right() + 1) *
- info->image_width / scaledSize.width() - x;
- int height = (scaledClipRect.bottom() + 1) *
- info->image_height / scaledSize.height() - y;
- clipRect = QRect(x, y, width, height);
- scaledSize = scaledClipRect.size();
- scaledClipRect = QRect();
- }
- } else {
- // Clipping and scaling: too difficult to figure out,
- // and not a likely use case, so do it the long way.
- }
- }
-
- // Determine the scale factor to pass to libjpeg for quick downscaling.
- if (!scaledSize.isEmpty()) {
- if (clipRect.isEmpty()) {
- info->scale_denom =
- qMin(info->image_width / scaledSize.width(),
- info->image_height / scaledSize.height());
- } else {
- info->scale_denom =
- qMin(clipRect.width() / scaledSize.width(),
- clipRect.height() / scaledSize.height());
- }
- if (info->scale_denom < 2) {
- info->scale_denom = 1;
- } else if (info->scale_denom < 4) {
- info->scale_denom = 2;
- } else if (info->scale_denom < 8) {
- info->scale_denom = 4;
- } else {
- info->scale_denom = 8;
- }
- info->scale_num = 1;
- if (!clipRect.isEmpty()) {
- // Correct the scale factor so that we clip accurately.
- // It is recommended that the clip rectangle be aligned
- // on an 8-pixel boundary for best performance.
- while (info->scale_denom > 1 &&
- ((clipRect.x() % info->scale_denom) != 0 ||
- (clipRect.y() % info->scale_denom) != 0 ||
- (clipRect.width() % info->scale_denom) != 0 ||
- (clipRect.height() % info->scale_denom) != 0)) {
- info->scale_denom /= 2;
- }
- }
- }
-
- // If high quality not required, use fast decompression
- if( quality < HIGH_QUALITY_THRESHOLD ) {
- info->dct_method = JDCT_IFAST;
- info->do_fancy_upsampling = FALSE;
- }
-
- (void) jpeg_calc_output_dimensions(info);
-
- // Determine the clip region to extract.
- QRect imageRect(0, 0, info->output_width, info->output_height);
- QRect clip;
- if (clipRect.isEmpty()) {
- clip = imageRect;
- } else if (info->scale_denom == info->scale_num) {
- clip = clipRect.intersected(imageRect);
- } else {
- // The scale factor was corrected above to ensure that
- // we don't miss pixels when we scale the clip rectangle.
- clip = QRect(clipRect.x() / int(info->scale_denom),
- clipRect.y() / int(info->scale_denom),
- clipRect.width() / int(info->scale_denom),
- clipRect.height() / int(info->scale_denom));
- clip = clip.intersected(imageRect);
- }
-
- // Allocate memory for the clipped QImage.
- if (!ensureValidImage(outImage, info, clip.size()))
- longjmp(err->setjmp_buffer, 1);
-
- // Avoid memcpy() overhead if grayscale with no clipping.
- bool quickGray = (info->output_components == 1 &&
- clip == imageRect);
- if (!quickGray) {
- // Ask the jpeg library to allocate a temporary row.
- // The library will automatically delete it for us later.
- // The libjpeg docs say we should do this before calling
- // jpeg_start_decompress(). We can't use "new" here
- // because we are inside the setjmp() block and an error
- // in the jpeg input stream would cause a memory leak.
- JSAMPARRAY rows = (info->mem->alloc_sarray)
- ((j_common_ptr)info, JPOOL_IMAGE,
- info->output_width * info->output_components, 1);
-
- (void) jpeg_start_decompress(info);
-
- while (info->output_scanline < info->output_height) {
- int y = int(info->output_scanline) - clip.y();
- if (y >= clip.height())
- break; // We've read the entire clip region, so abort.
-
- (void) jpeg_read_scanlines(info, rows, 1);
-
- if (y < 0)
- continue; // Haven't reached the starting line yet.
-
- if (info->output_components == 3) {
- // Expand 24->32 bpp.
- uchar *in = rows[0] + clip.x() * 3;
- QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- *out++ = qRgb(in[0], in[1], in[2]);
- in += 3;
- }
- } else if (info->out_color_space == JCS_CMYK) {
- // Convert CMYK->RGB.
- uchar *in = rows[0] + clip.x() * 4;
- QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- int k = in[3];
- *out++ = qRgb(k * in[0] / 255, k * in[1] / 255,
- k * in[2] / 255);
- in += 4;
- }
- } else if (info->output_components == 1) {
- // Grayscale.
- memcpy(outImage->scanLine(y),
- rows[0] + clip.x(), clip.width());
- }
- }
- } else {
- // Load unclipped grayscale data directly into the QImage.
- (void) jpeg_start_decompress(info);
- while (info->output_scanline < info->output_height) {
- uchar *row = outImage->scanLine(info->output_scanline);
- (void) jpeg_read_scanlines(info, &row, 1);
- }
- }
-
- if (info->output_scanline == info->output_height)
- (void) jpeg_finish_decompress(info);
-
- if (info->density_unit == 1) {
- outImage->setDotsPerMeterX(int(100. * info->X_density / 2.54));
- outImage->setDotsPerMeterY(int(100. * info->Y_density / 2.54));
- } else if (info->density_unit == 2) {
- outImage->setDotsPerMeterX(int(100. * info->X_density));
- outImage->setDotsPerMeterY(int(100. * info->Y_density));
- }
-
- if (scaledSize.isValid() && scaledSize != clip.size()) {
- *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, quality >= HIGH_QUALITY_THRESHOLD ? Qt::SmoothTransformation : Qt::FastTransformation);
- }
-
- if (!scaledClipRect.isEmpty())
- *outImage = outImage->copy(scaledClipRect);
- return !outImage->isNull();
- }
- else
- return false;
-}
-
-struct my_jpeg_destination_mgr : public jpeg_destination_mgr {
- // Nothing dynamic - cannot rely on destruction over longjump
- QIODevice *device;
- JOCTET buffer[max_buf];
-
-public:
- my_jpeg_destination_mgr(QIODevice *);
-};
-
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static void qt_init_destination(j_compress_ptr)
-{
-}
-
-static boolean qt_empty_output_buffer(j_compress_ptr cinfo)
-{
- my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
-
- int written = dest->device->write((char*)dest->buffer, max_buf);
- if (written == -1)
- (*cinfo->err->error_exit)((j_common_ptr)cinfo);
-
- dest->next_output_byte = dest->buffer;
- dest->free_in_buffer = max_buf;
-
-#if defined(Q_OS_UNIXWARE)
- return B_TRUE;
-#else
- return true;
-#endif
-}
-
-static void qt_term_destination(j_compress_ptr cinfo)
-{
- my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
- qint64 n = max_buf - dest->free_in_buffer;
-
- qint64 written = dest->device->write((char*)dest->buffer, n);
- if (written == -1)
- (*cinfo->err->error_exit)((j_common_ptr)cinfo);
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device)
-{
- jpeg_destination_mgr::init_destination = qt_init_destination;
- jpeg_destination_mgr::empty_output_buffer = qt_empty_output_buffer;
- jpeg_destination_mgr::term_destination = qt_term_destination;
- this->device = device;
- next_output_byte = buffer;
- free_in_buffer = max_buf;
-}
-
-static bool can_write_format(QImage::Format fmt)
-{
- switch (fmt) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- case QImage::Format_Indexed8:
- case QImage::Format_RGB888:
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- return true;
- break;
- default:
- break;
- }
- return false;
-}
-
-static bool write_jpeg_image(const QImage &sourceImage, QIODevice *device, int sourceQuality)
-{
- bool success = false;
- const QImage image = can_write_format(sourceImage.format()) ?
- sourceImage : sourceImage.convertToFormat(QImage::Format_RGB888);
- const QVector<QRgb> cmap = image.colorTable();
-
- struct jpeg_compress_struct cinfo;
- JSAMPROW row_pointer[1];
- row_pointer[0] = 0;
-
- struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
- struct my_error_mgr jerr;
-
- cinfo.err = jpeg_std_error(&jerr);
- jerr.error_exit = my_error_exit;
-
- if (!setjmp(jerr.setjmp_buffer)) {
- // WARNING:
- // this if loop is inside a setjmp/longjmp branch
- // do not create C++ temporaries here because the destructor may never be called
- // if you allocate memory, make sure that you can free it (row_pointer[0])
- jpeg_create_compress(&cinfo);
-
- cinfo.dest = iod_dest;
-
- cinfo.image_width = image.width();
- cinfo.image_height = image.height();
-
- bool gray=false;
- switch (image.format()) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- case QImage::Format_Indexed8:
- gray = true;
- for (int i = image.colorCount(); gray && i--;) {
- gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) &&
- qRed(cmap[i]) == qBlue(cmap[i]));
- }
- cinfo.input_components = gray ? 1 : 3;
- cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
- break;
- default:
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
- }
-
- jpeg_set_defaults(&cinfo);
-
- qreal diffInch = qAbs(image.dotsPerMeterX()*2.54/100. - qRound(image.dotsPerMeterX()*2.54/100.))
- + qAbs(image.dotsPerMeterY()*2.54/100. - qRound(image.dotsPerMeterY()*2.54/100.));
- qreal diffCm = (qAbs(image.dotsPerMeterX()/100. - qRound(image.dotsPerMeterX()/100.))
- + qAbs(image.dotsPerMeterY()/100. - qRound(image.dotsPerMeterY()/100.)))*2.54;
- if (diffInch < diffCm) {
- cinfo.density_unit = 1; // dots/inch
- cinfo.X_density = qRound(image.dotsPerMeterX()*2.54/100.);
- cinfo.Y_density = qRound(image.dotsPerMeterY()*2.54/100.);
- } else {
- cinfo.density_unit = 2; // dots/cm
- cinfo.X_density = (image.dotsPerMeterX()+50) / 100;
- cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;
- }
-
-
- int quality = sourceQuality >= 0 ? qMin(sourceQuality,100) : 75;
-#if defined(Q_OS_UNIXWARE)
- jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */);
- jpeg_start_compress(&cinfo, B_TRUE);
-#else
- jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);
- jpeg_start_compress(&cinfo, true);
-#endif
-
- row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
- int w = cinfo.image_width;
- while (cinfo.next_scanline < cinfo.image_height) {
- uchar *row = row_pointer[0];
- switch (image.format()) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- if (gray) {
- const uchar* data = image.scanLine(cinfo.next_scanline);
- if (image.format() == QImage::Format_MonoLSB) {
- for (int i=0; i<w; i++) {
- bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
- row[i] = qRed(cmap[bit]);
- }
- } else {
- for (int i=0; i<w; i++) {
- bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
- row[i] = qRed(cmap[bit]);
- }
- }
- } else {
- const uchar* data = image.scanLine(cinfo.next_scanline);
- if (image.format() == QImage::Format_MonoLSB) {
- for (int i=0; i<w; i++) {
- bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
- *row++ = qRed(cmap[bit]);
- *row++ = qGreen(cmap[bit]);
- *row++ = qBlue(cmap[bit]);
- }
- } else {
- for (int i=0; i<w; i++) {
- bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
- *row++ = qRed(cmap[bit]);
- *row++ = qGreen(cmap[bit]);
- *row++ = qBlue(cmap[bit]);
- }
- }
- }
- break;
- case QImage::Format_Indexed8:
- if (gray) {
- const uchar* pix = image.scanLine(cinfo.next_scanline);
- for (int i=0; i<w; i++) {
- *row = qRed(cmap[*pix]);
- ++row; ++pix;
- }
- } else {
- const uchar* pix = image.scanLine(cinfo.next_scanline);
- for (int i=0; i<w; i++) {
- *row++ = qRed(cmap[*pix]);
- *row++ = qGreen(cmap[*pix]);
- *row++ = qBlue(cmap[*pix]);
- ++pix;
- }
- }
- break;
- case QImage::Format_RGB888:
- memcpy(row, image.scanLine(cinfo.next_scanline), w * 3);
- break;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied: {
- QRgb* rgb = (QRgb*)image.scanLine(cinfo.next_scanline);
- for (int i=0; i<w; i++) {
- *row++ = qRed(*rgb);
- *row++ = qGreen(*rgb);
- *row++ = qBlue(*rgb);
- ++rgb;
- }
- break;
- }
- default:
- qWarning("QJpegHandler: unable to write image of format %i",
- image.format());
- break;
- }
- jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
-
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
- success = true;
- } else {
- jpeg_destroy_compress(&cinfo);
- success = false;
- }
-
- delete iod_dest;
- delete [] row_pointer[0];
- return success;
-}
-
-class QJpegHandlerPrivate
-{
-public:
- enum State {
- Ready,
- ReadHeader,
- Error
- };
-
- QJpegHandlerPrivate(QJpegHandler *qq)
- : quality(75), iod_src(0), state(Ready), q(qq)
- {}
-
- ~QJpegHandlerPrivate()
- {
- if(iod_src)
- {
- jpeg_destroy_decompress(&info);
- delete iod_src;
- iod_src = 0;
- }
- }
-
- bool readJpegHeader(QIODevice*);
- bool read(QImage *image);
-
- int quality;
- QVariant size;
- QImage::Format format;
- QSize scaledSize;
- QRect scaledClipRect;
- QRect clipRect;
- struct jpeg_decompress_struct info;
- struct my_jpeg_source_mgr * iod_src;
- struct my_error_mgr err;
-
- State state;
-
- QJpegHandler *q;
-};
-
-/*!
- \internal
-*/
-bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
-{
- if(state == Ready)
- {
- state = Error;
- iod_src = new my_jpeg_source_mgr(device);
-
- jpeg_create_decompress(&info);
- info.src = iod_src;
- info.err = jpeg_std_error(&err);
- err.error_exit = my_error_exit;
-
- if (!setjmp(err.setjmp_buffer)) {
- #if defined(Q_OS_UNIXWARE)
- (void) jpeg_read_header(&info, B_TRUE);
- #else
- (void) jpeg_read_header(&info, true);
- #endif
-
- int width = 0;
- int height = 0;
- read_jpeg_size(width, height, &info);
- size = QSize(width, height);
-
- format = QImage::Format_Invalid;
- read_jpeg_format(format, &info);
- state = ReadHeader;
- return true;
- }
- else
- {
- return false;
- }
- }
- else if(state == Error)
- return false;
- return true;
-}
-
-bool QJpegHandlerPrivate::read(QImage *image)
-{
- if(state == Ready)
- readJpegHeader(q->device());
-
- if(state == ReadHeader)
- {
- bool success = read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, &info, &err);
- state = success ? Ready : Error;
- return success;
- }
-
- return false;
-
-}
-
-QJpegHandler::QJpegHandler()
- : d(new QJpegHandlerPrivate(this))
-{
-}
-
-QJpegHandler::~QJpegHandler()
-{
- delete d;
-}
-
-bool QJpegHandler::canRead() const
-{
- if(d->state == QJpegHandlerPrivate::Ready && !canRead(device()))
- return false;
-
- if (d->state != QJpegHandlerPrivate::Error) {
- setFormat("jpeg");
- return true;
- }
-
- return false;
-}
-
-bool QJpegHandler::canRead(QIODevice *device)
-{
- if (!device) {
- qWarning("QJpegHandler::canRead() called with no device");
- return false;
- }
-
- char buffer[2];
- if (device->peek(buffer, 2) != 2)
- return false;
- return uchar(buffer[0]) == 0xff && uchar(buffer[1]) == 0xd8;
-}
-
-bool QJpegHandler::read(QImage *image)
-{
- if (!canRead())
- return false;
- return d->read(image);
-}
-
-bool QJpegHandler::write(const QImage &image)
-{
- return write_jpeg_image(image, device(), d->quality);
-}
-
-bool QJpegHandler::supportsOption(ImageOption option) const
-{
- return option == Quality
- || option == ScaledSize
- || option == ScaledClipRect
- || option == ClipRect
- || option == Size
- || option == ImageFormat;
-}
-
-QVariant QJpegHandler::option(ImageOption option) const
-{
- switch(option) {
- case Quality:
- return d->quality;
- case ScaledSize:
- return d->scaledSize;
- case ScaledClipRect:
- return d->scaledClipRect;
- case ClipRect:
- return d->clipRect;
- case Size:
- d->readJpegHeader(device());
- return d->size;
- case ImageFormat:
- d->readJpegHeader(device());
- return d->format;
- default:
- return QVariant();
- }
-}
-
-void QJpegHandler::setOption(ImageOption option, const QVariant &value)
-{
- switch(option) {
- case Quality:
- d->quality = value.toInt();
- break;
- case ScaledSize:
- d->scaledSize = value.toSize();
- break;
- case ScaledClipRect:
- d->scaledClipRect = value.toRect();
- break;
- case ClipRect:
- d->clipRect = value.toRect();
- break;
- default:
- break;
- }
-}
-
-QByteArray QJpegHandler::name() const
-{
- return "jpeg";
-}
-
-
-
-
-QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.h b/src/plugins/imageformats/jpeg/qjpeghandler.h
deleted file mode 100644
index c879f21..0000000
--- a/src/plugins/imageformats/jpeg/qjpeghandler.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QJPEGHANDLER_H
-#define QJPEGHANDLER_H
-
-#include <QtGui/qimageiohandler.h>
-#include <QtCore/QSize>
-#include <QtCore/QRect>
-
-QT_BEGIN_NAMESPACE
-
-class QJpegHandlerPrivate;
-class QJpegHandler : public QImageIOHandler
-{
-public:
- QJpegHandler();
- ~QJpegHandler();
-
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
-
- QByteArray name() const;
-
- static bool canRead(QIODevice *device);
-
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
-
-private:
- QJpegHandlerPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QJPEGHANDLER_H