]> git.draconx.ca Git - liblbx.git/blobdiff - src/png.c
liblbx: Don't scale palette values internally.
[liblbx.git] / src / png.c
index 288cf7719d227f83dc5c5f8342370149fc6ac9b2..83aeec43583a354834a8e49bd525113fc50a6876 100644 (file)
--- a/src/png.c
+++ b/src/png.c
@@ -23,6 +23,7 @@
 #include <stdarg.h>
 #include <stdbool.h>
 #include <setjmp.h>
+#include <assert.h>
 
 #include <png.h>
 
@@ -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);