Only sort generated palette colors by PLTE order for indexed PNG images

Non-indexed images can still have a PLTE chunk. We should use
`sortRgb` instead of `sortIndexed` for them, since their pixels' colors
may not all be present in the PLTE chunk and would be unsortable.
This commit is contained in:
Rangi
2026-09-13 18:53:31 -04:00
parent 49b3f566b1
commit f8a1da71c1
6 changed files with 11 additions and 8 deletions
+1
View File
@@ -14,6 +14,7 @@ struct Png {
uint32_t height = 0;
std::vector<Rgba> pixels{};
std::vector<Rgba> palette{};
bool isIndexed = false;
Png() {}
Png(char const *filename, std::streambuf &file);
+1 -7
View File
@@ -33,13 +33,7 @@ void sortIndexed(std::vector<Palette> &palettes, std::vector<Rgba> const &embPal
return true;
}
}
// A PNG image using PNG_COLOR_TYPE_RGB (2) or PNG_COLOR_TYPE_RGBA (6) can still
// contain a PLTE chunk. From the PNG spec: "If present, it provides a suggested set of
// from 1 to 256 colors to which the truecolor image can be quantized if the viewer
// cannot display truecolor directly." This means that an input image may have pixels
// with colors that are not in the PLTE chunk, so iterating through `embPal` may finish
// without returning. In that case, we compare `lhs` and `rhs` directly.
return lhs < rhs;
unreachable_(); // LCOV_EXCL_LINE
});
}
}
+1
View File
@@ -177,6 +177,7 @@ Png::Png(char const *filename, std::streambuf &file) {
break;
case PNG_COLOR_TYPE_PALETTE:
png_set_palette_to_rgb(png);
isIndexed = true; // This enables sorting generated palette colors by the PLTE chunk
break;
}
+8 -1
View File
@@ -390,7 +390,14 @@ static std::pair<std::vector<size_t>, std::vector<Palette>>
// "Sort" colors in the generated palettes, see the man page for the flowchart
if (options.palSpecType == Options::DMG) {
sortGrayscale(palettes, image.colors.raw());
} else if (!image.png.palette.empty()) {
} else if (image.png.isIndexed) {
// A PNG image using PNG_COLOR_TYPE_RGB (2) or PNG_COLOR_TYPE_RGBA (6) can still
// contain a PLTE chunk. From the PNG spec: "If present, it provides a suggested set of
// from 1 to 256 colors to which the truecolor image can be quantized if the viewer
// cannot display truecolor directly." We only sort palette colors by the PLTE chunk's
// color order if the image uses PNG_COLOR_TYPE_PALETTE (3), since that guarantees every
// color used will also be in the embedded palette.
assume(!image.png.palette.empty());
warning(
WARNING_EMBEDDED,
"Sorting palette colors by PNG's embedded PLTE chunk without '-c/--colors embedded'"
Binary file not shown.
Binary file not shown.