]> git.draconx.ca Git - liblbx.git/blobdiff - src/pnm.c
lbximg: Convert to new decoding API.
[liblbx.git] / src / pnm.c
index 865d2a19b1b1941cdc93cb058b14198a69cc9e7a..ace5e1824a5fa3140264876756446e465266c551 100644 (file)
--- a/src/pnm.c
+++ b/src/pnm.c
@@ -1,7 +1,7 @@
 /*
  * 2ooM: The Master of Orion II Reverse Engineering Project
  * Netpbm 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
@@ -24,6 +24,7 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <inttypes.h>
+#include <limits.h>
 
 #include "image.h"
 #include "tools.h"
@@ -183,8 +184,8 @@ static int fprintf_ascii(FILE *f, char *fmt, ...)
  */
 int img_output_pbm(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)
 {
        unsigned x, y;
 
@@ -192,16 +193,14 @@ int img_output_pbm(FILE *f, const char *filename,
                goto err;
 
        for (x = y = 0; y < height; ++x < width || (x = 0, y++)) {
+               unsigned long offset = (unsigned long) y * width + x;
+               bool vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT);
+
                if (fputc(to_ascii(x > 0 ? ' ' : '\n'), f) == EOF)
                        goto err;
 
-               if (mask[y][x]) {
-                       if (fputc(to_ascii('0'), f) == EOF)
-                               goto err;
-               } else {
-                       if (fputc(to_ascii('1'), f) == EOF)
-                               goto err;
-               }
+               if (fputc(to_ascii(vis ? '0' : '1'), f) == EOF)
+                       goto err;
        }
 
        if (fputc(to_ascii('\n'), f) == EOF)
@@ -218,7 +217,7 @@ err:
  * normal output format.
  */
 static int write_pgm(FILE *f, unsigned width, unsigned height,
-                     unsigned char **framedata, unsigned char **mask)
+                     unsigned char *pixels, unsigned char *mask)
 {
        unsigned x, y;
 
@@ -226,16 +225,14 @@ static int write_pgm(FILE *f, unsigned width, unsigned height,
                return -1;
 
        for (x = y = 0; y < height; ++x < width || (x = 0, y++)) {
+               unsigned long offset = (unsigned long) y * width + x;
+               bool vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT);
+
                if (fputc(to_ascii(x > 0 ? ' ' : '\n'), f) == EOF)
                        return -1;
 
-               if (!mask[y][x]) {
-                       if (fprintf_ascii(f, "  0") < 0)
-                               return -1;
-               } else {
-                       if (fprintf_ascii(f, "%3hhu", framedata[y][x]) < 0)
-                               return -1;
-               }
+               if (fprintf_ascii(f, "%3hhu", vis ? pixels[offset] : 0) < 0)
+                       return -1;
        }
 
        if (fputc(to_ascii('\n'), f) == EOF)
@@ -252,8 +249,8 @@ static int write_pgm(FILE *f, unsigned width, unsigned height,
  */
 int img_output_ppm(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)
 {
        unsigned x, y;
 
@@ -262,7 +259,7 @@ int img_output_ppm(FILE *f, const char *filename,
                 * For no-palette mode, write a PGM instead which is basically
                 * the same format but has only one value per pixel.
                 */
-               if (write_pgm(f, width, height, framedata, mask) < 0)
+               if (write_pgm(f, width, height, pixels, mask) < 0)
                        goto err;
                return 0;
        }
@@ -271,19 +268,18 @@ int img_output_ppm(FILE *f, const char *filename,
                goto err;
 
        for (x = y = 0; y < height; ++x < width || (x = 0, y++)) {
+               unsigned long offset = (unsigned long) y * width + x;
+               bool vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT);
+               struct lbx_colour c = { 0 };
+
                if (fputc(to_ascii(x > 0 ? ' ' : '\n'), f) == EOF)
                        goto err;
 
-               if (!mask[y][x]) {
-                       if (fprintf_ascii(f, " 0  0  0") < 0)
-                               goto err;
-               } else {
-                       struct lbx_colour *c = &palette[framedata[y][x]];
+               if (vis)
+                       c = palette[pixels[offset]];
 
-                       if (fprintf_ascii(f, "%2d %2d %2d",
-                                         c->red, c->green, c->blue) < 0)
-                               goto err;
-               }
+               if (fprintf_ascii(f, "%2d %2d %2d", c.red, c.green, c.blue) < 0)
+                       goto err;
        }
 
        if (fputc(to_ascii('\n'), f) == EOF)
@@ -301,8 +297,8 @@ err:
  */
 int img_output_pam(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);
        unsigned x, y;
@@ -320,13 +316,16 @@ int img_output_pam(FILE *f, const char *filename,
                        goto err;
 
                for (x = y = 0; y < height; ++x < width || (x = 0, y++)) {
-                       struct lbx_colour *c = &palette[framedata[y][x]];
+                       unsigned long offset = (unsigned long) y * width + x;
+                       struct lbx_colour *c = &palette[pixels[offset]];
                        unsigned char buf[4];
+                       bool vis;
 
+                       vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT);
                        buf[0] = c->red;
                        buf[1] = c->green;
                        buf[2] = c->blue;
-                       buf[3] = mask[y][x] ? 63 : 0;
+                       buf[3] = vis ? 63 : 0;
 
                        if (fwrite(buf, 1, depth, f) < depth)
                                goto err;
@@ -340,10 +339,13 @@ int img_output_pam(FILE *f, const char *filename,
                        goto err;
 
                for (x = y = 0; y < height; ++x < width || (x = 0, y++)) {
+                       unsigned long offset = (unsigned long) y * width + x;
                        unsigned char buf[2];
+                       bool vis;
 
-                       buf[0] = framedata[y][x];
-                       buf[1] = mask[y][x] ? 0xff : 0;
+                       vis = mask[offset/CHAR_BIT] & (1u << offset%CHAR_BIT);
+                       buf[0] = pixels[offset];
+                       buf[1] = vis ? 255 : 0;
 
                        if (fwrite(buf, 1, depth, f) < depth)
                                goto err;