#include <stdarg.h>
#include <stdbool.h>
#include <setjmp.h>
+#include <assert.h>
#include <png.h>
FILE *f;
};
-static int is_masked(unsigned char **mask, unsigned width, unsigned height)
-{
- for (unsigned y = 0; y < height; y++) {
- for (unsigned x = 0; x < width; x++) {
- if (mask[y][x] == 0)
- return 1;
- }
- }
-
- return 0;
-}
-
static void fatal(png_structp png, int err, const char *fmt, ...)
{
va_list ap;
}
}
+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;
}
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);
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);
unsigned char **framedata, unsigned char **mask,
struct lbx_colour *palette)
{
- bool masked = is_masked(mask, width, height);
+ bool masked = img_is_masked(mask, width, height);
struct file_info file = { filename, f };
png_structp png;
png_infop info;