about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2007-01-21 19:50:56 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2007-01-21 19:50:56 +0000
commit309587a52754c104178eaec4ca6dc7d98bc54c11 (patch)
tree27856abd8e6be0b24ca4d1d452a412c86d4ab0cf
parent581931fe0b8c9fe0aae80e0d14acf08d7a5f5e01 (diff)
downloadnetpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.tar.gz
netpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.tar.xz
netpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@214 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--editor/ppm3d.c308
1 files changed, 214 insertions, 94 deletions
diff --git a/editor/ppm3d.c b/editor/ppm3d.c
index c37ceeb1..fd9a10dd 100644
--- a/editor/ppm3d.c
+++ b/editor/ppm3d.c
@@ -1,18 +1,92 @@
-/* ppmto3d.c - convert a portable pixmap to a portable graymap
-**
-** Copyright (C) 1989 by Jef Poskanzer.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation.  This software is provided "as is" without express or
-** implied warranty.
-*/
+/*=============================================================================
+                                   ppmto3d
+===============================================================================
+  This program converts two PPM images into an anaglyph stereogram image PPM.
+  (for viewing with red/blue 3D glasses).
 
+=============================================================================*/
+
+#include <assert.h>
+
+#include "shhopt.h"
+#include "mallocvar.h"
 #include "ppm.h"
 #include "lum.h"
 
+
+
+struct cmdlineInfo {
+    /* All the information the user supplied in the command line,
+       in a form easy for the program to use.
+    */
+    const char * leftInputFileName;  /* '-' if stdin */
+    const char * rghtInputFileName;  /* '-' if stdin */
+    unsigned int offset;
+    unsigned int color;
+};
+
+
+
+static void
+parseCommandLine(int argc, char ** argv,
+                 struct cmdlineInfo * const cmdlineP) {
+/*----------------------------------------------------------------------------
+   parse program command line described in Unix standard form by argc
+   and argv.  Return the information in the options as *cmdlineP.  
+
+   If command line is internally inconsistent (invalid options, etc.),
+   issue error message to stderr and abort program.
+
+   Note that the strings we return are stored in the storage that
+   was passed to us as the argv array.  We also trash *argv.
+-----------------------------------------------------------------------------*/
+    optEntry * option_def;
+        /* Instructions to optParseOptions3 on how to parse our options.
+         */
+    optStruct3 opt;
+
+    unsigned int option_def_index;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENT3 */
+    OPTENT3(0, "color",   OPT_FLAG,   NULL,
+            &cmdlineP->color, 0 );
+
+    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 */
+
+    optParseOptions3( &argc, argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+    
+    if (argc-1 < 2)
+        pm_error("You must specify at least two arguments: left and right "
+                 "input file names.  You specified %u", argc-1);
+    else {
+        cmdlineP->leftInputFileName = argv[1];
+        cmdlineP->rghtInputFileName = argv[2];
+
+        if (argc-1 > 2) {
+            int const offsetnum = atoi(argv[3]);
+
+            if (offsetnum <= 0)
+                pm_error("Offset must be a positive number.  You specified "
+                         "'%s'", argv[3]);
+            else
+                cmdlineP->offset = offsetnum;
+
+            if (argc-1 > 3)
+                pm_error("Program takes at most 3 arguments:  left and "
+                         "right input file names and offset.  "
+                         "You specified %u", argc-1);
+        } else
+            cmdlineP->offset = 30;
+    }
+}
+
+
+
 static void
 computeGrayscaleRow(const pixel * const inputRow,
                     gray *        const outputRow,
@@ -34,105 +108,151 @@ computeGrayscaleRow(const pixel * const inputRow,
 
 
 
+static void
+compute3dRow(pixel *      const lPixelrow,
+             gray *       const lGrayrow,
+             pixel *      const rPixelrow,
+             gray *       const rGrayrow,
+             pixel *      const pixelrow,
+             unsigned int const cols,
+             unsigned int const offset) {
+    
+    unsigned int col;
+    gray * lgP;
+    gray * rgP;
+    pixel * pP;
+
+    assert(offset <= cols);
+
+    for (col = 0, pP = pixelrow, lgP = lGrayrow, rgP = rGrayrow;
+         col < cols + offset;
+         ++col) {
+            
+        if (col < offset/2)
+            ++lgP;
+        else if (col >= offset/2 && col < offset) {
+            pixval const blu = (float) *lgP;
+            pixval const red = 0;
+            PPM_ASSIGN(*pP, red, blu, blu);
+            ++lgP;
+            ++pP;
+        } else if (col >= offset && col < cols) {
+            pixval const red = (float) *rgP;
+            pixval const blu = (float) *lgP;
+            PPM_ASSIGN(*pP, red, blu, blu);
+            ++lgP;
+            ++rgP;
+            ++pP;
+        } else if (col >= cols && col < cols + offset/2) {
+            pixval const blu = 0;
+            pixval const red = (float) *rgP;
+            PPM_ASSIGN(*pP, red, blu, blu);
+            ++rgP;
+            ++pP;
+        } else
+            ++rgP;
+    }
+}    
+
+
+
+static void
+write3dRaster(FILE *       const ofP,
+              FILE *       const lIfP,
+              FILE *       const rIfP,
+              unsigned int const cols,
+              unsigned int const rows,
+              pixval       const maxval,
+              int          const lFormat,
+              int          const rFormat,
+              unsigned int const offset) {
+
+    pixel * lPixelrow;
+    gray * lGrayrow;
+    pixel * rPixelrow;
+    gray * rGrayrow;
+    pixel * pixelrow;
+
+    unsigned int row;
+
+    lPixelrow = ppm_allocrow (cols);
+    lGrayrow = pgm_allocrow (cols);
+    rPixelrow = ppm_allocrow (cols);
+    rGrayrow = pgm_allocrow (cols);
+    pixelrow = ppm_allocrow (cols);
+
+    for (row = 0; row < rows; ++row) {
+        ppm_readppmrow(lIfP, lPixelrow, cols, maxval, lFormat);
+        ppm_readppmrow(rIfP, rPixelrow, cols, maxval, rFormat);
+
+        computeGrayscaleRow(lPixelrow, lGrayrow, maxval, cols);
+        computeGrayscaleRow(rPixelrow, rGrayrow, maxval, cols);
+
+        compute3dRow(lPixelrow, lGrayrow, rPixelrow, rGrayrow,
+                     pixelrow, cols, offset);
+
+        ppm_writeppmrow(ofP, pixelrow, cols, maxval, 0);
+    }
+
+    ppm_freerow(pixelrow);
+    pgm_freerow(rGrayrow);
+    ppm_freerow(rPixelrow);
+    pgm_freerow(lGrayrow);
+    ppm_freerow(lPixelrow);
+}
+
+
+
 int
-main (int argc, char *argv[]) {
+main(int argc, char *argv[]) {
+
+    struct cmdlineInfo cmdline;
+    FILE * lIfP;
+    FILE * rIfP;
 
-    int offset; 
-    int cols, rows, row;
-    pixel* pixelrow;
+    int cols, rows;
     pixval maxval;
 
-    FILE* Lifp;
-    pixel* Lpixelrow;
-    gray* Lgrayrow;
-    int Lrows, Lcols, Lformat;
-    pixval Lmaxval;
+    int lRows, lCols;
+    int lFormat;
+    pixval lMaxval;
    
-    FILE* Rifp;
-    pixel* Rpixelrow;
-    gray* Rgrayrow;
-    int Rrows, Rcols, Rformat;
-    pixval Rmaxval;
+    int rRows, rCols;
+    int rFormat;
+    pixval rMaxval;
    
-    ppm_init (&argc, argv);
+    ppm_init(&argc, argv);
 
-    if (argc-1 > 3 || argc-1 < 2) 
-        pm_error("Wrong number of arguments (%d).  Arguments are "
-                 "leftppmfile rightppmfile [horizontal_offset]", argc-1);
+    parseCommandLine(argc, argv, &cmdline);
 
-    Lifp = pm_openr (argv[1]);
-    Rifp = pm_openr (argv[2]);
+    lIfP = pm_openr(cmdline.leftInputFileName);
+    rIfP = pm_openr(cmdline.rghtInputFileName);
 
-    if (argc-1 >= 3) 
-        offset = atoi (argv[3]);
-    else
-        offset = 30;
-
-    ppm_readppminit (Lifp, &Lcols, &Lrows, &Lmaxval, &Lformat);
-    ppm_readppminit (Rifp, &Rcols, &Rrows, &Rmaxval, &Rformat);
+    ppm_readppminit(lIfP, &lCols, &lRows, &lMaxval, &lFormat);
+    ppm_readppminit(rIfP, &rCols, &rRows, &rMaxval, &rFormat);
     
-    if ((Lcols != Rcols) || (Lrows != Rrows) || 
-        (Lmaxval != Rmaxval) || 
-        (PPM_FORMAT_TYPE(Lformat) != PPM_FORMAT_TYPE(Rformat)))
+    if ((lCols != rCols) || (lRows != rRows) || 
+        (lMaxval != rMaxval) || 
+        (PPM_FORMAT_TYPE(lFormat) != PPM_FORMAT_TYPE(rFormat)))
         pm_error ("Pictures are not of same size and format");
     
-    cols = Lcols;
-    rows = Lrows;
-    maxval = Lmaxval;
+    cols   = lCols;
+    rows   = lRows;
+    maxval = lMaxval;
+
+    if (cmdline.offset >= cols)
+        pm_error("Offset (%u columns) is not less than width of images "
+                 "(%u columns)", cmdline.offset, cols);
    
-    ppm_writeppminit (stdout, cols, rows, maxval, 0);
-    Lpixelrow = ppm_allocrow (cols);
-    Lgrayrow = pgm_allocrow (cols);
-    Rpixelrow = ppm_allocrow (cols);
-    Rgrayrow = pgm_allocrow (cols);
-    pixelrow = ppm_allocrow (cols);
+    ppm_writeppminit(stdout, cols, rows, maxval, 0);
 
-    for (row = 0; row < rows; ++row) {
-        ppm_readppmrow(Lifp, Lpixelrow, cols, maxval, Lformat);
-        ppm_readppmrow(Rifp, Rpixelrow, cols, maxval, Rformat);
-
-        computeGrayscaleRow(Lpixelrow, Lgrayrow, maxval, cols);
-        computeGrayscaleRow(Rpixelrow, Rgrayrow, maxval, cols);
-        {
-            int col;
-            gray* LgP;
-            gray* RgP;
-            pixel* pP;
-            for (col = 0, pP = pixelrow, LgP = Lgrayrow, RgP = Rgrayrow;
-                 col < cols + offset;
-                 ++col) {
-            
-                if (col < offset/2)
-                    ++LgP;
-                else if (col >= offset/2 && col < offset) {
-                    const pixval Blue = (pixval) (float) *LgP;
-                    const pixval Red = (pixval) 0;
-                    PPM_ASSIGN (*pP, Red, Blue, Blue);
-                    ++LgP;
-                    ++pP;
-                } else if (col >= offset && col < cols) {
-                    const pixval Red = (pixval) (float) *RgP;
-                    const pixval Blue = (pixval) (float) *LgP;
-                    PPM_ASSIGN (*pP, Red, Blue, Blue);
-                    ++LgP;
-                    ++RgP;
-                    ++pP;
-                } else if (col >= cols && col < cols + offset/2) {
-                    const pixval Blue = (pixval) 0;
-                    const pixval Red = (pixval) (float) *RgP;
-                    PPM_ASSIGN (*pP, Red, Blue, Blue);
-                    ++RgP;
-                    ++pP;
-                } else
-                    ++RgP;
-            }
-        }    
-        ppm_writeppmrow(stdout, pixelrow, cols, maxval, 0);
-    }
+    write3dRaster(stdout, lIfP, rIfP, cols, rows, maxval,
+                  lFormat, rFormat, cmdline.offset);
 
-    pm_close(Lifp);
-    pm_close(Rifp);
+    pm_close(lIfP);
+    pm_close(rIfP);
     pm_close(stdout);
 
     return 0;
 }
+