home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / plotting / imagetoo / imagetl1.lha / Imagetool / HDF / dfgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-20  |  40.1 KB  |  1,162 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.10
  3. *                July 1, 1990
  4. *
  5. * NCSA HDF Version 3.10 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. #ifdef RCSID
  18. static char RcsId[] = "@(#)$Revision: 3.3 $";
  19. #endif
  20. /*
  21. $Header: /pita/work/HDF/dev/RCS/src/dfgr.c,v 3.3 90/06/19 11:19:42 clow beta $
  22.  
  23. $Log:    dfgr.c,v $
  24.  * Revision 3.3  90/06/19  11:19:42  clow
  25.  * Implemented DFGRreadref to set next rig to read in.
  26.  * 
  27.  * Revision 3.2  90/05/11  12:55:03  clow
  28.  * added DFGRIrestart() for restarting files for general raster
  29.  * 
  30.  * Revision 3.1  90/05/04  16:26:50  clow
  31.  * changed argument list of DFGRIsetdims
  32.  * added DFGRIsetil
  33.  * 
  34.  * Revision 3.0  90/02/02  20:31:30  clow
  35.  * *** empty log message ***
  36.  * 
  37. */
  38.  
  39. /*-----------------------------------------------------------------------------
  40.  * File:    dfgr.c
  41.  * Purpose: read and write general raster images
  42.  * Invokes: df.c, dfkit.c, dfcomp.c, dfgroup.c, dfgr.h
  43.  * Contents: 
  44.  *  DFGRgetlutdims: get dimensions of lookup table
  45.  *  DFGRreqlutil: use this interlace when returning lookup table
  46.  *  DFGRgetlut: read in lookup table
  47.  *  DFGRgetimdims: get dimensions of image
  48.  *  DFGRreqimil: use this interlace when returning image
  49.  *  DFGRgetimage: read in image
  50.  *  DFGRsetcomp: specify compression scheme to be used
  51.  *  DFGRsetlutdims: set dimensions of lookup table
  52.  *  DFGRsetlut: set lookup table to write out with subsequent images
  53.  *  DFGRaddlut: write out lookup table
  54.  *  DFGRsetimdims: set dimensions of image
  55.  *  DFGRaddimage: write out image
  56.  *
  57.  *  DFGRgetrig: read in raster image group
  58.  *  DFGRaddrig: write out raster image group
  59.  *
  60.  *  DFGRIopen: open/reopen file
  61.  *  DFGRIriginfo: obtain info about next RIG
  62.  *  DFGRIgetdims: get dimensions of lut/iamge
  63.  *  DFGRIreqil: get lut/image with this interlace
  64.  *  DFGRIgetimlut: get image/lut
  65.  *  DFGRIsetdims: set image/lut dimensions
  66.  *  DFGRIaddimlut: write out image/lut
  67.  * Remarks: A RIG specifies attributes associated with an image - lookup table, 
  68.  *          dimension, compression, color compensation etc.
  69.  *---------------------------------------------------------------------------*/
  70.  
  71. #include "dfgr.h"
  72.  
  73. static char Grlastfile[DF_MAXFNLEN];
  74. static DFGRrig Grread;        /* information about RIG being read */
  75. static DFGRrig Grwrite;         /* information about RIG being written */
  76. static int Grnewdata = 0;    /* does Grread contain fresh data? */
  77. static int Grcompr = 0;         /* compression scheme to use */
  78. char *Grlutdata=NULL;        /* points to lut, if in memory */
  79. static uint16 Grrefset=0;    /* Ref of image to get next */
  80. static uint16 Grlastref = 0;    /* Last ref read/written */
  81. static int Grreqil[2]= {0, 0}; /* requested lut/image il */
  82. static struct {            /* track refs of set vals written before */
  83.     int lut;            /* -1: no vals set */
  84.     int16 dims[2];        /* 0: vals set, not written */
  85.     int nt;            /* non-zero: ref of val in file */
  86. } Ref = {-1, {-1, -1}, -1 };
  87.  
  88. static DFGRrig Grzrig = {    /* empty RIG for initialization */
  89.     { {0, 0}, {0, 0}, {0, 0}, },
  90.     { {0, 0, 0, 0, 0, 0, 0, 0},
  91.       {0, 0, 0, 0, 0, 0, 0, 0},
  92.       {0, 0, 0, 0, 0, 0, 0, 0}, },
  93.     0, 0, 0.0, 0.0, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0},
  94.     {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, NULL
  95. };
  96.  
  97. #ifndef VMS
  98. DF *DFGRIopen();
  99. #else /*VMS*/
  100. DF *_DFGRIopen();
  101. #endif
  102.  
  103. #define LUT     0
  104. #define IMAGE   1
  105.  
  106. /*-----------------------------------------------------------------------------
  107.  * Name:    DFGRgetlutdims
  108.  * Purpose: get dimensions of lut from next RIG
  109.  * Inputs:  filename: name of HDF file
  110.  *          pxdim, pydim: pointer to locations for returning x,y dimensions
  111.  *          pncomps: location for returning no of components
  112.  *          pil: location for returning interlace of lut in file
  113.  * Returns: 0 on success, -1 on failure with DFerror set
  114.  *          *pxdim, *pydim, *pncomps, *pil set on success
  115.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  116.  * Invokes: DFGRIgetdims
  117.  * Remarks: none
  118.  *---------------------------------------------------------------------------*/
  119.  
  120. int DFGRgetlutdims(filename, pxdim, pydim, pncomps, pil)
  121. char *filename;
  122. int32 *pxdim, *pydim;
  123. int *pncomps, *pil;
  124. {
  125.  
  126.     return(DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, LUT));
  127. }
  128.  
  129.  
  130. /*-----------------------------------------------------------------------------
  131.  * Name:    DFGRreqlutil
  132.  * Purpose: get next lut with specified interlace
  133.  * Inputs:  il: interlace to get next lut with
  134.  * Returns: 0 on success, -1 on failure with DFerror set
  135.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  136.  * Invokes: DFGRIreqil
  137.  * Remarks: none
  138.  *---------------------------------------------------------------------------*/
  139.  
  140. int DFGRreqlutil(il)
  141. int il;
  142. {
  143.     return(DFGRIreqil(il, LUT));
  144. }
  145.  
  146.  
  147. /*-----------------------------------------------------------------------------
  148.  * Name:    DFGRgetlut
  149.  * Purpose: get lut from next RIG
  150.  * Inputs:  filename: name of HDF file
  151.  *          lut: pointer to space to return lookup table
  152.  *          xdim, ydim: dimensions of space to return lut
  153.  * Returns: 0 on success, -1 on failure with DFerror set
  154.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  155.  * Invokes: DFGRIgetimlut
  156.  * Remarks: space is assumed to be xdim * ydim * ncomps bytes
  157.  *---------------------------------------------------------------------------*/
  158.  
  159. int DFGRgetlut(filename, lut, xdim, ydim)
  160. char *filename;
  161. char *lut;
  162. int32 xdim, ydim;
  163. {
  164.  
  165.     /* 0 == C */
  166.     return(DFGRIgetimlut(filename, lut, xdim, ydim, LUT, 0));
  167. }
  168.  
  169. /*-----------------------------------------------------------------------------
  170.  * Name:    DFGRgetimdims
  171.  * Purpose: get dimensions of next image RIG
  172.  * Inputs:  filename: name of HDF file
  173.  *          pxdim, pydim: pointer to locations for returning x,y dimensions
  174.  *          pncomps: location for returning no of components
  175.  *          pil: location for returning interlace of image in file
  176.  * Returns: 0 on success, -1 on failure with DFerror set
  177.  *          *pxdim, *pydim, *pncomps, *pil set on success
  178.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  179.  * Invokes: DFGRIgetdims
  180.  * Remarks: none
  181.  *---------------------------------------------------------------------------*/
  182.  
  183. int DFGRgetimdims(filename, pxdim, pydim, pncomps, pil)
  184. char *filename;
  185. int32 *pxdim, *pydim;
  186. int *pncomps, *pil;
  187. {
  188.     return(DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, IMAGE));
  189. }
  190.  
  191. /*-----------------------------------------------------------------------------
  192.  * Name:    DFGRreqimil
  193.  * Purpose: get next image with specified interlace
  194.  * Inputs:  il: interlace to get next image with
  195.  * Returns: 0 on success, -1 on failure with DFerror set
  196.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  197.  * Invokes: DFGRIreqil
  198.  * Remarks: none
  199.  *---------------------------------------------------------------------------*/
  200.  
  201. int DFGRreqimil(il)
  202. int il;
  203. {
  204.     return(DFGRIreqil(il, IMAGE));
  205. }
  206.  
  207. /*-----------------------------------------------------------------------------
  208.  * Name:    DFGRgetimage
  209.  * Purpose: get image from next RIG
  210.  * Inputs:  filename: name of HDF file
  211.  *          image: pointer to space to return image
  212.  *          xdim, ydim: dimensions of space to return lut
  213.  * Returns: 0 on success, -1 on failure with DFerror set
  214.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  215.  * Invokes: DFGRIgetimlut
  216.  * Remarks: space is assumed to be xdim * ydim * ncomps bytes
  217.  *---------------------------------------------------------------------------*/
  218.  
  219. int DFGRgetimage(filename, image, xdim, ydim)
  220. char *filename;
  221. char *image;
  222. int32 xdim, ydim;
  223. {
  224.     /* 0 == C */
  225.     return(DFGRIgetimlut(filename, image, xdim, ydim, IMAGE, 0));
  226. }
  227.  
  228. /*-----------------------------------------------------------------------------
  229.  * Name:    DFGRsetcompress
  230.  * Purpose: set compression scheme to use
  231.  * Inputs:  scheme: compression scheme
  232.  * Returns: 0 on success, -1 on failure with DFerror set
  233.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  234.  * Invokes: none
  235.  * Remarks: none
  236.  *---------------------------------------------------------------------------*/
  237.  
  238. int DFGRsetcompress(scheme)
  239. int scheme;
  240. {
  241.     Grcompr = scheme;
  242.     return(0);
  243. }
  244.  
  245. /*-----------------------------------------------------------------------------
  246.  * Name:    DFGRsetlutdims
  247.  * Purpose: set dimensions of lut to write next
  248.  * Inputs:  xdim, ydim: dimensions of lut
  249.  *          ncomps: no of components
  250.  *          il: interlace of lut
  251.  * Returns: 0 on success, -1 on failure with DFerror set
  252.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  253.  * Invokes: DFGRIsetdims
  254.  * Remarks: none
  255.  *---------------------------------------------------------------------------*/
  256.  
  257. int DFGRsetlutdims(xdim, ydim, ncomps, il)
  258. int32 xdim, ydim;
  259. int ncomps, il;
  260. {
  261.     if (DFGRIsetil(il, LUT) < 0) return -1;
  262.     return(DFGRIsetdims(xdim, ydim, ncomps, LUT));
  263. }
  264.  
  265.  
  266. /*-----------------------------------------------------------------------------
  267.  * Name:    DFGRsetlut
  268.  * Purpose: set lut for subsequent RIGs
  269.  * Inputs:  lut: lookup table to write
  270.  *          xdim, ydim: dimensions of array lut
  271.  * Returns: 0 on success, -1 on failure with DFerror set
  272.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  273.  * Invokes: DFGRIaddimlut
  274.  * Remarks: array lut is assumed to be xdim * ydim * ncomps bytes
  275.  *---------------------------------------------------------------------------*/
  276.  
  277. int DFGRsetlut(lut, xdim, ydim)
  278. char *lut;
  279. int32 xdim, ydim;
  280. {
  281.     /* 0 == C */
  282.     return(DFGRIaddimlut((char*)NULL, lut, xdim, ydim, LUT, 0));
  283. }
  284.  
  285.  
  286. /*-----------------------------------------------------------------------------
  287.  * Name:    DFGRaddlut
  288.  * Purpose: write lut to file, associate it with subsequent RIGs
  289.  * Inputs:  filename: name of HDF file
  290.  *          lut: lookup table to write
  291.  *          xdim, ydim: dimensions of array lut
  292.  * Returns: 0 on success, -1 on failure with DFerror set
  293.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  294.  * Invokes: DFGRIaddimlut
  295.  * Remarks: array lut is assumed to be xdim * ydim * ncomps bytes
  296.  *---------------------------------------------------------------------------*/
  297.  
  298. int DFGRaddlut(filename, lut, xdim, ydim)
  299. char *filename;
  300. char *lut;
  301. int32 xdim, ydim;
  302. {
  303.     /* 0 == C */
  304.     return(DFGRIaddimlut(filename, lut, xdim, ydim, LUT, 0));
  305. }
  306.  
  307.  
  308. /*-----------------------------------------------------------------------------
  309.  * Name:    DFGRsetimdims
  310.  * Purpose: set dimensions of image to write next
  311.  * Inputs:  xdim, ydim: dimensions of image
  312.  *          ncomps: no of components
  313.  *          il: interlace of image
  314.  * Returns: 0 on success, -1 on failure with DFerror set
  315.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  316.  * Invokes: DFGRIsetdims
  317.  * Remarks: none
  318.  *---------------------------------------------------------------------------*/
  319.  
  320. int DFGRsetimdims(xdim, ydim, ncomps, il)
  321. int32 xdim, ydim;
  322. int ncomps, il;
  323. {
  324.     if (DFGRIsetil(il, IMAGE) < 0) return -1;
  325.     return(DFGRIsetdims(xdim, ydim, ncomps, IMAGE));
  326. }
  327.  
  328. /*-----------------------------------------------------------------------------
  329.  * Name:    DFGRaddimage
  330.  * Purpose: Write out image
  331.  * Inputs:  filename: name of HDF file
  332.  *          image: image to write
  333.  *          xdim, ydim: dimensions of array image
  334.  * Returns: 0 on success, -1 on failure with DFerror set
  335.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  336.  * Invokes: DFGRIaddimlut
  337.  * Remarks: array image is assumed to be xdim * ydim * ncomps bytes
  338.  *---------------------------------------------------------------------------*/
  339.  
  340. int DFGRaddimage(filename, image, xdim, ydim)
  341. char *filename;
  342. char *image;
  343. int32 xdim, ydim;
  344. {
  345.     /* 0 == C */
  346.     return(DFGRIaddimlut(filename, image, xdim, ydim, IMAGE, 0));
  347. }
  348.  
  349.  
  350. /*-----------------------------------------------------------------------------
  351.  * Name:    DFGRreadref
  352.  * Purpose: Set ref of rig to get next
  353.  * Inputs:  filename: file to which this applies
  354.  *          ref: reference number of next get
  355.  * Returns: 0 on success, -1 on failure
  356.  * Users:   HDF programmers, other routines and utilities
  357.  * Invokes: DFGRIopen, DFIfind, DFclose
  358.  * Remarks: checks if rig with this ref exists
  359.  *---------------------------------------------------------------------------*/
  360.  
  361. int DFGRreadref(filename, ref)
  362. char *filename;
  363. uint16 ref;
  364. {
  365.     DF *dfile;
  366.     int cdd;
  367.     DFdle *dlep;
  368.  
  369.     DFerror = DFE_NOERROR;
  370.  
  371.     dfile = DFGRIopen(filename, DFACC_READ);
  372.     if (dfile==NULL) return(-1);
  373.  
  374.     if (DFIfind(dfile, DFTAG_RIG, ref, 1, 0, 0, &dlep, &cdd)<0)
  375.         return(DFIerr(dfile));
  376.  
  377.     Grrefset = ref;
  378.     return(DFclose(dfile));
  379. }
  380.  
  381.  
  382. /*****************************************************************************/
  383. /* This is the next lower layer - procedures to read in and write out a RIG. */
  384. /*****************************************************************************/
  385.  
  386. /*-----------------------------------------------------------------------------
  387.  * Name:    DFGRgetrig
  388.  * Purpose: Read a RIG into memory
  389.  * Inputs:  dfile: pointer to HDF file containing RIG
  390.  *          ref: reference number of RIG to get
  391.  *          rig: struct in which to place info obtained
  392.  * Returns: 0 on success, -1 on failure with DFerror set
  393.  *          contents of RIG in the struct rig
  394.  * Users:   HDF programmers, utilities, DFGRIgetdims,DFGRIgetimlut,
  395.  *          other routines
  396.  * Invokes: DFdiget, DFdinext, DFIcheck, DFgetelement
  397.  * Remarks: incomplete - does not support DFTAG_MA etc.
  398.  *---------------------------------------------------------------------------*/
  399.  
  400. int DFGRgetrig(dfile, ref, rig)
  401. DF *dfile;
  402. uint16 ref;
  403. DFGRrig *rig;
  404. {
  405.     DFdi elmt;
  406.     char ntstring[4];
  407.     int type;
  408.  
  409.     DFerror = DFE_NOERROR;
  410.  
  411.     if (DFIcheck(dfile))
  412.         return( -1);
  413.     if (!ref) {
  414.         DFerror = DFE_BADREF;
  415.         return(-1);
  416.     }
  417.  
  418.     if (DFdiread(dfile, DFTAG_RIG, ref)<0) /* read RIG into memory */
  419.         return(-1);
  420.  
  421.     *rig = Grzrig;        /* fill rig with zeroes */
  422.     while (!DFdiget(&elmt)) {    /* get next tag/ref from RIG */
  423.         switch (elmt.tag) {    /* process tag/ref */
  424.             case DFTAG_CI:
  425.             case DFTAG_RI:
  426.             case DFTAG_LUT:
  427.                 type = (elmt.tag==DFTAG_LUT) ? LUT : IMAGE;
  428.                 rig->data[type].tag = elmt.tag;
  429.                 rig->data[type].ref = elmt.ref;
  430.                 break;
  431.             case DFTAG_ID:          /* read description info */
  432.             case DFTAG_LD:
  433.                 type = (elmt.tag==DFTAG_LD) ? LUT : IMAGE;
  434. #ifdef DF_STRUCTOK
  435.                 if (DFgetelement(dfile, elmt.tag, elmt.ref,
  436.                  &rig->datadesc[type])<0)
  437.             return(-1);
  438. #else /*DF_STRUCTOK*/
  439.         if (DFgetelement(dfile, elmt.tag, elmt.ref, DFtbuf)>0) {
  440.                     register char *p;
  441.                     p = DFtbuf;
  442.                     INT32READ(p, rig->datadesc[type].xdim);
  443.                     INT32READ(p, rig->datadesc[type].ydim);
  444.                     UINT16READ(p, rig->datadesc[type].nt.tag);
  445.                     UINT16READ(p, rig->datadesc[type].nt.ref);
  446.                     INT16READ(p, rig->datadesc[type].ncomponents);
  447.                     INT16READ(p, rig->datadesc[type].interlace);
  448.                     UINT16READ(p, rig->datadesc[type].compr.tag);
  449.                     UINT16READ(p, rig->datadesc[type].compr.ref);
  450.                 } else return(-1);
  451. #endif /*DF_STRUCTOK*/
  452.                 if (rig->datadesc[type].nt.tag==0) break; /* old RIGs */
  453.  
  454.         /* read NT */
  455.                 if (DFgetelement(dfile, rig->datadesc[type].nt.tag,
  456.                  rig->datadesc[type].nt.ref, ntstring)<0)
  457.                     return(-1);
  458.                 if ((ntstring[2]!=8) || (ntstring[1]!=DFNT_UCHAR)) {
  459.                     DFerror = DFE_BADCALL;
  460.                     return(-1);
  461.                 }
  462.                 break;
  463.             default:        /* ignore unknown tags */
  464.                 break;
  465.         }
  466.     }
  467.     return(0);
  468. }
  469.  
  470. /*-----------------------------------------------------------------------------
  471.  * Name:    DFGRaddrig
  472.  * Purpose: Write RIG struct out to HDF file
  473.  * Inputs:  dfile: HDF file pointer
  474.  *          ref: ref to write RIG with
  475.  *          rig: struct containing RIG info to write
  476.  * Returns: 0 on success, -1 on failure with DFerror set
  477.  * Users:   HDF programmers, utilities, DFGRIaddimlut, other routines
  478.  * Invokes: DFIcheck, DFdistart, DFdiadd, DFdiend, DFputelement
  479.  * Remarks: none
  480.  *---------------------------------------------------------------------------*/
  481.  
  482. int DFGRaddrig(dfile, ref, rig)
  483. DF *dfile;
  484. uint16 ref;
  485. DFGRrig *rig;
  486. {
  487.     char ntstring[4];
  488.     int lutsize;
  489.  
  490.     DFerror = DFE_NOERROR;
  491.  
  492.     if (DFIcheck(dfile))
  493.         return( -1);
  494.     if (!ref) {
  495.         DFerror = DFE_BADREF;
  496.         return(-1);
  497.     }
  498.     if (Ref.nt<=0) {        /* if nt not previously written to file */
  499.                 /* construct and write out NT */
  500.         ntstring[0] = DFNT_VERSION; /* version */
  501.         ntstring[1] = DFNT_UCHAR; /* type */
  502.         ntstring[2] = 8;    /* width: RIG data is 8-bit chars */
  503.         ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
  504.         if (DFputelement(dfile, DFTAG_NT, ref,(char*)ntstring, (int32) 4) <0)
  505.             return(-1);
  506.         rig->datadesc[IMAGE].nt.tag = DFTAG_NT;
  507.         rig->datadesc[IMAGE].nt.ref = ref;
  508.         Ref.nt = ref;
  509.     }
  510.         
  511.     if (Ref.dims[IMAGE]==0) {
  512. #ifdef DF_STRUCTOK        /* write out description record */
  513.         if (DFputelement(dfile, DFTAG_ID, ref, &rig->datadesc[IMAGE], /* ID */
  514.              sizeof(rig->datadesc[IMAGE]))<0)
  515.             return(-1);
  516. #else /*DF_STRUCTOK*/
  517.         register char *p;
  518.         p = DFtbuf;
  519.         INT32WRITE(p, rig->datadesc[IMAGE].xdim);
  520.         INT32WRITE(p, rig->datadesc[IMAGE].ydim);
  521.         UINT16WRITE(p, rig->datadesc[IMAGE].nt.tag);
  522.         UINT16WRITE(p, rig->datadesc[IMAGE].nt.ref);
  523.         INT16WRITE(p, rig->datadesc[IMAGE].ncomponents);
  524.         INT16WRITE(p, rig->datadesc[IMAGE].interlace);
  525.         UINT16WRITE(p, rig->datadesc[IMAGE].compr.tag);
  526.         UINT16WRITE(p, rig->datadesc[IMAGE].compr.ref);
  527.         if (DFputelement(dfile, DFTAG_ID, ref, DFtbuf, (int32)(p-DFtbuf))<0)
  528.             return(-1);
  529. #endif /*DF_STRUCTOK*/
  530.         Ref.dims[IMAGE] = ref;
  531.     }
  532.     if (!Ref.lut) {        /* associated lut not written to this file */
  533.         if (Grlutdata==NULL) {    /* no lut associated */
  534.             DFerror = DFE_BADPTR;
  535.             return(-1);
  536.         }
  537.         lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim *
  538.         Grwrite.datadesc[LUT].ncomponents;
  539.         if (DFputelement(dfile, DFTAG_LUT, ref, Grlutdata, (int32)lutsize)<0)
  540.         return(-1);
  541.         rig->data[LUT].tag = DFTAG_LUT;
  542.         rig->data[LUT].ref = ref;
  543.         Ref.lut = ref;
  544.     }
  545.  
  546.     if (Ref.dims[LUT]==0) {
  547. #ifdef DF_STRUCTOK        /* write out description record */
  548.         if (DFputelement(dfile, DFTAG_LD, ref, &rig->datadesc[LUT], /* ID */
  549.              sizeof(rig->datadesc[LUT]))<0)
  550.             return(-1);
  551. #else /*DF_STRUCTOK*/
  552.         register char *p;
  553.         p = DFtbuf;
  554.         INT32WRITE(p, rig->datadesc[LUT].xdim);
  555.         INT32WRITE(p, rig->datadesc[LUT].ydim);
  556.         UINT16WRITE(p, rig->datadesc[LUT].nt.tag);
  557.         UINT16WRITE(p, rig->datadesc[LUT].nt.ref);
  558.         INT16WRITE(p, rig->datadesc[LUT].ncomponents);
  559.         INT16WRITE(p, rig->datadesc[LUT].interlace);
  560.         UINT16WRITE(p, rig->datadesc[LUT].compr.tag);
  561.         UINT16WRITE(p, rig->datadesc[LUT].compr.ref);
  562.         if (DFputelement(dfile, DFTAG_LD, ref, DFtbuf, (int32)(p-DFtbuf))<0)
  563.             return(-1);
  564. #endif /*DF_STRUCTOK*/
  565.         Ref.dims[LUT] = ref;
  566.     }
  567.  
  568.     /* prepare to start writing rig */
  569.     /* ### NOTE: the parameter to this call may go away */
  570.     if (DFdisetup(10)<0) return(-1); /* max 10 tag/refs in set */
  571.     /* add tag/ref to RIG - image description, image and lookup table */
  572.     if (DFdiput(DFTAG_ID,(uint16)Ref.dims[IMAGE]) < 0) return(-1);
  573.  
  574.     if (DFdiput(rig->data[IMAGE].tag, rig->data[IMAGE].ref) < 0) return(-1);
  575.  
  576.     if ((Ref.dims[LUT]>0) && (DFdiput(DFTAG_LD, (uint16)Ref.dims[LUT]) < 0))
  577.     return(-1);
  578.  
  579.     if ((Ref.lut>0) && (DFdiput(rig->data[LUT].tag, rig->data[LUT].ref) < 0))
  580.     return(-1);
  581.  
  582.     /* write out RIG */
  583.     return(DFdiwrite(dfile, DFTAG_RIG, ref));
  584. }
  585.  
  586. /*****************************************************************************/
  587. /*----------------------- Internal routines ---------------------------------*/
  588. /*****************************************************************************/
  589.  
  590.  
  591. /*-----------------------------------------------------------------------------
  592.  * Name:    DFGRIopen
  593.  * Purpose: open or reopen a file
  594.  * Inputs:  filename: name of file to open
  595.  *          access : access mode
  596.  * Returns: file pointer on success, NULL on failure with DFerror set
  597.  * Users:   HDF systems programmers, all the RIG routines 
  598.  * Invokes: DFopen
  599.  * Remarks: This is a hook for someday providing more efficient ways to
  600.  *          reopen a file, to avoid re-reading all the headers
  601.  *---------------------------------------------------------------------------*/
  602.  
  603. DF *DFGRIopen(filename, access)
  604. char *filename;
  605. int access;
  606. {
  607.  
  608.     DF *dfile;
  609.  
  610.     /* use reopen if same file as last time - more efficient */
  611.     if (strncmp(Grlastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  612.     /* treat create as different file */
  613.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  614.         Grrefset = 0;        /* no ref to get set for this file */
  615.         Grnewdata = 0;
  616.         if (Ref.lut>0) Ref.lut = 0;
  617.         if (Grlutdata==NULL) Ref.lut = (-1); /* no LUT if not a "set" call */
  618.         if (Ref.dims[IMAGE]>0) Ref.dims[IMAGE] = 0;
  619.         if (Ref.dims[LUT]>0) Ref.dims[LUT] = 0;
  620.         if (Ref.nt>0) Ref.nt = 0;
  621.         Grread = Grzrig;        /* no rigs read yet */
  622.     }
  623.     else
  624.         if (!(dfile = DFopen(filename, access, -1))) return(NULL);
  625.  
  626.     strncpy(Grlastfile, filename, DF_MAXFNLEN);
  627.         /* remember filename, so reopen may be used next time if same file */
  628.     return(dfile);
  629. }
  630.  
  631. /*-----------------------------------------------------------------------------
  632.  * Name:    DFGRIriginfo
  633.  * Purpose: Get information about next RIG in file
  634.  * Inputs:  dfile: pointer to DF file
  635.  * Returns: 0 on success, -1 on failure with DFerror set
  636.  * Users:   HDF systems programmers
  637.  * Invokes: DFIfind, DFgetelement, DFGRgetrig
  638.  * Remarks: if Grrefset set, gets image with that ref, if any
  639.  *---------------------------------------------------------------------------*/
  640.  
  641. int DFGRIriginfo(dfile)
  642. DF *dfile;
  643. {
  644.     DFdle *dlep;
  645.     int cdd, i, isfirst;
  646.     uint16 newref=0, newtag, gettag, getref;
  647.     struct {
  648.         uint16 xdim;
  649.         uint16 ydim;
  650.     } r8dims;
  651.     char *p;
  652.  
  653.     isfirst = (Grrefset!=0) || (Grread.data[IMAGE].ref==0);
  654.     getref = Grrefset;        /* ref if specified, else 0 */
  655.     Grrefset = 0;        /* no longer need to remember specified ref */
  656.     gettag = DFTAG_RIG;
  657.     for (i=0; i<4; i++) {    /* repeat for RIG, RI8, CI8, II8 */
  658.         if (DFIfind(dfile, gettag, getref, isfirst, gettag,
  659.             Grread.data[IMAGE].ref, &dlep, &cdd)<0) {
  660.         /* not found */
  661.             if (gettag==DFTAG_RIG) { /* were looking for RIGs */
  662.                 if ((Grread.data[IMAGE].tag==DFTAG_RI) /* file has Rigs */
  663.                     || (Grread.data[IMAGE].tag==DFTAG_CI)) {
  664.                     return(-1);    /* no more to return */
  665.                 }
  666.                 gettag = DFTAG_RI8; /* if no RIGs in file, look for RI8s */
  667.             }
  668.             else if ((gettag==DFTAG_II8) && (!newref)) { /* no RI8/CI8/II8 */
  669.                 return(-1);
  670.             }
  671.             continue;        /* continue checking */
  672.         }
  673.     /* found */
  674.         if (!newref || (dlep->dd[cdd].ref < newref)) { /* is it next one? */
  675.             newref = dlep->dd[cdd].ref;    /* remember tag, ref */
  676.             newtag = gettag;
  677.         }
  678.         if (gettag==DFTAG_RI8) gettag = DFTAG_CI8; /* check next */
  679.         else if (gettag==DFTAG_CI8) gettag = DFTAG_II8;
  680.         else break;        /* all checked, quit */
  681.     }
  682.  
  683.     if (newtag==DFTAG_RIG) {
  684.         if (DFGRgetrig(dfile, newref, &Grread)<0)
  685.             return(-1);
  686.     } else {
  687.         Grread.data[IMAGE].ref = newref;
  688.         Grread.data[IMAGE].tag = newtag;
  689.         if (newtag==DFTAG_CI8) Grread.datadesc[IMAGE].compr.tag = DFTAG_RLE;
  690.         else if (newtag==DFTAG_II8)
  691.             Grread.datadesc[IMAGE].compr.tag = DFTAG_IMC;
  692.  
  693.         if (DFgetelement(dfile, DFTAG_ID8, newref, (char*)&r8dims)<0)
  694.             return(-1);
  695. #ifdef DF_STRUCTOK
  696.         Grread.datadesc[IMAGE].xdim = r8dims.xdim;
  697.         Grread.datadesc[IMAGE].ydim = r8dims.ydim;
  698. #else /*DF_STRUCTOK*/
  699.         p = (char *) &r8dims;
  700.         UINT16READ(p, Grread.datadesc[IMAGE].xdim);
  701.         UINT16READ(p, Grread.datadesc[IMAGE].ydim);
  702. #endif /*DF_STRUCTOK*/
  703.  
  704.         if (DFIfind(dfile, DFTAG_IP8, newref, 0, 0, 0, &dlep, &cdd)>=0) {
  705.             Grread.data[LUT].tag = DFTAG_IP8;
  706.             Grread.data[LUT].ref = newref;
  707.         }
  708.         DFerror = DFE_NOERROR;    /* reset it, just in case! */
  709.     }
  710.  
  711.     /* if LUT dimensions not set, set default dimensions */
  712.     if (Grread.data[LUT].tag && Grread.datadesc[LUT].xdim==0) {
  713.         Grread.datadesc[LUT].xdim = 256;
  714.         Grread.datadesc[LUT].ydim = 1;
  715.         Grread.datadesc[LUT].ncomponents = 3;
  716.     }
  717.  
  718.     Grlastref = Grread.data[IMAGE].ref;    /* remember ref read */
  719.  
  720.     return(0);
  721. }
  722.  
  723. /*-----------------------------------------------------------------------------
  724.  * Name:    DFGRIgetdims
  725.  * Purpose: get dimensions of next image/lut from RIG
  726.  * Inputs:  filename: name of HDF file
  727.  *          pxdim, pxdim: pointer to locations for returning x,y dimensions
  728.  *          pncomps: location for returning no of components
  729.  *          pil: location for returning interlace of image/lut in file
  730.  *          type: LUT to get lut dims, IMAGE to get image dims
  731.  * Returns: 0 on success, -1 on failure with DFerror set
  732.  *          *pxdim, *pydim are set to dimensions of the next image on success
  733.  *          *pncomps, *pil set on success
  734.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  735.  * Invokes: DFGRIopen, DFclose, DFGRIriginfo, DFIerr
  736.  * Remarks: none
  737.  *---------------------------------------------------------------------------*/
  738.  
  739. int DFGRIgetdims(filename, pxdim, pydim, pncomps, pil, type)
  740. char *filename;
  741. int32 *pxdim, *pydim;
  742. int *pncomps, *pil, type;
  743. {
  744.     DF *dfile;
  745.  
  746.     DFerror = DFE_NOERROR;
  747.  
  748.     dfile = DFGRIopen(filename, DFACC_READ);
  749.     if (dfile == NULL) return(-1);
  750.  
  751.     if (type==IMAGE) {        /* getimdims sequences, getlutdims does not */
  752.         if (DFGRIriginfo(dfile)<0) /* reads next RIG or RI8 from file */
  753.             return(DFIerr(dfile)); /* on error, close file and return -1 */
  754.         Grnewdata = 1;
  755.     }
  756.  
  757.     if (type==LUT) if (Grread.data[LUT].ref==0) {
  758.             DFerror = DFE_NOMATCH;
  759.             return(-1);        /* no LUT */
  760.     }
  761.     if (pxdim) *pxdim = Grread.datadesc[type].xdim;
  762.     if (pydim) *pydim = Grread.datadesc[type].ydim;
  763.     if (pncomps) *pncomps = Grread.datadesc[type].ncomponents;
  764.     if (pil) *pil = Grread.datadesc[type].interlace;
  765.     return(DFclose(dfile));
  766. }
  767.  
  768. /*-----------------------------------------------------------------------------
  769.  * Name:    DFGRIreqil
  770.  * Purpose: set interlace with which to get subsequent images/luts
  771.  * Inputs:  il: interlace to get image/lut with
  772.  *          type: LUT for luts, IMAGE for images
  773.  * Returns: 0 on success, -1 on failure with DFerror set
  774.  * Users:   HDF users, utilities, other routines
  775.  * Invokes: none
  776.  * Remarks: none
  777.  *---------------------------------------------------------------------------*/
  778.  
  779. int DFGRIreqil(il, type)
  780. int il, type;
  781. {
  782.     DFerror = DFE_NOERROR;
  783.  
  784.     Grreqil[type] = il;
  785.  
  786.     return(0);
  787. }
  788.  
  789.  
  790. /*-----------------------------------------------------------------------------
  791.  * Name:    DFGRIgetimlut
  792.  * Purpose: get next image/lut from a RIG
  793.  * Inputs:  filename: name of HDF file
  794.  *          imlut: space to read image/lut into
  795.  *          xdim, ydim: dimensions of space allocated by user for image/lut
  796.  *          type: LUT for luts, IMAGE for images
  797.  *          isfortran: 0 if called from C, 1 if called from Fortran
  798.  * Returns: 0 on success, -1 on failure with DFerror set
  799.  *          image/lut in imlut
  800.  * Users:   HDF HLL users, utilities, other routines
  801.  * Invokes: DFGRIopen, DFGRIriginfo, DFIerr, DFclose, DFgetelement, DFgetcomp
  802.  * Remarks: Will also get RI8s and CI8s if no RIGs in file
  803.  *          Normally, DFGRgetimdims is called first and it moves to next image
  804.  *          But if that is not called, DFGRgetimlut will itself move to next
  805.  *          image (but not next lut!).
  806.  *          Automatically decompresses images/luts
  807.  *---------------------------------------------------------------------------*/
  808.  
  809. /* shut lint up */
  810. /* ARGSUSED */
  811. int DFGRIgetimlut(filename, imlut, xdim, ydim, type, isfortran)
  812. char *filename;
  813. int32 xdim, ydim;
  814. char *imlut;
  815. int type, isfortran;
  816. {
  817.     DF *dfile;
  818.     int32 currpos[3], currmax[3], destsize[3], bufsize, i, j;
  819.     char *buf, *destp;
  820.  
  821.     DFerror = DFE_NOERROR;
  822.  
  823.     dfile = DFGRIopen(filename, DFACC_READ);
  824.     if (dfile == NULL) return(-1);
  825.  
  826.     if ((type==IMAGE) && (Grnewdata!=1)) { /* if Grread not fresh */
  827.         if (DFGRIriginfo(dfile)<0) /* reads next RIG or RI8 from file */
  828.             return(DFIerr(dfile)); /* on error, close file and return -1 */
  829.     }
  830.     if (Grnewdata==0) {
  831.         DFerror = DFE_BADCALL;
  832.         return(-1);
  833.     }
  834.     Grnewdata = 0;        /* read new RIG next time */
  835.  
  836.     if ((xdim!=Grread.datadesc[type].xdim) ||
  837.     (ydim!=Grread.datadesc[type].ydim)) {
  838.         DFerror = DFE_BADDIM;
  839.         return(-1);
  840.     }
  841.  
  842.     /* read image/lut */
  843.     if (Grread.datadesc[type].compr.tag) { /* compressed image/lut */
  844.         if ((Grreqil[type] >= 0) &&
  845.         (Grreqil[type] != Grread.datadesc[type].interlace)) {
  846.             DFerror = DFE_NOTIMPL;
  847.             return(-1);
  848.         }
  849.         if (DFgetcomp(dfile, Grread.data[type].tag, Grread.data[type].ref,
  850.               imlut, Grread.datadesc[type].xdim,
  851.               Grread.datadesc[type].ydim,
  852.               Grread.datadesc[type].compr.tag)<0)
  853.             return(DFIerr(dfile));
  854.     } else {            /* non-compressed raster image/lut */
  855.         if (Grreqil[type]>=0) {
  856.             if (Grreqil[type]>=Grread.datadesc[type].ncomponents) {
  857.                 DFerror = DFE_BADDIM;
  858.                 return(-1);
  859.             }
  860.             else if (Grreqil[type]!=Grread.datadesc[type].interlace) {
  861.  
  862.                 if (DFaccess(dfile, Grread.data[type].tag,
  863.                  Grread.data[type].ref, "r")<0)
  864.                     return(DFIerr(dfile));
  865.         /* current position in data */
  866.                 currpos[0] = currpos[1] = currpos[2] = 0;
  867.                 currmax[0] = Grread.datadesc[type].ncomponents;
  868.                 currmax[1] = Grread.datadesc[type].ydim;
  869.                 currmax[2] = Grread.datadesc[type].xdim;
  870.  
  871.         /* compute size of each dim of dest array */
  872.                 destsize[0] = destsize[1] = 1;
  873.                 destsize[2] = currmax[1]; /* xdim is more sig than ydim */
  874.                 if (Grreqil[type]==0) {
  875.                     destsize[1] *= currmax[0];
  876.                     destsize[2] *= currmax[0];
  877.                 }
  878.                 else if (Grreqil[type]==1) {
  879.                     destsize[0] *= currmax[1];
  880.                     destsize[2] *= currmax[0];
  881.                 }
  882.                 else if (Grreqil[type]==2) {
  883.                     destsize[0] *= currmax[1] * currmax[2];
  884.                 }
  885.  
  886.                 bufsize = Grread.datadesc[type].ydim *
  887.             Grread.datadesc[type].ncomponents;
  888.                 buf = DFIgetspace((unsigned)bufsize);
  889.                 if (buf==NULL) return(DFIerr(dfile));
  890.  
  891.         /* read byte by byte and copy */
  892.                 for (i=0; i<Grread.datadesc[type].xdim; i++) {
  893.                     if (DFread(dfile, buf, bufsize)<0)
  894.             return(DFIerr(dfile));
  895.                     for (j=0; j<bufsize; j++) {
  896.                         destp = imlut + destsize[0] * currpos[0] +
  897.                 destsize[1] * currpos[1] +
  898.                 destsize[2] * currpos[2];
  899.                         *destp = buf[j];
  900.                         if (Grread.datadesc[type].interlace==0) {
  901.                             if (++currpos[0] == currmax[0]) {
  902.                                 currpos[0] = 0;
  903.                                 if (++currpos[1] == currmax[1]) {
  904.                                     currpos[1] = 0;
  905.                                     if (++currpos[2] == currmax[2]) break;
  906.                                 }
  907.                             }
  908.                         } else if (++currpos[1]==currmax[1]) {
  909.                             currpos[1] = 0;
  910.                             if (Grread.datadesc[type].interlace==1) {
  911.                                 if (++currpos[0] == currmax[0]) {
  912.                                     currpos[0] = 0;
  913.                                     if (++currpos[2] == currmax[2]) break;
  914.                                 }
  915.                             } else {
  916.                                 if (++currpos[2] == currmax[2]) {
  917.                                     currpos[2] = 0;
  918.                                     if (++currpos[0] == currmax[0]) break;
  919.                                 }
  920.                             }
  921.                         }
  922.                     }
  923.                 }
  924.                 return(0);
  925.             }
  926.         }
  927.         if (DFgetelement(dfile, Grread.data[type].tag, Grread.data[type].ref,
  928.              imlut)<0)
  929.             return(DFIerr(dfile));
  930.     }
  931.  
  932.     return(DFclose(dfile));
  933. }
  934.  
  935. /*-----------------------------------------------------------------------------
  936.  * Name:    DFGRIsetdims
  937.  * Purpose: set dimensions of image/lut
  938.  * Inputs:  xdim, ydim: dimensions of lut
  939.  *          ncomps: no of components
  940.  *          il: interlace of lut
  941.  *          type: LUT if lut, IMAGE if image
  942.  * Returns: 0 on success, -1 on failure with DFerror set
  943.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  944.  * Invokes: none
  945.  * Remarks: none
  946.  *---------------------------------------------------------------------------*/
  947.  
  948. int DFGRIsetdims(xdim, ydim, ncomps, type)
  949. int32 xdim, ydim;
  950. int ncomps;
  951. int type;
  952. {
  953.  
  954.     if ((xdim<=0) || (ydim<=0)) {
  955.         DFerror = DFE_BADDIM;
  956.         return(-1);
  957.     }
  958.     if (ncomps<0) {
  959.         DFerror = DFE_BADDIM;
  960.         return(-1);
  961.     }
  962.     Grwrite.datadesc[type].xdim = xdim;
  963.     Grwrite.datadesc[type].ydim = ydim;
  964.     Grwrite.datadesc[type].ncomponents = ncomps;
  965.  
  966.     Ref.dims[type] = 0;
  967.  
  968.     return(0);
  969. }
  970.  
  971. /*-----------------------------------------------------------------------------
  972.  * Name:    DFGRIsetil
  973.  * Purpose: set interlace of image/lut
  974.  * Inputs:  il: interlace of lut
  975.  *          type: LUT if lut, IMAGE if image
  976.  * Returns: 0 on success, -1 on failure with DFerror set
  977.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  978.  * Invokes: none
  979.  * Remarks: none
  980.  *---------------------------------------------------------------------------*/
  981.  
  982. int DFGRIsetil(il, type)
  983. int il;
  984. int type;
  985. {
  986.  
  987.     if (il<0) {
  988.         DFerror = DFE_BADDIM;
  989.         return(-1);
  990.     }
  991.     Grwrite.datadesc[type].interlace = il;
  992.  
  993.     return(0);
  994. }
  995. /*-----------------------------------------------------------------------------
  996.  * Name:    DFGRIrestart
  997.  * Purpose: restart file
  998.  * Inputs: 
  999.  * Returns: 0 on success, -1 on failure with DFerror set
  1000.  * Users:   HDF HLL (high-level library) users, utilities, other routines
  1001.  * Invokes: none
  1002.  * Remarks: none
  1003.  *---------------------------------------------------------------------------*/
  1004.     int
  1005. DFGRIrestart()
  1006. {
  1007.     Grlastfile[0] = '\0';
  1008.     Grrefset = 0;
  1009.     return 0;
  1010. }
  1011.  
  1012.  
  1013. /*-----------------------------------------------------------------------------
  1014.  * Name:    DFGRIaddimlut
  1015.  * Purpose: Internal routine to write RIG to file
  1016.  * Inputs:  filename: name of HDF file
  1017.  *          imlut: image/lut to be written to file
  1018.  *          xdim, ydim: dimensions of image/lut
  1019.  *          type: LUT if lut, IMAGE if image
  1020.  *          isfortran: 0 if called from C, 1 if called from Fortran
  1021.  * Returns: 0 on success, -1 on failure with DFerror set
  1022.  * Users:   HDF systems programmers, DFGRaddimage, DFGRaddlut, DFGRsetlut
  1023.  * Invokes: DFGRIopen, DFclose, DFputelement, DFdup, DFGRaddrig, DFputcomp,
  1024.  *          DFIerr
  1025.  * Remarks: Creates both RIG and RI8/CI8 tags, to accomodate older programs
  1026.  *          LUT will be associated with image if set previously
  1027.  *---------------------------------------------------------------------------*/
  1028.  
  1029. /* shut lint up */
  1030. /* ARGSUSED */
  1031. int DFGRIaddimlut(filename, imlut, xdim, ydim, type, isfortran)
  1032. char *filename;
  1033. int32 xdim, ydim;
  1034. char *imlut;
  1035. int type, isfortran;
  1036. {
  1037.     DF *dfile;
  1038.     uint16 wtag, wref;        /* tag of image/lut being written */
  1039.     char *newlut;
  1040.     int32 lutsize;
  1041.     int is8bit;
  1042.     struct {
  1043.         uint16 xdim;
  1044.         uint16 ydim;
  1045.     } r8dims;
  1046.     char *p;
  1047.  
  1048.     DFerror = DFE_NOERROR;
  1049.  
  1050.     if ((Ref.dims[type]==0) && ((xdim!=Grwrite.datadesc[type].xdim) ||
  1051.                 (ydim!=Grwrite.datadesc[type].ydim))) {
  1052.         DFerror = DFE_BADDIM;
  1053.         return(-1);
  1054.     }
  1055.  
  1056.     if (!imlut) {
  1057.         DFerror = DFE_BADPTR;
  1058.         return(-1);
  1059.     }
  1060.  
  1061.     if (Ref.dims[type]<0)    /* if dims not set, set dimensions */
  1062.         if (DFGRIsetdims(xdim, ydim, 1, type)<0) return(-1);
  1063.                 /* default: ncomps=1, il=0 */
  1064.  
  1065.     if ((type==LUT) && (filename==NULL)) { /* set call */
  1066.         if (Grlutdata) Grlutdata = (char *) DFIfreespace(Grlutdata);
  1067.         Ref.lut = -1;
  1068.         if (imlut==NULL) return(0);
  1069.         lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim *
  1070.         Grwrite.datadesc[LUT].ncomponents;
  1071.         Grlutdata = (char *) DFIgetspace((unsigned)lutsize);
  1072.         DFmovmem(imlut, Grlutdata, (int)lutsize);
  1073.         Ref.lut = 0;
  1074.         return(0);
  1075.     }
  1076.     dfile = DFGRIopen(filename, DFACC_ALL);
  1077.     if (dfile==NULL) return(-1);
  1078.  
  1079.     wref = DFnewref(dfile);
  1080.     if (!wref) return(DFIerr(dfile));
  1081.  
  1082.     wtag = (type==LUT) ? DFTAG_LUT : Grcompr ? DFTAG_CI : DFTAG_RI;
  1083.     Grwrite.data[type].tag = wtag;
  1084.  
  1085.     is8bit = (Grwrite.datadesc[IMAGE].ncomponents == 1);
  1086.  
  1087.     /* write out image/lut */
  1088.     if ((type==IMAGE) && Grcompr) {
  1089.         if (Grwrite.datadesc[IMAGE].ncomponents>1) {
  1090.             DFerror = DFE_NOTIMPL;
  1091.             return(DFIerr(dfile));
  1092.         }
  1093.         lutsize = Grwrite.datadesc[LUT].xdim * Grwrite.datadesc[LUT].ydim *
  1094.         Grwrite.datadesc[LUT].ncomponents;
  1095.         if (Grcompr=DFTAG_IMC) {
  1096.             if (Grlutdata==NULL) {
  1097.                 DFerror = DFE_BADCALL;
  1098.                 return(DFIerr(dfile));
  1099.             }
  1100.             newlut = (char *) DFIgetspace((unsigned)lutsize);
  1101.         }
  1102.         if (DFputcomp(dfile, wtag, wref, imlut, xdim, ydim,
  1103.               Grlutdata, newlut, Grcompr)<0)
  1104.             return(DFIerr(dfile));
  1105.     } else {            /* image need not be compressed */
  1106.         if (DFputelement(dfile, wtag, wref, imlut,
  1107.              xdim*ydim*Grwrite.datadesc[type].ncomponents)<0)
  1108.             return(DFIerr(dfile));
  1109.     }
  1110.     Grwrite.data[type].ref = wref;
  1111.     Grwrite.aspectratio = 1.0;
  1112.  
  1113.     wtag = (type==LUT) ? DFTAG_IP8 : Grcompr ?
  1114.     ((Grcompr==DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8;
  1115.     /* Write out Raster-8 tags for those who want it */
  1116.     if (is8bit && (DFdup(dfile, wtag, wref, Grwrite.data[type].tag, wref)<0))
  1117.         return(DFIerr(dfile));
  1118.  
  1119.     if (type==IMAGE) Grwrite.datadesc[IMAGE].compr.tag = Grcompr;
  1120.  
  1121.     if (Grcompr==DFTAG_IMC) {
  1122.         if (DFputelement(dfile, DFTAG_LUT, wref, newlut, lutsize)<0)
  1123.             return(DFIerr(dfile));
  1124.         Ref.lut = wref;
  1125.     }
  1126.  
  1127.     if (DFGRaddrig(dfile, wref, &Grwrite)<0) /* writes ID, NT */
  1128.         return(DFIerr(dfile));
  1129.  
  1130.     if (is8bit) {
  1131.     /* put in Raster-8 stuff also, for those who want it */
  1132.         if ((Ref.lut>=0) && DFdup(dfile, DFTAG_IP8, wref, DFTAG_LUT, wref)<0)
  1133.             return(DFIerr(dfile));
  1134. #ifdef DF_STRUCTOK
  1135.         r8dims.xdim = Grwrite.datadesc[IMAGE].xdim;
  1136.         r8dims.ydim = Grwrite.datadesc[IMAGE].ydim;
  1137. #else /*DF_STRUCTOK*/
  1138.         p = (char *) &r8dims.xdim;
  1139.         UINT16WRITE(p, Grwrite.datadesc[IMAGE].xdim);
  1140.         UINT16WRITE(p, Grwrite.datadesc[IMAGE].ydim);
  1141. #endif /*DF_STRUCTOK*/
  1142.         if (DFputelement(dfile, DFTAG_ID8, wref, (char*)&r8dims, (int32) 4)<0)
  1143.             return(DFIerr(dfile));
  1144.     }
  1145.  
  1146.     if (Grcompr==DFTAG_IMC) {
  1147.         Ref.lut = 0;
  1148.         newlut = (char *) DFIfreespace(newlut);
  1149.     }
  1150.  
  1151.     Grlastref = wref;        /* remember ref written */
  1152.     
  1153.     wref = 0;            /* don't know ref to write next */
  1154.  
  1155.     return(DFclose(dfile));
  1156. }
  1157.