diff --git a/plug-ins/common/file-pnm.c b/plug-ins/common/file-pnm.c index cf1d94ada9..e85cdab020 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; - d += info->xres * info->np; + 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; + } } 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