hdf5/tools/h4toh5vgroup.c
MuQun Yang a219b97a88 [svn-r2839]
Purpose:
     check in beta release h4toh5 converter
Description:
     1. add copy right and other comments to all .h and .c files
     2. fix bugs on sds unlimited dimension, hdf5 dimensional scale attribute and vdata translating
         from h4 to h5.

Solution:
     2.
        1) for sds with unlimited dimension to be converted into extensible hdf5 dataset,
        on hdf5 side, has to set a default chunk size even though the corresponding hdf4 file is not
	chunked.
        2) in this version, if sds object doesn't have dimensional scale data, we will not show
           the default hdf4 dimensional name ("fakedim0", etc.) in the new hdf5 dimensional scale
	   name attribute.
        3) fix a bug transferring vdata of which the field includes a character array. Make it correctly transfer into the corresponding hdf5 compound data type.


Platforms tested:

      eirene,arabica,baldric,hawkwind,paz,gondolin on new set of hdf4 test files.
2000-11-08 18:14:41 -05:00

809 lines
22 KiB
C

/*-------------------------------------------------------------------------
*
* Copyright (C) 2000 National Center for Supercomputing Applications.
* All rights reserved.
*
*-------------------------------------------------------------------------
*/
/******************************************************************************
Description:
1. converter
See HDF4 to HDF5 mapping specification at
(http://hdf.ncsa.uiuc.edu/HDF5/papers/h4toh5) for the default mapping
from HDF4 object to HDF5 object.
The whole converter includes 10 files, h4toh5util.h, h4toh5main.h, h4toh5util.c, h4toh5main.c, h4toh5sds.c, h4toh5image.c,h4toh5vdata.c,h4toh5vgroup.c,h4toh5pal.c and h4toh5anno.c.
2. this file
converting an hdf4 vgroup object into a hdf5 group.
Author: Kent Yang(ymuqun@ncsa.uiuc.edu)
*****************************************************************************/
#include "h4toh5main.h"
/*-------------------------------------------------------------------------
* Function: Vgroup_h4_to_h5
*
* Purpose: translate different Vgroup objects: vgroup,vdata,sds,image
into hdf5 datasets and recursively call the routine
*
* Return: FAIL if failed, SUCCEED if successful.
*
* In :
file_id: hdf4 file identifier
vgroup_id: hdf4 vgroup id
sd_id: sd interface id
h5_group: hdf5 group id
h5_dimgroup: hdf5 dimensional scale group id
h5_palgroup: hdf5 palette group id
Out:
Modification:
*-------------------------------------------------------------------------
*/
int Vgroup_h4_to_h5(int32 file_id,int32 vgroup_id,int32 sd_id,hid_t h5_group,hid_t h5_dimgroup,hid_t h5_palgroup)
{
int32 vgroup_tag;
int32 vgroup_ref;
int32 obj_tag;
int32 obj_ref;
int32 num_gobjects;
int i;
char refstr[5];
char vgroup_class[VGNAMELENMAX];
char vgroup_name[VGNAMELENMAX];
char* h5pgroup_name;
int check_vgname;
hid_t h5_pgroup;
vgroup_tag = VQuerytag(vgroup_id);
if(vgroup_tag == FAIL) {
printf("error in obtaining vgroup tag.\n");
return FAIL;
}
vgroup_ref = VQueryref(vgroup_id);
if(vgroup_ref == FAIL) {
printf("error in obtaining vgroup reference.\n");
return FAIL;
}
if(Vgetname(vgroup_id,vgroup_name) == FAIL) {
printf("error in obtaining vgroup name.\n");
return FAIL;
}
if(Vgetclass(vgroup_id,vgroup_class) == FAIL) {
printf("error in obtaining vgroup class name. \n");
return FAIL;
}
/*** ignore reserved HDF group ***/
if(vgroup_class != NULL) {
if(strcmp(vgroup_class,_HDF_ATTRIBUTE)==0) return SUCCEED;
if(strcmp(vgroup_class,_HDF_VARIABLE)==0) return SUCCEED;
if(strcmp(vgroup_class,_HDF_DIMENSION)==0) return SUCCEED;
if(strcmp(vgroup_class,_HDF_UDIMENSION)==0) return SUCCEED;
if(strcmp(vgroup_class,_HDF_CDF)==0) return SUCCEED;
if(strcmp(vgroup_class,GR_NAME)==0) return SUCCEED;
if(strcmp(vgroup_class,RI_NAME)==0) return SUCCEED;
}
if(vgroup_name != NULL)
if(strcmp(vgroup_name,GR_NAME)==0) return SUCCEED;
h5pgroup_name = get_name(vgroup_ref,estnum_vg,vg_hashtab,&check_vgname);
if(h5pgroup_name == NULL && check_vgname == 0 ) {
printf("error,cannot find group\n");
return FAIL;
}
if(h5pgroup_name == NULL && check_vgname ==-1 ) {
printf("error,group name is not defined.\n");
return FAIL;
}
/* create a hdf5 group under h5_group.*/
h5_pgroup = H5Gcreate(h5_group,h5pgroup_name,0);
if(h5_pgroup < 0) {
printf("error in creating group. \n");
free(h5pgroup_name);
return FAIL;
}
/* vgroup attributes into corresponding hdf5 group attributes.*/
if(vg_transattrs(vgroup_id,h5_pgroup)==FAIL) {
printf("error in translating vgroup attributes into hdf5 group attr.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
num_gobjects = Vntagrefs(vgroup_id);
if(num_gobjects == FAIL) {
printf("error in obtaining number of objects in the vgroup. \n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
if(Annoobj_h4_to_h5(file_id,vgroup_ref,vgroup_tag,h5_pgroup)==FAIL) {
printf("error in obtaining annotation of the vgroup.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
for( i = 0;i<num_gobjects;i++) {
if(Vgettagref(vgroup_id,i,&obj_tag,&obj_ref)==FAIL) {
printf("failed to get object tag and ref of the current");
printf(" object in this vgroup.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
if(conv_int_str(obj_ref,refstr)== FAIL) {
printf("failed to convert object reference number ");
printf("into string format at vgroup_h4_to_h5 routine.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
if (Visvg(vgroup_id,obj_ref)) {
if(convert_vgroup(file_id,sd_id,obj_ref,h5pgroup_name,h5_pgroup,
h5_dimgroup,h5_palgroup)== FAIL) {
printf("convert_vgroup routine failed,");
printf("cannot convert vgroup into hdf5 group successfully.\n");
free(h5pgroup_name);
H5Gclose(h5_pgroup);
return FAIL;
}
}
/* the object is independent vdata. */
else if(Visvs(vgroup_id,obj_ref)) {
if(convert_vdata(file_id,obj_ref,h5pgroup_name,h5_pgroup)==FAIL){
printf("fail to convert vdata into hdf5 dataset.\n");
free(h5pgroup_name);
H5Gclose(h5_pgroup);
return FAIL;
}
}
else if(obj_tag == DFTAG_NDG || obj_tag == DFTAG_SDG) {
if(convert_sds(file_id,sd_id,obj_ref,h5pgroup_name,h5_pgroup,
h5_dimgroup)==FAIL){
printf("fail to convert sds into hdf5 dataset.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
}
else if(obj_tag == DFTAG_RIG) {
if(convert_image(file_id,obj_ref,h5pgroup_name,
h5_pgroup,h5_palgroup)==FAIL){
printf("fail to convert image into hdf5 dataset.\n");
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return FAIL;
}
}
}
H5Gclose(h5_pgroup);
free(h5pgroup_name);
return SUCCEED;
}
/*-------------------------------------------------------------------------
* Function: convert_vgroup
*
* Purpose: subroutine interface for better modularity of vgroup_h4_to_h5
* In this routine, 1) h5 vgroup name is obtained;
2) vgroup_h4_to_h5 is called again for
unvisited vgroups
3) HardLink is created for visited vgroups
* Return: FAIL if failed, SUCCEED if successful.
*
* In :
file_id: hdf4 file identifier
sd_id: sd interface id
obj_ref: object reference number
h5pgroup_name: h5 group name
h5_pgroup: hdf5 group id
h5_dimgroup: hdf5 dimensional scale group id
h5_palgroup: hdf5 palette group id
*-------------------------------------------------------------------------
*/
int convert_vgroup(int32 file_id,int32 sd_id, int32 obj_ref,
char* h5pgroup_name,hid_t h5_pgroup,hid_t h5_dimgroup,
hid_t h5_palgroup) {
int32 vgroup_cid;
int32 istat;
int check_vgname;
char refstr[MAXREF_LENGTH];
char cvgroup_name[VGNAMELENMAX];
char* cor_cvgroupname;
char* h5cgroup_name;
char* h5lgroup_name;
int check_vgroup;
if(conv_int_str(obj_ref,refstr)== FAIL) {
printf("converting integer into string format.\n");
return FAIL;
}
vgroup_cid = Vattach(file_id,obj_ref,"r");
if(vgroup_cid == FAIL) {
printf("error in getting vgroup id.\n");
return FAIL;
}
/* recursively obtain information from the group*/
/* check whether it is looked up, if yes, create a hard link.*/
istat = Vgetname(vgroup_cid,cvgroup_name);
if(istat == FAIL) {
printf("failed to get the name of vgroup.\n");
Vdetach(vgroup_cid);
return FAIL;
}
/* look up vg hashtable and see whether this object is touched.*/
check_vgroup = lookup(obj_ref,estnum_vg,vg_hashtab);
/* if this vgroup has not been touched, convert it into hdf5 group.
else create a hard link to the existing group.*/
cor_cvgroupname = correct_name(cvgroup_name);
if(cor_cvgroupname == NULL) {
printf("error in generating corrected vgroup name. \n");
Vdetach(vgroup_cid);
return FAIL;
}
if(check_vgroup == 0) {
/* checking whether vgroup name contains ORI_SLASH, changing into CHA_SLASH.*/
h5cgroup_name = get_obj_aboname(cor_cvgroupname,refstr,h5pgroup_name,
HDF4_VGROUP);
if(h5cgroup_name == NULL) {
printf("error in getting the group name.\n");
Vdetach(vgroup_cid);
free(cor_cvgroupname);
return FAIL;
}
free(cor_cvgroupname);
if(set_name(obj_ref,estnum_vg,vg_hashtab,h5cgroup_name)== FAIL) {
printf("error in setting group name.\n");
Vdetach(vgroup_cid);
free(h5cgroup_name);
return FAIL;
}
if(Vgroup_h4_to_h5(file_id,vgroup_cid,sd_id,h5_pgroup,
h5_dimgroup,h5_palgroup)== FAIL) {
printf("error in transferring vgroup into hdf5 group.\n");
Vdetach(vgroup_cid);
free(h5cgroup_name);
return FAIL;
}
free(h5cgroup_name);
}
else {
h5cgroup_name = get_name(obj_ref,estnum_vg,vg_hashtab,&check_vgname);
if(h5cgroup_name == NULL && check_vgname ==0 ) {
printf("error,cannot find group\n");
Vdetach(vgroup_cid);
return FAIL;
}
if(h5cgroup_name == NULL && check_vgname == -1 ) {
printf("error,group name is not defined.\n");
Vdetach(vgroup_cid);
return FAIL;
}
/* create HL */
h5lgroup_name = get_obj_aboname(cor_cvgroupname,refstr,h5pgroup_name,
HDF4_VGROUP);
if(h5lgroup_name == NULL) {
printf("failed to obtain group name.\n");
Vdetach(vgroup_cid);
free(h5cgroup_name);
free(cor_cvgroupname);
return FAIL;
}
free(cor_cvgroupname);
if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cgroup_name,h5lgroup_name)<0) {
printf("cannot make hard link for two groups.\n");
Vdetach(vgroup_cid);
free(h5cgroup_name);
free(h5lgroup_name);
return FAIL;
}
free(h5cgroup_name);
free(h5lgroup_name);
}
Vdetach(vgroup_cid);
return SUCCEED;
}
/*-------------------------------------------------------------------------
* Function: convert_vdata
*
* Purpose: subroutine interface for better modularity of vgroup_h4_to_h5
* In this routine, 1) h5 vdata name is obtained;
2) vdata_h4_to_h5 is called for unvisited
vdatas
3) HardLink is created for visited vdatas
* Return: FAIL if failed, SUCCEED if successful.
*
* In :
file_id: hdf4 file identifier
obj_ref: object reference number
h5pgroup_name: h5 group name
h5_pgroup: hdf5 group id
*-------------------------------------------------------------------------
*/
int convert_vdata(int32 file_id,int32 obj_ref,char * h5pgroup_name,
hid_t h5_pgroup) {
int32 vdata_id;
int check_vdata;
int check_vdname;
int32 istat;
char refstr[5];
char cvdata_name[VGNAMELENMAX];
char* cor_cvdataname;
char* h5cvdata_name;
char* h5lvdata_name;
vdata_id = VSattach(file_id,obj_ref,"r");
if(vdata_id == FAIL) {
printf("error in attaching vdata. \n");
return FAIL;
}
if(conv_int_str(obj_ref,refstr)== FAIL) {
printf("converting integer into string format.\n");
VSdetach(vdata_id);
return FAIL;
}
istat = VSisattr(vdata_id);
if (istat == FAIL) {
printf("error in checking vdata attribute. \n");
VSdetach(vdata_id);
return FAIL;
}
if(istat); /*ignore, dependent vdata(attributes, etc.)can be retrieved later.*/
else { /* independent vdata, read in */
check_vdata = lookup(obj_ref,estnum_vd,vd_hashtab);
if(check_vdata < 0) {
printf("failed to look up the object.\n");
VSdetach(vdata_id);
return FAIL;
}
if(VSQueryname(vdata_id,cvdata_name)==FAIL) {
printf("error in querying name. \n");
VSdetach(vdata_id);
return FAIL;
}
cor_cvdataname = correct_name(cvdata_name);
if(cor_cvdataname == NULL) {
printf("error in generating corrected vdata name. \n");
VSdetach(vdata_id);
return FAIL;
}
if(check_vdata ==0) {
h5cvdata_name = get_obj_aboname(cor_cvdataname,refstr,h5pgroup_name,
HDF4_VDATA);
if(h5cvdata_name == NULL) {
printf("cannot obtain the converted hdf5 dataset name from vdata.\n");
VSdetach(vdata_id);
free(cor_cvdataname);
return FAIL;
}
free(cor_cvdataname);
if(set_name(obj_ref,estnum_vd,vd_hashtab,h5cvdata_name)== FAIL){
printf("failed to obtain vdata name.\n");
VSdetach(vdata_id);
free(h5cvdata_name);
return FAIL;
}
if(Vdata_h4_to_h5(file_id,vdata_id,h5_pgroup)==FAIL){
printf("failed to transfer vdata into hdf5 dataset.\n");
VSdetach(vdata_id);
free(h5cvdata_name);
return FAIL;
}
free(h5cvdata_name);
}
else {
h5cvdata_name = get_name(obj_ref,estnum_vd,vd_hashtab,
&check_vdname);
if(h5cvdata_name == NULL && check_vdname ==0 ){
printf("error,cannot find vdata\n");
VSdetach(vdata_id);
return FAIL;
}
if(h5cvdata_name == NULL && check_vdname ==-1 ){
printf("error,vdata name is not defined.\n");
VSdetach(vdata_id);
return FAIL;
}
/*create HL,
for the time being, we will use absolute path. */
h5lvdata_name = get_obj_aboname(cor_cvdataname,refstr,h5pgroup_name,
HDF4_VDATA);
if(h5lvdata_name == NULL) {
printf("error in obtaining vdata name.\n");
VSdetach(vdata_id);
free(h5cvdata_name);
free(cor_cvdataname);
return FAIL;
}
free(cor_cvdataname);
if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cvdata_name,h5lvdata_name)){
printf("error in creating hardlink for hdf5 dataset");
printf(" converted from vdata.\n");
VSdetach(vdata_id);
free(h5cvdata_name);
free(h5lvdata_name);
return FAIL;
}
free(h5cvdata_name);
free(h5lvdata_name);
}
VSdetach(vdata_id);
}
return SUCCEED;
}
/*-------------------------------------------------------------------------
* Function: convert_sds
*
* Purpose: subroutine interface for better modularity of vgroup_h4_to_h5
* In this routine, 1) h5 sds name is obtained;
2) sds_h4_to_h5 is called for unvisited
sds objects
3) HardLink is created for visited sds
* Return: FAIL if failed, SUCCEED if successful.
*
* In :
sd_id: hdf4 sds identifier
obj_ref: object reference number
h5_dimgroup: h5 dimensional scale group id
h5_pgroup: hdf5 group id
*-------------------------------------------------------------------------
*/
int convert_sds(int32 file_id,int32 sd_id,int32 obj_ref,char * h5pgroup_name,
hid_t h5_pgroup,hid_t h5_dimgroup) {
int32 sd_index;
int32 sds_id;
int32 sds_rank;
int32 sds_dimsizes[DIM_HASHSIZE];
int32 sds_dtype;
int32 num_sdsattrs;
char sds_name[MAX_NC_NAME];
char* cor_sdsname;
int check_sds;
int check_sdsname;
char refstr[5];
char* h5csds_name;
char* h5lsds_name;
sd_index = SDreftoindex(sd_id,obj_ref);
if(sd_index == FAIL){
printf("error in obtaining reference number of sds.\n");
return FAIL;
}
if(conv_int_str(obj_ref,refstr)== FAIL) {
printf("error in converting reference number into string type.\n");
return FAIL;
}
sds_id = SDselect(sd_id,sd_index);
if(sds_id == FAIL){
printf("error in obtaining sd id.\n");
return FAIL;
}
if(SDgetinfo(sds_id,sds_name,&sds_rank,sds_dimsizes,
&sds_dtype,&num_sdsattrs)==FAIL) {
printf("error in obtaining SD info.\n");
SDendaccess(sds_id);
return FAIL;
}
/* check whether this sds is touched. */
check_sds = lookup(obj_ref,2*num_sds,sds_hashtab);
cor_sdsname = correct_name(sds_name);
if(cor_sdsname == NULL) {
printf("error in generating corrected sds name. \n");
SDendaccess(sds_id);
return FAIL;
}
if(check_sds == 0) {
/* obtain the absolute name of sds object, deal with the name clashing by
looking up things in the "name hashing table".*/
h5csds_name = get_obj_aboname(cor_sdsname,refstr,h5pgroup_name,HDF4_SDS);
if(h5csds_name == NULL) {
printf("error in obtaining sds name.\n");
SDendaccess(sds_id);
free(cor_sdsname);
return FAIL;
}
free(cor_sdsname);
/* put the absolute path of sds into "hashing table".*/
if(set_name(obj_ref,2*num_sds,sds_hashtab,h5csds_name)==FAIL) {
printf("error in setting object name.\n");
SDendaccess(sds_id);
free(h5csds_name);
return FAIL;
}
/* convert the sds object into hdf5 dataset.*/
if(Sds_h4_to_h5(file_id,sds_id,h5_pgroup,h5_dimgroup)==FAIL){
printf("error in translating sds into hdf5 dataset.\n");
SDendaccess(sds_id);
free(h5csds_name);
return FAIL;
}
free(h5csds_name);
}
else {
/* if the object has been touched, create a hard link instead.*/
h5csds_name = get_name(obj_ref,2*num_sds,sds_hashtab,&check_sdsname);
if(h5csds_name == NULL) {
printf("error in getting sds name \n");
SDendaccess(sds_id);
return FAIL;
}
/*... ADD in the code. create HL,
for the time being, we will use absolute path. */
h5lsds_name = get_obj_aboname(cor_sdsname,refstr,h5pgroup_name,
HDF4_SDS);
if(h5lsds_name == NULL) {
printf("error in getting sds link name.\n");
SDendaccess(sds_id);
free(h5csds_name);
free(cor_sdsname);
return FAIL;
}
free(cor_sdsname);
if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5csds_name,h5lsds_name) <0) {
printf("error in getting hard link \n");
SDendaccess(sds_id);
free(h5csds_name);
free(h5lsds_name);
return FAIL;
}
free(h5csds_name);
free(h5lsds_name);
}
SDendaccess(sds_id);
return SUCCEED;
}
/*-------------------------------------------------------------------------
* Function: convert_image
*
* Purpose: subroutine interface for better modularity of vgroup_h4_to_h5
* In this routine, 1) h5 vdata name is obtained;
2) image_h4_to_h5 is called for unvisited
images
3) Hard Link is created for visited images
* Return: FAIL if failed, SUCCEED if successful.
*
* In :
file_id: hdf4 file identifier
obj_ref: object reference number
h5pgroup_name: h5 group name
h5_pgroup: hdf5 group id
h5_palgroup: hdf5 palette group id
*-------------------------------------------------------------------------
*/
int convert_image(int32 file_id,int32 obj_ref,char * h5pgroup_name,
hid_t h5_pgroup,hid_t h5_palgroup) {
int32 gr_id;
int32 gr_index;
int32 ri_id;
int32 istat;
char* h5cimage_name;
char* h5limage_name;
char refstr[5];
char image_name[MAX_GR_NAME];
char* cor_imagename;
int check_imagename;
int check_image;
gr_id = GRstart(file_id);
if(gr_id == FAIL) {
printf("error in obtaining gr id. \n");
return FAIL;
}
if(conv_int_str(obj_ref,refstr)== FAIL) {
printf("converting integer into string format.\n");
return FAIL;
}
gr_index= GRreftoindex(gr_id,obj_ref);
if(gr_index == FAIL) {
printf("error in getting gr index.\n");
return FAIL;
}
ri_id = GRselect(gr_id,gr_index);
if(ri_id == FAIL) {
printf("error in selecting gr interface.\n");
return FAIL;
}
istat = GRgetiminfo(ri_id, image_name, NULL, NULL, NULL, NULL, NULL);
if(istat == FAIL) {
GRendaccess(ri_id);
printf("error in getting GR images.\n");
return FAIL;
}
/* checking whether image name contains ORI_SLASH,
changing into CHA_SLASH.*/
cor_imagename = correct_name(image_name);
if(cor_imagename == NULL) {
printf("error in generating corrected image name. \n");
GRendaccess(ri_id);
return FAIL;
}
/* check whether this image is touched. */
check_image = lookup(obj_ref,2*num_images,gr_hashtab);
if(check_image == 0) {
/* obtain the absolute name of image object, deal with the name clashing by
looking up things in the "name hashing table".*/
h5cimage_name = get_obj_aboname(cor_imagename,refstr,h5pgroup_name,
HDF4_IMAGE);
if(h5cimage_name == NULL) {
printf("error in getting image name.\n");
GRendaccess(ri_id);
free(cor_imagename);
return FAIL;
}
free(cor_imagename);
if(set_name(obj_ref,2*num_images,gr_hashtab,h5cimage_name)==FAIL) {
printf("error setting image name.\n");
GRendaccess(ri_id);
free(h5cimage_name);
return FAIL;
}
if(Image_h4_to_h5(file_id,ri_id,h5_pgroup,h5_palgroup)==FAIL) {
printf("error in transferring image name into hdf5 dataset.\n");
GRendaccess(ri_id);
free(h5cimage_name);
return FAIL;
}
free(h5cimage_name);
}
else{
/*if the object is visited, create HL. */
h5cimage_name = get_name(obj_ref,2*num_images,gr_hashtab,
&check_imagename);
if(h5cimage_name == NULL) {
printf("error in getting image name into hdf5 dataset.\n");
GRendaccess(ri_id);
free(h5cimage_name);
return FAIL;
}
h5limage_name = get_obj_aboname(cor_imagename,refstr,h5pgroup_name,
HDF4_IMAGE);
if(h5limage_name == NULL) {
printf("error in getting link image name into hdf5 dataset.\n");
GRendaccess(ri_id);
free(h5cimage_name);
free(cor_imagename);
return FAIL;
}
free(cor_imagename);
if(H5Glink(h5_pgroup,H5G_LINK_HARD,h5cimage_name,h5limage_name)<0){
printf("error in linking two groups.\n");
GRendaccess(ri_id);
free(h5cimage_name);
free(h5limage_name);
return FAIL;
}
free(h5cimage_name);
free(h5limage_name);
}
GRendaccess(ri_id);
/* this is for efficient reason, we will comment out GRend.
GRend(gr_id);*/
return SUCCEED;
}