/*** File wcslib/imio.c *** October 30, 2012 *** By Jessica Mink, jmink@cfa.harvard.edu *** Harvard-Smithsonian Center for Astrophysics *** Copyright (C) 1996-2012 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Correspondence concerning WCSTools should be addressed as follows: Internet email: jmink@cfa.harvard.edu Postal address: Jessica Mink Smithsonian Astrophysical Observatory 60 Garden St. Cambridge, MA 02138 USA * Module: imio.c (image pixel manipulation) * Purpose: Read and write pixels from arbitrary data type 2D arrays * Subroutine: getpix (image, bitpix, w, h, bz, bs, x, y) * Read pixel from 2D image of any numeric type (0,0 lower left) * Subroutine: getpix1 (image, bitpix, w, h, bz, bs, x, y) * Read pixel from 2D image of any numeric type (1,1 lower left) * Subroutine: putpix (image, bitpix, w, h, bz, bs, x, y, dpix) * Write pixel into 2D image of any numeric type (0,0 lower left) * Subroutine: putpix1 (image, bitpix, w, h, bz, bs, x, y, dpix) * Write pixel into 2D image of any numeric type (1,1 lower left) * Subroutine: addpix (image, bitpix, w, h, bz, bs, x, y, dpix) * Copy pixel into 2D image of any numeric type (0,0 lower left) * Subroutine: addpix1 (image, bitpix, w, h, bz, bs, x, y, dpix) * Add pixel into 2D image of any numeric type (1,1 lower left) * Subroutine: maxvec (image, bitpix, bz, bs, pix1, npix) * Get maximum of vector from 2D image of any numeric type * Subroutine: minvec (image, bitpix, bz, bs, pix1, npix) * Get minimum of vector from 2D image of any numeric type * Subroutine: getvec (image, bitpix, bz, bs, pix1, npix, dvec) * Get vector from 2D image of any numeric type * Subroutine: putvec (image, bitpix, bz, bs, pix1, npix, dvec) * Copy pixel vector into a vector of any numeric type * Subroutine: addvec (image, bitpix, bz, bs, pix1, npix, dpix) * Add constant to pixel values in a vector * Subroutine: multvec (image, bitpix, bz, bs, pix1, npix, dpix) * Multiply pixel values in a vector by a constant * Subroutine: fillvec (image, bitpix, bz, bs, pix1, npix, dpix) * Copy pixel value in a vector of any numeric type * Subroutine: fillvec1 (image, bitpix, bz, bs, pix1, npix, dpix) * Copy pixel value int a vector of any numeric type * Subroutine: movepix (image1, bitpix, w1, x1, y1, image2, w2, x2, y2) * Copy pixel from one image location to another * Subroutine: imswap (bitpix,string,nbytes) * Swap bytes in string in place, with FITS bits/pixel code * Subroutine: imswap2 (string,nbytes) * Swap bytes in string in place * Subroutine imswap4 (string,nbytes) * Reverse bytes of Integer*4 or Real*4 vector in place * Subroutine imswap8 (string,nbytes) * Reverse bytes of Real*8 vector in place * Subroutine imswapped () * Return 1 if PC/DEC byte order, else 0 */ #include #include #include "fitsfile.h" static int scale = 1; /* If 0, skip scaling step */ void setscale (scale0) int scale0; {scale = scale0; return;} /* GETPIX1 -- Get pixel from 2D FITS image of any numeric type */ double getpix1 (image, bitpix, w, h, bzero, bscale, x, y) char *image; /* Image array as 1-D vector */ int bitpix; /* FITS bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ { return (getpix (image, bitpix, w, h, bzero, bscale, x-1, y-1)); } /* GETPIX -- Get pixel from 2D image of any numeric type */ double getpix (image, bitpix, w, h, bzero, bscale, x, y) char *image; /* Image array as 1-D vector */ int bitpix; /* FITS bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* Zero-based horizontal pixel number */ int y; /* Zero-based vertical pixel number */ { short *im2; int *im4; unsigned char *im1; unsigned short *imu; float *imr; double *imd; double dpix; /* Return 0 if coordinates are not inside image */ if (x < 0 || x >= w) return (0.0); if (y < 0 || y >= h) return (0.0); /* Extract pixel from appropriate type of array */ switch (bitpix) { case 8: im1 = (unsigned char *)image; dpix = (double) im1[(y*w) + x]; break; case 16: im2 = (short *)image; dpix = (double) im2[(y*w) + x]; break; case 32: im4 = (int *)image; dpix = (double) im4[(y*w) + x]; break; case -16: imu = (unsigned short *)image; dpix = (double) imu[(y*w) + x]; break; case -32: imr = (float *)image; dpix = (double) imr[(y*w) + x]; break; case -64: imd = (double *)image; dpix = imd[(y*w) + x]; break; default: dpix = 0.0; } if (scale) return (bzero + (bscale * dpix)); else return (dpix); } /* PUTPIX1 -- Copy pixel into 2D FITS image of any numeric type */ void putpix1 (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ double dpix; { putpix (image, bitpix, w, h, bzero, bscale, x-1, y-1, dpix); return; } /* PUTPIX -- Copy pixel into 2D image of any numeric type */ void putpix (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; int y; double dpix; { double *imd; float *imr; int *im4; short *im2; unsigned short *imu; unsigned char *im1; /* Return if coordinates are not inside image */ if (x < 0 || x >= w) return; if (y < 0 || y >= h) return; if (scale) dpix = (dpix - bzero) / bscale; switch (bitpix) { case 8: im1 = (unsigned char *)image; if (dpix < 0) im1[(y*w) + x] = (unsigned char) (dpix - 0.5); else im1[(y*w) + x] = (unsigned char) (dpix + 0.5); break; case 16: im2 = (short *)image; if (dpix < 0) im2[(y*w) + x] = (short) (dpix - 0.5); else im2[(y*w) + x] = (short) (dpix + 0.5); break; case 32: im4 = (int *)image; if (dpix < 0) im4[(y*w) + x] = (int) (dpix - 0.5); else im4[(y*w) + x] = (int) (dpix + 0.5); break; case -16: imu = (unsigned short *)image; if (dpix < 0) imu[(y*w) + x] = (unsigned short) 0; else imu[(y*w) + x] = (unsigned short) (dpix + 0.5); break; case -32: imr = (float *)image; imr[(y*w) + x] = (float) dpix; break; case -64: imd = (double *)image; imd[(y*w) + x] = dpix; break; } return; } /* ADDPIX1 -- Add pixel value into 2D FITS image of any numeric type */ void addpix1 (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* One-based horizontal pixel number */ int y; /* One-based vertical pixel number */ double dpix; /* Value to add to pixel */ { addpix (image, bitpix, w, h, bzero, bscale, x-1, y-1, dpix); return; } /* ADDPIX -- Add constant to pixel values in 2D image of any numeric type */ void addpix (image, bitpix, w, h, bzero, bscale, x, y, dpix) char *image; int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w; /* Image width in pixels */ int h; /* Image height in pixels */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int x; /* Zero-based horizontal pixel number */ int y; /* Zero-based vertical pixel number */ double dpix; /* Value to add to pixel */ { double *imd; float *imr; int *im4; short *im2; unsigned short *imu; unsigned char *im1; int ipix; /* Return if coordinates are not inside image */ if (x < 0 || x >= w) return; if (y < 0 || y >= h) return; if (scale) dpix = (dpix - bzero) / bscale; ipix = (y * w) + x; switch (bitpix) { case 8: im1 = (unsigned char *)image; if (dpix < 0) image[ipix] = im1[ipix] + (unsigned char) (dpix - 0.5); else image[ipix] = im1[ipix] + (unsigned char) (dpix + 0.5); break; case 16: im2 = (short *)image; if (dpix < 0) im2[ipix] = im2[ipix] + (short) (dpix - 0.5); else im2[ipix] = im2[ipix] + (short) (dpix + 0.5); break; case 32: im4 = (int *)image; if (dpix < 0) im4[ipix] = im4[ipix] + (int) (dpix - 0.5); else im4[ipix] = im4[ipix] + (int) (dpix + 0.5); break; case -16: imu = (unsigned short *)image; if (dpix > 0) imu[ipix] = imu[ipix] + (unsigned short) (dpix + 0.5); break; case -32: imr = (float *)image; imr[ipix] = imr[ipix] + (float) dpix; break; case -64: imd = (double *)image; imd[ipix] = imd[ipix] + dpix; break; } return; } /* MOVEPIX -- Copy pixel between images */ void movepix (image1, bitpix1, w1, x1, y1, image2, bitpix2, w2, x2, y2) char *image1; /* Pointer to first pixel in input image */ int bitpix1; /* Bits per input pixel (FITS codes) */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w1; /* Number of horizontal pixels in input image */ int x1, y1; /* Row and column for input pixel */ char *image2; /* Pointer to first pixel in output image */ int bitpix2; /* Bits per output pixel (FITS codes) */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ int w2; /* Number of horizontal pixels in output image */ int x2, y2; /* Row and column for output pixel */ { double dpix, *imd1, *imd2; float rpix, *imr1, *imr2; int *imi1, *imi2; short *ims1, *ims2; unsigned short *imu1, *imu2; unsigned char *imc1, *imc2; if (x1 < 0 || x2 < 0 || x1 >= w1 || x2 >= w2) return; if (y1 < 0 || y2 < 0) return; switch (bitpix1) { case 8: imc1 = (unsigned char *)image1; switch (bitpix2) { case 8: imc2 = (unsigned char *)image2; imc2[(y2*w2) + x2] = imc1[(y1*w1) + x1]; break; case 16: ims2 = (short *)image2; ims2[(y2*w2) + x2] = (short) imc1[(y1*w1) + x1]; break; case 32: imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) imc1[(y1*w1) + x1]; break; case -16: imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) imc1[(y1*w1) + x1]; break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) imc1[(y1*w1) + x1]; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) imc1[(y1*w1) + x1]; break; } break; case 16: ims1 = (short *)image1; switch (bitpix2) { case 8: imc2 = (unsigned char *)image1; imc2[(y2*w2) + x2] = (unsigned char) ims1[(y1*w1) + x1]; break; case 16: ims2 = (short *)image2; ims2[(y2*w2) + x2] = ims1[(y1*w1) + x1]; break; case 32: imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) ims1[(y1*w1) + x1]; break; case -16: imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) ims1[(y1*w1) + x1]; break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) ims1[(y1*w1) + x1]; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) ims1[(y1*w1) + x1]; break; } break; case 32: imi1 = (int *)image1; switch (bitpix2) { case 8: imc2 = (unsigned char *)image2; imc2[(y2*w2) + x2] = (unsigned char) imi1[(y1*w1) + x1]; break; case 16: ims2 = (short *)image2; ims2[(y2*w2) + x2] = (short) imi1[(y1*w1) + x1]; break; case 32: imi2 = (int *)image2; imi2[(y2*w2) + x2] = imi1[(y1*w1) + x1]; break; case -16: imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = (unsigned short) imi1[(y1*w1) + x1]; break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) imi1[(y1*w1) + x1]; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) imi1[(y1*w1) + x1]; break; } break; case -16: imu1 = (unsigned short *)image1; switch (bitpix2) { case 8: imc2 = (unsigned char *)image2; imc2[(y2*w2) + x2] = (unsigned char) imu1[(y1*w1) + x1]; break; case 16: ims2 = (short *)image2; ims2[(y2*w2) + x2] = (short) imu1[(y1*w1) + x1]; break; case 32: imi2 = (int *)image2; imi2[(y2*w2) + x2] = (int) imu1[(y1*w1) + x1]; break; case -16: imu2 = (unsigned short *)image2; imu2[(y2*w2) + x2] = imu1[(y1*w1) + x1]; break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) imu1[(y1*w1) + x1]; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) imu1[(y1*w1) + x1]; break; } break; case -32: imr1 = (float *)image1; rpix = imr1[(y1*w1) + x1]; switch (bitpix2) { case 8: imc2 = (unsigned char *)image2; if (rpix < 0.0) imc2[(y2*w2) + x2] = (unsigned char) 0; else imc2[(y2*w2) + x2] = (unsigned char) (rpix + 0.5); break; case 16: ims2 = (short *)image2; if (rpix < 0.0) ims2[(y2*w2) + x2] = (short) (rpix - 0.5); else ims2[(y2*w2) + x2] = (short) (rpix + 0.5); break; case 32: imi2 = (int *)image2; if (rpix < 0.0) imi2[(y2*w2) + x2] = (int) (rpix - 0.5); else imi2[(y2*w2) + x2] = (int) (rpix + 0.5); break; case -16: imu2 = (unsigned short *)image2; if (rpix < 0.0) imu2[(y2*w2) + x2] = (unsigned short) 0; else imu2[(y2*w2) + x2] = (unsigned short) (rpix + 0.5); break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = rpix; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = (double) rpix; break; } break; case -64: imd1 = (double *)image1; dpix = imd1[(y1*w1) + x1]; switch (bitpix2) { case 8: imc2 = (unsigned char *)image2; if (dpix < 0.0) imc2[(y2*w2) + x2] = (unsigned char) 0; else imc2[(y2*w2) + x2] = (unsigned char) (dpix + 0.5); break; case 16: ims2 = (short *)image2; if (dpix < 0.0) ims2[(y2*w2) + x2] = (short) (dpix - 0.5); else ims2[(y2*w2) + x2] = (short) (dpix + 0.5); break; case 32: imi2 = (int *)image2; if (dpix < 0.0) imi2[(y2*w2) + x2] = (int) (dpix - 0.5); else imi2[(y2*w2) + x2] = (int) (dpix + 0.5); break; case -16: imu2 = (unsigned short *)image2; if (dpix < 0.0) imu2[(y2*w2) + x2] = (unsigned short) 0; else imu2[(y2*w2) + x2] = (unsigned short) (dpix + 0.5); break; case -32: imr2 = (float *)image2; imr2[(y2*w2) + x2] = (float) dpix; break; case -64: imd2 = (double *)image2; imd2[(y2*w2) + x2] = dpix; break; } break; } return; } /* MAXVEC -- Get maximum value in vector from 2D image of any numeric type */ double maxvec (image, bitpix, bzero, bscale, pix1, npix) char *image; /* Image array from which to read vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to check */ int npix; /* Number of pixels to check */ { short *im2, imax2, ip2; int *im4, imax4, ip4; unsigned short *imu, imaxu, ipu; float *imr, imaxr, ipr; double *imd; double dmax = 0.0; double ipd; int ipix, pix2; unsigned char *imc, imaxc, ipc; pix2 = pix1 + npix; switch (bitpix) { case 8: imc = (unsigned char *)(image); imaxc = *(imc + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipc = *(imc + ipix); if (ipc > imaxc) imaxc = ipc; } dmax = (double) imaxc; break; case 16: im2 = (short *)image; imax2 = *(im2 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip2 = *(im2 + ipix); if (ip2 > imax2) imax2 = ip2; } dmax = (double) imax2; break; case 32: im4 = (int *)image; imax4 = *(im4 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip4 = *(im4 + ipix); if (ip4 > imax4) imax4 = ip4; } dmax = (double) imax4; break; case -16: imu = (unsigned short *)image; imaxu = *(imu + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipu = *(imu + ipix); if (ipu > imaxu) imaxu = ipu; } dmax = (double) imaxu; break; case -32: imr = (float *)image; imaxr = *(imr + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipr = *(imr + ipix); if (ipr > imaxr) imax2 = ipr; } dmax = (double) imaxr; break; case -64: imd = (double *)image; dmax = *(imd + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipd = *(imd + ipix); if (ipd > dmax) dmax = ipd; } break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) dmax = (dmax * bscale) + bzero; return (dmax); } /* MINVEC -- Get minimum value in vector from 2D image of any numeric type */ double minvec (image, bitpix, bzero, bscale, pix1, npix) char *image; /* Image array from which to read vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to check */ int npix; /* Number of pixels to check */ { short *im2, imin2, ip2; int *im4, imin4, ip4; unsigned short *imu, iminu, ipu; float *imr, iminr, ipr; double *imd, ipd; double dmin = 0.0; int ipix, pix2; unsigned char *imc, cmin, cp; pix2 = pix1 + npix; switch (bitpix) { case 8: imc = (unsigned char *)image; cmin = *(imc + pix1); for (ipix = pix1; ipix < pix2; ipix++) { cp = *(imc + ipix); if (cp < cmin) cmin = cp; } dmin = (double) cmin; break; case 16: im2 = (short *)image + pix1; imin2 = *im2; for (ipix = pix1; ipix < pix2; ipix++) { ip2 = *(im2 + ipix); if (ip2 < imin2) imin2 = ip2; } dmin = (double) imin2; break; case 32: im4 = (int *)image; imin4 = *(im4 + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ip4 = *(im4 + ipix); if (ip4 < imin4) imin4 = ip4; } dmin = (double) imin4; break; case -16: imu = (unsigned short *)image; iminu = *(imu + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipu = *(imu + ipix); if (ipu < iminu) iminu = ipu; } dmin = (double) iminu; break; case -32: imr = (float *)image; iminr = *(imr + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipr = *(imr + ipix); if (ipr < iminr) iminr = ipr; } dmin = (double) iminr; break; case -64: imd = (double *)image; dmin = *(imd + pix1); for (ipix = pix1; ipix < pix2; ipix++) { ipd = *(imd + ipix); if (ipd < dmin) dmin = ipd; } break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) dmin = (dmin * bscale) + bzero; return (dmin); } /* ADDVEC -- Add constant to pixel values in 2D image of any numeric type */ void addvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double dpix; /* Value to add to pixels */ { unsigned char *imc, ccon; short *im2, jcon; int *im4, icon; unsigned short *imu, ucon; float *imr, rcon; double *imd; int ipix, pix2; pix2 = pix1 + npix; if (scale) dpix = (dpix - bzero) / bscale; switch (bitpix) { case 8: imc = (unsigned char *) (image + pix1); if (dpix < 0) ccon = (unsigned char) (dpix - 0.5); else ccon = (unsigned char) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *imc++ += ccon; break; case 16: im2 = (short *) (image + pix1); if (dpix < 0) jcon = (short) (dpix - 0.5); else jcon = (short) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im2++ += jcon; break; case 32: im4 = (int *) (image + pix1); if (dpix < 0) icon = (int) (dpix - 0.5); else icon = (int) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im4++ += icon; break; case -16: imu = (unsigned short *) (image + pix1); if (dpix > 0) { ucon = (unsigned short) (dpix + 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imu++ += ucon; } else { icon = (int) (dpix - 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) { unsigned short tmp = (icon + (int) *imu); *imu++ += tmp; } } break; case -32: rcon = (float) dpix; imr = (float *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imr++ += rcon; break; case -64: imd = (double *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imd++ += dpix; break; } return; } /* MULTVEC -- Multiply pixel values in place in 2D image of any numeric type */ void multvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double dpix; /* Value by which to multiply pixels */ { char *imc, ccon; short *im2, jcon; int *im4, icon, isint; unsigned short *imu, ucon; float *imr, rcon; double *imd, dcon, dval; int ipix, pix2; pix2 = pix1 + npix; if (scale) dpix = (dpix - bzero) / bscale; ipix = (int) dpix; dcon = (double) ipix; if (dcon == dpix) isint = 1; else isint = 0; switch (bitpix) { case 8: imc = image + pix1; if (isint) { if (dpix < 0) ccon = (char) (dpix - 0.5); else ccon = (char) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *imc++ *= ccon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *imc) * dpix; if (dval < 256.0) *imc++ = (char) dval; else *imc++ = (char) 255; } } break; case 16: im2 = (short *) (image + pix1); if (isint) { im2 = (short *)image; if (dpix < 0) jcon = (short) (dpix - 0.5); else jcon = (short) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im2++ *= jcon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *im2) * dpix; if (dval < 32768.0) *im2++ = (short) dval; else *im2++ = (short) 32767; } } break; case 32: im4 = (int *) (image + pix1); if (isint) { if (dpix < 0) icon = (int) (dpix - 0.5); else icon = (int) (dpix + 0.5); for (ipix = pix1; ipix < pix2; ipix++) *im4++ *= icon; } else { for (ipix = pix1; ipix < pix2; ipix++) { dval = ((double) *im4) * dpix; if (dval < 32768.0) *im4++ = (int) dval; else *im4++ = (int) 32767; } } break; case -16: imu = (unsigned short *) (image + pix1); if (dpix > 0) { ucon = (unsigned short) (dpix + 0.5); imu = (unsigned short *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imu++ *= ucon; } break; case -32: rcon = (float) dpix; imr = (float *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imr++ *= rcon; break; case -64: imd = (double *) (image + pix1); for (ipix = pix1; ipix < pix2; ipix++) *imd++ *= dpix; break; } return; } /* GETVEC -- Get vector from 2D image of any numeric type */ void getvec (image, bitpix, bzero, bscale, pix1, npix, dvec0) char *image; /* Image array from which to extract vector */ int bitpix; /* Number of bits per pixel in image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel to extract */ int npix; /* Number of pixels to extract */ double *dvec0; /* Vector of pixels (returned) */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; double *dvec; int ipix, pix2; pix2 = pix1 + npix; dvec = dvec0; switch (bitpix) { case 8: for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(image + ipix); break; case 16: im2 = (short *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(im2 + ipix); break; case 32: im4 = (int *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(im4 + ipix); break; case -16: imu = (unsigned short *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imu + ipix); break; case -32: imr = (float *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imr + ipix); break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) *dvec++ = (double) *(imd + ipix); break; } /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) { dvec = dvec0; for (ipix = pix1; ipix < pix2; ipix++) { *dvec = (*dvec * bscale) + bzero; dvec++; } } return; } /* PUTVEC -- Copy pixel vector into 2D image of any numeric type */ void putvec (image, bitpix, bzero, bscale, pix1, npix, dvec) char *image; /* Image into which to copy vector */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* Offset of first pixel of vector in image */ int npix; /* Number of pixels to copy */ double *dvec; /* Vector of pixels to copy */ { short *im2; int *im4; unsigned short *imu; float *imr; double *imd; int ipix, pix2; double *dp = dvec; pix2 = pix1 + npix; /* Scale data if either BZERO or BSCALE keyword has been set */ if (scale && (bzero != 0.0 || bscale != 1.0)) { for (ipix = pix1; ipix < pix2; ipix++) { *dp = (*dp - bzero) / bscale; dp++; } dp = dvec; } switch (bitpix) { case 8: for (ipix = pix1; ipix < pix2; ipix++) *(image+ipix) = (char) *dp++; break; case 16: im2 = (short *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(im2+ipix) = (short) (*dp++ - 0.5); else *(im2+ipix) = (short) (*dp++ + 0.5); } break; case 32: im4 = (int *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(im4+ipix) = (int) (*dp++ - 0.5); else *(im4+ipix) = (int) (*dp++ + 0.5); } break; case -16: imu = (unsigned short *)image; for (ipix = pix1; ipix < pix2; ipix++) { if (*dp < 0.0) *(imu+ipix) = (unsigned short) 0; else *(imu+ipix) = (unsigned short) (*dp++ + 0.5); } break; case -32: imr = (float *)image; for (ipix = pix1; ipix < pix2; ipix++) *(imr+ipix) = (float) *dp++; break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) *(imd+ipix) = (double) *dp++; break; } return; } /* FILLVEC1 -- Copy single value into a vector of any numeric type */ void fillvec1 (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Vector to fill */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* First pixel to fill */ int npix; /* Number of pixels to fill */ double dpix; /* Value with which to fill pixels */ { fillvec (image, bitpix, bzero, bscale, pix1-1, npix, dpix); return; } /* FILLVEC -- Copy single value into a vector of any numeric type */ void fillvec (image, bitpix, bzero, bscale, pix1, npix, dpix) char *image; /* Vector to fill */ int bitpix; /* Number of bits per pixel im image */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ double bzero; /* Zero point for pixel scaling */ double bscale; /* Scale factor for pixel scaling */ int pix1; /* First pixel to fill */ int npix; /* Number of pixels to fill */ double dpix; /* Value with which to fill pixels */ { char ipc; short *im2, ip2; int *im4, ip4; unsigned short *imu, ipu; float *imr, ipr; double *imd; int ipix, pix2; double dp; pix2 = pix1 + npix; /* Scale data if either BZERO or BSCALE keyword has been set */ dp = dpix; if (scale && (bzero != 0.0 || bscale != 1.0)) dp = (dp - bzero) / bscale; switch (bitpix) { case 8: if (dp < 0.0) ipc = (char) (dp - 0.5); else ipc = (char) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) image[ipix] = ipc; break; case 16: im2 = (short *)image; if (dp < 0.0) ip2 = (short) (dp - 0.5); else ip2 = (short) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) im2[ipix] = ip2; break; case 32: im4 = (int *)image; if (dp < 0.0) ip4 = (int) (dp - 0.5); else ip4 = (int) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) im4[ipix] = ip4; break; case -16: imu = (unsigned short *)image; if (dp < 0.0) ipu = (unsigned short) (dp - 0.5); else ipu = (unsigned short) (dp + 0.5); for (ipix = pix1; ipix < pix2; ipix++) imu[ipix] = ipu; break; case -32: imr = (float *)image; ipr = (float) dp; for (ipix = pix1; ipix < pix2; ipix++) imr[ipix] = ipr; break; case -64: imd = (double *)image; for (ipix = pix1; ipix < pix2; ipix++) imd[ipix] = dp; break; } return; } /* IMSWAP -- Reverse bytes of any type of vector in place */ void imswap (bitpix, string, nbytes) int bitpix; /* Number of bits per pixel */ /* 16 = short, -16 = unsigned short, 32 = int */ /* -32 = float, -64 = double */ char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { switch (bitpix) { case 8: break; case 16: if (nbytes < 2) return; imswap2 (string,nbytes); break; case 32: if (nbytes < 4) return; imswap4 (string,nbytes); break; case -16: if (nbytes < 2) return; imswap2 (string,nbytes); break; case -32: if (nbytes < 4) return; imswap4 (string,nbytes); break; case -64: if (nbytes < 8) return; imswap8 (string,nbytes); break; } return; } /* IMSWAP2 -- Swap bytes in string in place */ void imswap2 (string,nbytes) char *string; /* Address of starting point of bytes to swap */ int nbytes; /* Number of bytes to swap */ { char *sbyte, temp, *slast; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp = sbyte[0]; sbyte[0] = sbyte[1]; sbyte[1] = temp; sbyte= sbyte + 2; } return; } /* IMSWAP4 -- Reverse bytes of Integer*4 or Real*4 vector in place */ void imswap4 (string,nbytes) char *string; /* Address of Integer*4 or Real*4 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp0, temp1, temp2, temp3; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp3 = sbyte[0]; temp2 = sbyte[1]; temp1 = sbyte[2]; temp0 = sbyte[3]; sbyte[0] = temp0; sbyte[1] = temp1; sbyte[2] = temp2; sbyte[3] = temp3; sbyte = sbyte + 4; } return; } /* IMSWAP8 -- Reverse bytes of Real*8 vector in place */ void imswap8 (string,nbytes) char *string; /* Address of Real*8 vector */ int nbytes; /* Number of bytes to reverse */ { char *sbyte, *slast; char temp[8]; slast = string + nbytes; sbyte = string; while (sbyte < slast) { temp[7] = sbyte[0]; temp[6] = sbyte[1]; temp[5] = sbyte[2]; temp[4] = sbyte[3]; temp[3] = sbyte[4]; temp[2] = sbyte[5]; temp[1] = sbyte[6]; temp[0] = sbyte[7]; sbyte[0] = temp[0]; sbyte[1] = temp[1]; sbyte[2] = temp[2]; sbyte[3] = temp[3]; sbyte[4] = temp[4]; sbyte[5] = temp[5]; sbyte[6] = temp[6]; sbyte[7] = temp[7]; sbyte = sbyte + 8; } return; } /* IMSWAPPED -- Returns 0 if big-endian (Sun,Mac), 1 if little-endian(PC,Alpha) */ int imswapped () { char *ctest; int itest; itest = 1; ctest = (char *)&itest; if (*ctest) return (1); else return (0); } /* Apr 17 1996 New file * May 22 1996 Add H so that PUTPIX and GETPIX can check coordinates * Jun 11 1996 Simplify NEWIMAGE subroutine * Jun 12 1996 Add byte-swapping subroutines * * Jul 24 1997 Add 8-bit option to subroutines * * May 27 1998 Include imio.h instead of fitshead.h * Jun 17 1998 Fix bug, changing all unsigned int's to unsigned short's * * Apr 29 1999 Add scaling to getpix, putpix, getvec, and putvec * Apr 29 1999 Fix bug in getvec in dealing with 1-byte data * Sep 14 1999 Change dp incrementing so it works on Alpha compiler * Sep 27 1999 Add interface for 1-based (FITS) image access * Sep 27 1999 Add addpix() and addpix1() * Dec 14 1999 In putpix(), addpix(), putvec(), round when output is integer * * Sep 20 2000 In getvec(), scale only if necessary * * Nov 27 2001 In movepix(), add char to char move * * Jan 23 2002 Add global scale switch to turn off scaling * Jun 4 2002 In getvec() and putvec(), change dpix to dvec * Jun 4 2002 Add addvec() to add to a vector * Jul 19 2002 Fix getvec() bug rescaling scaled numbers * * May 20 2003 Declare scale0 in setscale() * * Jan 28 2004 Add image limit check to movepix() * Feb 27 2004 Add fillvec() and fillvec1() to set vector to a constant * * Jun 27 2005 Fix major bug in fillvec(); pass value dpix in fillvec1(), too * Aug 18 2005 Add maxvec(), addvec(), and multvec() * * Mar 1 2006 Fix bug of occasional double application of bscale in getvec() * Apr 3 2006 Fix bad cast in unisigned int section of addvec() * May 3 2006 Code fixes in addpix and multpix suggested by Robert Lupton * Jun 8 2006 Drop erroneous second im2 assignment without offset in addvec() * Jun 20 2006 Fix typos masquerading as unitialized variables * * Jan 8 2007 Include fitsfile.h instead of imio.h * Jun 11 2007 Add minvec() and speed up maxvec() * * Apr 12 2012 Fix 8-bit variables to be unsigned char * Oct 19 2012 Fix errors with character images in minvec() and maxvec() * Oct 30 2012 Fix errors with short images in minvec() and maxvec() */