- Timestamp:
- May 28, 2015, 8:27:00 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20150429/src/libfits/matrix/F_compress_M.c
r38326 r38329 3 3 # include <zlib.h> 4 4 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 24 5 // the user needs to specify the various compression options: 25 // ztile[i] 26 // zcmptype 6 // ztile[i] (may be NULL) 7 // zcmptype 27 8 28 9 // steps to convert an image to a compressed table: … … 35 16 // * update header keywords 36 17 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 22 int 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; 56 35 57 36 // determine the number of tiles (from ztile[] and image size) … … 67 46 68 47 // 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); 70 49 71 50 // by using "P" format, we are limited to 32bit pointers (2GB heap) 72 51 // 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); 79 60 80 // this allocates the data array61 // this allocates the pointer data array for the full set of tiles (NOT the heap) 81 62 char *tmpbuffer = NULL; 82 63 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); 84 66 85 67 // 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 } 92 86 93 87 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 106 117 107 118 // search for algorithm-specific keywords. these are used to control compression options … … 114 125 if (!gfits_modify (header, key, "%s", 1, optvalue[i])) break; 115 126 } 116 117 # if (0)118 // XXX get ZMASKCMP119 int zsimple, have_zsimple;120 int have_ztension;121 122 // NOTE target of %t must be int length123 // 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 keywords128 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 PHU132 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 PHU141 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 extension151 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,1156 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);191 127 # endif 192 128 193 // XXX how to define zdef?194 129 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); 204 134 205 135 // 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); 207 140 208 141 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); 210 143 211 144 // init the otile[] counters 212 gfits_imfile_start (matrix, otile);145 if (!gfits_imtile_start (matrix, otile)) ESCAPE (A); 213 146 214 147 // compress the data : copy into a tile, compress the tile, then add to the output table … … 217 150 218 151 // size of the current tile 219 Nraw = gfits_tile_size (matrix, otile, ztile);152 int Nraw = gfits_tile_size (matrix, otile, ztile); 220 153 221 154 // 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); 223 156 224 157 // 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); 230 165 231 166 // 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); 233 168 234 169 // 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); 237 182 return (TRUE); 183 184 escape: 185 FREE (raw); 186 FREE (zdata); 187 188 FREE (otile); 189 FREE (ntile); 190 191 if (!Ztile) FREE (ztile); 192 return FALSE; 238 193 } 239 194 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 195 int 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 } 250 203 251 204 // raw_pixsize is the bytes / pixel for the input matrix … … 298 251 } } } 299 252 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 300 265 // this macro sets up the outer switch and calls above macro with all output bitpix options 301 266 # define SETUP_INSIZE(TYPE, SIZE) { \ … … 312 277 break; \ 313 278 case -32: \ 314 SCALE_AND_DIST (float, 4); \279 SCALE_AND_DIST_FLOAT (float, 4); \ 315 280 break; \ 316 281 case -64: \ 317 SCALE_AND_DIST (double, 8); \282 SCALE_AND_DIST_FLOAT (double, 8); \ 318 283 break; \ 319 284 default: \
Note:
See TracChangeset
for help on using the changeset viewer.
