00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "vp_global.h"
00032 
00033 static int StoreRLEVoxels ANSI_ARGS((vpContext *vpc, int fd,
00034     RLEVoxels *rle_voxels));
00035 static int LoadRLEVoxels ANSI_ARGS((vpContext *vpc, int fd,
00036     RLEVoxels *rle_voxels, int offsets, int swab));
00037 static void SwapWords ANSI_ARGS((void *data, unsigned size));
00038 static void SwapVoxels ANSI_ARGS((vpContext *vpc, void *voxels,
00039     int num_voxels, int fields, int bytes_per_voxel));
00040 #ifdef DEBUG
00041 void VPCheckScanOffsets ANSI_ARGS((RLEVoxels *rle_voxels,
00042     int rle_bytes_per_voxel));
00043 #endif
00044 static void SwapOctreeNode ANSI_ARGS((vpContext *vpc, int level, void *node));
00045 static int StoreTable ANSI_ARGS((vpContext *vpc, int fd, float *ptr,
00046     unsigned size));
00047 static int LoadTable ANSI_ARGS((vpContext *vpc, int fd, float **ptr_ptr,
00048     unsigned *size_ptr));
00049 
00050 
00051 
00052 
00053 
00054 
00055 typedef struct {
00056     unsigned magic;             
00057     unsigned xlen;              
00058     unsigned ylen;
00059     unsigned zlen;
00060     unsigned bytes_per_voxel;   
00061     unsigned num_shade_fields;  
00062 
00063     unsigned num_x_runs;        
00064     unsigned num_x_voxels;      
00065     unsigned num_x_offsets;     
00066     unsigned num_y_runs;        
00067     unsigned num_y_voxels;      
00068     unsigned num_y_offsets;     
00069     unsigned num_z_runs;        
00070     unsigned num_z_voxels;      
00071     unsigned num_z_offsets;     
00072     float min_opacity;          
00073 } RLEVoxelHdr;
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 vpResult
00111 vpStoreClassifiedVolume(vpc, fd)
00112 vpContext *vpc; 
00113 int fd;         
00114 {
00115     RLEVoxelHdr header;
00116     unsigned field_data[3*VP_MAX_FIELDS];
00117     int nsf, c;
00118     unsigned size;
00119     char pad_data[8];
00120     int pad_bytes;
00121     int retcode;
00122 
00123     
00124     if ((retcode = VPCheckVoxelFields(vpc)) != VP_OK)
00125         return(retcode);
00126 
00127     
00128     header.magic = VP_CVFILE_MAGIC;
00129     header.xlen = vpc->xlen;
00130     header.ylen = vpc->ylen;
00131     header.zlen = vpc->zlen;
00132     header.bytes_per_voxel = vpc->rle_bytes_per_voxel;
00133     header.num_shade_fields = vpc->num_shade_fields;
00134     if (vpc->rle_x == NULL) {
00135         header.num_x_runs = 0;
00136         header.num_x_voxels = 0;
00137         header.num_x_offsets = 0;
00138     } else {
00139         if ((retcode = VPCheckClassifiedVolume(vpc, VP_X_AXIS)) != VP_OK)
00140             return(retcode);
00141         header.num_x_runs = vpc->rle_x->run_count;
00142         header.num_x_voxels = vpc->rle_x->data_count;
00143         header.num_x_offsets = vpc->rle_x->scan_offsets_per_slice;
00144     }
00145     if (vpc->rle_y == NULL) {
00146         header.num_y_runs = 0;
00147         header.num_y_voxels = 0;
00148         header.num_y_offsets = 0;
00149     } else {
00150         if ((retcode = VPCheckClassifiedVolume(vpc, VP_Y_AXIS)) != VP_OK)
00151             return(retcode);
00152         header.num_y_runs = vpc->rle_y->run_count;
00153         header.num_y_voxels = vpc->rle_y->data_count;
00154         header.num_y_offsets = vpc->rle_y->scan_offsets_per_slice;
00155     }
00156     if (vpc->rle_z == NULL) {
00157         header.num_z_runs = 0;
00158         header.num_z_voxels = 0;
00159         header.num_z_offsets = 0;
00160     } else {
00161         if ((retcode = VPCheckClassifiedVolume(vpc, VP_Z_AXIS)) != VP_OK)
00162             return(retcode);
00163         header.num_z_runs = vpc->rle_z->run_count;
00164         header.num_z_voxels = vpc->rle_z->data_count;
00165         header.num_z_offsets = vpc->rle_z->scan_offsets_per_slice;
00166     }
00167     header.min_opacity = vpc->min_opacity;
00168     if (vpc->write_func(fd, &header, sizeof(header)) != sizeof(header))
00169         return(VPSetError(vpc, VPERROR_IO));
00170 
00171     
00172     nsf = vpc->num_shade_fields;
00173     for (c = 0; c < nsf; c++) {
00174         field_data[c] = vpc->field_size[c];
00175         field_data[nsf + c] = vpc->field_offset[c];
00176         field_data[2*nsf + c] = vpc->field_max[c];
00177     }
00178     size = 3*nsf*sizeof(unsigned);
00179     if (vpc->write_func(fd, field_data, size) != size)
00180         return(VPSetError(vpc, VPERROR_IO));
00181 
00182     
00183     pad_bytes = (8 - ((sizeof(header) + size) % 8)) & 0x7;
00184     if (pad_bytes > 0) {
00185         bzero(pad_data, pad_bytes);
00186         if (vpc->write_func(fd, pad_data, pad_bytes) != pad_bytes)
00187             return(VPSetError(vpc, VPERROR_IO));
00188     }
00189 
00190     
00191     if (vpc->rle_x != NULL) {
00192         if ((c = StoreRLEVoxels(vpc, fd, vpc->rle_x)) != VP_OK)
00193             return(c);
00194     }
00195     if (vpc->rle_y != NULL) {
00196         if ((c = StoreRLEVoxels(vpc, fd, vpc->rle_y)) != VP_OK)
00197             return(c);
00198     }
00199     if (vpc->rle_z != NULL) {
00200         if ((c = StoreRLEVoxels(vpc, fd, vpc->rle_z)) != VP_OK)
00201             return(c);
00202     }
00203 
00204     return(VP_OK);
00205 }
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 static int
00214 StoreRLEVoxels(vpc, fd, rle_voxels)
00215 vpContext *vpc;
00216 int fd;
00217 RLEVoxels *rle_voxels;
00218 {
00219     int size;
00220     char pad_data[8];
00221     int pad_bytes;
00222 
00223     bzero(pad_data, sizeof(pad_data));
00224     if (rle_voxels->run_count > 0) {
00225         size = rle_voxels->run_count;
00226         if (vpc->write_func(fd, rle_voxels->run_lengths, size) != size)
00227             return(VPSetError(vpc, VPERROR_IO));
00228 
00229         pad_bytes = (8 - (size % 8)) & 0x7;
00230         if (pad_bytes > 0) {
00231             if (vpc->write_func(fd, pad_data, pad_bytes) != pad_bytes)
00232                 return(VPSetError(vpc, VPERROR_IO));
00233         }
00234     }
00235     if (rle_voxels->data_count > 0) {
00236         size = rle_voxels->data_count * vpc->rle_bytes_per_voxel;
00237         if (vpc->write_func(fd, rle_voxels->data, size) != size)
00238             return(VPSetError(vpc, VPERROR_IO));
00239 
00240         pad_bytes = (8 - (size % 8)) & 0x7;
00241         if (pad_bytes > 0) {
00242             if (vpc->write_func(fd, pad_data, pad_bytes) != pad_bytes)
00243                 return(VPSetError(vpc, VPERROR_IO));
00244         }
00245     }
00246     if (rle_voxels->scan_offsets_per_slice > 0) {
00247         size = rle_voxels->scan_offsets_per_slice * rle_voxels->klen *
00248             sizeof(ScanOffset);
00249         if (vpc->write_func(fd, rle_voxels->scan_offsets, size) != size)
00250             return(VPSetError(vpc, VPERROR_IO));
00251 
00252         pad_bytes = (8 - (size % 8)) & 0x7;
00253         if (pad_bytes > 0) {
00254             if (vpc->write_func(fd, pad_data, pad_bytes) != pad_bytes)
00255                 return(VPSetError(vpc, VPERROR_IO));
00256         }
00257     }
00258     return(VP_OK);
00259 }
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 vpResult
00268 vpLoadClassifiedVolume(vpc, fd)
00269 vpContext *vpc; 
00270 int fd;         
00271 {
00272     RLEVoxelHdr header;
00273     unsigned field_data[3*VP_MAX_FIELDS];
00274     int nsf, c, swab;
00275     unsigned size;
00276     unsigned char *data;
00277     char pad_data[8];
00278     int pad_bytes;
00279     unsigned x_run_offset;
00280     unsigned x_data_offset;
00281     unsigned x_offset_offset;
00282     unsigned y_run_offset;
00283     unsigned y_data_offset;
00284     unsigned y_offset_offset;
00285     unsigned z_run_offset;
00286     unsigned z_data_offset;
00287     unsigned z_offset_offset;
00288     int current_offset;
00289     int destroy_old_volume;
00290 
00291     
00292     if (vpc->read_func(fd, &header, sizeof(header)) != sizeof(header))
00293         return(VPSetError(vpc, VPERROR_IO));
00294     swab = 0;
00295     if (header.magic != VP_CVFILE_MAGIC) {
00296         SwapWords(&header, sizeof(header));
00297         if (header.magic != VP_CVFILE_MAGIC)
00298             return(VPSetError(vpc, VPERROR_BAD_FILE));
00299         swab = 1;
00300     }
00301 
00302     
00303     size = 3 * header.num_shade_fields * sizeof(unsigned);
00304     if (vpc->read_func(fd, field_data, size) != size)
00305         return(VPSetError(vpc, VPERROR_IO));
00306     if (swab)
00307         SwapWords(field_data, size);
00308 
00309     
00310     pad_bytes = (8 - ((sizeof(header) + size) % 8)) & 0x7;
00311     if (pad_bytes > 0) {
00312         if (vpc->read_func(fd, pad_data, pad_bytes) != pad_bytes)
00313             return(VPSetError(vpc, VPERROR_IO));
00314     }
00315 
00316     
00317     destroy_old_volume = 0;
00318     if (vpc->xlen != header.xlen || vpc->ylen != header.ylen ||
00319         vpc->zlen != header.zlen ||
00320         vpc->raw_bytes_per_voxel < header.bytes_per_voxel ||
00321         vpc->num_voxel_fields < header.num_shade_fields)
00322         destroy_old_volume = 1;
00323     nsf = header.num_shade_fields;
00324     for (c = 0; c < nsf; c++) {
00325         if (vpc->field_size[c] != field_data[c] ||
00326             vpc->field_offset[c] != field_data[nsf + c] ||
00327             vpc->field_max[c] != field_data[2*nsf + c])
00328             destroy_old_volume = 1;
00329     }
00330     if (destroy_old_volume) {
00331         vpDestroyClassifiedVolume(vpc);
00332         vpDestroyMinMaxOctree(vpc);
00333         vpc->raw_voxels = NULL;
00334         vpc->raw_voxels_size = 0;
00335         vpc->xstride = 0;
00336         vpc->ystride = 0;
00337         vpc->zstride = 0;
00338     }
00339 
00340     
00341     if (destroy_old_volume) {
00342         vpc->xlen = header.xlen;
00343         vpc->ylen = header.ylen;
00344         vpc->zlen = header.zlen;
00345         vpc->raw_bytes_per_voxel = header.bytes_per_voxel;
00346         nsf = header.num_shade_fields;
00347         vpc->num_voxel_fields = nsf;
00348         for (c = 0; c < nsf; c++) {
00349             vpc->field_size[c] = field_data[c];
00350             vpc->field_offset[c] = field_data[nsf + c];
00351             vpc->field_max[c] = field_data[2*nsf + c];
00352         }
00353     }
00354     vpc->num_shade_fields = nsf;
00355     vpc->min_opacity = header.min_opacity;
00356     vpc->rle_bytes_per_voxel = header.bytes_per_voxel;
00357 
00358     
00359     if (vpc->mmap_func != NULL && !swab) {
00360         
00361         current_offset = sizeof(header) + size;
00362         current_offset += (8 - (current_offset % 8)) & 0x7;
00363         x_run_offset = current_offset;
00364         current_offset += header.num_x_runs;
00365         current_offset += (8 - (current_offset % 8)) & 0x7;
00366         x_data_offset = current_offset;
00367         current_offset += header.num_x_voxels * header.bytes_per_voxel;
00368         current_offset += (8 - (current_offset % 8)) & 0x7;
00369         x_offset_offset = current_offset;
00370         current_offset += header.num_x_offsets * sizeof(ScanOffset);
00371         current_offset += (8 - (current_offset % 8)) & 0x7;
00372         y_run_offset = current_offset;
00373         current_offset += header.num_y_runs;
00374         current_offset += (8 - (current_offset % 8)) & 0x7;
00375         y_data_offset = current_offset;
00376         current_offset += header.num_y_voxels * header.bytes_per_voxel;
00377         current_offset += (8 - (current_offset % 8)) & 0x7;
00378         y_offset_offset = current_offset;
00379         current_offset += header.num_y_offsets * sizeof(ScanOffset);
00380         current_offset += (8 - (current_offset % 8)) & 0x7;
00381         z_run_offset = current_offset;
00382         current_offset += header.num_z_runs;
00383         current_offset += (8 - (current_offset % 8)) & 0x7;
00384         z_data_offset = current_offset;
00385         current_offset += header.num_z_voxels * header.bytes_per_voxel;
00386         current_offset += (8 - (current_offset % 8)) & 0x7;
00387         z_offset_offset = current_offset;
00388         current_offset += header.num_z_offsets * sizeof(ScanOffset);
00389 
00390         
00391         if ((data = vpc->mmap_func(fd, current_offset,
00392                                    vpc->client_data)) == NULL)
00393             return(VPSetError(vpc, VPERROR_IO));
00394 
00395         
00396         vpc->rle_x = VPCreateRLEVoxels(vpc, header.ylen, header.zlen,
00397                                        header.xlen, 0, 0, 0);
00398         vpc->rle_x->run_count = header.num_x_runs;
00399         if (header.num_x_runs > 0)
00400             vpc->rle_x->run_lengths = (unsigned char *)(data + x_run_offset);
00401         vpc->rle_x->data_count = header.num_x_voxels;
00402         if (header.num_x_voxels > 0)
00403             vpc->rle_x->data = (void *)(data + x_data_offset);
00404         vpc->rle_x->scan_offsets_per_slice = header.num_x_offsets;
00405         if (header.num_x_offsets > 0)
00406             vpc->rle_x->scan_offsets = (ScanOffset *)(data + x_offset_offset);
00407         vpc->rle_x->mmapped = 1;
00408 
00409         
00410         vpc->rle_y = VPCreateRLEVoxels(vpc, header.zlen, header.xlen,
00411                                        header.ylen, 0, 0, 0);
00412         vpc->rle_y->run_count = header.num_y_runs;
00413         if (header.num_y_runs > 0)
00414             vpc->rle_y->run_lengths = (unsigned char *)(data + y_run_offset);
00415         vpc->rle_y->data_count = header.num_y_voxels;
00416         if (header.num_y_voxels > 0)
00417             vpc->rle_y->data = (void *)(data + y_data_offset);
00418         vpc->rle_y->scan_offsets_per_slice = header.num_y_offsets;
00419         if (header.num_y_offsets > 0)
00420             vpc->rle_y->scan_offsets = (ScanOffset *)(data + y_offset_offset);
00421         vpc->rle_y->mmapped = 1;
00422 
00423         
00424         vpc->rle_z = VPCreateRLEVoxels(vpc, header.xlen, header.ylen,
00425                                        header.zlen, 0, 0, 0);
00426         vpc->rle_z->run_count = header.num_z_runs;
00427         if (header.num_z_runs > 0)
00428             vpc->rle_z->run_lengths = (unsigned char *)(data + z_run_offset);
00429         vpc->rle_z->data_count = header.num_z_voxels;
00430         if (header.num_z_voxels > 0)
00431             vpc->rle_z->data = (void *)(data + z_data_offset);
00432         vpc->rle_z->scan_offsets_per_slice = header.num_z_offsets;
00433         if (header.num_z_offsets > 0)
00434             vpc->rle_z->scan_offsets = (ScanOffset *)(data + z_offset_offset);
00435         vpc->rle_z->mmapped = 1;
00436     } else {
00437         
00438         if (header.num_x_runs != 0) {
00439             vpc->rle_x = VPCreateRLEVoxels(vpc, header.ylen, header.zlen,
00440                 header.xlen, header.num_x_voxels, header.num_x_runs,
00441                 header.bytes_per_voxel);
00442             if ((c = LoadRLEVoxels(vpc, fd, vpc->rle_x, header.num_x_offsets,
00443                                    swab)) != VP_OK)
00444                 return(c);
00445         }
00446 
00447         
00448         if (header.num_y_runs != 0) {
00449             vpc->rle_y = VPCreateRLEVoxels(vpc, header.zlen, header.xlen,
00450                 header.ylen, header.num_y_voxels, header.num_y_runs,
00451                 header.bytes_per_voxel);
00452             if ((c = LoadRLEVoxels(vpc, fd, vpc->rle_y, header.num_y_offsets,
00453                                    swab)) != VP_OK)
00454                 return(c);
00455         }
00456 
00457         
00458         if (header.num_z_runs != 0) {
00459             vpc->rle_z = VPCreateRLEVoxels(vpc, header.xlen, header.ylen,
00460                 header.zlen, header.num_z_voxels, header.num_z_runs,
00461                 header.bytes_per_voxel);
00462             if ((c = LoadRLEVoxels(vpc, fd, vpc->rle_z, header.num_z_offsets,
00463                                    swab)) != VP_OK)
00464                 return(c);
00465         }
00466     }
00467 #ifdef DEBUG
00468     if (vpc->rle_x != NULL) {
00469         printf("Checking X scanline offsets....\n");
00470         VPCheckScanOffsets(vpc->rle_x, vpc->rle_bytes_per_voxel);
00471     }
00472     if (vpc->rle_y != NULL) {
00473         printf("Checking Y scanline offsets....\n");
00474         VPCheckScanOffsets(vpc->rle_y, vpc->rle_bytes_per_voxel);
00475     }
00476     if (vpc->rle_z != NULL) {
00477         printf("Checking Z scanline offsets....\n");
00478         VPCheckScanOffsets(vpc->rle_z, vpc->rle_bytes_per_voxel);
00479     }
00480 #endif
00481     return(VP_OK);
00482 }
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 static int
00491 LoadRLEVoxels(vpc, fd, rle_voxels, offsets, swab)
00492 vpContext *vpc;
00493 int fd;
00494 RLEVoxels *rle_voxels;
00495 int offsets;
00496 int swab;
00497 {
00498     int size;
00499     char pad_data[8];
00500     int pad_bytes;
00501 
00502     if (rle_voxels->run_count > 0) {
00503         size = rle_voxels->run_count;
00504         if (vpc->read_func(fd, rle_voxels->run_lengths, size) != size)
00505             return(VPSetError(vpc, VPERROR_IO));
00506 
00507         pad_bytes = (8 - (size % 8)) & 0x7;
00508         if (pad_bytes > 0) {
00509             if (vpc->read_func(fd, pad_data, pad_bytes) != pad_bytes)
00510                 return(VPSetError(vpc, VPERROR_IO));
00511         }
00512     }
00513     if (rle_voxels->data_count > 0) {
00514         size = rle_voxels->data_count * vpc->rle_bytes_per_voxel;
00515         if (vpc->read_func(fd, rle_voxels->data, size) != size)
00516             return(VPSetError(vpc, VPERROR_IO));
00517         if (swab)
00518             SwapVoxels(vpc, rle_voxels->data, rle_voxels->data_count,
00519                        vpc->num_shade_fields, vpc->rle_bytes_per_voxel);
00520 
00521         pad_bytes = (8 - (size % 8)) & 0x7;
00522         if (pad_bytes > 0) {
00523             if (vpc->read_func(fd, pad_data, pad_bytes) != pad_bytes)
00524                 return(VPSetError(vpc, VPERROR_IO));
00525         }
00526     }
00527     if (offsets > 0) {
00528         rle_voxels->scan_offsets_per_slice = offsets;
00529         size = rle_voxels->klen * offsets * sizeof(ScanOffset);
00530         Alloc(vpc, rle_voxels->scan_offsets, ScanOffset *, size,
00531               "scan_offsets");
00532         if (vpc->read_func(fd, rle_voxels->scan_offsets, size) != size)
00533             return(VPSetError(vpc, VPERROR_IO));
00534         if (swab)
00535             SwapWords(rle_voxels->scan_offsets, size);
00536 
00537         pad_bytes = (8 - (size % 8)) & 0x7;
00538         if (pad_bytes > 0) {
00539             if (vpc->read_func(fd, pad_data, pad_bytes) != pad_bytes)
00540                 return(VPSetError(vpc, VPERROR_IO));
00541         }
00542     }
00543     return(VP_OK);
00544 }
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 static void
00553 SwapWords(data, size)
00554 void *data;
00555 unsigned size;
00556 {
00557     unsigned char *ptr;
00558     int tmp1, tmp2;
00559 
00560     ptr = data;
00561     while (size >= 4) {
00562         tmp1 = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp1;
00563         tmp2 = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp2;
00564         size -= 4;
00565         ptr += 4;
00566     }
00567 }
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 static void
00576 SwapVoxels(vpc, voxels, num_voxels, fields, bytes_per_voxel)
00577 vpContext *vpc;         
00578 void *voxels;           
00579 int num_voxels;         
00580 int fields;             
00581 int bytes_per_voxel;    
00582 {
00583     int f, size, offset;
00584     unsigned char *voxel_ptr;
00585     int tmp1, tmp2;
00586 
00587     
00588     size = 0;
00589     for (f = 0; f < fields; f++) {
00590         if (vpc->field_size[f] > size)
00591             size = vpc->field_size[f];
00592     }
00593     if (size <= 1)
00594         return;
00595 
00596     
00597     voxel_ptr = voxels;
00598     while (num_voxels-- > 0) {
00599         for (f = 0; f < fields; f++) {
00600             size = vpc->field_size[f];
00601             if (size == 1)
00602                 continue;
00603             offset = vpc->field_offset[f];
00604             if (size == 2) {
00605                 tmp1 = voxel_ptr[offset];
00606                 voxel_ptr[offset] = voxel_ptr[offset+1];
00607                 voxel_ptr[offset+1] = tmp1;
00608             } else {
00609                 tmp1 = voxel_ptr[offset];
00610                 voxel_ptr[offset] = voxel_ptr[offset+3];
00611                 voxel_ptr[offset+3] = tmp1;
00612                 tmp2 = voxel_ptr[offset+1];
00613                 voxel_ptr[offset+1] = voxel_ptr[offset+2];
00614                 voxel_ptr[offset+2] = tmp2;
00615             }
00616         }
00617         voxel_ptr += bytes_per_voxel;
00618     }
00619 }
00620 
00621 
00622 
00623 
00624 
00625 
00626 typedef struct {
00627     unsigned magic;             
00628     unsigned xlen;              
00629     unsigned ylen;
00630     unsigned zlen;
00631     int num_clsfy_params;       
00632     int levels;                 
00633     int root_node_size;         
00634     int base_node_size;         
00635     int range_bytes_per_node;   
00636     int base_bytes_per_node;    
00637     int nonbase_bytes_per_node; 
00638     int status_offset;          
00639     int child_offset;           
00640     unsigned octree_bytes;      
00641 } MinMaxOctreeHdr;
00642 
00643 
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 vpResult
00659 vpStoreMinMaxOctree(vpc, fd)
00660 vpContext *vpc; 
00661 int fd;         
00662 {
00663     MinMaxOctreeHdr header;
00664     unsigned field_data[3*VP_MAX_FIELDS];
00665     int ncp, c;
00666     unsigned size;
00667 
00668     if (vpc->mm_octree == NULL)
00669         return(VPSetError(vpc, VPERROR_BAD_SIZE));
00670 
00671     
00672     bzero(&header, sizeof(MinMaxOctreeHdr));
00673     header.magic = VP_OCTFILE_MAGIC;
00674     header.xlen = vpc->xlen;
00675     header.ylen = vpc->ylen;
00676     header.zlen = vpc->zlen;
00677     header.num_clsfy_params = vpc->num_clsfy_params;
00678     header.levels = vpc->mm_octree->levels;
00679     header.root_node_size = vpc->mm_octree->root_node_size;
00680     header.base_node_size = vpc->mm_octree->base_node_size;
00681     header.range_bytes_per_node = vpc->mm_octree->range_bytes_per_node;
00682     header.base_bytes_per_node = vpc->mm_octree->base_bytes_per_node;
00683     header.nonbase_bytes_per_node = vpc->mm_octree->nonbase_bytes_per_node;
00684     header.status_offset = vpc->mm_octree->status_offset;
00685     header.child_offset = vpc->mm_octree->child_offset;
00686     header.octree_bytes = vpc->mm_octree->octree_bytes;
00687     if (vpc->write_func(fd, &header, sizeof(header)) != sizeof(header))
00688         return(VPSetError(vpc, VPERROR_IO));
00689 
00690     
00691     ncp = vpc->num_clsfy_params;
00692     for (c = 0; c < ncp; c++) {
00693         field_data[c] = vpc->field_size[vpc->param_field[c]];
00694         field_data[ncp + c] = vpc->field_max[vpc->param_field[c]];
00695         field_data[2*ncp + c] = vpc->mm_octree->node_offset[c];
00696     }
00697     size = 3*ncp*sizeof(unsigned);
00698     if (vpc->write_func(fd, field_data, size) != size)
00699         return(VPSetError(vpc, VPERROR_IO));
00700 
00701     
00702     size = vpc->mm_octree->octree_bytes;
00703     if (vpc->write_func(fd, vpc->mm_octree->root, size) != size)
00704         return(VPSetError(vpc, VPERROR_IO));
00705 
00706     return(VP_OK);
00707 }
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715 vpResult
00716 vpLoadMinMaxOctree(vpc, fd)
00717 vpContext *vpc; 
00718 int fd;         
00719 {
00720     MinMaxOctreeHdr header;
00721     unsigned field_data[3*VP_MAX_FIELDS];
00722     int ncp, c, swab;
00723     unsigned size;
00724 
00725     
00726     if (vpc->read_func(fd, &header, sizeof(header)) != sizeof(header))
00727         return(VPSetError(vpc, VPERROR_IO));
00728     swab = 0;
00729     if (header.magic != VP_OCTFILE_MAGIC) {
00730         SwapWords(&header, sizeof(header));
00731         if (header.magic != VP_OCTFILE_MAGIC)
00732             return(VPSetError(vpc, VPERROR_BAD_FILE));
00733         swab = 1;
00734     }
00735 
00736     
00737     size = 3 * header.num_clsfy_params * sizeof(unsigned);
00738     if (vpc->read_func(fd, field_data, size) != size)
00739         return(VPSetError(vpc, VPERROR_IO));
00740     if (swab)
00741         SwapWords(field_data, size);
00742 
00743     
00744     if ((c = VPCheckRawVolume(vpc)) != VP_OK)
00745         return(c);
00746     if (header.xlen != vpc->xlen || header.ylen != vpc->ylen ||
00747         header.zlen != vpc->zlen ||
00748         header.num_clsfy_params != vpc->num_clsfy_params)
00749         return(VPSetError(vpc, VPERROR_BAD_VOLUME));
00750     ncp = vpc->num_clsfy_params;
00751     for (c = 0; c < ncp; c++) {
00752         if (field_data[c] != vpc->field_size[vpc->param_field[c]] ||
00753             field_data[ncp + c] != vpc->field_max[vpc->param_field[c]])
00754             return(VPSetError(vpc, VPERROR_BAD_VOXEL));
00755     }
00756 
00757     
00758     vpDestroyMinMaxOctree(vpc);
00759 
00760     
00761     Alloc(vpc, vpc->mm_octree, MinMaxOctree *, sizeof(MinMaxOctree),
00762           "MinMaxOctree");
00763     bzero(vpc->mm_octree, sizeof(MinMaxOctree));
00764     vpc->mm_octree->levels = header.levels;
00765     vpc->mm_octree->root_node_size = header.root_node_size;
00766     vpc->mm_octree->base_node_size = header.base_node_size;
00767     vpc->mm_octree->range_bytes_per_node = header.range_bytes_per_node;
00768     vpc->mm_octree->base_bytes_per_node = header.base_bytes_per_node;
00769     vpc->mm_octree->nonbase_bytes_per_node = header.nonbase_bytes_per_node;
00770     vpc->mm_octree->status_offset = header.status_offset;
00771     vpc->mm_octree->child_offset = header.child_offset;
00772     vpc->mm_octree->octree_bytes = header.octree_bytes;
00773     ncp = header.num_clsfy_params;
00774     for (c = 0; c < ncp; c++)
00775         vpc->mm_octree->node_offset[c] = field_data[2*ncp + c];
00776 
00777     
00778     size = header.octree_bytes;
00779     Alloc(vpc, vpc->mm_octree->root, void *, size, "mm_octree");
00780     if (vpc->read_func(fd, vpc->mm_octree->root, size) != size)
00781         return(VPSetError(vpc, VPERROR_IO));
00782     if (swab)
00783         SwapOctreeNode(vpc, 0, vpc->mm_octree->root);
00784 
00785     return(VP_OK);
00786 }
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 static void
00796 SwapOctreeNode(vpc, level, node)
00797 vpContext *vpc;
00798 int level;
00799 void *node;
00800 {
00801     int p, field, size, offset, tmp1, tmp2;
00802     int child_bytes_per_node;
00803     char *node_ptr = node;
00804 
00805     
00806     for (p = 0; p < vpc->num_clsfy_params; p++) {
00807         field = vpc->param_field[p];
00808         size = vpc->field_size[field];
00809         if (size != 1) {
00810             ASSERT(size == 2);
00811             offset = vpc->mm_octree->node_offset[p];
00812             tmp1 = node_ptr[offset];
00813             node_ptr[offset] = node_ptr[offset+1];
00814             node_ptr[offset+1] = tmp1;
00815             tmp2 = node_ptr[offset+2];
00816             node_ptr[offset+2] = node_ptr[offset+3];
00817             node_ptr[offset+3] = tmp2;
00818         }
00819     }
00820 
00821     
00822     if (level != vpc->mm_octree->levels-1) {
00823         offset = vpc->mm_octree->child_offset;
00824         tmp1 = node_ptr[offset];
00825         node_ptr[offset] = node_ptr[offset+3];
00826         node_ptr[offset+3] = tmp1;
00827         tmp2 = node_ptr[offset+1];
00828         node_ptr[offset+1] = node_ptr[offset+2];
00829         node_ptr[offset+2] = tmp2;
00830 
00831         ASSERT(IntField(node, offset) != 0);
00832         node_ptr = (char *)vpc->mm_octree->root + IntField(node, offset);
00833         if (level == vpc->mm_octree->levels-2)
00834             child_bytes_per_node = vpc->mm_octree->base_bytes_per_node;
00835         else
00836             child_bytes_per_node = vpc->mm_octree->nonbase_bytes_per_node;
00837         SwapOctreeNode(vpc, level+1, node_ptr);
00838         node_ptr += child_bytes_per_node;
00839         SwapOctreeNode(vpc, level+1, node_ptr);
00840         node_ptr += child_bytes_per_node;
00841         SwapOctreeNode(vpc, level+1, node_ptr);
00842         node_ptr += child_bytes_per_node;
00843         SwapOctreeNode(vpc, level+1, node_ptr);
00844         node_ptr += child_bytes_per_node;
00845         SwapOctreeNode(vpc, level+1, node_ptr);
00846         node_ptr += child_bytes_per_node;
00847         SwapOctreeNode(vpc, level+1, node_ptr);
00848         node_ptr += child_bytes_per_node;
00849         SwapOctreeNode(vpc, level+1, node_ptr);
00850         node_ptr += child_bytes_per_node;
00851         SwapOctreeNode(vpc, level+1, node_ptr);
00852     }
00853 }
00854 
00855 
00856 
00857 
00858 
00859 
00860 typedef struct {
00861     unsigned magic;             
00862     unsigned xlen;              
00863     unsigned ylen;
00864     unsigned zlen;
00865     unsigned bytes_per_voxel;   
00866     unsigned num_voxel_fields;  
00867     unsigned num_shade_fields;  
00868     unsigned num_clsfy_fields;  
00869     int xstride;                
00870     int ystride;
00871     int zstride;
00872 } RawVoxelHdr;
00873 
00874 
00875 
00876 
00877 
00878 
00879 
00880 
00881 
00882 
00883 
00884 
00885 
00886 
00887 
00888 
00889 vpResult
00890 vpStoreRawVolume(vpc, fd)
00891 vpContext *vpc; 
00892 int fd;         
00893 {
00894     RawVoxelHdr header;
00895     unsigned field_data[3*VP_MAX_FIELDS];
00896     int nvf, c;
00897     unsigned size;
00898     int retcode;
00899 
00900     
00901     if ((retcode = VPCheckRawVolume(vpc)) != VP_OK)
00902         return(retcode);
00903 
00904     
00905     header.magic = VP_RVFILE_MAGIC;
00906     header.xlen = vpc->xlen;
00907     header.ylen = vpc->ylen;
00908     header.zlen = vpc->zlen;
00909     header.bytes_per_voxel = vpc->raw_bytes_per_voxel;
00910     header.num_voxel_fields = vpc->num_voxel_fields;
00911     header.num_shade_fields = vpc->num_shade_fields;
00912     header.num_clsfy_fields = vpc->num_clsfy_params;
00913     header.xstride = vpc->xstride;
00914     header.ystride = vpc->ystride;
00915     header.zstride = vpc->zstride;
00916     if (vpc->write_func(fd, &header, sizeof(header)) != sizeof(header))
00917         return(VPSetError(vpc, VPERROR_IO));
00918 
00919     
00920     nvf = vpc->num_voxel_fields;
00921     for (c = 0; c < nvf; c++) {
00922         field_data[c] = vpc->field_size[c];
00923         field_data[nvf + c] = vpc->field_offset[c];
00924         field_data[2*nvf + c] = vpc->field_max[c];
00925     }
00926     size = 3*nvf*sizeof(unsigned);
00927     if (vpc->write_func(fd, field_data, size) != size)
00928         return(VPSetError(vpc, VPERROR_IO));
00929 
00930     
00931     if (vpc->write_func(fd, vpc->raw_voxels, vpc->raw_voxels_size) !=
00932         vpc->raw_voxels_size)
00933         return(VPSetError(vpc, VPERROR_IO));
00934 
00935     return(VP_OK);
00936 }
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 vpResult
00945 vpLoadRawVolume(vpc, fd)
00946 vpContext *vpc; 
00947 int fd;         
00948 {
00949     RawVoxelHdr header;
00950     unsigned field_data[3*VP_MAX_FIELDS];
00951     int nvf, c, swab;
00952     unsigned size;
00953     unsigned voxel_offset;
00954     unsigned char *data;
00955     int destroy_old_volume;
00956 
00957     
00958     if (vpc->read_func(fd, &header, sizeof(header)) != sizeof(header))
00959         return(VPSetError(vpc, VPERROR_IO));
00960     swab = 0;
00961     if (header.magic != VP_RVFILE_MAGIC) {
00962         SwapWords(&header, sizeof(header));
00963         if (header.magic != VP_RVFILE_MAGIC)
00964             return(VPSetError(vpc, VPERROR_BAD_FILE));
00965         swab = 1;
00966     }
00967 
00968     
00969     size = 3 * header.num_voxel_fields * sizeof(unsigned);
00970     if (vpc->read_func(fd, field_data, size) != size)
00971         return(VPSetError(vpc, VPERROR_IO));
00972     if (swab)
00973         SwapWords(field_data, size);
00974     voxel_offset = sizeof(header) + size;
00975 
00976     
00977     vpDestroyClassifiedVolume(vpc);
00978     vpDestroyMinMaxOctree(vpc);
00979 
00980     
00981     vpc->xlen = header.xlen;
00982     vpc->ylen = header.ylen;
00983     vpc->zlen = header.zlen;
00984     vpc->raw_bytes_per_voxel = header.bytes_per_voxel;
00985     vpc->num_voxel_fields = header.num_voxel_fields;
00986     vpc->num_shade_fields = header.num_shade_fields;
00987     vpc->num_clsfy_params = header.num_clsfy_fields;
00988     vpc->xstride = header.xstride;
00989     vpc->ystride = header.ystride;
00990     vpc->zstride = header.zstride;
00991     nvf = header.num_voxel_fields;
00992     for (c = 0; c < nvf; c++) {
00993         vpc->field_size[c] = field_data[c];
00994         vpc->field_offset[c] = field_data[nvf + c];
00995         vpc->field_max[c] = field_data[2*nvf + c];
00996     }
00997 
00998     
00999     size = vpc->xlen*vpc->ylen*vpc->zlen*vpc->raw_bytes_per_voxel;
01000     vpc->raw_voxels_size = size;
01001     if (vpc->mmap_func != NULL && !swab) {
01002         if ((vpc->raw_voxels = vpc->mmap_func(fd, voxel_offset,
01003                                               vpc->client_data)) == NULL)
01004             return(VPSetError(vpc, VPERROR_IO));
01005     } else {
01006         Alloc(vpc, vpc->raw_voxels, void *, size, "raw_voxels");
01007         if (vpc->read_func(fd, vpc->raw_voxels, size) != size)
01008             return(VPSetError(vpc, VPERROR_IO));
01009         if (swab) {
01010             SwapVoxels(vpc, vpc->raw_voxels, vpc->xlen*vpc->ylen*vpc->zlen,
01011                        vpc->num_voxel_fields, vpc->raw_bytes_per_voxel);
01012         }
01013     }
01014 
01015     return(VP_OK);
01016 }
01017 
01018 
01019 
01020 
01021 
01022 
01023 typedef struct {
01024     unsigned magic;             
01025     unsigned major_version;     
01026     unsigned minor_version;     
01027     unsigned max_fields;        
01028     unsigned max_material;      
01029     unsigned max_lights;        
01030 } VpcHdr;
01031 
01032 
01033 
01034 
01035 
01036 
01037 
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 
01056 vpResult
01057 vpStoreContext(vpc, fd)
01058 vpContext *vpc;
01059 int fd;
01060 {
01061     VpcHdr header;
01062     int i;
01063     unsigned vpc_size;
01064 
01065     header.magic = VP_VPCFILE_MAGIC;
01066     header.major_version = VP_MAJOR_VERSION;
01067     header.minor_version = VP_MINOR_VERSION;
01068     header.max_fields = VP_MAX_FIELDS;
01069     header.max_material = VP_MAX_MATERIAL;
01070     header.max_lights = VP_MAX_LIGHTS;
01071     vpc_size = vpFieldOffset(vpc, end_of_parameters);
01072     if (vpc->write_func(fd, &header, sizeof(header)) != sizeof(header))
01073         return(VPSetError(vpc, VPERROR_IO));
01074     if (vpc->write_func(fd, vpc, vpc_size) != vpc_size)
01075         return(VPSetError(vpc, VPERROR_IO));
01076     if (!StoreTable(vpc, fd, vpc->shade_color_table,
01077                     vpc->shade_color_table_size))
01078         return(VPSetError(vpc, VPERROR_IO));
01079     if (!StoreTable(vpc, fd, vpc->shade_weight_table,
01080                     vpc->shade_weight_table_size))
01081         return(VPSetError(vpc, VPERROR_IO));
01082     for (i = 0; i < vpc->num_clsfy_params; i++) {
01083         if (!StoreTable(vpc, fd, vpc->clsfy_table[i],
01084                         vpc->clsfy_table_size[i]))
01085             return(VPSetError(vpc, VPERROR_IO));
01086     }
01087     return(VP_OK);
01088 }
01089 
01090 
01091 
01092 
01093 
01094 
01095 
01096 
01097 static int
01098 StoreTable(vpc, fd, ptr, size)
01099 vpContext *vpc;
01100 int fd;
01101 float *ptr;
01102 unsigned size;
01103 {
01104     if (size == 0 || ptr == NULL) {
01105         size = 0;
01106         if (vpc->write_func(fd, &size, sizeof(size)) != sizeof(size))
01107             return(0);
01108     } else {
01109         if (vpc->write_func(fd, &size, sizeof(size)) != sizeof(size))
01110             return(0);
01111         if (vpc->write_func(fd, ptr, size) != size)
01112             return(0);
01113     }
01114     return(1);
01115 }
01116 
01117 
01118 
01119 
01120 
01121 
01122 
01123 
01124 
01125 
01126 
01127 
01128 
01129 
01130 vpResult
01131 vpLoadContext(vpc, fd)
01132 vpContext *vpc;
01133 int fd;
01134 {
01135     VpcHdr header;
01136     int swab, i;
01137     unsigned vpc_size;
01138 
01139     
01140     if (vpc->read_func(fd, &header, sizeof(header)) != sizeof(header))
01141         return(VPSetError(vpc, VPERROR_IO));
01142     swab = 0;
01143     if (header.magic != VP_VPCFILE_MAGIC)
01144         return(VPSetError(vpc, VPERROR_BAD_FILE));
01145     if (header.major_version != VP_MAJOR_VERSION || 
01146         header.minor_version != VP_MINOR_VERSION ||
01147         header.max_fields != VP_MAX_FIELDS ||
01148         header.max_material != VP_MAX_MATERIAL ||
01149         header.max_lights != VP_MAX_LIGHTS) {
01150         return(VPSetError(vpc, VPERROR_BAD_VALUE));
01151     }
01152 
01153     
01154     vpDestroyMinMaxOctree(vpc);
01155     vpDestroyClassifiedVolume(vpc);
01156 
01157     
01158     vpc_size = vpFieldOffset(vpc, end_of_parameters);
01159     if (vpc->read_func(fd, vpc, vpc_size) != vpc_size)
01160         return(VPSetError(vpc, VPERROR_IO));
01161     vpc->raw_voxels = NULL;
01162     for (i = 0; i < VP_MAX_FIELDS; i++)
01163         vpc->clsfy_table[i] = NULL;
01164     vpc->shade_color_table = NULL;
01165     vpc->shade_weight_table = NULL;
01166     vpc->image = NULL;
01167     if (vpc->shade_func == NULL)
01168         vpc->shading_mode = LOOKUP_SHADER;
01169     if (!LoadTable(vpc, fd, &vpc->shade_color_table,
01170                    (unsigned *)&vpc->shade_color_table_size))
01171         goto failed;
01172     if (!LoadTable(vpc, fd, &vpc->shade_weight_table,
01173                    (unsigned *)&vpc->shade_weight_table_size))
01174         goto failed;
01175     for (i = 0; i < vpc->num_clsfy_params; i++) {
01176         if (!LoadTable(vpc, fd, &vpc->clsfy_table[i],
01177                        (unsigned *)&vpc->clsfy_table_size[i]))
01178             goto failed;
01179     }
01180     return(VP_OK);
01181 
01182  failed:
01183     if (vpc->shade_color_table != NULL) {
01184         Dealloc(vpc, vpc->shade_color_table);
01185         vpc->shade_color_table = NULL;
01186     }
01187     if (vpc->shade_weight_table != NULL) {
01188         Dealloc(vpc, vpc->shade_weight_table);
01189         vpc->shade_weight_table = NULL;
01190     }
01191     for (i = 0; i < vpc->num_clsfy_params; i++) {
01192         if (vpc->clsfy_table[i] != NULL) {
01193             Dealloc(vpc, vpc->clsfy_table[i]);
01194             vpc->clsfy_table[i] = NULL;
01195         }
01196     }
01197     return(VPSetError(vpc, VPERROR_IO));
01198 }
01199 
01200 
01201 
01202 
01203 
01204 
01205 
01206 
01207 static int
01208 LoadTable(vpc, fd, ptr_ptr, size_ptr)
01209 vpContext *vpc;
01210 int fd;
01211 float **ptr_ptr;
01212 unsigned *size_ptr;
01213 {
01214     if (vpc->read_func(fd, size_ptr, sizeof(unsigned)) != sizeof(unsigned))
01215         return(0);
01216     if (*size_ptr != 0) {
01217         Alloc(vpc, *ptr_ptr, void *, *size_ptr, "lookup table");
01218         if (vpc->read_func(fd, *ptr_ptr, *size_ptr) != *size_ptr)
01219             return(0);
01220     }
01221     return(1);
01222 }