From 95b6cf26837dba0ac215db552ce47031f3abfc6e Mon Sep 17 00:00:00 2001
From: Jake Petroules <jake.petroules@petroules.com>
Date: Mon, 6 Jan 2014 07:52:54 -0500
Subject: [PATCH] Add JPEG 2000 plugin.

It is moving from Qt Solutions.

Change-Id: Ie0dc44d258597f871544fa43238528f42628b799
Reviewed-by: Jake Petroules <jake.petroules@petroules.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
---
 dist/changes-5.3.0                            |    1 +
 .../doc/qtimageformats-dita.qdocconf          |    2 +-
 src/imageformats/doc/src/qtimageformats.qdoc  |    1 +
 src/plugins/imageformats/imageformats.pro     |   11 +-
 src/plugins/imageformats/jp2/jp2.json         |    4 +
 src/plugins/imageformats/jp2/jp2.pro          |    9 +
 src/plugins/imageformats/jp2/main.cpp         |  100 ++
 src/plugins/imageformats/jp2/qjp2handler.cpp  | 1218 +++++++++++++++++
 src/plugins/imageformats/jp2/qjp2handler.pri  |   10 +
 src/plugins/imageformats/jp2/qjp2handler_p.h  |   78 ++
 tests/auto/auto.pro                           |    3 +-
 tests/auto/jp2/jp2.pro                        |    8 +
 tests/auto/jp2/tst_qjp2.cpp                   |   88 ++
 tests/shared/images/jp2.qrc                   |    6 +
 tests/shared/images/jp2/logo.bmp              |  Bin 0 -> 119734 bytes
 tests/shared/images/jp2/logo.jp2              |  Bin 0 -> 27570 bytes
 16 files changed, 1533 insertions(+), 6 deletions(-)
 create mode 100644 src/plugins/imageformats/jp2/jp2.json
 create mode 100644 src/plugins/imageformats/jp2/jp2.pro
 create mode 100644 src/plugins/imageformats/jp2/main.cpp
 create mode 100644 src/plugins/imageformats/jp2/qjp2handler.cpp
 create mode 100644 src/plugins/imageformats/jp2/qjp2handler.pri
 create mode 100644 src/plugins/imageformats/jp2/qjp2handler_p.h
 create mode 100644 tests/auto/jp2/jp2.pro
 create mode 100644 tests/auto/jp2/tst_qjp2.cpp
 create mode 100644 tests/shared/images/jp2.qrc
 create mode 100644 tests/shared/images/jp2/logo.bmp
 create mode 100644 tests/shared/images/jp2/logo.jp2

diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0
index 5a7a19b6..026d568d 100644
--- a/dist/changes-5.3.0
+++ b/dist/changes-5.3.0
@@ -21,3 +21,4 @@ information about a particular change.
 
  - Add read/write support for Direct Draw Surface images.
  - Add read/write support for ICNS images.
+ - Add read/write support for JPEG 2000 images.
diff --git a/src/imageformats/doc/qtimageformats-dita.qdocconf b/src/imageformats/doc/qtimageformats-dita.qdocconf
index 82f9fdca..053e02a5 100644
--- a/src/imageformats/doc/qtimageformats-dita.qdocconf
+++ b/src/imageformats/doc/qtimageformats-dita.qdocconf
@@ -15,7 +15,7 @@ exampledirs += ../examples
 HTML.nobreadcrumbs = "true"
 
 examples.fileextensions = "*.cpp *.h *.js *.svg *.xml *.ui *.qml"
-examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
+examples.imageextensions = "*.png *.jp2 *.jpeg *.jpg *.gif *.mng"
 headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
 sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
 
diff --git a/src/imageformats/doc/src/qtimageformats.qdoc b/src/imageformats/doc/src/qtimageformats.qdoc
index 2c9f8a32..86cdd53e 100644
--- a/src/imageformats/doc/src/qtimageformats.qdoc
+++ b/src/imageformats/doc/src/qtimageformats.qdoc
@@ -54,6 +54,7 @@ libraries. If not found, it may fall back on using a bundled copy (in
 \header \li Format \li Description                      \li Support      \li 3rd party codec
 \row    \li DDS    \li Direct Draw Surface              \li Read/write   \li No
 \row    \li ICNS   \li Apple Icon Image                 \li Read/write   \li No
+\row    \li JP2    \li Joint Photographic Experts Group 2000 \li Read/write   \li Yes (bundled)
 \row    \li MNG    \li Multiple-image Network Graphics  \li Read         \li Yes (bundled)
 \row    \li TGA    \li Truevision Graphics Adapter      \li Read         \li No
 \row    \li TIFF   \li Tagged Image File Format         \li Read/write   \li Yes (bundled)
diff --git a/src/plugins/imageformats/imageformats.pro b/src/plugins/imageformats/imageformats.pro
index c6aa4098..01d2ac02 100644
--- a/src/plugins/imageformats/imageformats.pro
+++ b/src/plugins/imageformats/imageformats.pro
@@ -1,11 +1,14 @@
 TEMPLATE = subdirs
 SUBDIRS = \
-    tga \
-    wbmp \
+    dds \
+    icns \
+    jp2 \
     mng \
+    tga \
     tiff \
-    dds \
-    icns
+    wbmp
+
+wince:SUBDIRS -= jp2
 
 winrt {
     SUBDIRS -= tiff \
diff --git a/src/plugins/imageformats/jp2/jp2.json b/src/plugins/imageformats/jp2/jp2.json
new file mode 100644
index 00000000..e3d7fe30
--- /dev/null
+++ b/src/plugins/imageformats/jp2/jp2.json
@@ -0,0 +1,4 @@
+{
+    "Keys": [ "jp2" ],
+    "MimeTypes": [ "image/jp2", "image/jpx", "image/jpm", "video/mj2" ]
+}
diff --git a/src/plugins/imageformats/jp2/jp2.pro b/src/plugins/imageformats/jp2/jp2.pro
new file mode 100644
index 00000000..864ec269
--- /dev/null
+++ b/src/plugins/imageformats/jp2/jp2.pro
@@ -0,0 +1,9 @@
+TARGET  = qjp2
+
+PLUGIN_TYPE = imageformats
+PLUGIN_CLASS_NAME = QJp2Plugin
+load(qt_plugin)
+
+include(qjp2handler.pri)
+SOURCES += main.cpp
+OTHER_FILES += jp2.json
diff --git a/src/plugins/imageformats/jp2/main.cpp b/src/plugins/imageformats/jp2/main.cpp
new file mode 100644
index 00000000..700e96ed
--- /dev/null
+++ b/src/plugins/imageformats/jp2/main.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Petroules Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the JP2 plugins in the Qt ImageFormats module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qimageiohandler.h>
+#include <qstringlist.h>
+
+#ifndef QT_NO_IMAGEFORMATPLUGIN
+
+#include "qjp2handler_p.h"
+
+#include <qiodevice.h>
+#include <qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+class QJp2Plugin : public QImageIOPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jp2.json")
+
+public:
+    QStringList keys() const;
+    Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
+    QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
+};
+
+QStringList QJp2Plugin::keys() const
+{
+    return QStringList() << QLatin1String("jp2") << QLatin1String("j2k");
+}
+
+QImageIOPlugin::Capabilities QJp2Plugin::capabilities(QIODevice *device, const QByteArray &format) const
+{
+    if (format == "jp2" || format == "j2k")
+        return Capabilities(CanRead | CanWrite);
+    if (!format.isEmpty())
+        return 0;
+    if (!device->isOpen())
+        return 0;
+
+    Capabilities cap;
+    if (device->isReadable() && QJp2Handler::canRead(device, 0))
+        cap |= CanRead;
+    if (device->isWritable())
+        cap |= CanWrite;
+    return cap;
+}
+
+QImageIOHandler *QJp2Plugin::create(QIODevice *device, const QByteArray &format) const
+{
+    QJp2Handler *handler = new QJp2Handler();
+    handler->setDevice(device);
+    handler->setFormat(format);
+    return handler;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
+
+#endif // !QT_NO_IMAGEFORMATPLUGIN
diff --git a/src/plugins/imageformats/jp2/qjp2handler.cpp b/src/plugins/imageformats/jp2/qjp2handler.cpp
new file mode 100644
index 00000000..3a611d68
--- /dev/null
+++ b/src/plugins/imageformats/jp2/qjp2handler.cpp
@@ -0,0 +1,1218 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Petroules Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the JP2 plugins in the Qt ImageFormats module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjp2handler_p.h"
+
+#include "qimage.h"
+#include "qvariant.h"
+#include "qcolor.h"
+
+#ifdef Q_CC_MSVC
+#define JAS_WIN_MSVC_BUILD
+#endif
+#include <jasper/jasper.h>
+
+QT_BEGIN_NAMESPACE
+
+class QJp2HandlerPrivate
+{
+    Q_DECLARE_PUBLIC(QJp2Handler)
+    Q_DISABLE_COPY(QJp2HandlerPrivate)
+public:
+    int writeQuality;
+    QByteArray subType;
+    QJp2Handler *q_ptr;
+    QJp2HandlerPrivate(QJp2Handler *q_ptr);
+};
+
+enum SubFormat { Jp2Format, J2kFormat };
+
+/*
+    \class Jpeg2000JasperReader
+    \brief Jpeg2000JasperReader implements reading and writing of JPEG 2000
+    image files.
+
+    \internal
+
+    This class is designed to be used together with the an QImageIO IOHandler,
+    and it should probably not be necessary to instantiate it directly.
+
+    Internally it used the Jasper library for coding the image data.
+*/
+class Jpeg2000JasperReader
+{
+public:
+    Jpeg2000JasperReader(QIODevice *iod, const SubFormat format = Jp2Format);
+
+    ~Jpeg2000JasperReader();
+
+    bool read(QImage *pImage);
+    bool write(const QImage &image, int quality);
+private:
+    typedef void (Jpeg2000JasperReader::*ScanlineFunc)(jas_seqent_t** const, uchar*);
+    typedef void (Jpeg2000JasperReader::*ScanlineFuncWrite)(jas_matrix_t**, uchar*);
+
+    void copyJasperQt(ScanlineFunc scanlinecopier);
+    void copyJasperQtGeneric();
+    void copyScanlineJasperQtRGB(jas_seqent_t ** const jasperRow, uchar *qtScanLine);
+    void copyScanlineJasperQtRGBA(jas_seqent_t ** const jasperRow, uchar *qtScanLine);
+    void copyScanlineJasperQtGray(jas_seqent_t ** const jasperRow, uchar *qtScanLine);
+    void copyScanlineJasperQtGrayA(jas_seqent_t ** const jasperRow, uchar *qtScanLine);
+
+    void copyQtJasper(const ScanlineFuncWrite scanlinecopier);
+    void copyScanlineQtJasperRGB(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+    void copyScanlineQtJasperRGBA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+    void copyScanlineQtJasperColormapRGB(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+    void copyScanlineQtJasperColormapRGBA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+    void copyScanlineQtJasperColormapGrayscale(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+    void copyScanlineQtJasperColormapGrayscaleA(jas_matrix_t ** jasperRow, uchar *qtScanLine);
+
+    bool attemptColorspaceChange(int wantedColorSpace);
+    bool createJasperMatrix(jas_matrix_t **&matrix);
+    bool freeJasperMatrix(jas_matrix_t **matrix);
+    void printColorSpaceError();
+    jas_image_cmptparm_t createComponentMetadata(const int width, const int height);
+    jas_image_t *newRGBAImage(const int width, const int height, bool alpha);
+    jas_image_t *newGrayscaleImage(const int width, const int height, bool alpha);
+    bool decodeColorSpace(int clrspc, QString &family, QString &specific);
+    void printMetadata(jas_image_t *image);
+
+    bool jasperOk;
+
+    QIODevice *ioDevice;
+    QImage qtImage;
+    SubFormat format;
+
+    // Qt image properties
+    int qtWidth;
+    int qtHeight;
+    int qtDepth;
+    int qtNumComponents;
+
+    jas_image_t *jasper_image;
+    // jasper image properties
+    int jasNumComponents;
+    int jasComponentPrecicion[4];
+    int computedComponentWidth ;
+    int computedComponentHeight;
+    int computedComponentHorizontalSubsampling;
+    int computedComponentVerticalSubsampling;
+    int jasperColorspaceFamily;
+    // maps color to component (ex: colorComponentMapping[RED]
+    // gives the component that contains the red color)
+    int colorComponentMapping[4];
+    bool hasAlpha;
+};
+
+QJp2HandlerPrivate::QJp2HandlerPrivate(QJp2Handler *q_ptr)
+    : writeQuality(100), subType("jp2"), q_ptr(q_ptr)
+{
+}
+
+/*!
+    \class QJp2Handler
+    \brief The QJp2Handler class provides support for reading and writing
+    JPEG 2000 image files with the Qt plugin system.
+    Currently, it only supports dynamically-loaded plugins.
+
+    JPEG files comes in two subtypes: the JPEG 2000 file format (\c .jp2) and
+    the JPEG 2000 code stream format (\c .j2k, \c .jpc, or \c .j2c).
+    QJp2Handler can read and write both types.
+
+    To select a subtype, use the setOption() function with the
+    QImageIOHandler::SubType option and a parameter value of "jp2" or "j2k".
+
+    To set the image quality when writing, you can use setOption() with the
+    QImageIOHandler::Quality option, or QImageWriter::setQuality() if your are
+    using a QImageWriter object to write the image. The image quality is
+    specified as an int in the range 0 to 100. 0 means maximum compression and
+    99 means minimum compression. 100 selects lossless encoding, and this is the
+    default value.
+
+    The JPEG handler is only available as a plugin,
+    and this enables you to use normal QImage and QPixmap functions to read and
+    write images. For example:
+
+    \code
+        myLabel->setPixmap(QPixmap("myimage.jp2"));
+
+        QPixmap myPixmap;
+        myPixmap.save("myimage.jp2", "JP2");
+    \endcode
+*/
+
+/*!
+    Constructs an instance of QJp2Handler.
+*/
+QJp2Handler::QJp2Handler()
+    : d_ptr(new QJp2HandlerPrivate(this))
+{
+}
+
+/*!
+    Destructor for QJp2Handler.
+*/
+QJp2Handler::~QJp2Handler()
+{
+
+}
+
+/*!
+ Verifies if some values (magic bytes) are set as expected in the
+ header of the file. If the magic bytes were found, we assume that we
+ can read the file. The function will assume that the \a iod is
+ pointing to the beginning of the JPEG 2000 header. (i.e. it will for
+ instance not seek to the beginning of a file before reading).
+
+ If \a subType is not 0, it will contain "jp2" or "j2k" upon
+ successful return.
+*/
+bool QJp2Handler::canRead(QIODevice *iod, QByteArray *subType)
+{
+    bool bCanRead = false;
+    if (iod) {
+        const QByteArray header = iod->peek(12);
+        if (header.startsWith(QByteArrayLiteral("\000\000\000\fjP  \r\n\207\n"))) {
+            // Jp2 is the JPEG 2000 file format
+            bCanRead = true;
+            if (subType)
+                *subType = QByteArray("jp2");
+        } else if (header.startsWith(QByteArrayLiteral("\377\117\377\121\000"))) {
+            // J2c is the JPEG 2000 code stream
+            bCanRead = true;
+            if (subType)
+                *subType = QByteArray("j2k");
+        }
+    }
+    return bCanRead;
+}
+
+/*! \reimp
+*/
+bool QJp2Handler::canRead() const
+{
+    QByteArray subType;
+    if (canRead(device(), &subType)) {
+        setFormat(subType);
+        return true;
+    }
+    return false;
+}
+
+/*! \reimp
+*/
+bool QJp2Handler::read(QImage *image)
+{
+    Jpeg2000JasperReader reader(device());
+    return reader.read(image);
+}
+
+/*! \reimp
+*/
+bool QJp2Handler::write(const QImage &image)
+{
+    Q_D(const QJp2Handler);
+    SubFormat subFormat;
+    if (d->subType == QByteArray("jp2"))
+        subFormat = Jp2Format;
+    else
+        subFormat = J2kFormat;
+
+    Jpeg2000JasperReader writer(device(), subFormat);
+    return writer.write(image, d->writeQuality);
+}
+
+/*!
+    Get the value associated with \a option.
+    \sa setOption()
+*/
+QVariant QJp2Handler::option(ImageOption option) const
+{
+    Q_D(const QJp2Handler);
+    if (option == Quality) {
+        return QVariant(d->writeQuality);
+    } else if (option == SubType) {
+        return QVariant(d->subType);
+    }
+    return QVariant();
+}
+
+/*!
+    The JPEG 2000 handler supports two options.
+    Set \a option to QImageIOHandler::Quality to balance between quality and the
+    compression level, where \a value should be an integer in the interval
+    [0-100]. 0 is maximum compression (low quality) and 100 is lossless
+    compression (high quality).
+
+    Set \a option to QImageIOHandler::Subtype to choose the subtype,
+    where \a value should be a string equal to either "jp2" or "j2k"
+    \sa option()
+*/
+void QJp2Handler::setOption(ImageOption option, const QVariant &value)
+{
+    Q_D(QJp2Handler);
+    if (option == Quality) {
+        bool ok;
+        const int quality = value.toInt(&ok);
+        if (ok)
+            d->writeQuality = quality;
+    } else if (option == SubType) {
+        const QByteArray subTypeCandidate = value.toByteArray();
+        // Test for default Jpeg2000 file format (jp2), or stream format (j2k).
+        if (subTypeCandidate == QByteArrayLiteral("jp2") ||
+            subTypeCandidate == QByteArrayLiteral("j2k"))
+            d->subType = subTypeCandidate;
+    }
+}
+
+/*!
+    This function will return true if \a option is set to either
+    QImageIOHandler::Quality or QImageIOHandler::Subtype.
+*/
+bool QJp2Handler::supportsOption(ImageOption option) const
+{
+    return (option == Quality || option == SubType);
+}
+
+/*!
+    Return the common identifier of the format.
+    For JPEG 2000 this will return "jp2".
+ */
+QByteArray QJp2Handler::name() const
+{
+    return QByteArrayLiteral("jp2");
+}
+
+/*!
+    Automatic resource handling for a jas_image_t*.
+*/
+class ScopedJasperImage
+{
+public:
+    // Take reference to the pointer here, because the pointer
+    // may change when we change color spaces.
+    ScopedJasperImage(jas_image_t *&image):image(image) { }
+    ~ScopedJasperImage() { jas_image_destroy(image); }
+private:
+    jas_image_t *&image;
+};
+
+/*! \internal
+    Construct a Jpeg2000JasperReader using the provided \a imageIO.
+    Note that currently the jasper library is initialized in this constructor,
+    (and freed in the destructor) which means that:
+    - Only one instance of this class may exist at one time
+    - No thread safety
+*/
+Jpeg2000JasperReader::Jpeg2000JasperReader(QIODevice *iod, SubFormat format)
+    : jasperOk(true), ioDevice(iod), format(format), hasAlpha(false)
+{
+    if (jas_init()) {
+        jasperOk = false;
+        qDebug("Jasper Library initialization failed");
+    }
+}
+
+Jpeg2000JasperReader::~Jpeg2000JasperReader()
+{
+    if (jasperOk)
+        jas_cleanup();
+}
+
+/*! \internal
+    Opens the file data and attempts to decode it using the Jasper library.
+    Returns true if successful, false on failure
+*/
+bool Jpeg2000JasperReader::read(QImage *pImage)
+{
+    if (!jasperOk)
+        return false;
+
+    /*
+        Reading proceeds approximately as follows:
+        1. Open stream and decode using Jasper
+        2. Get image metadata
+        3. Change colorspace if necessary
+        4. Create a QImage of the appropriate type (32-bit for RGB,
+           8-bit for grayscale)
+        5. Copy image data from Jasper to the QImage
+
+        When copying the image data from the Jasper data structures to the
+        QImage, a generic copy function (copyJasperQt) iterates through the
+        scanlines and calls the provided (via the scanlineCopier argument)
+        scanline copy function for each scanline. The scanline copy function
+        selected according to image metadata such as color space and the
+        presence of an alpha channel.
+    */
+    QByteArray fileContents = ioDevice->readAll();
+    jas_stream_t *imageData = jas_stream_memopen(fileContents.data(),
+                                                 fileContents.size());
+    jasper_image = jas_image_decode(imageData, jas_image_getfmt(imageData), 0);
+    jas_stream_close(imageData);
+    if (!jasper_image) {
+        qDebug("Jasper library can't decode Jpeg2000 image data");
+        return false;
+    }
+    ScopedJasperImage scopedImage(jasper_image);
+    //printMetadata(jasper_image);
+
+    qtWidth = jas_image_width(jasper_image);
+    qtHeight = jas_image_height(jasper_image);
+    jasNumComponents = jas_image_numcmpts(jasper_image);
+    jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
+
+    bool needColorspaceChange = false;
+    if (jasperColorspaceFamily != JAS_CLRSPC_FAM_RGB &&
+        jasperColorspaceFamily != JAS_CLRSPC_FAM_GRAY)
+        needColorspaceChange = true;
+
+    // Get per-component data
+    int c;
+    for (c = 0; c < jasNumComponents; ++c) {
+        jasComponentPrecicion[c] = jas_image_cmptprec(jasper_image, c);
+
+        // Test for precision
+        if (jasComponentPrecicion[c] > 8 || jasComponentPrecicion[c] < 8)
+            needColorspaceChange = true;
+
+        // Test for subsampling
+        if (jas_image_cmpthstep(jasper_image, c) != 1 ||
+            jas_image_cmptvstep(jasper_image, c) != 1)
+            needColorspaceChange = true;
+
+        // Test for signed components
+        if (jas_image_cmptsgnd(jasper_image, c) != 0)
+            needColorspaceChange = true;
+    }
+
+    /*
+        If we encounter a different color space than RGB
+        (such as XYZ or YCbCr) we change that to RGB.
+        Also, if any component has "funny" metadata (such as precicion != 8 bits
+        or subsampling != 1) we also do a colorspace
+        change in order to convert it to something we can load.
+    */
+
+    bool decodeOk = true;
+    if (needColorspaceChange)
+        decodeOk = attemptColorspaceChange(JAS_CLRSPC_SRGB);
+
+    if (!decodeOk) {
+        printColorSpaceError();
+        return false;
+    }
+
+    // Image metadata may have changed, get from Jasper.
+    qtWidth = jas_image_width(jasper_image);
+    qtHeight = jas_image_height(jasper_image);
+    jasNumComponents = jas_image_numcmpts(jasper_image);
+    jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
+    for (c = 0; c < jasNumComponents; ++c) {
+        jasComponentPrecicion[c] = jas_image_cmptprec(jasper_image, c);
+    }
+
+    if (jasperColorspaceFamily != JAS_CLRSPC_FAM_RGB &&
+        jasperColorspaceFamily != JAS_CLRSPC_FAM_GRAY) {
+        qDebug("The Qt JPEG 2000 reader was unable to convert colorspace to RGB or grayscale");
+        return false;
+    }
+
+    // If a component has a subsampling factor != 1, we can't trust
+    // jas_image_height/width, so we need to figure it out ourselves
+    bool oddComponentSubsampling = false;
+    for (c = 0; c < jasNumComponents; ++c) {
+        if (jas_image_cmpthstep(jasper_image, c) != 1 ||
+            jas_image_cmptvstep(jasper_image, c) != 1) {
+            oddComponentSubsampling = true;
+        }
+    }
+
+    if (oddComponentSubsampling) {
+        // Check if all components have the same vertical/horizontal dim and
+        // subsampling
+        computedComponentWidth = jas_image_cmptwidth(jasper_image, 0);
+        computedComponentHeight = jas_image_cmptheight(jasper_image, 0);
+        computedComponentHorizontalSubsampling = jas_image_cmpthstep(jasper_image, 0);
+        computedComponentVerticalSubsampling = jas_image_cmptvstep(jasper_image, 0);
+
+        for (c = 1; c < jasNumComponents; ++c) {
+            if (computedComponentWidth != jas_image_cmptwidth(jasper_image, c) ||
+                computedComponentWidth != jas_image_cmptwidth(jasper_image, c) ||
+                computedComponentHorizontalSubsampling != jas_image_cmpthstep(jasper_image, c) ||
+                computedComponentVerticalSubsampling != jas_image_cmptvstep(jasper_image, c)) {
+                qDebug("The Qt JPEG 2000 reader does not support images where "
+                       "component geometry differs from image geometry");
+                return false;
+            }
+        }
+        qtWidth = computedComponentWidth * computedComponentHorizontalSubsampling;
+        qtHeight = computedComponentHeight * computedComponentVerticalSubsampling;
+    }
+
+    // Sanity check each component
+    for (c = 0; c < jasNumComponents; ++c) {
+        // Test for precision
+        if (jasComponentPrecicion[c]>8 || jasComponentPrecicion[c]<8) {
+            qDebug("The Qt JPEG 2000 reader does not support components with "
+                   "precision != 8");
+            decodeOk = false;
+        }
+#if 0
+        // Test the subsampling factor (space between pixels on the image grid)
+        if (oddComponentSubsampling) {
+            qDebug("The Qt JPEG 2000 reader does not support components with "
+                   "a subsampling factor != 1 (yet)");
+            decodeOk = false;
+        }
+#endif
+        // Test for signed components
+        if (jas_image_cmptsgnd(jasper_image, c) != 0) {
+            qDebug("Qt JPEG 2000 reader does not support signed components");
+            decodeOk = false;
+        }
+
+        // Test for component/image geomoetry mismach.
+        // If oddComponentSubsampling, then this is already taken care of above.
+        if (!oddComponentSubsampling)
+            if (jas_image_cmpttlx(jasper_image,c) != 0 ||
+                jas_image_cmpttly(jasper_image,c) != 0 ||
+                jas_image_cmptbrx(jasper_image,c) != jas_image_brx(jasper_image) ||
+                jas_image_cmptbry(jasper_image,c) != jas_image_bry(jasper_image) ||
+                jas_image_cmptwidth (jasper_image, c) != jas_image_width (jasper_image) ||
+                jas_image_cmptheight(jasper_image, c) != jas_image_height(jasper_image )) {
+                qDebug("The Qt JPEG 2000 reader does not support images where "
+                       "component geometry differs from image geometry");
+                printMetadata(jasper_image);
+                decodeOk = false;
+            }
+    }
+    if (!decodeOk)
+        return false;
+
+    // At this point, the colorspace should be either RGB or grayscale,
+    // and each component should have eight bits of precision and
+    // no unsupported geometry.
+    //printMetadata(jasper_image);
+
+    // Get color components
+    jasperColorspaceFamily = jas_clrspc_fam(jas_image_clrspc(jasper_image));
+    if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
+        if (jasNumComponents > 4)
+            qDebug("JPEG 2000 reader expected 3 or 4 components, got %d",
+                   jasNumComponents);
+
+        // Set up mapping from R,G,B -> component num.
+        colorComponentMapping[0] = jas_image_getcmptbytype(jasper_image,
+                                                           JAS_IMAGE_CT_RGB_R);
+        colorComponentMapping[1] = jas_image_getcmptbytype(jasper_image,
+                                                           JAS_IMAGE_CT_RGB_G);
+        colorComponentMapping[2] = jas_image_getcmptbytype(jasper_image,
+                                                           JAS_IMAGE_CT_RGB_B);
+        qtNumComponents = 3;
+    } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
+        if (jasNumComponents > 2)
+            qDebug("JPEG 2000 reader expected 1 or 2 components, got %d",
+                   jasNumComponents);
+        colorComponentMapping[0] = jas_image_getcmptbytype(jasper_image,
+                                    JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
+        qtNumComponents = 1;
+    } else {
+        printColorSpaceError();
+        return false;
+    }
+
+    // Get alpha component if one exists. Due to the lack of test images,
+    // loading images with alpha channels is a bit untested. It works
+    // with images saved with this implementation though.
+    const int posibleAlphaComponent1 = 3;
+    const int posibleAlphaComponent2 = 48;
+
+    if (jasNumComponents == qtNumComponents + 1) {
+        colorComponentMapping[qtNumComponents] = jas_image_getcmptbytype(jasper_image, posibleAlphaComponent1);
+        if (colorComponentMapping[qtNumComponents] < 0) {
+            colorComponentMapping[qtNumComponents] = jas_image_getcmptbytype(jasper_image, posibleAlphaComponent2);
+        }
+        if (colorComponentMapping[qtNumComponents] > 0) {
+            hasAlpha = true;
+            qtNumComponents++;
+        }
+    }
+
+    // Check for missing components
+    for (c = 0; c < qtNumComponents; ++c) {
+        if (colorComponentMapping[c] < 0) {
+            qDebug("JPEG 2000 reader missing a color component");
+            return false;
+        }
+    }
+
+    // Create a QImage of the correct type
+    if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
+        qtImage = QImage(qtWidth, qtHeight, hasAlpha
+                                                ? QImage::Format_ARGB32
+                                                : QImage::Format_RGB32);
+    } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
+        if (hasAlpha) {
+            qtImage = QImage(qtWidth, qtHeight, QImage::Format_ARGB32);
+        } else {
+            qtImage = QImage(qtWidth, qtHeight, QImage::Format_Indexed8);
+            qtImage.setColorCount(256);
+            for (int c = 0; c < 256; ++c)
+                qtImage.setColor(c, qRgb(c,c,c));
+        }
+    }
+
+    // Copy data
+    if (oddComponentSubsampling) {
+        // This is a hack really, copying of data with component subsampling
+        // != 1 doesn't fit in with the rest of the scanline copying framework.
+        copyJasperQtGeneric();
+    } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
+        if (hasAlpha)
+            copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtRGBA);
+        else
+            copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtRGB);
+    } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
+        if (hasAlpha)
+            copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtGrayA);
+        else
+            copyJasperQt(&Jpeg2000JasperReader::copyScanlineJasperQtGray);
+    }
+    if (decodeOk)
+        *pImage = qtImage;
+
+    return decodeOk;
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyJasperQtGeneric()
+{
+    // Create scanline data poinetrs
+    jas_matrix_t **jasperMatrix;
+    jas_seqent_t **jasperRow;
+    createJasperMatrix(jasperMatrix);
+    jasperRow = (jas_seqent_t**)malloc(jasNumComponents * sizeof(jas_seqent_t *));
+    Q_CHECK_PTR(jasperRow);
+
+    int imageY = 0;
+    for (int componentY = 0; componentY < computedComponentHeight; ++componentY) {
+        for (int c = 0; c < jasNumComponents; ++c) {
+            jas_image_readcmpt(jasper_image, colorComponentMapping[c], 0,
+                               componentY, computedComponentWidth, 1,
+                               jasperMatrix[c]);
+            jasperRow[c] = jas_matrix_getref(jasperMatrix[c], 0, 0);
+        }
+        for (int verticalSubsample = 0;
+                verticalSubsample < computedComponentVerticalSubsampling;
+                ++verticalSubsample) {
+            uchar *scanLineUchar = qtImage.scanLine(imageY);
+            QRgb *scanLineQRgb = reinterpret_cast<QRgb *>(scanLineUchar);
+            for (int componentX = 0; componentX < computedComponentWidth;
+                    ++componentX) {
+                for (int horizontalSubsample = 0;
+                        horizontalSubsample <
+                            computedComponentHorizontalSubsampling;
+                        ++horizontalSubsample) {
+                    if (jasperColorspaceFamily == JAS_CLRSPC_FAM_RGB) {
+                        if (hasAlpha) {
+                            *scanLineQRgb++ = (jasperRow[3][componentX] << 24) |
+                                              (jasperRow[0][componentX] << 16) |
+                                              (jasperRow[1][componentX] << 8) |
+                                              jasperRow[2][componentX];
+                        } else {
+                            *scanLineQRgb++ = (jasperRow[0][componentX] << 16) |
+                                              (jasperRow[1][componentX] << 8) |
+                                              jasperRow[2][componentX];
+                        }
+                    } else if (jasperColorspaceFamily == JAS_CLRSPC_FAM_GRAY) {
+                        if (hasAlpha) {
+                            *scanLineQRgb++ = (jasperRow[1][componentX] << 24) |
+                                              (jasperRow[0][componentX] << 16) |
+                                              (jasperRow[0][componentX] << 8) |
+                                              jasperRow[0][componentX];
+                        } else {
+                            *scanLineUchar++ = jasperRow[0][componentX];
+                        }
+                    }
+                }
+            }
+            ++imageY;
+        }
+    }
+}
+
+/*!
+    \internal
+    Copies data from Jasper to QImage. The scanlineCopier parameter specifies
+    which function to use for handling each scan line.
+*/
+void Jpeg2000JasperReader::copyJasperQt(const ScanlineFunc scanlineCopier)
+{
+    // Create scanline data poinetrs
+    jas_matrix_t **jasperMatrix;
+    jas_seqent_t **jasperRow;
+
+    createJasperMatrix(jasperMatrix);
+    jasperRow = (jas_seqent_t**)malloc(jasNumComponents * sizeof(jas_seqent_t *));
+    Q_CHECK_PTR(jasperRow);
+
+    for (int scanline = 0; scanline < qtHeight; ++scanline) {
+        for (int c = 0; c < jasNumComponents; ++c) {
+            jas_image_readcmpt(jasper_image, colorComponentMapping[c], 0,
+                               scanline, qtWidth, 1, jasperMatrix[c]);
+            jasperRow[c] = jas_matrix_getref(jasperMatrix[c], 0, 0);
+        }
+        (this->*scanlineCopier)(jasperRow, qtImage.scanLine(scanline));
+    }
+
+    freeJasperMatrix(jasperMatrix);
+    free(jasperRow);
+}
+
+/*!
+    \internal
+    Copies RGB data from Jasper to a 32-bit QImage.
+*/
+void Jpeg2000JasperReader::copyScanlineJasperQtRGB(
+                            jas_seqent_t ** const jasperRow, uchar *qtScanLine)
+{
+    QRgb *scanLine = reinterpret_cast<QRgb *>(qtScanLine);
+    for (int c = 0; c < qtWidth; ++c) {
+        *scanLine++ = (0xFF << 24) |
+                      (jasperRow[0][c] << 16) |
+                      (jasperRow[1][c] << 8) |
+                      jasperRow[2][c];
+    }
+}
+
+/*!
+    \internal
+    Copies RGBA data from Jasper to a 32-bit QImage.
+*/
+void Jpeg2000JasperReader::copyScanlineJasperQtRGBA(jas_seqent_t ** const jasperRow,  uchar *qtScanLine)
+{
+    QRgb *scanLine = reinterpret_cast<QRgb *>(qtScanLine);
+    for (int c = 0; c < qtWidth; ++c) {
+        *scanLine++ = (jasperRow[3][c] << 24) |
+                      (jasperRow[0][c] << 16) |
+                      (jasperRow[1][c] << 8) |
+                      jasperRow[2][c];
+    }
+}
+
+/*!
+    \internal
+    Copies data from a grayscale image to an 8-bit QImage.
+*/
+void Jpeg2000JasperReader::copyScanlineJasperQtGray(jas_seqent_t ** const jasperRow,  uchar *qtScanLine)
+{
+    for (int c = 0; c < qtWidth; ++c) {
+        // *qtScanLine++ = (jasperRow[0][c] >> (jasComponentPrecicion[0] - 8));
+        *qtScanLine++ = jasperRow[0][c];
+    }
+}
+
+/*!
+    \internal
+    Copies data from a grayscale image to a 32-bit QImage.
+    Note that in this case we use an 32-bit image for grayscale data, since the
+    alpha value is per-pixel, not per-color (per-color alpha is supported by
+    8-bit QImage).
+*/
+void Jpeg2000JasperReader::copyScanlineJasperQtGrayA(jas_seqent_t ** const jasperRow,  uchar *qtScanLine)
+{
+    QRgb *scanLine = reinterpret_cast<QRgb *>(qtScanLine);
+    for (int c = 0; c < qtWidth; ++c) {
+        *scanLine++ = (jasperRow[1][c] << 24) |
+                      (jasperRow[0][c] << 16) |
+                      (jasperRow[0][c] << 8) |
+                      jasperRow[0][c];
+    }
+}
+
+/*!
+    Opens the file data and attempts to decode it using the Jasper library.
+    Returns true on success, false on failure.
+
+    32-bit and color mapped color images are encoded as RGB images,
+    color mapped grayscale images are encoded as grayscale images
+*/
+bool Jpeg2000JasperReader::write(const QImage &image, int quality)
+{
+    if (!jasperOk)
+        return false;
+
+    qtImage = image;
+
+    qtHeight = qtImage.height();
+    qtWidth = qtImage.width();
+    qtDepth = qtImage.depth();
+
+    if (qtDepth == 32) { // RGB(A)
+        jasper_image = newRGBAImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
+        if (qtImage.hasAlphaChannel())
+            copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperRGBA);
+        else
+            copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperRGB);
+    } else if (qtDepth == 8) {
+        // Color mapped grayscale
+        if (qtImage.allGray()) {
+            jasper_image = newGrayscaleImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
+            if (qtImage.hasAlphaChannel())
+                copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscaleA);
+            else
+                copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscale);
+        } else {
+            // Color mapped color
+            jasper_image = newRGBAImage(qtWidth, qtHeight, qtImage.hasAlphaChannel());
+            if (qtImage.hasAlphaChannel())
+                copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapRGBA);
+            else
+                copyQtJasper(&Jpeg2000JasperReader::copyScanlineQtJasperColormapRGB);
+        }
+    } else {
+        qDebug("Unable to handle color depth %d", qtDepth);
+        return false;
+    }
+
+    int fmtid;
+    if (format == Jp2Format)
+        fmtid = jas_image_strtofmt(const_cast<char*>("jp2"));
+    else /* if (format == J2cFormat) */
+        // JasPer refers to the code stream format as jpc
+        fmtid = jas_image_strtofmt(const_cast<char*>("jpc"));
+
+    const int minQuality = 0;
+    const int maxQuality = 100;
+
+    if (quality == -1)
+        quality = 100;
+    if (quality <= minQuality)
+        quality = minQuality;
+    if (quality > maxQuality)
+        quality = maxQuality;
+
+    // Qt specifies quality as an integer in the range 0..100. Jasper specifies
+    // compression rate as an real in the range 0..1, where 1 corresponds to no
+    // compression. Computing the rate from quality is difficult, large images
+    // get better image quality than small images at the same rate. If the rate
+    // is too low, Jasper will generate a completely black image.
+    // minirate is the smallest safe rate value.
+    const double minRate = 0.001;
+
+    // maxRate specifies maximum target rate, which give the minimum amount
+    // of compression. Tests show that maxRates higer than 0.3 give no
+    // additional image quality for most images. Large images could use an even
+    // smaller maxRate value.
+    const double maxRate = 0.3;
+
+    // Set jasperRate to a value in the range minRate..maxRate. Distribute the
+    // quality steps more densely at the lower end if the rate scale.
+    const double jasperRate = minRate + pow((double(quality) / double(maxQuality)), 2) * maxRate;
+
+    // The Jasper format string contains two options:
+    // rate: rate=x
+    // lossy/lossless compression : mode=real/mode=int
+    QString jasperFormatString;
+
+    // If quality is not maxQuality, we set lossy encoding.
+    // (lossless is default)
+    if (quality != maxQuality) {
+        jasperFormatString += QLatin1String("mode=real");
+        jasperFormatString += QString(QLatin1String(" rate=%1")).arg(jasperRate);
+    }
+
+    // Open an empty jasper stream that grows automatically
+    jas_stream_t * memory_stream = jas_stream_memopen(0, -1);
+
+    // Jasper wants a non-const string.
+    char *str = qstrdup(jasperFormatString.toLatin1().constData());
+    jas_image_encode(jasper_image, memory_stream, fmtid, str);
+    delete[] str;
+    jas_stream_flush(memory_stream);
+
+    // jas_stream_t::obj_ is a void* which points to the stream implementation,
+    // e.g a file stream or a memory stream. But in our case we know that it is
+    // a memory stream since we created the object, so we just reiterpret_cast
+    // here..
+    char *buffer = reinterpret_cast<char *>(reinterpret_cast<jas_stream_memobj_t*>(memory_stream->obj_)->buf_);
+    qint64 length = jas_stream_length(memory_stream);
+    ioDevice->write(buffer, length);
+
+    jas_stream_close(memory_stream);
+    jas_image_destroy(jasper_image);
+
+    return true;
+}
+
+/*!
+    \internal
+    Copies data from qtImage to JasPer. The scanlineCopier parameter specifies
+    which function to use for handling each scan line.
+*/
+void Jpeg2000JasperReader::copyQtJasper(const ScanlineFuncWrite scanlinecopier)
+{
+    // Create jasper matrix for holding one scanline
+    jas_matrix_t **jasperMatrix;
+    createJasperMatrix(jasperMatrix);
+
+    for (int scanline = 0; scanline < qtHeight; ++scanline) {
+        (this->*scanlinecopier)(jasperMatrix, qtImage.scanLine(scanline));
+
+        // Write a scanline of data to jasper_image
+        for (int c = 0; c < jasNumComponents; ++c)
+            jas_image_writecmpt(jasper_image, c, 0, scanline, qtWidth, 1,
+                                jasperMatrix[c]);
+    }
+    freeJasperMatrix(jasperMatrix);
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperRGB(jas_matrix_t ** jasperRow,
+                                                   uchar *qtScanLine)
+{
+    QRgb *scanLineBuffer = reinterpret_cast<QRgb *>(qtScanLine);
+    for (int col = 0; col < qtWidth; ++col) {
+        jas_matrix_set(jasperRow[0], 0, col, (*scanLineBuffer & 0xFF0000) >> 16);
+        jas_matrix_set(jasperRow[1], 0, col, (*scanLineBuffer & 0x00FF00) >> 8);
+        jas_matrix_set(jasperRow[2], 0, col, *scanLineBuffer & 0x0000FF);
+        ++scanLineBuffer;
+    }
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperRGBA(jas_matrix_t ** jasperRow,
+                                                    uchar *qtScanLine)
+{
+    QRgb *scanLineBuffer = reinterpret_cast<QRgb *>(qtScanLine);
+    for (int col = 0; col < qtWidth; ++col) {
+        jas_matrix_set(jasperRow[3], 0, col, (*scanLineBuffer & 0xFF000000) >> 24);
+        jas_matrix_set(jasperRow[0], 0, col, (*scanLineBuffer & 0x00FF0000) >> 16);
+        jas_matrix_set(jasperRow[1], 0, col, (*scanLineBuffer & 0x0000FF00) >> 8);
+        jas_matrix_set(jasperRow[2], 0, col, *scanLineBuffer & 0x000000FF);
+        ++scanLineBuffer;
+    }
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperColormapRGB(jas_matrix_t ** jasperRow,
+                                                           uchar *qtScanLine)
+{
+    for (int col = 0; col < qtWidth; ++col) {
+        QRgb color = qtImage.color(*qtScanLine);
+        jas_matrix_set(jasperRow[0], 0, col, qRed(color));
+        jas_matrix_set(jasperRow[1], 0, col, qGreen(color));
+        jas_matrix_set(jasperRow[2], 0, col, qBlue(color));
+        ++qtScanLine;
+    }
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperColormapRGBA(jas_matrix_t ** jasperRow,
+                                                            uchar *qtScanLine)
+{
+    for (int col = 0; col < qtWidth; ++col) {
+        QRgb color = qtImage.color(*qtScanLine);
+        jas_matrix_set(jasperRow[0], 0, col, qRed(color));
+        jas_matrix_set(jasperRow[1], 0, col, qGreen(color));
+        jas_matrix_set(jasperRow[2], 0, col, qBlue(color));
+        jas_matrix_set(jasperRow[3], 0, col, qAlpha(color));
+        ++qtScanLine;
+    }
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscale(jas_matrix_t ** jasperRow,
+                                                                 uchar *qtScanLine)
+{
+    for (int col = 0; col < qtWidth; ++col) {
+        QRgb color = qtImage.color(*qtScanLine);
+        jas_matrix_set(jasperRow[0], 0, col, qGray(color));
+        ++qtScanLine;
+    }
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::copyScanlineQtJasperColormapGrayscaleA(jas_matrix_t ** jasperRow,
+                                                                  uchar *qtScanLine)
+{
+    for (int col = 0; col < qtWidth; ++col) {
+        QRgb color = qtImage.color(*qtScanLine);
+        jas_matrix_set(jasperRow[0], 0, col, qGray(color));
+        jas_matrix_set(jasperRow[1], 0, col, qAlpha(color));
+        ++qtScanLine;
+    }
+}
+
+/*!
+    \internal
+    Attempts to change the color space for the image to wantedColorSpace using
+    the JasPer library
+*/
+bool Jpeg2000JasperReader::attemptColorspaceChange(int wantedColorSpace)
+{
+    //qDebug("Attemting color space change");
+    jas_cmprof_t *outprof;
+    if (!(outprof = jas_cmprof_createfromclrspc(wantedColorSpace)))
+        return false;
+
+    jas_image_t *newimage;
+    if (!(newimage = jas_image_chclrspc(jasper_image, outprof,
+                                        JAS_CMXFORM_INTENT_PER))) {
+        jas_cmprof_destroy(outprof);
+        return false;
+    }
+    jas_image_destroy(jasper_image);
+    jas_cmprof_destroy(outprof);
+    jasper_image = newimage;
+    return true;
+}
+
+/*!
+    \internal
+    Set up a component with parameters suitable for storing a QImage.
+*/
+jas_image_cmptparm_t Jpeg2000JasperReader::createComponentMetadata(
+                                            const int width, const int height)
+{
+    jas_image_cmptparm_t param;
+    param.tlx = 0;
+    param.tly = 0;
+    param.hstep = 1;
+    param.vstep = 1;
+    param.width = width;
+    param.height = height;
+    param.prec = 8;
+    param.sgnd = 0;
+    return param;
+}
+
+/*!
+    \internal
+    Create a new RGB JasPer image with a possible alpha channel.
+*/
+jas_image_t* Jpeg2000JasperReader::newRGBAImage(const int width,
+                                                const int height, bool alpha)
+{
+    jasNumComponents = alpha ? 4 : 3;
+    jas_image_cmptparm_t *params = new jas_image_cmptparm_t[jasNumComponents];
+    jas_image_cmptparm_t param = createComponentMetadata(width, height);
+    for (int c=0; c < jasNumComponents; c++)
+        params[c] = param;
+    jas_image_t *newImage = jas_image_create(jasNumComponents, params,
+                                             JAS_CLRSPC_SRGB);
+
+    jas_image_setcmpttype(newImage, 0, JAS_IMAGE_CT_RGB_R);
+    jas_image_setcmpttype(newImage, 1, JAS_IMAGE_CT_RGB_G);
+    jas_image_setcmpttype(newImage, 2, JAS_IMAGE_CT_RGB_B);
+
+    /*
+        It is unclear how one stores opacity(alpha) components with JasPer,
+        the following seems to have no effect. The opacity component gets
+        type id 3 or 48 depending jp2 or j2c format no matter what one puts
+        in here.
+
+        The symbols are defined as follows:
+        #define JAS_IMAGE_CT_RGB_R 0
+        #define JAS_IMAGE_CT_RGB_G 1
+        #define JAS_IMAGE_CT_RGB_B 2
+        #define JAS_IMAGE_CT_OPACITY 0x7FFF
+    */
+    if (alpha)
+        jas_image_setcmpttype(newImage, 3, JAS_IMAGE_CT_OPACITY);
+    delete[] params;
+    return newImage;
+}
+
+/*!
+    \internal
+    Create a new RGB JasPer image with a possible alpha channel.
+*/
+jas_image_t *Jpeg2000JasperReader::newGrayscaleImage(const int width,
+                                                     const int height,
+                                                     bool alpha)
+{
+    jasNumComponents = alpha ? 2 : 1;
+    jas_image_cmptparm_t param = createComponentMetadata(width, height);
+    jas_image_t *newImage = jas_image_create(1, &param, JAS_CLRSPC_SGRAY);
+
+    jas_image_setcmpttype(newImage, 0, JAS_IMAGE_CT_GRAY_Y);
+
+    // See corresponding comment for newRGBAImage.
+    if (alpha)
+        jas_image_setcmpttype(newImage, 1, JAS_IMAGE_CT_OPACITY);
+    return newImage;
+}
+
+/*!
+    \internal
+    Allocate data structures that hold image data during transfer from the
+    JasPer data structures to QImage.
+*/
+bool Jpeg2000JasperReader::createJasperMatrix(jas_matrix_t **&matrix)
+{
+    matrix = (jas_matrix_t**)malloc(jasNumComponents * sizeof(jas_matrix_t *));
+    for (int c = 0; c < jasNumComponents; ++c)
+        matrix[c] = jas_matrix_create(1, qtWidth);
+    return true;
+}
+
+/*!
+    \internal
+    Free data structures that hold image data during transfer from the
+    JasPer data structures to QImage.
+*/
+bool Jpeg2000JasperReader::freeJasperMatrix(jas_matrix_t **matrix)
+{
+    for (int c = 0; c < jasNumComponents; ++c)
+        jas_matrix_destroy(matrix[c]);
+    free(matrix);
+    return false;
+}
+
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::printColorSpaceError()
+{
+    QString colorspaceFamily, colorspaceSpecific;
+    decodeColorSpace(jas_image_clrspc(jasper_image), colorspaceFamily,
+                     colorspaceSpecific);
+    qDebug("Jpeg2000 decoder is not able to handle color space %s - %s",
+           qPrintable(colorspaceFamily), qPrintable(colorspaceSpecific));
+}
+/*!
+    \internal
+*/
+bool Jpeg2000JasperReader::decodeColorSpace(int clrspc, QString &family,
+                                                        QString &specific)
+{
+    int fam = jas_clrspc_fam(clrspc);
+    int mbr = jas_clrspc_mbr(clrspc);
+
+    switch (fam) {
+        case 0: family = QLatin1String("JAS_CLRSPC_FAM_UNKNOWN"); break;
+        case 1: family = QLatin1String("JAS_CLRSPC_FAM_XYZ"); break;
+        case 2: family = QLatin1String("JAS_CLRSPC_FAM_LAB"); break;
+        case 3: family = QLatin1String("JAS_CLRSPC_FAM_GRAY"); break;
+        case 4: family = QLatin1String("JAS_CLRSPC_FAM_RGB"); break;
+        case 5: family = QLatin1String("JAS_CLRSPC_FAM_YCBCR"); break;
+        default: family = QLatin1String("Unknown"); return false;
+    }
+
+    switch (mbr) {
+        case 0:
+            switch (fam) {
+                case 1: specific = QLatin1String("JAS_CLRSPC_CIEXYZ"); break;
+                case 2: specific = QLatin1String("JAS_CLRSPC_CIELAB"); break;
+                case 3: specific = QLatin1String("JAS_CLRSPC_SGRAY"); break;
+                case 4: specific = QLatin1String("JAS_CLRSPC_SRGB"); break;
+                case 5: specific = QLatin1String("JAS_CLRSPC_SYCBCR"); break;
+                default: specific = QLatin1String("Unknown"); return false;
+            }
+            break;
+        case 1:
+            switch (fam) {
+                case 3: specific = QLatin1String("JAS_CLRSPC_GENGRAY"); break;
+                case 4: specific = QLatin1String("JAS_CLRSPC_GENRGB"); break;
+                case 5: specific = QLatin1String("JAS_CLRSPC_GENYCBCR"); break;
+                default: specific = QLatin1String("Unknown"); return false;
+            }
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+/*!
+    \internal
+*/
+void Jpeg2000JasperReader::printMetadata(jas_image_t *image)
+{
+#ifndef QT_NO_DEBUG
+    // jas_image_cmptparm_t param
+    qDebug("Image width: %d", jas_image_width(image));
+    qDebug("Image height: %d", jas_image_height(image));
+    qDebug("Coordinates on reference grid: (%d,%d) (%d,%d)",
+           jas_image_tlx(image), jas_image_tly(image),
+           jas_image_brx(image), jas_image_bry(image));
+    qDebug("Number of image components: %d", jas_image_numcmpts(image));
+
+    QString colorspaceFamily;
+    QString colorspaceSpecific;
+    decodeColorSpace(jas_image_clrspc(image), colorspaceFamily, colorspaceSpecific);
+    qDebug("Color model (space): %d, %s - %s", jas_image_clrspc(image),
+           qPrintable(colorspaceFamily), qPrintable(colorspaceSpecific));
+
+    qDebug("Component metadata:");
+
+    for (int c = 0; c < jas_image_numcmpts(image); ++c) {
+        qDebug("Component %d:", c);
+        qDebug("    Component type: %d", jas_image_cmpttype(image, c));
+        qDebug("    Width: %d", jas_image_cmptwidth(image, c));
+        qDebug("    Height: %d", jas_image_cmptheight(image, c));
+        qDebug("    Signedness: %d", jas_image_cmptsgnd(image, c));
+        qDebug("    Precision: %d", jas_image_cmptprec(image, c));
+        qDebug("    Horizontal subsampling factor: %d",jas_image_cmpthstep(image, c));
+        qDebug("    Vertical subsampling factor: %d",  jas_image_cmptvstep(image, c));
+        qDebug("    Coordinates on reference grid: (%d,%d) (%d,%d)",
+               jas_image_cmpttlx(image, c), jas_image_cmpttly(image, c),
+               jas_image_cmptbrx(image, c), jas_image_cmptbry(image, c));
+    }
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/jp2/qjp2handler.pri b/src/plugins/imageformats/jp2/qjp2handler.pri
new file mode 100644
index 00000000..539daaab
--- /dev/null
+++ b/src/plugins/imageformats/jp2/qjp2handler.pri
@@ -0,0 +1,10 @@
+# common to plugin and built-in forms
+INCLUDEPATH *= $$PWD
+HEADERS += $$PWD/qjp2handler_p.h
+SOURCES += $$PWD/qjp2handler.cpp
+config_jasper {
+    msvc: LIBS += libjasper.lib
+    else: LIBS += -ljasper
+} else {
+    include($$PWD/../../../3rdparty/jasper.pri)
+}
diff --git a/src/plugins/imageformats/jp2/qjp2handler_p.h b/src/plugins/imageformats/jp2/qjp2handler_p.h
new file mode 100644
index 00000000..4895bb88
--- /dev/null
+++ b/src/plugins/imageformats/jp2/qjp2handler_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Petroules Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the JP2 plugins in the Qt ImageFormats module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJP2HANDLER_H
+#define QJP2HANDLER_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qimageiohandler.h>
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+class QByteArray;
+class QIODevice;
+class QVariant;
+class QJp2HandlerPrivate;
+
+class QJp2Handler : public QImageIOHandler
+{
+public:
+    QJp2Handler();
+    virtual ~QJp2Handler();
+    static bool canRead(QIODevice *iod, QByteArray *subType);
+    virtual bool canRead() const;
+    virtual bool read(QImage *image);
+    virtual bool write(const QImage &image);
+    virtual QVariant option(ImageOption option) const;
+    virtual void setOption(ImageOption option, const QVariant &value);
+    virtual bool supportsOption(ImageOption option) const;
+    virtual QByteArray name() const;
+
+private:
+    Q_DECLARE_PRIVATE(QJp2Handler)
+    QScopedPointer<QJp2HandlerPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QJP2HANDLER_P_H
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 109f216a..73f1014a 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -3,6 +3,7 @@ SUBDIRS = \
     tga \
     wbmp \
     dds \
-    icns
+    icns \
+    jp2
 
 contains(QT_CONFIG, system-zlib): SUBDIRS += mng tiff
diff --git a/tests/auto/jp2/jp2.pro b/tests/auto/jp2/jp2.pro
new file mode 100644
index 00000000..26c2f836
--- /dev/null
+++ b/tests/auto/jp2/jp2.pro
@@ -0,0 +1,8 @@
+TARGET = tst_qjp2
+
+QT = core gui testlib
+CONFIG -= app_bundle
+CONFIG += testcase
+
+SOURCES += tst_qjp2.cpp
+RESOURCES += $$PWD/../../shared/images/jp2.qrc
diff --git a/tests/auto/jp2/tst_qjp2.cpp b/tests/auto/jp2/tst_qjp2.cpp
new file mode 100644
index 00000000..76087468
--- /dev/null
+++ b/tests/auto/jp2/tst_qjp2.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Petroules Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the MNG autotests in the Qt ImageFormats module.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtGui/QtGui>
+
+class tst_qjp2: public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void readImage_data();
+    void readImage();
+};
+
+void tst_qjp2::readImage_data()
+{
+    QTest::addColumn<QString>("fileName");
+    QTest::addColumn<QString>("referenceFileName");
+    QTest::addColumn<QSize>("size");
+
+    QTest::newRow("logo") << QString("logo.jp2") << QString("logo.bmp") << QSize(498, 80);
+}
+
+void tst_qjp2::readImage()
+{
+    QFETCH(QString, fileName);
+    QFETCH(QString, referenceFileName);
+    QFETCH(QSize, size);
+
+    QString path = QString(":/jp2/") + fileName;
+    QImageReader reader(path);
+    QVERIFY(reader.canRead());
+    QImage image = reader.read();
+    QVERIFY(!image.isNull());
+    QCOMPARE(image.size(), size);
+
+    path = QString(":jp2/") + referenceFileName;
+    QImageReader referenceReader(path);
+    QVERIFY(referenceReader.canRead());
+    QImage referenceImage = referenceReader.read();
+    QVERIFY(!referenceImage.isNull());
+    QCOMPARE(referenceImage.size(), size);
+
+    QCOMPARE(image, referenceImage);
+}
+
+QTEST_MAIN(tst_qjp2)
+#include "tst_qjp2.moc"
diff --git a/tests/shared/images/jp2.qrc b/tests/shared/images/jp2.qrc
new file mode 100644
index 00000000..f9520766
--- /dev/null
+++ b/tests/shared/images/jp2.qrc
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/">
+        <file>jp2/logo.bmp</file>
+        <file>jp2/logo.jp2</file>
+    </qresource>
+</RCC>
diff --git a/tests/shared/images/jp2/logo.bmp b/tests/shared/images/jp2/logo.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..735ba1b3dc1b353e562b79b4c631d0ab0e8e5de6
GIT binary patch
literal 119734
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
YJAY1dj>F*BpR9hpTK1!HC%*pw0fs{%3jhEB

literal 0
HcmV?d00001

diff --git a/tests/shared/images/jp2/logo.jp2 b/tests/shared/images/jp2/logo.jp2
new file mode 100644
index 0000000000000000000000000000000000000000..f99343db6d9459cde4f7cbdf4d9144b973cc2d7b
GIT binary patch
literal 27570
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

literal 0
HcmV?d00001

-- 
GitLab