public software.sextractor

[/] [trunk/] [src/] [fits/] [fitstab.c] - Blame information for rev 233

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 bertin
/*
2 233 bertin
*                               fitstab.c
3 2 bertin
*
4 233 bertin
* Handle FITS extensions and tables.
5 2 bertin
*
6 233 bertin
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 2 bertin
*
8 233 bertin
*       This file part of:      AstrOmatic FITS/LDAC library
9 2 bertin
*
10 233 bertin
*       Copyright:              (C) 1998-2010 IAP/CNRS/UPMC
11
*                               (C) 1997 European Southern Observatory
12
*                               (C) 1995,1996 Sterrewacht Leiden
13 2 bertin
*
14 233 bertin
*       Author:                 Emmanuel Bertin (IAP)
15
*
16
*       License:                GNU General Public License
17
*
18
*       AstrOmatic software is free software: you can redistribute it and/or
19
*       modify it under the terms of the GNU General Public License as
20
*       published by the Free Software Foundation, either version 3 of the
21
*       License, or (at your option) any later version.
22
*       AstrOmatic software is distributed in the hope that it will be useful,
23
*       but WITHOUT ANY WARRANTY; without even the implied warranty of
24
*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
*       GNU General Public License for more details.
26
*       You should have received a copy of the GNU General Public License
27
*       along with AstrOmatic software.
28
*       If not, see <http://www.gnu.org/licenses/>.
29
*
30
*       Last modified:          09/10/2010
31
*
32
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
33 2 bertin
 
34
#ifdef  HAVE_CONFIG_H
35
#include "config.h"
36
#endif
37
 
38
#include        <stdio.h>
39
#include        <stdlib.h>
40
#include        <string.h>
41
 
42
#include        "fitscat_defs.h"
43
#include        "fitscat.h"
44
 
45
/****** about_tab **************************************************************
46
PROTO   int about_tab(catstruct *cat, char *tabname, FILE *stream)
47
PURPOSE Print information concerning a tab structure.
48
INPUT   Pointer to the input catalog,
49
        table name,
50
        an output stream.
51
OUTPUT  RETURN_OK if the table was found, RETURN_ERROR otherwise.
52
NOTES   -.
53
AUTHOR  E.R. Deul(Leiden observatory),
54
        E. Bertin (IAP & Leiden observatory): return value modified.
55
        E.R. Deul(Leiden observatory): output units
56 215 bertin
VERSION 28/10/2009
57 2 bertin
 ***/
58
int about_tab(catstruct *cat, char *tabname, FILE *stream)
59
{
60
   tabstruct *tab;
61
   keystruct *key;
62
   int          i, j;
63
 
64
   if ((tab = name_to_tab(cat, tabname, 0))) {
65
       fprintf(stream, "Table %s\n", tabname);
66
      for (i=0, key=tab->key; i<tab->nkey; i++,key=key->nextkey)
67
    {
68
    fprintf(stream,
69
        "****** Key #%d\n", i+1);
70
    fprintf(stream,
71
        "       Key name:...............%s\n", key->name);
72
    fprintf(stream,
73
        "       Key comment:............%s\n", key->comment);
74
    fprintf(stream,
75
        "       Key type:...............");
76
    switch (key->ttype) {
77
    case T_BYTE: fprintf(stream,"Byte"); break;
78
    case T_SHORT: fprintf(stream,"Short Int"); break;
79
    case T_LONG: fprintf(stream,"Long Int"); break;
80 215 bertin
    case T_LONGLONG: fprintf(stream,"Long Long Int"); break;
81 2 bertin
    case T_FLOAT: fprintf(stream,"Float"); break;
82
    case T_DOUBLE: fprintf(stream,"Double"); break;
83
    case T_STRING: fprintf(stream,"String"); break;
84
    }
85
    fprintf(stream,"\n");
86
    fprintf(stream,
87
        "       Key dimension:..........%d ", key->naxis);
88
    if (key->naxis) fprintf(stream, "(");
89
    for (j=0;j<key->naxis;j++) {
90
       if (j>0) fprintf(stream, " ");
91
       fprintf(stream, "%d", key->naxisn[j]);
92
    }
93
    if (key->naxis) fprintf(stream, ")");
94
    fprintf(stream, "\n");
95
    if (key->unit[0] != '\0')
96
       fprintf(stream,
97
        "       Key unit:...............%s\n", key->unit);
98
    }
99
   } else return RETURN_ERROR;
100
 
101
   return RETURN_OK;
102
}
103
 
104
/****** add_tab ****************************************************************
105
PROTO   int add_tab(tabstruct *tab, catstruct *cat, int pos)
106
PURPOSE Add a table to a catalog.
107
INPUT   Pointer to the table,
108
        Pointer to the destination catalog,
109
        Position (1= first after the primary HDU, <=0 = at the end).
110
OUTPUT  RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
111
NOTES   Only 1-segment tables are accepted. To copy multi-segment tables,
112
        use copy_tab() instead.
113
        If a table with the same name and basic attributes already exists in
114
        the destination catalog, then the new table is appended to it.
115
AUTHOR  E. Bertin (IAP & Leiden observatory)
116
VERSION 15/08/2003
117
 ***/
118
int     add_tab(tabstruct *tab, catstruct *cat, int pos)
119
 
120
  {
121
   tabstruct    *outtab, *prevtab;
122
   int          i;
123
 
124
/*Check if a similar table doesn't already exist in the dest. cat */
125
  if ((outtab = name_to_tab(cat, tab->extname, 0)))
126
    {
127
    if ((outtab->naxis != 2)
128
        || (outtab->bitpix!=8)
129
        || strcmp(outtab->xtension,tab->xtension)
130
        || (outtab->tfields != tab->tfields)
131
        || (outtab->naxisn[0] != tab->naxisn[0]))
132
      return RETURN_ERROR;
133
 
134
    prevtab = outtab;
135
    for (i=outtab->nseg-1; i--;)
136
      prevtab = prevtab->nexttab;
137
    tab->seg = prevtab->seg+1;
138
    tab->nseg = 0;
139
    outtab->nseg++;
140
    }
141
  else
142
    {
143
    if ((prevtab = pos_to_tab(cat, pos, 0)))
144
      prevtab = prevtab->prevtab;
145
    else
146
      tab->nexttab = tab->prevtab = prevtab = tab;
147
    cat->ntab++;
148
    }
149
 
150
  (tab->nexttab = (tab->prevtab = prevtab)->nexttab)->prevtab = tab;
151
  prevtab->nexttab = tab;
152
 
153
  return RETURN_OK;
154
  }
155
 
156
 
157
/****** copy_tab **************************************************************
158
PROTO   int copy_tab(catstruct *catin, char *tabname, int seg,
159
                catstruct *catout, int pos)
160
PURPOSE Copy a table from one catalog to another.
161
INPUT   Pointer to the original catalog,
162
        Name of the table,
163
        Table segment (0 = all),
164
        Pointer to the destination catalog,
165
        Position (1= first after the primary HDU, <=0 = at the end)
166
OUTPUT  RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
167
NOTES   If a table with the same name and basic attributes already exists in
168
        the destination catalog, then the original table is appended to it.
169
AUTHOR  E. Bertin (IAP & Leiden observatory)
170
VERSION 15/08/2003
171
 ***/
172
int     copy_tab(catstruct *catin, char *tabname, int seg,
173
                catstruct *catout, int pos)
174
 
175
  {
176
   keystruct    *key;
177
   tabstruct    *outtab, *prevtab, *nexttab, *tabin,*tabout;
178
   int          i,j, nseg;
179
 
180
/*Convert the table name to a pointer*/
181
  if (!(tabin = name_to_tab(catin, tabname, seg)))
182
    return RETURN_ERROR;
183
 
184
  nseg = seg?1:tabin->nseg;
185
/*Check if a similar table doesn't already exist in the dest. cat */
186
  if (*tabname && (outtab = name_to_tab(catout, tabname, 0)))
187
    {
188
    if ((outtab->naxis != 2)
189
        || (outtab->bitpix!=8)
190
        || strcmp(outtab->xtension,tabin->xtension)
191
        || (outtab->tfields != tabin->tfields)
192
        || (outtab->naxisn[0] != tabin->naxisn[0]))
193
      return RETURN_ERROR;
194
    prevtab = outtab;
195
    for (i=0; i<outtab->nseg-1; i++)
196
      prevtab = prevtab->nexttab;
197
    nexttab = prevtab->nexttab;
198
    outtab->nseg += nseg;
199
    }
200
  else
201
    {
202
    prevtab = nexttab = outtab = NULL;
203
    catout->ntab++;
204
    }
205
 
206
/*Now copy each segment of the original table*/
207
  tabout = NULL;        /* to satisfy gcc -Wall */
208
  for (i=nseg; i--;)
209
     {
210
/*---First, allocate memory and copy data */
211
     QCALLOC(tabout, tabstruct, 1);
212
     *tabout = *tabin;
213
     if (tabin->naxis)
214
       QMEMCPY(tabin->naxisn, tabout->naxisn, int, tabin->naxis);
215
     if (tabin->headbuf)
216
       QMEMCPY(tabin->headbuf, tabout->headbuf, char, tabin->headnblock*FBSIZE);
217
     if (tabin->bodybuf)
218
       QMEMCPY(tabin->bodybuf, tabout->bodybuf, char, tabin->tabsize);
219
 
220
     key = tabin->key;
221
     tabout->key = NULL;
222
     tabout->nkey = 0;
223
     for (j=tabin->nkey; j--;)
224
       {
225
       copy_key(tabin, key->name, tabout, 0);
226
       key = key->nextkey;
227
       }
228
 
229
/*---Then, update the links */
230
     if (prevtab)
231
       {
232
       prevtab->nexttab = tabout;
233
       tabout->prevtab = prevtab;
234
       tabout->seg = prevtab->seg+1;
235
       tabout->nseg = 0;
236
       }
237
     else
238
       {
239
       outtab = tabout;
240
       outtab->prevtab = NULL;
241
       tabout->seg = 1;
242
       }
243
     tabin = tabin->nexttab;
244
     prevtab = tabout;
245
     }
246
 
247
/*place the new chain of table-segments within the catalog (tricky, isn't it?)*/
248
  if (!nexttab)
249
/*--if the table is new */
250
    {
251
    nexttab = pos_to_tab(catout, pos, 0);
252
    if (!nexttab)
253
      nexttab = catout->tab = tabout;
254
    else
255
      {
256
      outtab->prevtab = nexttab->prevtab;
257
      nexttab->prevtab->nexttab = outtab;
258
      }
259
    }
260
 
261
  prevtab->nexttab = nexttab;
262
  nexttab->prevtab = prevtab;
263
 
264
  return RETURN_OK;
265
  }
266
 
267
 
268
/****** copy_tab_fromptr ******************************************************
269
PROTO   void copy_tab_fromptr(tabstruct *tabin, catstruct *catout, int pos)
270
PURPOSE Copy a table from one catalog to another.
271
INPUT   Pointer to the original catalog,
272
        Pointer to the table,
273
        Pointer to the destination catalog,
274
        Position (1= first after the primary HDU, <=0 = at the end)
275
OUTPUT  -.
276
NOTES   -.
277
AUTHOR  E. Bertin (IAP & Leiden observatory)
278
VERSION 22/06/2001
279
 ***/
280
void    copy_tab_fromptr(tabstruct *tabin, catstruct *catout, int pos)
281
 
282
  {
283
   keystruct    *key;
284
   tabstruct    *prevtab, *nexttab,*tabout;
285
   int          j;
286
 
287
  catout->ntab++;
288
 
289
/* First, allocate memory and copy data */
290
   QCALLOC(tabout, tabstruct, 1);
291
   *tabout = *tabin;
292
   if (tabin->naxis)
293
     QMEMCPY(tabin->naxisn, tabout->naxisn, int, tabin->naxis);
294
   if (tabin->headbuf)
295
     QMEMCPY(tabin->headbuf, tabout->headbuf, char, tabin->headnblock*FBSIZE);
296
   if (tabin->bodybuf)
297
     QMEMCPY(tabin->bodybuf, tabout->bodybuf, char, tabin->tabsize);
298
 
299
   key = tabin->key;
300
   tabout->key = NULL;
301
   tabout->nkey = 0;
302
   for (j=tabin->nkey; j--;)
303
     {
304
     copy_key(tabin, key->name, tabout, 0);
305
     key = key->nextkey;
306
     }
307
 
308
/* Then, update the links */
309
   tabout->prevtab = NULL;
310
   tabout->seg = 1;
311
   tabin = tabin->nexttab;
312
   prevtab = tabout;
313
 
314
  if (!(nexttab = pos_to_tab(catout, pos, 0)))
315
    nexttab = catout->tab = tabout;
316
  else
317
    {
318
    tabout->prevtab = nexttab->prevtab;
319
    nexttab->prevtab->nexttab = tabout;
320
    }
321
 
322
  prevtab->nexttab = nexttab;
323
  nexttab->prevtab = prevtab;
324
 
325
  return;
326
  }
327
 
328
 
329
/****** copy_tabs **************************************************************
330
PROTO   int copy_tabs(catstruct *catin, catstruct *catout)
331
PURPOSE Copy all tables from one catalog to another.
332
INPUT   Pointer to the original catalog,
333
        Pointer to the destination catalog,
334
OUTPUT  RETURN_OK if everything went as expected, and RETURN_ERROR otherwise
335
        (for instance if there were tabs that were not binary-tables, and
336
        therefore that were not copied).
337
NOTES   If a table with the same name and basic attributes already exists in
338
        the destination catalog, then the original table is appended to it.
339
AUTHOR  E. Bertin (IAP & Leiden observatory)
340
VERSION 12/06/2001
341
 ***/
342
int     copy_tabs(catstruct *catin, catstruct *catout)
343
 
344
  {
345
   tabstruct    *tab;
346
   int          i, flag, ntab;
347
 
348
  if (!catin->tab)
349
    return RETURN_ERROR;
350
 
351
  tab = catin->tab->nexttab;    /* skip the primary header */
352
  flag = RETURN_OK;
353
  ntab = catin->ntab-1;
354
  if (!ntab)
355
    ntab = 1;
356
  for (i=ntab; i--;)
357
    {
358
    flag |= copy_tab(catin, tab->extname, 0, catout, 0);
359
    while (!(tab=tab->nexttab)->nseg);
360
    }
361
 
362
  return flag;
363
  }
364
 
365
 
366
/****** copy_tabs_blind *******************************************************
367
PROTO   int copy_tabs(catstruct *catin, catstruct *catout)
368
PURPOSE Copy all tables from one catalog to another, without trying to append.
369
INPUT   Pointer to the original catalog,
370
        Pointer to the destination catalog,
371
OUTPUT  RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
372
NOTES   -.
373
AUTHOR  E. Bertin (IAP & Leiden observatory)
374
VERSION 07/05/2002
375
 ***/
376
int     copy_tabs_blind(catstruct *catin, catstruct *catout)
377
 
378
  {
379
   tabstruct    *tab;
380
   int          i, ntab;
381
 
382
  if (!catin->tab)
383
    return RETURN_ERROR;
384
 
385
  tab = catin->tab;     /* don't skip the primary header */
386
  ntab = catin->ntab;
387
  for (i=ntab; i--;)
388
    {
389
    copy_tab_fromptr(tab, catout, 0);
390
    tab=tab->nexttab;
391
    }
392
 
393
  return RETURN_OK;
394
  }
395
 
396
 
397
/****** free_tab ***************************************************************
398
PROTO   void free_tab(tabstruct *tab)
399
PURPOSE Free memory associated to a table pointer.
400
INPUT   Pointer to the table.
401
OUTPUT  -.
402
NOTES   -.
403
AUTHOR  E. Bertin (IAP & Leiden observatory)
404
VERSION 28/02/2000
405
 ***/
406
void    free_tab(tabstruct *tab)
407
 
408
  {
409
  free_body(tab);
410
  free(tab->naxisn);
411
  free(tab->headbuf);
412
  free(tab->compress_buf);
413
  remove_keys(tab);
414
  free(tab);
415
 
416
  return;
417
  }
418
 
419
 
420
/****** new_tab ****************************************************************
421
PROTO   tabstruct *new_tab(char *tabname)
422
PURPOSE Create a new binary table.
423
INPUT   Name.
424
OUTPUT  A pointer to the new table.
425
NOTES   A defaut header is also created.
426
        No links are initialized.
427
AUTHOR  E. Bertin (IAP & Leiden observatory)
428
VERSION 25/04/97
429
 ***/
430
tabstruct       *new_tab(char *tabname)
431
 
432
  {
433
   static char  bintabtemplate[][80] = {
434
"XTENSION= 'BINTABLE'           / THIS IS A BINARY TABLE (FROM THE LDACTOOLS)",
435
"BITPIX  =                    8 / ",
436
"NAXIS   =                    2 / ",
437
"NAXIS1  =                    0 / BYTES PER ROW",
438
"NAXIS2  =                    0 / NUMBER OF ROWS",
439
"PCOUNT  =                    0 / RANDOM PARAMETER COUNT",
440
"GCOUNT  =                    1 / GROUP COUNT",
441
"TFIELDS =                    0 / FIELDS PER ROWS",
442
"EXTNAME = 'WHOCARES'           / TABLE NAME",
443
"END                            "};
444
   tabstruct    *tab;
445
   char         *buf;
446
   int          i;
447
 
448
  QCALLOC(tab, tabstruct, 1);
449
  strcpy(tab->xtension, "BINTABLE");
450
  strcpy(tab->extname, tabname);
451
  tab->naxis = 2;
452
  QCALLOC(tab->naxisn, int, tab->naxis);
453
  tab->bitpix = 8;
454
  tab->bytepix = 1;
455
  tab->pcount = 0;
456
  tab->gcount = 1;
457
  tab->seg = 1;
458
  tab->nseg = 1;
459
/*Provide a new header*/
460
  QCALLOC(tab->headbuf, char, FBSIZE);
461
  memcpy(tab->headbuf, bintabtemplate, sizeof(bintabtemplate));
462
  for (buf = tab->headbuf, i=FBSIZE; i--; buf++)
463
    if (!*buf)
464
      *buf = ' ';
465
  tab->headnblock = 1;
466
 
467
  return tab;
468
  }
469
 
470
 
471
/****** remove_tab *************************************************************
472
PROTO   int remove_tab(catstruct *cat, char *tabname, int seg)
473
PURPOSE Remove a table from a catalog.
474
INPUT   Pointer to the catalog,
475
        Name of the table,
476
        Table segment (0 = all).
477
OUTPUT  RETURN_OK if everything went as expected, and RETURN_ERROR otherwise.
478
NOTES   If tabname = "", the last table from the list is removed.
479
AUTHOR  E. Bertin (IAP & Leiden observatory)
480
VERSION 15/08/2003
481
 ***/
482
int     remove_tab(catstruct *cat, char *tabname, int seg)
483
 
484
  {
485
   tabstruct    *tab, *prevtab, *nexttab;
486
   int          i,nseg;
487
 
488
  if (!tabname || !cat->ntab || !cat->tab)
489
    return RETURN_ERROR;
490
 
491
  if (tabname[0])
492
    {
493
/*--Convert the table name to a pointer*/
494
    if (!(tab = name_to_tab(cat, tabname, seg)))
495
      return RETURN_ERROR;
496
/*--a small trick to simplify decisions afterwards*/
497
    if (seg && tab->nseg==1)
498
      seg = 0;
499
    }
500
  else
501
    {
502
    tab = cat->tab->prevtab;
503
    if (!seg)
504
      for (;!tab->nseg; tab = tab->prevtab);
505
    }
506
 
507
  prevtab = tab->prevtab;
508
  nseg = seg?1:tab->nseg;
509
 
510
/*Free memory for each table segment*/
511
  nexttab = NULL;       /* to satisfy gcc -Wall */
512
  for (i=nseg; i--;)
513
    {
514
    nexttab = tab->nexttab;
515
    if (cat->tab == tab)
516
      cat->tab = nexttab;
517
    free_tab(tab);
518
    tab = nexttab;
519
    }
520
 
521
  if (!seg)
522
    if (!--cat->ntab)
523
      {
524
      cat->tab = NULL;
525
      return RETURN_OK;
526
      }
527
 
528
/*update the links of neighbours*/
529
  nexttab->prevtab = prevtab;
530
  prevtab->nexttab = nexttab;
531
 
532
  if (seg)
533
/*--update status for each table segment*/
534
    {
535
    for (tab=prevtab;!tab->nseg; tab = tab->prevtab);
536
    for (nexttab=tab->nexttab,i=2;!nexttab->nseg;nexttab=nexttab->nexttab,i++);
537
      nexttab->seg = i;
538
    tab->nseg = i;
539
    tab->seg = 1;
540
    }
541
 
542
  return RETURN_OK;
543
  }
544
 
545
 
546
/****** remove_tabs ************************************************************
547
PROTO   int remove_tabs(catstruct *cat)
548
PURPOSE Remove all tables from a catalog.
549
INPUT   Pointer to the catalog.
550
OUTPUT  RETURN_OK if tabs were found, and RETURN_ERROR otherwise.
551
NOTES   -.
552
AUTHOR  E. Bertin (IAP & Leiden observatory)
553
VERSION 25/05/97
554
 ***/
555
int     remove_tabs(catstruct *cat)
556
 
557
  {
558
   int  t;
559
 
560
  if (!cat->tab)
561
    return RETURN_ERROR;
562
 
563
  for (t=cat->ntab; t--;)
564
    remove_tab(cat, "",0);
565
 
566
  return RETURN_OK;
567
  }
568
 
569
 
570
/****** update_tab ************************************************************
571
PROTO   int update_tab(tabstruct *tab)
572
PURPOSE Update a table according to what's in the keys.
573
INPUT   Table structure.
574
OUTPUT  RETURN_OK if tab is a binary table, or RETURN_ERROR otherwise.
575
NOTES   The headbuf pointer in the catstruct might be reallocated.
576
AUTHOR  E. Bertin (IAP & Leiden observatory)
577
VERSION 08/02/97
578
 ***/
579
int     update_tab(tabstruct *tab)
580
 
581
  {
582
   tabstruct    *keytab;
583
   keystruct    *key;
584
   int          i,j, nobj, nbytes;
585
 
586
/*Just pass if not a binary table*/
587
  if ((tab->naxis != 2)
588
        || (tab->bitpix!=8)
589
        || strncmp(tab->xtension, "BINTABLE", 8))
590
    return RETURN_ERROR;
591
 
592
/*Well, not much to do if there are no keys!*/
593
  if (!(key = tab->key))
594
    return RETURN_OK;
595
 
596
  nobj = -1;
597
  keytab = NULL;
598
  nbytes = 0;
599
  for (i=tab->nkey; i--;)
600
    {
601
    if (keytab && !key->ptr && key->tab != keytab)
602
      error(EXIT_FAILURE, "*Error*: wrong reference table in ",
603
        key->name);
604
    if (nobj!=-1 && (nobj != key->nobj))
605
      error(EXIT_FAILURE, "*Error*: wrong number of elements in key ",
606
        key->name);
607
    keytab = key->tab;
608
    nobj = key->nobj;
609
/*-- If the number of bytes per element is not set, recover it */
610
    if (!key->nbytes)
611
      {
612
      key->nbytes = t_size[key->ttype];
613
      for (j=key->naxis; j--;)
614
        key->nbytes *= key->naxisn[j];
615
      }
616
    nbytes += key->nbytes;
617
    key = key->nextkey;
618
    }
619
 
620
  tab->tabsize = nobj*nbytes;
621
  tab->naxisn[0] = nbytes;
622
  tab->naxisn[1] = nobj;
623
  tab->tfields = tab->nkey;
624
 
625
  return RETURN_OK;
626
  }
627
 
628
 
629
/****** name_to_tab ***********************************************************
630
PROTO   tabstruct *name_to_tab(catstruct *cat, char *tabname, int seg)
631
PURPOSE Name search of a table in a catalog.
632
INPUT   Pointer to the catalog,
633
        Table name,
634
        Table segment (0 = first).
635
OUTPUT  The table pointer if the name was matched, and NULL otherwise.
636
NOTES   -
637
VERSION 12/06/2001
638
 ***/
639
tabstruct       *name_to_tab(catstruct *cat, char *tabname, int seg)
640
 
641
  {
642
   tabstruct    *tab;
643
   int          i;
644
 
645
  if (!(tab = cat->tab))
646
    return NULL;
647
 
648
  for (i=cat->ntab; strcmp(tabname,tab->extname) && i--;)
649
    while (!(tab=tab->nexttab)->nseg);
650
 
651
  if (i<0)
652
    return NULL;
653
 
654
  if (seg)
655
    {
656
    for (;tab->seg!=seg && !tab->nexttab->nseg; tab=tab->nexttab);
657
    return tab->seg==seg?tab:NULL;
658
    }
659
 
660
  return tab;
661
  }
662
 
663
 
664
/****** pos_to_tab *************************************************************
665
PROTO   tabstruct *pos_to_tab(catstruct *cat, int pos, int seg)
666
PURPOSE Position search of a table in a catalog.
667
INPUT   Pointer to the catalog,
668
        Position of the table,
669
        Table segment (0 = first).
670
OUTPUT  The table pointer if the table exists at the given position, and the
671
        pointer to the primary ``table'' otherwise.
672
NOTES   pos = 1 means the first table after the primary one.
673
AUTHOR  E. Bertin (IAP & Leiden observatory)
674
VERSION 15/02/96
675
 ***/
676
tabstruct       *pos_to_tab(catstruct *cat, int pos, int seg)
677
 
678
  {
679
   tabstruct    *tab;
680
   int          i;
681
 
682
  tab = cat->tab;
683
  for (i=0; i!=pos && i<cat->ntab; i++)
684
    while (!(tab=tab->nexttab)->nseg);
685
 
686
  if (seg)
687
    for (;tab->seg!=seg && !tab->nexttab->nseg; tab=tab->nexttab);
688
 
689
  return i<cat->ntab?tab:cat->tab;
690
  }
691
 
692
/****** tabs_list **************************************************************
693
PROTO   char **tabs_list(catstruct *cat, int *n)
694
PURPOSE List all tables in a catalog.
695
INPUT   Pointer to the catalog,
696
        Pointer to the number of names in that list.
697
OUTPUT  A list of all table names.
698
NOTES   -.
699
AUTHOR  E.R. Deul (Leiden observatory)
700
VERSION ??/??/96
701
 ***/
702
char **tabs_list(catstruct *cat, int *n)
703
 
704
  {
705
   tabstruct    *tab;
706
   int          i;
707
   char         **names;
708
 
709
  tab = cat->tab;
710
  QCALLOC(names, char *, cat->ntab);
711
  for (i=0; i<cat->ntab; i++) {
712
    QCALLOC(names[i], char, MAXCHARS);
713
    strcpy(names[i],tab->extname);
714
    while (!(tab=tab->nexttab)->nseg);
715
  }
716
  *n = cat->ntab;
717
  return names;
718
  }
719
 
720
/****** tabs_row_len ***********************************************************
721
PROTO   int tab_row_len(char *file, char *tabname)
722
PURPOSE Return the row length in bytes of a given table in a given catalog.
723
INPUT   File pointer.
724
OUTPUT  Table size (bytes)
725
NOTES   -.
726
AUTHOR  E.R. Deul (Leiden observatory)
727
VERSION 05/06/200`
728
 ***/
729
int tab_row_len(char *file, char *tabname)
730
 
731
{
732
    catstruct   *tcat;
733
    tabstruct   *tab;
734
    int         retcode = -1;
735
 
736
    if ((tcat = read_cat(file)) != NULL) {
737
       if ((tab = name_to_tab(tcat, tabname, 0)) != NULL) {
738
          retcode = tab->naxisn[0];
739
          free_tab(tab);
740
       }
741
       close_cat(tcat);
742
       free_cat(&tcat,1);
743
    }
744
    return retcode;
745
}
746