5 #ifndef GLVERTEX_RAWFORMAT_H
6 #define GLVERTEX_RAWFORMAT_H
15 #define strdup _strdup
16 #define snprintf _snprintf
39 unsigned char *lglReadRawData(
const char *filename,
40 long long *width,
long long *height,
long long *depth,
41 unsigned int *components=NULL,
unsigned int *bits=NULL,
bool *sign=NULL,
bool *msb=NULL,
42 float *scalex=NULL,
float *scaley=NULL,
float *scalez=NULL);
45 bool lglReadRawInfo(
char *filename,
46 long long *width,
long long *height,
long long *depth,
47 unsigned int *components=NULL,
unsigned int *bits=NULL,
bool *sign=NULL,
bool *msb=NULL,
48 float *scalex=NULL,
float *scaley=NULL,
float *scalez=NULL);
51 char *lglWriteRawData(
const char *filename,
53 long long width,
long long height,
long long depth=1,
54 unsigned int components=1,
unsigned int bits=8,
bool sign=
false,
bool msb=
true,
55 float scalex=1.0f,
float scaley=1.0f,
float scalez=1.0f);
58 char *lglMakeRawInfo(
long long width,
long long height,
long long depth,
59 unsigned int components,
unsigned int bits,
bool sign,
bool msb,
60 float scalex,
float scaley,
float scalez);
63 unsigned short int *lglConvertRaw(
unsigned char *data,
64 long long width,
long long height,
long long depth,
65 unsigned int &components,
66 unsigned int &bits,
bool sign,
bool msb);
69 unsigned char *lglStretchRaw(
unsigned short int *data,
70 long long width,
long long height,
long long depth,
71 unsigned int components);
74 unsigned char *lglQuantizeRaw(
unsigned short int *data,
75 long long width,
long long height,
long long depth,
79 unsigned char *lglLoadRawData(
const char *filename,
80 long long *width,
long long *height,
long long *depth,
81 float *scalex=NULL,
float *scaley=NULL,
float *scalez=NULL);
84 unsigned char *lglLoadRawImage(
const char *filename,
85 int *width,
int *height,
89 unsigned char *lglLoadRawImage(std::string filename,
90 int *width,
int *height,
94 bool lglWriteRawImage(
const char *filename,
100 bool lglWriteRawImage(std::string filename,
101 unsigned char *image,
102 int width,
int height,
106 inline bool lglReadRawInfo(
char *filename,
107 long long *width,
long long *height,
long long *depth,
108 unsigned int *components,
unsigned int *bits,
bool *sign,
bool *msb,
109 float *scalex,
float *scaley,
float *scalez)
111 unsigned int rawcomps=1;
113 unsigned int rawbits=8;
115 int rawscalex=1000000,rawscaley=1000000,rawscalez=1000000;
121 dot=strrchr(filename,
'.');
123 if (
dot==NULL)
return(
false);
125 if (strcmp(
dot,
".raw")!=0)
return(
false);
128 dotdot=strrchr(filename,
'.');
131 if (dotdot==NULL)
return(
false);
133 *width=*height=*depth=1;
137 if (sscanf(dotdot,
"%lldx%lld%n",width,height,&count)!=2)
return(
false);
145 if (sscanf(dotdot,
"%lld%n",depth,&count)!=1)
return(
false);
154 while (*dotdot!=
'.' && *dotdot!=
'_')
158 case '1': rawcomps=1; rawbits=8;
break;
159 case '2': rawcomps=1; rawbits=16;
break;
160 case '3': rawcomps=3; rawbits=8;
break;
161 case '4': rawcomps=4; rawbits=8;
break;
162 case '6': rawcomps=3; rawbits=16;
break;
163 case '8': rawcomps=4; rawbits=16;
break;
164 case 'u': rawsign=
false;
break;
165 case 's': rawsign=
true;
break;
166 case 'm': rawmsb=
true;
break;
167 case 'l': rawmsb=
false;
break;
168 default:
return(
false);
179 if (sscanf(dotdot,
"%dx%d%n",&rawscalex,&rawscaley,&count)!=2)
return(
false);
187 if (sscanf(dotdot,
"%d%n",&rawscalez,&count)!=1)
return(
false);
193 if (*dotdot!=
'.')
return(
false);
197 if (rawcomps==1 && rawbits==16)
202 else if (rawcomps==3 && rawbits==16)
207 else if (rawcomps==4 && rawbits==16)
214 if (rawcomps!=1 && components==NULL)
return(
false);
215 if (rawbits!=8 && bits==NULL)
return(
false);
216 if (rawsign!=
false && sign==NULL)
return(
false);
217 if (rawmsb!=
true && msb==NULL)
return(
false);
219 if (components!=NULL) *components=rawcomps;
220 if (bits!=NULL) *bits=rawbits;
221 if (sign!=NULL) *sign=rawsign;
222 if (msb!=NULL) *msb=rawmsb;
224 if (rawscalex>rawmaxscale) rawmaxscale=rawscalex;
225 if (rawscaley>rawmaxscale) rawmaxscale=rawscaley;
226 if (rawscalez>rawmaxscale) rawmaxscale=rawscalez;
228 if (rawmaxscale==0)
return(
false);
230 if (scalex!=NULL) *scalex=rawscalex/1E6f;
231 if (scaley!=NULL) *scaley=rawscaley/1E6f;
232 if (scalez!=NULL) *scalez=rawscalez/1E6f;
238 inline char *lglMakeRawInfo(
long long width,
long long height,
long long depth,
239 unsigned int components,
unsigned int bits,
bool sign,
bool msb,
240 float scalex,
float scaley,
float scalez)
242 static const int maxlen=100;
247 snprintf(info,maxlen,
".%lldx%lld",width,height);
248 if (depth>1) snprintf(&info[strlen(info)],maxlen-strlen(info),
"x%lld",depth);
250 if (components!=1 || bits!=8 || sign!=
false || msb!=
true ||
251 scalex!=1.0f || scaley!=1.0f || scalez!=1.0f)
253 snprintf(&info[strlen(info)],maxlen-strlen(info),
"_");
255 if (sign==
false) snprintf(&info[strlen(info)],maxlen-strlen(info),
"u");
256 else snprintf(&info[strlen(info)],maxlen-strlen(info),
"s");
258 if (components==1 && bits==8) snprintf(&info[strlen(info)],maxlen-strlen(info),
"1");
259 else if (components==1 && bits==16) snprintf(&info[strlen(info)],maxlen-strlen(info),
"2");
260 else if (components==2 && bits==8) snprintf(&info[strlen(info)],maxlen-strlen(info),
"2");
261 else if (components==3 && bits==8) snprintf(&info[strlen(info)],maxlen-strlen(info),
"3");
262 else if (components==4 && bits==8) snprintf(&info[strlen(info)],maxlen-strlen(info),
"4");
263 else if (components==3 && bits==16) snprintf(&info[strlen(info)],maxlen-strlen(info),
"6");
264 else if (components==4 && bits==16) snprintf(&info[strlen(info)],maxlen-strlen(info),
"8");
267 if (components==2 || bits==16)
269 if (msb==
true) snprintf(&info[strlen(info)],maxlen-strlen(info),
"m");
270 else snprintf(&info[strlen(info)],maxlen-strlen(info),
"l");
273 if (scalex>maxscale) maxscale=scalex;
274 if (scaley>maxscale) maxscale=scaley;
275 if (scalez>maxscale) maxscale=scalez;
277 if (maxscale==0.0f)
return(NULL);
279 if (scalex!=1.0f || scaley!=1.0f || scalez!=1.0f)
281 snprintf(&info[strlen(info)],maxlen-strlen(info),
"_%dx%d",
int(1E6f*scalex+0.5f),
int(1E6f*scaley+0.5f));
282 if (depth>1) snprintf(&info[strlen(info)],maxlen-strlen(info),
"x%d",
int(1E6f*scalez+0.5f));
286 snprintf(&info[strlen(info)],maxlen-strlen(info),
".raw");
288 return(strdup(info));
292 inline char *lglRemoveRawSuffix(
const char *filename)
294 char *filename2,*
dot;
296 long long rawwidth,rawheight,rawdepth;
297 unsigned int rawcomps,rawbits;
299 float rawscalex,rawscaley,rawscalez;
301 filename2=strdup(filename);
303 if (lglReadRawInfo(filename2,
304 &rawwidth,&rawheight,&rawdepth,
305 &rawcomps,&rawbits,&rawsign,&rawmsb,
306 &rawscalex,&rawscaley,&rawscalez))
308 dot=strrchr(filename2,
'.');
312 dot=strrchr(filename2,
'.');
318 dot=strrchr(filename2,
'.');
320 if (strcmp(
dot,
".raw")==0) *
dot=
'\0';
327 inline char *lglAppendRawInfo(
const char *filename,
328 long long width,
long long height,
long long depth,
329 unsigned int components,
unsigned int bits,
bool sign,
bool msb,
330 float scalex,
float scaley,
float scalez)
337 info=lglMakeRawInfo(width,height,depth,
338 components,bits,sign,msb,
339 scalex,scaley,scalez);
341 if (info==NULL)
return(NULL);
344 filename2=lglRemoveRawSuffix(filename);
347 filename3=(
char *)malloc(strlen(filename2)+strlen(info)+1);
350 memcpy(filename3,filename2,strlen(filename2));
351 memcpy(filename3+strlen(info),info,strlen(info)+1);
360 inline unsigned char *lglReadRawData(
const char *filename,
361 long long *width,
long long *height,
long long *depth,
362 unsigned int *components,
unsigned int *bits,
bool *sign,
bool *msb,
363 float *scalex,
float *scaley,
float *scalez)
369 unsigned char *volume;
373 if ((file=fopen(filename,
"rb"))==NULL)
return(NULL);
376 name=strdup(filename);
377 if (!lglReadRawInfo(name,
379 components,bits,sign,msb,
380 scalex,scaley,scalez))
388 bytes=(*width)*(*height)*(*depth)*(*components);
391 if (*bits==16) bytes*=2;
393 if ((volume=(
unsigned char *)malloc((
size_t)bytes))==NULL)
return(NULL);
396 if (fread(volume,(
size_t)bytes,1,file)!=1)
409 inline char *lglWriteRawData(
const char *filename,
410 unsigned char *volume,
411 long long width,
long long height,
long long depth,
412 unsigned int components,
unsigned int bits,
bool sign,
bool msb,
413 float scalex,
float scaley,
float scalez)
421 output=lglAppendRawInfo(filename,
423 components,bits,sign,msb,
424 scalex,scaley,scalez);
426 if (output==NULL)
return(NULL);
429 if ((file=fopen(output,
"wb"))==NULL)
435 bytes=width*height*depth*components;
437 if (bits==16) bytes*=2;
438 else if (bits==32) bytes*=4;
441 if (fwrite(volume,(
size_t)bytes,1,file)!=1)
453 inline unsigned short int *lglConvertRaw(
unsigned char *data,
454 long long width,
long long height,
long long depth,
455 unsigned int &components,
456 unsigned int &bits,
bool sign,
bool msb)
460 unsigned short int *shorts=NULL;
461 long long cells=width*height*depth;
463 if (components==2 && bits==8)
468 else if (components==6 && bits==8)
473 else if (components==8 && bits==8)
483 if ((shorts=(
unsigned short int *)malloc((
size_t)cells*
sizeof(
unsigned short int)))==NULL)
return(NULL);
486 for (i=0; i<cells; i++) shorts[i]=data[i]+128;
488 for (i=0; i<cells; i++) shorts[i]=data[i];
492 if ((shorts=(
unsigned short int *)malloc((
size_t)cells*
sizeof(
unsigned short int)))==NULL)
return(NULL);
496 for (i=0; i<cells; i++) shorts[i]=(
signed short)(256*data[i<<1]+data[(i<<1)+1])+32768;
498 for (i=0; i<cells; i++) shorts[i]=(
unsigned short)(256*data[i<<1]+data[(i<<1)+1]);
501 for (i=0; i<cells; i++) shorts[i]=(
signed short)(data[i<<1]+256*data[(i<<1)+1])+32768;
503 for (i=0; i<cells; i++) shorts[i]=(
unsigned short)(data[i<<1]+256*data[(i<<1)+1]);
510 inline unsigned char *lglStretchRaw(
unsigned short int *data,
511 long long width,
long long height,
long long depth,
512 unsigned int components)
516 unsigned char *data2;
521 cells=width*height*depth*components;
526 for (i=0; i<cells; i++)
533 if (vmin==vmax) vmax=vmin+1;
535 if ((data2=(
unsigned char *)malloc((
size_t)cells))==NULL)
538 for (i=0; i<cells; i++)
539 data2[i]=(
int)((data[i]-vmin)*255.0/(vmax-vmin)+0.5);
545 inline int lglGetRawValue(
unsigned short int *data,
546 long long width,
long long height,
long long ,
547 long long i,
long long j,
long long k)
549 return(data[i+(j+k*height)*width]);
553 inline double lglGetRawGradMag(
unsigned short int *data,
554 long long width,
long long height,
long long depth,
555 long long i,
long long j,
long long k)
560 if (i<width-1) gx=(lglGetRawValue(data,width,height,depth,i+1,j,k)-lglGetRawValue(data,width,height,depth,i-1,j,k))/2.0;
561 else gx=lglGetRawValue(data,width,height,depth,i,j,k)-lglGetRawValue(data,width,height,depth,i-1,j,k);
563 if (i<width-1) gx=lglGetRawValue(data,width,height,depth,i+1,j,k)-lglGetRawValue(data,width,height,depth,i,j,k);
567 if (j<height-1) gy=(lglGetRawValue(data,width,height,depth,i,j+1,k)-lglGetRawValue(data,width,height,depth,i,j-1,k))/2.0;
568 else gy=lglGetRawValue(data,width,height,depth,i,j,k)-lglGetRawValue(data,width,height,depth,i,j-1,k);
570 if (j<height-1) gy=lglGetRawValue(data,width,height,depth,i,j+1,k)-lglGetRawValue(data,width,height,depth,i,j,k);
574 if (k<depth-1) gz=(lglGetRawValue(data,width,height,depth,i,j,k+1)-lglGetRawValue(data,width,height,depth,i,j,k-1))/2.0;
575 else gz=lglGetRawValue(data,width,height,depth,i,j,k)-lglGetRawValue(data,width,height,depth,i,j,k-1);
577 if (k<depth-1) gz=lglGetRawValue(data,width,height,depth,i,j,k+1)-lglGetRawValue(data,width,height,depth,i,j,k);
580 return(sqrt(gx*gx+gy*gy+gz*gz));
584 inline unsigned char *lglQuantizeRaw(
unsigned short int *data,
585 long long width,
long long height,
long long depth,
590 unsigned char *data2;
602 for (k=0; k<depth; k++)
603 for (j=0; j<height; j++)
604 for (i=0; i<width; i++)
606 v=lglGetRawValue(data,width,height,depth,i,j,k);
611 if (vmin==vmax) vmax=vmin+1;
613 if (vmax-vmin<256) linear=
true;
615 err=
new double[65536];
618 for (i=0; i<65536; i++) err[i]=255*(
double)(i-vmin)/(vmax-vmin);
621 for (i=0; i<65536; i++) err[i]=0.0;
623 for (k=0; k<depth; k++)
624 for (j=0; j<height; j++)
625 for (i=0; i<width; i++)
626 err[lglGetRawValue(data,width,height,depth,i,j,k)]+=sqrt(lglGetRawGradMag(data,width,height,depth,i,j,k));
628 for (i=0; i<65536; i++) err[i]=pow(err[i],1.0/3);
630 err[vmin]=err[vmax]=0.0;
632 for (k=0; k<256; k++)
634 for (eint=0.0,i=0; i<65536; i++) eint+=err[i];
638 for (i=0; i<65536; i++)
648 for (i=1; i<65536; i++) err[i]+=err[i-1];
651 for (i=0; i<65536; i++) err[i]*=255.0/err[65535];
654 cells=width*height*depth;
656 if ((data2=(
unsigned char *)malloc((
size_t)cells))==NULL)
662 for (i=0; i<cells; i++)
663 data2[i]=(
int)(err[data[i]]+0.5);
671 inline unsigned char *lglLoadRawData(
const char *filename,
672 long long *width,
long long *height,
long long *depth,
673 float *scalex,
float *scaley,
float *scalez)
675 unsigned char *data=NULL;
676 unsigned int components=0;
678 bool sign=
false,msb=
false;
680 data=lglReadRawData(filename,
682 &components,&bits,&sign,&msb,
683 scalex,scaley,scalez);
686 if ((bits==8 && sign) || bits==16)
688 unsigned short int *shorts=lglConvertRaw(data,*width,*height,*depth,components,bits,sign,msb);
691 unsigned char *data2;
694 data2=lglQuantizeRaw(shorts,*width,*height,*depth);
696 data2=lglStretchRaw(shorts,*width,*height,*depth,components);
707 inline unsigned char *lglLoadRawData(std::string filename,
708 long long *width,
long long *height,
long long *depth,
709 float *scalex,
float *scaley,
float *scalez)
711 return(lglLoadRawData(filename.c_str(),
713 scalex,scaley,scalez));
717 inline unsigned char *lglLoadRawImage(
const char *filename,
718 int *width,
int *height,
721 unsigned char *data=NULL;
722 long long lwidth=0,lheight=0,ldepth=0;
723 unsigned int ucomponents=0;
725 bool sign=
false,msb=
false;
727 data=lglReadRawData(filename,
728 &lwidth,&lheight,&ldepth,
729 &ucomponents,&bits,&sign,&msb);
739 if ((bits==8 && sign) || bits==16)
741 unsigned short int *shorts=lglConvertRaw(data,lwidth,lheight,ldepth,ucomponents,bits,sign,msb);
744 unsigned char *data2=lglStretchRaw(shorts,lwidth,lheight,ldepth,ucomponents);
751 *height=(int)lheight;
752 *components=ucomponents;
759 inline unsigned char *lglLoadRawImage(std::string filename,
760 int *width,
int *height,
763 return(lglLoadRawImage(filename.c_str(),
769 inline bool lglWriteRawImage(
const char *filename,
770 unsigned char *image,
771 int width,
int height,
776 raw=lglWriteRawData(filename,
791 inline bool lglWriteRawImage(std::string filename,
792 unsigned char *image,
793 int width,
int height,
796 return(lglWriteRawImage(filename.c_str(),