What happens
ProcessImage (IconHelper/IconHelper.cs:~164-229) writes the target colour as sRGB bytes (color.ToBytes()). But image.Metadata loaded from the source is never cleared, and AutoOrient() is never applied. ImageSharp carries the decoded metadata through Mutate, and the PNG encoder writes it back out (save at IconHelper.cs:~141).
Repro on a Release build of main (0857cce), processing with -c "#FF8800":
| Input |
Output |
20×20 PNG with an injected iCCP chunk (chunks IHDR iCCP pHYs IDAT IEND) |
Chunks IHDR iCCP pHYs IDAT IEND: the source colour profile is copied into the output |
The same PNG with gAMA = 100000 |
The output also carries gAMA 100000 |
| A 40×20 JPEG and a 40×20 PNG, each with a white bar in the left 10 columns and EXIF Orientation = 6 |
Trimmed in stored (unrotated) orientation. The output still carries an eXIf chunk with orientation 6, so EXIF-aware viewers show the bar horizontal, and texture loaders and UI frameworks that ignore EXIF show it vertical |
Why it matters
The tool exists to turn icons from mixed sources into one uniform set. With the source profile or gamma attached, colour-managed consumers render #FF8800 differently per file. A Display P3, Adobe RGB or phone-camera JPEG source, or any PNG with a gAMA chunk, is enough. The orientation also depends on the consumer. The README (lines ~260-261) describes the output as a clean 8-bit RGBA PNG with "no invisible colour data … carried into the file", but the colour metadata carried over contradicts that.
Suggested fix
- Call
image.Mutate(x => x.AutoOrient()) right after load, before bounds detection, so EXIF rotation is applied to the pixels.
- Before saving, clear
image.Metadata.ExifProfile, IccProfile, XmpProfile and IptcProfile, and reset the PNG gamma (GetPngMetadata().Gamma) so the file is plain sRGB.
Acceptance criteria
- The output PNG contains no
iCCP, gAMA, eXIf, iTXt/XMP or zTXt chunks, whatever the source carried.
- An EXIF-rotated input produces pixels in its displayed orientation.
- A gold-master or unit test covers a source with an ICC profile and a source with EXIF orientation.
What happens
ProcessImage(IconHelper/IconHelper.cs:~164-229) writes the target colour as sRGB bytes (color.ToBytes()). Butimage.Metadataloaded from the source is never cleared, andAutoOrient()is never applied. ImageSharp carries the decoded metadata throughMutate, and the PNG encoder writes it back out (save atIconHelper.cs:~141).Repro on a Release build of main (0857cce), processing with
-c "#FF8800":iCCPchunk (chunksIHDR iCCP pHYs IDAT IEND)IHDR iCCP pHYs IDAT IEND: the source colour profile is copied into the outputgAMA= 100000gAMA 100000eXIfchunk with orientation 6, so EXIF-aware viewers show the bar horizontal, and texture loaders and UI frameworks that ignore EXIF show it verticalWhy it matters
The tool exists to turn icons from mixed sources into one uniform set. With the source profile or gamma attached, colour-managed consumers render
#FF8800differently per file. A Display P3, Adobe RGB or phone-camera JPEG source, or any PNG with a gAMA chunk, is enough. The orientation also depends on the consumer. The README (lines ~260-261) describes the output as a clean 8-bit RGBA PNG with "no invisible colour data … carried into the file", but the colour metadata carried over contradicts that.Suggested fix
image.Mutate(x => x.AutoOrient())right after load, before bounds detection, so EXIF rotation is applied to the pixels.image.Metadata.ExifProfile,IccProfile,XmpProfileandIptcProfile, and reset the PNG gamma (GetPngMetadata().Gamma) so the file is plain sRGB.Acceptance criteria
iCCP,gAMA,eXIf,iTXt/XMP orzTXtchunks, whatever the source carried.