about summary refs log tree commit diff
path: root/converter/other/pamrgbatopng.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/other/pamrgbatopng.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pamrgbatopng.c')
-rw-r--r--converter/other/pamrgbatopng.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/converter/other/pamrgbatopng.c b/converter/other/pamrgbatopng.c
new file mode 100644
index 00000000..7babf9f9
--- /dev/null
+++ b/converter/other/pamrgbatopng.c
@@ -0,0 +1,150 @@
+#include <png.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#include "pam.h"
+#include "mallocvar.h"
+
+struct cmdlineInfo {
+    const char * inputFileName;
+};
+
+
+
+static void
+processCommandLine(int                  const argc,
+                   char *               const argv[],
+                   struct cmdlineInfo * const cmdlineP) {
+        
+    if (argc-1 < 1)
+        cmdlineP->inputFileName = "-";
+    else {
+        cmdlineP->inputFileName = argv[1];
+
+        if (argc-1 > 1)
+            pm_error("Too many arguments.  "
+                     "The only argument is the input file name.");
+    }
+}
+
+
+
+static void
+convertPamToPng(const struct pam * const pamP,
+                const tuple *      const tuplerow,
+                png_byte *         const pngRow) {
+    
+    unsigned int col;
+    
+    for (col = 0; col < pamP->width; ++col) {
+        unsigned int plane;
+        
+        for (plane = 0; plane < 4; ++plane)
+            pngRow[4 * col + plane] = tuplerow[col][plane];
+    }
+}
+
+
+
+static void
+writeRaster(const struct pam * const pamP,
+            png_struct *       const pngP) {
+    
+    tuple * tupleRow;
+    png_byte * pngRow;
+    
+    tupleRow = pnm_allocpamrow(pamP);
+    MALLOCARRAY(pngRow, pamP->width * 4);
+
+    if (pngRow == NULL)
+        pm_error("Unable to allocate space for PNG pixel row.");
+    else {
+        unsigned int row;
+        for (row = 0; row < pamP->height; ++row) {
+            pnm_readpamrow(pamP, tupleRow);
+            
+            convertPamToPng(pamP, tupleRow, pngRow);
+            
+            png_write_row(pngP, pngRow);
+        }
+        free(pngRow);
+    }
+    pnm_freepamrow(tupleRow);
+}
+
+
+
+static void
+pngErrorHandler(png_struct * const pngP,
+                const char * const message) {
+
+    pm_error("Error generating PNG image.  libpng says: %s", message);
+}
+
+
+
+static void
+writePng(const struct pam * const pamP,
+         FILE *             const ofP) {
+
+    png_struct * pngP;
+    png_info * infoP;
+
+    pngP = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!pngP)
+        pm_error("Could not allocate png struct.");
+
+    png_set_error_fn(pngP, NULL, &pngErrorHandler, NULL);
+
+    infoP = png_create_info_struct(pngP);
+    if (!infoP)
+        pm_error("Could not allocate PNG info structure");
+    else {
+        infoP->width      = pamP->width;
+        infoP->height     = pamP->height;
+        infoP->bit_depth  = 8;
+        infoP->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+        
+        png_init_io(pngP, ofP);
+
+        png_write_info(pngP, infoP);
+        
+        writeRaster(pamP, pngP);
+
+        png_write_end(pngP, infoP);
+        
+        png_destroy_write_struct(&pngP, &infoP);
+    }
+}
+    
+
+
+int
+main(int argc, char * argv[]) {
+
+    FILE * ifP;
+    struct cmdlineInfo cmdline;
+    struct pam pam;
+
+    pnm_init(&argc, argv);
+
+    processCommandLine(argc, argv, &cmdline);
+
+    ifP = pm_openr(cmdline.inputFileName);
+
+    pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(tuple_type));
+    
+    if (pam.depth < 4)
+        pm_error("PAM must have depth at least 4 (red, green, blue, alpha).  "
+                 "This one has depth %u", pam.depth);
+        
+    if (pam.maxval != 255)
+        pm_error("PAM must have maxval 255.  This one has %lu", pam.maxval);
+
+    writePng(&pam, stdout);
+
+    pm_close(ifP);
+
+    return 0;
+}