Compare commits
93 Commits
work/aacid
...
v6.26.0-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84f28e8bc9 | ||
|
|
a936927ec1 | ||
|
|
191e5e6a69 | ||
|
|
51db11eefc | ||
|
|
bc398382ac | ||
|
|
d5e5012cfb | ||
|
|
1b3f32a332 | ||
|
|
7cf60da031 | ||
|
|
d160f268e7 | ||
|
|
276338199a | ||
|
|
742b5097f6 | ||
|
|
2d2ee68cc0 | ||
|
|
d15c3c679d | ||
|
|
eb896efea1 | ||
|
|
142ec14c81 | ||
|
|
38b8b70304 | ||
|
|
e28c48cfeb | ||
|
|
3c08226aec | ||
|
|
7c86ccaefb | ||
|
|
ec0610d5b0 | ||
|
|
ae279c55f4 | ||
|
|
836e0a53bb | ||
|
|
5eb09116b0 | ||
|
|
92368ca58f | ||
|
|
a91c7ef72f | ||
|
|
ea2a4aafab | ||
|
|
c254875780 | ||
|
|
f3de2e77c1 | ||
|
|
1ef779f370 | ||
|
|
169a874cba | ||
|
|
ebf77ccdf5 | ||
|
|
359cb039d2 | ||
|
|
f4b91d8a54 | ||
|
|
263b5a88e2 | ||
|
|
8d07f7db1b | ||
|
|
1c2210c100 | ||
|
|
b7b438f903 | ||
|
|
336b8906aa | ||
|
|
2c8a1ad6ff | ||
|
|
e0f1ba640a | ||
|
|
32773e5f0c | ||
|
|
2410e45614 | ||
|
|
99e4223393 | ||
|
|
8224c0099d | ||
|
|
8d7fb2c3fd | ||
|
|
3353809906 | ||
|
|
abf4d32858 | ||
|
|
6b1c52c55c | ||
|
|
e644ab997f | ||
|
|
1fb3363e7b | ||
|
|
19df8b03a8 | ||
|
|
3f1ee9f9d1 | ||
|
|
8c9a7e88e5 | ||
|
|
30308f3541 | ||
|
|
af4597f796 | ||
|
|
b8b9849268 | ||
|
|
db1cb8de1f | ||
|
|
956b86c4de | ||
|
|
282c277204 | ||
|
|
237f25fd20 | ||
|
|
5140567853 | ||
|
|
72a809bcfd | ||
|
|
731ac375bb | ||
|
|
8061500b79 | ||
|
|
472ff92b96 | ||
|
|
847510f109 | ||
|
|
a8ad7be1cd | ||
|
|
7202e77c74 | ||
|
|
379c3c1738 | ||
|
|
6519d2930e | ||
|
|
ffcfa49f13 | ||
|
|
d3d4bea2f1 | ||
|
|
cfbeb397a8 | ||
|
|
1c6ce2437e | ||
|
|
3d9f1c4e9e | ||
|
|
e7d01c286f | ||
|
|
dfda863841 | ||
|
|
3d4d74fc02 | ||
|
|
326e56029a | ||
|
|
e8e5b091bc | ||
|
|
aeb2988eec | ||
|
|
abfda2ce69 | ||
|
|
d6d67c7b8b | ||
|
|
54c94764d1 | ||
|
|
7512874620 | ||
|
|
146f637385 | ||
|
|
436310b4f0 | ||
|
|
d8a8bcb68e | ||
|
|
2b80a0a55a | ||
|
|
8e164474b4 | ||
|
|
4c52480b73 | ||
|
|
19faa55a6d | ||
|
|
b9bfeedbc1 |
@@ -7,5 +7,5 @@ Dependencies:
|
||||
Options:
|
||||
test-before-installing: True
|
||||
require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
|
||||
cmake-options: "-DKIMAGEFORMATS_DDS=ON -DKIMAGEFORMATS_JXR=ON -DKIMAGEFORMATS_HEIF=ON"
|
||||
cmake-options: "-DKIMAGEFORMATS_WITH_KNOWN_CRASHES_JXR=ON -DKIMAGEFORMATS_HEIF=ON -DKIMAGEFORMATS_HEIF_TEST:STRING=OFF -DKIMAGEFORMATS_HEJ2_TEST:STRING=OFF -DKIMAGEFORMATS_AVCI_TEST:STRING=OFF"
|
||||
per-test-timeout: 90
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
set(KF_VERSION "6.20.0") # handled by release scripts
|
||||
set(KF_DEP_VERSION "6.19.0") # handled by release scripts
|
||||
set(KF_VERSION "6.26.0") # handled by release scripts
|
||||
set(KF_DEP_VERSION "6.26.0") # handled by release scripts
|
||||
project(KImageFormats VERSION ${KF_VERSION})
|
||||
|
||||
include(FeatureSummary)
|
||||
find_package(ECM 6.19.0 NO_MODULE)
|
||||
find_package(ECM 6.26.0 NO_MODULE)
|
||||
set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules")
|
||||
feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||
|
||||
@@ -21,7 +21,7 @@ include(ECMDeprecationSettings)
|
||||
include(CheckIncludeFiles)
|
||||
include(FindPkgConfig)
|
||||
|
||||
set(REQUIRED_QT_VERSION 6.7.0)
|
||||
set(REQUIRED_QT_VERSION 6.9.0)
|
||||
find_package(Qt6Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
|
||||
|
||||
find_package(KF6Archive ${KF_DEP_VERSION})
|
||||
@@ -65,6 +65,12 @@ set_package_properties(libavif PROPERTIES
|
||||
option(KIMAGEFORMATS_DDS "Enable plugin for DDS format" ON)
|
||||
|
||||
option(KIMAGEFORMATS_HEIF "Enable plugin for HEIF format" OFF)
|
||||
set(KIMAGEFORMATS_HEIF_TEST "ALL" CACHE STRING "Enable HEIF tests: OFF, READ_ONLY, ALL")
|
||||
set_property(CACHE KIMAGEFORMATS_HEIF_TEST PROPERTY STRINGS "OFF" "READ_ONLY" "ALL")
|
||||
set(KIMAGEFORMATS_HEJ2_TEST "ALL" CACHE STRING "Enable HEJ2 tests: OFF, READ_ONLY, ALL")
|
||||
set_property(CACHE KIMAGEFORMATS_HEJ2_TEST PROPERTY STRINGS "OFF" "READ_ONLY" "ALL")
|
||||
set(KIMAGEFORMATS_AVCI_TEST "ALL" CACHE STRING "Enable AVCI tests: OFF, ALL")
|
||||
set_property(CACHE KIMAGEFORMATS_AVCI_TEST PROPERTY STRINGS "OFF" "ALL")
|
||||
if(KIMAGEFORMATS_HEIF)
|
||||
pkg_check_modules(LibHeif IMPORTED_TARGET libheif>=1.10.0)
|
||||
endif()
|
||||
@@ -91,16 +97,17 @@ set_package_properties(LibRaw PROPERTIES
|
||||
PURPOSE "Required for the QImage plugin for RAW images"
|
||||
)
|
||||
|
||||
# JXR plugin disabled by default due to security issues
|
||||
option(KIMAGEFORMATS_JXR "Enable plugin for JPEG XR format" OFF)
|
||||
if(KIMAGEFORMATS_JXR)
|
||||
# JXR plugin disabled by default due to security issues.
|
||||
# You should not enable it unless you know what you are doing.
|
||||
option(KIMAGEFORMATS_WITH_KNOWN_CRASHES_JXR "Enable plugin for JPEG XR format" OFF)
|
||||
if(KIMAGEFORMATS_WITH_KNOWN_CRASHES_JXR)
|
||||
find_package(LibJXR)
|
||||
endif()
|
||||
add_feature_info(LibJXR LibJXR_FOUND "required for the QImage plugin for JPEG XR images")
|
||||
|
||||
ecm_set_disabled_deprecation_versions(
|
||||
QT 6.10.0
|
||||
KF 6.18.0
|
||||
QT 6.11.0
|
||||
KF 6.23.0
|
||||
)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
75
README.md
@@ -21,6 +21,7 @@ The following image formats have read-only support:
|
||||
- Krita (kra)
|
||||
- OpenRaster (ora)
|
||||
- Pixar raster (pxr)
|
||||
- PlayStation graphics (tim)
|
||||
- Portable FloatMap/HalfMap (pfm, phm)
|
||||
- Photoshop documents (psd, psb, pdd, psdt)
|
||||
- Radiance HDR (hdr)
|
||||
@@ -154,8 +155,31 @@ About the image:
|
||||
- `Owner`: Name of the owner of the image.
|
||||
- `Software`: Name and version number of the software package(s) used to
|
||||
create the image.
|
||||
- `Speed`: Floating-point number indicating the speed of GPS receiver
|
||||
movement in Km/h (e.g. 30.2).
|
||||
- `Title`: The title of the image.
|
||||
|
||||
About the shot:
|
||||
- `DigitalZoomRatio`: Floating-point number indicating the digital zoom ratio
|
||||
when the image was shot.
|
||||
- `ExposureMode`: Integer number indicating the exposure mode set when the
|
||||
image was shot as reported in the EXIF specifications.
|
||||
- `ExposureProgram`: Integer number indicating the class of the program used
|
||||
by the camera to set exposure when the picture is taken as reported in the
|
||||
EXIF specifications.
|
||||
- `ExposureTime`: Floating-point number indicating the exposure time,
|
||||
given in seconds (s).
|
||||
- `Flash`: Integer number indicating the status of flash when the image
|
||||
was shot as reported in the EXIF specifications.
|
||||
- `FNumber`: Floating-point number indicating the F number.
|
||||
- `FocalLength`: Floating-point number indicating the actual focal length
|
||||
of the lens, in millimeters (mm).
|
||||
- `ISOSpeedRatings`: Integer number indicating the sensitivity of the camera
|
||||
or input device when the image was shot as reported in the EXIF
|
||||
specifications.
|
||||
- `WhiteBalance`: Integer number indicating the white balance mode set when
|
||||
the image was shot as reported in the EXIF specifications.
|
||||
|
||||
About the camera:
|
||||
- `Manufacturer`: The manufacturer of the recording equipment.
|
||||
- `Model`: The model name or model number of the recording equipment.
|
||||
@@ -250,6 +274,7 @@ limit depends on the format encoding).
|
||||
- RAW: 65,535 x 65,535 pixels
|
||||
- RGB: 65,535 x 65,535 pixels
|
||||
- SCT: 300,000 x 300,000 pixels
|
||||
- TIM: 65,535 x 65,535 pixels
|
||||
- TGA: 65,535 x 65,535 pixels
|
||||
- XCF: 300,000 x 300,000 pixels
|
||||
|
||||
@@ -290,9 +315,14 @@ in your cmake options.**
|
||||
|
||||
The following defines can be defined in cmake to modify the behavior of the
|
||||
plugin:
|
||||
- `DDS_DISABLE_STRIDE_ALIGNMENT`: disable the stride aligment based on DDS
|
||||
- `DDS_DISABLE_STRIDE_ALIGNMENT`: disable the stride alignment based on DDS
|
||||
pitch: it is known that some writers do not set it correctly.
|
||||
|
||||
When writing, it is possible to set which pixel format to use by setting the
|
||||
subtypes. The default is `Automatic` which chooses the most appropriate format
|
||||
based on the image. For a complete list of subformats, please use the
|
||||
appropriate [`QImageWriter`](https://doc.qt.io/qt-6/qimagewriter.html) APIs.
|
||||
|
||||
### The HEIF plugin
|
||||
|
||||
**This plugin is disabled by default. It can be enabled by settings
|
||||
@@ -303,6 +333,15 @@ distributions. In particular, it is necessary that the HEIF library has
|
||||
support for HEVC codec. If HEVC codec is not available the plugin
|
||||
will compile but will fail the tests.
|
||||
|
||||
**If you are interested in compiling the plugin without running the tests,
|
||||
also use the following string options:**
|
||||
- `KIMAGEFORMATS_HEIF_TEST` to change the behaviour of HEIF tests. Set to
|
||||
`"OFF"` (no test at all) or `"READ_ONLY"` (run read tests only).
|
||||
- `KIMAGEFORMATS_HEJ2_TEST` to change the behaviour of HEJ2 tests. Set to
|
||||
`"OFF"` (no test at all) or `"READ_ONLY"` (run read tests only)..
|
||||
- `KIMAGEFORMATS_AVCI_TEST` to change the behaviour of AVCI tests. Set to
|
||||
`"OFF"` (no test at all).
|
||||
|
||||
### The EXR plugin
|
||||
|
||||
The following defines can be defined in cmake to modify the behavior of the
|
||||
@@ -313,6 +352,10 @@ plugin:
|
||||
attribute named "xmp". Note that Gimp reads the "xmp" attribute and Darktable
|
||||
writes it as well.
|
||||
|
||||
The plugin can set the following additional metadata:
|
||||
- `EXRLayerName`: A string containing the name of the EXR layer used to decode
|
||||
the image.
|
||||
|
||||
### The EPS plugin
|
||||
|
||||
The plugin uses `Ghostscript` to convert the raster image. When reading it
|
||||
@@ -348,9 +391,16 @@ The plugin supports the following image data:
|
||||
type 4.
|
||||
- FORM PBM: PBM is a chunky version of IFF pictures. It supports 8-bit images
|
||||
with color map only.
|
||||
- FORM IMAG (Compact Disc-Interactive): It supports CLut4, CLut7, CLut8, Rle7
|
||||
and DYuv formats.
|
||||
- FORM RGFX: It supports uncompressed images only.
|
||||
- FOR4 CIMG (Maya Image File Format): It supports 24/48-bit RGB and 32/64-bit
|
||||
RGBA images.
|
||||
|
||||
> [!note]
|
||||
> The plugin only supports the IFF, ILBM, and LBM file extensions. You'll
|
||||
> need to rename files with different extensions to open them.
|
||||
|
||||
### The JP2 plugin
|
||||
|
||||
**This plugin can be disabled by setting `KIMAGEFORMATS_JP2` to `OFF`
|
||||
@@ -361,6 +411,11 @@ JP2 plugin has the following limitations due to the lack of support by OpenJPEG:
|
||||
- Image resolution is not supported.
|
||||
- To write ICC profiles you need OpenJPEG V2.5.4 or higher
|
||||
|
||||
When writing, it is possible to set which format to use by setting the
|
||||
following subtypes:
|
||||
- `JP2` (default): Save data using the JP2 container.
|
||||
- `J2K`: Save only the compressed codestream.
|
||||
|
||||
### The JXL plugin
|
||||
|
||||
**The current version of the plugin limits the image size to 256 megapixels
|
||||
@@ -376,13 +431,18 @@ plugin:
|
||||
### The JXR plugin
|
||||
|
||||
**This plugin is disabled by default. It can be enabled by settings
|
||||
`KIMAGEFORMATS_JXR` to `ON` in your cmake options.**
|
||||
`KIMAGEFORMATS_WITH_KNOWN_CRASHES_JXR` to `ON` in your cmake options.**
|
||||
|
||||
> [!caution]
|
||||
> The plugin disabled by default due to security issues in [jxrlib](https://github.com/4creators/jxrlib):
|
||||
> the upstream jxrlib is dead and there is no "hope" they will fix the issues.
|
||||
> **You should not enable it unless you know what you are doing.**
|
||||
|
||||
The following defines can be defined in cmake to modify the behavior of the
|
||||
plugin:
|
||||
- `JXR_DENY_FLOAT_IMAGE`: disables the use of float images and consequently
|
||||
any HDR data will be lost.
|
||||
- `JXR_DISABLE_DEPTH_CONVERSION`: remove the neeeds of additional memory by
|
||||
- `JXR_DISABLE_DEPTH_CONVERSION`: remove the needs of additional memory by
|
||||
disabling the conversion between different color depths (e.g. RGBA64bpp to
|
||||
RGBA32bpp) at the cost of reduced compatibility.
|
||||
- `JXR_DISABLE_BGRA_HACK`: Windows displays and opens JXR files correctly out
|
||||
@@ -414,6 +474,8 @@ PSD support has the following limitations:
|
||||
- Multichannel images are treated as CMYK if they have 2 or more channels.
|
||||
- Multichannel images are treated as Grayscale if they have 1 channel.
|
||||
- Duotone images are treated as grayscale images.
|
||||
- Grayscale images with alpha channel or at 32 bit depth are converted to
|
||||
RGBA due to the lack of the appropriate Qt grayscale container.
|
||||
- Extra channels other than alpha are discarded.
|
||||
|
||||
The following defines can be defined in cmake to modify the behavior of the
|
||||
@@ -423,6 +485,13 @@ plugin:
|
||||
- `PSD_NATIVE_CMYK_SUPPORT_DISABLED`: disable native support for CMYK images
|
||||
when compiled with Qt 6.8+
|
||||
|
||||
The plugin can set the following additional metadata:
|
||||
- `PSDDuotoneOptions`: Byte array in hexadecimal format of color data of the
|
||||
duotone specification (the format of which is not documented). From the PSD
|
||||
specification: *"Other applications that read Photoshop files can treat a
|
||||
duotone image as a gray image, and just preserve the contents of the duotone
|
||||
information when reading and writing the file."*
|
||||
|
||||
### The RAW plugin
|
||||
|
||||
Loading RAW images always requires a conversion. To allow the user to
|
||||
|
||||
@@ -86,6 +86,7 @@ kimageformats_read_tests(
|
||||
ras
|
||||
rgb
|
||||
sct
|
||||
tim
|
||||
tga
|
||||
)
|
||||
|
||||
@@ -102,36 +103,52 @@ if (KF6Archive_FOUND)
|
||||
endif()
|
||||
|
||||
if (TARGET avif)
|
||||
kimageformats_read_tests(
|
||||
avif
|
||||
)
|
||||
if(${libavif_VERSION} VERSION_GREATER_EQUAL "1.2.0")
|
||||
kimageformats_read_tests(
|
||||
avif
|
||||
)
|
||||
else()
|
||||
message(WARNING "libavif ${libavif_VERSION} doesn't support decoding new AVIF files!\n"
|
||||
"AVIF read tests are disabled, consider updating libavif.")
|
||||
endif()
|
||||
|
||||
kimageformats_write_tests(
|
||||
avif-nodatacheck-lossless
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LibHeif_FOUND)
|
||||
kimageformats_read_tests(
|
||||
heif
|
||||
)
|
||||
# because the plug-ins use RGB->YUV conversion which sometimes results in 1 value difference.
|
||||
kimageformats_write_tests(FUZZ 1
|
||||
heif-nodatacheck-lossless
|
||||
)
|
||||
|
||||
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.17.0")
|
||||
kimageformats_read_tests(FUZZ 1
|
||||
hej2
|
||||
if (KIMAGEFORMATS_HEIF_TEST STREQUAL "ALL" OR KIMAGEFORMATS_HEIF_TEST STREQUAL "READ_ONLY")
|
||||
kimageformats_read_tests(
|
||||
heif
|
||||
)
|
||||
endif()
|
||||
if (KIMAGEFORMATS_HEIF_TEST STREQUAL "ALL")
|
||||
# because the plug-ins use RGB->YUV conversion which sometimes results in 1 value difference.
|
||||
kimageformats_write_tests(FUZZ 1
|
||||
hej2-nodatacheck-lossless
|
||||
heif-nodatacheck-lossless
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.17.0")
|
||||
if (KIMAGEFORMATS_HEJ2_TEST STREQUAL "ALL" OR KIMAGEFORMATS_HEJ2_TEST STREQUAL "READ_ONLY")
|
||||
kimageformats_read_tests(FUZZ 1
|
||||
hej2
|
||||
)
|
||||
endif()
|
||||
if (KIMAGEFORMATS_HEJ2_TEST STREQUAL "ALL")
|
||||
kimageformats_write_tests(FUZZ 1
|
||||
hej2-nodatacheck-lossless
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.19.6")
|
||||
kimageformats_read_tests(FUZZ 4
|
||||
avci
|
||||
)
|
||||
if (KIMAGEFORMATS_AVCI_TEST STREQUAL "ALL")
|
||||
kimageformats_read_tests(FUZZ 4
|
||||
avci
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ Depending on the format, you can specify the following additional options.
|
||||
|
||||
- `--help`: Displays help on commandline options.
|
||||
- `--fuzz <max>`: The fuzziness. Used to add some deviation in ARGB data
|
||||
(nornally used on lossy codec).
|
||||
(normally used on lossy codec).
|
||||
- `--perceptive-fuzz`: Used to scale dynamically the fuzziness based on
|
||||
the alpha channel value. This is useful on images with pre-multiplied and
|
||||
small alphas. Qt can use different roundings based on optimizations resulting
|
||||
|
||||
@@ -48,7 +48,7 @@ private Q_SLOTS:
|
||||
QCOMPARE(reader.text(QStringLiteral("Author")), QStringLiteral("KDE Community"));
|
||||
}
|
||||
|
||||
void textRead()
|
||||
void testRead()
|
||||
{
|
||||
QImageReader reader(QFINDTESTDATA("ani/test.ani"));
|
||||
QVERIFY(reader.canRead());
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
################################################################################
|
||||
LDFLAGS=""
|
||||
if [[ $FUZZING_ENGINE == "afl" ]]; then
|
||||
LDFLAGS="-fuse-ld=lld"
|
||||
fi
|
||||
export LDFLAGS
|
||||
|
||||
# build zstd
|
||||
cd $SRC/zstd
|
||||
@@ -175,6 +180,7 @@ HANDLER_TYPES="ANIHandler ani
|
||||
RAWHandler raw
|
||||
RGBHandler rgb
|
||||
ScitexHandler sct
|
||||
TIMHandler tim
|
||||
TGAHandler tga
|
||||
XCFHandler xcf"
|
||||
|
||||
@@ -185,7 +191,7 @@ echo "$HANDLER_TYPES" | while read class format; do
|
||||
/usr/libexec/moc $SRC/kimageformats/src/imageformats/$format.cpp -o $format.moc
|
||||
header=`ls $SRC/kimageformats/src/imageformats/$format*.h`
|
||||
/usr/libexec/moc $header -o moc_`basename $header .h`.cpp
|
||||
$CXX $CXXFLAGS -fPIC -DHANDLER=$class -std=c++17 autotests/ossfuzz/kimgio_fuzzer.cc $SRC/kimageformats/src/imageformats/$format.cpp $SRC/kimageformats/src/imageformats/scanlineconverter.cpp $SRC/kimageformats/src/imageformats/microexif.cpp $SRC/kimageformats/src/imageformats/chunks.cpp -o $OUT/$fuzz_target_name -DJXL_STATIC_DEFINE -DJXL_THREADS_STATIC_DEFINE -DJXL_CMS_STATIC_DEFINE -DINITGUID -I $SRC/kimageformats/src/imageformats/ -I $SRC/libavif/include/ -I $SRC/libjxl/build/lib/include/ -I $SRC/libjxl/lib/include/ -I /usr/local/include/OpenEXR/ -I /usr/local/include/KF6/KArchive/ -I /usr/local/include/openjpeg-2.5 -I /usr/local/include/Imath -I $SRC/jxrlib/common/include -I $SRC/jxrlib/jxrgluelib -I $SRC/jxrlib/image/sys -I /usr/include/QtCore/ -I /usr/include/QtGui/ -I . $SRC/libavif/build/libavif.a /usr/local/lib/libheif.a /usr/local/lib/libde265.a /usr/local/lib/libopenh264.a $SRC/aom/build.libavif/libaom.a $SRC/libjxl/build/lib/libjxl_threads.a $SRC/libjxl/build/lib/libjxl.a $SRC/libjxl/build/lib/libjxl_cms.a $SRC/libjxl/build/third_party/highway/libhwy.a $SRC/libjxl/build/third_party/brotli/libbrotlidec.a $SRC/libjxl/build/third_party/brotli/libbrotlienc.a $SRC/libjxl/build/third_party/brotli/libbrotlicommon.a -lQt6Gui -lQt6Core -lQt6BundledLibpng -lQt6BundledHarfbuzz -lm -lQt6BundledPcre2 -ldl -lpthread $LIB_FUZZING_ENGINE /usr/local/lib/libz.a -lKF6Archive /usr/local/lib/libz.a /usr/local/lib/libraw.a /usr/local/lib/libOpenEXR-3_3.a /usr/local/lib/libIex-3_3.a /usr/local/lib/libImath-3_1.a /usr/local/lib/libIlmThread-3_3.a /usr/local/lib/libOpenEXRCore-3_3.a /usr/local/lib/libOpenEXRUtil-3_3.a /usr/local/lib/libopenjp2.a /usr/local/lib/libzstd.a $SRC/jxrlib/build/libjxrglue.a $SRC/jxrlib/build/libjpegxr.a -llzma /usr/local/lib/libbz2.a -lclang_rt.builtins
|
||||
$CXX $CXXFLAGS $LDFLAGS -fPIC -DHANDLER=$class -std=c++17 autotests/ossfuzz/kimgio_fuzzer.cc $SRC/kimageformats/src/imageformats/$format.cpp $SRC/kimageformats/src/imageformats/scanlineconverter.cpp $SRC/kimageformats/src/imageformats/microexif.cpp $SRC/kimageformats/src/imageformats/chunks.cpp -o $OUT/$fuzz_target_name -DJXL_STATIC_DEFINE -DJXL_THREADS_STATIC_DEFINE -DJXL_CMS_STATIC_DEFINE -DINITGUID -I $SRC/kimageformats/src/imageformats/ -I $SRC/libavif/include/ -I $SRC/libjxl/build/lib/include/ -I $SRC/libjxl/lib/include/ -I /usr/local/include/OpenEXR/ -I /usr/local/include/KF6/KArchive/ -I /usr/local/include/openjpeg-2.5 -I /usr/local/include/Imath -I $SRC/jxrlib/common/include -I $SRC/jxrlib/jxrgluelib -I $SRC/jxrlib/image/sys -I /usr/include/QtCore/ -I /usr/include/QtGui/ -I . $SRC/libavif/build/libavif.a /usr/local/lib/libheif.a /usr/local/lib/libde265.a /usr/local/lib/libopenh264.a $SRC/aom/build.libavif/libaom.a $SRC/libjxl/build/lib/libjxl_threads.a $SRC/libjxl/build/lib/libjxl.a $SRC/libjxl/build/lib/libjxl_cms.a $SRC/libjxl/build/third_party/highway/libhwy.a $SRC/libjxl/build/third_party/brotli/libbrotlidec.a $SRC/libjxl/build/third_party/brotli/libbrotlienc.a $SRC/libjxl/build/third_party/brotli/libbrotlicommon.a -lQt6Gui -lQt6Core -lQt6BundledLibpng -lQt6BundledHarfbuzz -lm -lQt6BundledPcre2 -ldl -lpthread $LIB_FUZZING_ENGINE /usr/local/lib/libz.a /usr/local/lib/x86_64-linux-gnu/libKF6Archive.a /usr/local/lib/libz.a /usr/local/lib/libraw.a /usr/local/lib/libOpenEXR-3_3.a /usr/local/lib/libIex-3_3.a /usr/local/lib/libImath-3_1.a /usr/local/lib/libIlmThread-3_3.a /usr/local/lib/libOpenEXRCore-3_3.a /usr/local/lib/libOpenEXRUtil-3_3.a /usr/local/lib/libopenjp2.a /usr/local/lib/libzstd.a $SRC/jxrlib/build/libjxrglue.a $SRC/jxrlib/build/libjpegxr.a /usr/local/lib/liblzma.a /usr/local/lib/libbz2.a -lclang_rt.builtins
|
||||
|
||||
# -lclang_rt.builtins in the previous line is a temporary workaround to avoid a linker error "undefined reference to __truncsfhf2". Investigate why this is needed here, but not anywhere else, and possibly remove it.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Usage:
|
||||
python infra/helper.py build_image kimageformats
|
||||
python infra/helper.py build_fuzzers --sanitizer undefined|address|memory kimageformats
|
||||
python infra/helper.py run_fuzzer kimageformats kimgio_[ani|avif|dds|exr|hdr|heif|iff|jp2|jxl|jxr|kra|ora|pcx|pfm|pic|psd|pxr|qoi|ras|raw|rgb|sct|tga|xcf]_fuzzer
|
||||
python infra/helper.py run_fuzzer kimageformats kimgio_[ani|avif|dds|exr|hdr|heif|iff|jp2|jxl|jxr|kra|ora|pcx|pfm|pic|psd|pxr|qoi|ras|raw|rgb|sct|tim|tga|xcf]_fuzzer
|
||||
*/
|
||||
|
||||
#include <QBuffer>
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "raw_p.h"
|
||||
#include "rgb_p.h"
|
||||
#include "sct_p.h"
|
||||
#include "tim_p.h"
|
||||
#include "tga_p.h"
|
||||
#include "xcf_p.h"
|
||||
|
||||
|
||||
@@ -33,12 +33,12 @@ git clone --depth 1 -b master https://invent.kde.org/frameworks/extra-cmake-modu
|
||||
git clone --depth 1 --branch=dev git://code.qt.io/qt/qtbase.git
|
||||
git clone --depth 1 --branch=dev git://code.qt.io/qt/qttools.git
|
||||
git clone --depth 1 -b master https://invent.kde.org/frameworks/karchive.git
|
||||
git clone --depth 1 -b v3.12.0 https://aomedia.googlesource.com/aom
|
||||
git clone --depth 1 -b v1.2.1 https://github.com/AOMediaCodec/libavif.git
|
||||
git clone --depth 1 -b v3.13.1 https://aomedia.googlesource.com/aom
|
||||
git clone --depth 1 -b v1.3.0 https://github.com/AOMediaCodec/libavif.git
|
||||
git clone --depth 1 https://github.com/strukturag/libde265.git
|
||||
git clone --depth 1 -b v2.5.3 https://github.com/uclouvain/openjpeg.git
|
||||
git clone --depth 1 -b v2.5.4 https://github.com/uclouvain/openjpeg.git
|
||||
git clone --depth 1 https://github.com/strukturag/libheif.git
|
||||
git clone --depth=1 --branch v0.11.x --recursive --shallow-submodules https://github.com/libjxl/libjxl.git
|
||||
git clone --depth=1 --recursive --shallow-submodules https://github.com/libjxl/libjxl.git
|
||||
git clone --depth 1 https://github.com/LibRaw/LibRaw
|
||||
git clone --depth 1 https://github.com/mircomir/jxrlib.git
|
||||
git clone --depth 1 -b v2.6.0 https://github.com/cisco/openh264.git
|
||||
|
||||
BIN
autotests/read/avif/profile_gray.avif
Normal file
|
After Width: | Height: | Size: 267 KiB |
11
autotests/read/avif/profile_gray.avif.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "profile_gray.png",
|
||||
"colorSpace" : {
|
||||
"colorModel" : "Gray",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "SRgb",
|
||||
"gamma" : 2.31
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/avif/profile_gray.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
autotests/read/avif/profile_gray_gamma22.avif
Normal file
|
After Width: | Height: | Size: 261 KiB |
11
autotests/read/avif/profile_gray_gamma22.avif.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "profile_gray_gamma22.png",
|
||||
"colorSpace" : {
|
||||
"colorModel" : "Gray",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Gamma",
|
||||
"gamma" : 2.2
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/avif/profile_gray_gamma22.png
Normal file
|
After Width: | Height: | Size: 263 KiB |
BIN
autotests/read/avif/profile_gray_gamma28.avif
Normal file
|
After Width: | Height: | Size: 263 KiB |
11
autotests/read/avif/profile_gray_gamma28.avif.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "profile_gray_gamma28.png",
|
||||
"colorSpace" : {
|
||||
"colorModel" : "Gray",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Gamma",
|
||||
"gamma" : 2.8
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/avif/profile_gray_gamma28.png
Normal file
|
After Width: | Height: | Size: 265 KiB |
BIN
autotests/read/avif/profile_gray_linear.avif
Normal file
|
After Width: | Height: | Size: 216 KiB |
11
autotests/read/avif/profile_gray_linear.avif.json
Normal file
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "profile_gray_linear.png",
|
||||
"colorSpace" : {
|
||||
"colorModel" : "Gray",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Linear",
|
||||
"gamma" : 1
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/avif/profile_gray_linear.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
autotests/read/avif/profile_gray_prophoto.avif
Normal file
|
After Width: | Height: | Size: 255 KiB |
12
autotests/read/avif/profile_gray_prophoto.avif.json
Normal file
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "profile_gray_prophoto.png",
|
||||
"colorSpace" : {
|
||||
"description" : "grayscale D50 with ProPhoto TRC",
|
||||
"colorModel" : "Gray",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Custom",
|
||||
"gamma" : 0
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/avif/profile_gray_prophoto.png
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
autotests/read/avif/ycgco-re.avif
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
autotests/read/avif/ycgco-re.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
autotests/read/exr/ps2026_testcard_rgb.exr
Normal file
15
autotests/read/exr/ps2026_testcard_rgb.exr.json
Normal file
@@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "ps2026_testcard_rgb.png",
|
||||
"colorSpace" : {
|
||||
"description" : "sRGB build-in (Profilo RGB lineare)",
|
||||
"primaries" : "SRgb",
|
||||
"transferFunction" : "Linear",
|
||||
"gamma" : 1
|
||||
},
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 3937,
|
||||
"dotsPerMeterY" : 3937
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/exr/ps2026_testcard_rgb.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"fileName" : "rgb-gimp.png",
|
||||
"colorSpace" : {
|
||||
"description" : "",
|
||||
"description" : "Embedded RGB (linear)",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Linear",
|
||||
"gamma" : 1
|
||||
|
||||
BIN
autotests/read/iff/cdi_cl7.iff
Normal file
BIN
autotests/read/iff/cdi_cl7.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
autotests/read/iff/cdi_dyuv_each.iff
Normal file
9
autotests/read/iff/cdi_dyuv_each.iff.json
Normal file
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "cdi_dyuv_each.iff",
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 3937,
|
||||
"dotsPerMeterY" : 5249
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/iff/cdi_dyuv_each.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
autotests/read/iff/cdi_dyuv_one.iff
Normal file
BIN
autotests/read/iff/cdi_dyuv_one.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
autotests/read/iff/sv5_gray8_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_gray8_rgx.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
autotests/read/iff/sv5_idx8_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_idx8_rgx.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
autotests/read/iff/sv5_rgb16_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_rgb16_rgx.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
autotests/read/iff/sv5_rgb32_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_rgb32_rgx.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
autotests/read/iff/sv5_rgb8_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_rgb8_rgx.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
autotests/read/iff/sv5_rgba16_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_rgba16_rgx.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
autotests/read/iff/sv5_rgba32_rgx.iff
Normal file
37
autotests/read/iff/sv5_rgba32_rgx.iff.json
Normal file
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "sv5_rgba32_rgx.png",
|
||||
"colorSpace" : {
|
||||
"description" : "TIFF ICC Profile",
|
||||
"primaries" : "SRgb",
|
||||
"transferFunction" : "SRgb",
|
||||
"gamma" : 0
|
||||
},
|
||||
"metadata" : [
|
||||
{
|
||||
"key" : "Author",
|
||||
"value" : "KDE Project"
|
||||
},
|
||||
{
|
||||
"key" : "Copyright",
|
||||
"value" : "@2025 KDE Project"
|
||||
},
|
||||
{
|
||||
"key" : "CreationDate",
|
||||
"value" : "2025-01-14T10:34:51"
|
||||
},
|
||||
{
|
||||
"key" : "Description",
|
||||
"value" : "TV broadcast test image."
|
||||
},
|
||||
{
|
||||
"key" : "Title",
|
||||
"value" : "Test Card"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 2835,
|
||||
"dotsPerMeterY" : 2835
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/iff/sv5_rgba32_rgx.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
autotests/read/iff/sv5_rgba8_rgx.iff
Normal file
BIN
autotests/read/iff/sv5_rgba8_rgx.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
autotests/read/jxl/gray_linear_lossy.jxl
Normal file
14
autotests/read/jxl/gray_linear_lossy.jxl.json
Normal file
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "gray_linear_lossy.png",
|
||||
"fuzziness" : 1,
|
||||
"description" : "Minimum fuzziness value to pass the test on all architectures.",
|
||||
"colorSpace" : {
|
||||
"description" : "Gra_D65_Rel_SRG",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "SRgb",
|
||||
"gamma" : 0,
|
||||
"colorModel" : "Gray"
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/jxl/gray_linear_lossy.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
@@ -14,7 +14,7 @@
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "LIFE Pro 2.18.10"
|
||||
"value" : "LIFE Pro 2.20.35"
|
||||
},
|
||||
{
|
||||
"key" : "Altitude",
|
||||
@@ -32,6 +32,10 @@
|
||||
"key" : "Description",
|
||||
"value" : "TV broadcast test image."
|
||||
},
|
||||
{
|
||||
"key" : "HostComputer",
|
||||
"value" : "Windows 11 Enterprise (25H2)"
|
||||
},
|
||||
{
|
||||
"key" : "Latitude",
|
||||
"value" : "44.6478"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
{
|
||||
"fileName" : "32bit_grayscale.png",
|
||||
"colorSpace" : {
|
||||
"description" : "Linear Grayscale Profile",
|
||||
"colorModel" : "Gray",
|
||||
"description" : "RGB emulation of \"Linear Grayscale Profile\"",
|
||||
"colorModel" : "Rgb",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Linear",
|
||||
"gamma" : 1
|
||||
|
||||
BIN
autotests/read/psd/testcard_graya16.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
autotests/read/psd/testcard_graya16.psd
Normal file
26
autotests/read/psd/testcard_graya16.psd.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "testcard_graya16.png",
|
||||
"colorSpace" : {
|
||||
"description" : "RGB emulation of \"Gray Gamma 2.2\"",
|
||||
"colorModel" : "Rgb",
|
||||
"primaries" : "SRgb",
|
||||
"transferFunction" : "Gamma",
|
||||
"gamma" : 2.19922
|
||||
},
|
||||
"metadata" : [
|
||||
{
|
||||
"key" : "ModificationDate",
|
||||
"value" : "2025-11-17T07:27:47"
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "Adobe Photoshop 26.11 (Windows)"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 11811,
|
||||
"dotsPerMeterY" : 11811
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/psd/testcard_graya32.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
autotests/read/psd/testcard_graya32.psd
Normal file
26
autotests/read/psd/testcard_graya32.psd.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "testcard_graya32.png",
|
||||
"colorSpace" : {
|
||||
"description" : "RGB emulation of \"Profilo scala di grigio lineare\"",
|
||||
"colorModel" : "Rgb",
|
||||
"primaries" : "Custom",
|
||||
"transferFunction" : "Linear",
|
||||
"gamma" : 1
|
||||
},
|
||||
"metadata" : [
|
||||
{
|
||||
"key" : "ModificationDate",
|
||||
"value" : "2025-11-17T07:29:19"
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "Adobe Photoshop 26.11 (Windows)"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 11811,
|
||||
"dotsPerMeterY" : 11811
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/psd/testcard_graya8.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
autotests/read/psd/testcard_graya8.psd
Normal file
28
autotests/read/psd/testcard_graya8.psd.json
Normal file
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "testcard_graya8.png",
|
||||
"fuzziness" : 1,
|
||||
"perceptiveFuzziness" : true,
|
||||
"colorSpace" : {
|
||||
"description" : "RGB emulation of \"Gray Gamma 2.2\"",
|
||||
"colorModel" : "Rgb",
|
||||
"primaries" : "SRgb",
|
||||
"transferFunction" : "Gamma",
|
||||
"gamma" : 2.19922
|
||||
},
|
||||
"metadata" : [
|
||||
{
|
||||
"key" : "ModificationDate",
|
||||
"value" : "2025-11-17T07:28:50"
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "Adobe Photoshop 26.11 (Windows)"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
"dotsPerMeterX" : 11811,
|
||||
"dotsPerMeterY" : 11811
|
||||
}
|
||||
}
|
||||
]
|
||||
BIN
autotests/read/tim/testcard_idx4.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
autotests/read/tim/testcard_idx4.tim
Normal file
BIN
autotests/read/tim/testcard_idx8.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
autotests/read/tim/testcard_idx8.tim
Normal file
BIN
autotests/read/tim/testcard_rgb16.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
autotests/read/tim/testcard_rgb16.tim
Normal file
BIN
autotests/read/tim/testcard_rgb24.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
autotests/read/tim/testcard_rgb24.tim
Normal file
6
autotests/read/xcf/fruktpilot.xcf.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "fruktpilot.png",
|
||||
"fuzziness" : 1
|
||||
}
|
||||
]
|
||||
6
autotests/read/xcf/fruktpilot16_icc.xcf.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "fruktpilot16_icc.png",
|
||||
"fuzziness" : 1
|
||||
}
|
||||
]
|
||||
6
autotests/read/xcf/fruktpilot32_icc.xcf.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "fruktpilot32_icc.png",
|
||||
"fuzziness" : 1
|
||||
}
|
||||
]
|
||||
6
autotests/read/xcf/fruktpilot32fplin_icc.xcf.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "fruktpilot32fplin_icc.png",
|
||||
"fuzziness" : 1
|
||||
}
|
||||
]
|
||||
6
autotests/read/xcf/fruktpilot_icc.xcf.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"fileName" : "fruktpilot_icc.png",
|
||||
"fuzziness" : 1
|
||||
}
|
||||
]
|
||||
@@ -258,22 +258,26 @@ int main(int argc, char **argv)
|
||||
});
|
||||
QTextStream(stdout) << "QImageReader::supportedImageFormats: " << formatStrings.join(", ") << "\n";
|
||||
|
||||
// checks if the format has read capability
|
||||
if (!formats.contains(format)) {
|
||||
if (format == "avci" || format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : " << suffix << " is not supported with current libheif configuration!\n"
|
||||
<< "********* "
|
||||
<< "Finished basic read tests for " << suffix << " images *********\n";
|
||||
return 0;
|
||||
}
|
||||
QTextStream(stdout) << "FAIL : current configuration is missing necessary decoder(s) for " << suffix << "!\n"
|
||||
<< "********* "
|
||||
<< "Finished basic read tests for " << suffix << " images *********\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
const QFileInfoList lstImgDir = imgdir.entryInfoList();
|
||||
// Launch 2 runs for each test: first run on a random access device, second run on a sequential access device
|
||||
for (int seq = 0; seq < 2; ++seq) {
|
||||
// Launch 3 runs for each test:
|
||||
// - first run on a random access device with allocation limit set to 256 MiB.
|
||||
// - second run on a random access device with allocation limit set to 0 MiB.
|
||||
// - third run on a sequential access device.
|
||||
for (int run = 0; run < 3; ++run) {
|
||||
QImageReader::setAllocationLimit(run == 1 ? 0 : 256);
|
||||
bool seq = run == 2;
|
||||
if (seq) {
|
||||
QTextStream(stdout) << "* Run on SEQUENTIAL ACCESS device\n";
|
||||
} else {
|
||||
QTextStream(stdout) << "* Run on RANDOM ACCESS device\n";
|
||||
QTextStream(stdout) << "* Run on RANDOM ACCESS device (allocation limit: " << QImageReader::allocationLimit() << " MiB)\n";
|
||||
}
|
||||
for (const QFileInfo &fi : lstImgDir) {
|
||||
TemplateImage timg(fi);
|
||||
@@ -338,12 +342,7 @@ int main(int argc, char **argv)
|
||||
OptionTest optionTest;
|
||||
if (!optionTest.store(&inputReader)) {
|
||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": error while reading options\n";
|
||||
if (format == "heif") {
|
||||
// libheif + ffmpeg decoder is unable to load all HEIF files.
|
||||
++skipped;
|
||||
} else {
|
||||
++failed;
|
||||
}
|
||||
++failed;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,13 +138,11 @@ bool TemplateImage::checkOptionaInfo(const QImage& image, QString& error) const
|
||||
return false;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
auto clmName = QString(QMetaEnum::fromType<QColorSpace::ColorModel>().valueToKey(quint64(cs.colorModel())));
|
||||
if (clmName != clm) {
|
||||
error = QStringLiteral("ColorSpace ColorModel mismatch (current: %1, expected: %2)!").arg(clmName, clm);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test resolution
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
/*!
|
||||
* \brief skipSequentialDeviceTest
|
||||
* \return tre it the sequential test should be skipped.
|
||||
* \return True if the sequential test should be skipped.
|
||||
*/
|
||||
bool skipSequentialDeviceTest() const;
|
||||
|
||||
|
||||
@@ -13,14 +13,18 @@
|
||||
"key" : "ModificationDate",
|
||||
"value" : "2025-02-14T15:58:44+01:00"
|
||||
},
|
||||
{
|
||||
"key" : "Software" ,
|
||||
"value" : "Adobe Photoshop 26.2 (Windows)"
|
||||
},
|
||||
{
|
||||
"key" : "Altitude",
|
||||
"value" : "34"
|
||||
},
|
||||
{
|
||||
"key" : "Title",
|
||||
"value" : "A test"
|
||||
},
|
||||
{
|
||||
"key" : "Software",
|
||||
"value" : "KImageFormats write test"
|
||||
},
|
||||
{
|
||||
"key" : "Author",
|
||||
"value" : "KDE Project"
|
||||
@@ -45,6 +49,10 @@
|
||||
"key" : "LensModel",
|
||||
"value" : "A1234"
|
||||
},
|
||||
{
|
||||
"key" : "LensSerialNumber",
|
||||
"value" : "S/N:1234567"
|
||||
},
|
||||
{
|
||||
"key" : "Longitude",
|
||||
"value" : "10.9254"
|
||||
@@ -56,6 +64,50 @@
|
||||
{
|
||||
"key" : "Model",
|
||||
"value" : "KImageFormats"
|
||||
},
|
||||
{
|
||||
"key" : "SerialNumber",
|
||||
"value" : "S/N:7654321"
|
||||
},
|
||||
{
|
||||
"key" : "Speed",
|
||||
"value" : "13.2"
|
||||
},
|
||||
{
|
||||
"key" : "DigitalZoomRatio",
|
||||
"value" : "3.4"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureMode",
|
||||
"value" : "2"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureProgram",
|
||||
"value" : "6"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureTime",
|
||||
"value" : "0.004"
|
||||
},
|
||||
{
|
||||
"key" : "Flash",
|
||||
"value" : "16"
|
||||
},
|
||||
{
|
||||
"key" : "FNumber",
|
||||
"value" : "1.6"
|
||||
},
|
||||
{
|
||||
"key" : "FocalLength",
|
||||
"value" : "5.96"
|
||||
},
|
||||
{
|
||||
"key" : "ISOSpeedRatings",
|
||||
"value" : "50"
|
||||
},
|
||||
{
|
||||
"key" : "WhiteBalance",
|
||||
"value" : "1"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
"key" : "LensModel",
|
||||
"value" : "A1234"
|
||||
},
|
||||
{
|
||||
"key" : "LensSerialNumber",
|
||||
"value" : "S/N:1234567"
|
||||
},
|
||||
{
|
||||
"key" : "Longitude",
|
||||
"value" : "10.9254"
|
||||
@@ -52,6 +56,50 @@
|
||||
{
|
||||
"key" : "Model",
|
||||
"value" : "KImageFormats"
|
||||
},
|
||||
{
|
||||
"key" : "SerialNumber",
|
||||
"value" : "S/N:7654321"
|
||||
},
|
||||
{
|
||||
"key" : "Speed",
|
||||
"value" : "13.2"
|
||||
},
|
||||
{
|
||||
"key" : "DigitalZoomRatio",
|
||||
"value" : "3.4"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureMode",
|
||||
"value" : "2"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureProgram",
|
||||
"value" : "6"
|
||||
},
|
||||
{
|
||||
"key" : "ExposureTime",
|
||||
"value" : "0.004"
|
||||
},
|
||||
{
|
||||
"key" : "Flash",
|
||||
"value" : "16"
|
||||
},
|
||||
{
|
||||
"key" : "FNumber",
|
||||
"value" : "1.6"
|
||||
},
|
||||
{
|
||||
"key" : "FocalLength",
|
||||
"value" : "5.96"
|
||||
},
|
||||
{
|
||||
"key" : "ISOSpeedRatings",
|
||||
"value" : "50"
|
||||
},
|
||||
{
|
||||
"key" : "WhiteBalance",
|
||||
"value" : "1"
|
||||
}
|
||||
],
|
||||
"resolution" : {
|
||||
|
||||
@@ -62,7 +62,7 @@ void setOptionalInfo(QImage &image, const QString &suffix)
|
||||
|
||||
// Set metadata
|
||||
auto meta = obj.value("metadata").toArray();
|
||||
for (auto jv : meta) {
|
||||
for (auto &&jv : meta) {
|
||||
auto obj = jv.toObject();
|
||||
auto key = obj.value("key").toString();
|
||||
auto val = obj.value("value").toString();
|
||||
@@ -106,7 +106,7 @@ bool checkOptionalInfo(QImage &image, const QString &suffix)
|
||||
|
||||
// Test metadata
|
||||
auto meta = obj.value("metadata").toArray();
|
||||
for (auto jv : meta) {
|
||||
for (auto &&jv : meta) {
|
||||
auto obj = jv.toObject();
|
||||
auto key = obj.value("key").toString();
|
||||
auto val = obj.value("value").toString();
|
||||
@@ -319,11 +319,9 @@ QImage formatSourceImage(const QImage::Format &format)
|
||||
image = QImage(QStringLiteral("%1/rgba16.png").arg(folder));
|
||||
break;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
case QImage::Format_CMYK8888:
|
||||
image = QImage(QStringLiteral("%1/cmyk8.tif").arg(folder));
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -382,12 +380,7 @@ int formatTest(const QString &suffix, bool createTemplates)
|
||||
QBuffer buffer(&ba);
|
||||
auto writtenImage = QImageReader(&buffer, suffix.toLatin1()).read();
|
||||
if (writtenImage.isNull()) {
|
||||
if (suffix.toLatin1() == "heif") {
|
||||
// libheif + ffmpeg decoder is unable to load all HEIF files.
|
||||
++skipped;
|
||||
} else {
|
||||
++failed;
|
||||
}
|
||||
++failed;
|
||||
QTextStream(stdout) << "FAIL : error while reading the image " << formatName << "\n";
|
||||
continue;
|
||||
}
|
||||
@@ -641,23 +634,17 @@ int main(int argc, char **argv)
|
||||
|
||||
auto suffix = args.at(0);
|
||||
|
||||
// skip test if libheif configuration is obviously incomplete
|
||||
// skip test if configuration is obviously incomplete
|
||||
QByteArray format = suffix.toLatin1();
|
||||
const QList<QByteArray> read_formats = QImageReader::supportedImageFormats();
|
||||
const QList<QByteArray> write_formats = QImageWriter::supportedImageFormats();
|
||||
|
||||
if (!read_formats.contains(format)) {
|
||||
if (format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : libheif configuration is missing necessary decoder(s)!\n";
|
||||
return 0;
|
||||
}
|
||||
if (!read_formats.contains(format)) { // checks if the format has read capability
|
||||
QTextStream(stdout) << "FAIL : current configuration is missing necessary decoder(s) for " << format << "!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!write_formats.contains(format)) {
|
||||
if (format == "heif" || format == "hej2") {
|
||||
QTextStream(stdout) << "WARNING : libheif configuration is missing necessary encoder(s)!\n";
|
||||
return 0;
|
||||
}
|
||||
const QList<QByteArray> write_formats = QImageWriter::supportedImageFormats();
|
||||
if (!write_formats.contains(format)) { // checks if the format has write capability
|
||||
QTextStream(stdout) << "FAIL : libraries configuration is missing necessary encoder(s) for " << format << "!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// run test
|
||||
|
||||
@@ -137,6 +137,10 @@ kimageformats_add_plugin(kimg_sct SOURCES sct.cpp)
|
||||
|
||||
##################################
|
||||
|
||||
kimageformats_add_plugin(kimg_tim SOURCES tim.cpp)
|
||||
|
||||
##################################
|
||||
|
||||
kimageformats_add_plugin(kimg_tga SOURCES tga.cpp microexif.cpp scanlineconverter.cpp)
|
||||
|
||||
##################################
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "ani_p.h"
|
||||
#include "util_p.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QLoggingCategory>
|
||||
@@ -101,7 +102,7 @@ bool ANIHandler::read(QImage *outImage)
|
||||
}
|
||||
|
||||
const auto frameSize = *(reinterpret_cast<const quint32_le *>(frameSizeData.data()));
|
||||
if (!frameSize) {
|
||||
if (!frameSize || frameSize > quint32(kMaxQVectorSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -417,6 +418,9 @@ bool ANIHandler::ensureScanned() const
|
||||
// IART and INAM are technically inside LIST->INFO but "INFO" is supposedly optional
|
||||
// so just handle those two attributes wherever we encounter them
|
||||
} else if (chunkId == "INAM" || chunkId == "IART") {
|
||||
if (chunkSize > kMaxQVectorSize) {
|
||||
return false;
|
||||
}
|
||||
const QByteArray value = device()->read(chunkSize);
|
||||
|
||||
if (static_cast<quint32_le>(value.size()) != chunkSize) {
|
||||
|
||||
@@ -265,9 +265,15 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t resultdepth = m_decoder->image->depth;
|
||||
if (m_decoder->image->matrixCoefficients == 16 && m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444 && resultdepth == 10) {
|
||||
// 10-bit YCgCo-Re AVIF must be decoded to 8bit
|
||||
resultdepth = 8;
|
||||
}
|
||||
|
||||
QImage::Format resultformat;
|
||||
|
||||
if (m_decoder->image->depth > 8) {
|
||||
if (resultdepth > 8) {
|
||||
if (loadalpha) {
|
||||
resultformat = QImage::Format_RGBA64;
|
||||
} else {
|
||||
@@ -293,9 +299,7 @@ bool QAVIFHandler::decode_one_frame()
|
||||
colorspace = QColorSpace::fromIccProfile(icc_data);
|
||||
if (!colorspace.isValid()) {
|
||||
qCWarning(LOG_AVIFPLUGIN, "AVIF image has Qt-unsupported or invalid ICC profile!");
|
||||
}
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
else {
|
||||
} else {
|
||||
if (colorspace.colorModel() == QColorSpace::ColorModel::Cmyk) {
|
||||
qCWarning(LOG_AVIFPLUGIN, "CMYK ICC profile is not extected for AVIF, discarding the ICCprofile!");
|
||||
colorspace = QColorSpace();
|
||||
@@ -325,7 +329,6 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
float prim[8] = {0.64f, 0.33f, 0.3f, 0.6f, 0.15f, 0.06f, 0.3127f, 0.329f};
|
||||
// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY
|
||||
@@ -360,14 +363,12 @@ bool QAVIFHandler::decode_one_frame()
|
||||
case 13:
|
||||
q_trc = QColorSpace::TransferFunction::SRgb;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case 16: /* AVIF_TRANSFER_CHARACTERISTICS_PQ */
|
||||
q_trc = QColorSpace::TransferFunction::St2084;
|
||||
break;
|
||||
case 18: /* AVIF_TRANSFER_CHARACTERISTICS_HLG */
|
||||
q_trc = QColorSpace::TransferFunction::Hlg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
qCWarning(LOG_AVIFPLUGIN, "CICP colorPrimaries: %d, transferCharacteristics: %d\nThe colorspace is unsupported by this plug-in yet.",
|
||||
m_decoder->image->colorPrimaries,
|
||||
@@ -377,11 +378,9 @@ bool QAVIFHandler::decode_one_frame()
|
||||
}
|
||||
|
||||
if (q_trc != QColorSpace::TransferFunction::Custom) { // we create new colorspace using Qt
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
if (loadgray) {
|
||||
colorspace = QColorSpace(whitePoint, q_trc, q_trc_gamma);
|
||||
} else {
|
||||
#endif
|
||||
switch (m_decoder->image->colorPrimaries) {
|
||||
/* AVIF_COLOR_PRIMARIES_BT709 */
|
||||
case 0:
|
||||
@@ -389,6 +388,9 @@ bool QAVIFHandler::decode_one_frame()
|
||||
case 2: /* AVIF_COLOR_PRIMARIES_UNSPECIFIED */
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::SRgb, q_trc, q_trc_gamma);
|
||||
break;
|
||||
case 9:
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::Bt2020, q_trc, q_trc_gamma);
|
||||
break;
|
||||
/* AVIF_COLOR_PRIMARIES_SMPTE432 */
|
||||
case 12:
|
||||
colorspace = QColorSpace(QColorSpace::Primaries::DciP3D65, q_trc, q_trc_gamma);
|
||||
@@ -397,9 +399,7 @@ bool QAVIFHandler::decode_one_frame()
|
||||
colorspace = QColorSpace(whitePoint, redPoint, greenPoint, bluePoint, q_trc, q_trc_gamma);
|
||||
break;
|
||||
}
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!colorspace.isValid()) {
|
||||
@@ -414,7 +414,7 @@ bool QAVIFHandler::decode_one_frame()
|
||||
rgb.maxThreads = m_decoder->maxThreads;
|
||||
#endif
|
||||
|
||||
if (m_decoder->image->depth > 8) {
|
||||
if (resultdepth > 8) {
|
||||
rgb.depth = 16;
|
||||
rgb.format = AVIF_RGB_FORMAT_RGBA;
|
||||
|
||||
@@ -513,21 +513,12 @@ bool QAVIFHandler::decode_one_frame()
|
||||
#else
|
||||
switch (m_decoder->image->imir.axis) {
|
||||
#endif
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
|
||||
case 0: // top-to-bottom
|
||||
result = result.mirrored(false, true);
|
||||
break;
|
||||
case 1: // left-to-right
|
||||
result = result.mirrored(true, false);
|
||||
break;
|
||||
#else
|
||||
case 0: // top-to-bottom
|
||||
result = result.flipped(Qt::Vertical);
|
||||
break;
|
||||
case 1: // left-to-right
|
||||
result = result.flipped(Qt::Horizontal);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,22 +734,65 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_LINEAR */
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)8;
|
||||
break;
|
||||
case QColorSpace::TransferFunction::Gamma:
|
||||
if (qAbs(tmpgrayimage.colorSpace().gamma() - 2.2f) < 0.1f) {
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_BT470M */
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)4;
|
||||
} else if (qAbs(tmpgrayimage.colorSpace().gamma() - 2.8f) < 0.1f) {
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_BT470BG */
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)5;
|
||||
}
|
||||
break;
|
||||
case QColorSpace::TransferFunction::SRgb:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)13;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case QColorSpace::TransferFunction::St2084:
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)16;
|
||||
break;
|
||||
case QColorSpace::TransferFunction::Hlg:
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)18;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||
break;
|
||||
}
|
||||
|
||||
if (avif->transferCharacteristics == 2) { // in case TransferFunction was not identified yet
|
||||
if (tmpgrayimage.colorSpace().colorModel() == QColorSpace::ColorModel::Gray && lossless) {
|
||||
avif->colorPrimaries = (avifColorPrimaries)2;
|
||||
avif->matrixCoefficients = (avifMatrixCoefficients)6;
|
||||
|
||||
QByteArray iccprofile_gray = tmpgrayimage.colorSpace().iccProfile();
|
||||
|
||||
if (iccprofile_gray.size() > 0) {
|
||||
#if AVIF_VERSION >= 1000000
|
||||
res = avifImageSetProfileICC(avif, reinterpret_cast<const uint8_t *>(iccprofile_gray.constData()), iccprofile_gray.size());
|
||||
if (res != AVIF_RESULT_OK) {
|
||||
qCWarning(LOG_AVIFPLUGIN, "ERROR in avifImageSetProfileICC: %s", avifResultToString(res));
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
avifImageSetProfileICC(avif, reinterpret_cast<const uint8_t *>(iccprofile_gray.constData()), iccprofile_gray.size());
|
||||
#endif
|
||||
}
|
||||
} else { // convert to grayscale with SRgb
|
||||
tmpgrayimage.convertToColorSpace(QColorSpace(QPointF(0.3127f, 0.329f), QColorSpace::TransferFunction::SRgb), QImage::Format_Grayscale16);
|
||||
switch (tmpgrayimage.format()) {
|
||||
case QImage::Format_Grayscale8:
|
||||
save_depth = 8;
|
||||
break;
|
||||
case QImage::Format_Grayscale16:
|
||||
save_depth = 10;
|
||||
avif->transferCharacteristics = (avifTransferCharacteristics)13;
|
||||
break;
|
||||
default:
|
||||
qCWarning(LOG_AVIFPLUGIN, "Error saving Gray image");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (save_depth > 8) { // QImage::Format_Grayscale16
|
||||
@@ -799,7 +833,6 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
QImage tmpcolorimage;
|
||||
auto cs = image.colorSpace();
|
||||
if (cs.isValid() && cs.colorModel() == QColorSpace::ColorModel::Cmyk && image.format() == QImage::Format_CMYK8888) {
|
||||
@@ -814,9 +847,6 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
} else {
|
||||
tmpcolorimage = image.convertToFormat(tmpformat);
|
||||
}
|
||||
#else
|
||||
QImage tmpcolorimage = image.convertToFormat(tmpformat);
|
||||
#endif
|
||||
|
||||
avifPixelFormat pixel_format = AVIF_PIXEL_FORMAT_YUV420;
|
||||
if (m_quality >= KIMG_AVIF_QUALITY_HIGH) {
|
||||
@@ -847,6 +877,10 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
/* AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL */
|
||||
matrix_to_save = (avifMatrixCoefficients)12;
|
||||
break;
|
||||
case QColorSpace::Primaries::Bt2020:
|
||||
primaries_to_save = (avifColorPrimaries)9;
|
||||
matrix_to_save = (avifMatrixCoefficients)12;
|
||||
break;
|
||||
default:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||
primaries_to_save = (avifColorPrimaries)2;
|
||||
@@ -876,14 +910,12 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_SRGB */
|
||||
transfer_to_save = (avifTransferCharacteristics)13;
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case QColorSpace::TransferFunction::St2084:
|
||||
transfer_to_save = (avifTransferCharacteristics)16;
|
||||
break;
|
||||
case QColorSpace::TransferFunction::Hlg:
|
||||
transfer_to_save = (avifTransferCharacteristics)18;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED */
|
||||
transfer_to_save = (avifTransferCharacteristics)2;
|
||||
@@ -919,14 +951,12 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
case 5: // AVIF_TRANSFER_CHARACTERISTICS_BT470BG
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, 2.8f));
|
||||
break;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 8, 0))
|
||||
case 16:
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::St2084));
|
||||
break;
|
||||
case 18:
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::Hlg));
|
||||
break;
|
||||
#endif
|
||||
default: // AVIF_TRANSFER_CHARACTERISTICS_SRGB + any other
|
||||
tmpcolorimage.convertToColorSpace(QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::SRgb));
|
||||
transfer_to_save = (avifTransferCharacteristics)13;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 2025 Mirco Miranda <mircomir@outlook.com>
|
||||
SPDX-FileCopyrightText: 2025-2026 Mirco Miranda <mircomir@outlook.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
* - https://wiki.amigaos.net/wiki/IFF_FORM_and_Chunk_Registry
|
||||
* - https://www.fileformat.info/format/iff/egff.htm
|
||||
* - https://download.autodesk.com/us/maya/2010help/index.html (Developer resources -> File formats -> Maya IFF)
|
||||
* - https://aminet.net/package/dev/misc/IFF-RGFX
|
||||
*/
|
||||
|
||||
#ifndef KIMG_CHUNKS_P_H
|
||||
@@ -36,7 +37,7 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_IFFPLUGIN)
|
||||
#define LIST_CHUNK QByteArray("LIST")
|
||||
#define PROP_CHUNK QByteArray("PROP")
|
||||
|
||||
// Main chuncks (Maya)
|
||||
// Main chunks (Maya)
|
||||
#define CAT4_CHUNK QByteArray("CAT4") // 4 byte alignment
|
||||
#define FOR4_CHUNK QByteArray("FOR4")
|
||||
#define LIS4_CHUNK QByteArray("LIS4")
|
||||
@@ -55,7 +56,17 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_IFFPLUGIN)
|
||||
#define CMAP_CHUNK QByteArray("CMAP")
|
||||
#define CMYK_CHUNK QByteArray("CMYK") // https://wiki.amigaos.net/wiki/ILBM_IFF_Interleaved_Bitmap#ILBM.CMYK
|
||||
#define DPI__CHUNK QByteArray("DPI ")
|
||||
#define IDAT_CHUNK QByteArray("IDAT")
|
||||
#define IHDR_CHUNK QByteArray("IHDR")
|
||||
#define IPAR_CHUNK QByteArray("IPAR")
|
||||
#define PLTE_CHUNK QByteArray("PLTE")
|
||||
#define RBOD_CHUNK QByteArray("RBOD")
|
||||
#define RCOL_CHUNK QByteArray("RCOL")
|
||||
#define RFLG_CHUNK QByteArray("RFLG")
|
||||
#define RGHD_CHUNK QByteArray("RGHD")
|
||||
#define RSCM_CHUNK QByteArray("RSCM")
|
||||
#define XBMI_CHUNK QByteArray("XBMI")
|
||||
#define YUVS_CHUNK QByteArray("YUVS")
|
||||
|
||||
// Different palette for scanline
|
||||
#define BEAM_CHUNK QByteArray("BEAM")
|
||||
@@ -79,14 +90,18 @@ Q_DECLARE_LOGGING_CATEGORY(LOG_IFFPLUGIN)
|
||||
#define FVER_CHUNK QByteArray("FVER")
|
||||
#define HIST_CHUNK QByteArray("HIST")
|
||||
#define NAME_CHUNK QByteArray("NAME")
|
||||
#define VDAT_CHUNK QByteArray("VDAT")
|
||||
#define VERS_CHUNK QByteArray("VERS")
|
||||
#define XMP0_CHUNK QByteArray("XMP0") // https://aminet.net/package/docs/misc/IFF-metadata
|
||||
|
||||
// FORM types
|
||||
#define ACBM_FORM_TYPE QByteArray("ACBM")
|
||||
#define ILBM_FORM_TYPE QByteArray("ILBM")
|
||||
#define IMAG_FORM_TYPE QByteArray("IMAG")
|
||||
#define PBM__FORM_TYPE QByteArray("PBM ")
|
||||
#define RGB8_FORM_TYPE QByteArray("RGB8")
|
||||
#define RGBN_FORM_TYPE QByteArray("RGBN")
|
||||
#define RGFX_FORM_TYPE QByteArray("RGFX")
|
||||
|
||||
#define CIMG_FOR4_TYPE QByteArray("CIMG")
|
||||
#define TBMP_FOR4_TYPE QByteArray("TBMP")
|
||||
@@ -145,7 +160,7 @@ public:
|
||||
|
||||
/*!
|
||||
* \brief bytes
|
||||
* \return The size (in bytes) of the chunck data.
|
||||
* \return The size (in bytes) of the chunk data.
|
||||
*/
|
||||
|
||||
quint32 bytes() const;
|
||||
@@ -350,6 +365,12 @@ protected:
|
||||
|
||||
static ChunkList innerFromDevice(QIODevice *d, bool *ok, IFFChunk *parent = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief dataBytes
|
||||
* \return Maximum usable cache data size.
|
||||
*/
|
||||
quint32 dataBytes() const;
|
||||
|
||||
private:
|
||||
char _chunkId[4];
|
||||
|
||||
@@ -418,7 +439,8 @@ public:
|
||||
enum Compression {
|
||||
Uncompressed = 0, /**< Image data are uncompressed. */
|
||||
Rle = 1, /**< Image data are RLE compressed. */
|
||||
RgbN8 = 4 /**< RGB8/RGBN compresson. */
|
||||
Vdat = 2, /**< Image data are VDAT compressed. */
|
||||
RgbN8 = 4 /**< Image data are RGB8/RGBN compressed. */
|
||||
};
|
||||
enum Masking {
|
||||
None = 0, /**< Designates an opaque rectangular image. */
|
||||
@@ -750,10 +772,11 @@ public:
|
||||
/*!
|
||||
* \brief readStride
|
||||
* \param d The device.
|
||||
* \param header The bitmap header.
|
||||
* \param y The current scanline.
|
||||
* \param header The bitmap header.
|
||||
* \param camg The CAMG chunk (optional)
|
||||
* \param cmap The CMAP chunk (optional)
|
||||
* \param ipal The per-line palette chunk (optional)
|
||||
* \param formType The type of the current form chunk.
|
||||
* \return The scanline as requested for QImage.
|
||||
* \warning Call resetStrideRead() once before this one.
|
||||
@@ -770,8 +793,6 @@ public:
|
||||
* \brief resetStrideRead
|
||||
* Reset the stride read set the position at the beginning of the data and reset all buffers.
|
||||
* \param d The device.
|
||||
* \param header The BMHDChunk chunk (mandatory)
|
||||
* \param camg The CAMG chunk (optional)
|
||||
* \return True on success, otherwise false.
|
||||
* \sa strideRead
|
||||
* \note Must be called once before strideRead().
|
||||
@@ -782,6 +803,7 @@ public:
|
||||
* \brief safeModeId
|
||||
* \param header The header.
|
||||
* \param camg The CAMG chunk.
|
||||
* \param cmap The CMAP chunk.
|
||||
* \return The most likely ModeId if not explicitly specified.
|
||||
*/
|
||||
static CAMGChunk::ModeIds safeModeId(const BMHDChunk *header, const CAMGChunk *camg, const CMAPChunk *cmap = nullptr);
|
||||
@@ -802,6 +824,8 @@ protected:
|
||||
|
||||
QByteArray rgbN(const QByteArray &planes, qint32 y, const BMHDChunk *header, const CAMGChunk *camg = nullptr, const CMAPChunk *cmap = nullptr, const IPALChunk *ipal = nullptr) const;
|
||||
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
|
||||
private:
|
||||
mutable QByteArray _readBuffer;
|
||||
};
|
||||
@@ -864,7 +888,7 @@ public:
|
||||
/*!
|
||||
* \brief transformation
|
||||
* \return The image transformation.
|
||||
* \note The Default implentation returns the trasformation of EXIF chunk (if any).
|
||||
* \note The Default implementation returns the transformation of EXIF chunk (if any).
|
||||
*/
|
||||
virtual QImageIOHandler::Transformation transformation() const;
|
||||
|
||||
@@ -915,6 +939,13 @@ public:
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
|
||||
private:
|
||||
QImage::Format iffFormat() const;
|
||||
|
||||
QImage::Format cdiFormat() const;
|
||||
|
||||
QImage::Format rgfxFormat() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1351,6 +1382,32 @@ protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The VDATChunk class
|
||||
*/
|
||||
class VDATChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
virtual ~VDATChunk() override;
|
||||
VDATChunk();
|
||||
VDATChunk(const VDATChunk& other) = default;
|
||||
VDATChunk& operator =(const VDATChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
CHUNKID_DEFINE(VDAT_CHUNK)
|
||||
|
||||
const QByteArray &uncompressedData(const BMHDChunk *header) const;
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
|
||||
private:
|
||||
mutable QByteArray uncompressed;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The VERSChunk class
|
||||
*/
|
||||
@@ -1394,6 +1451,500 @@ protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
/*!
|
||||
* *** I-CD IFF CHUNKS ***
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief The IHDRChunk class
|
||||
* Image Header
|
||||
*/
|
||||
class IHDRChunk: public IFFChunk
|
||||
{
|
||||
public:
|
||||
enum Model {
|
||||
Invalid = 0, /**< Invalid model. */
|
||||
Rgb888 = 1, /**< red, green, blue - 8 bits per color. */
|
||||
Rgb555 = 2, /**< Green Book absolute RGB. */
|
||||
DYuv = 3, /**< Green Book Delta YUV. */
|
||||
CLut8 = 4, /**< Green Book 8 bit CLUT. */
|
||||
CLut7 = 5, /**< Green Book 7 bit CLUT. */
|
||||
CLut4 = 6, /**< Green Book 4 bit CLUT. */
|
||||
CLut3 = 7, /**< Green Book 3 bit CLUT. */
|
||||
Rle7 = 8, /**< Green Book runlength coded 7 bit CLUT. */
|
||||
Rle3 = 9, /**< Green Book runlength coded 3 bit CLUT. */
|
||||
PaletteOnly = 10 /**< color palette only. */
|
||||
};
|
||||
|
||||
enum DYuvKind {
|
||||
One = 0,
|
||||
Each = 1
|
||||
};
|
||||
|
||||
struct Yuv {
|
||||
Yuv(quint8 y0 = 0, quint8 u0 = 0, quint8 v0 = 0) : y(y0), u(u0), v(v0) {}
|
||||
quint8 y;
|
||||
quint8 u;
|
||||
quint8 v;
|
||||
};
|
||||
|
||||
virtual ~IHDRChunk() override;
|
||||
|
||||
IHDRChunk();
|
||||
IHDRChunk(const IHDRChunk& other) = default;
|
||||
IHDRChunk& operator =(const IHDRChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
/*!
|
||||
* \brief width
|
||||
* \return Width of the bitmap in pixels.
|
||||
*/
|
||||
qint32 width() const;
|
||||
|
||||
/*!
|
||||
* \brief height
|
||||
* \return Height of the bitmap in pixels.
|
||||
*/
|
||||
qint32 height() const;
|
||||
|
||||
/*!
|
||||
* \brief size
|
||||
* \return Size in pixels.
|
||||
*/
|
||||
QSize size() const;
|
||||
|
||||
/*!
|
||||
* \brief lineSize
|
||||
* Physical width of image (number of bytes in each scan line, including any data required at
|
||||
* the end of each scan line for padding [see description of each model’s IDAT chunk for padding
|
||||
* rules]) This field is not used when model() = Rle7 or Rle3.
|
||||
* When model() = Rgb555, this field defines the size of one scan line of the upper
|
||||
* or lower portion of the pixel data, but not the size of them both together.
|
||||
*/
|
||||
qint32 lineSize() const;
|
||||
|
||||
/*!
|
||||
* \brief model
|
||||
* Image model (coding method)
|
||||
*/
|
||||
Model model() const;
|
||||
|
||||
/*!
|
||||
* \brief depth
|
||||
* Physical size of pixel (number of bits per pixel used in storing image data) When
|
||||
* model() = Rle7 or Rle3, this value only represents the size of a
|
||||
* single pixel; the size of a run of pixels is indeterminate.
|
||||
*/
|
||||
quint16 depth() const;
|
||||
|
||||
/*!
|
||||
* \brief yuvKind
|
||||
* if model() = DYuv, indicates whether there is one DYUV start value for all
|
||||
* scan lines (in yuvStart()), or whether each scan line has its own start value in the
|
||||
* YUVS chunk which follows.
|
||||
*/
|
||||
DYuvKind yuvKind() const;
|
||||
|
||||
/*!
|
||||
* \brief yuvStart
|
||||
* Start values for DYUV image if model() = DYuv and dYuvKind() = One
|
||||
*/
|
||||
Yuv yuvStart() const;
|
||||
|
||||
CHUNKID_DEFINE(IHDR_CHUNK)
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The IHDRChunk class
|
||||
*/
|
||||
class IPARChunk: public IFFChunk
|
||||
{
|
||||
public:
|
||||
struct Rgb {
|
||||
Rgb(quint8 r0 = 0, quint8 g0 = 0, quint8 b0 = 0) : r(r0), g(g0), b(b0) {}
|
||||
quint8 r;
|
||||
quint8 g;
|
||||
quint8 b;
|
||||
};
|
||||
|
||||
virtual ~IPARChunk() override;
|
||||
|
||||
IPARChunk();
|
||||
IPARChunk(const IPARChunk& other) = default;
|
||||
IPARChunk& operator =(const IPARChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
/*!
|
||||
* \brief xOffset
|
||||
* X offset of origin in source image [0 < xOffset() < xPage()]
|
||||
*/
|
||||
qint32 xOffset() const;
|
||||
|
||||
/*!
|
||||
* \brief yOffset
|
||||
* \returnX offset of origin in source image [0 < yOffset() < yPage()]
|
||||
*/
|
||||
qint32 yOffset() const;
|
||||
|
||||
/*!
|
||||
* \brief aspectRatio
|
||||
* Aspect ratio of pixels in source image.
|
||||
*/
|
||||
double aspectRatio() const;
|
||||
|
||||
/*!
|
||||
* \brief xPage
|
||||
* X size of source image.
|
||||
*/
|
||||
qint32 xPage() const;
|
||||
|
||||
/*!
|
||||
* \brief yPage
|
||||
* Y size of source image.
|
||||
*/
|
||||
qint32 yPage() const;
|
||||
|
||||
/*!
|
||||
* \brief xGrub
|
||||
* X location of hot spot within image.
|
||||
*/
|
||||
qint32 xGrub() const;
|
||||
|
||||
/*!
|
||||
* \brief yGrub
|
||||
* Y location of hot spot within image.
|
||||
*/
|
||||
qint32 yGrub() const;
|
||||
|
||||
/*!
|
||||
* \brief transparency
|
||||
* Transparent color.
|
||||
*/
|
||||
Rgb transparency() const;
|
||||
|
||||
/*!
|
||||
* \brief mask
|
||||
* Mask color.
|
||||
*/
|
||||
Rgb mask() const;
|
||||
|
||||
CHUNKID_DEFINE(IPAR_CHUNK)
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The PLTEChunk class
|
||||
*/
|
||||
class PLTEChunk : public CMAPChunk
|
||||
{
|
||||
public:
|
||||
virtual ~PLTEChunk() override;
|
||||
PLTEChunk();
|
||||
PLTEChunk(const PLTEChunk& other) = default;
|
||||
PLTEChunk& operator =(const PLTEChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
/*!
|
||||
* \brief count
|
||||
* \return The number of color in the palette.
|
||||
*/
|
||||
virtual qint32 count() const override;
|
||||
|
||||
CHUNKID_DEFINE(PLTE_CHUNK)
|
||||
|
||||
protected:
|
||||
qint32 offset() const;
|
||||
|
||||
qint32 total() const;
|
||||
|
||||
virtual QList<QRgb> innerPalette() const override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The YUVSChunk class
|
||||
*/
|
||||
class YUVSChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
virtual ~YUVSChunk() override;
|
||||
YUVSChunk();
|
||||
YUVSChunk(const YUVSChunk& other) = default;
|
||||
YUVSChunk& operator =(const YUVSChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
qint32 count() const;
|
||||
|
||||
IHDRChunk::Yuv yuvStart(qint32 y) const;
|
||||
|
||||
CHUNKID_DEFINE(YUVS_CHUNK)
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The IDATChunk class
|
||||
*/
|
||||
class IDATChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
virtual ~IDATChunk() override;
|
||||
IDATChunk();
|
||||
IDATChunk(const IDATChunk& other) = default;
|
||||
IDATChunk& operator =(const IDATChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
CHUNKID_DEFINE(IDAT_CHUNK)
|
||||
|
||||
/*!
|
||||
* \brief readStride
|
||||
* \param d The device.
|
||||
* \param y The current scanline.
|
||||
* \param header The bitmap header.
|
||||
* \param params The additional parameters (optional)
|
||||
* \return The scanline as requested for QImage.
|
||||
* \warning Call resetStrideRead() once before this one.
|
||||
*/
|
||||
QByteArray strideRead(QIODevice *d,
|
||||
qint32 y,
|
||||
const IHDRChunk *header,
|
||||
const IPARChunk *params = nullptr,
|
||||
const YUVSChunk *yuvs = nullptr) const;
|
||||
|
||||
/*!
|
||||
* \brief resetStrideRead
|
||||
* Reset the stride read set the position at the beginning of the data and reset all buffers.
|
||||
* \param d The device.
|
||||
* \return True on success, otherwise false.
|
||||
* \sa strideRead
|
||||
* \note Must be called once before strideRead().
|
||||
*/
|
||||
bool resetStrideRead(QIODevice *d) const;
|
||||
|
||||
protected:
|
||||
quint32 strideSize(const IHDRChunk *header) const;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* *** RGFX IFF CHUNKS ***
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief The RGHDChunk class
|
||||
*/
|
||||
class RGHDChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
enum Compression {
|
||||
Uncompressed = 0,
|
||||
Xpk = 1, /**< any XPK-packer */
|
||||
Zip = 2 /**< libzip (LZ77/ZIP) compression */
|
||||
};
|
||||
|
||||
enum BitmapType {
|
||||
Planar8 = 0x0000, /**< unaligned planar 8 bit bitmap */
|
||||
Chunky8 = 0x0001, /**< unaligned chunky 8 bit bitmap */
|
||||
Rgb24 = 0x0002, /**< 3-byte 24 bit RGB triples */
|
||||
Rgb32 = 0x0004, /**< 4-byte 32 bit ARGB quadruples */
|
||||
Rgb15 = 0x0010, /**< 2-byte 15 bit RGB (x+3x5 bit integer) */
|
||||
Rgb16 = 0x0020, /**< 2-byte 16 bit ARGB (1+3x5 bit integer) */
|
||||
Rgb48 = 0x0040, /**< 6-byte 48 bit RGB (3x 16 bit integer) */
|
||||
Rgb64 = 0x0080, /**< 8-byte 64 bit ARGB (4x 16 bit integer) */
|
||||
Rgb96 = 0x0100, /**< 12-byte 96 bit RGB (3x 32 bit float) */
|
||||
Rgb128 = 0x0200, /**< 16-byte 128 bit ARGB (4x 32 bit float) */
|
||||
|
||||
HasAlpha = (1 << 30), /**< set if A is meaningful */
|
||||
HasInvAlpha = (1 << 31) /**< set if A is meaningful but inversed (A = 255 - alpha) */
|
||||
};
|
||||
Q_DECLARE_FLAGS(BitmapTypes, BitmapType)
|
||||
|
||||
virtual ~RGHDChunk() override;
|
||||
RGHDChunk();
|
||||
RGHDChunk(const RGHDChunk&) = default;
|
||||
RGHDChunk& operator=(const RGHDChunk&) = default;
|
||||
|
||||
CHUNKID_DEFINE(RGHD_CHUNK)
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
QSize size() const;
|
||||
|
||||
qint32 leftEdge() const;
|
||||
|
||||
qint32 topEdge() const;
|
||||
|
||||
qint32 width() const;
|
||||
|
||||
qint32 height() const;
|
||||
|
||||
qint32 pageWidth() const;
|
||||
|
||||
qint32 pageHeight() const;
|
||||
|
||||
quint32 depth() const;
|
||||
|
||||
quint32 pixelBits() const;
|
||||
|
||||
quint32 bytesPerLine() const;
|
||||
|
||||
Compression compression() const;
|
||||
|
||||
quint32 xAspect() const;
|
||||
|
||||
quint32 yAspect() const;
|
||||
|
||||
BitmapTypes bitmapType() const;
|
||||
|
||||
double aspectRatio() const;
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The RCOLChunk class
|
||||
*/
|
||||
class RCOLChunk : public CMAPChunk
|
||||
{
|
||||
public:
|
||||
virtual ~RCOLChunk() override;
|
||||
RCOLChunk();
|
||||
RCOLChunk(const RCOLChunk& other) = default;
|
||||
RCOLChunk& operator =(const RCOLChunk& other) = default;
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
virtual qint32 count() const override;
|
||||
|
||||
CHUNKID_DEFINE(RCOL_CHUNK)
|
||||
|
||||
protected:
|
||||
virtual QList<QRgb> innerPalette() const override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The RFLGChunk class
|
||||
*/
|
||||
class RFLGChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
enum class Flag : quint32 {
|
||||
FromGray = 0x08, /**< created from 8/16 bit gray source so R==G==B */
|
||||
From8Bit = 0x10, /**< created from 8 bit source, so (R,G,B)&0xFF00 == ... & 0x00FF */
|
||||
From4Bit = 0x20, /**< created from 4 bit source, so (R,G,B)&0xF0 == ... & 0x0F */
|
||||
From8BitAlpha = 0x40, /**< 16/32 bit alpha created from 8 bit alpha source */
|
||||
From16BitAlpha = 0x80 /**< 32 bit alpha created from 16 bit alpha source */
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
virtual ~RFLGChunk() override;
|
||||
RFLGChunk();
|
||||
RFLGChunk(const RFLGChunk&) = default;
|
||||
RFLGChunk& operator=(const RFLGChunk&) = default;
|
||||
|
||||
CHUNKID_DEFINE(RFLG_CHUNK)
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
Flags flags() const;
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The RSCMChunk class
|
||||
*/
|
||||
class RSCMChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
virtual ~RSCMChunk() override;
|
||||
RSCMChunk();
|
||||
RSCMChunk(const RSCMChunk&) = default;
|
||||
RSCMChunk& operator=(const RSCMChunk&) = default;
|
||||
|
||||
CHUNKID_DEFINE(RSCM_CHUNK)
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
/*!
|
||||
* \brief viewMode Default screenmode
|
||||
*
|
||||
* Since HAM modes only can be identified by their ID (or DIPF) you have to make sure,
|
||||
* that rcsm_ViewMode is OR'ed with HAM_KEY for these (same for EHB and EXTRAHALFBRITE_KEY).
|
||||
*
|
||||
* Specific RTG ViewModes will lose their meaning, as soon as graphics are transferred between
|
||||
* different systems, which is why the two LocalVM entries are considered obsolete.
|
||||
*
|
||||
* Always set the obsolete entries to 0xFFFFFFFF and avoid interpreting them.
|
||||
* \return default screenmode
|
||||
*/
|
||||
quint32 viewMode() const;
|
||||
|
||||
/*!
|
||||
* \brief localVM0
|
||||
* \obsolete obsolete local RTG
|
||||
*/
|
||||
quint32 localVM0() const;
|
||||
|
||||
/*!
|
||||
* \brief localVM1
|
||||
* \obsolete obsolete local RTG
|
||||
*/
|
||||
quint32 localVM1() const;
|
||||
|
||||
protected:
|
||||
virtual bool innerReadStructure(QIODevice *d) override;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The RBODChunk class
|
||||
*/
|
||||
class RBODChunk : public IFFChunk
|
||||
{
|
||||
public:
|
||||
virtual ~RBODChunk() override;
|
||||
RBODChunk();
|
||||
RBODChunk(const RBODChunk&) = default;
|
||||
RBODChunk& operator=(const RBODChunk&) = default;
|
||||
|
||||
CHUNKID_DEFINE(RBOD_CHUNK)
|
||||
|
||||
virtual bool isValid() const override;
|
||||
|
||||
QByteArray strideRead(QIODevice *d,
|
||||
qint32 y,
|
||||
const RGHDChunk *header,
|
||||
const RSCMChunk *rcsm = nullptr,
|
||||
const RCOLChunk *rcol = nullptr) const;
|
||||
|
||||
bool resetStrideRead(QIODevice *d) const;
|
||||
|
||||
private:
|
||||
QByteArray deinterleave(const QByteArray &planes, qint32 y, const RGHDChunk *header, const RSCMChunk *rcsm = nullptr, const RCOLChunk *rcol = nullptr) const;
|
||||
|
||||
quint32 strideSize(const RGHDChunk *header) const;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* *** UNDOCUMENTED CHUNKS ***
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#ifndef DDS_DISABLE_STRIDE_ALIGNMENT
|
||||
// Disable the stride aligment based on DDS pitch: it is known that some writers do not set it correctly
|
||||
// Disable the stride alignment based on DDS pitch: it is known that some writers do not set it correctly
|
||||
// #define DDS_DISABLE_STRIDE_ALIGNMENT
|
||||
#endif
|
||||
|
||||
@@ -2120,10 +2120,8 @@ bool writeL8(const QImage &outImage, QDataStream &s)
|
||||
}
|
||||
|
||||
ScanLineConverter slc(QImage::Format_Grayscale8);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
if(outImage.colorSpace().isValid())
|
||||
slc.setTargetColorSpace(QColorSpace(QPointF(0.3127, 0.3291), QColorSpace::TransferFunction::SRgb));
|
||||
#endif
|
||||
|
||||
for (int y = 0, h = outImage.height(); y < h; ++y) {
|
||||
const quint8 *scanLine = reinterpret_cast<const quint8*>(slc.convertedScanLine(outImage, y));
|
||||
|
||||
@@ -179,7 +179,7 @@ bool EPSHandler::read(QImage *image)
|
||||
|
||||
const QString gsExec = QStandardPaths::findExecutable(QStringLiteral("gs"));
|
||||
if (gsExec.isEmpty()) {
|
||||
qCWarning(EPSPLUGIN) << "Couldn't find gs exectuable (from GhostScript) in PATH.";
|
||||
qCWarning(EPSPLUGIN) << "Couldn't find gs executable (from GhostScript) in PATH.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||