about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2023-12-05 20:17:29 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2023-12-05 20:17:29 +0000
commit07b3549dc473e90f94997eb9f4fc11ea0bd8758e (patch)
tree3862a706144761dc97184f8237abf8153dae3fce
parent563d2b921e5611e8db9a83a2ddc847e556e5965f (diff)
downloadnetpbm-mirror-07b3549dc473e90f94997eb9f4fc11ea0bd8758e.tar.gz
netpbm-mirror-07b3549dc473e90f94997eb9f4fc11ea0bd8758e.tar.xz
netpbm-mirror-07b3549dc473e90f94997eb9f4fc11ea0bd8758e.zip
Restore ability to have pseudo-plain-PNM with sampels that exceed maxval
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4799 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--doc/HISTORY6
-rw-r--r--editor/pnmconvol.c62
2 files changed, 67 insertions, 1 deletions
diff --git a/doc/HISTORY b/doc/HISTORY
index c06ddd9a..9e3a8bca 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -8,6 +8,12 @@ not yet  BJH  Release 11.05.00
 
               pnmpad: Add -color, -promote, -extend-edge, -detect-background .
 
+              pnmconvol: Restore ability of convolution matrix to be a
+              pseudo-plain-PNM with samples that exceed the maxval.  Lost in
+              10.30 (October 2005) because maxval-checking code was added to
+              libnetpbm.  (Was fixed in 10.47.08 in November 2010, but only in
+              the 10.47 series).
+
               pamtosvg: fix "zero determinant" failure.  Introduced in
               Netpbm 11.04 (September 2023).
 
diff --git a/editor/pnmconvol.c b/editor/pnmconvol.c
index fcd52bea..981797c7 100644
--- a/editor/pnmconvol.c
+++ b/editor/pnmconvol.c
@@ -617,6 +617,64 @@ normalizeKernel(struct ConvKernel * const convKernelP) {
 
 
 static void
+readPseudoPnmKernel(FILE *       const fileP,
+                    struct pam * const pamP,
+                    tuple ***    const tuplesP) {
+/*----------------------------------------------------------------------------
+   Read in the pseudo-PNM that is the convolution matrix.
+
+   This is essentially pnm_readpam(), except that it can take sample values
+   that exceed the maxval, which is not legal in PNM.  That's why it's
+   psuedo-PNM and not true PNM.
+-----------------------------------------------------------------------------*/
+
+    /* pm_getuint() is supposed to be internal to libnetpbm, but since we're
+       doing this backward compatibility hack here, we use it anyway.
+    */
+
+    unsigned int
+    pm_getuint(FILE * const file);
+
+    tuple ** tuples;
+    unsigned int row;
+
+    pnm_readpaminit(fileP, pamP, PAM_STRUCT_SIZE(tuple_type));
+
+    tuples = pnm_allocpamarray(pamP);
+
+    for (row = 0; row < pamP->height; ++row) {
+        if (pamP->format == PGM_FORMAT || pamP->format == PPM_FORMAT) {
+            /* Plain format -- can't use pnm_readpnmrow() because it will
+               reject a sample > maxval
+            */
+            unsigned int col;
+            for (col = 0; col < pamP->width; ++col) {
+                switch (pamP->format) {
+                case PGM_FORMAT:
+                    tuples[row][col][0] = pm_getuint(fileP);
+                    break;
+                case PPM_FORMAT:
+                    tuples[row][col][PAM_RED_PLANE] = pm_getuint(fileP);
+                    tuples[row][col][PAM_GRN_PLANE] = pm_getuint(fileP);
+                    tuples[row][col][PAM_BLU_PLANE] = pm_getuint(fileP);
+                    break;
+                default:
+                    assert(false);
+                }
+            }
+        } else {
+            /* Raw or PBM format -- pnm_readpnmrow() won't do any maxval
+               checking
+            */
+            pnm_readpamrow(pamP, tuples[row]);
+        }
+    }
+    *tuplesP = tuples;
+}
+
+
+
+static void
 getKernelPnm(const char *         const fileName,
              unsigned int         const depth,
              bool                 const offset,
@@ -639,12 +697,14 @@ getKernelPnm(const char *         const fileName,
     cifP = pm_openr(fileName);
 
     /* Read in the convolution matrix. */
-    ctuples = pnm_readpam(cifP, &cpam, PAM_STRUCT_SIZE(tuple_type));
+    readPseudoPnmKernel(cifP, &cpam, &ctuples);
     pm_close(cifP);
 
     validateKernelDimensions(cpam.width, cpam.height);
 
     convKernelCreatePnm(&cpam, ctuples, depth, offset, convKernelPP);
+
+    pnm_freepamarray(ctuples, &cpam);
 }