IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 3, 2015, 8:20:19 PM (11 years ago)
Author:
eugene
Message:

adding GZIP_2 and getting RICE_1 to work (mostly)

File:
1 edited

Legend:

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

    r38356 r38362  
    33# include <zlib.h>
    44# define VERBOSE_DUMP 0
     5
     6int gfits_collect_gzp2 (Matrix *matrix, char *raw, int Nraw, int raw_bitpix, int *otile, int oblank, int *ztile, int zblank, float zscale, float zzero);
    57
    68// the user needs to specify the various compression options:
     
    7375  // define compression-specific keywords, update header as needed.
    7476  if (!gfits_modify (theader, "ZCMPTYPE", "%s", 1, zcmptype)) ESCAPE;
     77
     78  // define compression-specific keywords, update header as needed.
     79  if (!strcasecmp(zcmptype, "GZIP_1") || !strcasecmp(zcmptype, "GZIP_2")) {
     80    if ((header[0].bitpix == -32) || (header[0].bitpix == -64)) {
     81      if (!gfits_modify (theader, "ZQUANTIZ", "%s", 1, "NONE")) ESCAPE;
     82    }
     83  }
    7584
    7685  if (!gfits_modify_alt (theader, "ZSIMPLE", "%t", 1, TRUE)) ESCAPE;
     
    155164  int cmp_pixsize = gfits_compressed_data_pixsize (zcmptype, header[0].bitpix, NULL, NULL, 0);
    156165
     166  // define compression-specific keywords, update header as needed.
     167  if (!strcasecmp(zcmptype, "RICE_1")) {
     168    if (!gfits_modify (theader, "ZNAME1", "%s", 1, "BLOCKSIZE")) ESCAPE;
     169    if (!gfits_modify (theader, "ZVAL1", "%d", 1, 32)) ESCAPE;
     170    if (!gfits_modify (theader, "ZNAME2", "%s", 1, "BYTEPIX")) ESCAPE;
     171    if (!gfits_modify (theader, "ZVAL2", "%d", 1, raw_pixsize)) ESCAPE;
     172  }
     173
    157174  // size of a pixel in the image tile -- this is probably not needed
    158175  // int tile_pixsize = abs(header[0].bitpix) / 8;
     
    176193    // copy the raw pixels from their native matrix locations to the temporary output buffer
    177194    // for float -> int scaling by zscale, zzero may be applied
    178     if (!gfits_collect_data (matrix, raw, Nraw, raw_bitpix, otile, oblank, ztile, zblank, zscale, zzero)) ESCAPE;
     195    if (!strcasecmp (zcmptype, "GZIP_2")) {
     196      if (!gfits_collect_gzp2 (matrix, raw, Nraw, raw_bitpix, otile, oblank, ztile, zblank, zscale, zzero)) ESCAPE;
     197    } else {
     198      if (!gfits_collect_data (matrix, raw, Nraw, raw_bitpix, otile, oblank, ztile, zblank, zscale, zzero)) ESCAPE;
     199    }
    179200
    180201    if (VERBOSE_DUMP && (i == 0)) {
     
    214235    }
    215236
    216     // all other compression modes require swapping after compression
    217     // (compresssion & decompression operate on native ENDIAN)
    218     if (strcasecmp(zcmptype, "GZIP_1")) {
     237    // GZIP_1 is swapped before compression; GZIP_2 implies swapping.  All other
     238    // compression modes require swapping after compression (compresssion & decompression
     239    // operate on native ENDIAN)
     240    if (strcasecmp(zcmptype, "GZIP_1") && strcasecmp(zcmptype, "GZIP_2")) {
    219241      // Nzdata is number of bytes
    220242      if (!gfits_byteswap_zdata (zdata, Nzdata, cmp_pixsize)) ESCAPE;
     
    383405  return (TRUE);
    384406}
     407
     408// GZIP_2 organizes data in bytes by significance: (A1 A2 A3 A4), (B1 B2 B3 B4) -> (A1 B1), (A2, B2), (A3, B3), (A4, B4)
     409// NOTE that this organization depends on the machine endian state.
     410// raw_pixsize is the bytes / pixel for the input matrix
     411// place the raw image bytes for the current tile into the tile buffer
     412// * otile is the counter for the current output tile
     413// * ztile gives the size of the i-th dimension of the current tile
     414// * raw_bitpix defines the size and type of the raw buffer
     415int gfits_collect_gzp2 (Matrix *matrix, char *raw, int Nraw, int raw_bitpix, int *otile, int oblank, int *ztile, int zblank, float zscale, float zzero) {
     416
     417  int i, j, k;
     418  int *counter = NULL;
     419  int *Ztile = NULL;
     420
     421  ALLOCATE (counter, int, matrix->Naxes); // counter for current row in tile to copy
     422  ALLOCATE (Ztile, int, matrix->Naxes); // true sizes of this tile (in pixels)
     423 
     424  for (i = 0; i < matrix->Naxes; i++) {
     425    counter[i] = 0;
     426    Ztile[i] = MIN ((matrix->Naxis[i] - otile[i]*ztile[i]), ztile[i]);
     427  }
     428
     429  // number of lines in the tile (in pixels)
     430  int Nline = 1;
     431  int Npix = matrix->Naxis[0];
     432  for (i = 1; i < matrix->Naxes; i++) {
     433    Nline *= Ztile[i];
     434    Npix  *= matrix->Naxis[i];
     435  }
     436
     437  // confirm the tile size:
     438  assert (Nraw == Ztile[0]*Nline);
     439
     440  // set the starting point of the tile in the matrix buffer
     441  // start = otile[0]*ztile[0] + otile[1]*ztile[1]*Naxis[0] + otile[2]*ztile[2]*Naxis[0]*Naxis[1] + ...;
     442  // start = otile[0]*ztile[0] + Naxis[0]*(otile[1]*ztile[1] + Naxis[1]*(otile[2]*ztile[2] + ...));
     443  int start = otile[matrix->Naxes-1]*ztile[matrix->Naxes-1];
     444  for (i = matrix->Naxes - 2; i >= 0; i--) {
     445    int coord = otile[i]*ztile[i];
     446    start = start*matrix->Naxis[i] + coord;
     447  }
     448 
     449  int size = 0;
     450  switch (raw_bitpix) {
     451    case   8: size = 1; break;
     452    case  16: size = 2; break;
     453    case  32: size = 4; break;
     454    case -32: size = 4; break;
     455    case -64: size = 8; break;
     456    default: abort();
     457  }
     458
     459  // pixel offset in output array relative to tile start
     460  int offset = 0;
     461 
     462  static int pass = 0;
     463  for (k = 0; k < size; k++) {
     464    for (i = 0; i < Nline; i++) {
     465# ifdef BYTE_SWAP     
     466      char *srcptr = &matrix->buffer[size*(offset + start) + (size - k - 1)];
     467# else
     468      char *srcptr = &matrix->buffer[size*(offset + start) + k];
     469# endif
     470      char *rawptr = &raw[i*size*Ztile[0] + k*Nraw];   
     471      for (j = 0; j < Ztile[0]; j++, srcptr += size, rawptr ++) {               
     472        if (FALSE && (i == 0) && (j < 4) && (pass == 0)) {
     473          fprintf (stderr, "0x%02hhx -> 0x%02hhx\n", (int)(srcptr - matrix->buffer), (int)(rawptr - raw));
     474        }
     475        *rawptr = *srcptr;
     476        myAssert (srcptr - matrix->buffer < Npix*size, "memory overrun");
     477        myAssert (rawptr - raw < Nraw*size, "memory overrun");
     478      }
     479
     480      // update the counters, carrying to the next dimension if needed
     481      for (j = 1; j < matrix->Naxes; j++) {
     482        counter[j] ++;
     483        if (counter[j] == Ztile[j]) {
     484          counter[j] = 0;
     485        } else {
     486          break;
     487        }
     488      }
     489      if (j == matrix->Naxes) assert (i == Nline - 1); // we should be done here...
     490
     491      // Naxes = 3
     492      // offset = counter[1]*matrix->Naxis[0] + counter[2]*matrix->Naxis[0]*matrix->Naxis[1] +
     493      // offset = matrix->Naxis[0]*(counter[1] + matrix->Naxis[1]*(counter[2] + matrix->Naxis[2]*...))
     494
     495      // determine the offset of the next line relative to the start position
     496      offset = counter[matrix->Naxes - 1];
     497      for (j = matrix->Naxes - 2; j >= 0; j--) {
     498        offset = offset*matrix->Naxis[j] + counter[j];
     499      }     
     500    }
     501  }
     502  pass ++;
     503
     504  free (counter);
     505  free (Ztile);
     506
     507  return (TRUE);
     508}
Note: See TracChangeset for help on using the changeset viewer.