mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 02:32:06 +00:00
Allow fewer tRNS entries than PLTE colors (#1284)
This commit is contained in:
@@ -16,7 +16,7 @@ struct Palette;
|
|||||||
namespace sorting {
|
namespace sorting {
|
||||||
|
|
||||||
void indexed(std::vector<Palette> &palettes, int palSize, png_color const *palRGB,
|
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,
|
void grayscale(std::vector<Palette> &palettes,
|
||||||
std::array<std::optional<Rgba>, 0x8001> const &colors);
|
std::array<std::optional<Rgba>, 0x8001> const &colors);
|
||||||
void rgb(std::vector<Palette> &palettes);
|
void rgb(std::vector<Palette> &palettes);
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
namespace sorting {
|
namespace sorting {
|
||||||
|
|
||||||
void indexed(std::vector<Palette> &palettes, int palSize, png_color const *palRGB,
|
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");
|
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];
|
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) {
|
for (Palette &pal : palettes) {
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ class Png {
|
|||||||
int colorType;
|
int colorType;
|
||||||
int nbColors;
|
int nbColors;
|
||||||
png_colorp embeddedPal = nullptr;
|
png_colorp embeddedPal = nullptr;
|
||||||
|
int nbTransparentEntries;
|
||||||
png_bytep transparencyPal = nullptr;
|
png_bytep transparencyPal = nullptr;
|
||||||
|
|
||||||
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
||||||
@@ -116,8 +117,8 @@ public:
|
|||||||
|
|
||||||
int getColorType() const { return colorType; }
|
int getColorType() const { return colorType; }
|
||||||
|
|
||||||
std::tuple<int, png_const_colorp, png_bytep> getEmbeddedPal() const {
|
std::tuple<int, png_const_colorp, int, png_bytep> getEmbeddedPal() const {
|
||||||
return {nbColors, embeddedPal, transparencyPal};
|
return {nbColors, embeddedPal, nbTransparentEntries, transparencyPal};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getWidth() const { return width; }
|
uint32_t getWidth() const { return width; }
|
||||||
@@ -257,9 +258,8 @@ public:
|
|||||||
height, bitDepth, colorTypeName(), interlaceTypeName());
|
height, bitDepth, colorTypeName(), interlaceTypeName());
|
||||||
|
|
||||||
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
||||||
int nbTransparentEntries;
|
|
||||||
if (png_get_tRNS(png, info, &transparencyPal, &nbTransparentEntries, nullptr)) {
|
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: [",
|
options.verbosePrint(Options::VERB_INTERM, "Embedded palette has %d colors: [",
|
||||||
@@ -268,7 +268,8 @@ public:
|
|||||||
auto const &color = embeddedPal[i];
|
auto const &color = embeddedPal[i];
|
||||||
options.verbosePrint(
|
options.verbosePrint(
|
||||||
Options::VERB_INTERM, "#%02x%02x%02x%02x%s", color.red, color.green, color.blue,
|
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 {
|
} else {
|
||||||
options.verbosePrint(Options::VERB_INTERM, "No embedded palette\n");
|
options.verbosePrint(Options::VERB_INTERM, "No embedded palette\n");
|
||||||
@@ -510,7 +511,7 @@ struct AttrmapEntry {
|
|||||||
|
|
||||||
static void generatePalSpec(Png const &png) {
|
static void generatePalSpec(Png const &png) {
|
||||||
// Generate a palette spec from the first few colors in the embedded palette
|
// 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) {
|
if (embPalRGB == nullptr) {
|
||||||
fatal("`-c embedded` was given, but the PNG does not have an embedded palette!");
|
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) {
|
for (int i = 0; i < embPalSize; ++i) {
|
||||||
options.palSpec[0][i] = Rgba(embPalRGB[i].red, embPalRGB[i].green, embPalRGB[i].blue,
|
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
|
// "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) {
|
if (embPalRGB != nullptr) {
|
||||||
sorting::indexed(palettes, embPalSize, embPalRGB, embPalAlpha);
|
sorting::indexed(palettes, embPalSize, embPalRGB, embPalAlphaSize, embPalAlpha);
|
||||||
} else if (png.isSuitableForGrayscale()) {
|
} else if (png.isSuitableForGrayscale()) {
|
||||||
sorting::grayscale(palettes, png.getColors().raw());
|
sorting::grayscale(palettes, png.getColors().raw());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ class Png {
|
|||||||
int colorType;
|
int colorType;
|
||||||
int nbColors;
|
int nbColors;
|
||||||
png_colorp embeddedPal = nullptr;
|
png_colorp embeddedPal = nullptr;
|
||||||
|
int nbTransparentEntries;
|
||||||
png_bytep transparencyPal = nullptr;
|
png_bytep transparencyPal = nullptr;
|
||||||
|
|
||||||
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
[[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));
|
pixels.resize(static_cast<size_t>(width) * static_cast<size_t>(height));
|
||||||
|
|
||||||
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
if (png_get_PLTE(png, info, &embeddedPal, &nbColors) != 0) {
|
||||||
int nbTransparentEntries;
|
|
||||||
if (png_get_tRNS(png, info, &transparencyPal, &nbTransparentEntries, nullptr)) {
|
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