Add support for reading 16-bit raw PPM files

This should be useful for loading the output of programs such
as dcraw.
This commit is contained in:
Mukund Sivaraman 2011-03-26 15:09:59 +05:30
parent bc8d5f84d6
commit 647f0ada2a

View file

@ -569,10 +569,8 @@ load_image (const gchar *filename,
_("Premature end of file.")); _("Premature end of file."));
pnminfo->maxval = g_ascii_isdigit (*buf) ? atoi (buf) : 0; pnminfo->maxval = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
CHECK_FOR_ERROR (((pnminfo->maxval<=0) CHECK_FOR_ERROR (((pnminfo->maxval<=0) || (pnminfo->maxval>65535)),
|| (pnminfo->maxval>255 && !pnminfo->asciibody)), pnminfo->jmpbuf, _("Unsupported maximum value."));
pnminfo->jmpbuf,
_("Unsupported maximum value."));
} }
/* Create a new image of the proper size and associate the filename with it. /* 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, PNMInfo *info,
GimpPixelRgn *pixel_rgn) GimpPixelRgn *pixel_rgn)
{ {
guchar *data, *d; gint bpc;
guchar *data, *bdata, *d, *b;
gint x, y, i; gint x, y, i;
gint start, end, scanlines; gint start, end, scanlines;
gint fd; 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); fd = pnmscanner_fd (scan);
for (y = 0; y < info->yres; ) for (y = 0; y < info->yres; )
@ -718,34 +727,58 @@ pnm_load_raw (PNMScanner *scan,
end = MIN (end, info->yres); end = MIN (end, info->yres);
scanlines = end - start; scanlines = end - start;
d = data; d = data;
b = bdata;
for (i = 0; i < scanlines; i++) for (i = 0; i < scanlines; i++)
{ {
CHECK_FOR_ERROR ((info->xres * info->np CHECK_FOR_ERROR ((info->xres * info->np * bpc
!= read (fd, d, info->xres * info->np)), != read (fd, d, info->xres * info->np * bpc)),
info->jmpbuf, info->jmpbuf,
_("Premature end of file.")); _("Premature end of file."));
if (info->maxval != 255) /* Normalize if needed */ if (bpc > 1)
{ {
for (x = 0; x < info->xres * info->np; x++) for (x = 0; x < info->xres * info->np; x++)
{ {
d[x] = MIN (d[x], info->maxval); /* guard against overflow */ int v;
d[x] = 255.0 * (gdouble) d[x] / (gdouble) info->maxval;
}
}
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_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; y += scanlines;
} }
gimp_progress_update (1.0); gimp_progress_update (1.0);
g_free (data); g_free (data);
g_free (bdata);
} }
static void static void