IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 12, 2015, 6:18:23 PM (11 years ago)
Author:
eugene
Message:

merge changes from EAM dev branch ohana.20150429

Location:
trunk/Ohana
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana

  • trunk/Ohana/src/libfits/table/F_table_varlength.c

    r28241 r38441  
    22# include <gfitsio.h>
    33
     4// fills the column definition structure for a specific column based on a given table.
    45int gfits_varlength_column_define (FTable *ftable, VarLengthColumn *def, int column) {
    56
     
    1415  snprintf (field, 80, "TFORM%d", column);
    1516  if (!gfits_scan (ftable->header, field, "%s", 1, format)) return (FALSE);
     17
     18  def->column = column;
    1619
    1720  // find and remove the max field length element
     
    4851  if (*p1 == 'I') { def->nbytes = 2;  def->format = *p1; }
    4952  if (*p1 == 'J') { def->nbytes = 4;  def->format = *p1; }
     53  if (*p1 == 'K') { def->nbytes = 8;  def->format = *p1; }
    5054  if (*p1 == 'E') { def->nbytes = 4;  def->format = *p1; }
    5155  if (*p1 == 'D') { def->nbytes = 8;  def->format = *p1; }
     
    5458  if (!def->nbytes) { return (FALSE); }
    5559 
    56   /* scan columns to find column offset */
    57   def->Nstart = 0;
     60  /* scan columns to find column offset for metadata column*/
     61  def->offset = 0;
    5862  for (i = 1; i < column; i++) {
    5963    sprintf (field, "TFORM%d", i);
    6064    gfits_scan (ftable->header, field, "%s", 1, format);
    6165    gfits_bintable_format (format, tmpline, &Nv, &Nb);
    62     def->Nstart += Nv*Nb;
     66    def->offset += Nv*Nb;
    6367  }
    6468
    6569  // heap_start must be long long so file may be very large
    66   if (!gfits_scan (ftable->header, "THEAP", OFF_T_FMT, 1,  &def->heap_start)) {
    67     def->heap_start = ftable->header->Naxis[0]*ftable->header->Naxis[1];
    68   }
    69 
     70  // confirm that ftable->heap_start is correctly set?
     71
     72  return TRUE;
     73}
     74
     75# define SWAP_WORD \
     76  tmp = pchar[0]; pchar[0] = pchar[3]; pchar[3] = tmp; \
     77  tmp = pchar[1]; pchar[1] = pchar[2]; pchar[2] = tmp;
     78
     79# define SWAP_DBLE \
     80  tmp = pchar[0]; pchar[0] = pchar[7]; pchar[7] = tmp; \
     81  tmp = pchar[1]; pchar[1] = pchar[6]; pchar[6] = tmp; \
     82  tmp = pchar[2]; pchar[2] = pchar[5]; pchar[5] = tmp; \
     83  tmp = pchar[3]; pchar[3] = pchar[4]; pchar[4] = tmp;
     84
     85int gfits_byteswap_varlength_column (FTable *ftable, int column) {
     86
     87# ifdef BYTE_SWAP 
     88  VarLengthColumn zdef;
     89  if (!gfits_varlength_column_define (ftable, &zdef, column)) return FALSE;
     90
     91  char *bufstart = &ftable->buffer[zdef.offset];
     92
     93  int i;
     94  char *pchar, tmp;
     95
     96  off_t Nx = ftable->header->Naxis[0];
     97
     98  for (i = 0; i < ftable->header->Naxis[1]; i++) {
     99    if (zdef.mode == 'P') {
     100      pchar = &bufstart[i*Nx];
     101      SWAP_WORD;
     102      pchar = &bufstart[i*Nx + 4];
     103      SWAP_WORD;
     104    }     
     105    if (zdef.mode == 'Q') {
     106      char *pchar, tmp;
     107      pchar = &bufstart[i*Nx];
     108      SWAP_DBLE;
     109      pchar = &bufstart[i*Nx + 8];
     110      SWAP_DBLE;
     111    }
     112  }
     113# endif
    70114  return TRUE;
    71115}
     
    75119void *gfits_varlength_column_pointer (FTable *ftable, VarLengthColumn *column, off_t row, off_t *length) {
    76120
    77   void *result;
    78   off_t offset, Nx;
    79 
    80121  if ((column->mode != 'P') && (column->mode != 'Q')) abort();
    81122
    82123  // find the values for the specified row
    83124  // the values in the main table for this row and varlength column:
    84   Nx = ftable->header->Naxis[0];
    85 
    86 # define SWAP_WORD \
    87   tmp = pchar[0]; pchar[0] = pchar[3]; pchar[3] = tmp; \
    88   tmp = pchar[1]; pchar[1] = pchar[2]; pchar[2] = tmp;
    89 
    90 # ifdef BYTE_SWAP
    91   char *pchar, tmp;
    92   pchar = &ftable->buffer[row*Nx + column->Nstart];
    93   SWAP_WORD;
    94   pchar = &ftable->buffer[row*Nx + column->Nstart + 4];
    95   SWAP_WORD;
    96 # endif
     125  off_t Nx = ftable->header->Naxis[0];
     126  off_t offset = 0;
    97127
    98128  if (column->mode == 'P') {
    99129    int *ptr;
    100     ptr = (int *) &ftable->buffer[row*Nx + column->Nstart];
     130    ptr = (int *) &ftable->buffer[row*Nx + column->offset];
    101131    *length = ptr[0];
    102132    offset = ptr[1];
    103   } else if (column->mode == 'Q') {
     133  }
     134  if (column->mode == 'Q') {
    104135    off_t *ptr;
    105     ptr = (off_t *) &ftable->buffer[row*Nx + column->Nstart];
     136    ptr = (off_t *) &ftable->buffer[row*Nx + column->offset];
    106137    *length = ptr[0];
    107138    offset = ptr[1];
    108   } else {
    109         // this was actually trapped above
    110         abort();
    111   }
    112 
    113   result = (void *) (ftable->buffer + column->heap_start + offset);
     139  }
     140
     141  // fprintf (stderr, "length: %d, offset: %d\n", (int) *length, (int) offset);
     142
     143  void *result = (void *) (ftable->buffer + ftable->heap_start + offset);
    114144  return result;
    115145}
     146
     147// to generate a compressed image or a compressed table, we need to be able to add data
     148// for varlength columns to the heap.  To start, assume we have defined the cartesian
     149// portion of the table correctly, and are only extending the heap.
     150
     151int gfits_varlength_column_add_data (FTable *table, char *data, off_t Ndata, int row, VarLengthColumn *column) {
     152
     153  // find the current starting point for new data (end of current buffer main data + current heap
     154  off_t heap_offset = gfits_data_min_size (table->header);
     155
     156  // extend the buffer size to add the new data
     157  off_t Nbytes = gfits_data_pad_size (heap_offset + Ndata);
     158  REALLOCATE (table->buffer, char, Nbytes);
     159
     160  char *heap_ptr = table->buffer + heap_offset;
     161
     162  // add the new data to the table buffer
     163  memcpy (heap_ptr, data, Ndata);
     164
     165  // *** now we add the data description to the table ***
     166
     167  if ((column->mode != 'P') && (column->mode != 'Q')) abort();
     168
     169  // find the cell for the specified row & column
     170  // the values in the main table for this row and varlength column:
     171  int Nx = table->header->Naxis[0];
     172
     173  // set the cell values
     174  if (column->mode == 'P') {
     175    int *ptr;
     176    ptr = (int *) &table->buffer[row*Nx + column->offset];
     177    ptr[0] = Ndata;
     178    ptr[1] = heap_offset - table->heap_start;
     179  }
     180  if (column->mode == 'Q') {
     181    off_t *ptr;
     182    ptr = (off_t *) &table->buffer[row*Nx + column->offset];
     183    ptr[0] = Ndata;
     184    ptr[1] = heap_offset - table->heap_start;
     185  }
     186
     187  // update maxlen
     188  // fprintf (stderr, "row: %d, Ndata: %d, maxlen: %d\n", (int) row, (int) Ndata, (int) column->maxlen);
     189  column->maxlen = MAX (column->maxlen, Ndata);
     190
     191  off_t pcount;
     192  gfits_scan (table->header, "PCOUNT", OFF_T_FMT, 1, &pcount);
     193
     194  pcount += Ndata;
     195  gfits_modify (table->header, "PCOUNT", OFF_T_FMT, 1, pcount);
     196  table->header->pcount = pcount;
     197  table->datasize = gfits_data_size (table->header);
     198  myAssert (table->datasize == Nbytes, "inconsistent header and data");
     199
     200  return TRUE;
     201}
     202
     203// update the header TFORM value for this entry
     204int gfits_varlength_column_finish (FTable *ftable, VarLengthColumn *def) {
     205
     206  char field[81];
     207  char format[81];
     208
     209  // grab the value of TFORMn for this column
     210  snprintf (field, 80, "TFORM%d", def->column);
     211  if (!gfits_scan (ftable->header, field, "%s", 1, format)) return FALSE;
     212
     213  // find and update the max field length element
     214  char *p1 = strchr (format, '(');
     215  if (!p1) return (FALSE); // not a valid varlength column -- missing (e_max)
     216 
     217  p1 ++;
     218  *p1 = 0;
     219
     220  snprintf (p1, 80 - (p1 - format), "%d)", def->maxlen);
     221  if (!gfits_modify (ftable->header, field, "%s", 1, format)) return FALSE;
     222
     223  return TRUE;
     224}
Note: See TracChangeset for help on using the changeset viewer.