/****************************************************************************** NAME HULcreate_list - Create a linked list DESCRIPTION Creates a linked list. The list may either be sorted or un-sorted, based on the comparison function. RETURNS Returns a pointer to the list if successful and NULL otherwise *******************************************************************************/ list_head_t *HULcreate_list(HULfind_func_t find_func /* IN: object comparison function */ ) { CONSTR(FUNC, "HULcreate_list"); /* for HERROR */ list_head_t *ret_value=NULL; /* ptr to the linked list "head" node */ HEclear(); /* Allocate the head information */ if((ret_value=(list_head_t *)HDcalloc(1,sizeof(list_head_t)))==NULL) HGOTO_ERROR(DFE_NOSPACE, NULL); /* Set the counter */ ret_value->count=0; /* Store the creation flags, etc */ if(find_func==NULL) ret_value->flags=HUL_UNSORTED_LIST; else ret_value->flags=HUL_SORTED_LIST; ret_value->cmp_func=find_func; done: if(ret_value == NULL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULcreate_list() */
/****************************************************************************** NAME HULsearch_node - Search for an object in a linked-list DESCRIPTION Locate an object in a linked list using a key and comparison function. RETURNS Returns a pointer to the object found in the list, or NULL on failure. *******************************************************************************/ VOIDP HULsearch_node(list_head_t *lst, /* IN: list to search */ HULsearch_func_t srch_func, /* IN: function to use to find node */ VOIDP key /* IN: key of object to search for */ ) { CONSTR(FUNC, "HULsearch_node"); /* for HERROR */ node_info_t *curr_node; /* current node we are on */ VOIDP ret_value=NULL; /* default return value */ HEclear(); if(lst==NULL || srch_func==NULL || key==NULL) HGOTO_ERROR(DFE_ARGS,NULL); curr_node=lst->node_list; while(curr_node!=NULL) { if(srch_func(curr_node->obj_ptr,key)==1) HGOTO_DONE(curr_node->obj_ptr); } /* end while */ done: if(ret_value == NULL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULsearch_node() */
/****************************************************************************** NAME HULIget_list_node - Gets a list node DESCRIPTION Either gets an list node from the free list (if there is one available) or allocate a node. RETURNS Returns list node ptr if successful and NULL otherwise *******************************************************************************/ static node_info_t *HULIget_list_node(void) { CONSTR(FUNC, "HULIget_list_node"); /* for HERROR */ node_info_t *ret_value=NULL; HEclear(); if(node_free_list!=NULL) { ret_value=node_free_list; node_free_list=node_free_list->next; } /* end if */ else { if((ret_value=(node_info_t *)HDmalloc(sizeof(node_info_t)))==NULL) HGOTO_ERROR(DFE_NOSPACE, NULL); } /* end else */ done: if(ret_value == NULL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULIget_list_node() */
/****************************************************************************** NAME HULnext_node - Get the next object in a linked-list DESCRIPTION Returns the next object in a linked-list by walking through the list RETURNS Returns a pointer to the next object found in the list, or NULL on failure. *******************************************************************************/ VOIDP HULnext_node(list_head_t *lst /* IN: list to search */ ) { CONSTR(FUNC, "HULnext_node"); /* for HERROR */ VOIDP ret_value=NULL; /* default return value */ HEclear(); if(lst==NULL) HGOTO_ERROR(DFE_ARGS,NULL); if(lst->curr_node!=NULL) { lst->curr_node=lst->curr_node->next; if(lst->curr_node!=NULL) HGOTO_DONE(lst->curr_node->obj_ptr); } /* end if */ done: if(ret_value == NULL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULnext_node() */
/****************************************************************************** NAME HULdestroy_list - Destroys a linked list DESCRIPTION Destroys a linked list created by HULcreate_list(). This function walks through the list and frees all the nodes, then frees the list head. Note: this function does not (currently) free the objects in the nodes, it just leaves 'em hanging. RETURNS Returns SUCCEED/FAIL. *******************************************************************************/ intn HULdestroy_list(list_head_t *lst /* IN: list to destroy */ ) { CONSTR(FUNC, "HULdestroy_list"); /* for HERROR */ node_info_t *curr_node, /* current node while walking through list */ *next_node; /* next node in the list */ intn ret_value=SUCCEED; /* return value */ HEclear(); if(lst==NULL) HGOTO_ERROR(DFE_ARGS,FAIL); /* Chuck the list */ curr_node=lst->node_list; while(curr_node!=NULL) { next_node=curr_node->next; HULIrelease_list_node(curr_node); curr_node=next_node; } /* end while */ /* Chuck the list-head */ HDfree(lst); done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULdestroy_list() */
/****************************************************************************** NAME HULadd_node - Adds an object to a linked-list DESCRIPTION Adds an object to the linked list. If the list is sorted, the comparison function is used to determine where to insert the node, otherwise it is inserted at the head of the list. RETURNS Returns SUCCEED/FAIL. *******************************************************************************/ intn HULadd_node(list_head_t *lst, /* IN: list to modify */ VOIDP obj /* IN: object to add to the list */ ) { CONSTR(FUNC, "HULadd_node"); /* for HERROR */ node_info_t *new_node; /* new node to insert into the list */ intn ret_value=SUCCEED; /* return value */ HEclear(); if(lst==NULL || obj==NULL) HGOTO_ERROR(DFE_ARGS,FAIL); /* Allocate & initialize the new node */ if((new_node=HULIget_list_node())==NULL) HGOTO_ERROR(DFE_NOSPACE,FAIL); new_node->obj_ptr=obj; if(((lst->flags)&HUL_SORTED_LIST)!=0) { /* insert node into a sorted list */ node_info_t *curr_node, /* current node while walking through list */ *prev_node; /* previous node in the list */ prev_node=NULL; curr_node=lst->node_list; while(curr_node!=NULL) { if(lst->cmp_func(curr_node->obj_ptr,new_node->obj_ptr)>=0) { /* 'curr_node' object is greater than or equal to 'new_node' */ new_node->next=curr_node; if(prev_node==NULL) lst->node_list=new_node; else prev_node->next=new_node; HGOTO_DONE(SUCCEED); /* Break out of the loop */ } /* end if */ prev_node=curr_node; curr_node=curr_node->next; } /* end while */ /* Walked off the list, so append to last node */ if(prev_node==NULL) lst->node_list=new_node; else prev_node->next=new_node; } /* end if */ else { /* insert node into an un-sorted list */ new_node->next=lst->node_list; lst->node_list=new_node; } /* end else */ done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULadd_node() */
/* HDF Error Reporting. If there is an HDF error, then print all the * errors via CuError and clear the HDF error stack. */ void cuerrorreport_hdf() { int32 i=0, e; const char *estr; /* Print all errors stored in the error HDF stack. */ while ((e = HEvalue(i)) != DFE_NONE) { estr = HEstring(e); CuError(CU_DRIVER,"HDF reported error(s) - (%s)", estr); ++i; } HEclear(); /* Clear the HDF error stack. */ }
/*-------------------------------------------------------------------------- NAME DFPputpal -- Write palette to file USAGE intn DFPputpal(filename,palette,overwrite,filemode) char *filename; IN: name of HDF file void * palette; IN: ptr to the buffer retrieve the palette from intn overwrite; IN: whether to (1) overwrite last palette written, or (0) write it as a fresh palette char *filemode; IN: if "a" append palette to file, "w" create new file RETURNS SUCCEED on success, FAIL on failure. DESCRIPTION Stores a palette in an HDF file, with options for creating new file or appending, and overwriting last palette written. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS To overwrite, the filename must be the same as for the previous call. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ intn DFPputpal(const char *filename, const void * palette, intn overwrite, const char *filemode) { CONSTR(FUNC, "DFPputpal"); int32 file_id; intn ret_value = SUCCEED; HEclear(); if (!palette) HGOTO_ERROR(DFE_ARGS, FAIL); if (overwrite && HDstrcmp(filename, Lastfile)) HGOTO_ERROR(DFE_BADCALL, FAIL); file_id = DFPIopen(filename, (*filemode == 'w') ? DFACC_CREATE : DFACC_WRITE); if (file_id == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); /* if we want to overwrite, Lastref is the ref to write. If not, if Writeref is set, we use that ref. If not we get a fresh ref. The ref to write is placed in Lastref */ if (!overwrite) Lastref = (uint16) (Writeref ? Writeref : Htagnewref(file_id,DFTAG_IP8)); if (Lastref == 0) HGOTO_ERROR(DFE_NOREF, FAIL); Writeref = 0; /* don't know ref to write after this */ /* write out palette */ if (Hputelement(file_id, DFTAG_IP8, Lastref, (const uint8 *) palette, (int32) 768) < 0) { ret_value = (HDerr(file_id)); goto done; } /* Check for the tag/ref before creating it willy-nilly */ if(Hexist(file_id,DFTAG_LUT,Lastref)==FAIL) Hdupdd(file_id, DFTAG_LUT, Lastref, DFTAG_IP8, Lastref); ret_value = (Hclose(file_id)); done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end DFPputpal() */
/* * this routine checks that the given OPENED file is compatible with * version 2.0 or later of the HDF Vset library . * RETURNS 1 if file already compatible with r2. * 0 if not compatible. * -1 if error. */ int32 vicheckcompat(HFILEID f) { int16 foundold, foundnew; int32 aid; foundold = 0; foundnew = 0; /* locate any OLD vgs */ aid = Hstartread(f, (uint16) OLD_VGDESCTAG, DFREF_WILDCARD); if (aid != FAIL) { foundold++; Hendaccess(aid); } /* locate any OLD vdatas */ aid = Hstartread(f, (uint16) OLD_VSDESCTAG, DFREF_WILDCARD); if (aid != FAIL) { foundold++; Hendaccess(aid); } /* locate any NEW vgs */ aid = Hstartread(f, NEW_VGDESCTAG, DFREF_WILDCARD); if (aid != FAIL) { foundnew++; Hendaccess(aid); } /* locate any NEW vdatas */ aid = Hstartread(f, NEW_VSDESCTAG, DFREF_WILDCARD); if (aid != FAIL) { foundnew++; Hendaccess(aid); } HEclear(); /* clear the stack to remove faux failures - bug #655 */ if (foundold == 0) /* has no old vset elements */ return (1); /* just assume compatible */ if (foundnew > 0) return (1); /* file is already compatible */ else return (0); /* file is not compatible */ } /* vicheckcompat */
/****************************************************************************** NAME HULremove_node - Removes an object from a linked-list DESCRIPTION Remove an object from a linked list. The key and comparison function are provided locate the object to delete. RETURNS Returns a pointer to the object deleted from the list, or NULL on failure. *******************************************************************************/ VOIDP HULremove_node(list_head_t *lst, /* IN: list to modify */ HULsearch_func_t srch_func, /* IN: function to use to find node to remove */ VOIDP key /* IN: object to add to the list */ ) { CONSTR(FUNC, "HULremove_node"); /* for HERROR */ node_info_t *curr_node, /* current node we are on */ *prev_node; /* previous node we looked at */ VOIDP ret_value=NULL; /* default return value */ HEclear(); if(lst==NULL || srch_func==NULL || key==NULL) HGOTO_ERROR(DFE_ARGS,NULL); prev_node=NULL; curr_node=lst->node_list; while(curr_node!=NULL) { if(srch_func(curr_node->obj_ptr,key)==1) { if(prev_node==NULL) lst->node_list=curr_node->next; else prev_node->next=curr_node->next; ret_value=curr_node->obj_ptr; HULIrelease_list_node(curr_node); break; } /* end if */ } /* end while */ done: if(ret_value == NULL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end HULremove_node() */
/*-------------------------------------------------------------------------- NAME DFPreadref -- set ref # of palette to read next USAGE intn DFPreadref(filename,ref) char *filename; IN: name of HDF file uint16 ref; IN: ref # of palette to read next RETURNS SUCCEED on success, FAIL on failure. DESCRIPTION Sets the ref # of the next palette to read from a file GLOBAL VARIABLES Refset COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ intn DFPreadref(const char *filename, uint16 ref) { CONSTR(FUNC, "DFPreadref"); int32 file_id; int32 aid; intn ret_value = SUCCEED; HEclear(); if ((file_id = DFPIopen(filename, DFACC_READ)) == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); aid = Hstartread(file_id, DFTAG_IP8, ref); if (aid == FAIL) { aid = Hstartread(file_id, DFTAG_LUT, ref); if (aid == FAIL) { ret_value = (HDerr(file_id)); goto done; } } /* end if */ Hendaccess(aid); Refset = ref; ret_value = (Hclose(file_id)); done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end DFPreadref() */
/* HDF Error Reporting. At the start of opening the HDF file clear * the HDF error stack. */ void cuseterropts_hdf(int erropts){ HEclear(); /* Clear the HDF error stack. */ return; }
/*-------------------------------------------------------------------------- NAME DFPgetpal -- get next palette from file USAGE intn DFPgetpal(filename,palette) char *filename; IN: name of HDF file void * palette; OUT: ptr to the buffer to store the palette in RETURNS SUCCEED on success, FAIL on failure. DESCRIPTION Gets the next palette from the file specified. GLOBAL VARIABLES Lastref, Refset COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ intn DFPgetpal(const char *filename, void * palette) { CONSTR(FUNC, "DFPgetpal"); int32 file_id; int32 aid; int32 length; intn ret_value = SUCCEED; HEclear(); if (!palette) HGOTO_ERROR(DFE_ARGS, FAIL); if ((file_id = DFPIopen(filename, DFACC_READ)) == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); if (Refset) { aid = Hstartread(file_id, DFTAG_IP8, Refset); if (aid == FAIL) aid = Hstartread(file_id, DFTAG_LUT, Refset); } /* end if */ else if (Readref) { aid = Hstartread(file_id, DFTAG_IP8, Readref); if (aid == FAIL) aid = Hstartread(file_id, DFTAG_LUT, Readref); if (aid != FAIL && (Hnextread(aid, DFTAG_IP8, DFREF_WILDCARD, DF_CURRENT) == FAIL)) { if (Hnextread(aid, DFTAG_LUT, DFREF_WILDCARD, DF_CURRENT) == FAIL) { Hendaccess(aid); aid = FAIL; } /* end if */ } /* end if */ } /* end if */ else { aid = Hstartread(file_id, DFTAG_IP8, DFREF_WILDCARD); if (aid == FAIL) aid = Hstartread(file_id, DFTAG_LUT, DFREF_WILDCARD); } /* end else */ Refset = 0; /* on error, close file and return -1 */ if (aid == FAIL) { ret_value = (HDerr(file_id)); goto done; } if (Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, &Readref, &length, (int32 *) NULL, (int32 *) NULL, (int16 *) NULL, (int16 *) NULL) == FAIL) { Hendaccess(aid); ret_value = HDerr(file_id); goto done; } /* end if */ /* read palette */ if (Hread(aid, length, (uint8 *) palette) == FAIL) { Hendaccess(aid); ret_value = (HDerr(file_id)); goto done; } /* end if */ Hendaccess(aid); Lastref = Readref; ret_value = Hclose(file_id); done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end DFPgetpal() */
/*-------------------------------------------------------------------------- NAME DFPnpals -- determine # of palettes in a file USAGE intn DFPnpals(filename) char *filename; IN: name of HDF file RETURNS SUCCEED on success, FAIL on failure. DESCRIPTION Determines the number of unique palettes in a file. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ intn DFPnpals(const char *filename) { CONSTR(FUNC, "DFPnpals"); int32 file_id; intn curr_pal; /* current palette count */ int32 nip8, nlut; /* number of IP8s & number of LUTs */ intn npals; /* total number of palettes */ uint16 find_tag, find_ref; /* storage for tag/ref pairs found */ int32 find_off, find_len; /* storage for offset/lengths of tag/refs found */ int32 *pal_off; /* storage for an array of palette offsets */ intn i, j; /* local counting variable */ intn ret_value = SUCCEED; HEclear(); /* should use reopen if same file as last time - more efficient */ if ((file_id = DFPIopen(filename, DFACC_READ)) == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); /* count number of IPs */ if ((nip8 = Hnumber(file_id, DFTAG_IP8)) == FAIL) { ret_value = (HDerr(file_id)); goto done; } /* count number of LUTs */ if ((nlut = Hnumber(file_id, DFTAG_LUT)) == FAIL) { ret_value = (HDerr(file_id)); goto done; } npals = (intn) (nip8 + nlut); /* if no palettes just return zero and get out */ if (npals == 0) { if (Hclose(file_id) == FAIL) { ret_value = FAIL; goto done; } ret_value = npals; goto done; } /* Get space to store the palette offsets */ if ((pal_off = (int32 *) HDmalloc(npals * sizeof(int32))) == NULL) HGOTO_ERROR(DFE_NOSPACE, FAIL); /* go through the IP8s */ curr_pal = 0; find_tag = find_ref = 0; while (Hfind(file_id, DFTAG_IP8, DFREF_WILDCARD, &find_tag, &find_ref, &find_off, &find_len, DF_FORWARD) == SUCCEED) { pal_off[curr_pal] = find_off; /* store offset */ curr_pal++; } /* end while */ /* go through the LUTs */ find_tag = find_ref = 0; while (Hfind(file_id, DFTAG_LUT, DFREF_WILDCARD, &find_tag, &find_ref, &find_off, &find_len, DF_FORWARD) == SUCCEED) { pal_off[curr_pal] = find_off; /* store offset */ curr_pal++; } /* end while */ npals = curr_pal; /* reset the number of palettes we really have */ for (i = 1; i < curr_pal; i++) { /* go through the palettes looking for duplicates */ if(pal_off[i]!=(-1)) for (j = 0; j < i; j++) { if (pal_off[i] == pal_off[j]) { npals--; /* if duplicate found, decrement the number of palettes */ pal_off[j]=(-1); /* mark as used, so we don't count it too... */ } /* end if */ } /* end for */ } /* end for */ HDfree(pal_off); /* free offsets */ if (Hclose(file_id) == FAIL) HGOTO_ERROR(DFE_CANTCLOSE, FAIL); ret_value = npals; done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end DFPnpals() */