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 
00032 
00033 
00034 
00035 #include "config.h"
00036 #include "volpack.h"
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>   
00040 #include <math.h>
00041 extern double rint ANSI_ARGS((double x)); 
00042 
00043 #ifdef ANSI_C
00044 #include <stdarg.h>
00045 #else
00046 #include <varargs.h>
00047 #endif
00048 
00049 #if STDC_HEADERS || HAVE_STRING_H
00050 #include <string.h>
00051 
00052 #if !STDC_HEADERS && HAVE_MEMORY_H
00053 #include <memory.h>
00054 #endif 
00055 #define index strchr
00056 #define rindex strrchr
00057 #define bcopy(s, d, n) memcpy ((d), (s), (n))
00058 #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
00059 #define bzero(s, n) memset ((s), 0, (n))
00060 #else 
00061 #include <strings.h>
00062 
00063 #endif 
00064 
00065 #ifdef HAVE_LORES_TIMER
00066 
00067 #   define USE_TIMER
00068 #   include <sys/time.h>
00069 #   define DECLARE_TIME(t)      struct timeval t
00070 #   define GET_TIME(vpc, t)     gettimeofday(&t)
00071 #   define STORE_TIME(vpc, code, t0, t1)        \
00072     vpc->timer_ticks[code] += ((t1).tv_usec < (t0).tv_usec) ? \
00073         (((t1).tv_sec - (t0).tv_sec)*1000000 - ((t0).tv_usec - (t1).tv_usec)):\
00074         (((t1).tv_sec - (t0).tv_sec)*1000000 + ((t1).tv_usec - (t0).tv_usec));
00075 #endif
00076 
00077 #ifdef HAVE_HIRES_TIMER
00078 
00079 
00080 #   define USE_TIMER
00081 #   include <fcntl.h>
00082 #   include <sys/mman.h>
00083 #   include <sys/syssgi.h>
00084 #   include <sys/immu.h>
00085 #   define DECLARE_TIME(t)      unsigned t
00086 #   define GET_TIME(vpc, t)     t = *vpc->timer_addr
00087 #   define STORE_TIME(vpc, code, t0, t1)        \
00088     vpc->timer_ticks[code] += ((t1) < (t0)) ? \
00089         ((0xFFFFFFFF - (t0)) + (t1)) : ((t1) - (t0));
00090 #   define DECLARE_HIRES_TIME(t)        DECLARE_TIME(t)
00091 #   define GET_HIRES_TIME(vpc, t)       GET_TIME(vpc, t)
00092 #   define STORE_HIRES_TIME(vpc, code, t0, t1)  STORE_TIME(vpc, code, t0, t1)
00093 #   define COPY_HIRES_TIME(t0, t1)      t0 = t1
00094 #else
00095 #   define DECLARE_HIRES_TIME(t)
00096 #   define GET_HIRES_TIME(vpc, t)
00097 #   define STORE_HIRES_TIME(vpc, code, t0, t1)
00098 #   define COPY_HIRES_TIME(t0, t1)
00099 #endif
00100 
00101 #ifndef USE_TIMER
00102 #   define DECLARE_TIME(t)
00103 #   define GET_TIME(vpc, t)
00104 #   define STORE_TIME(vpc, code, t0, t1)
00105 #endif
00106 
00107 
00108 
00109 
00110 
00111 
00112 #define USE_RLEVOLUME   10      
00113 #define USE_RAWVOLUME   11      
00114 
00115 
00116 #define CALLBACK_SHADER 20
00117 #define LOOKUP_SHADER   21
00118 
00119 
00120 #define EXT_SURFACE     0
00121 #define INT_SURFACE     1
00122 
00123 
00124 #define MATL_AMB_R      0               
00125 #define MATL_DIFF_R     1               
00126 #define MATL_SPEC_R     2               
00127 #define MATL_AMB_G      3               
00128 #define MATL_DIFF_G     4               
00129 #define MATL_SPEC_G     5               
00130 #define MATL_AMB_B      6               
00131 #define MATL_DIFF_B     7               
00132 #define MATL_SPEC_B     8               
00133 #define MATL_SHINY      9               
00134 #define NUM_MATL_PROPS  10
00135 
00136 
00137 #define DEFAULT_AMBIENT         (0.1*255.0)
00138 #define DEFAULT_DIFFUSE         (0.4*255.0)
00139 #define DEFAULT_SPECULAR        (0.5*255.0)
00140 #define DEFAULT_SHINYNESS       10.0
00141 
00142 
00143 #define DEFAULT_DC_QUANTIZATION (1./255.) 
00144 
00145 
00146 #define WARP_WEIGHT_INDEX_BITS  6
00147 #define WARP_WEIGHT_ENTRIES     (1 << WARP_WEIGHT_INDEX_BITS)
00148 
00149 
00150 #define VP_MAX_OCTREE_LEVELS    16      
00151 
00152 
00153 
00154 
00155 #define MM_K_BIT        4               
00156 #define MM_J_BIT        2               
00157 #define MM_I_BIT        1
00158 
00159 #define MM_EMPTY        0               
00160 #define MM_FULL         1               
00161 #define MM_PARTFULL     2               
00162 
00163 
00164 #define INDEX_RUN_IS_ZERO 0x7000        
00165 
00166 
00167 
00168 
00169 
00170 
00171 #ifndef NULL           
00172 #define NULL 0
00173 #endif
00174 
00175 #define MAX(a,b)        (((a)<(b)) ? (b) : (a))
00176 #define MIN(a,b)        (((a)>(b)) ? (b) : (a))
00177 
00178 
00179 #define Alloc(context, ptr, type, size, use)                            \
00180 {                                                                       \
00181     (ptr) = (type)malloc((unsigned)(size));                             \
00182     if ((ptr) == NULL)                                                  \
00183         VPBug("out of memory");                                         \
00184     if ((context)->log_alloc_func != NULL)                              \
00185         (context)->log_alloc_func((ptr),(size),(use),                   \
00186                    __LINE__,__FILE__,(context)->client_data);           \
00187 }
00188 
00189 
00190 #define Dealloc(context, ptr)                                           \
00191 {                                                                       \
00192     if ((context)->log_free_func != NULL)                               \
00193         (context)->log_free_func(ptr, (context)->client_data);          \
00194     free((void *)ptr);                                                  \
00195 }
00196 
00197 
00198 #ifdef DEBUG
00199 #define Debug(x)        VPDebug x
00200 #else
00201 #define Debug(x)
00202 #endif
00203 
00204 
00205 #ifdef ASSERTIONS
00206 #define ASSERT(expr)                                                    \
00207     if (!(expr))                                                        \
00208         VPBug("assertion failed on line %d of file %s",                 \
00209               __LINE__, __FILE__)
00210 #else
00211 #define ASSERT(expr)
00212 #endif
00213 
00214 
00215 #define ReportStatus(context, frac)                                     \
00216     if ((context)->status_func != NULL)                                 \
00217         (context)->status_func(frac, (context)->client_data)
00218 
00219 
00220 #define ByteField(voxel, offset)   (*((unsigned char *)(voxel) + (offset)))
00221 #define ShortField(voxel, offset)  (*((unsigned short *)((char *)(voxel)+\
00222                                       (offset))))
00223 #define IntField(voxel, offset)    (*((unsigned *)((char *)(voxel)+(offset))))
00224 #define VoxelField(voxel, offset, size)                         \
00225     (((size) == 1) ? ByteField(voxel, offset) :                 \
00226      ((size) == 2) ? ShortField(voxel, offset) :                \
00227                      IntField(voxel, offset))
00228 
00229 
00230 
00231 
00232 
00233 
00234 typedef struct {                
00235     int first_len;              
00236     int first_data;             
00237 } ScanOffset;
00238 
00239 #ifdef INDEX_VOLUME
00240 
00241 
00242 typedef struct {                
00243     unsigned char run_count;    
00244 
00245 
00246 
00247     unsigned char len_offset;   
00248 
00249     short data_offset;          
00250 
00251 
00252 } VoxelLocation;
00253 #endif 
00254 
00255 
00256 
00257 typedef struct {                
00258     int ilen, jlen, klen;       
00259     int run_count;              
00260     unsigned char *run_lengths; 
00261     int data_count;             
00262     void *data;                 
00263     int scan_offsets_per_slice; 
00264 
00265     ScanOffset *scan_offsets;   
00266     int mmapped;                
00267 
00268 #ifdef INDEX_VOLUME
00269     VoxelLocation *voxel_index; 
00270 #endif
00271 } RLEVoxels;
00272 
00273 
00274 typedef struct {                
00275     short run_length;           
00276     short next_index;           
00277     union {
00278         struct {                
00279             short run_count;    
00280             short non_zero_count; 
00281 
00282         } p1;
00283         struct {                
00284             unsigned data_offset; 
00285             unsigned length_offset; 
00286         } p2;
00287     } p;
00288 } RunData;
00289 
00290 
00291 #define GBUFFER_SIZE    1024    
00292 
00293 
00294 
00295 
00296 typedef struct _gbuffer {       
00297     int bytes_left;             
00298     char *data_ptr;             
00299     struct _gbuffer *next;      
00300     char data[GBUFFER_SIZE];    
00301 } GBuffer;
00302 
00303 
00304 
00305 typedef struct {                
00306     RunData *rundata_y;         
00307 
00308     RunData *rundata_z;         
00309 
00310     GBuffer *data_buf_head;     
00311     GBuffer *data_buf_tail;     
00312     GBuffer *lengths_buf_head;  
00313     GBuffer *lengths_buf_tail;  
00314     int non_zero_count;         
00315     int x_run_count;            
00316     unsigned char octree_runs[VP_MAX_VOLUME_DIM];
00317                                 
00318     int octree_scans_left;      
00319 
00320     int next_z;                 
00321     int next_y;                 
00322 } ConstructionBuffer;
00323 
00324 
00325 
00326 typedef struct {                
00327     int levels;                 
00328 
00329 
00330     int root_node_size;         
00331     int base_node_size;         
00332     int range_bytes_per_node;   
00333     int base_bytes_per_node;    
00334 
00335     int nonbase_bytes_per_node; 
00336 
00337     int node_offset[VP_MAX_FIELDS]; 
00338 
00339     int status_offset;          
00340     int child_offset;           
00341     void *root;                 
00342 
00343     int octree_bytes;           
00344 
00345     
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 } MinMaxOctree;
00392 
00393 
00394 
00395 
00396 typedef struct {                
00397     int level_size;             
00398     int child_octant;           
00399 
00400 
00401     int child_offset1;          
00402 
00403     int child_offset2;          
00404 
00405     void *child2;               
00406 
00407 } MMOctreeLevel;
00408 
00409 
00410 typedef struct {                
00411     float clrflt;               
00412     float opcflt;               
00413     short lnk;                  
00414     unsigned char zratio;       
00415 
00416     unsigned char zfrac;        
00417 
00418 } GrayIntPixel;
00419 
00420 
00421 typedef struct {                
00422     float rclrflt;              
00423     float gclrflt;              
00424     float bclrflt;              
00425     float opcflt;               
00426     short lnk;                  
00427     unsigned char zratio;       
00428 
00429     unsigned char zfrac;        
00430 
00431 } RGBIntPixel;
00432 
00433 
00434 
00435 typedef struct {
00436     
00437     int miny;           
00438 
00439     int maxy;           
00440 
00441     double x_top_lft;   
00442     double x_top_rgt;   
00443     double x_incr_lft;  
00444 
00445     double x_incr_rgt;  
00446 
00447 } Trapezoid;
00448 
00449 
00450 struct _vp_context {                    
00451 
00452     
00453 
00454     
00455     int xlen, ylen, zlen;               
00456     short raw_bytes_per_voxel;          
00457     short num_voxel_fields;             
00458     short num_shade_fields;             
00459     short field_size[VP_MAX_FIELDS];    
00460     short field_offset[VP_MAX_FIELDS];  
00461     int field_max[VP_MAX_FIELDS];       
00462     void *raw_voxels;                   
00463     int raw_voxels_size;                
00464     int xstride, ystride, zstride;      
00465 
00466     
00467     double min_opacity;                 
00468     int num_clsfy_params;               
00469     int param_field[VP_MAX_FIELDS];     
00470     float *clsfy_table[VP_MAX_FIELDS];  
00471     int clsfy_table_size[VP_MAX_FIELDS]; 
00472 
00473     
00474     int color_channels;                 
00475     int shading_mode;                   
00476     float *shade_color_table;           
00477     int shade_color_table_size;         
00478     float *shade_weight_table;          
00479     int shade_weight_table_size;        
00480     short num_materials;                
00481     short color_field;                  
00482     short weight_field;                 
00483 
00484     
00485     double matl_props[VP_MAX_MATERIAL][2][NUM_MATL_PROPS]; 
00486 
00487     
00488     short light_enable[VP_MAX_LIGHTS];  
00489     vpVector4 light_vector[VP_MAX_LIGHTS]; 
00490 
00491     vpVector3 light_color[VP_MAX_LIGHTS];  
00492     int light_both_sides;               
00493     int reverse_surface_sides;          
00494 
00495     
00496     short dc_enable;                    
00497     double dc_front_factor;             
00498     double dc_density;                  
00499     int dc_table_len_hint;              
00500     double dc_quantization;             
00501 
00502     
00503     vpMatrix4 transforms[3];            
00504 
00505     short current_matrix;               
00506     int concat_left;                    
00507 
00508     int axis_override;                  
00509 
00510 
00511 
00512 
00513     
00514     void *image;                        
00515     int image_width;                    
00516     int image_height;
00517     short image_bytes_per_scan;         
00518     int pixel_type;                     
00519 
00520     
00521     double max_opacity;                 
00522     short int_image_width_hint;         
00523     short int_image_height_hint;
00524     short clamp_shade_table;            
00525 
00526     
00527     int param_maxrange[VP_MAX_FIELDS];  
00528 
00529 
00530     
00531     short rle_bytes_per_voxel;          
00532     int skip_rle_x;                     
00533     int skip_rle_y;                     
00534     int skip_rle_z;                     
00535 
00536     
00537     short enable_shadows;               
00538     short shadow_light_num;             
00539 
00540     short shadow_width_hint;            
00541     short shadow_height_hint;           
00542     float *shadow_color_table;          
00543     int shadow_color_table_size;        
00544     int shadow_bias;                    
00545 
00546     
00547 
00548     
00549 
00550 
00551     int end_of_parameters;
00552 
00553     
00554     void (*shade_func)();               
00555     int (*write_func) ANSI_ARGS((int, void *, unsigned)); 
00556     int (*read_func) ANSI_ARGS((int, void *, unsigned));  
00557     void *(*mmap_func) ANSI_ARGS((int, unsigned, void *));
00558     void (*log_alloc_func) ANSI_ARGS((void *,int,char *,int,char *,void *));
00559                                         
00560     void (*log_free_func) ANSI_ARGS((void *, void *));
00561                                         
00562     void (*status_func) ANSI_ARGS((double, void *)); 
00563 
00564     
00565     void *client_data;                  
00566 
00567     
00568     int filter_num_taps;                
00569     int filter_num_phases;              
00570     float *filter_weights;              
00571 
00572 
00573     
00574 
00575     
00576     MinMaxOctree *mm_octree;            
00577     unsigned *sum_table;                
00578     int sum_table_size;                 
00579 
00580     
00581     RLEVoxels *rle_x;                   
00582     RLEVoxels *rle_y;                   
00583     RLEVoxels *rle_z;                   
00584     ConstructionBuffer *cbuf;           
00585 
00586     
00587     short factored_view_ready;          
00588     short affine_view;                  
00589     short best_view_axis;               
00590     short reverse_slice_order;          
00591     short intermediate_width;           
00592     short intermediate_height;
00593     double shear_i;                     
00594     double shear_j;
00595     double trans_i;                     
00596     double trans_j;
00597     vpMatrix3 warp_2d;                  
00598     double depth_000;                   
00599     double depth_di;                    
00600     double depth_dj;                    
00601     double depth_dk;                    
00602 
00603     
00604     short max_intermediate_width;       
00605     short max_intermediate_height;
00606     short max_scan_length;              
00607     short intermediate_color_channels;  
00608     short pad_int_to_maxwidth;          
00609     union {                             
00610         GrayIntPixel *gray_intim;
00611         RGBIntPixel *rgb_intim;
00612     } int_image;
00613 
00614     
00615     double shadow_shear_i;              
00616     double shadow_shear_j;
00617     double shadow_trans_i;              
00618     double shadow_trans_j;
00619     short shadow_width;                 
00620     short shadow_height;
00621     short max_shadow_width;             
00622     short max_shadow_height;
00623     short pad_shadow_to_maxwidth;       
00624     GrayIntPixel *shadow_buffer;        
00625 
00626     
00627     float *dc_table;                    
00628     int dc_table_len;                   
00629 
00630     
00631     float affine_opac_correct[VP_OPACITY_MAX+1];
00632                                         
00633 
00634     float shadow_opac_correct[VP_OPACITY_MAX+1];
00635                                         
00636 
00637 
00638     
00639     vpResult error_code;                
00640 
00641 
00642 #ifdef DEBUG
00643     short debug_enable[VPDEBUG_COUNT];  
00644     int trace_u, trace_v;               
00645     int trace_shadow_k;                 
00646 
00647 #endif
00648 
00649 #ifdef USE_TIMER
00650     unsigned timer_ticks[VPTIMER_COUNT];
00651     double timer_usec_per_tick;         
00652 #ifdef HAVE_HIRES_TIMER
00653     volatile unsigned *timer_addr;      
00654     unsigned dummy_timer;               
00655 #endif
00656 #endif
00657 
00658 };
00659 
00660 
00661 
00662 
00663 
00664 
00665 
00666 
00667 extern vpResult             VPCheckVoxelFields ANSI_ARGS((vpContext *vpc));
00668 extern vpResult             VPCheckRawVolume ANSI_ARGS((vpContext *vpc));
00669 extern vpResult             VPCheckClassifiedVolume ANSI_ARGS((
00670                                 vpContext *vpc, int axis));
00671 extern vpResult             VPCheckClassifier ANSI_ARGS((vpContext *vpc));
00672 extern vpResult             VPCheckShader ANSI_ARGS((vpContext *vpc));
00673 extern vpResult             VPCheckImage ANSI_ARGS((vpContext *vpc));
00674 extern vpResult             VPCheckShadows ANSI_ARGS((vpContext *vpc));
00675 extern vpResult             VPSetError ANSI_ARGS((vpContext *vpc,
00676                                 vpResult code));
00677 
00678 
00679 extern vpResult             VPClassifyBlock ANSI_ARGS((vpContext *vpc,
00680                                 int correct, int x0, int y0, int z0,
00681                                 int x1, int y1, int z1, float *opc,
00682                                 int dst_xstride, int dst_ystride,
00683                                 int dst_zstride));
00684 extern float                VPClassifyVoxel ANSI_ARGS((vpContext *vpc,
00685                                 void *voxel));
00686 extern vpResult             VPShadeBlock ANSI_ARGS((vpContext *vpc,
00687                                 int x0, int y0, int z0, int x1, int y1, int z1,
00688                                 float *shd, int dst_xstride, int dst_ystride,
00689                                 int dst_zstride));
00690 extern void                 VPQuantize ANSI_ARGS((float *src, int xlen,
00691                                 int ylen, int zlen, double scale, int maxvalue,
00692                                 unsigned char *dst, int dst_xstride,
00693                                 int dst_ystride, int dst_zstride));
00694 
00695 
00696 extern void                 VPLoadTranslation ANSI_ARGS((vpMatrix4 m,
00697                                 double tx, double ty, double tz));
00698 extern void                 VPLoadRotation ANSI_ARGS((vpMatrix4 m,
00699                                 int axis, double degrees));
00700 extern void                 VPLoadScale ANSI_ARGS((vpMatrix4 m,
00701                                 double sx, double sy, double sz));
00702 
00703 
00704 extern vpResult             VPFactorView ANSI_ARGS((vpContext *vpc));
00705 extern void                 VPComputeViewTransform ANSI_ARGS((vpContext *vpc,
00706                                 vpMatrix4 vm));
00707 extern void                 VPResizeRenderBuffers ANSI_ARGS((vpContext *vpc,
00708                                 int max_width, int max_height, int max_scan));
00709 extern void                 VPResizeDepthCueTable ANSI_ARGS((vpContext *vpc,
00710                                 int entries, int copy));
00711 extern void                 VPComputeDepthCueTable ANSI_ARGS((vpContext *vpc,
00712                                 int first, int last));
00713 extern float                VPSliceDepthCueRatio ANSI_ARGS((vpContext *vpc));
00714 extern void                 VPDepthCueIntImage ANSI_ARGS((vpContext *vpc,
00715                                 int slicenum));
00716 extern void                 VPResizeShadowBuffer ANSI_ARGS((vpContext *vpc,
00717                                 int max_width, int max_height));
00718 
00719 
00720 extern void                 VPBug ANSI_ARGS((char *fmt, ...));
00721 #ifdef DEBUG
00722 extern void                 VPDebug ANSI_ARGS((vpContext *vpc, int debug_code,
00723                                 char *fmt, ...));
00724 #endif 
00725 
00726 
00727 extern RLEVoxels *          VPCreateRLEVoxels ANSI_ARGS((vpContext *vpc,
00728                                 int ilen, int jlen, int klen, int data_count,
00729                                 int run_count, int rle_bytes_per_voxel));
00730 extern void                 VPDestroyRLEVoxels ANSI_ARGS((vpContext *vpc,
00731                                 RLEVoxels *rle_voxels));
00732 #ifdef INDEX_VOLUME
00733 extern vpResult             VPComputeRLEScanOffsets ANSI_ARGS((
00734                                 vpContext *vpc));
00735 #endif
00736 #ifdef DEBUG
00737 extern void                 VPCheckScanOffsets ANSI_ARGS((
00738                                 RLEVoxels *rle_voxels,
00739                                 int rle_bytes_per_voxel));
00740 extern void                 VPValidateClassifiedVolume ANSI_ARGS((
00741                                 vpContext *vpc));
00742 extern void                 VPDumpView ANSI_ARGS((vpContext *vpc));
00743 extern void                 VPDumpClassifier ANSI_ARGS((vpContext *vpc));
00744 #endif
00745 
00746 
00747 
00748 extern void                 VPRenderAffine ANSI_ARGS((vpContext *vpc,
00749                                 int algorithm, void (*composite_func)()));
00750 
00751 
00752 extern void                 VPComputeSummedAreaTable ANSI_ARGS((
00753                                 vpContext *vpc));
00754 extern void                 VPClassifyOctree ANSI_ARGS((vpContext *vpc));
00755 extern void                 VPInitOctreeLevelStack ANSI_ARGS((vpContext *vpc,
00756                                MMOctreeLevel level_stack[VP_MAX_OCTREE_LEVELS],
00757                                int axis, int k));
00758 extern int                  VPComputeScanRuns ANSI_ARGS((vpContext *vpc,
00759                                MMOctreeLevel level_stack[VP_MAX_OCTREE_LEVELS],
00760                                unsigned char *run_lengths, int axis,
00761                                int j, int icount));
00762 extern int                  VPCheckRuns ANSI_ARGS((vpContext *vpc,
00763                                 unsigned char *run_lengths, int axis,
00764                                 int k, int j));
00765 extern void                 VPTestMinMaxOctree ANSI_ARGS((vpContext *vpc));
00766 
00767 
00768 extern void                 VPComputeWarpTables ANSI_ARGS((void));
00769 extern void                 VPAffineImageOverlap ANSI_ARGS((int in_width,
00770                                 int in_height, int out_width, int out_height,
00771                                 vpMatrix3 warp_matrix, double filter_width,
00772                                 Trapezoid full_overlap[9],
00773                                 Trapezoid part_overlap[9]));