Output the 18-bit palette values unadulterated, leaving it up to the
users to do conversion if necessary. Push the conversion down into the
consumers (currently PNG output and the GTK GUI) where a 24-bit palette
is required.
While we're at it, adjust the conversion to scale to the full output
range of [0, 255]. This is a slight change to the output, so all the
image hashes need to be adjusted in the regression test.
struct lbx_colour palette_internal[256];
struct lbx_colour palette_override[256];
struct lbx_colour palette_internal[256];
struct lbx_colour palette_override[256];
+static inline unsigned scale6to8(unsigned x)
+{
+ assert(x <= 0x3f);
+
+ return x*0xff / 0x3f;
+}
+
static void get_colour(unsigned char index, unsigned char out[static 4])
{
struct lbx_colour *colour;
static void get_colour(unsigned char index, unsigned char out[static 4])
{
struct lbx_colour *colour;
else if (palette_external[index].active)
colour = palette_external + index;
else
else if (palette_external[index].active)
colour = palette_external + index;
else
- colour = &(struct lbx_colour) { .red = 0xff, .blue = 0xff };
+ colour = &(struct lbx_colour) { .red = 0x3f, .blue = 0x3f };
- out[0] = colour->red;
- out[1] = colour->green;
- out[2] = colour->blue;
+ out[0] = scale6to8(colour->red);
+ out[1] = scale6to8(colour->green);
+ out[2] = scale6to8(colour->blue);
out[3] = -1; /* opaque */
}
out[3] = -1; /* opaque */
}
}
palette[i] = (struct lbx_colour) {
}
palette[i] = (struct lbx_colour) {
- .red = entry[1] << 2,
- .green = entry[2] << 2,
- .blue = entry[3] << 2,
+ .red = entry[1] & 0x3f,
+ .green = entry[2] & 0x3f,
+ .blue = entry[3] & 0x3f,
}
palette[img->palstart + i] = (struct lbx_colour){
}
palette[img->palstart + i] = (struct lbx_colour){
- .red = entry[1] << 2,
- .green = entry[2] << 2,
- .blue = entry[3] << 2,
+ .red = entry[1],
+ .green = entry[2],
+ .blue = entry[3],
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- unsigned char active;
+ unsigned red:6, green:6, blue:6, active:1;
/* Default the palette to a wonderful pink. */
for (i = 0; i < 256; i++) {
/* Default the palette to a wonderful pink. */
for (i = 0; i < 256; i++) {
- palette[i] = (struct lbx_colour){0xff, 0x00, 0xff};
+ palette[i] = (struct lbx_colour){0x3f, 0x00, 0x3f};
}
/* Read the external palette, if any. */
}
/* Read the external palette, if any. */
#include <stdarg.h>
#include <stdbool.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdbool.h>
#include <setjmp.h>
+static inline unsigned scale6to8(unsigned x)
+{
+ assert(x <= 0x3f);
+
+ return x*0xff / 0x3f;
+}
+
+/* Scale the 18-bit LBX palette into a 24-bit PNG palette. */
+static void fill_png_palette(png_color *out, const struct lbx_colour *in)
+{
+ for (unsigned i = 0; i < 256; i++) {
+ out[i] = (struct png_color_struct) {
+ .red = scale6to8(in[i].red),
+ .green = scale6to8(in[i].green),
+ .blue = scale6to8(in[i].blue),
+ };
+ }
+}
+
static void
write_rgba_frame(png_structp png, png_infop info,
unsigned char **framedata, unsigned char **mask,
static void
write_rgba_frame(png_structp png, png_infop info,
unsigned char **framedata, unsigned char **mask,
- struct lbx_colour *palette)
+ struct lbx_colour *lbx_palette)
{
png_uint_32 width = png_get_image_width(png, info);
png_uint_32 height = png_get_image_height(png, info);
{
png_uint_32 width = png_get_image_width(png, info);
png_uint_32 height = png_get_image_height(png, info);
+ png_color png_palette[256];
unsigned char (*row)[4];
jmp_buf parent;
unsigned char (*row)[4];
jmp_buf parent;
}
png_write_info(png, info);
}
png_write_info(png, info);
+ fill_png_palette(png_palette, lbx_palette);
for (png_uint_32 y = 0; y < height; y++) {
for (png_uint_32 x = 0; x < width; x++) {
for (png_uint_32 y = 0; y < height; y++) {
for (png_uint_32 x = 0; x < width; x++) {
- row[x][0] = palette[framedata[y][x]].red;
- row[x][1] = palette[framedata[y][x]].green;
- row[x][2] = palette[framedata[y][x]].blue;
+ row[x][0] = png_palette[framedata[y][x]].red;
+ row[x][1] = png_palette[framedata[y][x]].green;
+ row[x][2] = png_palette[framedata[y][x]].blue;
row[x][3] = mask[y][x] ? -1 : 0;
}
png_write_row(png, (void *)row);
row[x][3] = mask[y][x] ? -1 : 0;
}
png_write_row(png, (void *)row);
static void
write_palette_frame(png_structp png, png_infop info,
static void
write_palette_frame(png_structp png, png_infop info,
- unsigned char **framedata, struct lbx_colour *palette)
+ unsigned char **framedata, struct lbx_colour *lbx_palette)
{
png_color png_palette[256];
{
png_color png_palette[256];
- for (unsigned i = 0; i < 256; i++) {
- png_palette[i] = (png_color) {
- .red = palette[i].red,
- .green = palette[i].green,
- .blue = palette[i].blue,
- };
- }
-
+ fill_png_palette(png_palette, lbx_palette);
png_set_PLTE(png, info, png_palette, 256);
png_set_rows(png, info, framedata);
png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
png_set_PLTE(png, info, png_palette, 256);
png_set_rows(png, info, framedata);
png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
echo "mainmenu.lbx.021: single frame, embedded palette:"
$LBXIMG -df mainmenu.lbx.021
echo "mainmenu.lbx.021: single frame, embedded palette:"
$LBXIMG -df mainmenu.lbx.021
-compare 0 390c49cfd1fe5e2ac0490be976f20936
+compare 0 b5d488667bed557a089c5d8f8b0a3d64
echo "mainmenu.lbx.007: single frame, external palette:"
$LBXIMG -dp fonts.lbx.006 < mainmenu.lbx.007
echo "mainmenu.lbx.007: single frame, external palette:"
$LBXIMG -dp fonts.lbx.006 < mainmenu.lbx.007
-compare 0 76def3e188f666025c62e621e23ab0d0
+compare 0 5b9a1a10e4979531e91a41f02ee40537
echo "mainmenu.lbx.000: multi frame, external palette:"
$LBXIMG -dp fonts.lbx.006 < mainmenu.lbx.000 0 15 49
echo "mainmenu.lbx.000: multi frame, external palette:"
$LBXIMG -dp fonts.lbx.006 < mainmenu.lbx.000 0 15 49
-compare 0 cc4ae6d96f6233f3b50bdce8b7ca74ee
-compare 15 cad158da9a015adfcea7809a8a3b6f4b
-compare 49 390c49cfd1fe5e2ac0490be976f20936
+compare 0 6556baafebe441498f33865f2e9eb0de
+compare 15 76a6e8fe18614423f8780ee80f513e8c
+compare 49 b5d488667bed557a089c5d8f8b0a3d64
# Logos
$LBXTOOL -xf $DATADIR/logo.lbx
echo "logo.lbx.000: single frame, embedded palette, transparency:"
$LBXIMG -df logo.lbx.000
# Logos
$LBXTOOL -xf $DATADIR/logo.lbx
echo "logo.lbx.000: single frame, embedded palette, transparency:"
$LBXIMG -df logo.lbx.000
-compare 0 5cc8d2b761390d15be2738030c658bfc
+compare 0 cf4cbcb834ef35890d1283928b0187bf
echo "logo.lbx.001: multi frame, embedded palette:"
$LBXIMG -df logo.lbx.001 0 30 63
echo "logo.lbx.001: multi frame, embedded palette:"
$LBXIMG -df logo.lbx.001 0 30 63
-compare 0 f3f0859b39f2e76091842c8a7276b2a1
-compare 30 8fb41356a20c68c3be0939ad49256cf9
-compare 63 156f381c5d4bf6178affd3d6a4720118
+compare 0 542778cde51dc821e225ddd4a16dc197
+compare 30 609c2b9be5a1e18f5c36398554f9f2ec
+compare 63 664b12c7259948900ded3ff93e1f4ec7
# Ships
$LBXTOOL -xf $DATADIR/ships.lbx ships.lbx.{042,049}
echo "ships.lbx.042: single frame, external+override palette, transparency:"
$LBXIMG -df ships.lbx.042 -p fonts.lbx.012 -O ships.lbx.049
# Ships
$LBXTOOL -xf $DATADIR/ships.lbx ships.lbx.{042,049}
echo "ships.lbx.042: single frame, external+override palette, transparency:"
$LBXIMG -df ships.lbx.042 -p fonts.lbx.012 -O ships.lbx.049
-compare 0 bd643736d46ef387bcffcc8803aabb83
+compare 0 3426ef9c5c8e3dfbd1a95ed9211e2342
# Nebulae
$LBXTOOL -xf $DATADIR/starbg.lbx starbg.lbx.009
echo "starbg.lbx.009: single frame, raw data:"
$LBXIMG -df starbg.lbx.009 -p fonts.lbx.005
# Nebulae
$LBXTOOL -xf $DATADIR/starbg.lbx starbg.lbx.009
echo "starbg.lbx.009: single frame, raw data:"
$LBXIMG -df starbg.lbx.009 -p fonts.lbx.005
-compare 0 cfc5d92b6503951c4962498c7dcfea31
+compare 0 2e430234f410ef208f78d99a64fa449f
# Monsters
$LBXTOOL -xf $DATADIR/monster.lbx monster.lbx.{007,014}
echo "monster.lbx.007: multi frame, chunked:"
$LBXIMG -df monster.lbx.007 -p fonts.lbx.004 -O monster.lbx.014 0 5 19
# Monsters
$LBXTOOL -xf $DATADIR/monster.lbx monster.lbx.{007,014}
echo "monster.lbx.007: multi frame, chunked:"
$LBXIMG -df monster.lbx.007 -p fonts.lbx.004 -O monster.lbx.014 0 5 19
-compare 0 59399c8d2d74116ff4b330a2cc1f3cc2
-compare 5 6947e108f7c8d2d2d626c67af3fdb7e2
-compare 19 03d86257527f0d7a91c2cde57059e734
+compare 0 20eb7d52abb3cd718426d4732d9e2286
+compare 5 ea8c7a5fbeb9043fd8f30ae91b13550a
+compare 19 d501ecf1599ea724846625a9711c6ccb
# Clean up
if [[ $FAILED -eq 0 ]]; then
# Clean up
if [[ $FAILED -eq 0 ]]; then
rm -rf -- $SCRATCH
else
echo "$FAILED test(s) FAILED"
rm -rf -- $SCRATCH
else
echo "$FAILED test(s) FAILED"