Images are allocated without being initialized, so a reader must write
every pixel of every line. The IFF reader did not always:
- Maya: nothing checked that the tiles cover the image: areas no tile
covers are now opaque black.
- readStandardImage(), readCDIImage(), readRGFXImage() and
readDEEPImage() copied min(bytesPerLine, decoded line) bytes, and some
decoded lines are shorter than the image line:
- a PBM with 8 bitplanes and a 64 color CMAP was taken for HAM and
allocated as RGB888, while PBM data are one index per pixel: HAM is
no longer applied to PBM images;
- other mismatches (e.g. HAM without CMAP, RGB8 with 32 bitplanes, CD-i
CLUT3 or RGB888, a truncated CD-i line) are now an error: a decoded
line that does not cover the image line is refused.
Added the read test pbm_64colors.iff, which fails without this change.
Images are allocated without being initialized, so a reader must write
every pixel of every line. The PCX reader did not always:
- readImage2() and readImage4v2() decoded width / 4 and width / 2 bytes,
so the last pixels of lines whose width is not a multiple of 4 (2 bits)
or 2 (4 bits) were not set. They now decode every pixel.
- With a BytesPerLine smaller than a line of pixels, readImage1(),
readImage8() and readImage24() left the end of each line unset: such
headers are now refused by isSupported(), which replaces the check
readImage4() had.
Added the read tests indexed2_w13.pcx and indexed4_w13.pcx, which fail
without this change.
1-bit images with a color map are loaded as Indexed8, but their lines
were copied packed: the first (width + 7) / 8 bytes (rounded up to an
even number) of each line held packed bits read as indexes, and the rest
of the line was not set, so it kept whatever the memory held (images are
allocated without being initialized). The bits are now unpacked to one
index per pixel.
Added the read test pal1bit.ras, which fails without this change.
Originally we uses getNormalZ() for the image, which treat the
image as a normal map. Visual Studio simply fill the blue channel
with 0 instead. Since DDS is for DirectX which is a MS stuff, align
to Visual Studio might be a good idea.
Also, red and green channel should be swapped.
DX10 DDS files using the BC (block compression) formats were reported as
unsupported: knownDXGIFormat() only mapped the floating point DXGI
formats, so getFormat() returned FormatUnknown and ensureScanned() failed,
e.g. for a BC7_UNORM_SRGB (dxgi 99) image.
The following changes have been made:
- Added a self-contained BC7 decoder following the "BC7 Format"
specification, supporting all 8 modes, for both the UNORM and the
UNORM_SRGB variants (loaded as ARGB32)
- Added BC4 support (single channel, loaded as Grayscale8)
- Added BC5 support, reusing the existing ATI2/3Dc normal map decoder
- Added DX10 mappings for BC1/BC2/BC3, which were previously handled only
as the legacy DXT1/DXT3/DXT5 fourCC formats
- Added read tests for BC4, BC5, BC7 and BC7_UNORM_SRGB, plus DX10
variants of the existing BC1/BC2/BC3 test images
BC6H (HDR) is not supported.
The test data was generated from the existing rgba.png test image, encoded
with bc7enc_rdo and decoded with bcdec.
BUG: 524495
read_orientation_helper() mapped the irot/imir properties to an EXIF
orientation with a list of conditions that misses several combinations,
e.g. a 90 degrees counterclockwise rotation followed by a mirroring,
which is how iPhone front-camera photos are stored. For those it still
returned true, so libheif was told to ignore the transformations while
Qt got no orientation either, and the image was shown sideways.
The orientation is now chosen by a switch on the rotation and, in each
case, on the mirroring, which is applied after the rotation as MIAF
requires. Other rotation values are left to libheif.
The new read tests cover the twelve rotation and mirroring combinations,
named like the AVIF ones. All of them display the same picture (colored
corners and an "F"): the stored pixels are that picture with the
transformations undone, written as uncompressed HEIF with libheif. Four
of them fail without this change.
- ORA/KRA: merged in a single plugin (KRA)
- ORA: removed standalone plugin
- KRA: use of logging category
- KRA: add metadata support by processing the embedded `documentinfo.xml`
- Improved signature lookup (see MR !17) and added test case
When 1st parsing ends with invalid EXIF payload error,
we try 2nd time again while ignoring the EXIF metadata.
Dropped support for legacy 0.x libavif versions,
libavif 1.0.0+ is now required for the AVIF support.
New option `KIMAGEFORMATS_HEIC_TEST` for testing images with
HEVC codec only.
Existing option `KIMAGEFORMATS_HEIF_TEST` is used for testing other
possible (mostly quite rare) codecs that might be used by HEIF
images - uncompressed, deflate, zlib, brotli, jpeg.
Highlights:
- Adds support for a new palette changer chunk. Some test cases attached to #38 .
- Fixes the reading of ILBMs with the mask (test case: [cyclone.iff](/uploads/d8734d2155fd0d21f7b003b37e0d1259/cyclone.iff)).
- Adds support for HAM5 encoding.
- Adds more test cases created using [HAM Converter](http://mrsebe.bplaced.net/blog/wordpress/).
- Adds support for Atari STE RAST chunk outside FORM one (test case: [fish.iff](/uploads/c461cf4b6a1423cec60fbce645d9fd07/fish.iff)).
NOTE: I contacted Sebastiano Vigna, the author of the PCHG chunk specifications, and he provided me with:
- Some images to test the code (but I can't include them in the test cases).
- Permission to use [his code](https://vigna.di.unimi.it/amiga/PCHGLib.zip) without restrictions: Huffman decompression was achieved by converting `FastDecomp.a` via AI.
Closes#38
Adds TGA 2.0 compliance:
- Support for Extension Area, Developer Area and Footer (metadata support)
- Support for 15-bit and 16-bit per pixel images (both RGB and Indexed)
- Full support for rotation on reading (we cannot use Qt transformations because only a subset is part of the TGA specification)
- When writing you can choose the supported version (subType)
- Improved writing speed (approximately 10 times) and removed whole image conversions (significant memory savings)
It pass the [TrueVision TGA 2.0 conformance suite](https://github.com/zigimg/test-suite/tree/master/fixtures/tga).
Test changes:
- Read test: added ability to skip a specific test on sequential devices (via JSON behavior file)
- Write test: added the ability to set the subType when writing (via JSON properties file)
Closes#37
Add the following features:
- RGB8 image data support (test case added)
- RGBN image data support ([Clouds.iff](/uploads/9db869350f74421bf1813fa7d4332f4f/Clouds.iff))
- CAT chunk support: you can have more than one image for file (test case added)
- Image transformation support via EXIF data
[RGBN/RGB8](https://wiki.amigaos.net/wiki/RGBN_and_RGB8_IFF_Image_Data) files are used in Impulse's Turbo Silver and Imagine.
Closes#34
Read-only support for most common Interchange Format Files (IFF). Supports IFF saved by Photoshop for the Amiga and Maya platform and HAM6 coded files.
Closes#29
- Full rotation support on load and save.
- Improve also Windows compatibility by converting RGB32 to BGR32 on saving
Images saved with orientation are displayed correctly by Windows Explorer (which natively supports JXR files):
{width=597 height=259}
Improved metadata support via EXIF metadata. Since JXR is based on a TIFF container, EXIF data is read directly from the file so it always works (even with versions of libjxr that don't have the metadata reading API).
It also solves the following issues:
- Incorrect date format on saved JXR files (was saved in ISO format instead of `yyyy:MM:dd HH:mm:ss`).
- Incorrect date type setting in EXIF data: the `DateTime` tag should be updated on every save (verified by GIMP and Photoshop). Our `CreationDate` metadata is the equivalent of the EXIF `DateTimeOriginal` tag.
Closes#22
Allow to load/save info about:
- GPS info (latitude, longitude, altitude)
- Various text info (title, description, author, copyright, etc...)
- Image resolution
The compatibility of the modifications has been tested with GIMP.
Added a new parameter to the read tests called `perceptive-fuzz`.
The parameter, when active, modifies the fuzziness value based on the alpha value of the pixel. The more transparent the pixel, the more the fuzziness value increases.
We have found that some image manipulation functions give different results depending on the architecture (we think it is differences in rounding). These differences can become problematic with small alpha values when there are several image conversions from normal alpha to premultiplied alpha (and vice versa).
In particular, the offending plugin is XCF.
The parameter should be set if and only if necessary. CMakeList has not been modified to allow it to be enabled on all format images (you can still try it from the command line). To use it, you need to set it in the JSON file of the image that has problems (after careful analysis).
More info about the issue on #18
This MR also fixes a bug in `fazzeq()`: it only compared 1/4 of the image.
Below is the same XCF image rendered on AMD64 and PowerPC:
- AMD64:

- PowerPC:

The image is visually the same because the differences are with very low alpha and therefore are negligible. The patch proposed with this MR is useful in these cases.