IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 13, 2008, 3:27:25 PM (18 years ago)
Author:
Paul Price
Message:

Some fixes to image I/O: (1) when BITPIX=8, the FITS standard says unsigned ints (cf two's complement for BITPIX=16,32,64). Added some special cases for quantising to BITPIX=8 to accomodate this. (2) Adding support for marking bad pixels when doing compression. Out-of-range and non-finite pixels are written with value 2(BITPIX-1)-1, which is recovered (to NAN) when reading (through use of (Z)BLANK keyword). Added test for this. It doesn't pass yet --- the highest pixel in the image is being interpreted as NAN when it shouldn't be. Solution probably involves tweaking scaleRange() in psFitsScale.c, but not worrying about that now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/fits/psFitsScale.c

    r17447 r17660  
    4646    psAssert(options, "impossible");
    4747
    48     double range = pow(2.0, options->bitpix); // Range of values for target BITPIX
     48    double range = pow(2.0, options->bitpix) - 1.0; // Range of values for target BITPIX, reduced by the BLANK
    4949    double min = INFINITY, max = -INFINITY; // Minimum and maximum values
    5050    int numCols = image->numCols, numRows = image->numRows; // Size of image
     
    8686        *bzero = min;
    8787    } else {
    88         *bscale = (max - min) / (range - 1.0);
     88        *bscale = (max - min) / range ;
    8989        *bzero = min + 0.5 * range * (*bscale);
    9090    }
     
    157157
    158158    return true;
    159 
    160 
    161     return true;
    162159}
    163160
     
    168165bool psFitsScaleDetermine(double *bscale, // Scaling, to return
    169166                          double *bzero, // Zero point, to return
     167                          long *blank,  // Blank value, to return
    170168                          const psImage *image, // Image to scale
    171169                          const psFits *fits // FITS options
     
    174172    PS_ASSERT_PTR_NON_NULL(bscale, false);
    175173    PS_ASSERT_PTR_NON_NULL(bzero, false);
     174    PS_ASSERT_PTR_NON_NULL(blank, false);
    176175    PS_ASSERT_IMAGE_NON_NULL(image, false);
    177176    PS_ASSERT_FITS_NON_NULL(fits, false);
     
    179178    *bscale = 1.0;
    180179    *bzero = 0.0;
     180    *blank = 0;
    181181
    182182    psFitsOptions *options = fits->options; // FITS options
     
    201201    }
    202202
     203    *blank = (1 << (options->bitpix - 1)) - 1;
     204
    203205    switch (options->scaling) {
    204206      case PS_FITS_SCALE_NONE:
     
    229231    }
    230232
    231     psTrace("psLib.fits", 3, "BSCALE = %.10lf, BZERO = %.10lf\n", *bscale, *bzero);
     233    if (options->bitpix == 8) {
     234        // FITS standard wants unsigned for BITPIX=8, two's-complement for BITPIX=16,32,64.
     235        *bzero -= *bscale * 128;
     236        *blank = 255;
     237    }
     238
     239
     240    psTrace("psLib.fits", 3, "BSCALE = %.10lf, BZERO = %.10lf, BLANK = %ld\n", *bscale, *bzero, *blank);
    232241    return true;
    233242}
     
    252261    switch (bitpix) {
    253262      case 8:
    254         outType = PS_TYPE_S8;
     263        // Note: Use unsigned integer for BITPIX=8
     264        outType = PS_TYPE_U8;
    255265        break;
    256266      case 16:
     
    283293#define SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, OUTTYPE) \
    284294    case PS_TYPE_##OUTTYPE: { \
    285         ps##INTYPE scale = 1.0 / bscale; \
    286         ps##INTYPE zero = bzero; \
    287         ps##INTYPE min = - (1 << (options->bitpix - 1)); \
    288         ps##INTYPE max = (1 << (options->bitpix - 1)) - 1; \
     295        double scale = 1.0 / bscale; \
     296        double zero = bzero; \
     297        /* Note: BITPIX=8 treated differently, since it uses unsigned values; the rest use signed */ \
     298        double min = bitpix == 8 ? 0 : -pow(2.0, options->bitpix - 1); \
     299        double max = bitpix == 8 ? 255 : (pow(2.0, options->bitpix - 1) - 1.0); \
    289300        for (int y = 0; y < numRows; y++) { \
    290301            for (int x = 0; x < numCols; x++) { \
     
    301312                        value += psRandomUniform(rng); \
    302313                    } \
    303                     /* Check for underflow and overflow */ \
    304                     (OUT)->data.OUTTYPE[y][x] = (value < min ? min : (value > max ? max : value)); \
     314                    /* Check for underflow and overflow; set either to max */ \
     315                    (OUT)->data.OUTTYPE[y][x] = (value < min || value > max ? max : value); \
    305316                } \
    306317            } \
     
    312323    case PS_TYPE_##INTYPE: { \
    313324        switch (outType) { \
    314             SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S8); \
     325            SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, U8); \
    315326            SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S16); \
    316327            SCALE_WRITE_OUT_CASE(IN, INTYPE, OUT, S32); \
Note: See TracChangeset for help on using the changeset viewer.