home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / hdf / hdf.lha / DFP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1980-02-06  |  12.9 KB  |  445 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.3 $";
  27. #endif
  28. /*
  29. $Header: /hdf/hdf/v3.2r2/src/RCS/dfp.c,v 1.3 1992/10/23 00:14:11 koziol beta koziol $
  30.  
  31. $Log: dfp.c,v $
  32.  * Revision 1.3  1992/10/23  00:14:11  koziol
  33.  * Changed all DFIstr*() and DFImem*() calls to HDstr*() and HDmem*() calls
  34.  * #ifdef'd out the macros Jason defined for Hopen, Hclose, etc. for Vsets
  35.  * Replaced Vset VFREESPACE and VGETSPACE calls with actual calls to HDfreespace
  36.  * and HDgetspace
  37.  * Added a MS-Windows lower lower for file I/O (which may not be completely working
  38.  *
  39.  * Revision 1.2  1992/10/12  18:11:51  koziol
  40.  * Updated for v3.2r2 release
  41.  *
  42.  * Revision 1.1  1992/08/25  21:40:44  koziol
  43.  * Initial revision
  44.  *
  45. */
  46. /*-----------------------------------------------------------------------------
  47.  * File:    dfp.c
  48.  * Purpose: read and write palettes
  49.  * Invokes: df.c
  50.  * Contents:
  51.  *  DFPgetpal: retrieve next palette
  52.  *  DFPputpal: write palette to file
  53.  *  DFPaddpal: add palette to file
  54.  *  DFPnpals: number of palettes in HDF file
  55.  *  DFPreadref: get palette with this reference number next
  56.  *  DFPwriteref: put palette with this reference number next
  57.  *  DFPrestart: forget info about last file accessed - restart from beginning
  58.  *  DFPlastref: return reference number of last element read or written
  59.  *  DFPIopen: open/reopen file
  60.  *---------------------------------------------------------------------------*/
  61.  
  62. #include "hdf.h"
  63. #include "herr.h"
  64. #include "hfile.h"
  65.  
  66. static uint16 Readref=0;
  67. static uint16 Writeref=0;
  68. static uint16 Refset=0;                /* Ref of palette to get next */
  69. static uint16 Lastref = 0;     /* Last ref read/written */
  70.  
  71. static char Lastfile[DF_MAXFNLEN]; /* last file opened */
  72.  
  73. #ifdef VMS
  74. int32 _DFPIopen();
  75. #endif
  76.  
  77.  
  78. /*-----------------------------------------------------------------------------
  79.  * Name:    DFPgetpal
  80.  * Purpose: get next palette from file
  81.  * Inputs:  filename: name of HDF file
  82.  *          palette: 768 byte space to read palette into
  83.  * Returns: 0 on success, -1 on failure with DFerror set
  84.  *          palette in pal
  85.  * Users:   HDF HLL users, utilities, other routines
  86.  * Invokes: DFPIopen, DFIerr, DFclose, DFgetelement
  87.  *---------------------------------------------------------------------------*/
  88.  
  89. #ifdef PROTOTYPE
  90. intn DFPgetpal(char *filename, VOIDP palette)
  91. #else
  92. intn DFPgetpal(filename, palette)
  93.     char *filename;
  94.     VOIDP palette;
  95. #endif
  96. {
  97.     char *FUNC="DFPgetpal";
  98.     int32 file_id;
  99.     int32 aid;
  100.     int32 length;
  101.  
  102.     HEclear();
  103.  
  104.     if (!palette) {
  105.         HERROR(DFE_ARGS);
  106.         return FAIL;
  107.     }
  108.     file_id = DFPIopen(filename, DFACC_READ);
  109.     if (file_id == FAIL) {
  110.        return FAIL;
  111.     }
  112.  
  113.     if (Refset) {
  114.         aid = Hstartread(file_id, DFTAG_IP8, Refset);
  115.         if (aid == FAIL)
  116.             aid = Hstartread(file_id, DFTAG_LUT, Refset);
  117.     } else if (Readref) {
  118.         aid = Hstartread(file_id, DFTAG_IP8, Readref);
  119.         if(aid == FAIL)
  120.             aid = Hstartread(file_id, DFTAG_LUT, Readref);
  121.         if (aid != FAIL &&
  122.               (Hnextread(aid, DFTAG_IP8, DFREF_WILDCARD, DF_CURRENT) == FAIL)) {
  123.             if(Hnextread(aid, DFTAG_LUT, DFREF_WILDCARD, DF_CURRENT) == FAIL){
  124.                 Hendaccess(aid);
  125.                aid = FAIL;
  126.             }
  127.         }
  128.     } else {
  129.         aid = Hstartread(file_id, DFTAG_IP8, DFREF_WILDCARD);
  130.         if(aid == FAIL)
  131.             aid = Hstartread(file_id, DFTAG_LUT, DFREF_WILDCARD);
  132.     }
  133.  
  134.     Refset = 0;
  135.     if (aid == FAIL) {
  136.        return(HDerr(file_id));
  137.     }
  138.     /* on error, close file and return -1 */
  139.  
  140.     if (Hinquire(aid, (int32*)NULL, (uint16*)NULL, &Readref, &length,
  141.             (int32*)NULL, (int32*)NULL, (int16*)NULL, (int16*)NULL) == FAIL) {
  142.        Hendaccess(aid);
  143.        return HDerr(file_id);
  144.     }
  145.  
  146.         /* read palette */
  147.     if (Hread(aid, length, (uint8 *)palette) == FAIL) {
  148.        Hendaccess(aid);
  149.        return(HDerr(file_id));
  150.     }
  151.  
  152.     Hendaccess(aid);
  153.  
  154.     Lastref = Readref;
  155.  
  156.     return(Hclose(file_id));
  157. }
  158.  
  159.  
  160. /*-----------------------------------------------------------------------------
  161.  * Name:    DFPputpal
  162.  * Purpose: Write palette to file
  163.  * Inputs:  filename: name of HDF file
  164.  *          palette: palette to be written to file
  165.  *          overwrite: if 1, overwrite last palette read or written
  166.  *                     if 0, write it as a fresh palette
  167.  *          filemode: if "a", append palette to file
  168.  *                    if "w", create new file
  169.  * Returns: 0 on success, -1 on failure with DFerror set
  170.  * Users:   HDF users, programmers, utilities
  171.  * Invokes: DFPIopen, DFclose, DFputelement, DFIerr
  172.  * Remarks: To overwrite, the filename must be the same as for the previous
  173.  *          call
  174.  *---------------------------------------------------------------------------*/
  175.  
  176. #ifdef PROTOTYPE
  177. intn DFPputpal(char *filename, VOIDP palette, int overwrite, char *filemode)
  178. #else
  179. intn DFPputpal(filename, palette, overwrite, filemode)
  180.     char *filename;
  181.     VOIDP palette;
  182.     int overwrite;
  183.     char *filemode;
  184. #endif
  185. {
  186.     char *FUNC="DFPputpal";
  187.     int32 file_id;
  188.  
  189.     HEclear();
  190.  
  191.     if (!palette) {
  192.         HERROR(DFE_ARGS);
  193.         return FAIL;
  194.     }
  195.  
  196.     if (overwrite && HDstrcmp(filename, Lastfile)) {
  197.         HERROR(DFE_BADCALL);
  198.         return FAIL;
  199.     }
  200.  
  201.     file_id = DFPIopen(filename,
  202.                       (*filemode=='w') ? DFACC_CREATE : DFACC_WRITE);
  203.     if (file_id==FAIL) return FAIL;
  204.  
  205.         /* if we want to overwrite, Lastref is the ref to write.  If not, if
  206.             Writeref is set, we use that ref.  If not we get a fresh ref. The
  207.             ref to write is placed in Lastref */
  208.  
  209.     if (!overwrite) Lastref = Writeref ? Writeref : Hnewref(file_id);
  210.     if (Lastref == 0) return FAIL;
  211.  
  212.     Writeref = 0;           /* don't know ref to write after this */
  213.  
  214.         /* write out palette */
  215.     if (Hputelement(file_id, DFTAG_IP8, Lastref, 
  216.                              (uint8 *)palette, (int32) 768)<0)
  217.             return(HDerr(file_id));
  218.  
  219.     Hdupdd(file_id, DFTAG_LUT, Lastref, DFTAG_IP8, Lastref);
  220.  
  221.     return(Hclose(file_id));
  222. }
  223.  
  224.  
  225. /*-----------------------------------------------------------------------------
  226.  * Name:    DFPaddpal
  227.  * Purpose: Add palette to file
  228.  * Inputs:  filename: name of HDF file
  229.  *          palette: palette to be written to file
  230.  * Returns: 0 on success, -1 on failure with DFerror set
  231.  * Users:   HDF users, programmers, utilities
  232.  * Invokes: DFPputpal
  233.  *---------------------------------------------------------------------------*/
  234.  
  235. #ifdef PROTOTYPE
  236. int DFPaddpal(char *filename, VOIDP palette)
  237. #else
  238. int DFPaddpal(filename, palette)
  239.     char *filename;
  240.     VOIDP palette;
  241. #endif
  242. {
  243.  
  244.     return(DFPputpal(filename, palette, 0, "a"));
  245. }
  246.  
  247.  
  248. /*-----------------------------------------------------------------------------
  249.  * Name:    DFPnpals
  250.  * Purpose: How many palettes are present in this file?
  251.  * Inputs:  filename: name of HDF file
  252.  * Returns: number of palettes on success, -1 on failure with DFerror set
  253.  * Users:   HDF programmers, other routines and utilities
  254.  * Invokes: DFPIopen, DFclose, DFnumber
  255.  *---------------------------------------------------------------------------*/
  256.  
  257. #ifdef PROTOTYPE
  258. int DFPnpals(char *filename)
  259. #else
  260. int DFPnpals(filename)
  261.     char *filename;
  262. #endif
  263. {
  264.     char *FUNC="DFPnpals";
  265.     int32 file_id;
  266.     int npals1, npals2, npals;
  267.  
  268.     HEclear();
  269.  
  270.     /* should use reopen if same file as last time - more efficient */
  271.     file_id = DFPIopen(filename, DFACC_READ);
  272.     if (file_id==FAIL) return FAIL;
  273.  
  274.     npals1 = Hnumber(file_id, DFTAG_IP8);       /* count number of IPs */
  275.     if (npals1 == FAIL)
  276.        return(HDerr(file_id));
  277.     npals2 = Hnumber(file_id, DFTAG_LUT);       /* count number of LUTs */
  278.     if (npals2 == FAIL)
  279.        return(HDerr(file_id));
  280.  
  281.     npals = npals1 + npals2;
  282.  
  283.     if (Hclose(file_id) == FAIL) return FAIL;
  284.  
  285.     return(npals);
  286. }
  287.  
  288.  
  289. /*-----------------------------------------------------------------------------
  290.  * Name:    DFPreadref
  291.  * Purpose: Set ref of palette to get next
  292.  * Inputs:  filename: file to which this applies
  293.  *          ref: reference number of next get
  294.  * Returns: 0 on success, -1 on failure
  295.  * Users:   HDF programmers, other routines and utilities
  296.  * Invokes: DFPIopen, DFIfind, DFclose
  297.  * Remarks: checks if palette with this ref exists
  298.  *---------------------------------------------------------------------------*/
  299.  
  300. #ifdef PROTOTYPE
  301. intn DFPreadref(char *filename, uint16 ref)
  302. #else
  303. intn DFPreadref(filename, ref)
  304.     char *filename;
  305.     uint16 ref;
  306. #endif
  307. {
  308.     int32 file_id;
  309.     int32 aid;
  310.  
  311.     HEclear();
  312.  
  313.     file_id = DFPIopen(filename, DFACC_READ);
  314.     if (file_id == FAIL) return FAIL;
  315.  
  316.     aid = Hstartread(file_id, DFTAG_IP8, ref);
  317.     if (aid == FAIL) {
  318.       aid = Hstartread(file_id, DFTAG_LUT, ref);
  319.       if(aid == FAIL) 
  320.         return(HDerr(file_id));
  321.     }
  322.  
  323.     Hendaccess(aid);
  324.     Refset = ref;
  325.  
  326.     return(Hclose(file_id));
  327. }
  328.  
  329.  
  330. /*-----------------------------------------------------------------------------
  331.  * Name:    DFPwriteref
  332.  * Purpose: Set ref of palette to put next
  333.  * Inputs:  filename: file to which this applies
  334.  *          ref: reference number of next put
  335.  * Returns: 0 on success, -1 on failure
  336.  * Users:   HDF programmers, other routines and utilities
  337.  * Invokes: none
  338.  *---------------------------------------------------------------------------*/
  339.  
  340. /* shut lint up */
  341. /* ARGSUSED */
  342. #ifdef PROTOTYPE
  343. int DFPwriteref(char *filename, uint16 ref)
  344. #else
  345. int DFPwriteref(filename, ref)
  346.     char *filename;
  347.     uint16 ref;
  348. #endif
  349. {
  350.     Writeref = ref;
  351.     return SUCCEED;
  352. }
  353.  
  354.  
  355.  
  356. /*-----------------------------------------------------------------------------
  357.  * Name:    DFPrestart
  358.  * Purpose: Do not remember info about file - get again from first palette
  359.  * Inputs:  none
  360.  * Returns: 0 on success
  361.  * Users:   HDF programmers
  362.  * Remarks: Just reset Lastfile to NULL
  363.  *---------------------------------------------------------------------------*/
  364.  
  365. #ifdef PROTOTYPE
  366. int DFPrestart(void)
  367. #else
  368. int DFPrestart()
  369. #endif
  370. {
  371.  
  372.     Lastfile[0] = '\0';
  373.     return SUCCEED;
  374. }
  375.  
  376.  
  377. /*-----------------------------------------------------------------------------
  378.  * Name:    DFPlastref
  379.  * Purpose: Return last ref written or read
  380.  * Inputs:  none
  381.  * Globals: Lastref
  382.  * Returns: ref on success, -1 on error with DFerror set
  383.  * Users:   HDF users, utilities, other routines
  384.  * Invokes: none
  385.  * Method:  return Lastref
  386.  * Remarks: none
  387.  *---------------------------------------------------------------------------*/
  388.  
  389. #ifdef PROTOTYPE
  390. int DFPlastref(void)
  391. #else
  392. int DFPlastref()
  393. #endif
  394. {
  395.  
  396.     return(Lastref);
  397. }
  398.  
  399.  
  400.  
  401. /**************************************************************************/
  402. /*----------------------- Internal routines ------------------------------*/
  403. /**************************************************************************/
  404.  
  405.  
  406. /*-----------------------------------------------------------------------------
  407.  * Name:    DFPIopen
  408.  * Purpose: open or reopen a file
  409.  * Inputs:  filename: name of file to open
  410.  *          access : access mode
  411.  * Returns: file pointer on success, NULL on failure with DFerror set
  412.  * Users:   HDF systems programmers, other DFP routines
  413.  * Invokes: DFopen
  414.  * Remarks: This is a hook for someday providing more efficient ways to
  415.  *          reopen a file, to avoid re-reading all the headers
  416.  *---------------------------------------------------------------------------*/
  417.  
  418. #ifdef PROTOTYPE
  419. int32 DFPIopen(char *filename, int access)
  420. #else
  421. int32 DFPIopen(filename, access)
  422.     char *filename;
  423.     int access;
  424. #endif
  425. {
  426.  
  427.     int32 file_id;
  428.  
  429.         /* use reopen if same file as last time - more efficient */
  430.     if (HDstrncmp(Lastfile,filename,DF_MAXFNLEN) || (access==DFACC_CREATE)) {
  431.                                     /* treat create as different file */
  432.         if ((file_id = Hopen(filename, access, 0)) == FAIL)
  433.            return FAIL;
  434.         Refset = 0;         /* no ref to get set for this file */
  435.         Readref = 0;
  436.     } else
  437.         if ((file_id = Hopen(filename, access, 0)) == FAIL)
  438.            return FAIL;
  439.  
  440.     HDstrncpy(Lastfile, filename, DF_MAXFNLEN);
  441.     /* remember filename, so reopen may be used next time if same file */
  442.  
  443.     return(file_id);
  444. }
  445.