X-Git-Url: https://git.draconx.ca/gitweb/liblbx.git/blobdiff_plain/430be3ec2f86aec28fa21558b3141a2e28efd848..594902a517f5a77535a2d7bb903f8e1de358edf6:/src/png.c diff --git a/src/png.c b/src/png.c index c52db03..cc885f7 100644 --- a/src/png.c +++ b/src/png.c @@ -1,7 +1,7 @@ /* * 2ooM: The Master of Orion II Reverse Engineering Project * PNG output routines for lbximg extration. - * Copyright © 2013 Nick Bowler + * Copyright © 2013-2014 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -103,7 +103,7 @@ static void fill_png_palette(png_color *out, const struct lbx_colour *in) static void write_rgba_frame(png_structp png, png_infop info, - unsigned char **framedata, unsigned char **mask, + unsigned char *pixels, unsigned char *mask, struct lbx_colour *lbx_palette) { png_uint_32 width = png_get_image_width(png, info); @@ -133,10 +133,15 @@ write_rgba_frame(png_structp png, png_infop 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] = 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; + unsigned long offset = (unsigned long) y * width + x; + png_color *c = &png_palette[pixels[offset]]; + bool vis; + + vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT); + row[x][0] = c->red; + row[x][1] = c->green; + row[x][2] = c->blue; + row[x][3] = -vis; } png_write_row(png, (void *)row); } @@ -147,7 +152,7 @@ write_rgba_frame(png_structp png, png_infop info, static void write_masked_index_frame(png_structp png, png_infop info, - unsigned char **framedata, unsigned char **mask) + unsigned char *pixels, unsigned char *mask) { png_uint_32 width = png_get_image_width(png, info); png_uint_32 height = png_get_image_height(png, info); @@ -174,8 +179,12 @@ write_masked_index_frame(png_structp png, png_infop info, png_write_info(png, info); for (png_uint_32 y = 0; y < height; y++) { for (png_uint_32 x = 0; x < width; x++) { - row[x][0] = framedata[y][x]; - row[x][1] = mask[y][x] ? -1 : 0; + unsigned long offset = (unsigned long) y * width + x; + bool vis; + + vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT); + row[x][0] = pixels[offset]; + row[x][1] = -vis; } png_write_row(png, (void *)row); } @@ -185,28 +194,35 @@ 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 *lbx_palette) +write_index_frame(png_structp png, png_infop info, unsigned char *pixels) { - png_color png_palette[256]; + png_uint_32 width = png_get_image_width(png, info); + png_uint_32 height = png_get_image_height(png, info); - 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_write_info(png, info); + for (png_uint_32 y = 0; y < height; y++) { + unsigned long offset = (unsigned long) y * width; + + png_write_row(png, (void *)(pixels+offset)); + } + png_write_end(png, NULL); } static void -write_index_frame(png_structp png, png_infop info, unsigned char **framedata) +write_palette_frame(png_structp png, png_infop info, + unsigned char *pixels, struct lbx_colour *lbx_palette) { - png_set_rows(png, info, framedata); - png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL); + png_color png_palette[256]; + fill_png_palette(png_palette, lbx_palette); + png_set_PLTE(png, info, png_palette, 256); + + write_index_frame(png, info, pixels); } int img_output_png(FILE *f, const char *filename, unsigned width, unsigned height, - unsigned char **framedata, unsigned char **mask, - struct lbx_colour *palette) + unsigned char *pixels, unsigned char *mask, + struct lbx_colour *palette) { bool masked = img_is_masked(mask, width, height); struct file_info file = { filename, f }; @@ -246,28 +262,28 @@ int img_output_png(FILE *f, const char *filename, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - write_rgba_frame(png, info, framedata, mask, palette); + write_rgba_frame(png, info, pixels, mask, palette); } else if (palette) { png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - write_palette_frame(png, info, framedata, palette); + write_palette_frame(png, info, pixels, palette); } else if (masked) { png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - write_masked_index_frame(png, info, framedata, mask); + write_masked_index_frame(png, info, pixels, mask); } else { png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - write_index_frame(png, info, framedata); + write_index_frame(png, info, pixels); } png_destroy_write_struct(&png, &info);