IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6512


Ignore:
Timestamp:
Mar 3, 2006, 3:23:17 PM (20 years ago)
Author:
Paul Price
Message:

psFitsWriteImage will now update BITPIX, NAXIS1, NAXIS2 before writing.
Added psFitsReadImageCube, psFitsWriteImageCube.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/rel10_ifa/psLib/src/fits/psFitsImage.c

    r5511 r6512  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2005-11-14 22:18:30 $
     9 *  @version $Revision: 1.1.10.1 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2006-03-04 01:23:17 $
    1111 *
    1212 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    119119}
    120120
    121 psImage* psFitsReadImage(psImage* output, // a psImage to recycle.
    122                          const psFits* fits,    // the psFits object
    123                          psRegion region, // the region in the FITS image to read
    124                          int z)           // the z-plane in the FITS image cube to read
     121psImage* psFitsReadImage(//psImage* output, // a psImage to recycle.
     122    const psFits* fits,    // the psFits object
     123    psRegion region, // the region in the FITS image to read
     124    int z)           // the z-plane in the FITS image cube to read
    125125{
    126126    psS32 status = 0;           /* CFITSIO file vars */
     
    139139        psError(PS_ERR_BAD_PARAMETER_NULL, true,
    140140                PS_ERRORTEXT_psFits_NULL);
    141         psFree(output);
    142141        return NULL;
    143142    }
     
    165164                PS_ERRORTEXT_psFits_DATATYPE_UNKNOWN,
    166165                fitsErr);
    167         psFree(output);
    168166        return NULL;
    169167    }
     
    175173                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
    176174                fitsErr);
    177         psFree(output);
    178175        return NULL;
    179176    }
     
    184181                PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED,
    185182                nAxis);
    186         psFree(output);
    187183        return NULL;
    188184    }
     
    194190                PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
    195191                fitsErr);
    196         psFree(output);
    197192        return NULL;
    198193    }
     
    259254                PS_ERRORTEXT_psFits_FITS_TYPE_UNSUPPORTED,
    260255                bitPix);
    261         psFree(output);
    262         return NULL;
    263     }
    264 
    265     output = psImageRecycle(output,
    266                             lastPixel[0]-firstPixel[0]+1,
    267                             lastPixel[1]-firstPixel[1]+1,
    268                             datatype);
    269 
    270     if (output == NULL) {
    271         psError(PS_ERR_UNKNOWN, false,
    272                 "Failed to allocate a properly sized image.");
    273         return false;
    274     }
     256        return NULL;
     257    }
     258
     259    output = psImageAlloc(lastPixel[0]-firstPixel[0]+1, lastPixel[1]-firstPixel[1]+1, datatype);
    275260
    276261    // n.b., this assumes contiguous image buffer
     
    288273
    289274}
     275
     276psArray *psFitsReadImageCube(const psFits *fits, psRegion region)
     277{
     278    int nAxis = 0;                      // Number of axes
     279    long nAxes[3];                      // Number of pixels on each axis
     280
     281    if (fits == NULL) {
     282        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     283                PS_ERRORTEXT_psFits_NULL);
     284        return NULL;
     285    }
     286
     287    // Some of this replicates what is in psFitsReadImage, so it's a little inefficient.  But it saves
     288    // code replication, and should be sufficient for our needs.
     289
     290    if (fits_get_img_dim(fits->fd, &nAxis, &status) != 0) {
     291        (void)fits_get_errstatus(status, fitsErr);
     292        psError(PS_ERR_IO, true,
     293                PS_ERRORTEXT_psFits_IMAGE_DIM_UNKNOWN,
     294                fitsErr);
     295        return NULL;
     296    }
     297
     298    if (nAxis == 2) {
     299        psArray *images = psArrayAlloc(1); // Single image plane
     300        images->data[0] = psFitsReadImage(fits, region, 0);
     301        return images;
     302    }
     303    if (nAxis == 3) {
     304        if (fits_get_img_size(fits->fd, nAxis, nAxes, &status) != 0) {
     305            (void)fits_get_errstatus(status, fitsErr);
     306            psError(PS_ERR_IO, true,
     307                    PS_ERRORTEXT_psFits_IMAGE_SIZE_UNKNOWN,
     308                    fitsErr);
     309            return NULL;
     310        }
     311
     312        psArray *images = psArrayAlloc(nAxes[2]); // Array of image planes
     313        for (int i = 0; i < nAxes[2]; i++) {
     314            images->data[i] = psFitsReadImage(fits, region, i);
     315        }
     316
     317        return images;
     318    }
     319
     320    // Bad dimensionality
     321    psError(PS_ERR_IO, true, PS_ERRORTEXT_psFits_IMAGE_DIMENSION_UNSUPPORTED, nAxis);
     322    return NULL;
     323}
     324
    290325
    291326bool psFitsWriteImage(psFits* fits,
     
    340375    // write the header, if any.
    341376    if (header != NULL) {
     377        // Update with BITPIX, NAXIS[12]
     378        psMetadataAddS32(header, PS_LIST_HEAD, "BITPIX", PS_META_REPLACE, "Bits per pixel", bitPix);
     379        psMetadataAddS32(header, PS_LIST_HEAD, "NAXIS1", PS_META_REPLACE, "Bits per pixel", numCols);
     380        psMetadataAddS32(header, PS_LIST_HEAD, "NAXIS2", PS_META_REPLACE, "Bits per pixel", numRows);
     381
    342382        psFitsWriteHeader(header, (psPtr)fits);
    343383    }
     
    376416}
    377417
     418bool psFitsWriteImageCube(psFits *fits, psMetadata *header, const psArray *input, const char *extname)
     419{
     420    if (fits == NULL) {
     421        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     422                PS_ERRORTEXT_psFits_NULL);
     423        return false;
     424    }
     425
     426    if (input == NULL) {
     427        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     428                PS_ERRORTEXT_psFits_IMAGE_NULL);
     429        return false;
     430    }
     431
     432    if (input->n == 0) {
     433        psError(PS_ERR_BAD_PARAMETER_SIZE, true, PS_ERRORTEXT_psFits_ARRAY_EMPTY);
     434        return falase;
     435    }
     436
     437    if (input->n == 1) {
     438        // The problem reduces to one already solved
     439        return psFitsWriteImage(fits, header, input->data[0], extname);
     440    }
     441
     442    // Check that all images are of the same size
     443    {
     444        psImage *image = input->data[0];// First image off the array
     445        int numCols = image->numCols;   // Number of columns
     446        int numRows = image->numRows;   // Number of rows
     447        for (int i = 1; i < input->n; i++)
     448        {
     449            image = input->data[i];
     450            if (image->numCols != numCols || image->numRows != numRows) {
     451                psError(PS_ERR_BAD_PARAMETER_SIZE, true, PS_ERRORTEXT_psFits_ARRAY_SIZE_DIFFER);
     452                return false;
     453            }
     454        }
     455    }
     456
     457    // Need to check the header to make sure NAXIS and NAXIS[1-3] are correct
     458    psMetadata *headerCopy = NULL;      // Copy of header
     459    if (header) {
     460        headerCopy = psMemIncrRefCounter(header);
     461    } else {
     462        headerCopy = psMetadataAlloc();
     463    }
     464    bool update = psMetadataAddS32(headerCopy, PS_LIST_HEAD, "NAXIS", PS_META_REPLACE, "Dimensionality", 3) &&
     465                  psMetadataAddS32(headerCopy, PS_LIST_HEAD, "NAXIS1", PS_META_REPLACE, "Number of columns", numCols) &&
     466                  psMetadataAddS32(headerCopy, PS_LIST_HEAD, "NAXIS2", PS_META_REPLACE, "Number of rows", numRows) &&
     467                  psMetadataAddS32(headerCopy, PS_LIST_HEAD, "NAXIS3", PS_META_REPLACE, "Number of image planes",
     468                                   images->n);
     469    if (! update) {
     470        psError(PS_ERR_UNKNOWN, false, psFits_METADATA_ADD_FAILED, "NAXIS, NAXIS1, NAXIS2, NAXIS3");
     471        psFree(headerCopy);
     472        return false;
     473    }
     474
     475    // Now we can safely write the images out
     476    for (int i = 0; i < images->n; i++) {
     477        if (! psFitsWriteImage(fits, headerCopy, images->data[i], i, extname)) {
     478            psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psFits_WRITE_PLANE_FAILED, i);
     479            psFree(headerCopy);
     480            return false;
     481        }
     482    }
     483
     484    psFree(headerCopy);                 // Free, or drop reference
     485
     486    return true;
     487}
     488
     489
     490
    378491bool psFitsUpdateImage(psFits* fits,
    379492                       const psImage* input,
Note: See TracChangeset for help on using the changeset viewer.