mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Allow fewer tRNS entries than PLTE colors (#1284)
This commit is contained in:
@@ -16,7 +16,7 @@ struct Palette;
|
||||
namespace sorting {
|
||||
|
||||
void indexed(std::vector<Palette> &palettes, int palSize, png_color const *palRGB,
|
||||
png_byte *palAlpha);
|
||||
int palAlphaSize, png_byte *palAlpha);
|
||||
void grayscale(std::vector<Palette> &palettes,
|
||||
std::array<std::optional<Rgba>, 0x8001> const &colors);
|
||||
void rgb(std::vector<Palette> &palettes);
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
namespace sorting {
|
||||
|
||||
void indexed(std::vector<Palette> &palettes, int palSize, png_color const *palRGB,
|
||||
png_byte *palAlpha) {
|
||||
int palAlphaSize, png_byte *palAlpha) {
|
||||
options.verbosePrint(Options::VERB_LOG_ACT, "Sorting palettes using embedded palette...\n");
|
||||
|
||||
auto pngToRgb = [&palRGB, &palAlpha](int index) {
|
||||
auto pngToRgb = [&palRGB, &palAlphaSize, &palAlpha](int index) {
|
||||
auto const &c = palRGB[index];
|
||||
return Rgba(c.red, c.green, c.blue, palAlpha ? palAlpha[index] : 0xFF);
|
||||
return Rgba(c.red, c.green, c.blue, palAlpha && index < palAlphaSize ? palAlpha[index] : 0xFF);
|
||||
};
|
||||
|
||||
for (Palette &pal : palettes) {
|
||||
|
||||
@@ -83,6 +83,7 @@ class Png {
|
||||
int colorType;
|
||||
int nbColors;
|
||||
png_colorp embeddedPal = nullptr;
|
||||
int nbTransparentEntries;
|
||||
png_bytep transparencyPal = nullptr;
|
||||
|
||||
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
||||
@@ -116,8 +117,8 @@ public:
|
||||
|
||||
int getColorType() const { return colorType; }
|
||||
|
||||
std::tuple<int, png_const_colorp, png_bytep> getEmbeddedPal() const {
|
||||
return {nbColors, embeddedPal, transparencyPal};
|
||||
std::tuple<int, png_const_colorp, int, png_bytep> getEmbeddedPal() const {
|
||||
return {nbColors, embeddedPal, nbTransparentEntries, transparencyPal};
|
||||
}
|
||||
|
||||
uint32_t getWidth() const { return width; }
|
||||
@@ -257,9 +258,8 @@ public:
|
||||
height, bitDepth, colorTypeName(), interlaceTypeName());
|
||||
|
||||
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
||||
int nbTransparentEntries;
|
||||
if (png_get_tRNS(png, info, &transparencyPal, &nbTransparentEntries, nullptr)) {
|
||||
assert(nbTransparentEntries == nbColors);
|
||||
assert(nbTransparentEntries <= nbColors);
|
||||
}
|
||||
|
||||
options.verbosePrint(Options::VERB_INTERM, "Embedded palette has %d colors: [",
|
||||
@@ -268,7 +268,8 @@ public:
|
||||
auto const &color = embeddedPal[i];
|
||||
options.verbosePrint(
|
||||
Options::VERB_INTERM, "#%02x%02x%02x%02x%s", color.red, color.green, color.blue,
|
||||
transparencyPal ? transparencyPal[i] : 0xFF, i != nbColors - 1 ? ", " : "]\n");
|
||||
transparencyPal && i < nbTransparentEntries ? transparencyPal[i] : 0xFF,
|
||||
i != nbColors - 1 ? ", " : "]\n");
|
||||
}
|
||||
} else {
|
||||
options.verbosePrint(Options::VERB_INTERM, "No embedded palette\n");
|
||||
@@ -510,7 +511,7 @@ struct AttrmapEntry {
|
||||
|
||||
static void generatePalSpec(Png const &png) {
|
||||
// Generate a palette spec from the first few colors in the embedded palette
|
||||
auto [embPalSize, embPalRGB, embPalAlpha] = png.getEmbeddedPal();
|
||||
auto [embPalSize, embPalRGB, embPalAlphaSize, embPalAlpha] = png.getEmbeddedPal();
|
||||
if (embPalRGB == nullptr) {
|
||||
fatal("`-c embedded` was given, but the PNG does not have an embedded palette!");
|
||||
}
|
||||
@@ -523,7 +524,7 @@ static void generatePalSpec(Png const &png) {
|
||||
}
|
||||
for (int i = 0; i < embPalSize; ++i) {
|
||||
options.palSpec[0][i] = Rgba(embPalRGB[i].red, embPalRGB[i].green, embPalRGB[i].blue,
|
||||
embPalAlpha ? embPalAlpha[i] : 0xFF);
|
||||
embPalAlpha && i < embPalAlphaSize ? embPalAlpha[i] : 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,9 +560,9 @@ static std::tuple<DefaultInitVec<size_t>, std::vector<Palette>>
|
||||
}
|
||||
|
||||
// "Sort" colors in the generated palettes, see the man page for the flowchart
|
||||
auto [embPalSize, embPalRGB, embPalAlpha] = png.getEmbeddedPal();
|
||||
auto [embPalSize, embPalRGB, embPalAlphaSize, embPalAlpha] = png.getEmbeddedPal();
|
||||
if (embPalRGB != nullptr) {
|
||||
sorting::indexed(palettes, embPalSize, embPalRGB, embPalAlpha);
|
||||
sorting::indexed(palettes, embPalSize, embPalRGB, embPalAlphaSize, embPalAlpha);
|
||||
} else if (png.isSuitableForGrayscale()) {
|
||||
sorting::grayscale(palettes, png.getColors().raw());
|
||||
} else {
|
||||
|
||||
@@ -90,6 +90,7 @@ class Png {
|
||||
int colorType;
|
||||
int nbColors;
|
||||
png_colorp embeddedPal = nullptr;
|
||||
int nbTransparentEntries;
|
||||
png_bytep transparencyPal = nullptr;
|
||||
|
||||
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
||||
@@ -186,9 +187,8 @@ public:
|
||||
pixels.resize(static_cast<size_t>(width) * static_cast<size_t>(height));
|
||||
|
||||
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
||||
int nbTransparentEntries;
|
||||
if (png_get_tRNS(png, info, &transparencyPal, &nbTransparentEntries, nullptr)) {
|
||||
assert(nbTransparentEntries == nbColors);
|
||||
assert(nbTransparentEntries <= nbColors);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
0
test/gfx/trns_lt_plte.err
Normal file
0
test/gfx/trns_lt_plte.err
Normal file
1
test/gfx/trns_lt_plte.flags
Normal file
1
test/gfx/trns_lt_plte.flags
Normal file
@@ -0,0 +1 @@
|
||||
-Z
|
||||
BIN
test/gfx/trns_lt_plte.png
Normal file
BIN
test/gfx/trns_lt_plte.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 223 B |
Reference in New Issue
Block a user