[gimp/soc-2011-seamless-clone2] file-fits: add support for high bit depths
- From: Clayton Walker <claytonw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/soc-2011-seamless-clone2] file-fits: add support for high bit depths
- Date: Wed, 8 May 2013 15:01:14 +0000 (UTC)
commit 8e74b2b856444587796b18ea3e3254963c06d6c9
Author: Michael Henning <drawoc darkrefraction com>
Date: Sun Feb 17 18:32:08 2013 -0500
file-fits: add support for high bit depths
plug-ins/file-fits/fits-io.c | 439 +++++++++++++++++++++---------------------
plug-ins/file-fits/fits.c | 106 ++++++++--
2 files changed, 307 insertions(+), 238 deletions(-)
---
diff --git a/plug-ins/file-fits/fits-io.c b/plug-ins/file-fits/fits-io.c
index 5d99904..42d2760 100644
--- a/plug-ins/file-fits/fits-io.c
+++ b/plug-ins/file-fits/fits-io.c
@@ -1970,8 +1970,7 @@ fits_read_pixel (FitsFile *ff,
gdouble datadiff, pixdiff;
guchar pixbuffer[4096];
guchar *pix;
- guchar *cdata;
- guchar creplace;
+ glong creplace;
gint transcount = 0;
glong tdata, tmin, tmax;
gint maxelem;
@@ -1979,8 +1978,8 @@ fits_read_pixel (FitsFile *ff,
if (ff->openmode != 'r')
return -1; /* Not open for reading */
- if (trans->dsttyp != 'c')
- return -1; /* Currently we only return chars */
+ if (trans->dsttyp != 'k')
+ return -1; /* Currently we only return types equavalent to the image format */
if (npix <= 0)
return npix;
@@ -1994,278 +1993,282 @@ fits_read_pixel (FitsFile *ff,
tmin = (glong) trans->datamin;
tmax = (glong) trans->datamax;
- if (tmin < 0)
- tmin = 0;
- else if (tmin > 255)
- tmin = 255;
-
- if (tmax < 0)
- tmax = 0;
- else if (tmax > 255)
- tmax = 255;
-
- cdata = (guchar *) buf;
- creplace = (guchar) trans->replacement;
+ creplace = (glong) trans->replacement;
switch (hdulist->bitpix)
{
case 8:
- while (npix > 0) /* For all pixels to read */
- {
- FitsBitpix8 bp8, bp8blank;
+ {
+ guchar *cdata = (guchar *) buf;
+ while (npix > 0) /* For all pixels to read */
+ {
+ FitsBitpix8 bp8, bp8blank;
- maxelem = sizeof (pixbuffer) / hdulist->bpp;
- if (maxelem > npix)
- maxelem = npix;
+ maxelem = sizeof (pixbuffer) / hdulist->bpp;
+ if (maxelem > npix)
+ maxelem = npix;
- if (fread ((gchar *) pixbuffer, hdulist->bpp,
- maxelem, ff->fp) != maxelem)
- return -1;
+ if (fread ((gchar *) pixbuffer, hdulist->bpp,
+ maxelem, ff->fp) != maxelem)
+ return -1;
- npix -= maxelem;
+ npix -= maxelem;
- pix = pixbuffer;
+ pix = pixbuffer;
- if (hdulist->used.blank)
- {
- bp8blank = (FitsBitpix8) hdulist->blank;
+ if (hdulist->used.blank)
+ {
+ bp8blank = (FitsBitpix8) hdulist->blank;
- while (maxelem--)
- {
- bp8 = (FitsBitpix8) * (pix++);
+ while (maxelem--)
+ {
+ bp8 = (FitsBitpix8) * (pix++);
- if (bp8 == bp8blank) /* Is it a blank pixel ? */
- {
- *(cdata++) = creplace;
- }
- else /* Do transform */
- {
- tdata = (glong) (bp8 * scale + offs);
- tdata = CLAMP (tdata, tmin, tmax);
+ if (bp8 == bp8blank) /* Is it a blank pixel ? */
+ {
+ *(cdata++) = (guchar) creplace;
+ }
+ else /* Do transform */
+ {
+ tdata = (glong) (bp8 * scale + offs);
+ tdata = CLAMP (tdata, tmin, tmax);
- *(cdata++) = (guchar) tdata;
- }
+ *(cdata++) = (guchar) tdata;
+ }
- transcount++;
- }
- }
- else
- {
- while (maxelem--)
- {
- bp8 = (FitsBitpix8) * (pix++);
+ transcount++;
+ }
+ }
+ else
+ {
+ while (maxelem--)
+ {
+ bp8 = (FitsBitpix8) * (pix++);
- tdata = (glong) (bp8 * scale + offs);
- tdata = CLAMP (tdata, tmin, tmax);
+ tdata = (glong) (bp8 * scale + offs);
+ tdata = CLAMP (tdata, tmin, tmax);
- *(cdata++) = (guchar) tdata;
+ *(cdata++) = (guchar) tdata;
- transcount++;
- }
- }
- }
+ transcount++;
+ }
+ }
+ }
+ }
break;
case 16:
- while (npix > 0) /* For all pixels to read */
- {
- FitsBitpix16 bp16, bp16blank;
+ {
+ FitsBitpix16 *cdata = (FitsBitpix16 *) buf;
+ while (npix > 0) /* For all pixels to read */
+ {
+ FitsBitpix16 bp16, bp16blank;
- maxelem = sizeof (pixbuffer) / hdulist->bpp;
- if (maxelem > npix)
- maxelem = npix;
+ maxelem = sizeof (pixbuffer) / hdulist->bpp;
+ if (maxelem > npix)
+ maxelem = npix;
- if (fread ((gchar *) pixbuffer, hdulist->bpp,
- maxelem, ff->fp) != maxelem)
- return -1;
+ if (fread ((gchar *) pixbuffer, hdulist->bpp,
+ maxelem, ff->fp) != maxelem)
+ return -1;
- npix -= maxelem;
+ npix -= maxelem;
- pix = pixbuffer;
- if (hdulist->used.blank)
- {
- bp16blank = (FitsBitpix16) hdulist->blank;
+ pix = pixbuffer;
+ if (hdulist->used.blank)
+ {
+ bp16blank = (FitsBitpix16) hdulist->blank;
- while (maxelem--)
- {
- FITS_GETBITPIX16 (pix, bp16);
-
- if (bp16 == bp16blank)
- {
- *(cdata++) = creplace;
- }
- else
- {
- tdata = (glong) (bp16 * scale + offs);
-
- if (tdata < tmin)
- tdata = tmin;
- else if (tdata > tmax)
- tdata = tmax;
-
- *(cdata++) = (guchar) tdata;
- }
-
- transcount++;
- pix += 2;
- }
- }
- else
- {
- while (maxelem--)
- {
- FITS_GETBITPIX16 (pix, bp16);
+ while (maxelem--)
+ {
+ FITS_GETBITPIX16 (pix, bp16);
+
+ if (bp16 == bp16blank)
+ {
+ *(cdata++) = (FitsBitpix16) creplace;
+ }
+ else
+ {
+ tdata = (glong) (bp16 * scale + offs);
- tdata = (glong) (bp16 * scale + offs);
- if (tdata < tmin)
- tdata = tmin;
- else if (tdata > tmax)
- tdata = tmax;
+ if (tdata < tmin)
+ tdata = tmin;
+ else if (tdata > tmax)
+ tdata = tmax;
- *(cdata++) = (guchar) tdata;
+ *(cdata++) = (FitsBitpix16) tdata;
+ }
- transcount++;
- pix += 2;
- }
- }
- }
+ transcount++;
+ pix += 2;
+ }
+ }
+ else
+ {
+ while (maxelem--)
+ {
+ FITS_GETBITPIX16 (pix, bp16);
+
+ tdata = (glong) (bp16 * scale + offs);
+ if (tdata < tmin)
+ tdata = tmin;
+ else if (tdata > tmax)
+ tdata = tmax;
+
+ *(cdata++) = (FitsBitpix16) tdata;
+
+ transcount++;
+ pix += 2;
+ }
+ }
+ }
+ }
break;
case 32:
- while (npix > 0) /* For all pixels to read */
- {
- FitsBitpix32 bp32, bp32blank;
+ {
+ FitsBitpix32 *cdata = (FitsBitpix32 *) buf;
+ while (npix > 0) /* For all pixels to read */
+ {
+ FitsBitpix32 bp32, bp32blank;
- maxelem = sizeof (pixbuffer) / hdulist->bpp;
- if (maxelem > npix)
- maxelem = npix;
+ maxelem = sizeof (pixbuffer) / hdulist->bpp;
+ if (maxelem > npix)
+ maxelem = npix;
- if (fread ((gchar *) pixbuffer, hdulist->bpp,
- maxelem, ff->fp) != maxelem)
- return -1;
+ if (fread ((gchar *) pixbuffer, hdulist->bpp,
+ maxelem, ff->fp) != maxelem)
+ return -1;
- npix -= maxelem;
+ npix -= maxelem;
- pix = pixbuffer;
- if (hdulist->used.blank)
- {
- bp32blank = (FitsBitpix32) hdulist->blank;
+ pix = pixbuffer;
+ if (hdulist->used.blank)
+ {
+ bp32blank = (FitsBitpix32) hdulist->blank;
- while (maxelem--)
- {
- FITS_GETBITPIX32 (pix, bp32);
-
- if (bp32 == bp32blank)
- {
- *(cdata++) = creplace;
- }
- else
- {
- tdata = (glong) (bp32 * scale + offs);
- if (tdata < tmin)
- tdata = tmin;
- else if (tdata > tmax)
- tdata = tmax;
-
- *(cdata++) = (guchar) tdata;
- }
-
- transcount++;
- pix += 4;
- }
- }
- else
- {
- while (maxelem--)
- {
- FITS_GETBITPIX32 (pix, bp32);
+ while (maxelem--)
+ {
+ FITS_GETBITPIX32 (pix, bp32);
- tdata = (glong) (bp32 * scale + offs);
- tdata = CLAMP (tdata, tmin, tmax);
+ if (bp32 == bp32blank)
+ {
+ *(cdata++) = (FitsBitpix32) creplace;
+ }
+ else
+ {
+ tdata = (glong) (bp32 * scale + offs);
+ if (tdata < tmin)
+ tdata = tmin;
+ else if (tdata > tmax)
+ tdata = tmax;
- *(cdata++) = (guchar) tdata;
+ *(cdata++) = (FitsBitpix32) tdata;
+ }
- transcount++;
- pix += 4;
- }
- }
- }
+ transcount++;
+ pix += 4;
+ }
+ }
+ else
+ {
+ while (maxelem--)
+ {
+ FITS_GETBITPIX32 (pix, bp32);
+
+ tdata = (glong) (bp32 * scale + offs);
+ tdata = CLAMP (tdata, tmin, tmax);
+
+ *(cdata++) = (FitsBitpix32) tdata;
+
+ transcount++;
+ pix += 4;
+ }
+ }
+ }
+ }
break;
case -32:
- while (npix > 0) /* For all pixels to read */
- {
- FitsBitpixM32 bpm32 = 0;
+ {
+ FitsBitpixM32 *cdata = (FitsBitpixM32 *) buf;
+ while (npix > 0) /* For all pixels to read */
+ {
+ FitsBitpixM32 bpm32 = 0;
- maxelem = sizeof (pixbuffer) / hdulist->bpp;
- if (maxelem > npix)
- maxelem = npix;
+ maxelem = sizeof (pixbuffer) / hdulist->bpp;
+ if (maxelem > npix)
+ maxelem = npix;
- if (fread ((gchar *) pixbuffer, hdulist->bpp,
- maxelem, ff->fp) != maxelem)
- return -1;
+ if (fread ((gchar *) pixbuffer, hdulist->bpp,
+ maxelem, ff->fp) != maxelem)
+ return -1;
- npix -= maxelem;
+ npix -= maxelem;
- pix = pixbuffer;
- while (maxelem--)
- {
- if (fits_nan_32 (pix)) /* An IEEE special value ? */
- {
- *(cdata++) = creplace;
- }
- else /* Do transform */
- {
- FITS_GETBITPIXM32 (pix, bpm32);
+ pix = pixbuffer;
+ while (maxelem--)
+ {
+ if (fits_nan_32 (pix)) /* An IEEE special value ? */
+ {
+ *(cdata++) = trans->replacement;
+ }
+ else /* Do transform */
+ {
+ FITS_GETBITPIXM32 (pix, bpm32);
- tdata = (glong) (bpm32 * scale + offs);
- tdata = CLAMP (tdata, tmin, tmax);
+ bpm32 = bpm32 * scale + offs;
+ bpm32 = CLAMP (bpm32, trans->datamin, trans->datamax);
- *(cdata++) = (guchar) tdata;
- }
+ *(cdata++) = bpm32;
+ }
- transcount++;
- pix += 4;
- }
- }
+ transcount++;
+ pix += 4;
+ }
+ }
+ }
break;
case -64:
- while (npix > 0) /* For all pixels to read */
- {
- FitsBitpixM64 bpm64;
+ {
+ FitsBitpixM64 *cdata = (FitsBitpixM64 *) buf;
+ while (npix > 0) /* For all pixels to read */
+ {
+ FitsBitpixM64 bpm64;
- maxelem = sizeof (pixbuffer) / hdulist->bpp;
- if (maxelem > npix)
- maxelem = npix;
+ maxelem = sizeof (pixbuffer) / hdulist->bpp;
+ if (maxelem > npix)
+ maxelem = npix;
- if (fread ((gchar *) pixbuffer, hdulist->bpp,
- maxelem, ff->fp) != maxelem)
- return -1;
+ if (fread ((gchar *) pixbuffer, hdulist->bpp,
+ maxelem, ff->fp) != maxelem)
+ return -1;
- npix -= maxelem;
+ npix -= maxelem;
- pix = pixbuffer;
- while (maxelem--)
- {
- if (fits_nan_64 (pix))
- {
- *(cdata++) = creplace;
- }
- else
- {
- FITS_GETBITPIXM64 (pix, bpm64);
+ pix = pixbuffer;
+ while (maxelem--)
+ {
+ if (fits_nan_64 (pix))
+ {
+ *(cdata++) = trans->replacement;
+ }
+ else
+ {
+ FITS_GETBITPIXM64 (pix, bpm64);
- tdata = (glong) (bpm64 * scale + offs);
- tdata = CLAMP (tdata, tmin, tmax);
+ bpm64 = bpm64 * scale + offs;
+ bpm64 = CLAMP (bpm64, trans->datamin, trans->datamax);
- *(cdata++) = (guchar) tdata;
- }
+ *(cdata++) = bpm64;
+ }
- transcount++;
- pix += 8;
- }
- }
+ transcount++;
+ pix += 8;
+ }
+ }
+ }
break;
}
diff --git a/plug-ins/file-fits/fits.c b/plug-ins/file-fits/fits.c
index 43e8a90..fd82530 100644
--- a/plug-ins/file-fits/fits.c
+++ b/plug-ins/file-fits/fits.c
@@ -94,6 +94,7 @@ static gint32 create_new_image (const gchar *filename,
guint height,
GimpImageBaseType itype,
GimpImageType dtype,
+ GimpPrecision iprecision,
gint32 *layer_ID,
GeglBuffer **buffer);
@@ -502,13 +503,15 @@ create_new_image (const gchar *filename,
guint height,
GimpImageBaseType itype,
GimpImageType dtype,
+ GimpPrecision iprecision,
gint32 *layer_ID,
GeglBuffer **buffer)
{
gint32 image_ID;
char *tmp;
- image_ID = gimp_image_new (width, height, itype);
+ image_ID = gimp_image_new_with_precision (width, height, itype, iprecision);
+
if ((tmp = g_malloc (strlen (filename) + 64)) != NULL)
{
sprintf (tmp, "%s-img%ld", filename, (long)pagenum);
@@ -548,9 +551,12 @@ load_fits (const gchar *filename,
GeglBuffer *buffer;
GimpImageBaseType itype;
GimpImageType dtype;
+ GimpPrecision iprecision;
gint err = 0;
FitsHduList *hdulist;
FitsPixTransform trans;
+ double datamax, replacetransform;
+ const Babl *type, *format;
hdulist = fits_seek_image (ifp, (int)picnum);
if (hdulist == NULL)
@@ -559,38 +565,96 @@ load_fits (const gchar *filename,
width = hdulist->naxisn[0]; /* Set the size of the FITS image */
height = hdulist->naxisn[1];
+ switch (hdulist->bitpix)
+ {
+ case 8:
+ iprecision = GIMP_PRECISION_U8;
+ type = babl_type ("u8");
+ datamax = 255.0;
+ replacetransform = 1.0;
+ break;
+ case 16:
+ iprecision = GIMP_PRECISION_U16;
+ type = babl_type ("u16");
+ datamax = 65535.0;
+ replacetransform = 257;
+ break;
+ case 32:
+ iprecision = GIMP_PRECISION_U32;
+ type = babl_type ("u32");
+ datamax = 4294967295.0;
+ replacetransform = 16843009;
+ break;
+ case -32:
+ iprecision = GIMP_PRECISION_FLOAT;
+ type = babl_type ("float");
+ datamax = 1.0;
+ replacetransform = 1.0 / 255.0;
+ break;
+ case -64:
+ iprecision = GIMP_PRECISION_FLOAT;
+ type = babl_type ("double");
+ datamax = 1.0;
+ replacetransform = 1.0 / 255.0;
+ break;
+ default:
+ return -1;
+ }
+
if (ncompose == 2)
{
itype = GIMP_GRAY;
dtype = GIMP_GRAYA_IMAGE;
+ format = babl_format_new (babl_model ("Y'A"),
+ type,
+ babl_component ("Y'"),
+ babl_component ("A"),
+ NULL);
}
else if (ncompose == 3)
{
itype = GIMP_RGB;
dtype = GIMP_RGB_IMAGE;
+ format = babl_format_new (babl_model ("R'G'B'"),
+ type,
+ babl_component ("R'"),
+ babl_component ("G'"),
+ babl_component ("B'"),
+ NULL);
}
else if (ncompose == 4)
{
itype = GIMP_RGB;
dtype = GIMP_RGBA_IMAGE;
+ format = babl_format_new (babl_model ("R'G'B'A"),
+ type,
+ babl_component ("R'"),
+ babl_component ("G'"),
+ babl_component ("B'"),
+ babl_component ("A"),
+ NULL);
}
else
{
ncompose = 1;
itype = GIMP_GRAY;
dtype = GIMP_GRAY_IMAGE;
+ format = babl_format_new (babl_model ("Y'"),
+ type,
+ babl_component ("Y'"),
+ NULL);
}
- image_ID = create_new_image (filename, picnum, width, height, itype, dtype,
+ image_ID = create_new_image (filename, picnum, width, height, itype, dtype, iprecision,
&layer_ID, &buffer);
tile_height = gimp_tile_height ();
- data = g_malloc (tile_height * width * ncompose);
+ data = g_malloc (tile_height * width * ncompose * hdulist->bpp);
if (data == NULL)
return -1;
- data_end = data + tile_height * width * ncompose;
+ data_end = data + tile_height * width * ncompose * hdulist->bpp;
/* If the transformation from pixel value to data value has been
* specified, use it
@@ -614,9 +678,9 @@ load_fits (const gchar *filename,
}
trans.datamin = 0.0;
- trans.datamax = 255.0;
- trans.replacement = plvals.replace;
- trans.dsttyp = 'c';
+ trans.datamax = datamax;
+ trans.replacement = plvals.replace * replacetransform;
+ trans.dsttyp = 'k';
/* FITS stores images with bottom row first. Therefore we have to
* fill the image from bottom to top.
@@ -624,13 +688,13 @@ load_fits (const gchar *filename,
if (ncompose == 1)
{
- dest = data + tile_height * width;
+ dest = data + tile_height * width * hdulist->bpp;
scan_lines = 0;
for (i = 0; i < height; i++)
{
/* Read FITS line */
- dest -= width;
+ dest -= width * hdulist->bpp;
if (fits_read_pixel (ifp, hdulist, width, &trans, dest) != width)
{
err = 1;
@@ -647,27 +711,28 @@ load_fits (const gchar *filename,
gegl_buffer_set (buffer,
GEGL_RECTANGLE (0, height - i - 1,
width, scan_lines), 0,
- NULL, dest, GEGL_AUTO_ROWSTRIDE);
+ format, dest, GEGL_AUTO_ROWSTRIDE);
scan_lines = 0;
- dest = data + tile_height * width;
+ dest = data + tile_height * width * hdulist->bpp;
}
if (err)
break;
}
}
+ /* XXX: Needs to be ported to high bit depths */
else /* multiple images to compose */
{
gint channel;
- linebuf = g_malloc (width);
+ linebuf = g_malloc (width * hdulist->bpp);
if (linebuf == NULL)
return -1;
for (channel = 0; channel < ncompose; channel++)
{
- dest = data + tile_height * width * ncompose + channel;
+ dest = data + tile_height * width * hdulist->bpp * ncompose + channel;
scan_lines = 0;
for (i = 0; i < height; i++)
@@ -683,12 +748,12 @@ load_fits (const gchar *filename,
gegl_buffer_get (buffer,
GEGL_RECTANGLE (0, height - i - max_scan,
width, max_scan), 1.0,
- NULL, data_end - max_scan * width * ncompose,
+ format, data_end - max_scan * width * hdulist->bpp * ncompose,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
}
/* Read FITS scanline */
- dest -= width * ncompose;
+ dest -= width * ncompose * hdulist->bpp;
if (fits_read_pixel (ifp, hdulist, width, &trans, linebuf) != width)
{
err = 1;
@@ -698,10 +763,11 @@ load_fits (const gchar *filename,
src = linebuf;
while (j--)
{
- *dest = *(src++);
- dest += ncompose;
+ memcpy (dest, src, hdulist->bpp);
+ src += hdulist->bpp;
+ dest += ncompose * hdulist->bpp;
}
- dest -= width * ncompose;
+ dest -= width * ncompose * hdulist->bpp;
scan_lines++;
if ((i % 20) == 0)
@@ -713,10 +779,10 @@ load_fits (const gchar *filename,
gegl_buffer_set (buffer,
GEGL_RECTANGLE (0, height - i - 1,
width, scan_lines), 0,
- NULL, dest - channel, GEGL_AUTO_ROWSTRIDE);
+ format, dest - channel * hdulist->bpp, GEGL_AUTO_ROWSTRIDE);
scan_lines = 0;
- dest = data + tile_height * width * ncompose + channel;
+ dest = data + tile_height * width * ncompose * hdulist->bpp + channel * hdulist->bpp;
}
if (err)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]