1#include <IO/VolumesLoader/pvmutils.hpp>
14 VR_ERROR_NONFATAL = 0,
21#define ERRORMSG() vrerrormsg( __FILE__, __LINE__, VR_ERROR_FATAL )
22#define MEMERROR() vrerrormsg( __FILE__, __LINE__, VR_ERROR_MEM )
23#define IOERROR() vrerrormsg( __FILE__, __LINE__, VR_ERROR_IO )
24#define CODEERROR() vrerrormsg( __FILE__, __LINE__, VR_ERROR_CODE )
25#define WARNMSG( msg ) vrerrormsg( __FILE__, __LINE__, VR_ERROR_NONFATAL, msg )
27inline void vrerrormsg(
const char* file,
int line,
int fatal,
const char* msg =
nullptr ) {
28 if ( fatal == VR_ERROR_NONFATAL )
30 else if ( fatal == VR_ERROR_MEM )
31 fprintf( stderr,
"insufficient memory" );
32 else if ( fatal == VR_ERROR_IO )
34 else if ( fatal == VR_ERROR_CODE )
35 fprintf( stderr,
"unimplemented code" );
37 fprintf( stderr,
"fatal error" );
38 fprintf( stderr,
" in <%s> at line %d!\n", file, line );
39 if ( msg !=
nullptr )
fprintf( stderr,
"description: %s\n", msg );
41 if ( fatal != VR_ERROR_NONFATAL )
exit( 1 );
55#define DDS_MAXSTR ( 256 )
56#define DDS_BLOCKSIZE ( 1 << 20 )
57#define DDS_INTERLEAVE ( 1 << 24 )
59#define DDS_ISINTEL ( *( (unsigned char*)( &DDS_INTEL ) + 1 ) == 0 )
61char DDS_ID[] =
"DDS v3d\n";
62char DDS_ID2[] =
"DDS v3e\n";
63unsigned char* DDS_cache;
64unsigned int DDS_cachepos, DDS_cachesize;
66unsigned int DDS_buffer;
67unsigned int DDS_bufsize;
69unsigned short int DDS_INTEL = 1;
71inline int DDS_decode(
int bits ) {
72 return bits >= 1 ? bits + 1 : bits;
76inline unsigned int DDS_shiftl(
const unsigned int value,
const unsigned int bits ) {
77 return ( bits >= 32 ) ? 0 : value << bits;
80inline unsigned int DDS_shiftr(
const unsigned int value,
const unsigned int bits ) {
81 return ( bits >= 32 ) ? 0 : value >> bits;
84inline void DDS_swapuint(
unsigned int* x ) {
85 unsigned int tmp = *x;
87 *x = ( ( tmp & 0xff ) << 24 ) | ( ( tmp & 0xff00 ) << 8 ) | ( ( tmp & 0xff0000 ) >> 8 ) |
88 ( ( tmp & 0xff000000 ) >> 24 );
91void DDS_initbuffer() {
96inline void DDS_clearbits() {
102inline void DDS_loadbits(
unsigned char* data,
unsigned int size ) {
104 DDS_cachesize = size;
106 if ( ( DDS_cache = (
unsigned char*)
realloc( DDS_cache, DDS_cachesize + 4 ) ) ==
nullptr )
108 *( (
unsigned int*)&DDS_cache[DDS_cachesize] ) = 0;
110 DDS_cachesize = 4 * ( ( DDS_cachesize + 3 ) / 4 );
111 if ( ( DDS_cache = (
unsigned char*)
realloc( DDS_cache, DDS_cachesize ) ) ==
nullptr )
115inline unsigned int DDS_readbits(
unsigned int bits ) {
118 if ( bits < DDS_bufsize ) {
120 value = DDS_shiftr( DDS_buffer, DDS_bufsize );
123 value = DDS_shiftl( DDS_buffer, bits - DDS_bufsize );
125 if ( DDS_cachepos >= DDS_cachesize )
128 DDS_buffer = *( (
unsigned int*)&DDS_cache[DDS_cachepos] );
129 if ( DDS_ISINTEL ) DDS_swapuint( &DDS_buffer );
133 DDS_bufsize += 32 - bits;
134 value |= DDS_shiftr( DDS_buffer, DDS_bufsize );
137 DDS_buffer &= DDS_shiftl( 1, DDS_bufsize ) - 1;
143void DDS_deinterleave(
unsigned char* data,
146 unsigned int block = 0,
147 BOOLINT restore = FALSE ) {
148 unsigned int i, j, k;
150 unsigned char *data2, *ptr;
152 if ( skip <= 1 )
return;
155 if ( ( data2 = (
unsigned char*)
malloc( bytes ) ) ==
nullptr ) MEMERROR();
158 for ( ptr = data2, i = 0; i < skip; i++ )
159 for ( j = i; j < bytes; j += skip )
162 for ( ptr = data, i = 0; i < skip; i++ )
163 for ( j = i; j < bytes; j += skip )
166 memcpy( data, data2, bytes );
169 if ( ( data2 = (
unsigned char*)
malloc(
170 ( bytes < skip * block ) ? bytes : skip * block ) ) ==
nullptr )
174 for ( k = 0; k < bytes / skip / block; k++ ) {
175 for ( ptr = data2, i = 0; i < skip; i++ )
176 for ( j = i; j < skip * block; j += skip )
177 *ptr++ = data[k * skip * block + j];
179 memcpy( data + k * skip * block, data2, skip * block );
182 for ( ptr = data2, i = 0; i < skip; i++ )
183 for ( j = i; j < bytes - k * skip * block; j += skip )
184 *ptr++ = data[k * skip * block + j];
186 memcpy( data + k * skip * block, data2, bytes - k * skip * block );
189 for ( k = 0; k < bytes / skip / block; k++ ) {
190 for ( ptr = data + k * skip * block, i = 0; i < skip; i++ )
191 for ( j = i; j < skip * block; j += skip )
194 memcpy( data + k * skip * block, data2, skip * block );
197 for ( ptr = data + k * skip * block, i = 0; i < skip; i++ )
198 for ( j = i; j < bytes - k * skip * block; j += skip )
201 memcpy( data + k * skip * block, data2, bytes - k * skip * block );
209void DDS_interleave(
unsigned char* data,
212 unsigned int block = 0 ) {
213 DDS_deinterleave( data, bytes, skip, block, TRUE );
217void DDS_decode(
unsigned char* chunk,
219 unsigned char** data,
221 unsigned int block = 0 ) {
222 unsigned int skip, strip;
224 unsigned char *ptr1, *ptr2;
226 unsigned int cnt, cnt1, cnt2;
232 DDS_loadbits( chunk, size );
234 skip = DDS_readbits( 2 ) + 1;
235 strip = DDS_readbits( 16 ) + 1;
237 ptr1 = ptr2 =
nullptr;
240 while ( ( cnt1 = DDS_readbits( DDS_RL ) ) != 0 ) {
241 bits = DDS_decode( DDS_readbits( 3 ) );
243 for ( cnt2 = 0; cnt2 < cnt1; cnt2++ ) {
244 if ( strip == 1 || cnt <= strip )
245 act += DDS_readbits( bits ) - ( 1 << bits ) / 2;
247 act += *( ptr2 - strip ) - *( ptr2 - strip - 1 ) + DDS_readbits( bits ) -
255 if ( ( cnt & ( DDS_BLOCKSIZE - 1 ) ) == 0 ) {
256 if ( ptr1 ==
nullptr ) {
257 if ( ( ptr1 = (
unsigned char*)
malloc( DDS_BLOCKSIZE ) ) ==
nullptr ) MEMERROR();
261 if ( ( ptr1 = (
unsigned char*)
realloc( ptr1, cnt + DDS_BLOCKSIZE ) ) ==
273 if ( ptr1 !=
nullptr )
274 if ( ( ptr1 = (
unsigned char*)
realloc( ptr1, cnt ) ) ==
nullptr ) MEMERROR();
276 DDS_interleave( ptr1, cnt, skip, block );
283unsigned char* readRAWfiled( FILE* file,
unsigned int* bytes ) {
285 unsigned int cnt, blkcnt;
291 if ( data ==
nullptr ) {
292 if ( ( data = (
unsigned char*)
malloc( DDS_BLOCKSIZE ) ) ==
nullptr ) MEMERROR();
294 else if ( ( data = (
unsigned char*)
realloc( data, cnt + DDS_BLOCKSIZE ) ) ==
nullptr )
297 blkcnt =
fread( &data[cnt], 1, DDS_BLOCKSIZE, file );
299 }
while ( blkcnt == DDS_BLOCKSIZE );
306 if ( ( data = (
unsigned char*)
realloc( data, cnt ) ) ==
nullptr ) MEMERROR();
314unsigned char* readRAWfile(
const char* filename,
unsigned int* bytes ) {
319 if ( ( file =
fopen( filename,
"rb" ) ) ==
nullptr )
return nullptr;
321 data = readRAWfiled( file, bytes );
329unsigned char* readDDSfile(
const char* filename,
unsigned int* bytes ) {
336 unsigned char *chunk, *data;
339 if ( ( file =
fopen( filename,
"rb" ) ) ==
nullptr )
return nullptr;
341 for ( cnt = 0; DDS_ID[cnt] !=
'\0'; cnt++ )
342 if (
fgetc( file ) != DDS_ID[cnt] ) {
348 if ( version == 0 ) {
349 if ( ( file =
fopen( filename,
"rb" ) ) ==
nullptr )
return nullptr;
351 for ( cnt = 0; DDS_ID2[cnt] !=
'\0'; cnt++ )
352 if (
fgetc( file ) != DDS_ID2[cnt] ) {
360 if ( ( chunk = readRAWfiled( file, &size ) ) ==
nullptr ) IOERROR();
364 DDS_decode( chunk, size, &data, bytes, version == 1 ? 0 : DDS_INTERLEAVE );
372unsigned char* readPVMvolume(
const char* filename,
374 unsigned int* height,
380 unsigned char** desc,
381 unsigned char** courtesy,
382 unsigned char** parameter,
383 unsigned char** comment ) {
384 unsigned char *data, *ptr;
385 unsigned int datasize, numc;
389 unsigned char* volume;
391 float sx = 1.0f, sy = 1.0f, sz = 1.0f;
393 unsigned int len1 = 0, len2 = 0, len3 = 0, len4 = 0;
395 if ( ( data = readDDSfile( filename, &datasize ) ) ==
nullptr )
396 if ( ( data = readRAWfile( filename, &datasize ) ) ==
nullptr )
return nullptr;
398 if ( datasize < 5 )
return nullptr;
400 if ( ( data = (
unsigned char*)
realloc( data, datasize + 1 ) ) ==
nullptr ) MEMERROR();
401 data[datasize] =
'\0';
403 if (
strncmp( (
char*)data,
"PVM\n", 4 ) != 0 ) {
404 if (
strncmp( (
char*)data,
"PVM2\n", 5 ) == 0 )
406 else if (
strncmp( (
char*)data,
"PVM3\n", 5 ) == 0 )
412 if (
sscanf( (
char*)ptr,
"%u %u %u\n%g %g %g\n", width, height, depth, &sx, &sy, &sz ) !=
415 if ( *width < 1 || *height < 1 || *depth < 1 || sx <= 0.0f || sy <= 0.0f || sz <= 0.0f )
417 ptr = (
unsigned char*)
strchr( (
char*)ptr,
'\n' ) + 1;
421 while ( *ptr ==
'#' )
422 while ( *ptr++ !=
'\n' )
425 if (
sscanf( (
char*)ptr,
"%u %u %u\n", width, height, depth ) != 3 ) ERRORMSG();
426 if ( *width < 1 || *height < 1 || *depth < 1 ) ERRORMSG();
429 if ( scalex !=
nullptr && scaley !=
nullptr && scalez !=
nullptr ) {
435 ptr = (
unsigned char*)
strchr( (
char*)ptr,
'\n' ) + 1;
436 if (
sscanf( (
char*)ptr,
"%u\n", &numc ) != 1 ) ERRORMSG();
437 if ( numc < 1 ) ERRORMSG();
439 if ( bytes !=
nullptr )
441 else if ( numc != 1 )
444 ptr = (
unsigned char*)
strchr( (
char*)ptr,
'\n' ) + 1;
446 len1 =
strlen( (
char*)( ptr + ( *width ) * ( *height ) * ( *depth ) * numc ) ) + 1;
448 len2 =
strlen( (
char*)( ptr + ( *width ) * ( *height ) * ( *depth ) * numc + len1 ) ) + 1;
451 strlen( (
char*)( ptr + ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2 ) ) +
454 len4 =
strlen( (
char*)( ptr + ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2 +
457 if ( ( volume = (
unsigned char*)
malloc( ( *width ) * ( *height ) * ( *depth ) * numc + len1 +
458 len2 + len3 + len4 ) ) ==
nullptr )
460 if ( data + datasize !=
461 ptr + ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2 + len3 + len4 )
464 memcpy( volume, ptr, ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2 + len3 + len4 );
467 if ( desc !=
nullptr ) {
469 *desc = volume + ( *width ) * ( *height ) * ( *depth ) * numc;
473 if ( courtesy !=
nullptr ) {
475 *courtesy = volume + ( *width ) * ( *height ) * ( *depth ) * numc + len1;
480 if ( parameter !=
nullptr ) {
482 *parameter = volume + ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2;
484 *parameter =
nullptr;
487 if ( comment !=
nullptr ) {
489 *comment = volume + ( *width ) * ( *height ) * ( *depth ) * numc + len1 + len2 + len3;
hepler function to manage enum as underlying types in VariableSet