IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 28, 2015, 8:27:00 PM (11 years ago)
Author:
eugene
Message:

adding code for table compress/uncompress; image compress works (but is not quite compatible with cfitsio for some reason and byteswap is broken)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ohana.20150429/src/libfits/matrix/F_compress_M.c

    r38326 r38329  
    33# include <zlib.h>
    44
    5 # define ESCAPE { \
    6   if (ztile != NULL) free (ztile); \
    7   if (optname != NULL) { \
    8     for (j = 0; j < Noptions; j++) { \
    9       free (optname[j]); \
    10       free (optvalue[j]); \
    11     } \
    12     free (optname); \
    13     free (optvalue); \
    14   } \
    15   if (out != NULL) free (out); \
    16   if (otile != NULL) free (otile); \
    17   if (ntile != NULL) free (ntile); \
    18   return (FALSE); }
    19 
    20 # define MOD_KEYWORD(ZNAME,NAME,TYPE,OUT,VALUE) { \
    21     gfits_modify (theader, ZNAME, TYPE, 1, OUT);          \
    22     gfits_delete (theader, NAME, 1); }
    23 
    245// the user needs to specify the various compression options:
    25 // ztile[i]
    26 // zcmptype
     6// ztile[i] (may be NULL)
     7// zcmptype 
    278
    289// steps to convert an image to a compressed table:
     
    3516// * update header keywords
    3617
    37 // XXX do not try to support compression of an image with an associated table (not valid)
    38 
    39 int gfits_compress_image (Header *header, Matrix *matrix, FTable *ftable, int *ztile, char *zcmptype) {
    40 
    41   // off_t Nzdata, Nzrows, zcol;
    42   // int i, j, status, zimage, Nout, max_tile_size;
    43   // char cmptype[80];
    44   // char zaxis[10], naxis[10], key[10], word[81], exttype[81], checksum[81], datasum[81];
    45   // int Noptions, NOPTIONS, zblank, oblank;
    46   // VarLengthColumn zdef;
    47   // float zscale, zzero;
    48 
    49   // int zdata_pixsize, odata_pixsize;
    50   // int *otile = NULL;
    51   // int *ntile = NULL;
    52   // char **optname = NULL;
    53   // char **optvalue = NULL;
    54   // char *out = NULL;
    55   // char *zdata = NULL;
     18// we do not try to support compression of an image with an associated table (not valid)
     19
     20# define ESCAPE(A) { fprintf (stderr, "error in %s @ line %d\n", __func__, __LINE__); goto escape; }
     21
     22int gfits_compress_image (Header *header, Matrix *matrix, FTable *ftable, int *Ztile, char *zcmptype) {
     23
     24  int i;
     25
     26  // pointers to track the tile data
     27  int *otile = NULL;
     28  int *ntile = NULL;
     29  char *raw = NULL;
     30  char *zdata = NULL;
     31
     32  int *ztile = Ztile;
     33
     34  Header *theader = ftable->header;
    5635
    5736  // determine the number of tiles (from ztile[] and image size)
     
    6746
    6847  // creates an empty (Naxes = 2, Naxis[i] = 0) table header with XTENSION = BINTABLE, EXTNAME = COMPRESSED_IMAGE
    69   gfits_create_table_header (&theader, "BINTABLE", "COMPRESSED_IMAGE");
     48  if (!gfits_create_table_header (theader, "BINTABLE", "COMPRESSED_IMAGE")) ESCAPE(A);
    7049
    7150  // by using "P" format, we are limited to 32bit pointers (2GB heap)
    7251  // XXX how is the "B" format used?
    73   gfits_define_bintable_column (&theader, "1PB(0)", "COMPRESSED_DATA", "compressed image data", "none", 1.0, 0.0);
    74 
    75   // XXX I need to copy the bulk of the header from the matrix header -> ftable.header
    76   gfits_create_table (&theader, ftable);
    77   // copy original header to output header
    78   // XXX gfits_copy_header (header, theader); -- I need to copy only the desired keywords.
     52  if (!gfits_define_bintable_column (theader, "1PB(0)", "COMPRESSED_DATA", "compressed image data", "none", 1.0, 0.0)) ESCAPE (A);
     53  if (!gfits_delete (theader, "TUNIT1", 1)) ESCAPE(A);
     54
     55  // allocates the default data array (ftable->buffer)
     56  if (!gfits_create_table (theader, ftable)) ESCAPE (A);
     57
     58  // copy original header to output header (XXX this needs to be finished)
     59  if (!gfits_copy_keywords_compress (header, theader)) ESCAPE (A);
    7960 
    80   // this allocates the data array
     61  // this allocates the pointer data array for the full set of tiles (NOT the heap)
    8162  char *tmpbuffer = NULL;
    8263  ALLOCATE_ZERO (tmpbuffer, char, Ntile);
    83   gfits_set_bintable_column (&theader, &ftable, "COMPRESSED_DATA", tmpbuffer, Ntile);
     64  if (!gfits_set_bintable_column (theader, ftable, "COMPRESSED_DATA", tmpbuffer, Ntile)) ESCAPE (A);
     65  free (tmpbuffer);
    8466
    8567  // add ZIMAGE from output header
    86   gfits_modify_alt (theader, "ZIMAGE", "%t", 1, TRUE);
    87 
    88   // translate image-specific keywords to Z versions (updates the Z version, removes the old version)
    89   // XXX use the header or the structure as authoratative?
    90   MOVE_KEYWORD ("ZBITPIX", "BITPIX", "%d");
    91   MOVE_KEYWORD ("ZNAXIS",  "NAXIS",  "%d");
     68  if (!gfits_modify_alt (theader, "ZIMAGE", "%t", 1, TRUE)) ESCAPE (A);
     69
     70  // define compression-specific keywords, update header as needed.
     71  if (!gfits_modify (theader, "ZCMPTYPE", "%s", 1, zcmptype)) ESCAPE(A);
     72
     73  if (!gfits_modify_alt (theader, "ZSIMPLE", "%t", 1, TRUE)) ESCAPE (A);
     74  // gfits_modify (header, "ZTENSION", "%s", 1, exttype);
     75
     76  // supply the Z* header values from the source image header
     77  if (!gfits_modify (theader, "ZBITPIX", "%d", 1, header[0].bitpix)) ESCAPE (A);
     78
     79  if (!gfits_modify (theader, "ZNAXIS",  "%d", 1, header[0].Naxes)) ESCAPE (A);
     80
     81  char keyword[11];
     82  for (i = 0; i < header[0].Naxes; i++) {
     83    snprintf (keyword, 10, "ZNAXIS%d", i + 1);
     84    if (!gfits_modify (theader, keyword, OFF_T_FMT, 1,  header[0].Naxis[i])) ESCAPE (A);
     85  }
    9286
    9387  for (i = 0; i < header->Naxes; i++) {
    94     snprintf (zaxis, 10, "ZNAXIS%d", i + 1);
    95     snprintf (naxis, 10, "NAXIS%d", i + 1);
    96     MOD_KEYWORD (zaxis,  naxis,  OFF_T_FMT,  header->Naxis[i]);
    97   }   
    98 
    99   for (i = 0; i < header->Naxes; i++) {
    100     snprintf (key, 10, "ZTILE%d", i + 1);
    101     if (!gfits_modify (theader, key, "%d", 1, ztile[i])) ESCAPE;
    102   }
    103 
    104   // define compression-specific keywords, update header as needed.
    105   if (!gfits_modify (header, "ZCMPTYPE", "%s", 1, zcmptype)) ESCAPE;
     88    snprintf (keyword, 10, "ZTILE%d", i + 1);
     89    if (!gfits_modify (theader, keyword, "%d", 1, ztile[i])) ESCAPE(A);
     90  }
     91
     92  if (!gfits_modify (theader, "BSCALE", "%lf", 1, header[0].bscale)) ESCAPE (A);
     93  if (!gfits_modify (theader, "BZERO",  "%lf", 1, header[0].bzero)) ESCAPE (A);
     94
     95  // other keywords to define:
     96  // ZEXTEND
     97  // ZBLOCKED
     98  // ZHECKSUM
     99  // ZDATASUM
     100  // PCOUNT -> ZPCOUNT
     101  // GCOUNT -> ZGCOUNT
     102
     103  float zscale = 1.0;
     104  // gfits_modify (header, "ZSCALE", "%f", 1, zscale);
     105
     106  float zzero = 0.0;
     107  // gfits_modify (header, "ZZERO", "%f", 1, zzero);
     108
     109  int zblank = 32767;
     110  // gfits_modify (header, "ZBLANK", "%d", 1, zblank);
     111
     112  int oblank = 32767;
     113  // gfits_modify (header, "BLANK", "%d", 1, oblank);
     114
     115# if (0)
     116  // need to set ZNAMEnn and ZVALnn if they are defined and used
    106117
    107118  // search for algorithm-specific keywords. these are used to control compression options
     
    114125    if (!gfits_modify (header, key, "%s", 1, optvalue[i])) break;
    115126  }
    116 
    117 # if (0)
    118   // XXX get ZMASKCMP
    119   int zsimple, have_zsimple;
    120   int have_ztension;
    121 
    122   // NOTE target of %t must be int length
    123   // XXX how do I specify this??
    124   // have_zsimple  = gfits_scan_alt (header, "ZSIMPLE", "%t", 1, &zsimple);
    125   // have_ztension = gfits_scan (header, "ZTENSION", "%s", 1, exttype);
    126 
    127   // this is a very bogus case: we cannot have both keywords
    128   if (have_zsimple && have_ztension) ESCAPE;
    129 
    130   // if neither are present, we have an image that is not really following the standard:
    131   // assume it is a PHU
    132   if (!have_zsimple && !have_ztension) {
    133     header->simple = TRUE;
    134     gfits_extended_to_primary (header, header->simple, "Image data");
    135 
    136     MOD_KEYWORD_ALT ("ZEXTEND",  "EXTEND",   "%t", &header->extend, header->extend);
    137     MOD_KEYWORD_ALT ("ZBLOCKED", "BLOCKED",  "%t", &header->extend, header->extend);
    138   }
    139 
    140   // have_zsimple : image comes from a PHU
    141   if (have_zsimple) {
    142     header->simple = zsimple;
    143     gfits_delete (header, "ZSIMPLE", 1);
    144     gfits_extended_to_primary (header, header->simple, "Image data");
    145 
    146     MOD_KEYWORD_ALT ("ZEXTEND",  "EXTEND",   "%t", &header->extend, header->extend);
    147     MOD_KEYWORD_ALT ("ZBLOCKED", "BLOCKED",  "%t", &header->extend, header->extend);
    148   }
    149 
    150   // have_ztension : image comes from an extension
    151   if (have_ztension) {
    152     gfits_delete (header, "ZTENSION", 1);
    153     gfits_modify_extended (header, exttype, "Image extension");
    154 
    155     // we may have an uncompressed PCOUNT / GCOUNT value, otherwise set to 0,1
    156     if (gfits_scan (header, "ZPCOUNT", "%d", 1, &header->pcount)) {
    157         gfits_delete (header, "ZPCOUNT", 1);
    158         gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
    159     } else {
    160         header->pcount = 0;
    161         gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
    162     }
    163     if (gfits_scan (header, "ZGCOUNT", "%d", 1, &header->gcount)) {
    164         gfits_delete (header, "ZGCOUNT", 1);
    165         gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
    166     } else {
    167         header->pcount = 1;
    168         gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
    169     }
    170   } else {
    171     header->pcount = 0;
    172     header->gcount = 1;
    173     gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
    174     gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
    175   }
    176 
    177   MOD_KEYWORD ("ZHECKSUM", "CHECKSUM", "%s", checksum,        checksum);
    178   MOD_KEYWORD ("ZDATASUM", "DATASUM",  "%s", datasum,         datasum);
    179 
    180   zscale = 1;
    181   gfits_scan (header, "ZSCALE", "%f", 1, &zscale);
    182 
    183   zblank = 32767;
    184   gfits_scan (header, "ZBLANK", "%d", 1, &zblank);
    185 
    186   oblank = 32767;
    187   gfits_scan (header, "BLANK", "%d", 1, &oblank);
    188 
    189   zzero = 0;
    190   gfits_scan (header, "ZZERO", "%f", 1, &zzero);
    191127# endif
    192128
    193   // XXX how to define zdef?
    194129  VarLengthColumn zdef;
    195   if (!gfits_varlength_column_define (ftable, &zdef, zcol)) ESCAPE;
    196 
    197   max_tile_size = gfits_imtile_maxsize (matrix, ztile);
    198 
    199   // size of an element in the vartable heap section
    200   zdata_pixsize = gfits_vartable_heap_pixsize (zdef.format);
    201 
    202   // size of a pixel in the final image (not needed)
    203   // raw_pixsize = gfits_uncompressed_data_pixsize (cmptype, header[0].bitpix, optname, optvalue, Noptions)
     130  if (!gfits_varlength_column_define (ftable, &zdef, 1)) ESCAPE(A);
     131
     132  // allocate the working buffers to the max tile size
     133  int max_tile_size = gfits_imtile_maxsize (matrix, ztile);
    204134
    205135  // size of a pixel in the raw image tile:
    206   raw_pixsize = abs(header[0].bitpix) / 8;
     136  int raw_pixsize = abs(header[0].bitpix) / 8;
     137
     138  // size of a pixel in the raw image tile:
     139  int tile_pixsize = gfits_uncompressed_data_pixsize (zcmptype, header[0].bitpix, NULL, NULL, 0);
    207140
    208141  ALLOCATE (raw,   char, raw_pixsize*max_tile_size);
    209   ALLOCATE (zdata, char, raw_pixsize*max_tile_size); //
     142  ALLOCATE (zdata, char, raw_pixsize*max_tile_size);
    210143
    211144  // init the otile[] counters
    212   gfits_imfile_start (matrix, otile);
     145  if (!gfits_imtile_start (matrix, otile)) ESCAPE (A);
    213146
    214147  // compress the data : copy into a tile, compress the tile, then add to the output table
     
    217150
    218151    // size of the current tile
    219     Nraw = gfits_tile_size (matrix, otile, ztile);
     152    int Nraw = gfits_tile_size (matrix, otile, ztile);
    220153
    221154    // copy the raw pixels from their native matrix locations to the temporary output buffer
    222     if (!gfits_collect_data (matrix, raw, Nraw, raw_pixsize, otile, oblank, ztile, zblank, zscale, zzero)) return (FALSE);
     155    if (!gfits_collect_data (matrix, raw, Nraw, raw_pixsize, otile, oblank, ztile, zblank, zscale, zzero)) ESCAPE(A);
    223156
    224157    // XXX the tile must not be > 2GB
    225 
    226     Nzdata = raw_pixsize*max_tile_size; // available space, replaced with actual output size on compression
    227     if (!gfits_compress_data (zdata, &Nzdata, zcmptype, optname, optvalue, Noptions, raw, Nraw, raw_pixsize)) return (FALSE);
    228 
    229     if (!gfits_varlength_column_add_data (ftable, zdata, Nzdata, i, &zdef)) return FALSE;
     158   
     159    // optname, optvalue = NULL, Noptions = 0
     160
     161    int Nzdata = raw_pixsize*max_tile_size; // available space, replaced with actual output size on compression
     162    if (!gfits_compress_data (zdata, &Nzdata, zcmptype, NULL, NULL, 0, raw, Nraw, tile_pixsize)) ESCAPE(A);
     163
     164    if (!gfits_varlength_column_add_data (ftable, zdata, Nzdata, i, &zdef)) ESCAPE(A);
    230165
    231166    // XXX need to activate
    232     if (FALSE) gfits_byteswap_zdata (zdata, Nzdata, zdata_pixsize) return (FALSE);
     167    // if (FALSE) gfits_byteswap_zdata (zdata, Nzdata, zdata_pixsize) ESCAPE(A);
    233168
    234169    // update the otile[] counters, carrying to the next dimension if needed
    235     gfits_imfile_next (matrix, ztile, ntile, otile);
    236   }
     170    gfits_imtile_next (matrix, ztile, ntile, otile);
     171  }
     172
     173  if (!gfits_varlength_column_finish (ftable, &zdef)) ESCAPE(A);
     174
     175  free (raw);
     176  free (zdata);
     177
     178  free (otile);
     179  free (ntile);
     180
     181  if (!Ztile) free (ztile);
    237182  return (TRUE);
     183
     184escape:
     185  FREE (raw);
     186  FREE (zdata);
     187
     188  FREE (otile);
     189  FREE (ntile);
     190
     191  if (!Ztile) FREE (ztile);
     192  return FALSE;
    238193}
    239194
    240   // this takes place in three major steps:
    241   // 1) rawdata -> tiledata (copy a tile chunk to the tiledata buffer)
    242   // 2) compress tiledata -> zdata
    243   // 3) add zdata to table data heap
    244 
    245   // heapdata.pixsize : zdef.format
    246   // zdata.pixsize : depends on compression
    247   // odata.pixsize : depends on compression
    248   // idata.pixsize : header.bitpix
    249 
     195int gfits_copy_keywords_compress (Header *srchead, Header *tgthead) {
     196
     197  int i;
     198
     199  for (i = 0; i < srchead->datasize; i += FT_LINE_LENGTH) {
     200  }
     201  return TRUE;
     202}
    250203
    251204// raw_pixsize is the bytes / pixel for the input matrix
     
    298251      } } }
    299252
     253  // we need to set up switches for all of the possible combinations:
     254  // this macro is used at the inner switch to run the actual loop
     255  // note we copy Optr to Iptr
     256# define SCALE_AND_DIST_FLOAT(TYPE, SIZE) {                                     \
     257    TYPE *Optr = (TYPE *) &matrix->buffer[SIZE*(offset + start)];       \
     258    for (j = 0; j < Ztile[0]; j++, Iptr++, Optr++) {                    \
     259      if (!isfinite(*Optr)) {                                           \
     260        *Iptr = zblank;                                                 \
     261      } else {                                                          \
     262        *Iptr = (*Optr - zzero) / zscale;                               \
     263      } } }
     264
    300265  // this macro sets up the outer switch and calls above macro with all output bitpix options
    301266# define SETUP_INSIZE(TYPE, SIZE) {                     \
     
    312277        break;                                          \
    313278      case -32:                                         \
    314         SCALE_AND_DIST (float, 4);                      \
     279        SCALE_AND_DIST_FLOAT (float, 4);                        \
    315280        break;                                          \
    316281      case -64:                                         \
    317         SCALE_AND_DIST (double, 8);                     \
     282        SCALE_AND_DIST_FLOAT (double, 8);                       \
    318283        break;                                          \
    319284      default:                                          \
Note: See TracChangeset for help on using the changeset viewer.