58#include <system_threads.h>
62#include "vrml_parser/Structs.h"
63#include "main/ProdCon.h"
64#include "OpenGL_Utils.h"
66#include "LoadTextures.h"
67#include "../scenegraph/Component_CubeMapTexturing.h"
75#include <libFreeWRL.h>
82#include "ImageLoader.h"
84#if !(defined(_ANDROID) || defined(ANDROIDNDK))
108void *LoadTextures_constructor(){
113void LoadTextures_init(
struct tLoadTextures *t)
120 t->prv = LoadTextures_constructor();
123 p->texture_request_list = NULL;
124 p->loader_waiting =
false;
126 p->texture_list = NULL;
128 p->TextureParsing = FALSE;
135 IMAGETYPE_UNKNOWN = 0,
144static int sniffImageFileHeader(
char *filename) {
162 FILE* fp = fopen(filename,
"rb");
163 rvt=fread(header,20,1,fp);
166 iret = IMAGETYPE_UNKNOWN;
167 if(!strncmp(&header[1],
"PNG",3))
168 iret = IMAGETYPE_PNG;
170 if(!strncmp(header,
"ÿØÿ",3))
171 iret = IMAGETYPE_JPEG;
173 if(!strncmp(header,
"GIF",3))
174 iret = IMAGETYPE_GIF;
176 if(!strncmp(header,
"DDS ",4))
177 iret = IMAGETYPE_DDS;
179 if(!strncmp(header,
"web3dit",7))
180 iret = IMAGETYPE_WEB3DIT;
182 if(!strncmp(header,
"NRRD",4))
183 iret = IMAGETYPE_NRRD;
185 if(!strncmp(header,
"vol",3))
186 iret = IMAGETYPE_VOL;
191static int sniffImageChannels_bruteForce(
unsigned char *imageblob,
int width,
int height){
195 int i,ii4,j,jj4, hasAlpha, hasColor, channels;
199 for(i=0;i<height;i++){
205 for(j=0;j<width;j++){
207 hasAlpha = hasAlpha || imageblob[jj4+3] != 255;
208 hasColor = hasColor || imageblob[jj4] != imageblob[jj4+1] || imageblob[jj4+1] != imageblob[jj4+2];
213 for(j=3;j<width*4;j+=4){
214 hasAlpha = hasAlpha || imageblob[ii4 + j] != 255;
217 if(hasAlpha && hasColor)
break;
219 channels = hasColor ? 3 : 1;
220 channels = hasAlpha ? channels + 1 : channels;
233 DEBUG_MSG(
"%s\t%p\t%s\n", texst(entry->status), entry, entry->filename);
237void texture_dump_list()
240 DEBUG_MSG(
"TEXTURE: wait queue\n");
242 ml_foreach(p->texture_list, texture_dump_entry(ml_elem(__l)));
243 DEBUG_MSG(
"TEXTURE: end wait queue\n");
247static size_t st(
int k){
256 unsigned char R,B,*data;
260 data = this_tex->texdata;
267 ipix = (st(i)*st(y) + st(j))*st(x) + st(k);
268 ibyte = ipix * st(4);
270 B = data[ibyte+st(2)];
272 data[ibyte+st(2)] = R;
287 unsigned char *texture;
293 iptr = node->image.p;
297 DEBUG_TEX (
"start of texture_load_from_pixelTexture...\n");
300 if (node->image.n < 3) {
301 printf (
"PixelTexture, need at least 3 elements, have %d\n",node->image.n);
309 depth = *iptr; iptr++;
311 DEBUG_TEX (
"wid %d hei %d depth %d\n",wid,hei,depth);
313 if ((depth < 0) || (depth >4)) {
314 printf (
"PixelTexture, depth %d out of range, assuming 1\n",(
int) depth);
318 if ((wid*hei-3) > node->image.n) {
319 printf (
"PixelTexture, not enough data for wid %d hei %d, have %d\n",
320 wid, hei, (wid*hei)-2);
333 this_tex->hasAlpha = ((depth == 2) || (depth == 4));
334 this_tex->channels = depth;
336 texture = MALLOC (
unsigned char *, wid*hei*4);
337 this_tex->texdata = texture;
338 this_tex->status = TEX_NEEDSBINDING;
342 for (count = 0; count < (wid*hei); count++) {
345 texture[tctr++] = *iptr & 0xff;
346 texture[tctr++] = *iptr & 0xff;
347 texture[tctr++] = *iptr & 0xff;
348 texture[tctr++] = 0xff;
352 texture[tctr++] = (*iptr>>8) & 0xff;
353 texture[tctr++] = (*iptr>>8) & 0xff;
354 texture[tctr++] = (*iptr>>8) & 0xff;
355 texture[tctr++] = (*iptr>>0) & 0xff;
359 texture[tctr++] = (*iptr>>16) & 0xff;
360 texture[tctr++] = (*iptr>>8) & 0xff;
361 texture[tctr++] = (*iptr>>0) & 0xff;
362 texture[tctr++] = 0xff;
366 texture[tctr++] = (*iptr>>24) & 0xff;
367 texture[tctr++] = (*iptr>>16) & 0xff;
368 texture[tctr++] = (*iptr>>8) & 0xff;
369 texture[tctr++] = (*iptr>>0) & 0xff;
383 int hei,wid,bpp,dep,nvox,nints;
384 unsigned char *texture;
390 iptr = node->image.p;
394 DEBUG_TEX (
"start of texture_load_from_pixelTexture...\n");
397 if (node->image.n < 4) {
398 printf (
"PixelTexture, need at least 3 elements, have %d\n",node->image.n);
412 DEBUG_TEX (
"bpp %d wid %d hei %d dep %d \n",bpp,wid,hei,dep);
414 if ((bpp < 0) || (bpp >4)) {
415 printf (
"PixelTexture, bytes per pixel %d out of range, assuming 1\n",(
int) bpp);
419 nints = (nvox * bpp) / 4;
420 if ((nints + 4) > node->image.n) {
421 printf (
"PixelTexture3D, not enough data for bpp %d wid %d hei %d, dep %d, need %d have %d\n",
422 bpp, wid, hei, dep, nints + 4, node->image.n);
436 this_tex->hasAlpha = ((bpp == 2) || (bpp == 4));
437 this_tex->channels = bpp;
439 texture = MALLOC (
unsigned char *, wid*hei*4*dep);
440 this_tex->texdata = texture;
441 this_tex->status = TEX_NEEDSBINDING;
445 for (count = 0; count < (wid*hei*dep); count++) {
448 texture[tctr++] = *iptr & 0xff;
449 texture[tctr++] = *iptr & 0xff;
450 texture[tctr++] = *iptr & 0xff;
451 texture[tctr++] = 0xff;
455 texture[tctr++] = (*iptr>>8) & 0xff;
456 texture[tctr++] = (*iptr>>8) & 0xff;
457 texture[tctr++] = (*iptr>>8) & 0xff;
458 texture[tctr++] = (*iptr>>0) & 0xff;
462 texture[tctr++] = (*iptr>>16) & 0xff;
463 texture[tctr++] = (*iptr>>8) & 0xff;
464 texture[tctr++] = (*iptr>>0) & 0xff;
465 texture[tctr++] = 0xff;
469 texture[tctr++] = (*iptr>>24) & 0xff;
470 texture[tctr++] = (*iptr>>16) & 0xff;
471 texture[tctr++] = (*iptr>>8) & 0xff;
472 texture[tctr++] = (*iptr>>0) & 0xff;
492 int i,j,k,nx,ny,nz,ishex, iret, totalbytes, ipix, nchan;
498 fp = fopen(fname,
"r");
507 rv=fgets(line,1000,fp);
508 if(strncmp(line,
"x3di3d",6)){
514 if(!strncmp(line,
"x3di3d x",8)) ishex = 1;
515 rvi=fscanf(fp,
"%d %d %d %d",&nchan, &nx,&ny,&nz);
516 totalbytes = 4 * nx * ny * nz;
517 if(totalbytes <= 128 * 128 * 128 * 4){
518 unsigned char *rgbablob;
519 rgbablob = malloc(nx * ny * nz * 4);
520 memset(rgbablob,0,nx*ny*nz*4);
526 unsigned char pixel[4],*rgba;
528 rvi=fscanf(fp,
"%x",&pixint);
530 rvi=fscanf(fp,
"%d",&pixint);
532 pixel[0] = (pixint >> 0) & 0xff;
533 pixel[1] = (pixint >> 8) & 0xff;
534 pixel[2] = (pixint >> 16) & 0xff;
535 pixel[3] = (pixint >> 24) & 0xff;
537 ipix = (i*nz +j)*ny +k;
538 rgba = &rgbablob[ipix*4];
541 case 1: rgba[0] = rgba[1] = rgba[2] = pixel[0]; rgba[3] = 255;
break;
542 case 2: rgba[0] = rgba[1] = rgba[2] = pixel[1]; rgba[3] = pixel[0];
break;
543 case 3: rgba[0] = pixel[2]; rgba[1] = pixel[1]; rgba[2] = pixel[2]; rgba[3] = 255;
545 case 4: rgba[0] = pixel[3]; rgba[1] = pixel[2]; rgba[2] = pixel[1]; rgba[3] = pixel[0];
break;
553 tti->channels = nchan;
557 tti->texdata = rgbablob;
576 int i,j,k,nx,ny,nz, ipix, nchan;
578 unsigned char *rgbablob;
581 fp = fopen(fname,
"w+");
582 nchan = tti->channels;
586 rgbablob = tti->texdata;
588 fprintf(fp,
"x3di3d x\n");
589 fprintf(fp,
"%d %d %d %d",nchan, nx,ny,nz);
595 ipix = (i*nz +j)*ny +k;
596 rgba = &rgbablob[ipix*4];
599 case 1: pixint = rgba[0];
break;
600 case 2: pixint = (rgba[0] << 8) + rgba[3];
break;
601 case 3: pixint = (rgba[0] << 16) + (rgba[1] << 8) + (rgba[2] << 0);
break;
602 case 4: pixint = (rgba[0] << 24) + (rgba[1] << 16) + (rgba[2] << 8) + rgba[3];
break;
607 case 1: fprintf(fp,
" %#.2x",pixint);
break;
608 case 2: fprintf(fp,
" %#.4x",pixint);
break;
609 case 3: fprintf(fp,
" %#.6x",pixint);
break;
610 case 4: fprintf(fp,
" %#.8x",pixint);
break;
612 fprintf(fp,
" 0x00");
break;
649 int i,j,k,m,nx,ny,nz,nv,nc, iret, totalbytes, ipix, jpix, kpix, nchan;
650 int version, Rmin, Rmax, Nchannelspervalue, Mvaluesperpixel, Dimensions;
651 unsigned int pixint, Pixels[10], iydown;
653 char Geometry, ODescription[200], Type, Componentnames[10], YDirection;
658 fp = fopen(fname,
"r");
664 rv = fgets(line,1000,fp);
665 if(strncmp(line,
"web3dit",7)){
671 rv=fgets(line,1000,fp);
672 sscanf(line,
"%c",&Geometry);
673 rv=fgets(line,1000,fp);
674 sscanf(line,
"%d",&version);
675 rv=fgets(line,1000,fp);
676 sscanf(line,
"%s",ODescription);
677 rv=fgets(line,1000,fp);
678 sscanf(line,
"%c",&Type);
679 rv=fgets(line,1000,fp);
680 sscanf(line,
"%d %d",&Rmin,&Rmax);
682 rv=fgets(line,1000,fp);
683 sscanf(line,
"%d",&Nchannelspervalue);
684 rv=fgets(line,1000,fp);
685 sscanf(line,
"%d",&Mvaluesperpixel);
686 rv=fgets(line,1000,fp);
687 sscanf(line,
"%s",Componentnames);
688 rv=fgets(line,1000,fp);
689 sscanf(line,
"%d",&Dimensions);
690 rv=fgets(line,1000,fp);
691 sscanf(line,
"%d %d %d",&Pixels[0], &Pixels[1], &Pixels[2]);
692 rv=fgets(line,1000,fp);
693 sscanf(line,
"%c",&YDirection);
694 rv=fgets(line,1000,fp);
700 if(Dimensions > 2) nz = Pixels[2];
701 nv = Mvaluesperpixel;
702 nc = Nchannelspervalue;
705 if(YDirection ==
'U') iydown = 0;
707 totalbytes = 4 * nx * ny * nz;
708 if(totalbytes <= 256 * 256 * 256 * 4){
709 unsigned char *rgbablob;
710 rgbablob = malloc(totalbytes);
711 memset(rgbablob,0,totalbytes);
717 unsigned char pixel[4],*rgba, n;
718 pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
725 rvi=fscanf(fp,
"%f",&pixfloat);
728 rvi=fscanf(fp,
"%x",&pixint);
732 rvi=fscanf(fp,
"%d",&pixint);
738 pixel[n] = (
unsigned char)(
unsigned int)((pixfloat - Rmin) / (Rmax - Rmin) * 255.0);
743 pixel[n] = (pixint >> n*8) & 0xff;
752 ipix = (i*ny +j)*nx +k;
753 jpix = (i*ny +(ny-1-j))*nx + k;
754 kpix = iydown ? jpix : ipix;
755 rgba = &rgbablob[kpix*4];
758 case 1: rgba[0] = rgba[1] = rgba[2] = pixel[0]; rgba[3] = 255;
break;
759 case 2: rgba[0] = rgba[1] = rgba[2] = pixel[1]; rgba[3] = pixel[0];
break;
760 case 3: rgba[0] = pixel[2]; rgba[1] = pixel[1]; rgba[2] = pixel[0]; rgba[3] = 255;
762 case 4: rgba[0] = pixel[3]; rgba[1] = pixel[2]; rgba[2] = pixel[1]; rgba[3] = pixel[0];
break;
771 tti->channels = nchan;
775 tti->texdata = rgbablob;
778 for(i=0;i<tti->z;i++){
779 for(j=0;j<tti->y;j++){
780 for(k=0;k<tti->x;k++){
784 ipix = (i*tti->y + j)*tti->x + k;
787 memcpy(&pixint,&tti->texdata[kpix*4],4);
788 printf(
"%x ",pixint);
831 int i,j,k,nx,ny,nz, ipix, jpix, kpix, iydown, nchan;
832 int version, Rmin, Rmax, Nchannelspervalue, Mvaluesperpixel, Dimensions;
834 char Geometry, *ODescription, Type, *Componentnames, YDirection;
836 static char *LRGBA [] = {
"L",
"LA",
"RGB",
"RGBA"};
839 fp = fopen(fname,
"w+");
841 unsigned char *rgbablob;
842 nchan = tti->channels;
846 rgbablob = tti->texdata;
847 Dimensions = nz == 1 ? 2 : 3;
851 Nchannelspervalue = nchan;
858 if(nz > 1) Geometry =
'3';
859 Componentnames = LRGBA[nchan -1];
862 iydown = (YDirection ==
'D') ? 1 : 0;
864 fprintf(fp,
"web3dit%c #H 7 byte magic header, means web3d compatible image in text form, 1byte for Geometry sniffing\n",Geometry);
865 fprintf(fp,
"%c #G {C,P,3,2}: image geometry: C: cubemap RHS y-up z/depth/layer/order [+-x,+-y,+-z], top of top +z, bottom of bottom -z P: 360 panorama [L->R, 360/z ], 3: texture3D or Volume [z=depth], 2: texture2D\n",Geometry);
866 fprintf(fp,
"%d #F {1} file version\n",version);
867 fprintf(fp,
"%s #O optional description\n",ODescription);
868 fprintf(fp,
"%c #T {x,i,f} how to read space-delimited value: x as hex, i as int, f as float\n",Type);
869 fprintf(fp,
"%d %d #R range of channel, most useful for normalizing floats\n",Rmin,Rmax);
870 fprintf(fp,
"%d #N channels/components per value ie RGBA as int: 4, RGBA as 4 ints: 1\n",Nchannelspervalue);
871 fprintf(fp,
"%d #M values per pixel ie RGBA as int: 1, RGBA as 4 ints: 4\n",Mvaluesperpixel);
872 fprintf(fp,
"%s #C[N*M] component names and order, choose from: {R,G,B,A,L} ie RGBA, LA, L, RGB\n",Componentnames);
873 fprintf(fp,
"%d #D number of dimensions, 2 for normal 2D image, 3 for 3D image\n",Dimensions);
874 fprintf(fp,
"%d %d %d #P[D] size in pixels in each dimension: x,y,z (use 1 for z if 2D)\n",nx,ny,nz);
875 fprintf(fp,
"%c #Y {U,D} image y-Down or texture y-Up row order\n",YDirection);
876 fprintf(fp,
"#I image values follow with x in inner loop, y-down image direction, z in outer:\n");
883 ipix = (i*ny +j)*nx +k;
884 jpix = (i*ny +(ny-1-j))*nx + k;
885 kpix = iydown ? jpix : ipix;
886 rgba = &rgbablob[kpix*4];
889 case 1: pixint = rgba[0];
break;
890 case 2: pixint = (rgba[0] << 8) + rgba[3];
break;
891 case 3: pixint = (rgba[0] << 16) + (rgba[1] << 8) + (rgba[2] << 0);
break;
892 case 4: pixint = (rgba[0] << 24) + (rgba[1] << 16) + (rgba[2] << 8) + rgba[3];
break;
897 case 1: fprintf(fp,
" %#.2x",pixint);
break;
898 case 2: fprintf(fp,
" %#.4x",pixint);
break;
899 case 3: fprintf(fp,
" %#.6x",pixint);
break;
900 case 4: fprintf(fp,
" %#.8x",pixint);
break;
902 fprintf(fp,
" 0x00");
break;
934 int i,j,k,nx,ny,nz, bitsperpixel, bpp, iendian, iret, totalbytes, ipix, nchan;
936 float sx,sy,sz,tx,ty,tz;
941 fp = fopen(fname,
"r+b");
947 rv=fgets(line,1000,fp);
948 if(strncmp(line,
"vol",3)){
953 rv=fgets(line,1000,fp);
954 sscanf(line,
"%d %d %d",&nx,&ny,&nz);
955 rv=fgets(line,1000,fp);
956 sscanf(line,
"%f %f %f",&sx,&sy,&sz);
957 rv=fgets(line,1000,fp);
958 sscanf(line,
"%f %f %f",&tx,&ty,&tz);
959 rv=fgets(line,1000,fp);
960 sscanf(line,
"%d %d",&bitsperpixel,&iendian);
961 bpp = bitsperpixel / 8;
963 switch(bitsperpixel){
964 case 1: nchan = 1;
break;
966 case 2: nchan = 4;
break;
968 case 4: nchan = 1;
break;
970 case 8: nchan = 1;
break;
972 case 16: nchan = 1;
break;
974 case 32: nchan = 1;
break;
980 totalbytes = bpp * nx * ny * nz;
981 if(totalbytes < 128 * 128 * 128 *4){
982 unsigned char* blob, *rgbablob;
986 blob = malloc(totalbytes + 4);
987 rgbablob = malloc(nx * ny * nz * 4);
988 memset(rgbablob,0,nx*ny*nz*4);
990 rvt=fread(blob,totalbytes,1,fp);
995 unsigned char *pixel,*rgba;
996 ipix = (i*ny +j)*nx +k;
998 pixel = &blob[ipix*bpp];
999 rgba = &rgbablob[ipix*4];
1001 switch(bitsperpixel){
1007 rgba[0] = pixel[0] >> 4;
1008 rgba[1] = pixel[0] & 0xF;
1009 rgba[2] = pixel[1] >> 4;
1010 rgba[3] = pixel[1] & 0xF;
1017 rgba[0] = rgba[1] = rgba[2] = (
unsigned char)pixel[0];
1021 rgba[0] = rgba[1] = rgba[2] = (
unsigned char) *(
unsigned short*)pixel;
1036 if(blob) free(blob);
1037 tti->channels = nchan;
1041 tti->texdata = rgbablob;
1055int isMachineLittleEndian(){
1058 unsigned short int one = 1;
1061 c = (
unsigned char *)&one;
1062 iret = (c[0] == 1) ? TRUE : FALSE;
1076const char *fieldname;
1080{
"type:",5,NRRDFIELD_type},
1081{
"dimension:",10,NRRDFIELD_dimension},
1082{
"sizes:",6,NRRDFIELD_sizes},
1083{
"spacings:",9,NRRDFIELD_spacing},
1084{
"encoding:",9,NRRDFIELD_encoding},
1085{
"endian:",7,NRRDFIELD_endian},
1101const char * stypes[7];
1105} nrrddatatypes [] = {
1106{{
"signed char",
"int8_t",
"int8", NULL,NULL,NULL,NULL}, CDATATYPE_char, 1,
"%hh"},
1107{{
"uchar",
"unsigned char",
"uint8",
"uint8_t", NULL,NULL,NULL}, CDATATYPE_uchar, 1,
"%hhu" },
1108{{
"short",
"short int",
"signed short",
"signed short int",
"int16",
"int16_t", NULL}, CDATATYPE_short, 2,
"%hd" },
1109{{
"ushort",
"unsigned short",
"unsigned short int",
"uint16",
"uint16_t", NULL, NULL}, CDATATYPE_ushort, 2,
"%hu" },
1110{{
"int",
"signed int",
"int32",
"int32_t", NULL, NULL, NULL}, CDATATYPE_int, 4,
"%d"},
1111{{
"uint",
"unsigned int",
"uint32",
"uint32_t", NULL, NULL, NULL}, CDATATYPE_uint, 4,
"%u" },
1112{{
"longlong",
"long long",
"long long int",
"signed long long",
"signed long long int",
"int64",
"int64_t"}, CDATATYPE_longlong, 8,
"%lld"},
1113{{
"ulonglong",
"unsigned long long",
"unsigned long long int",
"uint64",
"uint64_t", NULL, NULL}, CDATATYPE_ulonglong, 8,
"%llu" },
1114{{
"float", NULL,NULL,NULL,NULL, NULL,NULL},CDATATYPE_float,4,
"%f" },
1115{{
"double", NULL,NULL,NULL,NULL, NULL,NULL},CDATATYPE_double,8,
"%lf"},
1116{{NULL,NULL,NULL,NULL, NULL,NULL,NULL},0},
1119NRRDENDIAN_LITTLE = 1,
1123NRRDENCODING_RAW = 1,
1168 fp = fopen(fname,
"r+b");
1170 unsigned long long i,j,k;
1171 int ifieldtype, idatatype;
1173 int idim, ilen, isize[4], iendian, iencoding, ifound,slen,klen, bsize;
1175 char cendian[256], cencoding[256];
1178 unsigned long long nvoxel;
1179 unsigned long long totalbytes;
1180 unsigned char *data;
1181 unsigned char *voxel;
1190 rv=fgets(line,2047,fp);
1191 if(strncmp(line,
"NRRD",4)){
1201 isize[0] = isize[1] = isize[2] = isize[3] = 0;
1207 rv=fgets(line,2047,fp);
1211 if(strlen(line) < 3){
1218 if(!nrrdfields[i].fieldname)
break;
1219 if(!strncmp(line,nrrdfields[i].fieldname,nrrdfields[i].len)){
1220 ifieldtype = nrrdfields[i].fieldtype;
1221 ilen = nrrdfields[i].len;
1226 remainder = &line[ilen];
1228 case NRRDFIELD_type:
1231 if(remainder[0] ==
' ') remainder = &remainder[1];
1234 slen = strlen(remainder);
1237 for(i=0;i<slen;i++){
1238 char c = remainder[slen-1 -i];
1239 if(c ==
'\n' || c ==
'\r' || c ==
' ') klen--;
1246 if(nrrddatatypes[k].itype == 0)
break;
1248 if(nrrddatatypes[k].stypes[j]){
1249 if(!strncmp(remainder,nrrddatatypes[k].stypes[j],klen)){
1251 idatatype = nrrddatatypes[k].itype;
1253 bsize = nrrddatatypes[k].bsize;
1254 fmt = nrrddatatypes[k].fmt;
1263 case NRRDFIELD_dimension:
1264 sscanf(remainder,
"%d",&idim);
1267 case NRRDFIELD_sizes:
1270 sscanf(remainder,
"%d",&isize[0]);
break;
1272 sscanf(remainder,
"%d%d",&isize[0],&isize[1]);
break;
1274 sscanf(remainder,
"%d%d%d",&isize[0],&isize[1],&isize[2]);
break;
1276 sscanf(remainder,
"%d%d%d%d",&isize[0],&isize[1],&isize[2],&isize[3]);
break;
1281 case NRRDFIELD_encoding:
1282 sscanf(remainder,
"%s",cencoding);
1283 if(!strcmp(cencoding,
"raw"))
1284 iencoding = NRRDENCODING_RAW;
1285 else if(!strcmp(cencoding,
"ascii"))
1286 iencoding = NRRDENCODING_ASCII;
1290 case NRRDFIELD_endian:
1291 sscanf(remainder,
"%s",cendian);
1292 if(!strcmp(cendian,
"little"))
1293 iendian = NRRDENDIAN_LITTLE;
1294 else if(!strcmp(cendian,
"big"))
1295 iendian = NRRDENDIAN_BIG;
1305 printf(
"iendian %d idatatype %d iencoding %d idim %d isizes %d %d %d %d bsize %d\n",
1306 iendian,idatatype,iencoding,idim,isize[0],isize[1],isize[2],isize[3], bsize);
1307 printf(
"machine endian isLittle=%d\n",isMachineLittleEndian());
1308 printf(
"hows that?\n");
1314 for(i=0;i<idim-1;i++){
1315 isize[i] = isize[i+1];
1320 if(idim <3) isize[2] = 1;
1321 if(idim <2) isize[1] = 1;
1327 nvoxel = isize[0] * isize[1] * isize[2];
1328 totalbytes = nvoxel * bsize;
1329 data = MALLOC(
unsigned char *,(
size_t)totalbytes);
1330 memset(data,4,(
size_t)totalbytes);
1331 voxel = MALLOC(
unsigned char *, bsize);
1333 if(iencoding == NRRDENCODING_RAW){
1334 int dataLittleEndian;
1335 size_t nelem_read, element_size = 0L;
1336 element_size = bsize;
1337 nelem_read = fread(data,element_size, (
size_t)nvoxel,fp);
1338 printf(
"num elems read = %llu elemsize %ld bytes requeted = %llu %llu\n",(
unsigned long long)nelem_read,(
long)bsize,bsize*nvoxel,totalbytes);
1340 dataLittleEndian = iendian == NRRDENDIAN_LITTLE ? TRUE : FALSE;
1341 if(isMachineLittleEndian() != dataLittleEndian && bsize > 1){
1343 printf(
"swapping endian\n");
1344 for(i=0;i<nvoxel;i++){
1345 unsigned char * voxel = &data[i*bsize];
1346 for(j=0;j<bsize/2;j++){
1350 voxel[j] = voxel[k];
1355 }
else if(iencoding == NRRDENCODING_ASCII){
1358 for(i=0;i<isize[2];i++){
1360 for(j=0;j<isize[1];j++){
1362 for(k=0;k<isize[0];k++){
1367 rvi=fscanf(fp,fmt,voxel);
1369 memcpy(&data[kvox*bsize],voxel,bsize);
1381 case CDATATYPE_char:
1385 case CDATATYPE_uchar:
1389 case CDATATYPE_short:
1390 dlo = dhi = (double) *(
short*)(voxel);
1392 case CDATATYPE_ushort:
1393 dlo = dhi = (double) *(
unsigned short*)(voxel);
1394 printf(
"initial range for ushort hi %lf lo %lf\n",dhi,dlo);
1397 dlo = dhi = (double) *(
long*)(voxel);
1399 case CDATATYPE_uint:
1400 dlo = dhi = (double) *(
unsigned long*)(voxel);
1402 case CDATATYPE_longlong:
1403 dlo = dhi = (double) *(
long long *)(voxel);
1405 case CDATATYPE_ulonglong:
1406 dlo = dhi = (double) *(
unsigned long long *)(voxel);
1408 case CDATATYPE_float:
1409 dlo = dhi = (double) *(
float*)(voxel);
1411 case CDATATYPE_double:
1412 dlo = dhi = *(
double*)(voxel);
1418 for(i=0;i<nvoxel;i++){
1419 unsigned char *voxel;
1423 voxel = &data[i*bsize];
1425 case CDATATYPE_char:
1426 dlo = min(dlo,(
double)*(
char*)(voxel));
1427 dhi = max(dhi,(
double)*(
char*)(voxel));
1429 case CDATATYPE_uchar:
1430 dlo = min(dlo,(
double)*(
unsigned char*)(voxel));
1431 dhi = max(dhi,(
double)*(
unsigned char*)(voxel));
1433 case CDATATYPE_short:
1434 dlo = min(dlo,(
double)*(
short*)(voxel));
1435 dhi = max(dhi,(
double)*(
short*)(voxel));
1437 case CDATATYPE_ushort:
1438 dlo = min(dlo,(
double)*(
unsigned short*)(voxel));
1439 dhi = max(dhi,(
double)*(
unsigned short*)(voxel));
1442 dlo = min(dlo,(
double)*(
long*)(voxel));
1443 dhi = max(dhi,(
double)*(
long*)(voxel));
1445 case CDATATYPE_uint:
1446 dlo = min(dlo,(
double)*(
unsigned long*)(voxel));
1447 dhi = max(dhi,(
double)*(
unsigned long*)(voxel));
1449 case CDATATYPE_longlong:
1450 dlo = min(dlo,(
double)*(
unsigned long long*)(voxel));
1451 dhi = max(dhi,(
double)*(
unsigned long long*)(voxel));
1453 case CDATATYPE_ulonglong:
1454 dlo = min(dlo,(
double)*(
unsigned long*)(voxel));
1455 dhi = max(dhi,(
double)*(
unsigned long*)(voxel));
1457 case CDATATYPE_float:
1458 dlo = min(dlo,(
double)*(
float*)(voxel));
1459 dhi = max(dhi,(
double)*(
float*)(voxel));
1461 case CDATATYPE_double:
1462 dlo = min(dlo,(
double)*(
double*)(voxel));
1463 dhi = max(dhi,(
double)*(
double*)(voxel));
1469 d255range = 255.0/(dhi - dlo);
1470 if(1) printf(
"nrrd image voxel range hi %lf lo %lf 255range scale factor %lf\n",dhi,dlo,d255range);
1472 tti->texdata = MALLOC(
unsigned char *,(
size_t)nvoxel * 4);
1475 tti->hasAlpha = TRUE;
1479 memset(counts,0,256*
sizeof(
int));
1480 for(i=0;i<nvoxel;i++){
1481 unsigned char *voxel;
1483 unsigned char *rgba = &tti->texdata[i*4];
1487 voxel = &data[i*bsize];
1491 case CDATATYPE_char:
1492 A = (char)(voxel[0]) + 127;
1494 case CDATATYPE_uchar:
1497 case CDATATYPE_short:
1498 A = (
unsigned char) ((*(
short *)voxel) / 255) + 127;
1500 case CDATATYPE_ushort:
1503 unsigned short thisushort;
1504 memcpy(&thisushort,voxel,bsize);
1513 counts[thisushort]++;
1515 A = (
unsigned char) thisushort;
1519 A = (
unsigned char)((*((
long *)voxel))/65536/255 + 127);
1521 case CDATATYPE_uint:
1522 A = (
unsigned char) ((*((
unsigned long *)voxel))/65536/255);
1524 case CDATATYPE_longlong:
1525 A = (
unsigned char) ((*((
long long *)voxel))/65536/65536/255 + 127);
1527 case CDATATYPE_ulonglong:
1528 A = (
unsigned char) ((*((
unsigned long long *)voxel))/65536/65536/255);
1547 case CDATATYPE_char:
1548 A = (
unsigned char)((
int)(voxel[0])) + 127;
1550 case CDATATYPE_uchar:
1553 case CDATATYPE_short:
1554 dtemp = (double)(*(
short *)voxel);
1555 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1557 case CDATATYPE_ushort:
1558 dtemp = (double)(*(
unsigned short *)voxel);
1565 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1570 dtemp = (double)(*(
long *)voxel);
1571 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1573 case CDATATYPE_uint:
1574 dtemp = (double)(*(
unsigned long *)voxel);
1575 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1577 case CDATATYPE_longlong:
1578 dtemp = (double)(*(
long long *)voxel);
1579 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1581 case CDATATYPE_ulonglong:
1582 dtemp = (double)(*(
unsigned long long *)voxel);
1583 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1585 case CDATATYPE_float:
1586 dtemp = (double)(*(
float *)voxel);
1587 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1589 case CDATATYPE_double:
1590 dtemp = (double)(*(
double *)voxel);
1591 A = (
unsigned char)(
unsigned short)(
unsigned int)((dtemp - dlo)*d255range);
1607 if(0)
for(i=0;i<256;i++)
1609 printf(
"counts[%ld]=%ld\n",(
long)i,(
long)counts[i]);
1618#if defined(_ANDROID) || defined(ANDROIDNDK)
1620static unsigned char *flipImageVerticallyB(
unsigned char *input,
int height,
int width,
int bpp) {
1622 unsigned char *sourcerow, *destrow;
1623 unsigned char * blob;
1625 rowcount = width * bpp;
1626 blob = MALLOC(
unsigned char*, height * rowcount);
1627 for(i=0;i<height;i++) {
1628 ii = height - 1 - i;
1629 sourcerow = &input[i*rowcount];
1630 destrow = &blob[ii*rowcount];
1631 memcpy(destrow,sourcerow,rowcount);
1636static unsigned char *flipImageVertically(
unsigned char *input,
int height,
int width) {
1637 return flipImageVerticallyB(input,height,width,4);
1639static unsigned char *expandto4bppfromGray(
unsigned char *input,
int height,
int width,
int bpp) {
1640 int i, j, rowcountin, rowcountout;
1641 unsigned char *sourcerow, *destrow;
1642 unsigned char * blob;
1644 rowcountin = width * bpp;
1645 rowcountout = width * 4;
1646 blob = MALLOCV(height * rowcountout);
1647 for (i = 0; i<height; i++) {
1648 sourcerow = &input[i*rowcountin];
1649 destrow = &blob[i*rowcountout];
1650 for (j = 0; j<width; j++) {
1651 unsigned char *op = &destrow[j * 4];
1652 op[0] = op[1] = op[2] = sourcerow[j*bpp];
1653 op[3] = bpp == 1 ? 255 : sourcerow[j*bpp + 1];
1659static unsigned char *expandto4bppfromRGB(
unsigned char *input,
int height,
int width,
int bpp) {
1660 int i, j, rowcountin, rowcountout;
1661 unsigned char *sourcerow, *destrow;
1662 unsigned char * blob;
1664 rowcountin = width * bpp;
1665 rowcountout = width * 4;
1666 blob = MALLOCV(height * rowcountout);
1667 for (i = 0; i<height; i++) {
1668 sourcerow = &input[i*rowcountin];
1669 destrow = &blob[i*rowcountout];
1670 for(j=0;j<width;j++){
1671 memcpy(&destrow[j*4], &sourcerow[j*bpp], bpp);
1672 destrow[j*4 + 3] = 255;
1678static unsigned char *expandto4bpp(
unsigned char *input,
int height,
int width,
int bpp) {
1679 unsigned char * retval = NULL;
1680 if(bpp == 1 || bpp == 2)
1681 retval = expandto4bppfromGray(input, height, width, bpp);
1683 retval = expandto4bppfromRGB(input, height, width, bpp);
1693static img_lib_t ilib = NULL;
1698 if(!ilib) ierr = img_lib_attach( &ilib );
1699 img.format = IMG_FMT_PKLE_ARGB8888;
1700 img.flags |= IMG_FORMAT;
1701 ierr= img_load_file(ilib, fname, NULL, &img);
1710 tti->texdata = img.access.direct.data;
1712 printf(
"ouch in gdiplus image loader L140 - no image data\n");
1715 int flipvertically = 1;
1717 int i,j,ii,rowcount;
1718 unsigned char *sourcerow, *destrow;
1719 unsigned char * blob;
1720 rowcount = tti->x * 4;
1721 blob = MALLOCV(img.h * rowcount);
1722 for(i=0;i<img.h;i++) {
1723 ii = tti->y - 1 - i;
1724 sourcerow = &tti->texdata[i*rowcount];
1725 destrow = &blob[ii*rowcount];
1726 memcpy(destrow,sourcerow,rowcount);
1728 tti->texdata = blob;
1743char* download_file(
char* filename);
1745int load_file_blob(
const char *filename,
char **blob,
int *len);
1747#if defined(ANDROIDNDK)
1748#define HAVE_LIBJPEG_H 1
1749#ifdef HAVE_LIBJPEG_H
1752struct my_error_mgr {
1753 struct jpeg_error_mgr pub;
1754 jmp_buf setjmp_buffer;
1757typedef struct my_error_mgr * my_error_ptr;
1764my_error_exit(j_common_ptr cinfo)
1767 my_error_ptr myerr = (my_error_ptr)cinfo->err;
1774 longjmp(myerr->setjmp_buffer, 1);
1778#define JPEG_SUCCESS 0
1784 unsigned char *image_data = 0;
1788 struct jpeg_decompress_struct cinfo;
1789 struct my_error_mgr jerr;
1793 unsigned rowcount, columncount;
1799 if ((infile = fopen(filename,
"rb")) == NULL) {
1800 fprintf(stderr,
"can't open %s\n", filename);
1814 cinfo.err = jpeg_std_error(&jerr.pub);
1815 jerr.pub.error_exit = my_error_exit;
1816 if (setjmp(jerr.setjmp_buffer)) {
1818 ConsoleMessage(
"FreeWRL Image problem - could not read %s\n", filename);
1819 jpeg_destroy_compress((j_compress_ptr)&cinfo);
1825 jpeg_create_decompress(&cinfo);
1828 jpeg_stdio_src(&cinfo, infile);
1833 tempInt = jpeg_read_header(&cinfo, TRUE);
1837 (void)jpeg_start_decompress(&cinfo);
1841 row = (JSAMPLE*)MALLOCV(cinfo.output_width *
sizeof(JSAMPLE)*cinfo.output_components);
1843 image_data = (
unsigned char *)MALLOCV(cinfo.output_width *
sizeof(JSAMPLE) * cinfo.output_height * cinfo.output_components);
1845 for (rowcount = 0; rowcount < cinfo.output_height; rowcount++) {
1846 nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
1851 for (columncount = 0; columncount < cinfo.output_width; columncount++) {
1852 for (dp = 0; dp<cinfo.output_components; dp++) {
1853 image_data[(cinfo.output_height - rowcount - 1)
1854 *cinfo.output_width*cinfo.output_components
1855 + columncount* cinfo.output_components + dp]
1856 = row[columncount*cinfo.output_components + dp];
1861 int iret = JPEG_SUCCESS;
1862 if (jpeg_finish_decompress(&cinfo) != TRUE) {
1863 printf(
"warning: jpeg_finish_decompress error\n");
1875 this_tex->x = (int)cinfo.output_width;
1876 this_tex->y = (int)cinfo.output_height;
1877 this_tex->hasAlpha = 0;
1879 int bpp = cinfo.output_components;
1880 this_tex->channels = bpp;
1883 char *data4bpp = expandto4bpp(image_data,this_tex->y,this_tex->x,bpp);
1885 this_tex->frames = 1;
1886 this_tex->texdata = data4bpp;
1887 FREE_IF_NZ(image_data);
1888 this_tex->filename = filename;
1890 jpeg_destroy_decompress(&cinfo);
1893 return JPEG_SUCCESS;
1900#define HAVE_LIBPNG_H 1
1906#define PNG_SUCCESS 0
1909 const png_byte* data;
1910 const png_size_t size;
1914 const DataHandle data;
1919 const png_uint_32 width;
1920 const png_uint_32 height;
1921 const int color_type;
1923static GLenum get_gl_color_format(
const int png_color_format) {
1928 switch (png_color_format) {
1929 case PNG_COLOR_TYPE_GRAY:
1930 return GL_LUMINANCE;
1931 case PNG_COLOR_TYPE_RGB_ALPHA:
1933 case PNG_COLOR_TYPE_GRAY_ALPHA:
1934 return GL_LUMINANCE_ALPHA;
1935 case PNG_COLOR_TYPE_RGB:
1942static PngInfo read_and_update_info(
const png_structp png_ptr,
const png_infop info_ptr)
1944 png_uint_32 width, height;
1945 int bit_depth, color_type;
1947 png_read_info(png_ptr, info_ptr);
1949 png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
1952 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1953 png_set_tRNS_to_alpha(png_ptr);
1956 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1957 png_set_expand_gray_1_2_4_to_8(png_ptr);
1960 if (color_type == PNG_COLOR_TYPE_PALETTE)
1961 png_set_palette_to_rgb(png_ptr);
1965 if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_RGB)
1966 png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
1970 png_set_packing(png_ptr);
1971 else if (bit_depth == 16)
1972 png_set_scale_16(png_ptr);
1974 png_read_update_info(png_ptr, info_ptr);
1977 color_type = png_get_color_type(png_ptr, info_ptr);
1979 return (PngInfo) { width, height, color_type };
1981static DataHandle read_entire_png_image(
1982 const png_structp png_ptr,
1983 const png_infop info_ptr,
1984 const png_uint_32 height)
1986 const png_size_t row_size = png_get_rowbytes(png_ptr, info_ptr);
1987 const int data_length = row_size * height;
1988 assert(row_size > 0);
1990 png_byte* raw_image = malloc(data_length);
1991 assert(raw_image != NULL);
1993 png_byte* row_ptrs[height];
1996 for (i = 0; i < height; i++) {
1997 row_ptrs[i] = raw_image + i * row_size;
2000 png_read_image(png_ptr, &row_ptrs[0]);
2002 return (DataHandle) { raw_image, data_length };
2004static void read_png_data_callback(
2005 png_structp png_ptr, png_byte* raw_data, png_size_t read_length) {
2006 ReadDataHandle* handle = png_get_io_ptr(png_ptr);
2007 const png_byte* png_src = handle->data.data + handle->offset;
2009 memcpy(raw_data, png_src, read_length);
2010 handle->offset += read_length;
2013TACTIC_FROM_FILE = 1,
2014TACTIC_FROM_BLOB = 2,
2020 unsigned char *image_data = 0;
2021 int image_data_isMalloced;
2025 unsigned long image_width = 0;
2026 unsigned long image_height = 0;
2027 unsigned long image_rowbytes = 0;
2028 int image_channels = 0;
2029 int glcolortype = 0;
2030 double display_exponent = 0.0;
2036 tactic= TACTIC_FROM_BLOB;
2039 png_structp png_ptr = png_create_read_struct(
2040 PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
2041 png_infop info_ptr = png_create_info_struct(png_ptr);
2044 if(tactic == TACTIC_FROM_FILE){
2047 fp = fopen(filename,
"rb");
2048 rvt=fread(header, 1, 8, fp);
2049 is_png = !png_sig_cmp(png_data, 0, 8);
2055 fp = fopen(filename,
"rb");
2056 png_init_io(png_ptr, fp);
2057 }
else if(tactic == TACTIC_FROM_BLOB){
2058 if (!load_file_blob(filename, &png_data, &png_data_size)) {
2061 is_png = !png_sig_cmp(png_data, 0, 8);
2066 ReadDataHandle png_data_handle = (ReadDataHandle) { {png_data, png_data_size}, 0 };
2067 png_set_read_fn(png_ptr, &png_data_handle, read_png_data_callback);
2070 if (setjmp(png_jmpbuf(png_ptr)))
2072 png_destroy_read_struct(&png_ptr, &info_ptr,
2074 if (tactic == TACTIC_FROM_FILE) fclose(fp);
2082 const PngInfo png_info = read_and_update_info(png_ptr, info_ptr);
2083 const DataHandle raw_image = read_entire_png_image(
2084 png_ptr, info_ptr, png_info.height);
2086 png_read_end(png_ptr, info_ptr);
2087 this_tex->x = png_info.width;
2088 this_tex->y = png_info.height;
2100 switch (png_info.color_type) {
2101 case PNG_COLOR_TYPE_GRAY: image_channels = 1;
break;
2102 case PNG_COLOR_TYPE_GRAY_ALPHA: image_channels = 2;
break;
2103 case PNG_COLOR_TYPE_RGB: image_channels = 3;
break;
2104 case PNG_COLOR_TYPE_RGB_ALPHA: image_channels = 4;
break;
2108 this_tex->channels = image_channels;
2109 this_tex->hasAlpha = this_tex->channels == 2 || this_tex->channels == 4;
2111 image_data = raw_image.data;
2113 image_data_isMalloced = 0;
2114 if(image_channels < 4){
2115 image_data = expandto4bpp(image_data, this_tex->y, this_tex->x, image_channels);
2116 image_data_isMalloced = 1;
2119 unsigned char *dataflipped = flipImageVerticallyB(image_data, this_tex->y, this_tex->x, bpp);
2120 free(raw_image.data);
2121 if(image_data_isMalloced) free(image_data);
2122 this_tex->frames = 1;
2123 this_tex->texdata = dataflipped;
2124 this_tex->filename = filename;
2125 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2130 if (tactic == TACTIC_FROM_FILE) fclose(fp);
2136#define HAVE_LIBGIF_H 1
2141int getTransparentColor(GifFileType * file)
2145 ExtensionBlock * ext = file->SavedImages[0].ExtensionBlocks;
2147 for (i = 0; i < file->SavedImages[0].ExtensionBlockCount; i++, ext++) {
2149 if (ext->Function == GRAPHICS_EXT_FUNC_CODE) {
2150 if (ext->Bytes[0] & 1)
2151 return ext->Bytes[3];
2161#define GIF_SUCCESS 0
2166 int ErrorCode, alpha, iret;
2168 InterlacedOffset[] = { 0, 4, 2, 1 },
2169 InterlacedJumps[] = { 8, 8, 4, 2 };
2170 ColorMapObject *ColorMap;
2171 GifRowType *ScreenBuffer;
2174 GifFileType *GifFile = DGifOpenFileName(filename, &ErrorCode);
2178 if (GifFile->SHeight == 0 || GifFile->SWidth == 0) {
2182 ErrorCode = DGifSlurp(GifFile);
2183 if(ErrorCode != GIF_OK)
2185 alpha = getTransparentColor(GifFile);
2187 ColorMap = (GifFile->Image.ColorMap
2188 ? GifFile->Image.ColorMap
2189 : GifFile->SColorMap);
2190 if (ColorMap == NULL) {
2194 if(GifFile->ImageCount){
2195 unsigned char *pixel;
2196 int i,j,ipix,icolor;
2198 unsigned char * raw = GifFile->SavedImages[0].RasterBits;
2199 int width = GifFile->SavedImages[0].ImageDesc.Width;
2200 int height = GifFile->SavedImages[0].ImageDesc.Height;
2201 GifColorType *Colors = ColorMap->Colors;
2202 unsigned char *rgba = MALLOCV(width * height * 4);
2203 GifColorType *color;
2205 for(i=0;i<height;i++){
2206 for(j=0;j<width;j++){
2208 pixel = &rgba[ipix*4];
2210 color = &Colors[icolor];
2211 pixel[0] = color->Red;
2212 pixel[1] = color->Green;
2213 pixel[2] = color->Blue;
2214 pixel[3] = icolor == alpha ? 0 : 255;
2217 this_tex->x = width;
2218 this_tex->y = height;
2219 this_tex->hasAlpha = alpha > -1 ? 1 : 0;
2220 this_tex->channels = 3 + this_tex->hasAlpha;
2221 this_tex->frames = 1;
2223 char *dataflipped = flipImageVerticallyB(rgba, this_tex->y, this_tex->x, bpp);
2225 this_tex->texdata = dataflipped;
2226 this_tex->filename = filename;
2248 FILE* fp = fopen(filename,
"rb");
2249 rvt=fread(header,20,1,fp);
2253 if(!strncmp(&header[1],
"PNG",3))
2254 loadImageTexture_png(this_tex, filename);
2256#ifdef HAVE_LIBJPEG_H
2257 if(!strncmp(header,
"ÿØÿ",3))
2258 loadImageTexture_jpeg(this_tex, filename);
2261 if(!strncmp(header,
"GIF",3))
2262 loadImageTexture_gif(this_tex, filename);
2282#if defined(ANDROIDNDK)
2284 char * fname = STRDUP(filename);
2285 imtype = sniffImageFileHeader(fname);
2290 #ifdef HAVE_LIBPNG_H
2291 ret = loadImageTexture_png(this_tex, filename);
2294 case IMAGETYPE_JPEG:
2295 #ifdef HAVE_LIBJPEG_H
2296 ret = loadImageTexture_jpeg(this_tex, filename);
2300 #ifdef HAVE_LIBGIF_H
2301 ret = loadImageTexture_gif(this_tex, filename);
2305 ret = textureIsDDS(this_tex, fname);
break;
2306 case IMAGETYPE_WEB3DIT:
2307 ret = loadImage_web3dit(this_tex,fname);
break;
2308 case IMAGETYPE_NRRD:
2309 ret = loadImage_nrrd(this_tex,fname);
2312 ret = loadImage3DVol(this_tex, fname);
break;
2313 case IMAGETYPE_UNKNOWN:
2349 return this_tex->frames;
2355#if defined(_ANDROID)
2356 unsigned char *image = NULL;
2357 unsigned char *imagePtr;
2361 bool result = FALSE;
2363 if (myFile->fileData == NULL) {
2374 this_tex->texdata = flipImageVertically(myFile->fileData, myFile->imageHeight, myFile->imageWidth);
2376 this_tex->filename = filename;
2377 this_tex->hasAlpha = myFile->imageAlpha;
2378 this_tex->channels = 4;
2379 this_tex->frames = 1;
2380 this_tex->x = myFile->imageWidth;
2381 this_tex->y = myFile->imageHeight;
2384#ifdef FRONTEND_GETS_FILES
2385 close_openned_file(myFile);
2395#if defined (_MSC_VER)
2399 fname = STRDUP(filename);
2400 imtype = sniffImageFileHeader(fname);
2405 case IMAGETYPE_JPEG:
2407 ret = loadImage(this_tex, fname);
2408 #ifndef GL_ES_VERSION_2_0
2409 texture_swap_B_R(this_tex);
2413 if(imtype == IMAGETYPE_JPEG){
2416 nchan = sniffImageChannels_bruteForce(this_tex->texdata, this_tex->x, this_tex->y);
2418 if(nchan > -1) this_tex->channels = nchan;
2422 ret = textureIsDDS(this_tex, fname);
break;
2423 case IMAGETYPE_WEB3DIT:
2424 ret = loadImage_web3dit(this_tex,fname);
break;
2425 case IMAGETYPE_NRRD:
2426 ret = loadImage_nrrd(this_tex,fname);
break;
2428 ret = loadImage3DVol(this_tex, fname);
break;
2429 case IMAGETYPE_UNKNOWN:
2442#if !defined (_MSC_VER) && !defined(_ANDROID) && !defined(ANDROIDNDK)
2445 Imlib_Load_Error error_return;
2449 fname = STRDUP(filename);
2450 imtype = sniffImageFileHeader(fname);
2455 ret = textureIsDDS(this_tex, fname);
break;
2456 case IMAGETYPE_WEB3DIT:
2457 ret = loadImage_web3dit(this_tex,fname);
break;
2458 case IMAGETYPE_NRRD:
2459 ret = loadImage_nrrd(this_tex,fname);
break;
2461 ret = loadImage3DVol(this_tex, fname);
break;
2463 case IMAGETYPE_JPEG:
2465 case IMAGETYPE_UNKNOWN:
2470 image = imlib_load_image_with_error_return(filename,&error_return);
2471 ret = (error_return == 0);
2475 switch(error_return){
2476 case IMLIB_LOAD_ERROR_NONE: es =
"IMLIB_LOAD_ERROR_NONE";
break;
2477 case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST: es =
"IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST";
break;
2478 case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY: es =
"IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY";
break;
2479 case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ: es =
"IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ";
break;
2480 case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT: es =
"IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT";
break;
2481 case IMLIB_LOAD_ERROR_PATH_TOO_LONG: es =
"IMLIB_LOAD_ERROR_PATH_TOO_LONG";
break;
2482 case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT: es =
"IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT";
break;
2483 case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY: es =
"IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY";
break;
2484 case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE: es =
"IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE";
break;
2485 case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS: es =
"IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS";
break;
2486 case IMLIB_LOAD_ERROR_OUT_OF_MEMORY: es =
"IMLIB_LOAD_ERROR_OUT_OF_MEMORY";
break;
2487 case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS: es =
"IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS";
break;
2488 case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE: es =
"IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE";
break;
2489 case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE: es =
"IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE";
break;
2490 case IMLIB_LOAD_ERROR_UNKNOWN:
2492 es =
"IMLIB_LOAD_ERROR_UNKNOWN";
break;
2494 ERROR_MSG(
"imlib load error = %d %s\n",error_return,es);
2495 ERROR_MSG(
"load_texture_from_file: failed to load image: %s\n", filename);
2498 DEBUG_TEX(
"load_texture_from_file: Imlib2 succeeded to load image: %s\n", filename);
2500 imlib_context_set_image(image);
2501 imlib_image_flip_vertical();
2504 this_tex->filename = filename;
2505 this_tex->hasAlpha = (imlib_image_has_alpha() == 1);
2506 this_tex->channels = this_tex->hasAlpha ? 4 : 3;
2507 this_tex->frames = 1;
2508 this_tex->x = imlib_image_get_width();
2509 this_tex->y = imlib_image_get_height();
2511 this_tex->texdata = (
unsigned char *) imlib_image_get_data_for_reading_only();
2515 if(imtype == IMAGETYPE_JPEG)
2518 nchan = sniffImageChannels_bruteForce(this_tex->texdata, this_tex->x, this_tex->y);
2520 if(nchan > -1) this_tex->channels = nchan;
2523 texture_swap_B_R(this_tex);
2548 resource_type_t restype;
2552 DEBUG_TEX(
"textureThread - working on %p (%s)\n"
2553 "which is node %p, nodeType %d status %s, opengltex %u, and frames %d\n",
2554 entry, entry->filename, entry->scenegraphNode, entry->nodeType,
2555 texst(entry->status), entry->OpenGLTexture,
2558 entry->status = TEX_LOADING;
2563 if (!checkNode(entry->scenegraphNode,__FILE__,__LINE__)) {
2564 ConsoleMessage (
"node for texture just deleted...\n");
2569 switch (entry->nodeType) {
2571 case NODE_PixelTexture:
2572 texture_load_from_pixelTexture(entry,(
struct X3D_PixelTexture *)entry->scenegraphNode);
2577 case NODE_PixelTexture3D:
2578 texture_load_from_pixelTexture3D(entry,(
struct X3D_PixelTexture3D *)entry->scenegraphNode);
2583 case NODE_ImageTexture:
2586 restype = resm_image;
2589 case NODE_ImageTexture3D:
2592 restype = resm_image;
2595 case NODE_ComposedTexture3D:
2600 case NODE_MovieTexture:
2603 entry->status = TEX_NEEDSBINDING;
2604 restype = resm_movie;
2607 case NODE_ImageCubeMapTexture:
2610 restype = resm_image;
2614 printf (
"invalid nodetype given to loadTexture, %s is not valid\n",stringNodeType(entry->nodeType));
2617 entry->status = TEX_NOTFOUND;
2622 res = resource_create_multi(url);
2623 res->type=rest_multi;
2624 res->media_type = restype;
2625 resource_identify(parentPath, res);
2626 res->whereToPlaceData = entry;
2627 res->textureNumber = entry->textureNumber;
2628 resitem_enqueue(ml_new(res));
2654static void texture_process_list_item(
s_list_t *item)
2656 bool remove_it = FALSE;
2660 if (!item || !item->elem)
2663 entry = ml_elem(item);
2665 DEBUG_TEX(
"texture_process_list: %s\n", entry->filename);
2669 switch (entry->status) {
2673 if (texture_process_entry(entry)) {
2684 entry->status = TEX_NEEDSBINDING;
2702void threadsafe_enqueue_item_signal(
s_list_t *item,
s_list_t** queue, pthread_mutex_t* queue_lock, pthread_cond_t *queue_nonzero);
2703s_list_t* threadsafe_dequeue_item_wait(
s_list_t** queue, pthread_mutex_t *queue_lock, pthread_cond_t *queue_nonzero, BOOL* wait);
2705void texitem_enqueue(
s_list_t *item){
2710 threadsafe_enqueue_item_signal(item, &p->texture_request_list, &tg->threads.mutex_texture_list, &tg->threads.texture_list_condition);
2717 return threadsafe_dequeue_item_wait(&p->texture_request_list, &tg->threads.mutex_texture_list, &tg->threads.texture_list_condition, &tg->threads.TextureThreadWaiting);
2720static const int tex_command_exit;
2722void texitem_queue_exit(){
2723 texitem_enqueue(ml_new(&tex_command_exit));
2728 texitem_enqueue(ml_new(entry));
2735 textureNumber = res->textureNumber;
2738 entry = getTableIndex(textureNumber);
2740 texitem_enqueue(ml_new(entry));
2748#if !defined(HAVE_PTHREAD_CANCEL)
2749void Texture_thread_exit_handler(
int sig)
2751 ConsoleMessage(
"Texture_thread_exit_handler: No pTheadCancel - textureThread exiting - maybe should cleanup? Should be done but need to check some rainy day");
2758void _textureThread(
void *globalcontext)
2761 tg->threads.loadThread = pthread_self();
2762 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
2770 tg->threads.TextureThreadRunning = TRUE;
2775 s_list_t *item = texitem_dequeue();
2776 elem = ml_elem(item);
2778 if (elem == &tex_command_exit){
2782 if (tg->threads.flushing){
2786 p->TextureParsing = TRUE;
2787 texture_process_list_item(item);
2788 p->TextureParsing = FALSE;
2791 printf(
"Ending texture load thread gracefully\n");
2792 tg->threads.TextureThreadRunning = FALSE;