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 }