]> git.draconx.ca Git - liblbx.git/blobdiff - src/lbximg.c
lbximg: Add a new PNG writing routine.
[liblbx.git] / src / lbximg.c
index ff38c89b71f998f0dff387f5f2404e4ffb0783cf..c761c176f6ee308e421cbdf67dfe73bdaaee0b2d 100644 (file)
 #include <getopt.h>
 #include <errno.h>
 
-#include <png.h>
-
 #include "tools.h"
 #include "image.h"
 #include "error.h"
 #include "lbx.h"
 
+#include "imgoutput.h"
+
 /* Global flags */
 static int verbose = 0;
 static char *outname = "out";
@@ -104,127 +104,39 @@ int parserange(unsigned frames, char *str, unsigned char *bits)
        return 0;
 }
 
-static int ismasked(unsigned char **mask, unsigned width, unsigned height)
-{
-       unsigned y, x;
-       for (y = 0; y < height; y++) {
-               for (x = 0; x < width; x++) {
-                       if (mask[y][x] == 0) return 1;
-               }
-       }
-
-       return 0;
-}
-
 int outpng(unsigned int frameno,
            unsigned char **framedata, unsigned char **mask,
            unsigned int width, unsigned int height,
            struct lbx_colour palette[static 256])
 {
        char name[strlen(outname) + sizeof ".65535.png"];
-       unsigned char *row;
-       unsigned int x, y;
        FILE *of;
-
-       png_structp png;
-       png_infop   info;
+       int rc;
 
        assert(frameno < 65536);
        snprintf(name, sizeof name, "%s.%03d.png", outname, frameno);
 
-       row = malloc(4 * width);
-       if (!row) {
-               tool_err(0, "failed to allocate row buffer");
-               return -1;
-       }
-
        of = fopen(name, "wb");
        if (!of) {
                tool_err(0, "failed to open %s", name);
                return -1;
        }
 
-       png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-       if (!png) {
-               tool_err(-1, "failed to init libpng.");
-               goto err;
-       }
-
-       info = png_create_info_struct(png);
-       if (!info) {
-               tool_err(-1, "failed to init libpng.");
-               png_destroy_write_struct(&png, NULL);
-               goto err;
+       rc = img_output_png(of, name, width, height, framedata, mask, palette);
+       if (rc < 0) {
+               fclose(of);
+               return -1;
        }
 
-       if (setjmp(png_jmpbuf(png))) {
-               png_destroy_write_struct(&png, &info);
-               goto err;
+       if (fclose(of) == EOF) {
+               tool_err(0, "error writing %s", name);
+               return -1;
        }
-
-       png_init_io(png, of);
-
-       if (!ismasked(mask, width, height)) {
-               /*
-                * This case is easy; we can just feed the palette and pixel
-                * data to libpng and let it do its magic.
-                */
-
-               png_color png_palette[256];
-               for (unsigned i = 0; i < 256; i++) {
-                       png_palette[i].red   = palette[i].red;
-                       png_palette[i].green = palette[i].green;
-                       png_palette[i].blue  = palette[i].blue;
-               }
-
-               png_set_IHDR(png, info, width, height, 8,
-                            PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
-                            PNG_COMPRESSION_TYPE_DEFAULT,
-                            PNG_FILTER_TYPE_DEFAULT);
                
-               png_set_PLTE(png, info, png_palette, 256);
-               png_set_rows(png, info, framedata);
-               png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
-       } else {
-               /*
-                * Unfortunately, LBX doesn't translate nicely to PNG here.
-                * LBX has a 256 colour palette _plus_ transparency.
-                * We'll form an RGBA PNG to deal with this.
-                */
-
-               png_set_IHDR(png, info, width, height, 8,
-                            PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
-                            PNG_COMPRESSION_TYPE_DEFAULT,
-                            PNG_FILTER_TYPE_DEFAULT);
-       
-               png_write_info(png, info);
-       
-               for (y = 0; y < height; y++) {
-                       for (x = 0; x < width; x++) {
-                               row[4*x+0] = palette[framedata[y][x]].red;
-                               row[4*x+1] = palette[framedata[y][x]].green;
-                               row[4*x+2] = palette[framedata[y][x]].blue;
-                               row[4*x+3] = (mask[y][x]) ? -1 : 0;
-                       }
-       
-                       png_write_row(png, row);
-               }
-       
-               png_write_end(png, NULL);
-       }
-
-       png_destroy_write_struct(&png, &info);
-       fclose(of);
-       free(row);
-
        if (verbose)
                printf("wrote %s\n", name);
+
        return 0;
-err:
-       fclose(of);
-       remove(name);
-       free(row);
-       return -1;
 }
 
 static int loadoverride(FILE *f, struct lbx_colour palette[static 256])