about summary refs log tree commit diff
path: root/editor/specialty/ppmrelief.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-02-09 04:07:18 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2014-02-09 04:07:18 +0000
commit6df52cf3846ae2afe8c3b633cd28126937311e90 (patch)
tree286fa9c80b3fe89f3df6196ff0021725848f87ff /editor/specialty/ppmrelief.c
parent9ac8b572b9055563a26f4275defb9e8d4e4d6734 (diff)
downloadnetpbm-mirror-6df52cf3846ae2afe8c3b633cd28126937311e90.tar.gz
netpbm-mirror-6df52cf3846ae2afe8c3b633cd28126937311e90.tar.xz
netpbm-mirror-6df52cf3846ae2afe8c3b633cd28126937311e90.zip
clip output values to 0..maxval; detect too-small input
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2121 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor/specialty/ppmrelief.c')
-rw-r--r--editor/specialty/ppmrelief.c116
1 files changed, 70 insertions, 46 deletions
diff --git a/editor/specialty/ppmrelief.c b/editor/specialty/ppmrelief.c
index 5e0669c3..14a6d0a8 100644
--- a/editor/specialty/ppmrelief.c
+++ b/editor/specialty/ppmrelief.c
@@ -1,4 +1,4 @@
-/* ppmrelief.c - generate a relief map of a portable pixmap
+/* ppmrelief.c - generate a relief map of a PPM image
 **
 ** Copyright (C) 1990 by Wilson H. Bent, Jr.
 **
@@ -11,80 +11,104 @@
 */
 
 #include <stdio.h>
+
+#include "pm_c_util.h"
 #include "ppm.h"
 
+
+
+static pixval
+clip(int    const p,
+     pixval const maxval) {
+
+    return MAX(0, MIN(maxval, p));
+}
+
+
+
 int
-main(int argc, char * argv[]) {
-
-    FILE* ifp;
-    pixel** inputbuf;
-    pixel* outputrow;
-    int argn, rows, cols, format, row;
-    register int col;
-    pixval maxval, mv2;
+main(int argc, const char * argv[]) {
+
+    FILE * ifP;
+    pixel ** inputbuf;
+    pixel * outputrow;
+    int argn, format, rows, cols;
+    unsigned int row, col;
+    pixval maxval;
     const char* const usage = "[ppmfile]";
 
-    ppm_init( &argc, argv );
+    pm_proginit(&argc, argv);
 
     argn = 1;
 
     if ( argn != argc ) {
-        ifp = pm_openr( argv[argn] );
+        ifP = pm_openr( argv[argn] );
         ++argn;
     } else
-        ifp = stdin;
+        ifP = stdin;
 
     if ( argn != argc )
         pm_usage( usage );
-    
-    ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
-    mv2 = maxval / 2;
+
+    ppm_readppminit(ifP, &cols, &rows, &maxval, &format );
+
+    if (cols < 3 || rows < 3 )
+        pm_error("Input image too small: %u x %u.  Must be at least 3x3",
+                  cols, rows);
 
     /* Allocate space for 3 input rows, plus an output row. */
-    inputbuf = ppm_allocarray( cols, 3 );
-    outputrow = ppm_allocrow( cols );
+    inputbuf  = ppm_allocarray(cols, 3);
+    outputrow = ppm_allocrow(cols);
 
-    ppm_writeppminit( stdout, cols, rows, maxval, 0 );
+    ppm_writeppminit(stdout, cols, rows, maxval, 0);
 
     /* Read in the first two rows. */
-    ppm_readppmrow( ifp, inputbuf[0], cols, maxval, format );
-    ppm_readppmrow( ifp, inputbuf[1], cols, maxval, format );
+    ppm_readppmrow(ifP, inputbuf[0], cols, maxval, format);
+    ppm_readppmrow(ifP, inputbuf[1], cols, maxval, format);
 
     /* Write out the first row, all zeros. */
-    for ( col = 0; col < cols; ++col )
+    for (col = 0; col < cols; ++col)
         PPM_ASSIGN( outputrow[col], 0, 0, 0 );
-    ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 );
+
+    ppm_writeppmrow(stdout, outputrow, cols, maxval, 0);
 
     /* Now the rest of the image - read in the 3rd row of inputbuf,
-    ** and convolve with the first row into the output buffer.
+       and convolve with the first row into the output buffer.
     */
-    for ( row = 2 ; row < rows; ++row ) {
-        pixval r, g, b;
-        int rowa, rowb;
-
-        rowa = row % 3;
-        rowb = (row + 2) % 3;
-        ppm_readppmrow( ifp, inputbuf[rowa], cols, maxval, format );
-        
-        for ( col = 0; col < cols - 2; ++col ) {
-            r = PPM_GETR( inputbuf[rowa][col] ) +
-                ( mv2 - PPM_GETR( inputbuf[rowb][col + 2] ) );
-            g = PPM_GETG( inputbuf[rowa][col] ) +
-                ( mv2 - PPM_GETG( inputbuf[rowb][col + 2] ) );
-            b = PPM_GETB( inputbuf[rowa][col] ) +
-                ( mv2 - PPM_GETB( inputbuf[rowb][col + 2] ) );
-            PPM_ASSIGN( outputrow[col + 1], r, g, b );
+    for (row = 2 ; row < rows; ++row) {
+        pixval       const mv2 = maxval / 2;
+        unsigned int const rowa = row % 3;
+        unsigned int const rowb = (rowa + 2) % 3;
+
+        ppm_readppmrow(ifP, inputbuf[rowa], cols, maxval, format);
+
+        for (col = 0; col < cols - 2; ++col) {
+            pixel const inputA = inputbuf[rowa][col];
+            pixel const inputB = inputbuf[rowb][col + 2];
+            
+            pixval const r =
+                clip(PPM_GETR(inputA) + (mv2 - PPM_GETR(inputB)), maxval);
+            pixval const g =
+                clip(PPM_GETG(inputA) + (mv2 - PPM_GETG(inputB)), maxval);
+            pixval const b =
+                clip(PPM_GETB(inputA) + (mv2 - PPM_GETB(inputB)), maxval);
+
+            PPM_ASSIGN(outputrow[col + 1], r, g, b);
         }
-        ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 );
+        ppm_writeppmrow(stdout, outputrow, cols, maxval, 0);
     }
 
     /* And write the last row, zeros again. */
-    for ( col = 0; col < cols; ++col )
-        PPM_ASSIGN( outputrow[col], 0, 0, 0 );
-    ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 );
+    for (col = 0; col < cols; ++col)
+        PPM_ASSIGN(outputrow[col], 0, 0, 0);
+
+    ppm_writeppmrow(stdout, outputrow, cols, maxval, 0);
+
+    ppm_freerow(outputrow);
+    ppm_freearray(inputbuf, 3);
 
-    pm_close( ifp );
-    pm_close( stdout );
+    pm_close(ifP);
+    pm_close(stdout);
 
-    exit( 0 );
+    return 0;
 }