[gimp] Add support for reading 16-bit raw PPM files



commit 647f0ada2af7b91c7b5110b46a0230cd3f79f112
Author: Mukund Sivaraman <muks banu com>
Date:   Sat Mar 26 15:09:59 2011 +0530

    Add support for reading 16-bit raw PPM files
    
    This should be useful for loading the output of programs such
    as dcraw.

 plug-ins/common/file-pnm.c |   59 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 46 insertions(+), 13 deletions(-)
---
diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c
index cf1d94a..e85cdab 100644
--- a/plug-ins/common/file-pnm.c
+++ b/plug-ins/common/file-pnm.c
@@ -569,10 +569,8 @@ load_image (const gchar  *filename,
                        _("Premature end of file."));
 
       pnminfo->maxval = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
-      CHECK_FOR_ERROR (((pnminfo->maxval<=0)
-                        || (pnminfo->maxval>255 && !pnminfo->asciibody)),
-                       pnminfo->jmpbuf,
-                       _("Unsupported maximum value."));
+      CHECK_FOR_ERROR (((pnminfo->maxval<=0) || (pnminfo->maxval>65535)),
+                       pnminfo->jmpbuf, _("Unsupported maximum value."));
     }
 
   /* Create a new image of the proper size and associate the filename with it.
@@ -703,12 +701,23 @@ pnm_load_raw (PNMScanner   *scan,
               PNMInfo      *info,
               GimpPixelRgn *pixel_rgn)
 {
-  guchar *data, *d;
+  gint    bpc;
+  guchar *data, *bdata, *d, *b;
   gint    x, y, i;
   gint    start, end, scanlines;
   gint    fd;
 
-  data = g_new (guchar, gimp_tile_height () * info->xres * info->np);
+  if (info->maxval > 255)
+    bpc = 2;
+  else
+    bpc = 1;
+
+  data = g_new (guchar, gimp_tile_height () * info->xres * info->np * bpc);
+
+  bdata = NULL;
+  if (bpc > 1)
+    bdata = g_new (guchar, gimp_tile_height () * info->xres * info->np);
+
   fd = pnmscanner_fd (scan);
 
   for (y = 0; y < info->yres; )
@@ -718,34 +727,58 @@ pnm_load_raw (PNMScanner   *scan,
       end = MIN (end, info->yres);
       scanlines = end - start;
       d = data;
+      b = bdata;
 
       for (i = 0; i < scanlines; i++)
         {
-          CHECK_FOR_ERROR ((info->xres * info->np
-                            != read (fd, d, info->xres * info->np)),
+          CHECK_FOR_ERROR ((info->xres * info->np * bpc
+                            != read (fd, d, info->xres * info->np * bpc)),
                            info->jmpbuf,
                            _("Premature end of file."));
 
-          if (info->maxval != 255)      /* Normalize if needed */
+          if (bpc > 1)
             {
               for (x = 0; x < info->xres * info->np; x++)
                 {
-                  d[x] = MIN (d[x], info->maxval); /* guard against overflow */
-                  d[x] = 255.0 * (gdouble) d[x] / (gdouble) info->maxval;
+                  int v;
+
+                  v = *d++ << 8;
+                  v += *d++;
+
+                  b[x] = MIN (v, info->maxval); /* guard against overflow */
+                  b[x] = 255.0 * (gdouble) v / (gdouble) info->maxval;
                 }
+              b += info->xres * info->np;
             }
+          else
+            {
+              if (info->maxval != 255)      /* Normalize if needed */
+                {
+                  for (x = 0; x < info->xres * info->np; x++)
+                    {
+                      d[x] = MIN (d[x], info->maxval); /* guard against overflow */
+                      d[x] = 255.0 * (gdouble) d[x] / (gdouble) info->maxval;
+                    }
+                }
 
-          d += info->xres * info->np;
+              d += info->xres * info->np;
+            }
         }
 
       gimp_progress_update ((double) y / (double) info->yres);
-      gimp_pixel_rgn_set_rect (pixel_rgn, data, 0, y, info->xres, scanlines);
+
+      if (bpc > 1)
+        gimp_pixel_rgn_set_rect (pixel_rgn, bdata, 0, y, info->xres, scanlines);
+      else
+        gimp_pixel_rgn_set_rect (pixel_rgn, data, 0, y, info->xres, scanlines);
+
       y += scanlines;
     }
 
   gimp_progress_update (1.0);
 
   g_free (data);
+  g_free (bdata);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]