about summary refs log tree commit diff
path: root/converter/ppm/411toppm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/411toppm.c')
-rw-r--r--converter/ppm/411toppm.c219
1 files changed, 94 insertions, 125 deletions
diff --git a/converter/ppm/411toppm.c b/converter/ppm/411toppm.c
index 6ece4c4b..eb2372a5 100644
--- a/converter/ppm/411toppm.c
+++ b/converter/ppm/411toppm.c
@@ -30,7 +30,7 @@
 
    Bryan Henderson reworked the program to use the Netpbm libraries to
    create the PPM output and follow some other Netpbm conventions.
-   2001-03-03.  Bryan's contribution is public domain.  
+   2001-03-03.  Bryan's contribution is public domain.
 */
 /*
  * Copyright (c) 1995 The Regents of the University of California.
@@ -56,22 +56,21 @@
  * HEADER FILES *
  *==============*/
 #include <stdio.h>
-#include <stdlib.h>
 
 #include "pm_c_util.h"
-#include "ppm.h"
-#include "shhopt.h"
 #include "mallocvar.h"
+#include "shhopt.h"
+#include "ppm.h"
 
 typedef unsigned char uint8;
 
 #define CHOP(x)     ((x < 0) ? 0 : ((x > 255) ? 255 : x))
 
-struct cmdline_info {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
-    const char *input_filespec;  /* Filespec of input file */
+    const char * inputFileName;
     int width;
     int height;
 };
@@ -79,38 +78,42 @@ struct cmdline_info {
 
 
 static void
-parse_command_line(int argc, char ** argv,
-                   struct cmdline_info *cmdline_p) {
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo *cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
 
-    optStruct *option_def = malloc(100*sizeof(optStruct));
+    optEntry * option_def;
         /* Instructions to OptParseOptions2 on how to parse our options.
          */
-    optStruct2 opt;
+    optStruct3 opt;
 
     unsigned int option_def_index;
 
-    option_def_index = 0;   /* incremented by OPTENTRY */
-    OPTENTRY(0,   "width",      OPT_INT,    &cmdline_p->width,          0);
-    OPTENTRY(0,   "height",     OPT_INT,    &cmdline_p->height,         0);
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENT3 */
+    OPTENT3(0,   "width",      OPT_INT,    &cmdlineP->width,  NULL,   0);
+    OPTENT3(0,   "height",     OPT_INT,    &cmdlineP->height, NULL,   0);
 
     /* Set the defaults */
-    cmdline_p->width = 64;
-    cmdline_p->height = 48;
+    cmdlineP->width = 64;
+    cmdlineP->height = 48;
 
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
     
-    optParseOptions2(&argc, argv, opt, 0);
-        /* Uses and sets argc, argv, and some of *cmdline_p and others. */
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
-    if (cmdline_p->width <= 0)
+    if (cmdlineP->width <= 0)
         pm_error("-width must be positive.");
-    if (cmdline_p->height <= 0)
+    if (cmdlineP->width %4 != 0)
+        pm_error("-width must be a multiple of 4.");
+    if (cmdlineP->height <= 0)
         pm_error("-height must be positive.");
 
     if (argc > 2)
@@ -118,145 +121,111 @@ parse_command_line(int argc, char ** argv,
                  "You supplied %d", argc-1);
     else {
         if (argc > 1)
-            cmdline_p->input_filespec = argv[1];
+            cmdlineP->inputFileName = argv[1];
         else
-            cmdline_p->input_filespec = "-";
+            cmdlineP->inputFileName = "-";
     }
+    free(option_def);
 }
 
 
 
-static void 
-ReadYUV(FILE *fpointer, const int width, const int height, 
-        uint8 ** const orig_y, uint8 ** const orig_cb, 
-        uint8 ** const orig_cr) {
+static void
+ReadYUV(FILE  * const ifP,
+        uint8 * const inbuff) {
+
+    size_t bytesRead;
 
-    int y, x, i;
+    bytesRead = fread(inbuff, 1, 6, ifP);
 
-    for (y = 0; y < height; y++) {
-        for (x = 0, i = 0; x < width; x+=4, i++) {
-            fread(orig_y[y]+x , 1, 4, fpointer);
-            fread(orig_cb[y]+i, 1, 1, fpointer);
-            fread(orig_cr[y]+i, 1, 1, fpointer);
-        }
-    }
+    if (bytesRead != 6 ) {
+        if (feof(ifP))
+            pm_error("Premature end of input.");
+        else
+            pm_error("Error reading input.");
+     }
 }
 
 
 
 static void
-AllocYCC(const int width, const int height,
-         uint8 *** const orig_yP, uint8 *** const orig_crP, 
-         uint8 *** const orig_cbP) {
-    int y;
-
-    MALLOCARRAY_NOFAIL(*orig_yP, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL((*orig_yP)[y], width);
-
-    MALLOCARRAY_NOFAIL(*orig_crP, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL((*orig_crP)[y], width/4);
-
-    MALLOCARRAY_NOFAIL(*orig_cbP, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL((*orig_cbP)[y], width/4);
-}
+YUVtoPPM(FILE  * const ifP,
+         int     const width,
+         int     const height,
+         pixel * const pixrow ) {
 
+    unsigned int col;
 
+    for (col = 0; col < width; ++col) {
 
-static void 
-YUVtoPPM(const int width, const int height, 
-         uint8 ** const orig_y, 
-         uint8 ** const orig_cb,
-         uint8 ** const orig_cr,
-         pixel ** const ppm_image
-         ) {
-    int     **Y, **U, **V;
-    int    y;
+        uint8 inbuff[6];
 
-    /* first, allocate tons of memory */
+        uint8 * const origY  = &inbuff[0];
+        uint8 * const origCb = &inbuff[4];
+        uint8 * const origCr = &inbuff[5];
+        int   y, u, v;
+        int32_t tempR, tempG, tempB;
+        pixval r, g, b;
 
-    MALLOCARRAY_NOFAIL(Y, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL(Y[y], width);
-    
-    MALLOCARRAY_NOFAIL(U, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL(U[y], width / 4);
-
-    MALLOCARRAY_NOFAIL(V, height);
-    for (y = 0; y < height; y++) 
-        MALLOCARRAY_NOFAIL(V[y], width/4);
-
-	for ( y = 0; y < height; y ++ ) {
-        int x;
-	    for ( x = 0; x < width/4; x ++ ) {
-            U[y][x] = orig_cb[y][x] - 128;
-            V[y][x] = orig_cr[y][x] - 128;
-	    }
-    }
-	for ( y = 0; y < height; y ++ ) {
-        int x;
-	    for ( x = 0; x < width; x ++ )
-	    {
-            Y[y][x] = orig_y[y][x] - 16;
-	    }
-    }
-    for ( y = 0; y < height; y++ ) {
-        int x;
-        for ( x = 0; x < width; x++ ) {
-            pixval r, g, b;
-            long   tempR, tempG, tempB;
-            /* look at yuvtoppm source for explanation */
-            
-            tempR = 104635*V[y][x/4];
-            tempG = -25690*U[y][x/4] + -53294 * V[y][x/4];
-            tempB = 132278*U[y][x/4];
-            
-            tempR += (Y[y][x]*76310);
-            tempG += (Y[y][x]*76310);
-            tempB += (Y[y][x]*76310);
-            
-            r = CHOP((int)(tempR >> 16));
-            g = CHOP((int)(tempG >> 16));
-            b = CHOP((int)(tempB >> 16));
-
-            PPM_ASSIGN(ppm_image[y][x], r, g, b);
+        if (col % 4 == 0) {
+            ReadYUV(ifP, inbuff);
+            u = origCb[0] - 128;
+            v = origCr[0] - 128;
         }
+
+        y = origY[col % 4] - 16;
+
+        tempR = 104635 * v              + y * 76310;
+        tempG = -25690 * u + -53294 * v + y * 76310;
+        tempB = 132278 * u              + y * 76310;
+
+        r = CHOP((int)(tempR >> 16));
+        g = CHOP((int)(tempG >> 16));
+        b = CHOP((int)(tempB >> 16));
+        
+        PPM_ASSIGN(pixrow[col], r, g, b);
     }
-    /* We really should free the Y, U, and V arrays now */
 }
 
 
 
 int
-main(int argc, char **argv) {
-    FILE *infile;
-    struct cmdline_info cmdline;
-    uint8 **orig_y, **orig_cb, **orig_cr;
-    pixel **ppm_image;
+main(int argc, const char **argv) {
 
-    ppm_init(&argc, argv);
+    pixval const maxval = 255;
+    struct CmdlineInfo cmdline;
+    FILE  * ifP;
+    pixel * pixrow;
+    unsigned int row;
 
-    parse_command_line(argc, argv, &cmdline);
+    pm_proginit(&argc, argv);
 
-    AllocYCC(cmdline.width, cmdline.height, &orig_y, &orig_cr, &orig_cb);
-    ppm_image = ppm_allocarray(cmdline.width, cmdline.height);
+    parseCommandLine(argc, argv, &cmdline);
 
-    pm_message("Reading (%dx%d):  %s\n", cmdline.width, cmdline.height, 
-               cmdline.input_filespec);
-    infile = pm_openr(cmdline.input_filespec);
-    ReadYUV(infile, cmdline.width, cmdline.height, orig_y, orig_cb, orig_cr);
-    pm_close(infile);
+    pixrow = ppm_allocrow(cmdline.width);
 
-    YUVtoPPM(cmdline.width, cmdline.height, orig_y, orig_cb, orig_cr, 
-             ppm_image);
+    pm_message("Reading (%ux%u): '%s'", cmdline.width, cmdline.height,
+               cmdline.inputFileName);
 
-    ppm_writeppm(stdout, ppm_image, cmdline.width, cmdline.height, 255, 0);
+    ifP = pm_openr(cmdline.inputFileName);
 
-    ppm_freearray(ppm_image, cmdline.height);
+    ppm_writeppminit(stdout, cmdline.width, cmdline.height, maxval, 0);
+
+    for (row = 0; row < cmdline.height; ++row) {
+        YUVtoPPM(ifP, cmdline.width, cmdline.height, pixrow);
+        ppm_writeppmrow(stdout, pixrow, cmdline.width, maxval, 0);
+    }
+
+    if (fgetc(ifP) != EOF)
+        pm_message("Extraneous data at end of image.");
+
+    pm_close(ifP);
+    ppm_freerow(pixrow);
 
     return 0;
 }
 
+/*
+   By default a .411 file is width=64, height=48, 4608 bytes.
+   There is no header.
+*/