public software.sextractor

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

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