From 4e74df93acc6594cd8a212c30dc2b429520caef2 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Thu, 13 Jun 2013 21:57:11 -0400 Subject: [PATCH] liblbx: Don't scale palette values internally. 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. --- src/gui/render.c | 15 +++++++++++---- src/image.c | 12 ++++++------ src/image.h | 5 +---- src/lbximg.c | 2 +- src/png.c | 41 ++++++++++++++++++++++++++++------------- tests/regress.zsh | 29 +++++++++++++++-------------- 6 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/gui/render.c b/src/gui/render.c index e30e6c8..a96cc06 100644 --- a/src/gui/render.c +++ b/src/gui/render.c @@ -29,6 +29,13 @@ struct lbx_colour palette_external[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; @@ -40,11 +47,11 @@ static void get_colour(unsigned char index, unsigned char out[static 4]) 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 */ } diff --git a/src/image.c b/src/image.c index 4657208..98d1a31 100644 --- a/src/image.c +++ b/src/image.c @@ -413,9 +413,9 @@ lbx_img_loadpalette(void *f, const struct lbx_file_ops *fops, } 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, .active = 1, }; } @@ -451,9 +451,9 @@ lbx_img_getpalette(struct lbx_image *pub, struct lbx_colour palette[static 256]) } 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], .active = 1, }; } diff --git a/src/image.h b/src/image.h index b51b360..2057a42 100644 --- a/src/image.h +++ b/src/image.h @@ -11,10 +11,7 @@ struct lbx_image { }; struct lbx_colour { - unsigned char red; - unsigned char green; - unsigned char blue; - unsigned char active; + unsigned red:6, green:6, blue:6, active:1; }; struct lbx_imginfo { diff --git a/src/lbximg.c b/src/lbximg.c index 085e191..6c54b0f 100644 --- a/src/lbximg.c +++ b/src/lbximg.c @@ -180,7 +180,7 @@ static int loadpalette(struct lbx_image *img, struct lbx_imginfo *info, /* 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. */ diff --git a/src/png.c b/src/png.c index 288cf77..83aeec4 100644 --- a/src/png.c +++ b/src/png.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -93,13 +94,33 @@ static void flush_data(png_structp png) } } +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, - 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_color png_palette[256]; unsigned char (*row)[4]; jmp_buf parent; @@ -121,11 +142,12 @@ write_rgba_frame(png_structp png, png_infop 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++) { - 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); @@ -176,18 +198,11 @@ write_masked_index_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]; - 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); diff --git a/tests/regress.zsh b/tests/regress.zsh index 041e83f..a3a5adf 100755 --- a/tests/regress.zsh +++ b/tests/regress.zsh @@ -43,53 +43,53 @@ $LBXTOOL -xf $DATADIR/mainmenu.lbx mainmenu.lbx.{000,007,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 -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 -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 -compare 0 5cc8d2b761390d15be2738030c658bfc +compare 0 cf4cbcb834ef35890d1283928b0187bf 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 -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 -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 -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 @@ -97,4 +97,5 @@ if [[ $FAILED -eq 0 ]]; then rm -rf -- $SCRATCH else echo "$FAILED test(s) FAILED" + exit 1 fi -- 2.43.0