00001 #include "../header/Texture.h"
00002
00003
00004
00005 Texture::Texture()
00006 {
00007 picture = NULL;
00008 N_x=-1;
00009 N_y=-1;
00010 }
00011
00012 Texture::~Texture()
00013 {
00014 destroy();
00015 }
00016
00017 int Texture::destroy()
00018 {
00019 if(picture!=NULL)
00020 {
00021 delete[] picture;
00022 picture = NULL;
00023 }
00024
00025 N_x=-1;
00026 N_y=-1;
00027
00028 return 0;
00029 }
00030
00031
00032 int Texture::load_picture(const char* file_name)
00033 {
00034 int ok=0;
00035
00036
00037 int file_type = get_file_type(file_name);
00038 ok+=destroy();
00039
00040 switch(file_type)
00041 {
00042 case JPG_FORMAT:
00043 cout<<"JPG texture detected"<<endl;
00044 load_jpg_picture(file_name);
00045 cout<<"JPG texture loaded [OK]"<<endl;
00046 break;
00047 case PNG_FORMAT:
00048 cout<<"PNG texture detected"<<endl;
00049 load_png_picture(file_name);
00050 cout<<"PNG texture loaded [OK]"<<endl;
00051 break;
00052 case NO_FORMAT:
00053 cout<<"WARNING NO known format for "<<file_name<<endl;
00054 }
00055
00056
00057 return ok;
00058 }
00059
00060
00061 int Texture::load_jpg_picture(const char* file_name)
00062 {
00063 int ok=0;
00064
00065 struct jpeg_decompress_struct cinfo;
00066 struct jpeg_error_mgr jerr;
00067 FILE *file;
00068
00069
00070 memset(&cinfo, 0, sizeof(cinfo));
00071 cinfo.err = jpeg_std_error(&jerr);
00072
00073 if ((file=fopen(file_name,"rb"))==NULL)
00074 {
00075 fprintf(stderr,"Error : opening file %s\n",file_name);
00076 exit(1);
00077 }
00078
00079
00080 jpeg_create_decompress(&cinfo);
00081 jpeg_stdio_src(&cinfo, file);
00082 jpeg_read_header(&cinfo, TRUE);
00083 jpeg_start_decompress(&cinfo);
00084
00085
00086 N_x = cinfo.image_width;
00087 N_y = cinfo.image_height;
00088 depth = cinfo.num_components;
00089
00090
00091
00092
00093
00094 picture = new unsigned char[N_x*N_y*depth];
00095 if(picture==NULL)
00096 {
00097 cout<<"ERROR allocating picture in jpg reader\n";
00098 exit(-1);
00099 }
00100
00101
00102 JSAMPROW j;
00103 for (int k = 0; k < N_y; ++k)
00104 {
00105 j = (picture + (k * N_x * depth));
00106 jpeg_read_scanlines (&cinfo, &j, 1);
00107 }
00108
00109
00110 jpeg_finish_decompress(&cinfo);
00111 jpeg_destroy_decompress(&cinfo);
00112
00113
00114 return ok;
00115 }
00116
00117
00118
00119 int Texture::load_png_picture(const char* file_name)
00120 {
00121
00122
00123 int i;
00124 int bpp;
00125 int num_passes;
00126 int pass;
00127 FILE *fp;
00128 png_structp pp;
00129 png_infop info;
00130 unsigned char **pixels;
00131
00132 pp = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00133 info = png_create_info_struct (pp);
00134
00135 if(!pp || !info)
00136 {
00137 printf("out of memory read png\n");
00138 exit(-1);
00139 }
00140
00141 if (setjmp (pp->jmpbuf))
00142 {
00143 printf ("Error while reading '%s'. File corrupted?\n", file_name);
00144 return -1;
00145 }
00146
00147
00148 fp = fopen (file_name, "r");
00149 if (fp == NULL)
00150 {
00151 printf ("Could not open '%s' for reading: %s\n", file_name, strerror (errno));
00152 return -1;
00153 }
00154 png_init_io (pp, fp);
00155 png_read_info (pp, info);
00156
00157 if (info->bit_depth == 16)
00158 png_set_strip_16 (pp);
00159
00160 if (info->color_type == PNG_COLOR_TYPE_GRAY && info->bit_depth < 8)
00161 png_set_expand (pp);
00162
00163
00164
00165 if (info->valid & PNG_INFO_tRNS)
00166 png_set_expand (pp);
00167
00168
00169
00170
00171
00172
00173 num_passes = png_set_interlace_handling (pp);
00174
00175
00176 png_read_update_info (pp, info);
00177
00178
00179
00180 switch (info->color_type)
00181 {
00182 case PNG_COLOR_TYPE_RGB:
00183 bpp = 3;
00184 break;
00185
00186 case PNG_COLOR_TYPE_RGB_ALPHA:
00187 bpp = 4;
00188 break;
00189
00190 case PNG_COLOR_TYPE_GRAY:
00191 bpp = 1;
00192 break;
00193
00194 case PNG_COLOR_TYPE_GRAY_ALPHA:
00195 bpp = 2;
00196 break;
00197
00198 default:
00199 printf ("Unknown color model in PNG file '%s'.\n", file_name);
00200 return -1;
00201 }
00202
00203 N_x = info->width;
00204 N_y = info->height;
00205
00206 picture = (unsigned char*)malloc(bpp*N_x*N_y*sizeof(unsigned char));
00207
00208
00209
00210
00211 pixels = (unsigned char**)malloc (sizeof (unsigned char *) * info->height);
00212
00213 for (i = 0; i < N_y; i++)
00214 pixels[i] = picture + info->width * info->channels * i;
00215
00216 for (pass = 0; pass < num_passes; pass++)
00217 png_read_rows (pp, pixels, NULL, N_y);
00218
00219 png_read_end (pp, info);
00220
00221 png_destroy_read_struct (&pp, &info, NULL);
00222
00223 free (pixels);
00224 free (pp);
00225 free (info);
00226
00227
00228 fclose (fp);
00229
00230
00231
00232 return 0;
00233 }
00234
00235
00236
00237 int Texture::export_ppm(const char* _file_name)
00238 {
00239 int ok=0;
00240 char file_name[100];
00241
00242
00243
00244 FILE *fid_file;
00245
00246
00247
00248 if(picture==NULL)
00249 exit(-1);
00250
00251 strcpy(file_name,_file_name);
00252 strcat(file_name,".ppm");
00253
00254 fid_file = fopen(file_name,"w");
00255 if(fid_file==NULL)
00256 {
00257 cout<<"ERROR CANNOT CREATE "<<file_name<<"\n";
00258 return (-1);
00259 }
00260
00261 fprintf(fid_file,"P3\n");
00262 fprintf(fid_file,"# %s.ppm\n",file_name);
00263 fprintf(fid_file,"%d %d\n",N_x,N_y);
00264 fprintf(fid_file,"255\n");
00265
00266 int k;
00267 for(k=0;k<N_x*N_y;k++)
00268 fprintf(fid_file,"%d \n%d \n%d \n",picture[4*k],picture[4*k+1],picture[4*k+2]);
00269
00270 ok+=fclose(fid_file);
00271
00272 return ok;
00273 }
00274
00275 int Texture::get_Nx()
00276 {
00277 return N_x;
00278 }
00279 int Texture::get_Ny()
00280 {
00281 return N_y;
00282 }
00283 int Texture::get_nearest_texel(float s_1,float s_2,float *texel)
00284 {
00285 int ok=0;
00286 int us_1=0,us_2=0;
00287 int k_texture=0;
00288 int k_dim=0;
00289
00290 if(picture==NULL)
00291 exit(-1);
00292
00293
00294 us_1 = (int)(fabs(s_1*N_x+0.5))%N_x;
00295 us_2 = (int)(fabs(s_2*N_y+0.5))%N_y;
00296
00297 k_texture = 4*(us_1+us_2*N_x);
00298
00299
00300 for(k_dim=0;k_dim<3;k_dim++)
00301 {
00302 texel[k_dim] = (float)(picture[k_texture+k_dim])/256;
00303 }
00304
00305 return ok;
00306 }
00307
00308
00309 int Texture::get_linear_texel(float s_1,float s_2,float *texel)
00310 {
00311 int ok=0;
00312
00313 float us_1=0.0,us_2=0.0;
00314 int k_1=0,k_2=0;
00315
00316 us_1 = s_1*N_x;
00317 us_2 = s_2*N_y;
00318
00319 k_1 = (int)us_1;
00320 k_2 = (int)us_2;
00321
00322
00323 float t_x = (us_1-k_1);
00324 float t_y = (us_2-k_2);
00325
00326
00327
00328 if(picture==NULL)
00329 {
00330 cout<<"ERROR NO PICTURE in texture interpolation\n";
00331 exit(-1);
00332 }
00333
00334 int k_10=k_1,k_11=k_1+1;
00335 int k_20=k_2,k_21=k_2+1;
00336
00337
00338 if(k_11>=N_x)
00339 k_11=k_10;
00340 if(k_21>=N_y)
00341 k_21=k_20;
00342
00343 int X00 = k_10 + k_20*N_x;
00344 int X01 = k_11 + k_20*N_x;
00345 int X10 = k_10 + k_21*N_x;
00346 int X11 = k_11 + k_21*N_x;
00347
00348
00349 int k_dim=0;
00350
00351 for(k_dim=0;k_dim<3;k_dim++)
00352 {
00353 texel[k_dim] =
00354 t_x * t_y * (float)picture[4*X11+k_dim]+
00355 (1-t_x) * t_y * (float)picture[4*X10+k_dim]+
00356 t_x * (1-t_y) * (float)picture[4*X01+k_dim]+
00357 (1-t_x) * (1-t_y) * (float)picture[4*X00+k_dim];
00358 }
00359
00360
00361
00362 return ok;
00363 }
00364
00365
00366 unsigned char* Texture::get_data()
00367 {
00368 return picture;
00369 }
00370
00371
00372 int Texture::get_file_type(const char* filename)
00373 {
00374 int file_type = NO_FORMAT;
00375 char *buffer = NULL;
00376
00377
00378 buffer = strrchr(filename,'.');
00379
00380 if(strcmp(buffer+1,"jpg")==0 || strcmp(buffer+1,"jpeg")==0)
00381 file_type = JPG_FORMAT;
00382 if(strcmp(buffer+1,"png")==0)
00383 file_type = PNG_FORMAT;
00384
00385 return file_type;
00386 }
00387
00388 int Texture::get_depth()
00389 {
00390 return depth;
00391 }