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 void EncodeScanline ANSI_ARGS((vpContext *vpc, void *voxels,
00034     MinMaxOctree *octree, MMOctreeLevel level_stack[VP_MAX_OCTREE_LEVELS]));
00035 static void InitRLE ANSI_ARGS((vpContext *vpc));
00036 static void CacheVoxel ANSI_ARGS((vpContext *vpc, double opacity,
00037     void *rawvoxel));
00038 static void CacheLength ANSI_ARGS((vpContext *vpc, int length));
00039 static void CountNonZeroVoxel ANSI_ARGS((RunData *rundata, int index,
00040     int end_of_scan, vpContext *vpc));
00041 static void RepackClassifiedVolume ANSI_ARGS((vpContext *vpc));
00042 static RLEVoxels *CreateEmptyRLEVoxels ANSI_ARGS((vpContext *vpc,
00043     int ilen, int jlen, int klen));
00044 static RLEVoxels *CreateRLEVoxelsFromRunData ANSI_ARGS((vpContext *vpc,
00045     int ilen, int jlen, int klen, int non_zero_count, RunData *run_data,
00046     int rle_bytes_per_voxel));
00047 static void StoreNonZeroVoxel ANSI_ARGS((void *voxel, int rle_bytes_per_voxel,
00048     void *data, unsigned char *lengths, RunData *rundata, int index));
00049 static void PadScanlines ANSI_ARGS((int ilen, int jlen, int klen,
00050     RunData *run_data, unsigned char *lengths));
00051 static ConstructionBuffer *CreateConstructionBuffer ANSI_ARGS((
00052     vpContext *vpc));
00053 static void DestroyConstructionBuffer ANSI_ARGS((vpContext *vpc,
00054     ConstructionBuffer *cbuf));
00055 static GBuffer *CreateGBuffer ANSI_ARGS((vpContext *vpc));
00056 static void DestroyGBuffer ANSI_ARGS((vpContext *vpc, GBuffer *gbuf));
00057 #ifdef INDEX_VOLUME
00058 static vpResult ComputeIndex ANSI_ARGS((vpContext *vpc,
00059     RLEVoxels *rle_voxels));
00060 #endif
00061 static vpResult ComputeScanOffsets ANSI_ARGS((vpContext *vpc,
00062     RLEVoxels *rle_voxels));
00063 #ifdef DEBUG
00064 static void ValidateRLEVoxels ANSI_ARGS((vpContext *vpc, RLEVoxels *rle,
00065     int istride, int jstride, int kstride, int axis));
00066 #endif
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 vpResult
00075 vpClassifyScalars(vpc, scalar_data, length, scalar_field, grad_field,
00076                   norm_field)
00077 vpContext *vpc;         
00078 unsigned char *scalar_data; 
00079 int length;             
00080 int scalar_field;       
00081 int grad_field;         
00082 int norm_field;         
00083 {
00084     int xlen, ylen, zlen;       
00085     int y, z;                   
00086     unsigned char *scalar;      
00087     int scalar_ystride;         
00088     int scalar_zstride;         
00089     char *voxel;                
00090     unsigned char *s_py, *s_my, *s_pz, *s_mz; 
00091     int retcode;                
00092     void *voxel_scan;           
00093 
00094     
00095     xlen = vpc->xlen;
00096     ylen = vpc->ylen;
00097     zlen = vpc->zlen;
00098     if (xlen == 0 || ylen == 0 || zlen == 0 || vpc->raw_bytes_per_voxel == 0)
00099         return(VPSetError(vpc, VPERROR_BAD_VOLUME));
00100     if (xlen * ylen * zlen != length)
00101         return(VPSetError(vpc, VPERROR_BAD_SIZE));
00102 
00103     
00104     scalar = scalar_data;
00105     scalar_ystride = xlen;
00106     scalar_zstride = xlen*ylen;
00107     Alloc(vpc, voxel_scan, void *, xlen*vpc->raw_bytes_per_voxel,"voxel_scan");
00108 
00109     
00110     for (z = 0; z < zlen; z++) {
00111         ReportStatus(vpc, (double)z / (double)zlen);
00112         for (y = 0; y < ylen; y++) {
00113             s_my = (y == 0)      ? NULL : scalar - scalar_ystride;
00114             s_py = (y == ylen-1) ? NULL : scalar + scalar_ystride;
00115             s_mz = (z == 0)      ? NULL : scalar - scalar_zstride;
00116             s_pz = (z == zlen-1) ? NULL : scalar + scalar_zstride;
00117             voxel = voxel_scan;
00118             retcode = vpScanlineNormals(vpc, xlen, scalar, s_my, s_py,
00119                                         s_mz, s_pz, voxel, scalar_field,
00120                                         grad_field, norm_field);
00121             if (retcode != VP_OK) {
00122                 Dealloc(vpc, voxel_scan);
00123                 return(retcode);
00124             }
00125             retcode = vpClassifyScanline(vpc, voxel_scan);
00126             if (retcode != VP_OK) {
00127                 Dealloc(vpc, voxel_scan);
00128                 return(retcode);
00129             }
00130             scalar += scalar_ystride;
00131         }
00132         scalar += scalar_zstride - ylen*scalar_ystride;
00133     }
00134     ReportStatus(vpc, 1.0);
00135     Dealloc(vpc, voxel_scan);
00136     return(VP_OK);
00137 }
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 vpResult
00147 vpClassifyVolume(vpc)
00148 vpContext *vpc;         
00149 {
00150     int xlen, ylen, zlen;       
00151     int y, z;                   
00152     char *voxel;                
00153     int voxel_ystride;          
00154     int voxel_zstride;          
00155     int retcode;                
00156     MinMaxOctree *octree;       
00157     MMOctreeLevel level_stack[VP_MAX_OCTREE_LEVELS]; 
00158 
00159     
00160     if ((retcode = VPCheckRawVolume(vpc)) != VP_OK)
00161         return(retcode);
00162     if ((retcode = VPCheckClassifier(vpc)) != VP_OK)
00163         return(retcode);
00164 
00165     
00166     vpDestroyClassifiedVolume(vpc);
00167     InitRLE(vpc);
00168     xlen = vpc->xlen;
00169     ylen = vpc->ylen;
00170     zlen = vpc->zlen;
00171     voxel = vpc->raw_voxels;
00172     voxel_ystride = vpc->ystride;
00173     voxel_zstride = vpc->zstride;
00174     octree = vpc->mm_octree;
00175     if (octree != NULL) {
00176         VPComputeSummedAreaTable(vpc);
00177         VPClassifyOctree(vpc);
00178     }
00179 
00180     
00181     for (z = 0; z < zlen; z++) {
00182         ReportStatus(vpc, (double)z / (double)zlen);
00183         if (octree != NULL)
00184             VPInitOctreeLevelStack(vpc, level_stack, VP_Z_AXIS, z);
00185         for (y = 0; y < ylen; y++) {
00186             EncodeScanline(vpc, voxel, octree, level_stack);
00187             voxel += voxel_ystride;
00188         }
00189         voxel += voxel_zstride - ylen*voxel_ystride;
00190     }
00191     ReportStatus(vpc, 1.0);
00192 
00193     return(VP_OK);
00194 }
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 vpResult
00204 vpClassifyScanline(vpc, voxels)
00205 vpContext *vpc;         
00206 void *voxels;           
00207 {
00208     int retcode;
00209 
00210     
00211     if (vpc->cbuf == NULL) {
00212         if ((retcode = VPCheckClassifier(vpc)) != VP_OK)
00213             return(retcode);
00214         vpDestroyClassifiedVolume(vpc);
00215         InitRLE(vpc);
00216     }
00217 
00218     
00219     EncodeScanline(vpc, voxels, NULL, NULL);
00220 
00221     return(VP_OK);
00222 }
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 static void
00231 EncodeScanline(vpc, voxels, octree, level_stack)
00232 vpContext *vpc;         
00233 void *voxels;           
00234 MinMaxOctree *octree;   
00235 MMOctreeLevel level_stack[VP_MAX_OCTREE_LEVELS]; 
00236 {
00237     ConstructionBuffer *cbuf;   
00238     RunData rundata_x;          
00239     RunData *rundata_y;         
00240     RunData *rundata_z;         
00241     int skip_rle_x;             
00242     int skip_rle_y;             
00243     int skip_rle_z;             
00244     int y, z;                   
00245     int x;                      
00246     int xlen, ylen, zlen;       
00247     float opacity;              
00248     float min_opacity;          
00249     int raw_bytes_per_voxel;    
00250     int run_length;             
00251     char *rawvoxel;             
00252     unsigned char *octree_run_ptr;      
00253     int voxel_count;            
00254     int retcode;
00255 
00256     
00257     cbuf = vpc->cbuf;
00258     xlen = vpc->xlen;
00259     ylen = vpc->ylen;
00260     zlen = vpc->zlen;
00261     bzero(&rundata_x, sizeof(RunData));
00262     rundata_y = &cbuf->rundata_y[cbuf->next_z];
00263     rundata_z = &cbuf->rundata_z[cbuf->next_y * xlen];
00264     skip_rle_x = vpc->skip_rle_x;
00265     skip_rle_y = vpc->skip_rle_y;
00266     skip_rle_z = vpc->skip_rle_z;
00267     min_opacity = vpc->min_opacity;
00268     raw_bytes_per_voxel = vpc->raw_bytes_per_voxel;
00269     rawvoxel = voxels;
00270     y = cbuf->next_y;
00271     z = cbuf->next_z;
00272     if (octree != NULL) {
00273         if (cbuf->octree_scans_left == 0) {
00274             cbuf->octree_scans_left = VPComputeScanRuns(vpc, level_stack,
00275                 cbuf->octree_runs, VP_Z_AXIS, y, xlen);
00276         }
00277         cbuf->octree_scans_left--;
00278         octree_run_ptr = cbuf->octree_runs;
00279     }
00280 
00281     
00282     x = 0;
00283     while (x < xlen) {
00284         if (octree == NULL) {
00285             
00286             voxel_count = xlen;
00287         } else do {
00288             
00289             voxel_count = *octree_run_ptr++;
00290             rundata_y += zlen * voxel_count;
00291             rundata_z += voxel_count;
00292             rawvoxel += raw_bytes_per_voxel * voxel_count;
00293             x += voxel_count;
00294 
00295             
00296             voxel_count = *octree_run_ptr++;
00297         } while (voxel_count == 0 && x < xlen);
00298 
00299         
00300         while (voxel_count-- > 0) {
00301             
00302             opacity = VPClassifyVoxel(vpc, rawvoxel);
00303 
00304             
00305             if (opacity > min_opacity) {
00306                 
00307                 CacheVoxel(vpc, opacity, rawvoxel);
00308                 if (!skip_rle_x) {
00309                     rundata_y->p.p1.non_zero_count++;
00310                     CountNonZeroVoxel(rundata_y, y, 0, NULL);
00311                 }
00312                 if (!skip_rle_y) {
00313                     rundata_z->p.p1.non_zero_count++;
00314                     CountNonZeroVoxel(rundata_z, z, 0, NULL);
00315                 }
00316                 rundata_x.p.p1.non_zero_count++;
00317                 CountNonZeroVoxel(&rundata_x, x, 0, vpc);
00318             }
00319 
00320             rundata_y += zlen;
00321             rundata_z++;
00322             rawvoxel += raw_bytes_per_voxel;
00323             x++;
00324         } 
00325     } 
00326 
00327     
00328     CountNonZeroVoxel(&rundata_x, x, 1, vpc);
00329 
00330     
00331     cbuf->non_zero_count += rundata_x.p.p1.non_zero_count;
00332     cbuf->x_run_count += rundata_x.p.p1.run_count;
00333 
00334     
00335     if (++cbuf->next_y == ylen) {
00336         cbuf->next_y = 0;
00337         cbuf->octree_scans_left = 0;
00338         if (++cbuf->next_z == zlen) {
00339             RepackClassifiedVolume(vpc);
00340             DestroyConstructionBuffer(vpc, vpc->cbuf);
00341             vpc->cbuf = NULL;
00342 #ifdef DEBUG
00343             printf("\r");
00344             if (!skip_rle_x) {
00345                 printf("Checking X scanline offsets....\n");
00346                 VPCheckScanOffsets(vpc->rle_x, vpc->rle_bytes_per_voxel);
00347             }
00348             if (!skip_rle_y) {
00349                 printf("Checking Y scanline offsets....\n");
00350                 VPCheckScanOffsets(vpc->rle_y, vpc->rle_bytes_per_voxel);
00351             }
00352             if (!skip_rle_z) {
00353                 printf("Checking Z scanline offsets....\n");
00354                 VPCheckScanOffsets(vpc->rle_z, vpc->rle_bytes_per_voxel);
00355             }
00356             VPValidateClassifiedVolume(vpc);
00357 #endif
00358         }
00359     }
00360 }
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 static void
00369 InitRLE(vpc)
00370 vpContext *vpc;
00371 {
00372     int f;
00373     int rle_bytes_per_voxel, size, offset;
00374     int maxsize = 0;
00375 
00376     
00377     rle_bytes_per_voxel = 0;
00378     for (f = 0; f < vpc->num_shade_fields; f++) {
00379         size = vpc->field_size[f];
00380         offset = vpc->field_offset[f] + size;
00381         if (offset > rle_bytes_per_voxel)
00382             rle_bytes_per_voxel = offset;
00383         if (size > maxsize)
00384             maxsize = size;
00385     }
00386 
00387     
00388 
00389 
00390 
00391     rle_bytes_per_voxel++;
00392     rle_bytes_per_voxel = (rle_bytes_per_voxel + maxsize-1) & ~(maxsize-1);
00393     vpc->rle_bytes_per_voxel = rle_bytes_per_voxel;
00394 
00395     
00396     vpc->cbuf = CreateConstructionBuffer(vpc);
00397 }
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 static void
00406 CacheVoxel(vpc, opacity, rawvoxel)
00407 vpContext *vpc;                 
00408 double opacity;                 
00409 void *rawvoxel;                 
00410 {
00411     ConstructionBuffer *cbuf;   
00412     GBuffer *data_buf;          
00413     void *data_ptr;             
00414     int rle_bytes_per_voxel;    
00415     int opc_int;                
00416 
00417     
00418     cbuf = vpc->cbuf;
00419     data_buf = cbuf->data_buf_tail;
00420     rle_bytes_per_voxel = vpc->rle_bytes_per_voxel;
00421 
00422     
00423     if (data_buf->bytes_left < rle_bytes_per_voxel) {
00424         
00425         data_buf->next = CreateGBuffer(vpc);
00426         data_buf = data_buf->next;
00427         cbuf->data_buf_tail = data_buf;
00428     }
00429     data_ptr = data_buf->data_ptr;
00430 
00431     
00432     bcopy(rawvoxel, data_ptr, rle_bytes_per_voxel-1);
00433 
00434     
00435     opc_int = opacity*255.;
00436     if (opc_int > 255)
00437         opc_int = 255;
00438     else if (opc_int < 0)
00439         opc_int = 0;
00440     ByteField(data_ptr, rle_bytes_per_voxel-1) = opc_int;
00441 
00442     data_buf->data_ptr += rle_bytes_per_voxel;
00443     data_buf->bytes_left -= rle_bytes_per_voxel;
00444 }
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 static void
00453 CacheLength(vpc, length)
00454 vpContext *vpc;
00455 int length;
00456 {
00457     GBuffer *lengths_buf;
00458 
00459     lengths_buf = vpc->cbuf->lengths_buf_tail;
00460     if (lengths_buf->bytes_left == 0) {
00461         
00462         lengths_buf->next = CreateGBuffer(vpc);
00463         lengths_buf = lengths_buf->next;
00464         vpc->cbuf->lengths_buf_tail = lengths_buf;
00465     }
00466     *(lengths_buf->data_ptr)++ = length;
00467     lengths_buf->bytes_left--;
00468 }
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 static void
00484 CountNonZeroVoxel(rundata, index, end_of_scan, vpc)
00485 RunData *rundata;       
00486 int index;              
00487 int end_of_scan;        
00488 
00489 vpContext *vpc;         
00490 {
00491     int run_length;
00492 
00493     if (rundata->next_index != index) {
00494         
00495 
00496 
00497         if (rundata->next_index != 0) {
00498             
00499             run_length = rundata->run_length;
00500             while (run_length > 255) {
00501                 
00502                 run_length -= 255;
00503                 rundata->p.p1.run_count += 2;
00504                 if (vpc != NULL) {
00505                     CacheLength(vpc, 255);
00506                     CacheLength(vpc, 0);
00507                 }
00508             }
00509             rundata->p.p1.run_count++;
00510             if (vpc != NULL)
00511                 CacheLength(vpc, run_length);
00512         }
00513 
00514         
00515         run_length = index - rundata->next_index;
00516         while (run_length > 255) {
00517             
00518             run_length -= 255;
00519             rundata->p.p1.run_count += 2;
00520             if (vpc != NULL) {
00521                 CacheLength(vpc, 255);
00522                 CacheLength(vpc, 0);
00523             }
00524         }
00525         rundata->p.p1.run_count++;
00526         if (vpc != NULL)
00527             CacheLength(vpc, run_length);
00528 
00529         if (end_of_scan) {
00530             
00531             rundata->p.p1.run_count++;
00532             if (vpc != NULL)
00533                 CacheLength(vpc, 0);
00534         } else {
00535             
00536             rundata->run_length = 1;
00537             rundata->next_index = index + 1;
00538         }
00539     } else if (!end_of_scan) {
00540         
00541         if (rundata->next_index == 0) {
00542             rundata->p.p1.run_count++;  
00543             if (vpc != NULL)
00544                 CacheLength(vpc, 0);
00545         }
00546         rundata->run_length++;
00547         rundata->next_index = index + 1;
00548     } else {
00549         
00550         run_length = rundata->run_length;
00551         while (run_length > 255) {
00552             
00553             run_length -= 255;
00554             rundata->p.p1.run_count += 2;
00555             if (vpc != NULL) {
00556                 CacheLength(vpc, 255);
00557                 CacheLength(vpc, 0);
00558             }
00559         }
00560         rundata->p.p1.run_count++;
00561         if (vpc != NULL)
00562             CacheLength(vpc, run_length);
00563     }
00564 }
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 static void
00575 RepackClassifiedVolume(vpc)
00576 vpContext *vpc;
00577 {
00578     int xlen, ylen, zlen;       
00579     int x, y, z;                
00580     int non_zero_count;         
00581     int rle_bytes_per_voxel;    
00582     int skip_rle_x;             
00583     int skip_rle_y;             
00584     int skip_rle_z;             
00585     char *x_data;               
00586     char *y_data;               
00587     char *z_data;               
00588     unsigned char *x_lengths;   
00589     unsigned char *y_lengths;   
00590     unsigned char *z_lengths;   
00591     int z_data_offset;          
00592     int z_length_offset;        
00593     GBuffer *data_buf;          
00594     char *data;                 
00595     int data_bytes_left;        
00596     GBuffer *lengths_buf;       
00597     unsigned char *lengths;     
00598     int lengths_bytes_left;     
00599     int x_run_length;           
00600     int is_non_zero;            
00601     RunData *rundata_y;         
00602     RunData *rundata_z;         
00603 
00604     
00605     xlen = vpc->xlen;
00606     ylen = vpc->ylen;
00607     zlen = vpc->zlen;
00608     non_zero_count = vpc->cbuf->non_zero_count;
00609     rle_bytes_per_voxel = vpc->rle_bytes_per_voxel;
00610     skip_rle_x = vpc->skip_rle_x;
00611     skip_rle_y = vpc->skip_rle_y;
00612     skip_rle_z = vpc->skip_rle_z;
00613 
00614     
00615     if (non_zero_count == 0) {
00616         if (!skip_rle_x)
00617             vpc->rle_x = CreateEmptyRLEVoxels(vpc, ylen, zlen, xlen);
00618         if (!skip_rle_y)
00619             vpc->rle_y = CreateEmptyRLEVoxels(vpc, zlen, xlen, ylen);
00620         if (!skip_rle_z)
00621             vpc->rle_z = CreateEmptyRLEVoxels(vpc, xlen, ylen, zlen);
00622         return;
00623     }
00624 
00625     
00626     if (!skip_rle_x) {
00627         vpc->rle_x = CreateRLEVoxelsFromRunData(vpc, ylen, zlen, xlen,
00628             non_zero_count, vpc->cbuf->rundata_y, rle_bytes_per_voxel);
00629         x_data = vpc->rle_x->data;
00630         x_lengths = vpc->rle_x->run_lengths;
00631     }
00632 
00633     
00634     if (!skip_rle_y) {
00635         vpc->rle_y = CreateRLEVoxelsFromRunData(vpc, zlen, xlen, ylen, 
00636             non_zero_count, vpc->cbuf->rundata_z, rle_bytes_per_voxel);
00637         y_data = vpc->rle_y->data;
00638         y_lengths = vpc->rle_y->run_lengths;
00639     }
00640 
00641     
00642     if (!skip_rle_z) {
00643         vpc->rle_z = VPCreateRLEVoxels(vpc, xlen, ylen, zlen, non_zero_count,
00644             vpc->cbuf->x_run_count, rle_bytes_per_voxel);
00645         Alloc(vpc, vpc->rle_z->scan_offsets, ScanOffset *,
00646               zlen*sizeof(ScanOffset), "scan_offsets");
00647         vpc->rle_z->scan_offsets_per_slice = 1;
00648         z_data = vpc->rle_z->data;
00649         z_lengths = vpc->rle_z->run_lengths;
00650         z_data_offset = 0;
00651         z_length_offset = 0;
00652     }
00653 
00654     
00655     data_buf = vpc->cbuf->data_buf_head;
00656     data = NULL;
00657     data_bytes_left = 0;
00658     lengths_buf = vpc->cbuf->lengths_buf_head;
00659     lengths = NULL;
00660     lengths_bytes_left = 0;
00661     x_run_length = 0;
00662     is_non_zero = 1;
00663     for (z = 0; z < zlen; z++) {
00664         ReportStatus(vpc, (double)z / (double)zlen);
00665         if (!skip_rle_z) {
00666             vpc->rle_z->scan_offsets[z].first_data = z_data_offset;
00667             vpc->rle_z->scan_offsets[z].first_len =
00668                 (z_length_offset & 0x1) ? z_length_offset + 1 :
00669                 z_length_offset;
00670         }
00671         rundata_z = vpc->cbuf->rundata_z;
00672         for (y = 0; y < ylen; y++) {
00673             rundata_y = &vpc->cbuf->rundata_y[z];
00674             for (x = 0; x < xlen; x++) {
00675                 while (x_run_length == 0) {
00676                     
00677                     if (lengths_bytes_left <= 0) {
00678                         
00679                         lengths = (unsigned char *)lengths_buf->data;
00680                         lengths_bytes_left = GBUFFER_SIZE -
00681                                              lengths_buf->bytes_left;
00682                         lengths_buf = lengths_buf->next;
00683                         if (!skip_rle_z) {
00684                             bcopy(lengths, z_lengths, lengths_bytes_left);
00685                             z_lengths += lengths_bytes_left;
00686                         }
00687                     }
00688                     x_run_length = *lengths++;
00689                     lengths_bytes_left--;
00690                     is_non_zero = !is_non_zero;
00691                     z_length_offset++;
00692                 }
00693                 x_run_length--; 
00694                 if (is_non_zero) {
00695                     
00696                     if (data_bytes_left <= 0) {
00697                         data = data_buf->data;
00698                         data_bytes_left = GBUFFER_SIZE - data_buf->bytes_left;
00699                         data_buf = data_buf->next;
00700                         if (!skip_rle_z) {
00701                             bcopy(data, z_data, data_bytes_left);
00702                             z_data = (char *)z_data + data_bytes_left;
00703                         }
00704                     }
00705 
00706                     
00707                     if (!skip_rle_x) {
00708                         StoreNonZeroVoxel(data, rle_bytes_per_voxel, x_data,
00709                                           x_lengths, rundata_y, y);
00710                     }
00711                     if (!skip_rle_y) {
00712                         StoreNonZeroVoxel(data, rle_bytes_per_voxel, y_data,
00713                                           y_lengths, rundata_z, z);
00714                     }
00715                     data += rle_bytes_per_voxel;
00716                     data_bytes_left -= rle_bytes_per_voxel;
00717                     z_data_offset += rle_bytes_per_voxel;
00718                 }
00719                 rundata_y += zlen;
00720                 rundata_z++;
00721             } 
00722         } 
00723     } 
00724     ReportStatus(vpc, 1.0);
00725 
00726     if (!skip_rle_x)
00727         PadScanlines(ylen, zlen, xlen, vpc->cbuf->rundata_y, x_lengths);
00728     if (!skip_rle_y)
00729         PadScanlines(zlen, xlen, ylen, vpc->cbuf->rundata_z, y_lengths);
00730 }
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 static RLEVoxels *
00739 CreateEmptyRLEVoxels(vpc, ilen, jlen, klen)
00740 vpContext *vpc;
00741 int ilen, jlen, klen;
00742 {
00743     RLEVoxels *rle_voxels;
00744     int j, k;
00745     unsigned char *run_lengths;
00746     ScanOffset *scan_offsets;
00747 
00748     rle_voxels = VPCreateRLEVoxels(vpc, ilen, jlen, klen, 1, 2*jlen*klen, 1);
00749     Alloc(vpc, rle_voxels->scan_offsets, ScanOffset *, klen*sizeof(ScanOffset),
00750           "scan_offsets");
00751     rle_voxels->scan_offsets_per_slice = 1;
00752     run_lengths = rle_voxels->run_lengths;
00753     scan_offsets = rle_voxels->scan_offsets;
00754     for (k = 0; k < klen; k++) {
00755         scan_offsets->first_len = k*jlen*2;
00756         scan_offsets->first_data = 0;
00757         scan_offsets++;
00758         for (j = 0; j < jlen; j++) {
00759             *run_lengths++ = ilen;
00760             *run_lengths++ = 0;
00761         }
00762     }
00763     return(rle_voxels);
00764 }
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 static RLEVoxels *
00776 CreateRLEVoxelsFromRunData(vpc, ilen, jlen, klen, non_zero_count, run_data,
00777                            rle_bytes_per_voxel)
00778 vpContext *vpc;         
00779 int ilen, jlen, klen;   
00780 int non_zero_count;     
00781 RunData *run_data;      
00782 int rle_bytes_per_voxel;
00783 {
00784     int j, k;                   
00785     int scan_run_count;         
00786     int run_count;              
00787     int scan_non_zero_count;    
00788     int data_offset;            
00789     int length_offset;          
00790 
00791     ScanOffset *slice_offset;   
00792     RLEVoxels *rle_voxels;      
00793 
00794     Alloc(vpc, slice_offset, ScanOffset *, klen*sizeof(ScanOffset),
00795           "scan_offsets");
00796 
00797     
00798 
00799 
00800     data_offset = 0;
00801     length_offset = 0;
00802     run_count = 0;
00803     for (k = 0; k < klen; k++) {
00804         slice_offset[k].first_data = data_offset;
00805         slice_offset[k].first_len = length_offset;
00806         for (j = 0; j < jlen; j++) {
00807             CountNonZeroVoxel(run_data, ilen, 1, NULL);
00808             scan_non_zero_count = run_data->p.p1.non_zero_count;
00809             scan_run_count = run_data->p.p1.run_count;
00810             run_data->run_length = 0;
00811             run_data->next_index = 0;
00812             run_data->p.p2.data_offset = data_offset;
00813             run_data->p.p2.length_offset = length_offset;
00814             data_offset += scan_non_zero_count * rle_bytes_per_voxel;
00815             length_offset += scan_run_count * sizeof(unsigned char);
00816             run_count += scan_run_count;
00817             run_data++;
00818         }
00819     }
00820 
00821     
00822     rle_voxels = VPCreateRLEVoxels(vpc, ilen, jlen, klen, non_zero_count,
00823                                    run_count, rle_bytes_per_voxel);
00824     rle_voxels->scan_offsets_per_slice = 1;
00825     rle_voxels->scan_offsets = slice_offset;
00826     return(rle_voxels);
00827 }
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 static void
00837 StoreNonZeroVoxel(voxel, rle_bytes_per_voxel, data, lengths, rundata, index)
00838 void *voxel;            
00839 int rle_bytes_per_voxel;
00840 void *data;             
00841 unsigned char *lengths; 
00842 RunData *rundata;       
00843 int index;              
00844 {
00845     int run_length;
00846 
00847     
00848     if (voxel != NULL) {
00849         bcopy(voxel, (char *)data + rundata->p.p2.data_offset,
00850               rle_bytes_per_voxel);
00851         rundata->p.p2.data_offset += rle_bytes_per_voxel;
00852     }
00853 
00854     
00855     if (rundata->next_index != index) {
00856         
00857 
00858 
00859         if (rundata->next_index != 0) {
00860             
00861             run_length = rundata->run_length;
00862             while (run_length > 255) {
00863                 
00864                 run_length -= 255;
00865                 lengths[rundata->p.p2.length_offset++] = 255;
00866                 lengths[rundata->p.p2.length_offset++] = 0;
00867             }
00868             lengths[rundata->p.p2.length_offset++] = run_length;
00869         }
00870 
00871         
00872         run_length = index - rundata->next_index;
00873         while (run_length > 255) {
00874             
00875             run_length -= 255;
00876             lengths[rundata->p.p2.length_offset++] = 255;
00877             lengths[rundata->p.p2.length_offset++] = 0;
00878         }
00879         lengths[rundata->p.p2.length_offset++] = run_length;
00880 
00881         if (voxel == NULL) {
00882             
00883             lengths[rundata->p.p2.length_offset++] = 0;
00884         } else {
00885             
00886             rundata->run_length = 1;
00887             rundata->next_index = index + 1;
00888         }
00889     } else if (voxel != NULL) {
00890         
00891         if (rundata->next_index == 0) {
00892             lengths[rundata->p.p2.length_offset++] = 0;
00893         }
00894         rundata->run_length++;
00895         rundata->next_index = index + 1;
00896     } else {
00897         
00898         run_length = rundata->run_length;
00899         while (run_length > 255) {
00900             
00901             run_length -= 255;
00902             lengths[rundata->p.p2.length_offset++] = 255;
00903             lengths[rundata->p.p2.length_offset++] = 0;
00904         }
00905         lengths[rundata->p.p2.length_offset++] = run_length;
00906     }
00907 }
00908 
00909 
00910 
00911 
00912 
00913 
00914 
00915 static void
00916 PadScanlines(ilen, jlen, klen, run_data, lengths)
00917 int ilen, jlen, klen;   
00918 RunData *run_data;      
00919 unsigned char *lengths; 
00920 {
00921     int scan_count;             
00922     int scan_run_count;         
00923     int scan;                   
00924 
00925     scan_count = jlen * klen;
00926     for (scan = 0; scan < scan_count; scan++) {
00927         StoreNonZeroVoxel(NULL, 0, NULL, lengths, run_data, ilen);
00928         run_data++;
00929     }
00930 }
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 RLEVoxels *
00940 VPCreateRLEVoxels(vpc, ilen, jlen, klen, data_count, run_count,
00941                   rle_bytes_per_voxel)
00942 vpContext *vpc;         
00943 int ilen, jlen, klen;   
00944 int data_count;         
00945 int run_count;          
00946 int rle_bytes_per_voxel;
00947 {
00948     RLEVoxels *rle_voxels;
00949 
00950     Alloc(vpc, rle_voxels, RLEVoxels *, sizeof(RLEVoxels), "RLEVoxels");
00951     rle_voxels->ilen = ilen;
00952     rle_voxels->jlen = jlen;
00953     rle_voxels->klen = klen;
00954     rle_voxels->run_count = run_count;
00955     if (run_count > 0) {
00956         Alloc(vpc, rle_voxels->run_lengths, unsigned char *, run_count,
00957               "run_lengths");
00958     } else {
00959         rle_voxels->run_lengths = NULL;
00960     }
00961     rle_voxels->data_count = data_count;
00962     if (data_count > 0) {
00963         Alloc(vpc, rle_voxels->data, void *, data_count * rle_bytes_per_voxel,
00964               "voxeldata");
00965     } else {
00966         rle_voxels->data = NULL;
00967     }
00968     rle_voxels->scan_offsets_per_slice = 0;
00969     rle_voxels->scan_offsets = NULL;
00970     rle_voxels->mmapped = 0;
00971 #ifdef INDEX_VOLUME
00972     rle_voxels->voxel_index = NULL;
00973 #endif
00974     return(rle_voxels);
00975 }
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 void
00984 VPDestroyRLEVoxels(vpc, rle_voxels)
00985 vpContext *vpc;
00986 RLEVoxels *rle_voxels;
00987 {
00988     if (!rle_voxels->mmapped) {
00989         if (rle_voxels->run_lengths != NULL)
00990             Dealloc(vpc, rle_voxels->run_lengths);
00991         if (rle_voxels->data != NULL)
00992             Dealloc(vpc, rle_voxels->data);
00993         if (rle_voxels->scan_offsets != NULL)
00994             Dealloc(vpc, rle_voxels->scan_offsets);
00995     }
00996 #ifdef INDEX_VOLUME
00997     if (rle_voxels->voxel_index != NULL)
00998         Dealloc(vpc, rle_voxels->voxel_index);
00999 #endif
01000     Dealloc(vpc, rle_voxels);
01001 }
01002 
01003 
01004 
01005 
01006 
01007 
01008 
01009 static ConstructionBuffer *
01010 CreateConstructionBuffer(vpc)
01011 vpContext *vpc;
01012 {
01013     ConstructionBuffer *cbuf;
01014     int xlen, ylen, zlen;
01015 
01016     xlen = vpc->xlen;
01017     ylen = vpc->ylen;
01018     zlen = vpc->zlen;
01019     Alloc(vpc, cbuf, ConstructionBuffer *, sizeof(ConstructionBuffer),
01020           "ConstructionBuffer");
01021     Alloc(vpc, cbuf->rundata_y, RunData *, xlen*zlen*sizeof(RunData),
01022           "rundata_y");
01023     Alloc(vpc, cbuf->rundata_z, RunData *, ylen*xlen*sizeof(RunData),
01024           "rundata_z");
01025     bzero(cbuf->rundata_y, xlen*zlen*sizeof(RunData));
01026     bzero(cbuf->rundata_z, ylen*xlen*sizeof(RunData));
01027     cbuf->data_buf_head = CreateGBuffer(vpc);
01028     cbuf->data_buf_tail = cbuf->data_buf_head;
01029     cbuf->lengths_buf_head = CreateGBuffer(vpc);
01030     cbuf->lengths_buf_tail = cbuf->lengths_buf_head;
01031     cbuf->non_zero_count = 0;
01032     cbuf->x_run_count = 0;
01033     cbuf->octree_scans_left = 0;
01034     cbuf->next_z = 0;
01035     cbuf->next_y = 0;
01036     return(cbuf);
01037 }
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 static void
01046 DestroyConstructionBuffer(vpc, cbuf)
01047 vpContext *vpc;
01048 ConstructionBuffer *cbuf;
01049 {
01050     GBuffer *gbuf, *next_gbuf;
01051 
01052     Dealloc(vpc, cbuf->rundata_y);
01053     Dealloc(vpc, cbuf->rundata_z);
01054     for (gbuf = cbuf->data_buf_head; gbuf != NULL; gbuf = next_gbuf) {
01055         next_gbuf = gbuf->next;
01056         DestroyGBuffer(vpc, gbuf);
01057     }
01058     for (gbuf = cbuf->lengths_buf_head; gbuf != NULL; gbuf = next_gbuf) {
01059         next_gbuf = gbuf->next;
01060         DestroyGBuffer(vpc, gbuf);
01061     }
01062     Dealloc(vpc, cbuf);
01063 }
01064 
01065 
01066 
01067 
01068 
01069 
01070 
01071 static GBuffer *
01072 CreateGBuffer(vpc)
01073 vpContext *vpc;
01074 {
01075     GBuffer *gbuf;
01076 
01077     Alloc(vpc, gbuf, GBuffer *, sizeof(GBuffer), "GBuffer");
01078     gbuf->bytes_left = GBUFFER_SIZE;
01079     gbuf->data_ptr = gbuf->data;
01080     gbuf->next = NULL;
01081     return(gbuf);
01082 }
01083 
01084 
01085 
01086 
01087 
01088 
01089 
01090 static void
01091 DestroyGBuffer(vpc, gbuf)
01092 vpContext *vpc;
01093 GBuffer *gbuf;
01094 {
01095     Dealloc(vpc, gbuf);
01096 }
01097 
01098 
01099 
01100 
01101 
01102 
01103 
01104 vpResult
01105 vpDestroyClassifiedVolume(vpc)
01106 vpContext *vpc;
01107 {
01108     if (vpc->cbuf != NULL) {
01109         DestroyConstructionBuffer(vpc, vpc->cbuf);
01110         vpc->cbuf = NULL;
01111     }
01112     if (vpc->rle_x != NULL) {
01113         VPDestroyRLEVoxels(vpc, vpc->rle_x);
01114         vpc->rle_x = NULL;
01115     }
01116     if (vpc->rle_y != NULL) {
01117         VPDestroyRLEVoxels(vpc, vpc->rle_y);
01118         vpc->rle_y = NULL;
01119     }
01120     if (vpc->rle_z != NULL) {
01121         VPDestroyRLEVoxels(vpc, vpc->rle_z);
01122         vpc->rle_z = NULL;
01123     }
01124     return(VP_OK);
01125 }
01126 
01127 #ifdef INDEX_VOLUME
01128 
01129 
01130 
01131 
01132 
01133 
01134 vpResult
01135 vpComputeRLEIndex(vpc)
01136 vpContext *vpc;
01137 {
01138     vpResult result;
01139 
01140     if ((result = VPComputeRLEScanOffsets(vpc)) != VP_OK)
01141         return(result);
01142     if (vpc->rle_x != NULL) {
01143         if ((result = ComputeIndex(vpc, vpc->rle_x)) != VP_OK)
01144             return(result);
01145     }
01146     if (vpc->rle_y != NULL) {
01147         if ((result = ComputeIndex(vpc, vpc->rle_y)) != VP_OK)
01148             return(result);
01149     }
01150     if (vpc->rle_z != NULL) {
01151         if ((result = ComputeIndex(vpc, vpc->rle_z)) != VP_OK)
01152             return(result);
01153     }
01154     return(VP_OK);
01155 }
01156 
01157 
01158 
01159 
01160 
01161 
01162 
01163 
01164 
01165 
01166 
01167 static vpResult
01168 ComputeIndex(vpc, rle_voxels)
01169 vpContext *vpc;
01170 RLEVoxels *rle_voxels;
01171 {
01172     int ilen, jlen, klen;       
01173     unsigned char *RLElen;      
01174     VoxelLocation *index;       
01175     int i, j, k;                
01176     unsigned len_offset;        
01177 
01178     unsigned data_offset;       
01179 
01180     int run_is_zero;            
01181     int run_count;              
01182     int voxel_size;             
01183 
01184     ilen = rle_voxels->ilen;
01185     jlen = rle_voxels->jlen;
01186     klen = rle_voxels->klen;
01187     RLElen = rle_voxels->run_lengths;
01188     if (rle_voxels->scan_offsets_per_slice != jlen)
01189         return(VPERROR_BAD_VOLUME);
01190     if (rle_voxels->voxel_index == NULL) {
01191         Alloc(vpc, rle_voxels->voxel_index, VoxelLocation *,
01192               ilen * jlen * klen * sizeof(VoxelLocation), "voxel_index");
01193     }
01194     index = rle_voxels->voxel_index;
01195     voxel_size = vpc->rle_bytes_per_voxel;
01196     run_is_zero = 0;
01197     run_count = 0;
01198     for (k = 0; k < klen; k++) {
01199         for (j = 0; j < jlen; j++) {
01200             ASSERT(run_is_zero == 0);
01201             ASSERT(run_count == 0);
01202             len_offset = 0;
01203             data_offset = 0;
01204             for (i = 0; i < ilen; i++) {
01205                 
01206                 if (len_offset > 256) {
01207                     Dealloc(vpc, rle_voxels->voxel_index);
01208                     rle_voxels->voxel_index = NULL;
01209                     return(VPERROR_LIMIT_EXCEEDED);
01210                 }
01211                 index->run_count = run_count;
01212                 index->len_offset = len_offset;
01213                 if (run_is_zero)
01214                     index->data_offset = data_offset | INDEX_RUN_IS_ZERO;
01215                 else
01216                     index->data_offset = data_offset;
01217                 index++;
01218 
01219                 
01220                 while (run_count == 0) {
01221                     run_count = *RLElen++;
01222                     run_is_zero = !run_is_zero;
01223                     len_offset++;
01224                 }
01225                 run_count--;
01226                 if (!run_is_zero)
01227                     data_offset += voxel_size;
01228             }
01229             ASSERT(run_count == 0);
01230             if (run_is_zero) {
01231                 run_count = *RLElen++;
01232                 run_is_zero = !run_is_zero;
01233                 len_offset++;
01234             }
01235         }
01236     }
01237     return(VP_OK);
01238 }
01239 #endif 
01240 
01241 
01242 
01243 
01244 
01245 
01246 
01247 
01248 vpResult
01249 VPComputeRLEScanOffsets(vpc)
01250 vpContext *vpc;
01251 {
01252     vpResult result;
01253 
01254     if (vpc->rle_x != NULL) {
01255         if ((result = ComputeScanOffsets(vpc, vpc->rle_x)) != VP_OK)
01256             return(result);
01257 #ifdef DEBUG
01258         VPCheckScanOffsets(vpc->rle_x, vpc->rle_bytes_per_voxel);
01259 #endif
01260     }
01261 
01262     if (vpc->rle_y != NULL) {
01263         if ((result = ComputeScanOffsets(vpc, vpc->rle_y)) != VP_OK)
01264             return(result);
01265 #ifdef DEBUG
01266         VPCheckScanOffsets(vpc->rle_y, vpc->rle_bytes_per_voxel);
01267 #endif
01268     }
01269 
01270     if (vpc->rle_z != NULL) {
01271         if ((result = ComputeScanOffsets(vpc, vpc->rle_z)) != VP_OK)
01272             return(result);
01273 #ifdef DEBUG
01274         VPCheckScanOffsets(vpc->rle_z, vpc->rle_bytes_per_voxel);
01275 #endif
01276     }
01277     return(VP_OK);
01278 }
01279 
01280 
01281 
01282 
01283 
01284 
01285 
01286 
01287 static vpResult
01288 ComputeScanOffsets(vpc, rle_voxels)
01289 vpContext *vpc;
01290 RLEVoxels *rle_voxels;
01291 {
01292     int ilen, jlen, klen;       
01293     unsigned char *RLElen;      
01294     ScanOffset *scan_offset;    
01295     int i, j, k;                
01296     unsigned len_offset;        
01297 
01298     unsigned data_offset;       
01299 
01300     int voxel_size;             
01301     int zerocount, nonzerocount;
01302 
01303     if (rle_voxels->mmapped)
01304         return(VPERROR_IO);
01305     ilen = rle_voxels->ilen;
01306     jlen = rle_voxels->jlen;
01307     klen = rle_voxels->klen;
01308     RLElen = rle_voxels->run_lengths;
01309     if (rle_voxels->scan_offsets_per_slice != jlen) {
01310         if (rle_voxels->scan_offsets != NULL)
01311             Dealloc(vpc, rle_voxels->scan_offsets);
01312         Alloc(vpc, rle_voxels->scan_offsets, ScanOffset *,
01313               klen * jlen * sizeof(ScanOffset), "scan_offsets");
01314         rle_voxels->scan_offsets_per_slice = jlen;
01315     }
01316     scan_offset = rle_voxels->scan_offsets;
01317     len_offset = 0;
01318     data_offset = 0;
01319     voxel_size = vpc->rle_bytes_per_voxel;
01320 
01321     for (k = 0; k < klen; k++) {
01322         for (j = 0; j < jlen; j++) {
01323             scan_offset->first_len = len_offset;
01324             scan_offset->first_data = data_offset;
01325             scan_offset++;
01326             for (i = 0; i < ilen; ) {
01327                 zerocount = *RLElen++;   
01328                 nonzerocount = *RLElen++;
01329                 len_offset += 2;
01330                 data_offset += nonzerocount * voxel_size;
01331                 i += zerocount + nonzerocount;
01332             }
01333             ASSERT(i == ilen);
01334         }
01335     }
01336     return(VP_OK);
01337 }
01338 
01339 #ifdef DEBUG
01340 
01341 
01342 
01343 
01344 
01345 
01346 void
01347 VPCheckScanOffsets(rle_voxels, rle_bytes_per_voxel)
01348 RLEVoxels *rle_voxels;
01349 {
01350     int i, j, k;
01351     int ilen, jlen, klen;
01352     int run_length;
01353     int is_non_zero;
01354     unsigned char *run_length_ptr;
01355     int length_offset;
01356     int data_offset;
01357     int scan_offsets_per_slice;
01358     ScanOffset *scan_offset;
01359 
01360     scan_offsets_per_slice = rle_voxels->scan_offsets_per_slice;
01361     if (scan_offsets_per_slice == 0)
01362         return;
01363     ilen = rle_voxels->ilen;
01364     jlen = rle_voxels->jlen;
01365     klen = rle_voxels->klen;
01366     run_length_ptr = rle_voxels->run_lengths;
01367     run_length = 0;
01368     is_non_zero = 1;
01369     length_offset = 0;
01370     data_offset = 0;
01371     for (k = 0; k < klen; k++) {
01372         for (j = 0; j < jlen; j++) {
01373             if (j < scan_offsets_per_slice) {
01374                 scan_offset = &rle_voxels->scan_offsets[
01375                                k*scan_offsets_per_slice + j];
01376                 if (scan_offset->first_len != length_offset) {
01377                     printf("Bad length offset on slice %d, scanline %d: ",k,j);
01378                     printf("%d should be %d\n", scan_offset->first_len,
01379                            length_offset);
01380                 }
01381                 if (scan_offset->first_data != data_offset) {
01382                     printf("Bad data offset on slice %d, scanline %d: ",k,j);
01383                     printf("%d should be %d\n", scan_offset->first_data,
01384                            data_offset);
01385                 }
01386             }
01387             for (i = 0; i < ilen; i++) {
01388                 while (run_length == 0) {
01389                     run_length = *run_length_ptr++;
01390                     is_non_zero = !is_non_zero;
01391                     length_offset++;
01392                 }
01393                 run_length--;
01394                 if (is_non_zero)
01395                     data_offset += rle_bytes_per_voxel;
01396             }
01397             if (run_length != 0) {
01398                 printf("Run did not terminate at end of scanline ");
01399                 printf("on slice %d, scanline %d\n", k, j);
01400             }
01401             if (!is_non_zero) {
01402                 if (*run_length_ptr++ != 0) {
01403                     printf("Missing zero run at end of scanline ");
01404                     printf("on slice %d, scanline %d\n", k, j);
01405                 }
01406                 is_non_zero = !is_non_zero;
01407                 length_offset++;
01408             }
01409         }
01410     }
01411 }
01412 
01413 
01414 
01415 
01416 
01417 
01418 
01419 void
01420 VPValidateClassifiedVolume(vpc)
01421 vpContext *vpc;
01422 {
01423     if (vpc->raw_voxels == NULL)
01424         return;
01425     if (vpc->rle_z != NULL) {
01426         printf("Checking Z view....\n");
01427         ValidateRLEVoxels(vpc, vpc->rle_z, vpc->xstride, vpc->ystride,
01428                           vpc->zstride, VP_Z_AXIS);
01429     }
01430     if (vpc->rle_y != NULL) {
01431         printf("Checking Y view....\n");
01432         ValidateRLEVoxels(vpc, vpc->rle_y, vpc->zstride, vpc->xstride,
01433                           vpc->ystride, VP_Y_AXIS);
01434     }
01435     if (vpc->rle_x != NULL) {
01436         printf("Checking X view....\n");
01437         ValidateRLEVoxels(vpc, vpc->rle_x, vpc->ystride, vpc->zstride,
01438                           vpc->xstride, VP_X_AXIS);
01439     }
01440 }
01441 
01442 static void
01443 ValidateRLEVoxels(vpc, rle, istride, jstride, kstride, axis)
01444 vpContext *vpc;
01445 RLEVoxels *rle;
01446 int istride, jstride, kstride;
01447 int axis;
01448 {
01449     char *rawvoxel;
01450     char *rlevoxel;
01451     unsigned char *lengths;
01452     int i, j, k;
01453     int count;
01454     int is_non_zero;
01455     int num_runs;
01456     float opacity;
01457     int ilen, jlen, klen;
01458     int founderror;
01459     int raw_opc_int;
01460     int rle_opc_int;
01461     int rle_bytes_per_voxel;
01462 
01463     rawvoxel = (char *)vpc->raw_voxels;
01464     rlevoxel = (char *)rle->data;
01465     lengths = rle->run_lengths;
01466     ilen = rle->ilen;
01467     jlen = rle->jlen;
01468     klen = rle->klen;
01469     rle_bytes_per_voxel = vpc->rle_bytes_per_voxel;
01470     founderror = 0;
01471     for (k = 0; k < klen; k++) {
01472         for (j = 0; j < jlen; j++) {
01473             count = 0;
01474             is_non_zero = 1;
01475             num_runs = 0;
01476             for (i = 0; i < ilen; i++) {
01477                 while (count == 0) {
01478                     count = *lengths++;
01479                     is_non_zero = !is_non_zero;
01480                     if (++num_runs > rle->ilen)
01481                         VPBug("runaway scan detected by ValidateRLEVoxels");
01482                 }
01483                 opacity = VPClassifyVoxel(vpc, rawvoxel);
01484                 if (is_non_zero) {
01485                     if (opacity <= vpc->min_opacity &&
01486                         fabs(opacity - vpc->min_opacity) > 0.001) {
01487                         printf("\n");
01488                         printf("**** zero rawvoxel in nonzero rlerun ****\n");
01489                         printf("voxel (i,j,k)=(%d,%d,%d), viewaxis %d\n",
01490                                i, j, k, axis);
01491                         printf("Actual opacity: %17.15f\n", opacity);
01492                         printf("Threshold:      %17.15f\n", vpc->min_opacity);
01493                         founderror = 1;
01494                     }
01495                     raw_opc_int = (int)rint(opacity*255.);
01496                     rle_opc_int = ByteField(rlevoxel, rle_bytes_per_voxel-1);
01497                     if (abs(raw_opc_int - rle_opc_int) > 1) {
01498                         printf("\n");
01499                         printf("**** rawvoxel and rlevoxel disagree ****\n");
01500                         printf("voxel (i,j,k)=(%d,%d,%d), viewaxis %d\n",
01501                                i, j, k, axis);
01502                         printf("Raw opacity: %3d\n", raw_opc_int);
01503                         printf("RLE opacity: %3d\n", rle_opc_int);
01504                         founderror = 1;
01505                     }
01506                     rlevoxel += rle_bytes_per_voxel;
01507                 } else {
01508                     if (opacity > vpc->min_opacity &&
01509                         fabs(opacity - vpc->min_opacity) > 0.001) {
01510                         printf("\n");
01511                         printf("**** nonzero rawvoxel in zero rlerun ****\n");
01512                         printf("voxel (i,j,k)=(%d,%d,%d), viewaxis %d\n",
01513                                i, j, k, axis);
01514                         printf("Actual opacity: %17.15f\n", opacity);
01515                         printf("Threshold:      %17.15f\n", vpc->min_opacity);
01516                         founderror = 1;
01517                     }
01518                 }
01519                 if (founderror) {
01520                     VPDumpClassifier(vpc);
01521                     VPBug("ValidateRLEVoxels found a problem");
01522                 }
01523                 rawvoxel += istride;
01524                 count--;
01525             }
01526             if (count != 0)
01527                 VPBug("Run did not terminate at end of scanline");
01528             if (!is_non_zero) {
01529                 if (*lengths++ != 0)
01530                     VPBug("Missing zero run at end of scanline");
01531                 is_non_zero = !is_non_zero;
01532             }
01533             rawvoxel += jstride - ilen*istride;
01534         }
01535         rawvoxel += kstride - jlen*jstride;
01536     }
01537 }
01538 #endif
01539 
01540 void
01541 VPDumpView(vpc)
01542 vpContext *vpc;
01543 {
01544     int c;
01545 
01546     printf("MODEL:\n");
01547     for (c = 0; c < 4; c++) {
01548         printf("    %12.6f %12.6f %12.6f %12.6f\n",
01549                vpc->transforms[VP_MODEL][c][0],
01550                vpc->transforms[VP_MODEL][c][1],
01551                vpc->transforms[VP_MODEL][c][2],
01552                vpc->transforms[VP_MODEL][c][3]);
01553     }
01554     printf("VIEW:\n");
01555     for (c = 0; c < 4; c++) {
01556         printf("    %12.6f %12.6f %12.6f %12.6f\n",
01557                vpc->transforms[VP_MODEL][c][0],
01558                vpc->transforms[VP_MODEL][c][1],
01559                vpc->transforms[VP_MODEL][c][2],
01560                vpc->transforms[VP_MODEL][c][3]);
01561     }
01562     printf("PROJECT:\n");
01563     for (c = 0; c < 4; c++) {
01564         printf("    %12.6f %12.6f %12.6f %12.6f\n",
01565                vpc->transforms[VP_MODEL][c][0],
01566                vpc->transforms[VP_MODEL][c][1],
01567                vpc->transforms[VP_MODEL][c][2],
01568                vpc->transforms[VP_MODEL][c][3]);
01569     }
01570 }
01571 
01572 void
01573 VPDumpClassifier(vpc)
01574 vpContext *vpc;
01575 {
01576     int c, d;
01577 
01578     for (d = 0; d < vpc->num_clsfy_params; d++) {
01579         printf("CLASSIFIER PARAM %d:\n   ", d);
01580         for (c = 0; c < vpc->field_max[vpc->param_field[d]]; c++) {
01581             printf(" %8.6f", vpc->clsfy_table[d][c]);
01582             if (c % 8 == 7)
01583                 printf("\n   ");
01584         }
01585         printf("\n");
01586     }
01587 }