Compare commits
148 Commits
v6.5.0-rc1
...
master
Author | SHA1 | Date | |
---|---|---|---|
0a9f9fe106 | |||
21b3b890ec | |||
aef4bd7e1c | |||
ea1983a7d1 | |||
775b53f1f6 | |||
02cf1502c0 | |||
f6c718a789 | |||
4f2f2425d3 | |||
e6357c22f7 | |||
094177a01c | |||
7420f47c17 | |||
888bca7387 | |||
e3aefd2aa1 | |||
aa8134ee0d | |||
9f09473aa0 | |||
62eb1d28cb | |||
15bece40ec | |||
1b3d2afbe3 | |||
850068c1dc | |||
6bf38ea638 | |||
2adca7c0ca | |||
dd69fdaea9 | |||
ae62ea3dfc | |||
9c47845f15 | |||
7c7fa73020 | |||
92e4271e84 | |||
6f588c6fd3 | |||
a182478e2c | |||
4026f41890 | |||
bef2b9168f | |||
473f5d9847 | |||
9bee29cc01 | |||
cdf3be3af1 | |||
752b18a42c | |||
97a1ea181c | |||
64a43fb04f | |||
6821c29819 | |||
e4d95c03fa | |||
afa8ed1a5d | |||
245c835d92 | |||
b2663d2651 | |||
35ab37c628 | |||
b28baa4a1e | |||
5d2540c135 | |||
25cc8bc262 | |||
7742537f8c | |||
d3386bbf50 | |||
e77986c7e0 | |||
c0261f4926 | |||
e5cf9caac5 | |||
90d4256f3d | |||
bb1c6aab9e | |||
74a734efed | |||
e9fa4b6610 | |||
36a6ef7d78 | |||
9fd6896cec | |||
9b14e752db | |||
90a2e3b412 | |||
b28cf4c352 | |||
b536ec4a5e | |||
7d7b295ac2 | |||
397957a976 | |||
18a729f7a1 | |||
7a74b50d64 | |||
0a06a07fa4 | |||
e89408b426 | |||
8a05711e99 | |||
d6534f0e68 | |||
f608441b03 | |||
49060026b7 | |||
424e7a75de | |||
be534ea06e | |||
baaf1093a1 | |||
e83458a5d8 | |||
873ec1bb5f | |||
287a447095 | |||
ebb9c1ec18 | |||
ac3591c7ea | |||
a89367dde6 | |||
65a587afad | |||
5f92bcbf26 | |||
ae00c110f2 | |||
f39ca9dc9b | |||
f296c38daf | |||
bda8487147 | |||
bb10c4bd5c | |||
1982557a55 | |||
c97ee00f5e | |||
e6a0f8758b | |||
5c0c7e4fd7 | |||
40c2aae0cd | |||
f49704b2df | |||
43f3fd05f7 | |||
a7cf1a87f9 | |||
fe28130cb3 | |||
c0d5b8854b | |||
0b2c6d725d | |||
894524f7e4 | |||
348ddce987 | |||
1cb294545f | |||
b649cca304 | |||
adc5c7ae9a | |||
a6f7482957 | |||
d91c7dd912 | |||
86865223d2 | |||
ecbcf3b7f4 | |||
87eff569a4 | |||
a531978e2a | |||
ceb1c46fea | |||
6558b3255a | |||
374961dab4 | |||
b5d8b6638e | |||
92a1752c1f | |||
9f05ecb523 | |||
28c4ceeba9 | |||
f029a4a8ed | |||
56f229a2f1 | |||
72d4c41415 | |||
4923e2ecaa | |||
b645c9c258 | |||
8265b3602b | |||
dbd439bd98 | |||
a664baa9f9 | |||
c38a1a0248 | |||
2ea724c241 | |||
ecfbff8197 | |||
4dedd88c08 | |||
d233e80dbb | |||
799ac37660 | |||
0378bd67e1 | |||
7d696a81d2 | |||
b5d5abe0ea | |||
3f4690d1e9 | |||
ac1006cc66 | |||
97120b2537 | |||
fee0165bef | |||
ae641f7e94 | |||
46f7b90ce6 | |||
f7c8eaa140 | |||
36bfee8ae3 | |||
e2aaf89ec5 | |||
989a5c70d6 | |||
8588c053b6 | |||
145dedf360 | |||
2405a09e36 | |||
d02dcb064b | |||
0590c6b49d | |||
eb46f0f421 |
2
.gitattributes
vendored
@ -11,3 +11,5 @@ autotests/read/hdr/fake_earth.hdr binary
|
|||||||
autotests/read/hdr/rgb.hdr binary
|
autotests/read/hdr/rgb.hdr binary
|
||||||
autotests/read/hdr/rgb-landscape.hdr binary
|
autotests/read/hdr/rgb-landscape.hdr binary
|
||||||
autotests/read/hdr/rgb-portrait.hdr binary
|
autotests/read/hdr/rgb-portrait.hdr binary
|
||||||
|
autotests/read/pfm/testcard_gray_half.phm binary
|
||||||
|
autotests/read/pfm/testcard_rgb_half.phm binary
|
||||||
|
@ -5,6 +5,18 @@ include:
|
|||||||
- project: sysadmin/ci-utilities
|
- project: sysadmin/ci-utilities
|
||||||
file:
|
file:
|
||||||
- /gitlab-templates/linux-qt6.yml
|
- /gitlab-templates/linux-qt6.yml
|
||||||
|
- /gitlab-templates/linux-qt6-next.yml
|
||||||
|
- /gitlab-templates/alpine-qt6.yml
|
||||||
- /gitlab-templates/android-qt6.yml
|
- /gitlab-templates/android-qt6.yml
|
||||||
- /gitlab-templates/freebsd-qt6.yml
|
- /gitlab-templates/freebsd-qt6.yml
|
||||||
- /gitlab-templates/windows-qt6.yml
|
- /gitlab-templates/windows-qt6.yml
|
||||||
|
- /gitlab-templates/xml-lint.yml
|
||||||
|
- /gitlab-templates/yaml-lint.yml
|
||||||
|
|
||||||
|
image_json_validate:
|
||||||
|
stage: validate
|
||||||
|
image: invent-registry.kde.org/sysadmin/ci-images/suse-qt68:latest
|
||||||
|
tags:
|
||||||
|
- Linux
|
||||||
|
script:
|
||||||
|
- find src/imageformats/ -name *.json | xargs -I file bash -c "echo file && jq -e '(.Keys | type == \"array\") and (.MimeTypes | type == \"array\") and (.MimeTypes | length) == (.Keys | length)' file"
|
||||||
|
12
.kde-ci.yml
@ -1,9 +1,11 @@
|
|||||||
Dependencies:
|
Dependencies:
|
||||||
- 'on': ['Linux', 'FreeBSD', 'macOS', 'Windows', 'Android']
|
- 'on': ['Linux', 'FreeBSD', 'macOS', 'Windows', 'Android']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/extra-cmake-modules': '@same'
|
'frameworks/extra-cmake-modules': '@same'
|
||||||
'frameworks/karchive' : '@same'
|
'frameworks/karchive': '@same'
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
test-before-installing: True
|
test-before-installing: True
|
||||||
require-passing-tests-on: [ 'Linux', 'FreeBSD', 'Windows' ]
|
require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
|
||||||
|
cmake-options: "-DKIMAGEFORMATS_DDS=ON -DKIMAGEFORMATS_JXR=ON -DKIMAGEFORMATS_HEIF=ON"
|
||||||
|
per-test-timeout: 90
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
set(KF_VERSION "6.5.0") # handled by release scripts
|
set(KF_VERSION "6.17.0") # handled by release scripts
|
||||||
set(KF_DEP_VERSION "6.5.0") # handled by release scripts
|
set(KF_DEP_VERSION "6.16.0") # handled by release scripts
|
||||||
project(KImageFormats VERSION ${KF_VERSION})
|
project(KImageFormats VERSION ${KF_VERSION})
|
||||||
|
|
||||||
include(FeatureSummary)
|
include(FeatureSummary)
|
||||||
find_package(ECM 6.5.0 NO_MODULE)
|
find_package(ECM 6.16.0 NO_MODULE)
|
||||||
set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules")
|
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)
|
feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ include(ECMDeprecationSettings)
|
|||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
include(FindPkgConfig)
|
include(FindPkgConfig)
|
||||||
|
|
||||||
set(REQUIRED_QT_VERSION 6.5.0)
|
set(REQUIRED_QT_VERSION 6.7.0)
|
||||||
find_package(Qt6Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
|
find_package(Qt6Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
|
||||||
|
|
||||||
find_package(KF6Archive ${KF_DEP_VERSION})
|
find_package(KF6Archive ${KF_DEP_VERSION})
|
||||||
@ -62,6 +62,8 @@ set_package_properties(libavif PROPERTIES
|
|||||||
PURPOSE "Required for the QImage plugin for AVIF images"
|
PURPOSE "Required for the QImage plugin for AVIF images"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option(KIMAGEFORMATS_DDS "Enable plugin for DDS format" ON)
|
||||||
|
|
||||||
option(KIMAGEFORMATS_HEIF "Enable plugin for HEIF format" OFF)
|
option(KIMAGEFORMATS_HEIF "Enable plugin for HEIF format" OFF)
|
||||||
if(KIMAGEFORMATS_HEIF)
|
if(KIMAGEFORMATS_HEIF)
|
||||||
pkg_check_modules(LibHeif IMPORTED_TARGET libheif>=1.10.0)
|
pkg_check_modules(LibHeif IMPORTED_TARGET libheif>=1.10.0)
|
||||||
@ -70,17 +72,26 @@ add_feature_info(LibHeif LibHeif_FOUND "required for the QImage plugin for HEIF/
|
|||||||
|
|
||||||
option(KIMAGEFORMATS_JXL "Enable plugin for JPEG XL format" ON)
|
option(KIMAGEFORMATS_JXL "Enable plugin for JPEG XL format" ON)
|
||||||
if(KIMAGEFORMATS_JXL)
|
if(KIMAGEFORMATS_JXL)
|
||||||
pkg_check_modules(LibJXL IMPORTED_TARGET libjxl>=0.7.0)
|
pkg_check_modules(LibJXL IMPORTED_TARGET libjxl>=0.9.4)
|
||||||
pkg_check_modules(LibJXLThreads IMPORTED_TARGET libjxl_threads>=0.7.0)
|
pkg_check_modules(LibJXLThreads IMPORTED_TARGET libjxl_threads>=0.9.4)
|
||||||
|
pkg_check_modules(LibJXLCMS IMPORTED_TARGET libjxl_cms>=0.9.4)
|
||||||
endif()
|
endif()
|
||||||
add_feature_info(LibJXL LibJXL_FOUND "required for the QImage plugin for JPEG XL images")
|
add_feature_info(LibJXL LibJXL_FOUND "required for the QImage plugin for JPEG XL images")
|
||||||
|
|
||||||
|
option(KIMAGEFORMATS_JP2 "Enable plugin for JPEG 2000 format" ON)
|
||||||
|
if(KIMAGEFORMATS_JP2)
|
||||||
|
find_package(OpenJPEG CONFIG)
|
||||||
|
endif()
|
||||||
|
add_feature_info(OpenJPEG OpenJPEG_FOUND "required for the QImage plugin for JPEG 2000 images")
|
||||||
|
|
||||||
|
|
||||||
find_package(LibRaw 0.20.2)
|
find_package(LibRaw 0.20.2)
|
||||||
set_package_properties(LibRaw PROPERTIES
|
set_package_properties(LibRaw PROPERTIES
|
||||||
TYPE OPTIONAL
|
TYPE OPTIONAL
|
||||||
PURPOSE "Required for the QImage plugin for RAW images"
|
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)
|
option(KIMAGEFORMATS_JXR "Enable plugin for JPEG XR format" OFF)
|
||||||
if(KIMAGEFORMATS_JXR)
|
if(KIMAGEFORMATS_JXR)
|
||||||
find_package(LibJXR)
|
find_package(LibJXR)
|
||||||
@ -88,8 +99,8 @@ endif()
|
|||||||
add_feature_info(LibJXR LibJXR_FOUND "required for the QImage plugin for JPEG XR images")
|
add_feature_info(LibJXR LibJXR_FOUND "required for the QImage plugin for JPEG XR images")
|
||||||
|
|
||||||
ecm_set_disabled_deprecation_versions(
|
ecm_set_disabled_deprecation_versions(
|
||||||
QT 6.5
|
QT 6.9.0
|
||||||
KF 5.102
|
KF 6.13.0
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
@ -98,6 +109,28 @@ if (BUILD_TESTING)
|
|||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF6ImageFormats")
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/KF6ImageFormatsConfigVersion.cmake"
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
COMPATIBILITY AnyNewerVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_package_config_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/KF6ImageFormatsConfig.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/KF6ImageFormatsConfig.cmake"
|
||||||
|
INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/KF6ImageFormatsConfig.cmake"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/KF6ImageFormatsConfigVersion.cmake"
|
||||||
|
DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
|
||||||
|
COMPONENT Devel
|
||||||
|
)
|
||||||
|
|
||||||
include(ECMFeatureSummary)
|
include(ECMFeatureSummary)
|
||||||
ecm_feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
ecm_feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||||
|
|
||||||
|
5
KF6ImageFormatsConfig.cmake.in
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2025 Xaver Hugl <xaver.hugl@gmail.com>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
# empty, because this is plugins for Qt instead of a library to link against
|
360
README.md
@ -1,6 +1,7 @@
|
|||||||
# KImageFormats
|
# KImageFormats
|
||||||
|
|
||||||
Plugins to allow QImage to support extra file formats.
|
Plugins to allow [`QImage`](https://doc.qt.io/qt-6/qimage.html) to support
|
||||||
|
extra file formats.
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
@ -16,21 +17,25 @@ The following image formats have read-only support:
|
|||||||
- Animated Windows cursors (ani)
|
- Animated Windows cursors (ani)
|
||||||
- Camera RAW images (arw, cr2, cr3, dcs, dng, ...)
|
- Camera RAW images (arw, cr2, cr3, dcs, dng, ...)
|
||||||
- Gimp (xcf)
|
- Gimp (xcf)
|
||||||
|
- Interchange Format Files (IFF)
|
||||||
- Krita (kra)
|
- Krita (kra)
|
||||||
- OpenRaster (ora)
|
- OpenRaster (ora)
|
||||||
- Pixar raster (pxr)
|
- Pixar raster (pxr)
|
||||||
- Portable FloatMap (pfm)
|
- Portable FloatMap/HalfMap (pfm, phm)
|
||||||
- Photoshop documents (psd, psb, pdd, psdt)
|
- Photoshop documents (psd, psb, pdd, psdt)
|
||||||
- Radiance HDR (hdr)
|
- Radiance HDR (hdr)
|
||||||
|
- Scitex CT (sct)
|
||||||
- Sun Raster (im1, im8, im24, im32, ras, sun)
|
- Sun Raster (im1, im8, im24, im32, ras, sun)
|
||||||
|
|
||||||
The following image formats have read and write support:
|
The following image formats have read and write support:
|
||||||
|
|
||||||
- AV1 Image File Format (avif)
|
- AV1 Image File Format (avif)
|
||||||
|
- DirectDraw Surface (dds)
|
||||||
- Encapsulated PostScript (eps)
|
- Encapsulated PostScript (eps)
|
||||||
- High Efficiency Image File Format (heif). Can be enabled with the KIMAGEFORMATS_HEIF build option.
|
- High Efficiency Image File Format (heif)
|
||||||
|
- JPEG 2000 (jp2, j2k, jpf)
|
||||||
- JPEG XL (jxl)
|
- JPEG XL (jxl)
|
||||||
- JPEG XR (jxr). Can be enabled with the KIMAGEFORMATS_JXR build option.
|
- JPEG XR (jxr)
|
||||||
- OpenEXR (exr)
|
- OpenEXR (exr)
|
||||||
- Personal Computer Exchange (pcx)
|
- Personal Computer Exchange (pcx)
|
||||||
- Quite OK Image format (qoi)
|
- Quite OK Image format (qoi)
|
||||||
@ -40,16 +45,24 @@ The following image formats have read and write support:
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See the QImageIOPlugin documentation for information on how to write a
|
See the [`QImageIOPlugin`](https://doc.qt.io/qt-6/qimageioplugin.html)
|
||||||
new plugin.
|
documentation for information on how to write a new plugin.
|
||||||
|
|
||||||
The main difference between this framework and the qimageformats module
|
The main difference between this framework and the image formats of Qt is
|
||||||
of Qt is the license. As such, if you write an imageformat plugin and
|
the license. As such, if you write an image format plugin and you are
|
||||||
you are willing to sign the Qt Project contributor agreement, it may be
|
willing to sign the Qt Project contributor agreement, it may be better to
|
||||||
better to submit the plugin directly to the Qt Project.
|
submit the plugin directly to the Qt Project.
|
||||||
|
|
||||||
|
To be accepted, contributions must:
|
||||||
|
- Contain the test images needed to verify that the changes work correctly.
|
||||||
|
- Pass the tests successfully.
|
||||||
|
|
||||||
|
For more info about tests, see also [Autotests README](autotests/README.md).
|
||||||
|
|
||||||
## Duplicated Plugins
|
## Duplicated Plugins
|
||||||
|
|
||||||
|
### The TGA plugin
|
||||||
|
|
||||||
The TGA plugin supports more formats than Qt's own TGA plugin;
|
The TGA plugin supports more formats than Qt's own TGA plugin;
|
||||||
specifically, the one provided here supports indexed, greyscale and RLE
|
specifically, the one provided here supports indexed, greyscale and RLE
|
||||||
images (types 1-3 and 9-11), while Qt's plugin only supports type 2
|
images (types 1-3 and 9-11), while Qt's plugin only supports type 2
|
||||||
@ -60,6 +73,18 @@ licensing. If anyone were willing to write fresh code to improve Qt's
|
|||||||
TGA plugin, it would allow the TGA plugin in this framework to be
|
TGA plugin, it would allow the TGA plugin in this framework to be
|
||||||
removed.
|
removed.
|
||||||
|
|
||||||
|
### The DDS plugin
|
||||||
|
|
||||||
|
The DDS plugin is a fork from Qt 5.6 with bug fixes and improvements.
|
||||||
|
|
||||||
|
The plugin was forked because Qt Project no longer supports its DDS plugin.
|
||||||
|
|
||||||
|
### The JP2 plugin
|
||||||
|
|
||||||
|
The JP2 plugin is based on the popular and wide used OpenJPEG library.
|
||||||
|
|
||||||
|
The Qt project has a no longer supported JPEG 2000 plugin based on Jasper.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This framework is licensed under the
|
This framework is licensed under the
|
||||||
@ -68,3 +93,318 @@ This framework is licensed under the
|
|||||||
The CMake code in this framework is licensed under the
|
The CMake code in this framework is licensed under the
|
||||||
[BSD license](http://opensource.org/licenses/BSD-3-Clause).
|
[BSD license](http://opensource.org/licenses/BSD-3-Clause).
|
||||||
|
|
||||||
|
## Plugin status
|
||||||
|
|
||||||
|
The current implementation of a plugin may not be complete or may have
|
||||||
|
limitations of various kinds. Typically the limitations are on maximum size
|
||||||
|
and color depth.
|
||||||
|
|
||||||
|
The various plugins are also limited by the formats natively supported by Qt.
|
||||||
|
For example, native support for CMYK images is only available since Qt 6.8.
|
||||||
|
|
||||||
|
### HDR images
|
||||||
|
|
||||||
|
HDR images are supported via floating point image formats from DDS, EXR, HDR,
|
||||||
|
JXL, JXR, PFM and PSD plugins.
|
||||||
|
It is important to note that in the past these plugins stripped away HDR
|
||||||
|
information, returning SDR images.
|
||||||
|
|
||||||
|
HDR images return R, G and B values outside the range 0.0 - 1.0.
|
||||||
|
While Qt painters handles HDR data correctly, some older programs may display
|
||||||
|
strange artifacts if they do not use a tone mapping operator (or at least a
|
||||||
|
clamp). This is not a plugin issue.
|
||||||
|
|
||||||
|
### Metadata
|
||||||
|
|
||||||
|
Metadata support is available in formats that include it via
|
||||||
|
`QImage::setText()` and `QImage::text()`. To ensure consistent metadata
|
||||||
|
functionality, the following keys have been adopted.
|
||||||
|
|
||||||
|
About the image:
|
||||||
|
- `Altitude`: Floating-point number indicating the GPS altitude in meters
|
||||||
|
above sea level (e.g. 35.4).
|
||||||
|
- `Author`: Person who created the image.
|
||||||
|
- `Comment`: Additional image information in human-readable form, for
|
||||||
|
example a verbal description of the image.
|
||||||
|
- `Copyright`: Copyright notice of the person or organization that claims
|
||||||
|
the copyright to the image.
|
||||||
|
- `CreationDate`: When the image was created or captured. Date and time in
|
||||||
|
ISO 8601 format without milliseconds (e.g. 2024-03-23T15:30:43). This value
|
||||||
|
should be kept unchanged when present.
|
||||||
|
- `Description`: A string that describes the subject of the image.
|
||||||
|
- `Direction`: Floating-point number indicating the direction of the image
|
||||||
|
when it was captured in degrees (e.g. 123.3).
|
||||||
|
- `DocumentName`: The name of the document from which this image was
|
||||||
|
scanned.
|
||||||
|
- `HostComputer`: The computer and/or operating system in use at the time
|
||||||
|
of image creation.
|
||||||
|
- `Latitude`: Floating-point number indicating the latitude in degrees
|
||||||
|
north of the equator (e.g. 27.717).
|
||||||
|
- `Longitude`: Floating-point number indicating the longitude in degrees
|
||||||
|
east of Greenwich (e.g. 85.317).
|
||||||
|
- `ModificationDate`: Last modification date and time in ISO 8601 format
|
||||||
|
without milliseconds (e.g. 2024-03-23T15:30:43). This value should be
|
||||||
|
updated every time the image is saved.
|
||||||
|
- `Owner`: Name of the owner of the image.
|
||||||
|
- `Software`: Name and version number of the software package(s) used to
|
||||||
|
create the image.
|
||||||
|
- `Title`: The title of the image.
|
||||||
|
|
||||||
|
About the camera:
|
||||||
|
- `Manufacturer`: The manufacturer of the recording equipment.
|
||||||
|
- `Model`: The model name or model number of the recording equipment.
|
||||||
|
- `SerialNumber`: The serial number of the recording equipment.
|
||||||
|
|
||||||
|
About the lens:
|
||||||
|
- `LensManufacturer`: The manufacturer of the interchangeable lens that was
|
||||||
|
used.
|
||||||
|
- `LensModel`: The model name or model number of the lens that was used.
|
||||||
|
- `LensSerialNumber`: The serial number of the interchangeable lens that was
|
||||||
|
used.
|
||||||
|
|
||||||
|
Complex metadata (requires a parser):
|
||||||
|
- `XML:org.gimp.xml`: XML metadata generated by GIMP and present only in XCF
|
||||||
|
files.
|
||||||
|
- `XML:com.adobe.xmp`: [Extensible Metadata Platform (XMP)](https://developer.adobe.com/xmp/docs/)
|
||||||
|
is the metadata standard used by Adobe applications and is supported by all
|
||||||
|
common image formats. **Note that XMP metadata is read and written by
|
||||||
|
plugins as is.** Since it may contain information present in other metadata
|
||||||
|
(e.g. `Description`), it is the user's responsibility to ensure consistency
|
||||||
|
between all metadata and XMP metadata when writing an image.
|
||||||
|
|
||||||
|
Supported metadata may vary from one plugin to another. Please note that only
|
||||||
|
the most common metadata are supported and some plugins may return keys not
|
||||||
|
listed here.
|
||||||
|
|
||||||
|
### EXIF Metadata
|
||||||
|
|
||||||
|
[EXIF (Exchangeable Image File Format)](https://en.wikipedia.org/wiki/Exif)
|
||||||
|
metadata is a standard for embedding information within the image file itself.
|
||||||
|
|
||||||
|
Unlike the metadata described above, EXIF metadata is used internally by some
|
||||||
|
plugins to standardize image handling. For example, the JXL plugin uses them
|
||||||
|
to **set/get the image resolution and metadata**. They are also needed to
|
||||||
|
make the image properties appear in the file details of some file managers
|
||||||
|
(e.g. Dolphin).
|
||||||
|
|
||||||
|
When reading, EXIF metadata is converted into simple metadata (e.g.
|
||||||
|
`Description`) and inserted into the image if and only if it is not already
|
||||||
|
present.
|
||||||
|
|
||||||
|
On writing, the image metadata is converted to EXIF and saved appropriately.
|
||||||
|
Note that, if not present in the image to be saved, the following metadata
|
||||||
|
are created automatically:
|
||||||
|
|
||||||
|
- `Software`: Created using `applicationName` and `applicationVersion` methods
|
||||||
|
of [`QCoreApplication`](https://doc.qt.io/qt-6/qcoreapplication.html).
|
||||||
|
- `CreationDate`: Set to current time and date.
|
||||||
|
- `ModificationDate`: Set to current time and date.
|
||||||
|
|
||||||
|
### ICC profile support
|
||||||
|
|
||||||
|
ICC profile support is implemented in all formats that handle them using
|
||||||
|
[`QColorSpace`](https://doc.qt.io/qt-6/qcolorspace.html). When saving, some
|
||||||
|
plugins convert the image using color profiles according to format
|
||||||
|
specifications. In particular, HDR formats almost always convert to linear
|
||||||
|
RGB.
|
||||||
|
|
||||||
|
### Maximum image size
|
||||||
|
|
||||||
|
Where possible, plugins support large images. By convention, many of the
|
||||||
|
large image plugins are limited to a maximum of 300,000 x 300,000 pixels.
|
||||||
|
Anyway, all plugins are also limited by the
|
||||||
|
`QImageIOReader::allocationLimit()`. Below are the maximum sizes for each
|
||||||
|
plugin ('n/a' means no limit, i.e. the limit depends on the format encoding).
|
||||||
|
|
||||||
|
- ANI: n/a
|
||||||
|
- AVIF: 32,768 x 32,768 pixels, in any case no larger than 256 megapixels
|
||||||
|
- DDS: n/a
|
||||||
|
- EXR: 300,000 x 300,000 pixels
|
||||||
|
- EPS: n/a
|
||||||
|
- HDR: n/a (large image)
|
||||||
|
- HEIF: n/a
|
||||||
|
- IFF: 65,535 x 65,535 pixels
|
||||||
|
- JP2: 300,000 x 300,000 pixels, in any case no larger than 2 gigapixels
|
||||||
|
- JXL: 262,144 x 262,144 pixels, in any case no larger than 256 megapixels
|
||||||
|
- JXR: n/a, in any case no larger than 4 GB
|
||||||
|
- KRA: same size as Qt's PNG plugin
|
||||||
|
- ORA: same size as Qt's PNG plugin
|
||||||
|
- PCX: 65,535 x 65,535 pixels
|
||||||
|
- PFM: n/a (large image)
|
||||||
|
- PIC: 65,535 x 65,535 pixels
|
||||||
|
- PSD: 300,000 x 300,000 pixels
|
||||||
|
- PXR: 65,535 x 65,535 pixels
|
||||||
|
- QOI: 300,000 x 300,000 pixels
|
||||||
|
- RAS: n/a (large image)
|
||||||
|
- RAW: n/a (depends on the RAW format loaded)
|
||||||
|
- RGB: 65,535 x 65,535 pixels
|
||||||
|
- SCT: 300,000 x 300,000 pixels
|
||||||
|
- TGA: 65,535 x 65,535 pixels
|
||||||
|
- XCF: 300,000 x 300,000 pixels
|
||||||
|
|
||||||
|
### Sequential and random access devices
|
||||||
|
|
||||||
|
All plugins work fine on random access devices while only some work on
|
||||||
|
sequential access devices.
|
||||||
|
Some plugins, such as PSD, allow reading RGB images on sequential access
|
||||||
|
devices, but cannot do the same for Lab files.
|
||||||
|
|
||||||
|
**Important: some plugins use `QIODevice` transactions and/or
|
||||||
|
`QIODevice::ungetChar()`. Therefore, the device used to read the image must not
|
||||||
|
have any active transactions.**
|
||||||
|
|
||||||
|
### Memory usage
|
||||||
|
|
||||||
|
Qt has added many image formats over time. In older plugins, to support new
|
||||||
|
formats, `QImage` conversion functions have been used, causing memory
|
||||||
|
consumption proportional to the size of the image to be saved.
|
||||||
|
Normally this is not a source of problems because the affected plugins
|
||||||
|
are limited to maximum images of 2GiB or less.
|
||||||
|
|
||||||
|
On plugins for formats that support large images, progressive conversion has
|
||||||
|
been used or the maximum size of the image that can be saved has been limited.
|
||||||
|
|
||||||
|
### Non-RGB formats
|
||||||
|
|
||||||
|
PSD plugin loads CMYK, Lab and Multichannel images and converts them to RGB
|
||||||
|
without using the ICC profile.
|
||||||
|
|
||||||
|
JP2, JXL, JXR, PSD and SCT plugins natively support 4-channel CMYK images when
|
||||||
|
compiled with Qt 6.8+.
|
||||||
|
|
||||||
|
### The DDS plugin
|
||||||
|
|
||||||
|
**This plugin can be disabled by setting `KIMAGEFORMATS_DDS` to `OFF`
|
||||||
|
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
|
||||||
|
pitch: it is known that some writers do not set it correctly.
|
||||||
|
|
||||||
|
### The HEIF plugin
|
||||||
|
|
||||||
|
**This plugin is disabled by default. It can be enabled by settings
|
||||||
|
`KIMAGEFORMATS_HEIF` to `ON` in your cmake options.**
|
||||||
|
|
||||||
|
The plugin is disabled due to issues with the heif library on certain
|
||||||
|
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.
|
||||||
|
|
||||||
|
### The EXR plugin
|
||||||
|
|
||||||
|
The following defines can be defined in cmake to modify the behavior of the
|
||||||
|
plugin:
|
||||||
|
- `EXR_CONVERT_TO_SRGB`: the linear data is converted to sRGB on read to
|
||||||
|
accommodate programs that do not support color profiles.
|
||||||
|
- `EXR_DISABLE_XMP_ATTRIBUTE`: disables the stores XMP values in a non-standard
|
||||||
|
attribute named "xmp". Note that Gimp reads the "xmp" attribute and Darktable
|
||||||
|
writes it as well.
|
||||||
|
|
||||||
|
### The EPS plugin
|
||||||
|
|
||||||
|
The plugin uses `Ghostscript` to convert the raster image. When reading it
|
||||||
|
converts the EPS to PPM and uses the Qt PPM plugin to read the image.
|
||||||
|
When writing it uses [`QPrinter`](https://doc.qt.io/qt-6/qprinter.html) to
|
||||||
|
create a temporary PDF file which is then converted to EPS. Therefore, if
|
||||||
|
`Ghostscript` is not installed, the plugin will not work.
|
||||||
|
|
||||||
|
### The HDR plugin
|
||||||
|
|
||||||
|
The following defines can be defined in cmake to modify the behavior of the
|
||||||
|
plugin:
|
||||||
|
- `HDR_HALF_QUALITY`: on read, a 16-bit float image is returned instead of a
|
||||||
|
32-bit float one.
|
||||||
|
|
||||||
|
### The JP2 plugin
|
||||||
|
|
||||||
|
**This plugin can be disabled by setting `KIMAGEFORMATS_JP2` to `OFF`
|
||||||
|
in your cmake options.**
|
||||||
|
|
||||||
|
JP2 plugin has the following limitations due to the lack of support by OpenJPEG:
|
||||||
|
- Metadata are not supported.
|
||||||
|
- Image resolution is not supported.
|
||||||
|
- To write ICC profiles you need OpenJPEG V2.5.4 or higher
|
||||||
|
|
||||||
|
### The JXL plugin
|
||||||
|
|
||||||
|
**The current version of the plugin limits the image size to 256 megapixels
|
||||||
|
according to feature level 5 of the JXL stream encoding.**
|
||||||
|
|
||||||
|
The following defines can be defined in cmake to modify the behavior of the
|
||||||
|
plugin:
|
||||||
|
- `JXL_HDR_PRESERVATION_DISABLED`: disable floating point images (both read
|
||||||
|
and write) by converting them to UINT16 images. Any HDR data is lost. Note
|
||||||
|
that FP images are always disabled when compiling with libJXL less than v0.9.
|
||||||
|
- `JXL_DECODE_BOXES_DISABLED`: disable reading of metadata (e.g. XMP).
|
||||||
|
|
||||||
|
### The JXR plugin
|
||||||
|
|
||||||
|
**This plugin is disabled by default. It can be enabled by settings
|
||||||
|
`KIMAGEFORMATS_JXR` to `ON` in your cmake options.**
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
of the box. Unfortunately it doesn't seem to open (P)RGBA @32bpp files as
|
||||||
|
it only wants (P)BGRA32bpp files (a format not supported by Qt). Only for
|
||||||
|
this format an hack is activated to guarantee total compatibility of the
|
||||||
|
plugin with Windows.
|
||||||
|
- `JXR_ENABLE_ADVANCED_METADATA`: enable metadata support (e.g. XMP). Some
|
||||||
|
distributions use an incomplete JXR library that does not allow reading
|
||||||
|
metadata, causing compilation errors.
|
||||||
|
|
||||||
|
### The KRA plugin
|
||||||
|
|
||||||
|
The KRA format is a ZIP archive containing image data. In particular, the
|
||||||
|
rendered image in PNG format is saved in the root: the plugin reads this
|
||||||
|
image.
|
||||||
|
|
||||||
|
### The ORA plugin
|
||||||
|
|
||||||
|
The ORA format is a ZIP archive containing image data. In particular, the
|
||||||
|
rendered image in PNG format is saved in the root: the plugin reads this
|
||||||
|
image.
|
||||||
|
|
||||||
|
### The PSD plugin
|
||||||
|
|
||||||
|
PSD support has the following limitations:
|
||||||
|
- Only images saved by Photoshop using compatibility mode enabled (Photoshop
|
||||||
|
default) can be decoded.
|
||||||
|
- 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.
|
||||||
|
- Extra channels other than alpha are discarded.
|
||||||
|
|
||||||
|
The following defines can be defined in cmake to modify the behavior of the
|
||||||
|
plugin:
|
||||||
|
- `PSD_FAST_LAB_CONVERSION`: the LAB image is converted to linear sRGB instead
|
||||||
|
of sRGB which significantly increases performance.
|
||||||
|
- `PSD_NATIVE_CMYK_SUPPORT_DISABLED`: disable native support for CMYK images
|
||||||
|
when compiled with Qt 6.8+
|
||||||
|
|
||||||
|
### The RAW plugin
|
||||||
|
|
||||||
|
Loading RAW images always requires a conversion. To allow the user to
|
||||||
|
choose how to convert the image, it was chosen to use the quality parameter
|
||||||
|
to act on the converter. The quality parameter can be used with values from
|
||||||
|
0 to 100 (0 = fast, 100 = maximum quality) or by setting flags to
|
||||||
|
selectively change the conversion (see also [raw_p.h](./src/imageformats/raw_p.h)).
|
||||||
|
|
||||||
|
The default setting tries to balance quality and conversion speed.
|
||||||
|
|
||||||
|
### The XCF plugin
|
||||||
|
|
||||||
|
XCF support has the following limitations:
|
||||||
|
- XCF format up to [version 12](https://testing.developer.gimp.org/core/standards/xcf/#version-history)
|
||||||
|
(no support for GIMP 3).
|
||||||
|
- The returned image is always 8-bit.
|
||||||
|
- Cannot read zlib compressed files.
|
||||||
|
- The rendered image may be slightly different (colors/transparencies) than
|
||||||
|
in GIMP.
|
||||||
|
@ -19,9 +19,15 @@ macro(kimageformats_read_tests)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(_testname ${KIF_RT_UNPARSED_ARGUMENTS})
|
foreach(_testname ${KIF_RT_UNPARSED_ARGUMENTS})
|
||||||
|
string(REGEX MATCH "-skipoptional" _is_skip_optional "${_testname}")
|
||||||
|
unset(skip_optional_arg)
|
||||||
|
if (_is_skip_optional)
|
||||||
|
set(skip_optional_arg "--skip-optional-tests")
|
||||||
|
string(REGEX REPLACE "-skipoptional$" "" _testname "${_testname}")
|
||||||
|
endif()
|
||||||
add_test(
|
add_test(
|
||||||
NAME kimageformats-read-${_testname}
|
NAME kimageformats-read-${_testname}
|
||||||
COMMAND readtest ${_fuzzarg} ${_testname}
|
COMMAND readtest ${skip_optional_arg} ${_fuzzarg} ${_testname}
|
||||||
)
|
)
|
||||||
endforeach(_testname)
|
endforeach(_testname)
|
||||||
endmacro()
|
endmacro()
|
||||||
@ -43,6 +49,8 @@ macro(kimageformats_write_tests)
|
|||||||
foreach(_testname ${KIF_RT_UNPARSED_ARGUMENTS})
|
foreach(_testname ${KIF_RT_UNPARSED_ARGUMENTS})
|
||||||
string(REGEX MATCH "-lossless$" _is_lossless "${_testname}")
|
string(REGEX MATCH "-lossless$" _is_lossless "${_testname}")
|
||||||
string(REGEX MATCH "-nodatacheck" _is_no_data_check "${_testname}")
|
string(REGEX MATCH "-nodatacheck" _is_no_data_check "${_testname}")
|
||||||
|
string(REGEX MATCH "-skipoptional" _is_skip_optional "${_testname}")
|
||||||
|
unset(skip_optional_arg)
|
||||||
unset(lossless_arg)
|
unset(lossless_arg)
|
||||||
unset(no_data_check_arg)
|
unset(no_data_check_arg)
|
||||||
if (_is_lossless)
|
if (_is_lossless)
|
||||||
@ -53,9 +61,13 @@ macro(kimageformats_write_tests)
|
|||||||
set(no_data_check_arg "--no-data-check")
|
set(no_data_check_arg "--no-data-check")
|
||||||
string(REGEX REPLACE "-nodatacheck$" "" _testname "${_testname}")
|
string(REGEX REPLACE "-nodatacheck$" "" _testname "${_testname}")
|
||||||
endif()
|
endif()
|
||||||
|
if (_is_skip_optional)
|
||||||
|
set(skip_optional_arg "--skip-optional-tests")
|
||||||
|
string(REGEX REPLACE "-skipoptional$" "" _testname "${_testname}")
|
||||||
|
endif()
|
||||||
add_test(
|
add_test(
|
||||||
NAME kimageformats-write-${_testname}
|
NAME kimageformats-write-${_testname}
|
||||||
COMMAND writetest ${lossless_arg} ${no_data_check_arg} ${_fuzzarg} ${_testname}
|
COMMAND writetest ${lossless_arg} ${no_data_check_arg} ${skip_optional_arg} ${_fuzzarg} ${_testname}
|
||||||
)
|
)
|
||||||
endforeach(_testname)
|
endforeach(_testname)
|
||||||
endmacro()
|
endmacro()
|
||||||
@ -65,6 +77,7 @@ endmacro()
|
|||||||
# result against the data read from the corresponding png file
|
# result against the data read from the corresponding png file
|
||||||
kimageformats_read_tests(
|
kimageformats_read_tests(
|
||||||
hdr
|
hdr
|
||||||
|
iff
|
||||||
pcx
|
pcx
|
||||||
pfm
|
pfm
|
||||||
psd
|
psd
|
||||||
@ -72,9 +85,15 @@ kimageformats_read_tests(
|
|||||||
qoi
|
qoi
|
||||||
ras
|
ras
|
||||||
rgb
|
rgb
|
||||||
|
sct
|
||||||
tga
|
tga
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(KIMAGEFORMATS_DDS)
|
||||||
|
kimageformats_read_tests(dds)
|
||||||
|
kimageformats_write_tests(dds-nodatacheck-lossless)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (KF6Archive_FOUND)
|
if (KF6Archive_FOUND)
|
||||||
kimageformats_read_tests(
|
kimageformats_read_tests(
|
||||||
kra
|
kra
|
||||||
@ -104,16 +123,46 @@ if (LibHeif_FOUND)
|
|||||||
kimageformats_read_tests(FUZZ 1
|
kimageformats_read_tests(FUZZ 1
|
||||||
hej2
|
hej2
|
||||||
)
|
)
|
||||||
|
kimageformats_write_tests(FUZZ 1
|
||||||
|
hej2-nodatacheck-lossless
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (LibHeif_VERSION VERSION_GREATER_EQUAL "1.19.6")
|
||||||
|
kimageformats_read_tests(FUZZ 4
|
||||||
|
avci
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (OpenJPEG_FOUND)
|
||||||
|
kimageformats_read_tests(
|
||||||
|
jp2
|
||||||
|
)
|
||||||
|
# CMYK writing is incorrect in versions before 2.5.3
|
||||||
|
if ("${OPENJPEG_MAJOR_VERSION}.${OPENJPEG_MINOR_VERSION}.${OPENJPEG_BUILD_VERSION}" VERSION_GREATER_EQUAL "2.5.3")
|
||||||
|
kimageformats_write_tests(
|
||||||
|
jp2-nodatacheck-lossless
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LibJXL_FOUND AND LibJXLThreads_FOUND)
|
if (LibJXL_FOUND AND LibJXLThreads_FOUND)
|
||||||
kimageformats_read_tests(
|
if(LibJXL_VERSION VERSION_GREATER_EQUAL "0.11.0")
|
||||||
jxl
|
kimageformats_read_tests(
|
||||||
)
|
jxl
|
||||||
kimageformats_write_tests(
|
)
|
||||||
jxl-nodatacheck-lossless
|
kimageformats_write_tests(
|
||||||
)
|
jxl-nodatacheck-lossless
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
kimageformats_read_tests(
|
||||||
|
jxl-skipoptional
|
||||||
|
)
|
||||||
|
kimageformats_write_tests(
|
||||||
|
jxl-skipoptional-nodatacheck-lossless
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (LibJXR_FOUND)
|
if (LibJXR_FOUND)
|
||||||
@ -125,9 +174,7 @@ if (LibJXR_FOUND)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Allow some fuzziness when reading this formats, to allow for
|
kimageformats_read_tests(
|
||||||
# rounding errors (eg: in alpha blending).
|
|
||||||
kimageformats_read_tests(FUZZ 1
|
|
||||||
xcf
|
xcf
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -138,7 +185,7 @@ kimageformats_read_tests(FUZZ 1
|
|||||||
# You can append -lossless to the format to indicate that
|
# You can append -lossless to the format to indicate that
|
||||||
# reading back the image data will result in an identical image.
|
# reading back the image data will result in an identical image.
|
||||||
kimageformats_write_tests(
|
kimageformats_write_tests(
|
||||||
pcx-lossless
|
pcx-nodatacheck
|
||||||
pic-lossless
|
pic-lossless
|
||||||
qoi-lossless
|
qoi-lossless
|
||||||
rgb-lossless
|
rgb-lossless
|
||||||
@ -157,7 +204,7 @@ if (OpenEXR_FOUND)
|
|||||||
)
|
)
|
||||||
# Color space conversions from sRGB to linear on saving and
|
# Color space conversions from sRGB to linear on saving and
|
||||||
# from linear to sRGB on loading result in some rounding errors.
|
# from linear to sRGB on loading result in some rounding errors.
|
||||||
kimageformats_write_tests(FUZZ 5
|
kimageformats_write_tests(FUZZ 6
|
||||||
exr-nodatacheck-lossless
|
exr-nodatacheck-lossless
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
253
autotests/README.md
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
# Autotests
|
||||||
|
|
||||||
|
Automated testing for plugins to allow
|
||||||
|
[`QImage`](https://doc.qt.io/qt-6/qimage.html) to support
|
||||||
|
extra file formats.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The testing part is essential for the correct functioning of the plugins.
|
||||||
|
There are generic read/write tests and specific tests for the plugins that
|
||||||
|
require them.
|
||||||
|
|
||||||
|
## Read tests
|
||||||
|
|
||||||
|
The generic reading tests are contained in the `read` folder. Inside the
|
||||||
|
`read` folder, there are one or more folders for each plugin to be tested.
|
||||||
|
A plugin can support multiple image file types, and if you need different
|
||||||
|
parameters for each type, you need to create a folder for each type supported
|
||||||
|
by the plugin (see e.g. HEIF plugin). If all formats supported by the plugin
|
||||||
|
do not require different parameters, a single folder approach is simpler (see
|
||||||
|
e.g. PSD plugin).
|
||||||
|
|
||||||
|
The reading tests are mainly based on comparing the image read by the plugin
|
||||||
|
with a template in a known and working format. For this reason, the template
|
||||||
|
formats chosen are those distributed by the Qt project: PNG in the first
|
||||||
|
instance and TIFF for image formats not supported by PNG (e.g. CMYK images).
|
||||||
|
|
||||||
|
Some image options such as `QImageIOHandler::Size`,
|
||||||
|
`QImageIOHandler::ImageFormat` and `QImageIOHandler::ImageTransformation` are
|
||||||
|
also checked. If supported by the plugin, the resulting image is checked to
|
||||||
|
see if it is compatible with the option's specification.
|
||||||
|
|
||||||
|
Optionally, for each image, you can also create a JSON file to modify the test
|
||||||
|
behavior and/or verify data other than image pixels, such as metadata.
|
||||||
|
|
||||||
|
Finally, two tests are run for each test case:
|
||||||
|
- On a random access device: this test must not fail.
|
||||||
|
- On a sequential access device: a plugin may not support sequential operation.
|
||||||
|
In this case, the test is skipped. However, if an image is returned, the test
|
||||||
|
must succeed.
|
||||||
|
|
||||||
|
### The readtest command
|
||||||
|
|
||||||
|
To start a test, run the `readtest` command with the format to test as an
|
||||||
|
argument. The format is one of those supported by plugins and a folder with
|
||||||
|
the name of the format must be present inside the `read` folder.
|
||||||
|
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).
|
||||||
|
- `--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
|
||||||
|
in very different RGB values. Since the alpha is small visually there is no
|
||||||
|
difference (so it is not considered an error).
|
||||||
|
- `--skip-optional-tests`: Used to skip the optional test such as metadata
|
||||||
|
and resolution tests.
|
||||||
|
|
||||||
|
Note that some tests may fail if the correct options are not used. The correct
|
||||||
|
options for each test are defined in [CMakeLists.txt](CMakeLists.txt).
|
||||||
|
See also [Add a test to CMakeLists.txt](#add-a-test-to-cmakeliststxt).
|
||||||
|
|
||||||
|
### Test image nomenclature
|
||||||
|
|
||||||
|
Each test consists of the image to test, the verification image(s) (template)
|
||||||
|
and, optionally, the additional JSON file.
|
||||||
|
To be a test, the names of these files must be the same (except for
|
||||||
|
the extension). A test for a JXL image would be, for example, composed like
|
||||||
|
this:
|
||||||
|
- `testRGB.jxl`: The image to test.
|
||||||
|
- `testRGB.jxl.json`: The test behavior modifier (note that it must contain
|
||||||
|
the double extension).
|
||||||
|
- `testRGB.png`: How the image should look (template). The template name
|
||||||
|
can be different if specified in the JSON file.
|
||||||
|
|
||||||
|
Although there is no precise rule for the name of a test, it is good to have
|
||||||
|
a name that is explanatory.
|
||||||
|
|
||||||
|
### JSON behavior file
|
||||||
|
|
||||||
|
The behavior file was initially introduced to solve compatibility issues
|
||||||
|
between different versions of Qt supported by the framework. It was later
|
||||||
|
extended to also check image metadata.
|
||||||
|
|
||||||
|
The JSON file consists of an array of JSON objects. The objects in the array
|
||||||
|
are iterated sequentially and the first object that matches the requirements
|
||||||
|
is used for testing (successes are ignored).
|
||||||
|
|
||||||
|
Supported values for JSON objects:
|
||||||
|
- `comment`: Type string. A string shown by the test when a condition occurs.
|
||||||
|
- `description`: Type string. A description of the object. Not used by the
|
||||||
|
test.
|
||||||
|
- `disableAutoTransform`: Type boolean. By default, tests are run with
|
||||||
|
autotransform enabled (i.e. rotation is applied if the plugin supports it).
|
||||||
|
Set to `true` to disable autotransform.
|
||||||
|
- `filename`: Type string. Name of the template file to use. E.g.
|
||||||
|
"testRGB_Qt_6_2.png".
|
||||||
|
- `fuzziness`: Type integer. Set the fuzziness only if not already set on the
|
||||||
|
command line. The value set on the command line wins over the one in the JSON
|
||||||
|
file.
|
||||||
|
- `maxQtVersion`: Type string. Maximum Qt version this object is compatible
|
||||||
|
with (if not set means all). E.g. "6.2.99".
|
||||||
|
- `metadata`: Type Array. An array of key/value objects (string type)
|
||||||
|
containing the image metadata as returned by `QImage::text`.
|
||||||
|
- `minQtVersion`: Type string. Minimum Qt version this object is compatible
|
||||||
|
with (if not set means all). E.g. "6.2.0".
|
||||||
|
- `perceptiveFuzziness` Type boolean. Set the perceptive fuzziness only if not
|
||||||
|
already set on the command line. The value set on the command line wins over
|
||||||
|
the one in the JSON file.
|
||||||
|
- `resolution`: Type object. An object with the `dotsPerMeterX` and
|
||||||
|
`dotsPerMeterY` (integer) values of the image.
|
||||||
|
- `seeAlso`: Type string. More info about the object. Normally used to point
|
||||||
|
to bug reports. Not used by the test.
|
||||||
|
- `unsupportedFormat`: Type `boolean`. When true, the test is skipped.
|
||||||
|
|
||||||
|
Some examples:
|
||||||
|
- Example 1: [Runs only on Qt without alpha bug on float formats](read/jxl/testcard_rgba_fp16.jxl.json)
|
||||||
|
- Example 2: [Rotation disabled](read/jxl/orientation6_notranfs.jxl.json)
|
||||||
|
- Example 3: [Metadata](read/psd/metadata.psd.json)
|
||||||
|
- Example 4: [Check Qt version, resolution and metadata](read/psd/mch-16bits.psd.json)
|
||||||
|
- Example 5: [Fuzziness setting](read/xcf/birthday16.xcf.json)
|
||||||
|
|
||||||
|
These are just a few examples. More examples can be found in the test folders.
|
||||||
|
|
||||||
|
## Write tests
|
||||||
|
|
||||||
|
The generic writing tests are contained in the `write/basic` and
|
||||||
|
`write/format` folders. Similar to the read tests, they verify the written
|
||||||
|
(and then reread) image with a template.
|
||||||
|
|
||||||
|
The write test is composed of several phases:
|
||||||
|
- Basic test: Uses the `write/basic` folder and checks the most common images
|
||||||
|
and, optionally, metadata and resolution via a JSON properties file.
|
||||||
|
- Format test: Uses the `write/format` folder and checks that all QImage image
|
||||||
|
formats are written correctly.
|
||||||
|
- Dimensional test: Uses the `write/format` folder and check images of
|
||||||
|
different sizes (odd numbers, prime numbers, etc.) to verify internal
|
||||||
|
alignments.
|
||||||
|
- Null device test: Verify that there are no crashes if the device is null.
|
||||||
|
|
||||||
|
### The writetest command
|
||||||
|
|
||||||
|
To start a test, run the `writetest` command with the format to test as an
|
||||||
|
argument. The format is one of those supported by plugins, a folder with
|
||||||
|
the name of the format must be present inside the `write/format` folder and
|
||||||
|
may need a template image in `write/basic`.
|
||||||
|
Depending on the format, you can specify the following additional options.
|
||||||
|
|
||||||
|
- `--help`: Displays help on commandline options.
|
||||||
|
- `--create-format-templates`: Create template images for all formats
|
||||||
|
supported by the QImage in `write/format`. Command to simplify the creation of
|
||||||
|
format test images when adding a new plugin or modifying an old one. This
|
||||||
|
command is not intended to be used from the CMakeLists file as it must be used
|
||||||
|
manually and the generated images must be verified one by one.
|
||||||
|
- `--fuzz <max>`: The fuzziness. Used to add some deviation in ARGB data
|
||||||
|
(nornally used on lossy codec).
|
||||||
|
- `--lossless`: Check that reading back the data gives the same image.
|
||||||
|
- `--no-data-check`: Don't check that write data is exactly the same.
|
||||||
|
- `--skip-optional-tests`: Skip optional data tests (metadata, resolution,
|
||||||
|
etc...).
|
||||||
|
|
||||||
|
Note that some tests may fail if the correct options are not used. The correct
|
||||||
|
options for each test are defined in [CMakeLists.txt](CMakeLists.txt).
|
||||||
|
See also [Add a test to CMakeLists.txt](#add-a-test-to-cmakeliststxt).
|
||||||
|
|
||||||
|
### JSON properties file
|
||||||
|
|
||||||
|
The properties file must be located in `write/basic` and must have the name
|
||||||
|
of the file format (e.g. jxl.json). It is a JSON object composed of the
|
||||||
|
following values:
|
||||||
|
- `format`: Type string. The format tested.
|
||||||
|
- `metadata`: Type Array. An array of key/value objects (string type)
|
||||||
|
containing the image metadata as returned by `QImage::text`.
|
||||||
|
- `resolution`: Type object. An object with the `dotsPerMeterX` and `
|
||||||
|
dotsPerMeterY` (integer) values of the image.
|
||||||
|
|
||||||
|
[This is an example](write/basic/jxl.json) of property file.
|
||||||
|
|
||||||
|
|
||||||
|
## Custom tests
|
||||||
|
|
||||||
|
If the generic read/write tests do not meet the requirements of a plugin,
|
||||||
|
it is possible to write a custom test.
|
||||||
|
In general it makes sense to write a dedicated test for a format if and
|
||||||
|
only if you are testing unique features not present in other plugins.
|
||||||
|
|
||||||
|
### The PIC test
|
||||||
|
|
||||||
|
The PIC test is generated using Qt Test class. For more information
|
||||||
|
see [Qt Test](https://doc.qt.io/qt-6/qttest-index.html).
|
||||||
|
|
||||||
|
### The ANI test
|
||||||
|
|
||||||
|
The ANI test is generated using Qt Test class. For more information
|
||||||
|
see [Qt Test](https://doc.qt.io/qt-6/qttest-index.html).
|
||||||
|
|
||||||
|
|
||||||
|
## Add a test to CMakeLists.txt
|
||||||
|
|
||||||
|
To add a test to CMake use the `kimageformats_read_tests` and
|
||||||
|
`kimageformats_write_tests` functions. For example, to add the read
|
||||||
|
tests for the PSD you just write `kimageformats_read_tests(psd)`.
|
||||||
|
|
||||||
|
It is also possible to pass command line arguments to the test by
|
||||||
|
appropriately composing the string passed to the test functions.
|
||||||
|
For boolean parameters you need to add a string starting with '-'
|
||||||
|
after the image format. For example, to pass `--skip-optional-tests`
|
||||||
|
to the PSD plugin write `kimageformats_read_tests(psd-skipoptional)`.
|
||||||
|
|
||||||
|
To add a fuzziness of 4, you must first set it as follows:
|
||||||
|
`kimageformats_read_tests(FUZZ 4 psd-skipoptional)`.
|
||||||
|
|
||||||
|
The possible modifiers for `kimageformats_read_tests` are as follows:
|
||||||
|
- `-skipoptional`: Add the `--skip-optional-tests` command line parameter.
|
||||||
|
|
||||||
|
The possible modifiers for `kimageformats_write_tests` are as follows:
|
||||||
|
- `-lossless`: Add the `--lossless` command line parameter.
|
||||||
|
- `-nodatacheck`: Add the `--no-data-check` command line parameter.
|
||||||
|
- `-skipoptional`: Add the `--skip-optional-tests` command line parameter.
|
||||||
|
|
||||||
|
To set multiple parameters, you can enter multiple modifiers. For example:
|
||||||
|
```
|
||||||
|
kimageformats_write_tests(FUZZ 1
|
||||||
|
hej2-nodatacheck-lossless
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## OSS-Fuzz
|
||||||
|
|
||||||
|
Plugins are also tested with [OSS-Fuzz](https://google.github.io/oss-fuzz/)
|
||||||
|
project to identify possible security issues. When adding a new plugin it is
|
||||||
|
also necessary to add it to the test in the [kimageformats
|
||||||
|
project](https://github.com/google/oss-fuzz/tree/master/projects/kimageformats)
|
||||||
|
on OSS-Fuzz.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
List of tests not implemented or only partially implemented.
|
||||||
|
|
||||||
|
### Color Profiles Test
|
||||||
|
|
||||||
|
Many plugins support color profiles via [`QColorSpace`](https://doc.qt.io/qt-6/qcolorspace.html).
|
||||||
|
Checking for correct color management is increasingly necessary especially now
|
||||||
|
that monitors are HDR and other than RGB color spaces have been added to Qt.
|
||||||
|
|
||||||
|
Furthermore, lossy plugins often have different color management behaviors
|
||||||
|
depending on how the image is saved.
|
||||||
|
|
||||||
|
### Animations Test
|
||||||
|
|
||||||
|
Few plugins support animations. There are currently no plans for
|
||||||
|
implementation.
|
@ -4,34 +4,66 @@
|
|||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QRgb>
|
||||||
|
#include <QRgba64>
|
||||||
|
|
||||||
|
inline int iAbs(const int &v)
|
||||||
|
{
|
||||||
|
return v < 0 ? -v : v;
|
||||||
|
}
|
||||||
|
|
||||||
template<class Trait>
|
template<class Trait>
|
||||||
static bool fuzzyeq(const QImage &im1, const QImage &im2, uchar fuzziness)
|
static bool fuzzyeq(const QImage &im1, const QImage &im2, int fuzziness, bool perceptiveFuzzer)
|
||||||
{
|
{
|
||||||
Q_ASSERT(im1.format() == im2.format());
|
Q_ASSERT(im1.format() == im2.format());
|
||||||
Q_ASSERT(im1.depth() == 24 || im1.depth() == 32 || im1.depth() == 64);
|
Q_ASSERT(im1.depth() == 24 || im1.depth() == 32 || im1.depth() == 64);
|
||||||
|
|
||||||
|
const bool hasAlpha = im1.hasAlphaChannel();
|
||||||
const int height = im1.height();
|
const int height = im1.height();
|
||||||
const int width = im1.width();
|
const int width = im1.width();
|
||||||
for (int i = 0; i < height; ++i) {
|
for (int i = 0; i < height; ++i) {
|
||||||
const Trait *line1 = reinterpret_cast<const Trait *>(im1.scanLine(i));
|
const Trait *line1 = reinterpret_cast<const Trait *>(im1.scanLine(i));
|
||||||
const Trait *line2 = reinterpret_cast<const Trait *>(im2.scanLine(i));
|
const Trait *line2 = reinterpret_cast<const Trait *>(im2.scanLine(i));
|
||||||
for (int j = 0; j < width; ++j) {
|
for (int j = 0; j < width; ++j) {
|
||||||
if (line1[j] > line2[j]) {
|
auto &&px1 = line1[j];
|
||||||
if (line1[j] - line2[j] > fuzziness) {
|
auto &&px2 = line2[j];
|
||||||
return false;
|
auto fuzz = int(fuzziness);
|
||||||
}
|
|
||||||
} else {
|
// Calculate the deltas
|
||||||
if (line2[j] - line1[j] > fuzziness) {
|
auto dr = iAbs(int(qRed(px2)) - int(qRed(px1)));
|
||||||
return false;
|
auto dg = iAbs(int(qGreen(px2)) - int(qGreen(px1)));
|
||||||
}
|
auto db = iAbs(int(qBlue(px2)) - int(qBlue(px1)));
|
||||||
|
auto da = iAbs(int(qAlpha(px2)) - int(qAlpha(px1)));
|
||||||
|
|
||||||
|
// Always compare alpha even on images without it: some formats (e.g. RGBX64),
|
||||||
|
// want it set to a certain value (e.g. 65535).
|
||||||
|
if (da > fuzz)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Calculate the perceptive fuzziness.
|
||||||
|
if (hasAlpha && perceptiveFuzzer) {
|
||||||
|
auto alpha = std::max(4, int(qAlpha(px1)));
|
||||||
|
if (sizeof(Trait) == 4)
|
||||||
|
fuzz = std::min(fuzz * (255 / alpha), 255);
|
||||||
|
else
|
||||||
|
fuzz = std::min(fuzz * (65535 / alpha), 255 * 257);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare the deltas of R, G, B components.
|
||||||
|
if (dr > fuzz)
|
||||||
|
return false;
|
||||||
|
if (dg > fuzz)
|
||||||
|
return false;
|
||||||
|
if (db > fuzz)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow each byte to be different by up to 1, to allow for rounding errors
|
// allow each byte to be different by up to 1, to allow for rounding errors
|
||||||
static bool fuzzyeq(const QImage &im1, const QImage &im2, uchar fuzziness)
|
static bool fuzzyeq(const QImage &im1, const QImage &im2, uchar fuzziness, bool perceptiveFuzzer = false)
|
||||||
{
|
{
|
||||||
return (im1.depth() == 64) ? fuzzyeq<quint16>(im1, im2, fuzziness) : fuzzyeq<quint8>(im1, im2, fuzziness);
|
return (im1.depth() == 64) ? fuzzyeq<QRgba64>(im1, im2, int(fuzziness) * 257, perceptiveFuzzer) : fuzzyeq<QRgb>(im1, im2, int(fuzziness), perceptiveFuzzer);
|
||||||
}
|
}
|
||||||
|
BIN
autotests/read/avci/eco_kde_gray.avci
Normal file
BIN
autotests/read/avci/eco_kde_gray.png
Normal file
After Width: | Height: | Size: 250 KiB |
BIN
autotests/read/avif/metadata.avif
Normal file
After Width: | Height: | Size: 18 KiB |
59
autotests/read/avif/metadata.avif.json
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "metadata.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "ModificationDate",
|
||||||
|
"value" : "2025-02-19T08:27:22+01:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GIMP 3.0.0-RC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Altitude",
|
||||||
|
"value" : "34"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Author",
|
||||||
|
"value" : "KDE Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Copyright",
|
||||||
|
"value" : "@2025 KDE Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Description",
|
||||||
|
"value" : "TV broadcast test image."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Latitude",
|
||||||
|
"value" : "44.6478"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensManufacturer",
|
||||||
|
"value" : "KDE Glasses"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensModel",
|
||||||
|
"value" : "A1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Longitude",
|
||||||
|
"value" : "10.9254"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Manufacturer",
|
||||||
|
"value" : "KFramework"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Model",
|
||||||
|
"value" : "KImageFormats"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resolution" : {
|
||||||
|
"dotsPerMeterX" : 11811,
|
||||||
|
"dotsPerMeterY" : 5905
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
BIN
autotests/read/avif/metadata.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
autotests/read/dds/earth-cubemap.dds
Normal file
2
autotests/read/dds/earth-cubemap.license
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
SPDX-FileCopyrightText: Copyright (c) 2006 - 2010 The Open Toolkit library.
|
||||||
|
SPDX-License-Identifier: MIT
|
BIN
autotests/read/dds/earth-cubemap.png
Normal file
After Width: | Height: | Size: 956 KiB |
BIN
autotests/read/dds/gray8.dds
Normal file
BIN
autotests/read/dds/gray8.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
autotests/read/dds/indexed.dds
Normal file
BIN
autotests/read/dds/indexed.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
autotests/read/dds/r16.dds
Normal file
BIN
autotests/read/dds/r16.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
autotests/read/dds/r16dx10.dds
Normal file
BIN
autotests/read/dds/r16dx10.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
autotests/read/dds/r32.dds
Normal file
BIN
autotests/read/dds/r32.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
autotests/read/dds/r32dx10.dds
Normal file
BIN
autotests/read/dds/r32dx10.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
autotests/read/dds/rg16.dds
Normal file
BIN
autotests/read/dds/rg16.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
autotests/read/dds/rg16dx10.dds
Normal file
BIN
autotests/read/dds/rg16dx10.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
autotests/read/dds/rg32.dds
Normal file
BIN
autotests/read/dds/rg32.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
autotests/read/dds/rg32dx10.dds
Normal file
BIN
autotests/read/dds/rg32dx10.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
autotests/read/dds/rgba.dds
Normal file
BIN
autotests/read/dds/rgba.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
autotests/read/dds/rgba102.dds
Normal file
BIN
autotests/read/dds/rgba102.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgba16dx10.dds
Normal file
7
autotests/read/dds/rgba16dx10.dds.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "rgba16dx10.png",
|
||||||
|
"fuzziness" : 1,
|
||||||
|
"description" : "Minimum fuzziness value to pass the test on all architectures."
|
||||||
|
}
|
||||||
|
]
|
BIN
autotests/read/dds/rgba16dx10.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgba32dx10.dds
Normal file
BIN
autotests/read/dds/rgba32dx10.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgba4.dds
Normal file
BIN
autotests/read/dds/rgba4.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
autotests/read/dds/rgba5551.dds
Normal file
BIN
autotests/read/dds/rgba5551.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
autotests/read/dds/rgba_abgr.dds
Normal file
BIN
autotests/read/dds/rgba_abgr.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
autotests/read/dds/rgba_bc1.dds
Normal file
BIN
autotests/read/dds/rgba_bc1.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
autotests/read/dds/rgba_bc2.dds
Normal file
BIN
autotests/read/dds/rgba_bc2.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
autotests/read/dds/rgba_bc3.dds
Normal file
BIN
autotests/read/dds/rgba_bc3.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
autotests/read/dds/rgba_f16.dds
Normal file
7
autotests/read/dds/rgba_f16.dds.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "rgba_f16.png",
|
||||||
|
"fuzziness" : 1,
|
||||||
|
"description" : "Minimum fuzziness value to pass the test on all architectures."
|
||||||
|
}
|
||||||
|
]
|
BIN
autotests/read/dds/rgba_f16.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgba_f32.dds
Normal file
BIN
autotests/read/dds/rgba_f32.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgbpa16dx10.dds
Normal file
BIN
autotests/read/dds/rgbpa16dx10.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
autotests/read/dds/rgbpa32dx10.dds
Normal file
BIN
autotests/read/dds/rgbpa32dx10.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
9
autotests/read/exr/rgb-gimp.exr.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "rgb-gimp.png",
|
||||||
|
"resolution" : {
|
||||||
|
"dotsPerMeterX" : 3937,
|
||||||
|
"dotsPerMeterY" : 3937
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"fileName" : "orientation_all.png"
|
"fileName" : "orientation_all.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "GEGL"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
BIN
autotests/read/heif/metadata.heif
Normal file
59
autotests/read/heif/metadata.heif.json
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "metadata.png",
|
||||||
|
"metadata" : [
|
||||||
|
{
|
||||||
|
"key" : "ModificationDate",
|
||||||
|
"value" : "2025-02-26T16:52:06Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Software" ,
|
||||||
|
"value" : "LIFE Pro 2.18.10 (Linux)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Altitude",
|
||||||
|
"value" : "34"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Author",
|
||||||
|
"value" : "KDE Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Copyright",
|
||||||
|
"value" : "@2025 KDE Project"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Description",
|
||||||
|
"value" : "TV broadcast test image."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Latitude",
|
||||||
|
"value" : "44.6478"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensManufacturer",
|
||||||
|
"value" : "KDE Glasses"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensModel",
|
||||||
|
"value" : "A1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Longitude",
|
||||||
|
"value" : "10.9254"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Manufacturer",
|
||||||
|
"value" : "KFramework"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Model",
|
||||||
|
"value" : "KImageFormats"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resolution" : {
|
||||||
|
"dotsPerMeterX" : 11811,
|
||||||
|
"dotsPerMeterY" : 5905
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
BIN
autotests/read/heif/metadata.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
autotests/read/iff/blue_noise_rgba16.iff
Normal file
BIN
autotests/read/iff/blue_noise_rgba16.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
autotests/read/iff/blue_noise_rgba8.iff
Normal file
BIN
autotests/read/iff/blue_noise_rgba8.png
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
autotests/read/iff/flag_ham6.iff
Normal file
BIN
autotests/read/iff/flag_ham6.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
autotests/read/iff/meta_rgba.iff
Normal file
31
autotests/read/iff/meta_rgba.iff.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"fileName" : "metadata.png",
|
||||||
|
"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/meta_rgba.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
autotests/read/iff/ps_testcard_bitmap_amiga.iff
Normal file
BIN
autotests/read/iff/ps_testcard_bitmap_amiga.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
autotests/read/iff/ps_testcard_gray_amiga.iff
Normal file
BIN
autotests/read/iff/ps_testcard_gray_amiga.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
autotests/read/iff/ps_testcard_indexed_amiga.iff
Normal file
BIN
autotests/read/iff/ps_testcard_indexed_amiga.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
autotests/read/iff/ps_testcard_rgb16_maya.iff
Normal file
BIN
autotests/read/iff/ps_testcard_rgb16_maya.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
autotests/read/iff/ps_testcard_rgb_amiga.iff
Normal file
BIN
autotests/read/iff/ps_testcard_rgb_amiga.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
autotests/read/iff/ps_testcard_rgb_maya.iff
Normal file
BIN
autotests/read/iff/ps_testcard_rgb_maya.png
Normal file
After Width: | Height: | Size: 7.9 KiB |