home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / hdf / unix / hdf3_2r2 / src / dfr8.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-30  |  35.8 KB  |  1,051 lines

  1. /***************************************************************************
  2. *
  3. *
  4. *                         NCSA HDF version 3.2r2
  5. *                            October 30, 1992
  6. *
  7. * NCSA HDF Version 3.2 source code and documentation are in the public
  8. * domain.  Specifically, we give to the public domain all rights for future
  9. * licensing of the source code, all resale rights, and all publishing rights.
  10. *
  11. * We ask, but do not require, that the following message be included in all
  12. * derived works:
  13. *
  14. * Portions developed at the National Center for Supercomputing Applications at
  15. * the University of Illinois at Urbana-Champaign, in collaboration with the
  16. * Information Technology Institute of Singapore.
  17. *
  18. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  19. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  20. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  21. *
  22. ****************************************************************************
  23. */
  24.  
  25. #ifdef RCSID
  26. static char RcsId[] = "@(#)$Revision: 1.5 $";
  27. #endif
  28. /*
  29. $Header: /hdf/hdf/v3.2r2/src/RCS/dfr8.c,v 1.5 1992/10/30 18:36:52 koziol beta koziol $
  30.  
  31. $Log: dfr8.c,v $
  32.  * Revision 1.5  1992/10/30  18:36:52  koziol
  33.  * Fixed casts in a bunch of functions to make the SGI ANSI compiler happy
  34.  *
  35.  * Revision 1.4  1992/10/23  00:14:11  koziol
  36.  * Changed all DFIstr*() and DFImem*() calls to HDstr*() and HDmem*() calls
  37.  * #ifdef'd out the macros Jason defined for Hopen, Hclose, etc. for Vsets
  38.  * Replaced Vset VFREESPACE and VGETSPACE calls with actual calls to HDfreespace
  39.  * and HDgetspace
  40.  * Added a MS-Windows lower lower for file I/O (which may not be completely working
  41.  *
  42.  * Revision 1.3  1992/10/12  18:11:51  koziol
  43.  * Updated for v3.2r2 release
  44.  *
  45.  * Revision 1.2  1992/09/17  20:02:56  koziol
  46.  * Included Shiming's bugfix to RIG stuff
  47.  *
  48.  * Revision 1.1  1992/08/25  21:40:44  koziol
  49.  * Initial revision
  50.  *
  51. */
  52. /*-----------------------------------------------------------------------------
  53.  * File:    dfr8.c
  54.  * Purpose: read and write 8-bit Raster Image Groups
  55.  * Invokes: df.c, dfcomp.c, dfgroup.c, dfrig.h
  56.  * Contents:
  57.  *  DFR8getdims: retrieve information about 8-bit image dimensions
  58.  *  DFR8getimage: retrieve 8-bit image and associated palette
  59.  *  DFR8setpalette: specify palette to be used with subsequent 8-bit images
  60.  *  DFR8Iputimage: internal routine that write 8-bit images to files
  61.  *  DFR8putimage: write 8-bit image into an HDF file
  62.  *  DFR8addimage: append another 8-bit image to an HDF file
  63.  *  DFR8getrig: read in a raster image group for 8-bit images
  64.  *  DFR8putrig: write out a raster image group for 8-bit images
  65.  *  DFR8nimages: number of images in HDF file
  66.  *  DFR8readref: get image with this reference number next
  67.  *  DFR8writeref: put image with this reference number next
  68.  *  DFR8restart: forget info about last file accessed - restart from beginning
  69.  *  DFR8lastref: return reference number of last element read or written
  70.  *  DFR8Iopen: open/reopen file
  71.  *  DFR8Iriginfo: obtain info about next RIG/RI8 to get
  72.  * Remarks: A RIG specifies attributes associated with an image - palette,
  73.  *          dimension, compression, color compensation etc.
  74.  *          The palette for an 8-bit image is assumed to always be 768 bytes
  75.  *          The palette is arranged as RGBRGB...
  76.  *---------------------------------------------------------------------------*/
  77.  
  78. #include "hdf.h"
  79. #include "herr.h"
  80. #include "dfrig.h"
  81.  
  82. static int foundRig = -1;      /* -1: don't know if HDF file has RIGs */
  83.                                /* 0: No RIGs, try for RI8s etc. */
  84.                                /* 1: RIGs used, ignore RI8s etc. */
  85. static DFRrig Readrig;         /* information about RIG being read */
  86. static DFRrig Writerig;        /* information about RIG being written */
  87. static int Newdata = 0;        /* does Readrig contain fresh data? */
  88. static uint16 Writeref=0;      /* ref of next image to put in this file */
  89. static int Newpalette=(-1);    /* -1 = no palette is associated */
  90.                                /* 0 = palette already written out */
  91.                                /* 1 = new palette, not yet written out */
  92. static uint8 Palette[768];      /* to store palette for 8-bit images */
  93. static uint16 Refset=0;        /* Ref of image to get next */
  94. static uint16 Lastref = 0;     /* Last ref read/written */
  95. static DFRrig Zrig = {         /* empty RIG for initialization */
  96.     {0, 0}, {0, 0, {0, 0}, 0, 0, {0, 0}},
  97.     {0, 0}, {0, 0, {0, 0}, 0, 0, {0, 0}},
  98.     {0, 0}, {0, 0, {0, 0}, 0, 0, {0, 0}},
  99.     0, 0, (float32)0.0, (float32)0.0,
  100.     {(float32)0.0, (float32)0.0, (float32)0.0},
  101.     {(float32)0.0, (float32)0.0, (float32)0.0},
  102.     {(float32)0.0, (float32)0.0, (float32)0.0},
  103.     {(float32)0.0, (float32)0.0, (float32)0.0}, NULL
  104. };
  105.  
  106. #ifdef PERM_OUT
  107. #ifndef VMS
  108. int32 DFR8Iopen();
  109. #else /*VMS*/
  110. int32 _DFR8Iopen();
  111. #endif
  112. #endif
  113.  
  114. typedef struct R8dim {
  115.     uint16 xd;
  116.     uint16 yd;
  117. } R8dim;                       /* dimensions of raster-8 image */
  118.  
  119. /* private functions */
  120. #ifdef PROTOTYPE
  121. PRIVATE intn DFR8Iputimage(char *filename, VOIDP image, int32 xdim, int32 ydim,
  122.                          uint16 compress, int op);
  123. PRIVATE int DFR8getrig(int32 file_id, uint16 ref, DFRrig *rig);
  124. PRIVATE int DFR8putrig(int32 file_id, uint16 ref, DFRrig *rig, int wdim);
  125. PRIVATE int32 DFR8Iopen(char *filename, int access);
  126. PRIVATE int DFR8Iriginfo(int32 file_id);
  127. #else
  128. PRIVATE intn DFR8Iputimage();
  129. PRIVATE int DFR8getrig();
  130. PRIVATE int DFR8putrig();
  131. PRIVATE int32 DFR8Iopen();
  132. PRIVATE int DFR8Iriginfo();
  133. #endif
  134.  
  135. uint8 R8tbuf[512];
  136.  
  137. /*-----------------------------------------------------------------------------
  138.  * Name:    DFR8getdims
  139.  * Purpose: get dimensions of next image from RIG, also if there is a palette
  140.  * Inputs:  filename: name of HDF file
  141.  *          pxdim, pxdim, pointer to locations for returning x,y dimensions
  142.  *          pispal: pointer to location for rtning whether there is a palette
  143.  * Returns: 0 on success, -1 on failure with DFerror set
  144.  *          *pxdim, *pydim are set to dimensions of the next image
  145.  *          *pispal is set to 1 if a palette is associated with it, else 0
  146.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  147.  * Invokes: DFR8Iopen, DFclose, DFR8Iriginfo, DFIerr
  148.  * Remarks: will also handle file with just raster-8 tags: RI8, CI8, ID8, IP8
  149.  *---------------------------------------------------------------------------*/
  150.  
  151. #ifdef PROTOTYPE
  152. intn DFR8getdims(char *filename, int32 *pxdim, int32 *pydim, intn *pispal)
  153. #else
  154. intn DFR8getdims(filename, pxdim, pydim, pispal)
  155.     char *filename;
  156.     int32 *pxdim, *pydim;
  157.     intn *pispal;
  158. #endif
  159. {
  160.     char *FUNC="DFR8getdims";
  161.     int32 file_id;
  162.  
  163.     HEclear();
  164.  
  165.     if (!filename || !*filename || !pxdim || !pydim) {
  166.         HERROR(DFE_ARGS);
  167.         return FAIL;
  168.     }
  169.  
  170.     file_id = DFR8Iopen(filename, DFACC_READ);
  171.     if (file_id == FAIL) {
  172.        return FAIL;
  173.     }
  174.  
  175.     if (DFR8Iriginfo(file_id) == FAIL) /* reads next RIG or RI8 from file */
  176.         return(HDerr(file_id)); /* on error, close file and return -1 */
  177.  
  178.     Newdata = 1;
  179.     *pxdim = Readrig.descimage.xdim;
  180.     *pydim = Readrig.descimage.ydim;
  181.     if (pispal) *pispal = Readrig.lut.tag ? 1 : 0; /* is there a palette */
  182.  
  183.     return(Hclose(file_id));
  184. }
  185.  
  186. /*-----------------------------------------------------------------------------
  187.  * Name:    DFR8getimage
  188.  * Purpose: get next image from a RIG, get palette also if desired
  189.  * Inputs:  filename: name of HDF file
  190.  *          image: space to read image into
  191.  *          xdim, ydim: dimensions of space allocated by user for image
  192.  *          pal: 768-byte space for palette, null if palette not wanted
  193.  * Returns: 0 on success, -1 on failure with DFerror set
  194.  *          image in image, palette in pal
  195.  * Users:   HDF HLL users, utilities, other routines
  196.  * Invokes: DFR8Iopen, DFR8Iriginfo, HDerr, DFclose, DFgetelement, DFgetcomp
  197.  * Remarks: Will also get RI8s and CI8s if no RIGs in file
  198.  *          Normally,DFR8getdims is called first and it finds next image to get
  199.  *          But if that is not called, DFR8getimage will itself find next image
  200.  *          Automatically decompresses images
  201.  *---------------------------------------------------------------------------*/
  202.  
  203. #ifdef PROTOTYPE
  204. intn DFR8getimage(char *filename, uint8 *image, int32 xdim, int32 ydim,
  205.                 uint8 *pal)
  206. #else
  207. intn DFR8getimage(filename, image, xdim, ydim, pal)
  208.     char *filename;
  209.     int32 xdim, ydim;
  210.     uint8 *image;
  211.     uint8 *pal;
  212. #endif
  213. {
  214.     char *FUNC="DFR8getimage";
  215.     int32 file_id;
  216.  
  217.     HEclear();
  218.  
  219.     if (!filename || !*filename || !image
  220.        || (xdim<=0) || (ydim<=0)) {
  221.        HERROR(DFE_ARGS);
  222.         return FAIL;
  223.     }
  224.  
  225.     file_id = DFR8Iopen(filename, DFACC_READ);
  226.     if (file_id == FAIL) {
  227.        return(FAIL);
  228.     }
  229.  
  230.     if (!Newdata) {            /* if Readrig not fresh */
  231.         if (DFR8Iriginfo(file_id) == FAIL) /*reads next RIG or RI8 from file */
  232.             return(HDerr(file_id)); /* on error, close file and return -1 */
  233.     }
  234.     Newdata = 0;               /* read new RIG next time */
  235.  
  236.     if ((Readrig.descimage.xdim > xdim) || (Readrig.descimage.ydim > ydim)) {
  237.        HERROR(DFE_ARGS);
  238.         return(HDerr(file_id));
  239.     }
  240.  
  241.     /* read image */
  242.     if (Readrig.descimage.compr.tag) { /* compressed image */
  243.         if (DFgetcomp(file_id, Readrig.image.tag, Readrig.image.ref, image,
  244.                      Readrig.descimage.xdim, Readrig.descimage.ydim,
  245.                      Readrig.descimage.compr.tag) == FAIL)
  246.             return(HDerr(file_id));
  247.     } else {                   /* non-compressed raster image */
  248.         if (Hgetelement(file_id, Readrig.image.tag,
  249.                        Readrig.image.ref, (uint8 *)image) == FAIL)
  250.             return(HDerr(file_id));
  251.     }
  252.  
  253.     if (xdim > Readrig.descimage.xdim) {
  254.        int32 off1, off2;
  255.        int32 x, y;
  256.  
  257.        off1 = (Readrig.descimage.ydim - 1) * xdim;
  258.        off2 = (Readrig.descimage.ydim - 1) * Readrig.descimage.xdim;
  259.        for (y = Readrig.descimage.ydim - 1; y > 0; y-- ) {
  260.            for (x = Readrig.descimage.xdim - 1; x >= 0; x--)
  261.                image[off1+x] = image[off2+x];
  262.            off1 -= xdim;
  263.            off2 -= Readrig.descimage.xdim;
  264.        }
  265.     }
  266.  
  267.     if (pal && Readrig.lut.tag) { /* read palette */
  268.         if (Hgetelement(file_id, Readrig.lut.tag, 
  269.                                Readrig.lut.ref,(uint8 *)pal) == FAIL)
  270.             return(HDerr(file_id));
  271.     }
  272.     return(Hclose(file_id));
  273. }
  274.  
  275. /*-----------------------------------------------------------------------------
  276.  * Name:    DFR8setpalette
  277.  * Purpose: set palette for subsequent images
  278.  * Inputs:  pal: palette to set
  279.  * Returns: 0 on success, -1 on failure with DFerror set
  280.  * Users:   HDF users, utilities, other routines
  281.  * Invokes: none
  282.  * Remarks: if pal is NULL, no palette is associated with subsequent images
  283.  *---------------------------------------------------------------------------*/
  284.  
  285. #ifdef PROTOTYPE
  286. int DFR8setpalette(uint8 *pal)
  287. #else
  288. int DFR8setpalette(pal)
  289.     uint8 *pal;
  290. #endif
  291. {
  292. /*    char *FUNC="DFR8setpalette"; */
  293.     int i;
  294.  
  295. /*    HEclear(); */
  296.  
  297.     if (!pal) {
  298.         Newpalette = -1;       /* no palette */
  299.         Writerig.lut.tag = 0;
  300.         Writerig.lut.ref = 0;   /* forget tag/ref of previous palette */
  301.         Writerig.desclut.xdim = 0;
  302.         Writerig.desclut.ncomponents = 0;
  303.     } else {                   /* store palette */
  304.         for (i=0; i<768; i++)
  305.             Palette[i] = pal[i];
  306.         Newpalette = 1;
  307.     }
  308.     return SUCCEED;
  309. }
  310.  
  311. /*-----------------------------------------------------------------------------
  312.  * Name:    DFR8Iputimage
  313.  * Purpose: Internal routine to write RIG to file
  314.  * Inputs:  filename: name of HDF file
  315.  *          image: image to be written to file
  316.  *          xdim, ydim: dimensions of image
  317.  *          compress: compression scheme to be used on image, 0 if none
  318.  *                    possible values are DFTAG_RLE and DFTAG_IMC
  319.  *          op: 0 will overwrite existing file, 1 will append image to file
  320.  * Returns: 0 on success, -1 on failure with DFerror set
  321.  * Users:   HDF systems programmers, DFR8putimage, DFR8addimage
  322.  * Invokes: DFR8Iopen, DFclose, DFputelement, DFdup, DFR8putrig, DFputcomp,
  323.  *          HDerr
  324.  * Remarks: Palette will be associated with image is isPalette is 1
  325.  *          Palette will be written to file if not written before (Palref=0)
  326.  *          Creates both RIG and RI8/CI8 tags, to accomodate older programs
  327.  *---------------------------------------------------------------------------*/
  328.  
  329. #ifdef PROTOTYPE
  330. PRIVATE intn DFR8Iputimage(char *filename, VOIDP image, int32 xdim, int32 ydim,
  331.                          uint16 compress, int op)
  332. #else
  333. PRIVATE intn DFR8Iputimage(filename, image, xdim, ydim, compress, op)
  334.     char *filename;
  335.     int32 xdim, ydim;
  336.     VOIDP image;
  337.     uint16 compress;            /* compression scheme */
  338.     int op;                     /* 0 is a put, 1 is a putnext */
  339. #endif
  340. {
  341.     char *FUNC="DFR8Iputimage";
  342.     int access;                        /* create if op 0, write if op 1 */
  343.     int32 file_id;
  344.     uint16 r8tag;              /*RIG and raster tags of image being written */
  345.     uint8 *pal;                 /* pointer to palette to be written */
  346.     uint8 newpal[768];          /*Imcomp creates new palette to be associated*/
  347.     int wdim;                  /* have dimensions already been written out? */
  348.  
  349.     HEclear();
  350.  
  351.     if (!filename || !*filename || !image
  352.        || (xdim<=0) || (ydim<=0)) {
  353.        HERROR(DFE_ARGS);
  354.         return FAIL;
  355.     }
  356.     pal = (Newpalette>=0) ? Palette : NULL;
  357.     access = op ? DFACC_WRITE : DFACC_CREATE;
  358.  
  359.     file_id = DFR8Iopen(filename, access);
  360.     if (file_id==FAIL) {
  361.        return FAIL;
  362.     }
  363.  
  364.     if (!Writeref) Writeref = Hnewref(file_id);
  365.     if (Writeref == 0) {
  366.        return FAIL;
  367.     }
  368.  
  369.     /* write out image */
  370.     if (compress) {
  371.         if (DFputcomp(file_id, DFTAG_CI, Writeref, (uint8*)image, xdim, ydim,
  372.                      (uint8*)pal, (uint8*)newpal, compress) == FAIL)
  373.             return(HDerr(file_id));
  374.         Writerig.image.tag = DFTAG_CI;
  375.         if (compress==DFTAG_IMC) {
  376.             pal = newpal;      /* Imcomp creates new pal */
  377.             Newpalette = 1;    /* write out palette */
  378.         }
  379.     } else {                   /* image need not be compressed */
  380.         if (Hputelement(file_id, DFTAG_RI, Writeref, 
  381.                                      (uint8 *)image, xdim*ydim) == FAIL)
  382.             return(HDerr(file_id));
  383.         Writerig.image.tag = DFTAG_RI;
  384.     }
  385.     Writerig.image.ref = Writeref;
  386.     Writerig.descimage.ncomponents = 1;
  387.     Writerig.aspectratio = (float32)1.0;
  388.  
  389.     /* Write out Raster-8 tags for those who want it */
  390.     r8tag = compress ?
  391.        ((compress==DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8;
  392.     if (Hdupdd(file_id, r8tag, Writeref, Writerig.image.tag, Writeref) == FAIL)
  393.         return(HDerr(file_id));
  394.  
  395.     /* Write out palette */
  396.     if (pal) {                 /* if there is a palette */
  397.         if (Newpalette==1) {   /* write palette */
  398.             if (Hputelement(file_id, DFTAG_LUT, Writeref, 
  399.                                    (uint8 *)pal, (int32) 768) == FAIL)
  400.                 return(HDerr(file_id));
  401.             Writerig.lut.tag = DFTAG_LUT;
  402.             Writerig.lut.ref = Writeref;
  403.             Writerig.desclut.xdim = 768;
  404.             Writerig.desclut.ncomponents = 1;
  405.         }
  406.         if (compress!=DFTAG_IMC) Newpalette = 0;
  407.        /* if IMCOMP, original palette not written out */
  408.  
  409.        /* put in Raster-8 stuff also, for those who want it */
  410.        Hdeldd(file_id, DFTAG_IP8, Writeref);
  411.         if (Hdupdd(file_id, DFTAG_IP8, Writeref, Writerig.lut.tag,
  412.                   Writerig.lut.ref) == FAIL)
  413.             return(HDerr(file_id));
  414.     }
  415.  
  416.     /* Write out RIG */
  417.     if ((Writerig.descimage.xdim==xdim) && (Writerig.descimage.ydim==ydim) &&
  418.        (Writerig.descimage.compr.tag==compress))
  419.         wdim = 0;
  420.     else {
  421.         wdim = 1;
  422.         Writerig.descimage.xdim = xdim;
  423.         Writerig.descimage.ydim = ydim;
  424.         Writerig.descimage.compr.tag = compress;
  425.     }
  426.     if (DFR8putrig(file_id, Writeref, &Writerig, wdim)
  427.        == FAIL)                /* writes ID, NT */
  428.         return(HDerr(file_id));
  429.  
  430.     Lastref = Writeref;                /* remember ref written */
  431.  
  432.     Writeref = 0;               /* don't know ref to write next */
  433.  
  434.     return(Hclose(file_id));
  435. }
  436.  
  437. /*-----------------------------------------------------------------------------
  438.  * Name:    DFR8putimage
  439.  * Purpose: Write RIG to HDF file
  440.  * Inputs:  filename: name of HDF file
  441.  *          image: image to be written to file
  442.  *          xdim, ydim: dimensions of image
  443.  *          compress: compression scheme to be used on image, 0 if none
  444.  * Returns: 0 on success, -1 on failure with DFerror set
  445.  * Users:   HDF HLL users, utilities, other routines
  446.  * Invokes: DFR8Iputimage
  447.  * Remarks: overwrites existing HDF file
  448.  *---------------------------------------------------------------------------*/
  449.  
  450. #ifdef PROTOTYPE
  451. int DFR8putimage(char *filename, VOIDP image, int32 xdim, int32 ydim,
  452.                 uint16 compress)
  453. #else
  454. int DFR8putimage(filename, image, xdim, ydim, compress)
  455.     char *filename;
  456.     int32 xdim, ydim;
  457.     VOIDP image;
  458.     uint16 compress;
  459. #endif
  460. {
  461.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 0));
  462. }
  463.  
  464.  
  465. /*-----------------------------------------------------------------------------
  466.  * Name:    DFR8addimage
  467.  * Purpose: Append RIG to HDF file
  468.  * Inputs:  filename: name of HDF file
  469.  *          image: image to be written to file
  470.  *          xdim, ydim: dimensions of image
  471.  *          compress: compression scheme to be used on image, 0 if none
  472.  * Returns: 0 on success, -1 on failure with DFerror set
  473.  * Users:   HDF HLL users, utilities, other routines
  474.  * Invokes: DFR8Iputimage
  475.  * Remarks: inserts image into existing file, will create file if necessary
  476.  *---------------------------------------------------------------------------*/
  477.  
  478. #ifdef PROTOTYPE
  479. int DFR8addimage(char *filename, VOIDP image, int32 xdim, int32 ydim,
  480.                 uint16 compress)
  481. #else
  482. int DFR8addimage(filename, image, xdim, ydim, compress)
  483.     char *filename;
  484.     int32 xdim, ydim;
  485.     VOIDP image;
  486.     uint16 compress;
  487. #endif
  488. {
  489.     return(DFR8Iputimage(filename, image, xdim, ydim, compress, 1));
  490. }
  491.  
  492.  
  493. /*****************************************************************************/
  494. /* This is the next lower layer - procedures to get and put a RIG. */
  495. /* These are specific to 8-bit */
  496. /*****************************************************************************/
  497.  
  498. /*-----------------------------------------------------------------------------
  499.  * Name:    DFR8getrig
  500.  * Purpose: Read a RIG into memory
  501.  * Inputs:  file_id: pointer to HDF file containing RIG
  502.  *          ref: reference number of RIG to get
  503.  *          rig: struct in which to place info obtained
  504.  * Returns: 0 on success, -1 on failure with DFerror set
  505.  *          contents of RIG in the struct rig
  506.  * Users:   HDF programmers, utilities, DFR8getdims,DFR8getimage
  507.  * Invokes: DFdiget, DFdinext, DFIcheck, DFgetelement
  508.  * Remarks: assumes 8-bit
  509.  *---------------------------------------------------------------------------*/
  510.  
  511. #ifdef PROTOTYPE
  512. PRIVATE int DFR8getrig(int32 file_id, uint16 ref, DFRrig *rig)
  513. #else
  514. PRIVATE int DFR8getrig(file_id, ref, rig)
  515.     int32 file_id;
  516.     uint16 ref;
  517.     DFRrig *rig;
  518. #endif
  519. {
  520.     char *FUNC="DFR8getrig";
  521.     uint16 elt_tag;
  522.     uint16 elt_ref;
  523.     uint8 ntstring[4];
  524.  
  525.     HEclear();
  526.  
  527.     if (!HDvalidfid(file_id) || !ref || !rig) {
  528.        HERROR(DFE_ARGS);
  529.         return FAIL;
  530.     }
  531.  
  532.     if (DFdiread(file_id, DFTAG_RIG, ref) == FAIL) /* read RIG into memory */
  533.         return FAIL;
  534.  
  535.     *rig = Zrig;               /* fill rig with zeroes */
  536.     while (DFdiget(&elt_tag, &elt_ref) != FAIL) {
  537.        /*get next tag/ref from RIG */
  538.         switch (elt_tag) {     /* process tag/ref */
  539.             case DFTAG_CI:
  540.             case DFTAG_RI:
  541.                 rig->image.tag = elt_tag; /* put tag/ref in struct */
  542.                 rig->image.ref = elt_ref;
  543.                 break;
  544.             case DFTAG_LUT:
  545.                 rig->lut.tag = elt_tag;
  546.                 rig->lut.ref = elt_ref;
  547.                 break;
  548.             case DFTAG_ID:     /* read description info */
  549.                 if (Hgetelement(file_id, elt_tag, elt_ref, 
  550.                                            (uint8 *)R8tbuf) != FAIL) {
  551.                     uint8 *p;
  552.                     p = R8tbuf;
  553.                     INT32DECODE(p, rig->descimage.xdim);
  554.                     INT32DECODE(p, rig->descimage.ydim);
  555.                     UINT16DECODE(p, rig->descimage.nt.tag);
  556.                     UINT16DECODE(p, rig->descimage.nt.ref);
  557.                     INT16DECODE(p, rig->descimage.ncomponents);
  558.                     INT16DECODE(p, rig->descimage.interlace);
  559.                     UINT16DECODE(p, rig->descimage.compr.tag);
  560.                     UINT16DECODE(p, rig->descimage.compr.ref);
  561.                 } else
  562.                     return FAIL;
  563.                 if (rig->descimage.ncomponents!=1) {
  564.                     HERROR(DFE_BADCALL);
  565.                     return FAIL;
  566.                 }
  567.                 if (rig->descimage.nt.tag==0) break; /* old RIGs */
  568.  
  569.                /* read NT */
  570.                 if (Hgetelement(file_id, rig->descimage.nt.tag,
  571.                                rig->descimage.nt.ref, ntstring) == FAIL)
  572.                     return FAIL;
  573.                 if ((ntstring[2]!=8) || (ntstring[1]!=DFNT_UCHAR)) {
  574.                     HERROR(DFE_BADCALL);
  575.                     return FAIL;
  576.                 }
  577.                 break;
  578.             default:           /* ignore unknown tags */
  579.                 break;
  580.         }
  581.     }
  582.     return(0);
  583. }
  584.  
  585. /*-----------------------------------------------------------------------------
  586.  * Name:    DFR8putrig
  587.  * Purpose: Write RIG struct out to HDF file
  588.  * Inputs:  file_id: HDF file pointer
  589.  *          ref: ref to put RIG with
  590.  *          rig: struct containing RIG info to put
  591.  *          wdim: if 1, write out new description records. if 0 already written
  592.  * Returns: 0 on success, -1 on failure with DFerror set
  593.  * Users:   HDF programmers, utilities, DFR8Iputimage, other routines
  594.  * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement
  595.  * Remarks: assumes 8-bit.  Writes out NT if necessary, ID, ID8 if told to
  596.  *---------------------------------------------------------------------------*/
  597.  
  598. #ifdef PROTOTYPE
  599. PRIVATE int DFR8putrig(int32 file_id, uint16 ref, DFRrig *rig, int wdim)
  600. #else
  601. PRIVATE int DFR8putrig(file_id, ref, rig, wdim)
  602.     int32 file_id;
  603.     uint16 ref;
  604.     DFRrig *rig;
  605.     int wdim;
  606. #endif
  607. {
  608.     char *FUNC="DFR8putrig";
  609.     static uint16 prevdimref=0; /*ref of previous dimension record, to reuse */
  610.     R8dim im8dim;
  611.     uint8 ntstring[4];
  612.  
  613.     HEclear();
  614.  
  615.     if (!HDvalidfid(file_id) || !ref) {
  616.        HERROR(DFE_ARGS);
  617.         return FAIL;
  618.     }
  619.  
  620.     if (!rig->descimage.nt.tag) {
  621.        /* construct and write out NT */
  622.         ntstring[0] = DFNT_VERSION; /* version */
  623.         ntstring[1] = DFNT_UCHAR; /* type */
  624.         ntstring[2] = 8;       /* width: RIG data is 8-bit chars */
  625.         ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
  626.         if (Hputelement(file_id, DFTAG_NT, ref, ntstring, (int32) 4)  == FAIL)
  627.             return FAIL;
  628.         rig->descimage.nt.tag = DFTAG_NT;
  629.         rig->descimage.nt.ref = ref;
  630.     }
  631.  
  632.     im8dim.xd = (uint16)rig->descimage.xdim;
  633.     im8dim.yd = (uint16)rig->descimage.ydim;
  634.     if (wdim) {
  635.         uint8 *p;
  636.  
  637.         p = R8tbuf;
  638.         INT32ENCODE(p, rig->descimage.xdim);
  639.         INT32ENCODE(p, rig->descimage.ydim);
  640.         UINT16ENCODE(p, rig->descimage.nt.tag);
  641.         UINT16ENCODE(p, rig->descimage.nt.ref);
  642.         INT16ENCODE(p, rig->descimage.ncomponents);
  643.         INT16ENCODE(p, rig->descimage.interlace);
  644.         UINT16ENCODE(p, rig->descimage.compr.tag);
  645.         UINT16ENCODE(p, rig->descimage.compr.ref);
  646.         if (Hputelement(file_id, DFTAG_ID, ref, R8tbuf,(int32)(p-R8tbuf))
  647.            == FAIL)
  648.             return FAIL;
  649.        /* write out ID8 */
  650.         p = R8tbuf;
  651.         UINT16ENCODE(p, im8dim.xd);
  652.         UINT16ENCODE(p, im8dim.yd);
  653.         if (Hputelement(file_id, DFTAG_ID8, ref, R8tbuf, (int32) 4) == FAIL)
  654.             return FAIL;
  655.         prevdimref = ref;
  656.     }
  657.     if (!prevdimref) {
  658.         HERROR(DFE_ARGS);
  659.         return FAIL;
  660.     }
  661.  
  662.     /* prepare to start writing rig */
  663.     /* ### NOTE: the second parameter to this call may go away */
  664.     if (DFdisetup(10) == FAIL)
  665.        return FAIL;            /* max 10 tag/refs in set */
  666.  
  667.     /* add tag/ref to RIG - image description, image and palette */
  668.     if (DFdiput(DFTAG_ID, prevdimref) == FAIL)
  669.        return FAIL;
  670.  
  671.     if (DFdiput(rig->image.tag, rig->image.ref) == FAIL)
  672.        return FAIL;
  673.  
  674.     if (rig->lut.ref
  675.        && DFdiput(rig->lut.tag, rig->lut.ref) == FAIL)
  676.        return FAIL;
  677.  
  678.     /* write out RIG */
  679.     return(DFdiwrite(file_id, DFTAG_RIG, ref));
  680. }
  681.  
  682.  
  683. /*-----------------------------------------------------------------------------
  684.  * Name:    DFR8nimages
  685.  * Purpose: How many images are present in this file?
  686.  * Inputs:  filename: name of HDF file
  687.  * Returns: number of images  on success, -1 on failure with DFerror set
  688.  * Users:   HDF programmers, other routines and utilities
  689.  * Invokes: DFR8Iopen, DFclose, DFnumber
  690.  * Remarks: the number is the number of RIGs if RIGs are present
  691.  *          If not, it is the number of RI8s + number of CI8s
  692.  *---------------------------------------------------------------------------*/
  693.  
  694. #ifdef PROTOTYPE
  695. int DFR8nimages(char *filename)
  696. #else
  697. int DFR8nimages(filename)
  698.     char *filename;
  699. #endif
  700. {
  701.     char *FUNC="DFR8nimages";
  702.     int32 file_id;
  703.     int nimages=0;
  704.  
  705.     HEclear();
  706.  
  707.     /* should use reopen if same file as last time - more efficient */
  708.     file_id = DFR8Iopen(filename, DFACC_READ);
  709.     if (file_id == FAIL)
  710.        return FAIL;
  711.  
  712.     /* find next rig */
  713.     if (foundRig) {            /* either RIGs present or don't know */
  714.         nimages = Hnumber(file_id, DFTAG_RIG); /* count number of RIGs */
  715.         if (nimages>0) {
  716.             foundRig = 1;
  717.             if (Hclose(file_id) == FAIL)
  718.                return FAIL;
  719.             return(nimages);
  720.         }
  721.         foundRig = 0;
  722.     }
  723.     nimages = Hnumber(file_id, DFTAG_RI8);
  724.     nimages += Hnumber(file_id, DFTAG_CI8);
  725.     if (Hclose(file_id) == FAIL)
  726.        return FAIL;
  727.     return(nimages);
  728. }
  729.  
  730. /*-----------------------------------------------------------------------------
  731.  * Name:    DFR8readref
  732.  * Purpose: Set ref of image to get next
  733.  * Inputs:  filename: file to which this applies
  734.  *          ref: reference number of next get
  735.  * Returns: 0 on success, -1 on failure
  736.  * Users:   HDF programmers, other routines and utilities
  737.  * Invokes: DFR8Iopen, DFIfind
  738.  * Remarks: checks if image with this ref exists
  739.  *---------------------------------------------------------------------------*/
  740.  
  741. #ifdef PROTOTYPE
  742. intn DFR8readref(char *filename, uint16 ref)
  743. #else
  744. intn DFR8readref(filename, ref)
  745.     char *filename;
  746.     uint16 ref;
  747. #endif
  748. {
  749.     char *FUNC="DFR8readref";
  750.     int32 file_id;
  751.     int32 aid;
  752.  
  753.     HEclear();
  754.  
  755.     file_id = DFR8Iopen(filename, DFACC_READ);
  756.     if (file_id == FAIL)
  757.        return FAIL;
  758.     if ((aid = Hstartread(file_id, DFTAG_RIG, ref)) == FAIL
  759.        && (aid = Hstartread(file_id, DFTAG_RI8, ref)) == FAIL
  760.        && (aid = Hstartread(file_id, DFTAG_CI8, ref)) == FAIL) {
  761.        HERROR(DFE_NOMATCH);
  762.        return(HDerr(file_id));
  763.     }
  764.     Refset = ref;
  765.     Newdata = 0;
  766.     Hendaccess(aid);
  767.     return(Hclose(file_id));
  768. }
  769.  
  770. /*-----------------------------------------------------------------------------
  771.  * Name:    DFR8writeref
  772.  * Purpose: Set ref of image to put next
  773.  * Inputs:  filename: file to which this applies
  774.  *          ref: reference number of next put
  775.  * Returns: 0 on success, -1 on failure
  776.  * Users:   HDF programmers, other routines and utilities
  777.  * Invokes: DFR8Iopen, DFIfind
  778.  * Remarks: none
  779.  *---------------------------------------------------------------------------*/
  780.  
  781. /* shut lint up */
  782. /* ARGSUSED */
  783. #ifdef PROTOTYPE
  784. int DFR8writeref(char *filename, uint16 ref)
  785. #else
  786. int DFR8writeref(filename, ref)
  787.     char *filename;
  788.     uint16 ref;
  789. #endif
  790. {
  791.     HEclear();
  792.  
  793.     Writeref = ref;
  794.     return SUCCEED;
  795. }
  796.  
  797. static char Lastfile[DF_MAXFNLEN];          /* last file opened */
  798.  
  799. /*-----------------------------------------------------------------------------
  800.  * Name:    DFR8restart
  801.  * Purpose: Do not remember info about file - get again from first image
  802.  * Inputs:  none
  803.  * Returns: 0 on success
  804.  * Users:   HDF programmers
  805.  * Remarks: Just reset Lastfile to NULL
  806.  *---------------------------------------------------------------------------*/
  807.  
  808. #ifdef PROTOTYPE
  809. int DFR8restart(void)
  810. #else
  811. int DFR8restart()
  812. #endif
  813. {
  814.     Lastfile[0] = '\0';
  815.     return SUCCEED;
  816. }
  817.  
  818.  
  819. /*-----------------------------------------------------------------------------
  820.  * Name:    DFR8lastref
  821.  * Purpose: Return last ref written or read
  822.  * Inputs:  none
  823.  * Globals: Lastref
  824.  * Returns: ref on success, -1 on error with DFerror set
  825.  * Users:   HDF users, utilities, other routines
  826.  * Invokes: none
  827.  * Method:  return Lastref
  828.  * Remarks: none
  829.  *---------------------------------------------------------------------------*/
  830.  
  831. #ifdef PROTOTYPE
  832. int DFR8lastref(void)
  833. #else
  834. int DFR8lastref()
  835. #endif
  836. {
  837.     return((int) Lastref);
  838. }
  839.  
  840.  
  841.  
  842. /*************************************************************************/
  843. /*----------------------- Internal routines -----------------------------*/
  844. /*************************************************************************/
  845.  
  846.  
  847. /*-----------------------------------------------------------------------------
  848.  * Name:    DFR8Iopen
  849.  * Purpose: open or reopen a file
  850.  * Inputs:  filename: name of file to open
  851.  *          access : access mode
  852.  * Returns: file pointer on success, NULL on failure with DFerror set
  853.  * Users:   HDF systems programmers, all the RIG routines
  854.  * Invokes: DFopen
  855.  * Remarks: This is a hook for someday providing more efficient ways to
  856.  *          reopen a file, to avoid re-reading all the headers
  857.  *---------------------------------------------------------------------------*/
  858.  
  859. #ifdef PROTOTYPE
  860. PRIVATE int32 DFR8Iopen(char *filename, int access)
  861. #else
  862. PRIVATE int32 DFR8Iopen(filename, access)
  863.     char *filename;
  864.     int access;
  865. #endif
  866. {
  867.  
  868.     int32 file_id;
  869.  
  870.     /* use reopen if same file as last time - more efficient */
  871.     if (HDstrncmp(Lastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  872.                                /* treat create as different file */
  873.         file_id = Hopen(filename, access, 0);
  874.        if (file_id == FAIL) {
  875.            return FAIL;
  876.        }
  877.         foundRig = -1;         /* don't know if any RIGs in file */
  878.         Refset = 0;            /* no ref to get set for this file */
  879.         Newdata = 0;
  880.         Readrig = Zrig;                /* blank out read/write RIGs */
  881.         Writerig = Zrig;
  882.         if (Newpalette!=(-1)) Newpalette = 1; /* need to write out palette */
  883.     } else {
  884.         file_id = Hopen(filename, access, 0);
  885.        if (file_id == FAIL) {
  886.            return FAIL;
  887.        }
  888.     }
  889.  
  890.     HDstrncpy(Lastfile, filename, DF_MAXFNLEN);
  891.     /* remember filename, so reopen may be used next time if same file */
  892.     return(file_id);
  893. }
  894.  
  895. /*-----------------------------------------------------------------------------
  896.  * Name:    DFR8Iriginfo
  897.  * Purpose: Getinformation about next RIG or Raster-8 in file
  898.  * Inputs:  file_id: pointer to DF file
  899.  * Returns: 0 on success, -1 on failure with DFerror set
  900.  * Users:   HDF systems programmers
  901.  * Invokes: DFIfind, DFgetelement
  902.  * Remarks: checks for RIGs first, then RI8s
  903.  *          if Refset set, gets image with that ref, if any
  904.  *---------------------------------------------------------------------------*/
  905.  
  906. #ifdef PROTOTYPE
  907. PRIVATE int DFR8Iriginfo(int32 file_id)
  908. #else
  909. PRIVATE int DFR8Iriginfo(file_id)
  910.     int32 file_id;
  911. #endif
  912. {
  913.     char *FUNC="DFR8riginfo";
  914.     uint16 riref=0, ciref=0;
  915.     int32 aid=FAIL;
  916.     uint16 ref;
  917.  
  918.     HEclear();
  919.     /* find next rig */
  920.     if (foundRig) {            /* either RIGs present or don't know */
  921.        if (!Refset && Readrig.image.ref)
  922.            aid = Hstartread(file_id, DFTAG_RIG, Readrig.image.ref);
  923.        do {
  924.            if (Refset) {
  925.                aid = Hstartread(file_id, DFTAG_RIG, Refset);
  926.            } else {
  927.                if (!Readrig.image.ref) {
  928.                    aid = Hstartread(file_id, DFTAG_RIG, DFREF_WILDCARD);
  929.                } else {
  930.                    if (aid != FAIL
  931.                        && Hnextread(aid, DFTAG_RIG, DFREF_WILDCARD,
  932.                                     DF_CURRENT) == FAIL) {
  933.                        Hendaccess(aid);
  934.                        aid = FAIL;
  935.                    }
  936.                }
  937.            }
  938.            if (aid == FAIL) {
  939.                if (foundRig==1) { /*RIGs present, but no more to return */
  940.                    HERROR(DFE_NOMATCH);
  941.                    return FAIL;
  942.                }
  943.                foundRig = 0; /* No RIGs present in file */
  944.            }
  945.            /* RIG found */
  946.            if (aid != FAIL)   {
  947.               Hinquire(aid, (int32*)NULL, (uint16*)NULL, &ref,
  948.                     (int32*)NULL, (int32*)NULL, (int32*)NULL,
  949.                     (int16*)NULL, (int16*)NULL);
  950.               if (DFR8getrig(file_id, ref, &Readrig) == FAIL) {
  951.                  if (Refset || (HEvalue(1) != DFE_BADCALL)) {
  952.                      Refset = 0;
  953.                      Hendaccess(aid);
  954.                      return FAIL;
  955.                  }
  956.                  Readrig.image.ref = ref;
  957.               } else {
  958.                  foundRig = 1;
  959.                  Refset = 0;
  960.               }
  961.            }
  962.        } while ( (aid != FAIL) && (HEvalue(1) == DFE_BADCALL));
  963.        if (aid != FAIL) Hendaccess(aid);
  964.     }
  965.     if (Refset || !foundRig) { /* No RIGs present, look for RI8 and CI8 */
  966.        /* look for Refset if DFR8ref called, else look for next ref */
  967.        if (Refset) {
  968.            aid = Hstartread(file_id, DFTAG_RI8, Refset);
  969.        } else {
  970.            if (Readrig.image.ref) {
  971.                aid = Hstartread(file_id, DFTAG_RI8, Readrig.image.ref);
  972.                if (aid != FAIL
  973.                    && Hnextread(aid, DFTAG_RI8, DFREF_WILDCARD,
  974.                                 DF_CURRENT) == FAIL) {
  975.                    Hendaccess(aid);
  976.                    aid = FAIL;
  977.                }
  978.            } else {
  979.                aid = Hstartread(file_id, DFTAG_RI8, DFREF_WILDCARD);
  980.            }
  981.        }
  982.        if (aid != FAIL) {
  983.            Hinquire(aid, (int32*)NULL, (uint16*)NULL, &riref,
  984.                     (int32*)NULL, (int32*)NULL, (int32*)NULL,
  985.                     (int16*)NULL, (int16*)NULL);
  986.            Hendaccess(aid);
  987.        }
  988.  
  989.        if (Refset) {
  990.            aid = Hstartread(file_id, DFTAG_CI8, Refset);
  991.        } else {
  992.            if (Readrig.image.ref) {
  993.                aid = Hstartread(file_id, DFTAG_CI8, Readrig.image.ref);
  994.                if (aid != FAIL
  995.                    && Hnextread(aid, DFTAG_CI8, DFREF_WILDCARD,
  996.                                 DF_CURRENT) == FAIL) {
  997.                    Hendaccess(aid);
  998.                    aid = FAIL;
  999.                }
  1000.            } else {
  1001.                aid = Hstartread(file_id, DFTAG_CI8, DFREF_WILDCARD);
  1002.            }
  1003.        }
  1004.        if (aid != FAIL) {
  1005.            Hinquire(aid, (int32*)NULL, (uint16*)NULL, &ciref,
  1006.                     (int32*)NULL, (int32*)NULL, (int32*)NULL,
  1007.                     (int16*)NULL, (int16*)NULL);
  1008.            Hendaccess(aid);
  1009.        }
  1010.  
  1011.         Refset = 0;
  1012.         if (!riref && !ciref) {
  1013.            HERROR(DFE_NOMATCH);
  1014.             return FAIL;
  1015.         }
  1016.         if ((!ciref) || (riref && (riref<ciref))) {
  1017.  
  1018.            /* next image is RI8 */
  1019.  
  1020.            Readrig.image.ref = riref;
  1021.             Readrig.image.tag = DFTAG_RI8;
  1022.         } else {
  1023.  
  1024.            /* next image is CI8 */
  1025.  
  1026.            Readrig.image.ref = ciref;
  1027.             Readrig.image.tag = DFTAG_CI8;
  1028.             Readrig.descimage.compr.tag = DFTAG_RLE;
  1029.         }
  1030.  
  1031.         if (Hgetelement(file_id, DFTAG_ID8, Readrig.image.ref, R8tbuf)
  1032.            != FAIL) {
  1033.             uint8 *p;
  1034.             p = R8tbuf;
  1035.             UINT16DECODE(p, Readrig.descimage.xdim);
  1036.             UINT16DECODE(p, Readrig.descimage.ydim);
  1037.         } else
  1038.            return FAIL;
  1039.  
  1040.         if ((aid = Hstartread(file_id, DFTAG_IP8, Readrig.image.ref))
  1041.            != FAIL) {
  1042.             Readrig.lut.tag = DFTAG_IP8;
  1043.             Readrig.lut.ref = Readrig.image.ref;
  1044.  
  1045.            Hendaccess(aid);
  1046.         }
  1047.     }
  1048.     Lastref = Readrig.image.ref; /* remember ref read */
  1049.     return SUCCEED;
  1050. }
  1051.