mirror of
https://github.com/gbdev/rgbds.git
synced 2026-10-06 04:05:38 +00:00
Implement -c embedded:multiple (#2194)
This commit is contained in:
1 parent
c592d665a8
commit
ffa32a94e8
12 files changed
+66
-3
No files matched your search
@@ -28,6 +28,7 @@ struct Options {
|
||||
INLINE,
|
||||
EXTERNAL,
|
||||
EMBEDDED,
|
||||
EMBEDDED_MULTIPLE,
|
||||
DMG,
|
||||
} palSpecType = NO_SPEC; // -c
|
||||
std::vector<std::array<std::optional<Rgba>, 4>> palSpec{};
|
||||
@@ -61,6 +62,9 @@ struct Options {
|
||||
uint16_t maxNbColors() const { return nbColorsPerPal * nbPalettes; }
|
||||
|
||||
bool hasExplicitPalSpec() const { return palSpecType == INLINE || palSpecType == EXTERNAL; }
|
||||
bool hasEmbeddedPalSpec() const {
|
||||
return palSpecType == EMBEDDED || palSpecType == EMBEDDED_MULTIPLE;
|
||||
}
|
||||
|
||||
uint8_t dmgColors[4] = {};
|
||||
uint8_t dmgValue(uint8_t i) const {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
void parseInlinePalSpec(char const * const rawArg);
|
||||
void parseEmbeddedPalSpec(Png const &png);
|
||||
void parseEmbeddedMultiplePalSpec(Png const &png);
|
||||
void parseExternalPalSpec(char const *arg);
|
||||
void parseDmgPalSpec(char const * const rawArg);
|
||||
void parseBackgroundPalSpec(char const *arg);
|
||||
|
||||
@@ -189,6 +189,11 @@ is the case-insensitive word
|
||||
then the first four colors of the input PNG's embedded palette are used.
|
||||
It is an error if the PNG is not indexed, or if colors other than these 4 are used.
|
||||
.Pq This is different from the default behavior of indexed PNGs, as then unused entries in the embedded palette are ignored, whereas they are not with Fl c Cm embedded .
|
||||
If
|
||||
.Ar pal_spec
|
||||
is case-insensitive
|
||||
.Cm embedded:multiple ,
|
||||
then every four colors of the input PNG's embedded palette are used for multiple palettes.
|
||||
.It Sy DMG palette spec
|
||||
If
|
||||
.Ar pal_spec
|
||||
|
||||
@@ -200,6 +200,9 @@ static void parseArg(int ch, char *arg) {
|
||||
} else if (strcasecmp(arg, "embedded") == 0) {
|
||||
// Use PLTE, error out if missing
|
||||
options.palSpecType = Options::EMBEDDED;
|
||||
} else if (strcasecmp(arg, "embedded:multiple") == 0) {
|
||||
// Use PLTE, error out if missing
|
||||
options.palSpecType = Options::EMBEDDED_MULTIPLE;
|
||||
} else if (strcasecmp(arg, "auto") == 0) {
|
||||
options.palSpecType = Options::NO_SPEC;
|
||||
} else if (strcasecmp(arg, "dmg") == 0) {
|
||||
@@ -526,7 +529,10 @@ static void verboseOutputConfig() {
|
||||
case Options::INLINE:
|
||||
case Options::EXTERNAL:
|
||||
case Options::EMBEDDED:
|
||||
case Options::EMBEDDED_MULTIPLE:
|
||||
if (options.palSpecType == Options::EMBEDDED) {
|
||||
fputs("\tEmbedded single palette spec from PNG indexed PLTE chunk\n", stderr);
|
||||
} else if (options.palSpecType == Options::EMBEDDED_MULTIPLE) {
|
||||
fputs("\tEmbedded palette spec from PNG indexed PLTE chunk\n", stderr);
|
||||
} else {
|
||||
fputs("\tExplicit palette spec\n", stderr);
|
||||
@@ -695,6 +701,12 @@ int main(int argc, char *argv[]) {
|
||||
parseEmbeddedPalSpec(png);
|
||||
}
|
||||
break;
|
||||
case Options::EMBEDDED_MULTIPLE:
|
||||
assume(!localOptions.palSpec);
|
||||
if (useInputImage) {
|
||||
parseEmbeddedMultiplePalSpec(png);
|
||||
}
|
||||
break;
|
||||
case Options::INLINE:
|
||||
assume(localOptions.palSpec);
|
||||
parseInlinePalSpec(localOptions.palSpec->c_str());
|
||||
|
||||
+42
-2
@@ -185,8 +185,8 @@ void parseEmbeddedPalSpec(Png const &png) {
|
||||
|
||||
// Ignore extraneous colors if they are unused
|
||||
size_t nbColors = png.palette.size();
|
||||
if (nbColors > options.maxOpaqueColors()) {
|
||||
nbColors = options.maxOpaqueColors();
|
||||
if (nbColors > options.nbColorsPerPal) {
|
||||
nbColors = options.nbColorsPerPal;
|
||||
}
|
||||
|
||||
// Fill in the palette spec
|
||||
@@ -198,6 +198,46 @@ void parseEmbeddedPalSpec(Png const &png) {
|
||||
}
|
||||
}
|
||||
|
||||
void parseEmbeddedMultiplePalSpec(Png const &png) {
|
||||
// Generate a palette spec from N palettes' length of colors in the embedded palette
|
||||
if (png.palette.empty()) {
|
||||
error("\"-c embedded:multiple\" was given, but the PNG does not have an embedded palette");
|
||||
return;
|
||||
}
|
||||
|
||||
// Use enough embedded colors to evenly divide into N palettes
|
||||
size_t nbColors = png.palette.size();
|
||||
size_t nbPalettes = nbColors / options.nbColorsPerPal;
|
||||
if (uint16_t maxNbColors = options.maxNbColors(); nbColors > maxNbColors) {
|
||||
warnx(
|
||||
"PNG embedded palette contains %zu colors, but there can only be %" PRIu16
|
||||
"; ignoring extra",
|
||||
nbColors,
|
||||
maxNbColors
|
||||
);
|
||||
nbColors = maxNbColors;
|
||||
nbPalettes = options.nbPalettes;
|
||||
}
|
||||
if (size_t nbUsedColors = options.nbColorsPerPal * nbPalettes; nbColors > nbUsedColors) {
|
||||
warnx(
|
||||
"PNG embedded palette contains %zu colors, but only %zu can be used for %zu palettes; "
|
||||
"ignoring extra",
|
||||
nbColors,
|
||||
nbUsedColors,
|
||||
nbPalettes
|
||||
);
|
||||
}
|
||||
|
||||
// Fill in the palette spec
|
||||
options.palSpec.clear();
|
||||
for (size_t i = 0; i < nbPalettes; ++i) {
|
||||
auto &palette = options.palSpec.emplace_back();
|
||||
for (size_t j = 0; j < options.nbColorsPerPal; ++j) {
|
||||
palette[j] = png.palette[i * options.nbColorsPerPal + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Appends the first line read from `file` to the end of the provided `buffer`.
|
||||
// Returns true if a line was read.
|
||||
[[nodiscard]]
|
||||
|
||||
+1
-1
@@ -282,7 +282,7 @@ void reverse() {
|
||||
palettes[0][i] = grayColors[options.dmgValue(i)];
|
||||
}
|
||||
grayscale = true;
|
||||
} else if (options.palSpecType == Options::EMBEDDED) {
|
||||
} else if (options.hasEmbeddedPalSpec()) {
|
||||
warnx("An embedded palette was requested, but no palette file was specified; ignoring "
|
||||
"request");
|
||||
grayscale = true;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-c embedded:multiple
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 209 B |
Reference in new issue
Block a user