From e5fce91de6ef72f15c7d31b16b2494f534c7157c Mon Sep 17 00:00:00 2001 From: Heiko Becker Date: Wed, 5 Aug 2015 22:52:52 +0200 Subject: [PATCH] Remove DDS and JPEG-2000 plugins They were already disabled when building with Qt >= 5.3 in commit 3d45b270ea8341d1516d5863cc49884c2744f2f2 because Qt has better plugins for those image formats. Now that we depend on Qt 5.3 we can remove them. REVIEW: 124636 --- CMakeLists.txt | 12 - README.md | 2 - autotests/CMakeLists.txt | 12 - autotests/read/jp2/bw.jp2 | Bin 306 -> 0 bytes autotests/read/jp2/bw.png | Bin 663 -> 0 bytes autotests/read/jp2/rgb.jp2 | Bin 303 -> 0 bytes autotests/read/jp2/rgb.png | Bin 510 -> 0 bytes autotests/write/bw.jp2 | Bin 306 -> 0 bytes autotests/write/rgb.jp2 | Bin 303 -> 0 bytes src/imageformats/CMakeLists.txt | 27 +- src/imageformats/config-jp2.h.cmake | 2 - src/imageformats/dds.cpp | 1038 --------------------------- src/imageformats/dds.desktop | 7 - src/imageformats/dds.json | 4 - src/imageformats/dds_p.h | 37 - src/imageformats/jp2.cpp | 526 -------------- src/imageformats/jp2.json | 4 - src/imageformats/jp2_p.h | 42 -- 18 files changed, 3 insertions(+), 1710 deletions(-) delete mode 100644 autotests/read/jp2/bw.jp2 delete mode 100644 autotests/read/jp2/bw.png delete mode 100644 autotests/read/jp2/rgb.jp2 delete mode 100644 autotests/read/jp2/rgb.png delete mode 100644 autotests/write/bw.jp2 delete mode 100644 autotests/write/rgb.jp2 delete mode 100644 src/imageformats/config-jp2.h.cmake delete mode 100644 src/imageformats/dds.cpp delete mode 100644 src/imageformats/dds.desktop delete mode 100644 src/imageformats/dds.json delete mode 100644 src/imageformats/dds_p.h delete mode 100644 src/imageformats/jp2.cpp delete mode 100644 src/imageformats/jp2.json delete mode 100644 src/imageformats/jp2_p.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e9915be..e04016d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,18 +34,6 @@ if (UNIX) endif() endif() -# QtImageFormats 5.3 comes with a JPEG-2000 plugin; don't duplicate it here -# TODO: remove our JPEG-2000 plugin when we depend on Qt 5.3. -if (Qt5Gui_VERSION VERSION_LESS 5.3.0) - find_package(Jasper) - set_package_properties(Jasper PROPERTIES - DESCRIPTION "A library for handling JPEG-2000 images" - PURPOSE "Required for the QImage plugin for JPEG-2000 images" - URL "http://www.ece.uvic.ca/~mdadams/jasper" - TYPE OPTIONAL - ) -endif() - find_package(OpenEXR) set_package_properties(OpenEXR PROPERTIES TYPE OPTIONAL diff --git a/README.md b/README.md index c22c8cf..7322db3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ image formats. The following image formats have read-only support: -- DirectDraw Surface (dds) - Gimp (xcf) - OpenEXR (exr) - Photoshop documents (psd) @@ -22,7 +21,6 @@ The following image formats have read-only support: The following image formats have read and write support: - Encapsulated PostScript (eps) -- JPEG-2000 (jp2) - Personal Computer Exchange (pcx) - SGI images (rgb, rgba, sgi, bw) - Softimage PIC (pic) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 8a2209d..853607e 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -86,22 +86,10 @@ kimageformats_write_tests( # kimageformats_read_tests(eps) # kimageformats_write_tests(eps) #endif() -if (JASPER_FOUND) - # FIXME: when we read JPEG2000 files on different architectures - # (specifically x86_64 and i386), we get off-by-one errors. The - # jasper utility does not have the same problem, so it is not a - # problem inherent in the jasper library. For now, we just allow - # a little fuzziness to make sure it does not get any worse (being - # off by one in an image value is not noticable to the human eye, - # so it is not a release-blocking issue). - kimageformats_read_tests(FUZZ 1 jp2) - kimageformats_write_tests(jp2) -endif() if (OpenEXR_FOUND) # FIXME: OpenEXR tests endif() - find_package(Qt5Test ${REQUIRED_QT_VERSION} CONFIG QUIET) if(NOT Qt5Test_FOUND) diff --git a/autotests/read/jp2/bw.jp2 b/autotests/read/jp2/bw.jp2 deleted file mode 100644 index 5e1ec4d5aab0c212400eae3e0129aa0d2d5f78bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvAUFj4@r8KAT-kj?;d#WFKeih#5N7&Ei818D{Z z{^b0eB1SM%07L>6C;#{VAIP8&7E=I{APfTvKn4gy05dxyBLw|VVNhmZbS_FwEXgmj zQt(PF4oEFh2um$0&dkqKFx0a&FwisnAH=`|)X2!l%EH3H_&H z#45^!DLR1x_8Hz2_On*e4h BM^yj- diff --git a/autotests/read/jp2/bw.png b/autotests/read/jp2/bw.png deleted file mode 100644 index 759028abd54182fe6bb2df5e0e526f26aa6c36ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 663 zcmV;I0%-k-P)Kl*v-$Knz5sOxZC1|En}zioU{bxBFUa&PlU%o@Ycm1XUUzcyJpxRVb(^K+L+wOQdbsd#^dKW0;vgJ-P3QXg@l! zM-|+M2*v}-Oe4Dsvoa!l?>Xlf<2;VFmT#}BmI%Oc9A5(ZyH2DVux@$*4aoGaV68dE zdV1P>dql=c;}`G?_yzm|egXd@{sLh3(I0+RO|1X`002ovPDHLkV1jYKD3JgF diff --git a/autotests/read/jp2/rgb.jp2 b/autotests/read/jp2/rgb.jp2 deleted file mode 100644 index 7aea73e28dccdca79ce6846e147f127f7737b096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvAUFj4@r8KAT-kj?;d#WFKeih#5N7&Ei818D{Z z{^b0eB1SM%07L>6C;#{VAIP8&7E=I{APfTvKn4gy05dxyBLw|VVNhmZbS_FwEXgmj zQt(PF4oEFh2um$0&dkqKFx0a&FwisnAH=`|)X2!l%EH3H_&H x#45^!DLR1xRkZ))>{FsG-14tjg!NtH|cYjiO0|NZN2>@?UL{0zz diff --git a/autotests/read/jp2/rgb.png b/autotests/read/jp2/rgb.png deleted file mode 100644 index 255fe53c7a72ea2954cac369633b6c6adc7c05ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 510 zcmVKR6%m%Fbo4A|Np}_fgWhfYNk$iXL^hd8Ofmt5Fo`Q zxK>r|`(9PYaqRnkR8=3UYCjH_tE!69HipI+W9Zs%W8kN?tq0q^AxVkX5s48bw#y!X zMMeNb0+2-M7l5@Ckb^Qw@`jI-#5Or{M`{d7Kq$IwTXhusayNeJPm6BP( z8qcOrjqPm(D}4fKPPk2OhpVbwww)k3*^?St+u;@9rGF&Z2B{$(w@@8s$M$)J=MtYy zp3!p%TByE%rw)1!;>(d-LnBeoCRf$#H?oBiZV#Ne(>I~%0Xe81g`WXtv7L1ON}?87 zyUK1N*DO~g#iuDdB|0^k#MRStLr$RrR8_ppK|d-F4g*kMvyHWp+PcZh=@yE8wh(~J zX5rBQ0P55;_e#InO^CAy2T7J;rubw40L5vH^(j3!%Tv*vQ&qRmSM;0g0Azf7A#VCz z%`$7Vn|nnE AT>t<8 diff --git a/autotests/write/bw.jp2 b/autotests/write/bw.jp2 deleted file mode 100644 index 5e1ec4d5aab0c212400eae3e0129aa0d2d5f78bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvAUFj4@r8KAT-kj?;d#WFKeih#5N7&Ei818D{Z z{^b0eB1SM%07L>6C;#{VAIP8&7E=I{APfTvKn4gy05dxyBLw|VVNhmZbS_FwEXgmj zQt(PF4oEFh2um$0&dkqKFx0a&FwisnAH=`|)X2!l%EH3H_&H z#45^!DLR1x_8Hz2_On*e4h BM^yj- diff --git a/autotests/write/rgb.jp2 b/autotests/write/rgb.jp2 deleted file mode 100644 index 7aea73e28dccdca79ce6846e147f127f7737b096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303 zcmZQzVBpCLP*C9IYUg5LU=T?wsVvAUFj4@r8KAT-kj?;d#WFKeih#5N7&Ei818D{Z z{^b0eB1SM%07L>6C;#{VAIP8&7E=I{APfTvKn4gy05dxyBLw|VVNhmZbS_FwEXgmj zQt(PF4oEFh2um$0&dkqKFx0a&FwisnAH=`|)X2!l%EH3H_&H x#45^!DLR1xRkZ))>{FsG-14tjg!NtH|cYjiO0|NZN2>@?UL{0zz diff --git a/src/imageformats/CMakeLists.txt b/src/imageformats/CMakeLists.txt index 7e75c21..8cf8d54 100644 --- a/src/imageformats/CMakeLists.txt +++ b/src/imageformats/CMakeLists.txt @@ -2,15 +2,7 @@ ################################## -if (Qt5Gui_VERSION VERSION_LESS 5.3.0) - add_library(kimg_dds MODULE dds.cpp) - target_link_libraries(kimg_dds Qt5::Gui) - - install(TARGETS kimg_dds DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats/) - install(FILES dds.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) -else() - install(FILES dds-qt.desktop RENAME dds.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) -endif() +install(FILES dds-qt.desktop RENAME dds.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) ################################## @@ -26,22 +18,9 @@ endif() ################################## -check_include_files(sys/types.h HAVE_SYS_TYPES_H) -check_include_files(stdint.h HAVE_STDINT_H) -configure_file(config-jp2.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-jp2.h) -if(JASPER_FOUND) - add_library(kimg_jp2 MODULE jp2.cpp) - target_compile_options(kimg_jp2 PRIVATE ${JASPER_DEFINITIONS}) - target_include_directories(kimg_jp2 PRIVATE ${JASPER_INCLUDE_DIR}) - target_link_libraries(kimg_jp2 Qt5::Gui ${JASPER_LIBRARIES}) - - install(TARGETS kimg_jp2 DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats/) - install(FILES jp2.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) -elseif (NOT Qt5Gui_VERSION VERSION_LESS 5.3.0) - # need this for Qt's version of the plugin - install(FILES jp2.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) -endif() +# need this for Qt's version of the plugin +install(FILES jp2.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/) ################################## diff --git a/src/imageformats/config-jp2.h.cmake b/src/imageformats/config-jp2.h.cmake deleted file mode 100644 index 1ef5135..0000000 --- a/src/imageformats/config-jp2.h.cmake +++ /dev/null @@ -1,2 +0,0 @@ -#cmakedefine01 HAVE_STDINT_H -#cmakedefine01 HAVE_SYS_TYPES_H diff --git a/src/imageformats/dds.cpp b/src/imageformats/dds.cpp deleted file mode 100644 index bef46b1..0000000 --- a/src/imageformats/dds.cpp +++ /dev/null @@ -1,1038 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Ignacio Castaño - - This program is free software; you can redistribute it and/or - modify it under the terms of the Lesser GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - Almost all this code is based on nVidia's DDS-loading example - and the DevIl's source code by Denton Woods. -*/ - -/* this code supports: - * reading: - * rgb and dxt dds files - * cubemap dds files - * volume dds files -- TODO - * writing: - * rgb dds files only -- TODO - */ - -#include "dds_p.h" - -#include -#include -#include -// #include - -#include // sqrtf - -#ifndef __USE_ISOC99 -#define sqrtf(x) ((float)sqrt(x)) -#endif - -typedef quint32 uint; -typedef quint16 ushort; -typedef quint8 uchar; - -#if !defined(MAKEFOURCC) -# define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - (uint(uchar(ch0)) | (uint(uchar(ch1)) << 8) | \ - (uint(uchar(ch2)) << 16) | (uint(uchar(ch3)) << 24 )) -#endif - -#define HORIZONTAL 1 -#define VERTICAL 2 -#define CUBE_LAYOUT HORIZONTAL - -struct Color8888 { - uchar r, g, b, a; -}; - -union Color565 { - struct { - ushort b : 5; - ushort g : 6; - ushort r : 5; - } c; - ushort u; -}; - -union Color1555 { - struct { - ushort b : 5; - ushort g : 5; - ushort r : 5; - ushort a : 1; - } c; - ushort u; -}; - -union Color4444 { - struct { - ushort b : 4; - ushort g : 4; - ushort r : 4; - ushort a : 4; - } c; - ushort u; -}; - -static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); -static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); -static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); -static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); -static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); -static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); -static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); -static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); - -static const uint DDSD_CAPS = 0x00000001l; -static const uint DDSD_PIXELFORMAT = 0x00001000l; -static const uint DDSD_WIDTH = 0x00000004l; -static const uint DDSD_HEIGHT = 0x00000002l; -static const uint DDSD_PITCH = 0x00000008l; - -static const uint DDSCAPS_TEXTURE = 0x00001000l; -static const uint DDSCAPS2_VOLUME = 0x00200000l; -static const uint DDSCAPS2_CUBEMAP = 0x00000200l; - -static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800l; -static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000l; -static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000l; - -static const uint DDPF_RGB = 0x00000040l; -static const uint DDPF_FOURCC = 0x00000004l; -static const uint DDPF_ALPHAPIXELS = 0x00000001l; - -enum DDSType { - DDS_A8R8G8B8 = 0, - DDS_A1R5G5B5 = 1, - DDS_A4R4G4B4 = 2, - DDS_R8G8B8 = 3, - DDS_R5G6B5 = 4, - DDS_DXT1 = 5, - DDS_DXT2 = 6, - DDS_DXT3 = 7, - DDS_DXT4 = 8, - DDS_DXT5 = 9, - DDS_RXGB = 10, - DDS_ATI2 = 11, - DDS_UNKNOWN -}; - -struct DDSPixelFormat { - uint size; - uint flags; - uint fourcc; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; -}; - -static QDataStream &operator>> (QDataStream &s, DDSPixelFormat &pf) -{ - s >> pf.size; - s >> pf.flags; - s >> pf.fourcc; - s >> pf.bitcount; - s >> pf.rmask; - s >> pf.gmask; - s >> pf.bmask; - s >> pf.amask; - return s; -} - -struct DDSCaps { - uint caps1; - uint caps2; - uint caps3; - uint caps4; -}; - -static QDataStream &operator>> (QDataStream &s, DDSCaps &caps) -{ - s >> caps.caps1; - s >> caps.caps2; - s >> caps.caps3; - s >> caps.caps4; - return s; -} - -struct DDSHeader { - uint size; - uint flags; - uint height; - uint width; - uint pitch; - uint depth; - uint mipmapcount; - uint reserved[11]; - DDSPixelFormat pf; - DDSCaps caps; - uint notused; -}; - -static QDataStream &operator>> (QDataStream &s, DDSHeader &header) -{ - s >> header.size; - s >> header.flags; - s >> header.height; - s >> header.width; - s >> header.pitch; - s >> header.depth; - s >> header.mipmapcount; - for (int i = 0; i < 11; i++) { - s >> header.reserved[i]; - } - s >> header.pf; - s >> header.caps; - s >> header.notused; - return s; -} - -static bool IsValid(const DDSHeader &header) -{ - if (header.size != 124) { - return false; - } - const uint required = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT); - if ((header.flags & required) != required) { - return false; - } - if (header.pf.size != 32) { - return false; - } - if (!(header.caps.caps1 & DDSCAPS_TEXTURE)) { - return false; - } - return true; -} - -// Get supported type. We currently support 10 different types. -static DDSType GetType(const DDSHeader &header) -{ - if (header.pf.flags & DDPF_RGB) { - if (header.pf.flags & DDPF_ALPHAPIXELS) { - switch (header.pf.bitcount) { - case 16: - return (header.pf.amask == 0x8000) ? DDS_A1R5G5B5 : DDS_A4R4G4B4; - case 32: - return DDS_A8R8G8B8; - } - } else { - switch (header.pf.bitcount) { - case 16: - return DDS_R5G6B5; - case 24: - return DDS_R8G8B8; - } - } - } else if (header.pf.flags & DDPF_FOURCC) { - switch (header.pf.fourcc) { - case FOURCC_DXT1: - return DDS_DXT1; - case FOURCC_DXT2: - return DDS_DXT2; - case FOURCC_DXT3: - return DDS_DXT3; - case FOURCC_DXT4: - return DDS_DXT4; - case FOURCC_DXT5: - return DDS_DXT5; - case FOURCC_RXGB: - return DDS_RXGB; - case FOURCC_ATI2: - return DDS_ATI2; - } - } - return DDS_UNKNOWN; -} - -static bool HasAlpha(const DDSHeader &header) -{ - return header.pf.flags & DDPF_ALPHAPIXELS; -} - -static bool IsCubeMap(const DDSHeader &header) -{ - return header.caps.caps2 & DDSCAPS2_CUBEMAP; -} - -static bool IsSupported(const DDSHeader &header) -{ - if (header.caps.caps2 & DDSCAPS2_VOLUME) { - return false; - } - if (GetType(header) == DDS_UNKNOWN) { - return false; - } - return true; -} - -static bool LoadA8R8G8B8(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - for (uint y = 0; y < h; y++) { - QRgb *scanline = (QRgb *) img.scanLine(y); - for (uint x = 0; x < w; x++) { - uchar r, g, b, a; - s >> b >> g >> r >> a; - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadR8G8B8(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - for (uint y = 0; y < h; y++) { - QRgb *scanline = (QRgb *) img.scanLine(y); - for (uint x = 0; x < w; x++) { - uchar r, g, b; - s >> b >> g >> r; - scanline[x] = qRgb(r, g, b); - } - } - - return true; -} - -static bool LoadA1R5G5B5(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - for (uint y = 0; y < h; y++) { - QRgb *scanline = (QRgb *) img.scanLine(y); - for (uint x = 0; x < w; x++) { - Color1555 color; - s >> color.u; - uchar a = (color.c.a != 0) ? 0xFF : 0; - uchar r = (color.c.r << 3) | (color.c.r >> 2); - uchar g = (color.c.g << 3) | (color.c.g >> 2); - uchar b = (color.c.b << 3) | (color.c.b >> 2); - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadA4R4G4B4(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - for (uint y = 0; y < h; y++) { - QRgb *scanline = (QRgb *) img.scanLine(y); - for (uint x = 0; x < w; x++) { - Color4444 color; - s >> color.u; - uchar a = (color.c.a << 4) | color.c.a; - uchar r = (color.c.r << 4) | color.c.r; - uchar g = (color.c.g << 4) | color.c.g; - uchar b = (color.c.b << 4) | color.c.b; - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadR5G6B5(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - for (uint y = 0; y < h; y++) { - QRgb *scanline = (QRgb *) img.scanLine(y); - for (uint x = 0; x < w; x++) { - Color565 color; - s >> color.u; - uchar r = (color.c.r << 3) | (color.c.r >> 2); - uchar g = (color.c.g << 2) | (color.c.g >> 4); - uchar b = (color.c.b << 3) | (color.c.b >> 2); - scanline[x] = qRgb(r, g, b); - } - } - - return true; -} - -static QDataStream &operator>> (QDataStream &s, Color565 &c) -{ - return s >> c.u; -} - -struct BlockDXT { - Color565 col0; - Color565 col1; - uchar row[4]; - - void GetColors(Color8888 color_array[4]) - { - color_array[0].r = (col0.c.r << 3) | (col0.c.r >> 2); - color_array[0].g = (col0.c.g << 2) | (col0.c.g >> 4); - color_array[0].b = (col0.c.b << 3) | (col0.c.b >> 2); - color_array[0].a = 0xFF; - - color_array[1].r = (col1.c.r << 3) | (col1.c.r >> 2); - color_array[1].g = (col1.c.g << 2) | (col1.c.g >> 4); - color_array[1].b = (col1.c.b << 3) | (col1.c.b >> 2); - color_array[1].a = 0xFF; - - if (col0.u > col1.u) { - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; - color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; - color_array[2].a = 0xFF; - - color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3; - color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; - color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; - color_array[3].a = 0xFF; - } else { - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; - } - } -}; - -static QDataStream &operator>> (QDataStream &s, BlockDXT &c) -{ - return s >> c.col0 >> c.col1 >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3]; -} - -struct BlockDXTAlphaExplicit { - ushort row[4]; -}; - -static QDataStream &operator>> (QDataStream &s, BlockDXTAlphaExplicit &c) -{ - return s >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3]; -} - -struct BlockDXTAlphaLinear { - uchar alpha0; - uchar alpha1; - uchar bits[6]; - - void GetAlphas(uchar alpha_array[8]) - { - alpha_array[0] = alpha0; - alpha_array[1] = alpha1; - - // 8-alpha or 6-alpha block? - if (alpha_array[0] > alpha_array[1]) { - // 8-alpha block: derive the other 6 alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - - alpha_array[2] = (6 * alpha0 + alpha1) / 7; // bit code 010 - alpha_array[3] = (5 * alpha0 + 2 * alpha1) / 7; // Bit code 011 - alpha_array[4] = (4 * alpha0 + 3 * alpha1) / 7; // Bit code 100 - alpha_array[5] = (3 * alpha0 + 4 * alpha1) / 7; // Bit code 101 - alpha_array[6] = (2 * alpha0 + 5 * alpha1) / 7; // Bit code 110 - alpha_array[7] = (alpha0 + 6 * alpha1) / 7; // Bit code 111 - } else { - // 6-alpha block: derive the other alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - - alpha_array[2] = (4 * alpha0 + alpha1) / 5; // Bit code 010 - alpha_array[3] = (3 * alpha0 + 2 * alpha1) / 5; // Bit code 011 - alpha_array[4] = (2 * alpha0 + 3 * alpha1) / 5; // Bit code 100 - alpha_array[5] = (alpha0 + 4 * alpha1) / 5; // Bit code 101 - alpha_array[6] = 0x00; // Bit code 110 - alpha_array[7] = 0xFF; // Bit code 111 - } - } - - void GetBits(uchar bit_array[16]) - { - // Split 24 packed bits into 8 bytes, 3 bits at a time. - uint b = bits[0] | bits[1] << 8 | bits[2] << 16; - bit_array[0] = uchar(b & 0x07); b >>= 3; - bit_array[1] = uchar(b & 0x07); b >>= 3; - bit_array[2] = uchar(b & 0x07); b >>= 3; - bit_array[3] = uchar(b & 0x07); b >>= 3; - bit_array[4] = uchar(b & 0x07); b >>= 3; - bit_array[5] = uchar(b & 0x07); b >>= 3; - bit_array[6] = uchar(b & 0x07); b >>= 3; - bit_array[7] = uchar(b & 0x07); - - b = bits[3] | bits[4] << 8 | bits[5] << 16; - bit_array[8] = uchar(b & 0x07); b >>= 3; - bit_array[9] = uchar(b & 0x07); b >>= 3; - bit_array[10] = uchar(b & 0x07); b >>= 3; - bit_array[11] = uchar(b & 0x07); b >>= 3; - bit_array[12] = uchar(b & 0x07); b >>= 3; - bit_array[13] = uchar(b & 0x07); b >>= 3; - bit_array[14] = uchar(b & 0x07); b >>= 3; - bit_array[15] = uchar(b & 0x07); - } -}; - -static QDataStream &operator>> (QDataStream &s, BlockDXTAlphaLinear &c) -{ - s >> c.alpha0 >> c.alpha1; - return s >> c.bits[0] >> c.bits[1] >> c.bits[2] >> c.bits[3] >> c.bits[4] >> c.bits[5]; -} - -static bool LoadDXT1(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - QRgb *scanline[4]; - - for (uint y = 0; y < h; y += 4) { - for (uint j = 0; j < 4; j++) { - scanline[j] = (QRgb *) img.scanLine(y + j); - } - for (uint x = 0; x < w; x += 4) { - - // Read 64bit color block. - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3 << 2, 3 << 4, 3 << 6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for (uint j = 0; j < 4; j++) { - for (uint i = 0; i < 4; i++) { - if (img.valid(x + i, y + j)) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - scanline[j][x + i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - } - } - } - } - return true; -} - -static bool LoadDXT3(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaExplicit alpha; - QRgb *scanline[4]; - - for (uint y = 0; y < h; y += 4) { - for (uint j = 0; j < 4; j++) { - scanline[j] = (QRgb *) img.scanLine(y + j); - } - for (uint x = 0; x < w; x += 4) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3 << 2, 3 << 4, 3 << 6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for (uint j = 0; j < 4; j++) { - ushort a = alpha.row[j]; - for (uint i = 0; i < 4; i++) { - if (img.valid(x + i, y + j)) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = a & 0x0f; - color_array[idx].a = color_array[idx].a | (color_array[idx].a << 4); - scanline[j][x + i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - a >>= 4; - } - } - } - } - return true; -} - -static bool LoadDXT2(QDataStream &s, const DDSHeader &header, QImage &img) -{ - if (!LoadDXT3(s, header, img)) { - return false; - } - //UndoPremultiplyAlpha(img); - return true; -} - -static bool LoadDXT5(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaLinear alpha; - QRgb *scanline[4]; - - for (uint y = 0; y < h; y += 4) { - for (uint j = 0; j < 4; j++) { - scanline[j] = (QRgb *) img.scanLine(y + j); - } - for (uint x = 0; x < w; x += 4) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - uchar alpha_array[8]; - alpha.GetAlphas(alpha_array); - - uchar bit_array[16]; - alpha.GetBits(bit_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3 << 2, 3 << 4, 3 << 6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for (uint j = 0; j < 4; j++) { - for (uint i = 0; i < 4; i++) { - if (img.valid(x + i, y + j)) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = alpha_array[bit_array[j * 4 + i]]; - scanline[j][x + i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - } - } - } - } - - return true; -} -static bool LoadDXT4(QDataStream &s, const DDSHeader &header, QImage &img) -{ - if (!LoadDXT5(s, header, img)) { - return false; - } - //UndoPremultiplyAlpha(img); - return true; -} - -static bool LoadRXGB(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaLinear alpha; - QRgb *scanline[4]; - - for (uint y = 0; y < h; y += 4) { - for (uint j = 0; j < 4; j++) { - scanline[j] = (QRgb *) img.scanLine(y + j); - } - for (uint x = 0; x < w; x += 4) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - uchar alpha_array[8]; - alpha.GetAlphas(alpha_array); - - uchar bit_array[16]; - alpha.GetBits(bit_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3 << 2, 3 << 4, 3 << 6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for (uint j = 0; j < 4; j++) { - for (uint i = 0; i < 4; i++) { - if (img.valid(x + i, y + j)) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = alpha_array[bit_array[j * 4 + i]]; - scanline[j][x + i] = qRgb(color_array[idx].a, color_array[idx].g, color_array[idx].b); - } - } - } - } - } - - return true; -} - -static bool LoadATI2(QDataStream &s, const DDSHeader &header, QImage &img) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXTAlphaLinear xblock; - BlockDXTAlphaLinear yblock; - QRgb *scanline[4]; - - for (uint y = 0; y < h; y += 4) { - for (uint j = 0; j < 4; j++) { - scanline[j] = (QRgb *) img.scanLine(y + j); - } - for (uint x = 0; x < w; x += 4) { - - // Read 128bit color block. - s >> xblock; - s >> yblock; - - // Decode color block. - uchar xblock_array[8]; - xblock.GetAlphas(xblock_array); - - uchar xbit_array[16]; - xblock.GetBits(xbit_array); - - uchar yblock_array[8]; - yblock.GetAlphas(yblock_array); - - uchar ybit_array[16]; - yblock.GetBits(ybit_array); - - // Write color block. - for (uint j = 0; j < 4; j++) { - for (uint i = 0; i < 4; i++) { - if (img.valid(x + i, y + j)) { - const uchar nx = xblock_array[xbit_array[j * 4 + i]]; - const uchar ny = yblock_array[ybit_array[j * 4 + i]]; - - const float fx = float(nx) / 127.5f - 1.0f; - const float fy = float(ny) / 127.5f - 1.0f; - const float fz = sqrtf(1.0f - fx * fx - fy * fy); - const uchar nz = uchar((fz + 1.0f) * 127.5f); - - scanline[j][x + i] = qRgb(nx, ny, nz); - } - } - } - } - } - - return true; -} - -typedef bool (* TextureLoader)(QDataStream &s, const DDSHeader &header, QImage &img); - -// Get an appropriate texture loader for the given type. -static TextureLoader GetTextureLoader(DDSType type) -{ - switch (type) { - case DDS_A8R8G8B8: - return LoadA8R8G8B8; - case DDS_A1R5G5B5: - return LoadA1R5G5B5; - case DDS_A4R4G4B4: - return LoadA4R4G4B4; - case DDS_R8G8B8: - return LoadR8G8B8; - case DDS_R5G6B5: - return LoadR5G6B5; - case DDS_DXT1: - return LoadDXT1; - case DDS_DXT2: - return LoadDXT2; - case DDS_DXT3: - return LoadDXT3; - case DDS_DXT4: - return LoadDXT4; - case DDS_DXT5: - return LoadDXT5; - case DDS_RXGB: - return LoadRXGB; - case DDS_ATI2: - return LoadATI2; - default: - return NULL; - }; -} - -// Load a 2d texture. -static bool LoadTexture(QDataStream &s, const DDSHeader &header, QImage &img) -{ - // Create dst image. - img = QImage(header.width, header.height, QImage::Format_RGB32); - - // Read image. - DDSType type = GetType(header); - - // Enable alpha buffer for transparent or DDS images. - if (HasAlpha(header) || type >= DDS_DXT1) { - img = img.convertToFormat(QImage::Format_ARGB32); - } - - TextureLoader loader = GetTextureLoader(type); - if (loader == NULL) { - return false; - } - - return loader(s, header, img); -} - -static int FaceOffset(const DDSHeader &header) -{ - - DDSType type = GetType(header); - - int mipmap = qMax(header.mipmapcount, 1U); - int size = 0; - int w = header.width; - int h = header.height; - - if (type >= DDS_DXT1) { - int multiplier = (type == DDS_DXT1) ? 8 : 16; - do { - int face_size = qMax(w / 4, 1) * qMax(h / 4, 1) * multiplier; - size += face_size; - w >>= 1; - h >>= 1; - } while (--mipmap); - } else { - int multiplier = header.pf.bitcount / 8; - do { - int face_size = w * h * multiplier; - size += face_size; - w = qMax(w >> 1, 1); - h = qMax(h >> 1, 1); - } while (--mipmap); - } - - return size; -} - -#if CUBE_LAYOUT == HORIZONTAL -static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {3, 1} }; -#elif CUBE_LAYOUT == VERTICAL -static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {1, 3} }; -#endif -static int face_flags[6] = { - DDSCAPS2_CUBEMAP_POSITIVEX, - DDSCAPS2_CUBEMAP_NEGATIVEX, - DDSCAPS2_CUBEMAP_POSITIVEY, - DDSCAPS2_CUBEMAP_NEGATIVEY, - DDSCAPS2_CUBEMAP_POSITIVEZ, - DDSCAPS2_CUBEMAP_NEGATIVEZ -}; - -// Load unwrapped cube map. -static bool LoadCubeMap(QDataStream &s, const DDSHeader &header, QImage &img) -{ - // Create dst image. -#if CUBE_LAYOUT == HORIZONTAL - img = QImage(4 * header.width, 3 * header.height, QImage::Format_RGB32); -#elif CUBE_LAYOUT == VERTICAL - img = QImage(3 * header.width, 4 * header.height, QImage::Format_RGB32); -#endif - - DDSType type = GetType(header); - - // Enable alpha buffer for transparent or DDS images. - if (HasAlpha(header) || type >= DDS_DXT1) { - img = img.convertToFormat(QImage::Format_ARGB32); - } - - // Select texture loader. - TextureLoader loader = GetTextureLoader(type); - if (loader == NULL) { - return false; - } - - // Clear background. - img.fill(0); - - // Create face image. - QImage face(header.width, header.height, QImage::Format_RGB32); - - int offset = s.device()->pos(); - int size = FaceOffset(header); - - for (int i = 0; i < 6; i++) { - - if (!(header.caps.caps2 & face_flags[i])) { - // Skip face. - continue; - } - - // Seek device. - s.device()->seek(offset); - offset += size; - - // Load face from stream. - if (!loader(s, header, face)) { - return false; - } - -#if CUBE_LAYOUT == VERTICAL - if (i == 5) { - face = face.mirror(true, true); - } -#endif - - // Compute face offsets. - int offset_x = face_offset[i][0] * header.width; - int offset_y = face_offset[i][1] * header.height; - - // Copy face on the image. - for (uint y = 0; y < header.height; y++) { - QRgb *src = (QRgb *) face.scanLine(y); - QRgb *dst = (QRgb *) img.scanLine(y + offset_y) + offset_x; - memcpy(dst, src, sizeof(QRgb) * header.width); - } - } - - return true; -} - -DDSHandler::DDSHandler() -{ -} - -bool DDSHandler::canRead() const -{ - if (canRead(device())) { - setFormat("dds"); - return true; - } - return false; -} - -bool DDSHandler::read(QImage *image) -{ - QDataStream s(device()); - s.setByteOrder(QDataStream::LittleEndian); - - // Validate header. - uint fourcc; - s >> fourcc; - if (fourcc != FOURCC_DDS) { -// qDebug() << "This is not a DDS file."; - return false; - } - - // Read image header. - DDSHeader header; - s >> header; - - // Check image file format. - if (s.atEnd() || !IsValid(header)) { -// qDebug() << "This DDS file is not valid."; - return false; - } - - // Determine image type, by now, we only support 2d textures. - if (!IsSupported(header)) { -// qDebug() << "This DDS file is not supported."; - return false; - } - - bool result; - - if (IsCubeMap(header)) { - result = LoadCubeMap(s, header, *image); - } else { - result = LoadTexture(s, header, *image); - } - - return result; -} - -bool DDSHandler::canRead(QIODevice *device) -{ - if (!device) { - qWarning("DDSHandler::canRead() called with no device"); - return false; - } - - qint64 oldPos = device->pos(); - - char head[3]; - qint64 readBytes = device->read(head, sizeof(head)); - if (readBytes != sizeof(head)) { - if (device->isSequential()) { - while (readBytes > 0) { - device->ungetChar(head[readBytes-- - 1]); - } - } else { - device->seek(oldPos); - } - return false; - } - - if (device->isSequential()) { - while (readBytes > 0) { - device->ungetChar(head[readBytes-- - 1]); - } - } else { - device->seek(oldPos); - } - - return qstrncmp(head, "DDS", 3) == 0; -} - -QImageIOPlugin::Capabilities DDSPlugin::capabilities(QIODevice *device, const QByteArray &format) const -{ - if (format == "dds") { - return Capabilities(CanRead); - } - if (!format.isEmpty()) { - return 0; - } - if (!device->isOpen()) { - return 0; - } - - Capabilities cap; - if (device->isReadable() && DDSHandler::canRead(device)) { - cap |= CanRead; - } - return cap; -} - -QImageIOHandler *DDSPlugin::create(QIODevice *device, const QByteArray &format) const -{ - QImageIOHandler *handler = new DDSHandler; - handler->setDevice(device); - handler->setFormat(format); - return handler; -} diff --git a/src/imageformats/dds.desktop b/src/imageformats/dds.desktop deleted file mode 100644 index 27f0318..0000000 --- a/src/imageformats/dds.desktop +++ /dev/null @@ -1,7 +0,0 @@ -[Desktop Entry] -Type=Service -X-KDE-ServiceTypes=QImageIOPlugins -X-KDE-ImageFormat=dds -X-KDE-MimeType=image/x-dds -X-KDE-Read=true -X-KDE-Write=false diff --git a/src/imageformats/dds.json b/src/imageformats/dds.json deleted file mode 100644 index bc30795..0000000 --- a/src/imageformats/dds.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": [ "dds" ], - "MimeTypes": [ "image/x-dds" ] -} diff --git a/src/imageformats/dds_p.h b/src/imageformats/dds_p.h deleted file mode 100644 index 51c9fd7..0000000 --- a/src/imageformats/dds_p.h +++ /dev/null @@ -1,37 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Ignacio Castaño - - This program is free software; you can redistribute it and/or - modify it under the terms of the Lesser GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. -*/ - -#ifndef KIMG_DDS_H -#define KIMG_DDS_H - -#include - -class DDSHandler : public QImageIOHandler -{ -public: - DDSHandler(); - - virtual bool canRead() const; - virtual bool read(QImage *image); - - static bool canRead(QIODevice *device); -}; - -class DDSPlugin : public QImageIOPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "dds.json") - -public: - virtual Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - virtual QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; - -#endif // KIMG_DDS_H - diff --git a/src/imageformats/jp2.cpp b/src/imageformats/jp2.cpp deleted file mode 100644 index dc9998c..0000000 --- a/src/imageformats/jp2.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/* -* QImageIO Routines to read/write JPEG2000 images. -* copyright (c) 2002 Michael Ritzert -* -* This library is distributed under the conditions of the GNU LGPL. -*/ - -#include "jp2_p.h" - -#include - -#if HAVE_SYS_TYPES_H -#include -#endif - -#if HAVE_STDINT_H -#include -#endif - -#include -#include -#include - -// dirty, but avoids a warning because jasper.h includes jas_config.h. -#undef PACKAGE -#undef VERSION -#include - -// code taken in parts from JasPer's jiv.c - -#define DEFAULT_RATE 0.10 -#define MAXCMPTS 256 - -/************************* JasPer QIODevice stream ***********************/ - -//unfortunately this is declared as static in JasPer libraries -static jas_stream_t *jas_stream_create() -{ - jas_stream_t *stream; - - if (!(stream = (jas_stream_t *)jas_malloc(sizeof(jas_stream_t)))) { - return 0; - } - stream->openmode_ = 0; - stream->bufmode_ = 0; - stream->flags_ = 0; - stream->bufbase_ = 0; - stream->bufstart_ = 0; - stream->bufsize_ = 0; - stream->ptr_ = 0; - stream->cnt_ = 0; - stream->ops_ = 0; - stream->obj_ = 0; - stream->rwcnt_ = 0; - stream->rwlimit_ = -1; - - return stream; -} - -//unfortunately this is declared as static in JasPer libraries -static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, - int bufsize) -{ - /* If this function is being called, the buffer should not have been - initialized yet. */ - assert(!stream->bufbase_); - - if (bufmode != JAS_STREAM_UNBUF) { - /* The full- or line-buffered mode is being employed. */ - if (!buf) { - /* The caller has not specified a buffer to employ, so allocate - one. */ - if ((stream->bufbase_ = (unsigned char *)jas_malloc(JAS_STREAM_BUFSIZE + - JAS_STREAM_MAXPUTBACK))) { - stream->bufmode_ |= JAS_STREAM_FREEBUF; - stream->bufsize_ = JAS_STREAM_BUFSIZE; - } else { - /* The buffer allocation has failed. Resort to unbuffered - operation. */ - stream->bufbase_ = stream->tinybuf_; - stream->bufsize_ = 1; - } - } else { - /* The caller has specified a buffer to employ. */ - /* The buffer must be large enough to accommodate maximum - putback. */ - assert(bufsize > JAS_STREAM_MAXPUTBACK); - stream->bufbase_ = JAS_CAST(uchar *, buf); - stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK; - } - } else { - /* The unbuffered mode is being employed. */ - /* A buffer should not have been supplied by the caller. */ - assert(!buf); - /* Use a trivial one-character buffer. */ - stream->bufbase_ = stream->tinybuf_; - stream->bufsize_ = 1; - } - stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK]; - stream->ptr_ = stream->bufstart_; - stream->cnt_ = 0; - stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK; -} - -static int qiodevice_read(jas_stream_obj_t *obj, char *buf, int cnt) -{ - QIODevice *io = (QIODevice *) obj; - return io->read(buf, cnt); -} - -static int qiodevice_write(jas_stream_obj_t *obj, char *buf, int cnt) -{ - QIODevice *io = (QIODevice *) obj; - return io->write(buf, cnt); -} - -static long qiodevice_seek(jas_stream_obj_t *obj, long offset, int origin) -{ - QIODevice *io = (QIODevice *) obj; - long newpos; - - switch (origin) { - case SEEK_SET: - newpos = offset; - break; - case SEEK_END: - newpos = io->size() - offset; - break; - case SEEK_CUR: - newpos = io->pos() + offset; - break; - default: - return -1; - } - if (newpos < 0) { - return -1; - } - if (io->seek(newpos)) { - return newpos; - } else { - return -1; - } -} - -static int qiodevice_close(jas_stream_obj_t *) -{ - return 0; -} - -static jas_stream_ops_t jas_stream_qiodeviceops = { - qiodevice_read, - qiodevice_write, - qiodevice_seek, - qiodevice_close -}; - -static jas_stream_t *jas_stream_qiodevice(QIODevice *iodevice) -{ - jas_stream_t *stream; - - if (!iodevice) { - return 0; - } - if (!(stream = jas_stream_create())) { - return 0; - } - - /* A stream associated with a memory buffer is always opened - for both reading and writing in binary mode. */ - stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; - - jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); - - /* Select the operations for a memory stream. */ - stream->obj_ = (void *)iodevice; - stream->ops_ = &jas_stream_qiodeviceops; - - return stream; -} - -/************************ End of JasPer QIODevice stream ****************/ - -typedef struct { - jas_image_t *image; - - int cmptlut[MAXCMPTS]; - - jas_image_t *altimage; -} gs_t; - -static jas_image_t * -read_image(QIODevice *io) -{ - jas_stream_t *in = 0; - - in = jas_stream_qiodevice(io); - - if (!in) { - return 0; - } - - jas_image_t *image = jas_image_decode(in, -1, 0); - jas_stream_close(in); - - // image may be 0, but that's Ok - return image; -} // read_image - -static bool -convert_colorspace(gs_t &gs) -{ - jas_cmprof_t *outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB); - if (!outprof) { - return false; - } - - gs.altimage = jas_image_chclrspc(gs.image, outprof, - JAS_CMXFORM_INTENT_PER); - if (!gs.altimage) { - return false; - } - - return true; -} // convert_colorspace - -static bool -render_view(gs_t &gs, QImage *outImage) -{ - if (!gs.altimage) { - return false; - } - QImage qti; - if ((gs.cmptlut[0] = jas_image_getcmptbytype(gs.altimage, - JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R))) < 0 || - (gs.cmptlut[1] = jas_image_getcmptbytype(gs.altimage, - JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G))) < 0 || - (gs.cmptlut[2] = jas_image_getcmptbytype(gs.altimage, - JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))) < 0) { - return false; - } // if - - const int *cmptlut = gs.cmptlut; - int v[3]; - - // check that all components have the same size. - const int width = jas_image_cmptwidth(gs.altimage, cmptlut[0]); - const int height = jas_image_cmptheight(gs.altimage, cmptlut[0]); - for (int i = 1; i < 3; ++i) { - if (jas_image_cmptwidth(gs.altimage, cmptlut[i]) != width || - jas_image_cmptheight(gs.altimage, cmptlut[i]) != height) { - return false; - } - } // for - - jas_matrix_t *cmptmatrix[3]; - jas_seqent_t *buf[3]; - int prec[3]; - - for (int k = 0; k < 3; ++k) { - prec[k] = jas_image_cmptprec(gs.altimage, cmptlut[k]); - if (!(cmptmatrix[k] = jas_matrix_create(1, width))) { - return false; - } - } - - qti = QImage(jas_image_width(gs.altimage), jas_image_height(gs.altimage), - QImage::Format_RGB32); - if (qti.isNull()) { - return false; - } - uint32_t *data = (uint32_t *)qti.bits(); - - for (int y = 0; y < height; ++y) { - for (int k = 0; k < 3; ++k) { - if (jas_image_readcmpt(gs.altimage, cmptlut[k], 0, y, width, 1, cmptmatrix[k])) { - return false; - } - buf[k] = jas_matrix_getref(cmptmatrix[k], 0, 0); - } - for (int x = 0; x < width; ++x) { - for (int k = 0; k < 3; ++k) { - v[k] = *buf[k]; - // if the precision of the component is too small, increase - // it to use the complete value range. - v[k] <<= 8 - prec[k]; - - if (v[k] < 0) { - v[k] = 0; - } else if (v[k] > 255) { - v[k] = 255; - } - ++buf[k]; - } // for k - - *data++ = qRgb(v[0], v[1], v[2]); - } // for x - } // for y - - for (int k = 0; k < 3; ++k) { - if (cmptmatrix[k]) { - jas_matrix_destroy(cmptmatrix[k]); - } - } - - *outImage = qti; - return true; -} // render_view - -static jas_image_t * -create_image(const QImage &qi) -{ - // prepare the component parameters - jas_image_cmptparm_t *cmptparms = new jas_image_cmptparm_t[ 3 ]; - - for (int i = 0; i < 3; ++i) { - // x and y offset - cmptparms[i].tlx = 0; - cmptparms[i].tly = 0; - - // the resulting image will be hstep*width x vstep*height ! - cmptparms[i].hstep = 1; - cmptparms[i].vstep = 1; - cmptparms[i].width = qi.width(); - cmptparms[i].height = qi.height(); - - // we write everything as 24bit truecolor ATM - cmptparms[i].prec = 8; - cmptparms[i].sgnd = false; - } - - jas_image_t *ji = jas_image_create(3 /* number components */, cmptparms, JAS_CLRSPC_UNKNOWN); - delete[] cmptparms; - - // returning 0 is ok - return ji; -} // create_image - -static bool -write_components(jas_image_t *ji, const QImage &qi) -{ - const unsigned height = qi.height(); - const unsigned width = qi.width(); - - jas_matrix_t *m = jas_matrix_create(height, width); - if (!m) { - return false; - } - - jas_image_setclrspc(ji, JAS_CLRSPC_SRGB); - - jas_image_setcmpttype(ji, 0, JAS_IMAGE_CT_RGB_R); - for (uint y = 0; y < height; ++y) - for (uint x = 0; x < width; ++x) { - jas_matrix_set(m, y, x, qRed(qi.pixel(x, y))); - } - jas_image_writecmpt(ji, 0, 0, 0, width, height, m); - - jas_image_setcmpttype(ji, 1, JAS_IMAGE_CT_RGB_G); - for (uint y = 0; y < height; ++y) - for (uint x = 0; x < width; ++x) { - jas_matrix_set(m, y, x, qGreen(qi.pixel(x, y))); - } - jas_image_writecmpt(ji, 1, 0, 0, width, height, m); - - jas_image_setcmpttype(ji, 2, JAS_IMAGE_CT_RGB_B); - for (uint y = 0; y < height; ++y) - for (uint x = 0; x < width; ++x) { - jas_matrix_set(m, y, x, qBlue(qi.pixel(x, y))); - } - jas_image_writecmpt(ji, 2, 0, 0, width, height, m); - jas_matrix_destroy(m); - - return true; -} // write_components - -static bool -write_image(const QImage &image, QIODevice *io, int quality) -{ - jas_stream_t *stream = 0; - stream = jas_stream_qiodevice(io); - - // by here, a jas_stream_t is open - if (!stream) { - return false; - } - - jas_image_t *ji = create_image(image); - if (!ji) { - jas_stream_close(stream); - return false; - } // if - - if (!write_components(ji, image)) { - jas_stream_close(stream); - jas_image_destroy(ji); - return false; - } // if - - // optstr: - // - rate=#B => the resulting file size is about # bytes - // - rate=0.0 .. 1.0 => the resulting file size is about the factor times - // the uncompressed size - // use sprintf for locale-aware string - char rateBuffer[16]; - sprintf(rateBuffer, "rate=%.2g\n", (quality < 0) ? DEFAULT_RATE : quality / 100.0); - int i = jp2_encode(ji, stream, rateBuffer); - - jas_image_destroy(ji); - jas_stream_close(stream); - - if (i != 0) { - return false; - } - - return true; -} - -JP2Handler::JP2Handler() -{ - quality = 75; - jas_init(); -} - -JP2Handler::~JP2Handler() -{ - jas_cleanup(); -} - -bool JP2Handler::canRead() const -{ - if (canRead(device())) { - setFormat("jp2"); - return true; - } - return false; -} - -bool JP2Handler::canRead(QIODevice *device) -{ - if (!device) { - return false; - } - return device->peek(6) == QByteArray("\x00\x00\x00\x0C\x6A\x50", 6); -} - -bool JP2Handler::read(QImage *image) -{ - if (!canRead()) { - return false; - } - - gs_t gs; - if (!(gs.image = read_image(device()))) { - return false; - } - - if (!convert_colorspace(gs)) { - return false; - } - - render_view(gs, image); - - if (gs.image) { - jas_image_destroy(gs.image); - } - if (gs.altimage) { - jas_image_destroy(gs.altimage); - } - return true; - -} - -bool JP2Handler::write(const QImage &image) -{ - return write_image(image, device(), quality); -} - -bool JP2Handler::supportsOption(ImageOption option) const -{ - return option == Quality; -} - -QVariant JP2Handler::option(ImageOption option) const -{ - if (option == Quality) { - return quality; - } - return QVariant(); -} - -void JP2Handler::setOption(ImageOption option, const QVariant &value) -{ - if (option == Quality) { - quality = qBound(-1, value.toInt(), 100); - } -} - -QImageIOPlugin::Capabilities JP2Plugin::capabilities(QIODevice *device, const QByteArray &format) const -{ - if (format == "jp2") { - return Capabilities(CanRead | CanWrite); - } - if (!format.isEmpty()) { - return 0; - } - if (!device->isOpen()) { - return 0; - } - - Capabilities cap; - if (device->isReadable() && JP2Handler::canRead(device)) { - cap |= CanRead; - } - if (device->isWritable()) { - cap |= CanWrite; - } - return cap; -} - -QImageIOHandler *JP2Plugin::create(QIODevice *device, const QByteArray &format) const -{ - QImageIOHandler *handler = new JP2Handler; - handler->setDevice(device); - handler->setFormat(format); - return handler; -} diff --git a/src/imageformats/jp2.json b/src/imageformats/jp2.json deleted file mode 100644 index 3ff6cde..0000000 --- a/src/imageformats/jp2.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": [ "jp2" ], - "MimeTypes": [ "image/jp2" ] -} diff --git a/src/imageformats/jp2_p.h b/src/imageformats/jp2_p.h deleted file mode 100644 index 448e847..0000000 --- a/src/imageformats/jp2_p.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -* QImageIO Routines to read/write JPEG2000 images. -* copyright (c) 2002 Michael Ritzert -* -* This library is distributed under the conditions of the GNU LGPL. -*/ -#ifndef KIMG_JP2_H -#define KIMG_JP2_H - -#include - -class JP2Handler : public QImageIOHandler -{ -public: - JP2Handler(); - virtual ~JP2Handler(); - - virtual bool canRead() const; - virtual bool read(QImage *image); - virtual bool write(const QImage &image); - - virtual bool supportsOption(ImageOption option) const; - virtual QVariant option(ImageOption option) const; - virtual void setOption(ImageOption option, const QVariant &value); - - static bool canRead(QIODevice *device); - -private: - int quality; -}; - -class JP2Plugin : public QImageIOPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jp2.json") - -public: - virtual Capabilities capabilities(QIODevice *device, const QByteArray &format) const; - virtual QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; -}; - -#endif // KIMG_JP2_H