about summary refs log tree commit diff
path: root/editor/ppm3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/ppm3d.c')
-rw-r--r--editor/ppm3d.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/editor/ppm3d.c b/editor/ppm3d.c
new file mode 100644
index 00000000..c37ceeb1
--- /dev/null
+++ b/editor/ppm3d.c
@@ -0,0 +1,138 @@
+/* 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.
+*/
+
+#include "ppm.h"
+#include "lum.h"
+
+static void
+computeGrayscaleRow(const pixel * const inputRow,
+                    gray *        const outputRow,
+                    pixval        const maxval,
+                    unsigned int  const cols) {
+
+    if (maxval <= 255) {
+        unsigned int col;
+        /* Use fast approximation to 0.299 r + 0.587 g + 0.114 b. */
+        for (col = 0; col < cols; ++col)
+            outputRow[col] = ppm_fastlumin(inputRow[col]);
+    } else {
+        unsigned int col;
+        /* Can't use fast approximation, so fall back on floats. */
+        for (col = 0; col < cols; ++col)
+            outputRow[col] = PPM_LUMIN(inputRow[col]) + 0.5;
+    }
+}
+
+
+
+int
+main (int argc, char *argv[]) {
+
+    int offset; 
+    int cols, rows, row;
+    pixel* pixelrow;
+    pixval maxval;
+
+    FILE* Lifp;
+    pixel* Lpixelrow;
+    gray* Lgrayrow;
+    int Lrows, Lcols, Lformat;
+    pixval Lmaxval;
+   
+    FILE* Rifp;
+    pixel* Rpixelrow;
+    gray* Rgrayrow;
+    int Rrows, Rcols, Rformat;
+    pixval Rmaxval;
+   
+    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);
+
+    Lifp = pm_openr (argv[1]);
+    Rifp = pm_openr (argv[2]);
+
+    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);
+    
+    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;
+   
+    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);
+
+    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);
+    }
+
+    pm_close(Lifp);
+    pm_close(Rifp);
+    pm_close(stdout);
+
+    return 0;
+}