Texture.cpp

Go to the documentation of this file.
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   //read header
00080   jpeg_create_decompress(&cinfo);
00081   jpeg_stdio_src(&cinfo, file);
00082   jpeg_read_header(&cinfo, TRUE);
00083   jpeg_start_decompress(&cinfo);
00084 
00085   //size
00086   N_x = cinfo.image_width;
00087   N_y = cinfo.image_height;
00088   depth = cinfo.num_components;
00089 
00090 
00091 
00092   //  GLubyte *texels = new GLubyte[N_x*N_y*depth];
00093   //allocate
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   //process data
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   //end
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   //TOOK from David
00122 
00123   int             i;            /* Looping var */
00124   int             bpp;          /* Bytes per pixel */
00125   int             num_passes;   /* Number of interlace passes in file */
00126   int             pass;         /* Current pass in file */
00127   FILE           *fp;           /* File pointer */
00128   png_structp     pp;           /* PNG read pointer */
00129   png_infop       info;         /* PNG info pointers */
00130   unsigned char **pixels;       /* Pixel rows */
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   /* Open the file and initialize the PNG read "engine"...  */
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   /* Expand G+tRNS to GA, RGB+tRNS to RGBA */
00164 
00165   if (info->valid & PNG_INFO_tRNS)
00166     png_set_expand (pp);
00167 
00168   /*
00169    * Turn on interlace handling... libpng returns just 1 (ie single pass)
00170    * if the image is not interlaced
00171    */
00172 
00173   num_passes = png_set_interlace_handling (pp);
00174 
00175   /* Update the info structures after the transformations take effect */
00176   png_read_update_info (pp, info);
00177 
00178 
00179 
00180   switch (info->color_type)
00181     {
00182     case PNG_COLOR_TYPE_RGB:           /* RGB */
00183       bpp = 3;
00184       break;
00185 
00186     case PNG_COLOR_TYPE_RGB_ALPHA:     /* RGBA */
00187       bpp = 4;
00188       break;
00189 
00190     case PNG_COLOR_TYPE_GRAY:          /* Grayscale */
00191       bpp = 1;
00192       break;
00193 
00194     case PNG_COLOR_TYPE_GRAY_ALPHA:    /* Grayscale + alpha */
00195       bpp = 2;
00196       break;
00197 
00198     default:                   /* Aie! Unknown type */
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   //  picture = new unsigned char[bpp*N_x*N_y];
00208 
00209 
00210   /* png decodes by row... */
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   //export in ppm
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");//magic number
00262   fprintf(fid_file,"# %s.ppm\n",file_name);//name of the file in comment
00263   fprintf(fid_file,"%d %d\n",N_x,N_y);//size of the file
00264   fprintf(fid_file,"255\n");//max value
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   //nearest
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   //linear interpolant
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   //protection on boundaries
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   //get last dot and return extension
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 }

Generated on Mon Mar 30 16:55:54 2009 by  doxygen 1.5.6