inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/ivrgb
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_ivrgb
00005 #define inlib_ivrgb
00006 
00007 // read an "inventor rgb" image file.
00008 // See SoOffscreenRendererP::writeToRGB.
00009 
00010 #include <cstdio> //FILE
00011 
00012 #include <cstring> //memset,memcpy,strcpy
00013 
00014 //#define INLIB_IVRGB_DEBUG
00015 
00016 namespace inlib {
00017 namespace ivrgb {
00018 
00019 inline bool write_short(FILE* a_file,unsigned short a_val){
00020   unsigned char b[2];
00021   b[0] = (unsigned char)(a_val >> 8);
00022   b[1] = (unsigned char)(a_val & 0xff);
00023   if(::fwrite(b,2,1,a_file)!=1) {
00024 #ifdef INLIB_IVRGB_DEBUG
00025     ::printf("debug : inlib::ivrgb::write_short : failed\n");
00026 #endif
00027     return false;
00028   }
00029   return true;
00030 }
00031 
00032 bool write_file(FILE* a_file,
00033                 unsigned char* a_buffer,
00034                 unsigned int a_w,unsigned int a_h,unsigned int a_bpp) {
00035 
00036   if(!write_short(a_file,0x01da)) return false;
00037   if(!write_short(a_file,0x0001)) return false;
00038 
00039   unsigned int nrcomponents = a_bpp;
00040   if(!write_short(a_file,0x0003)) return false;
00041 
00042   if(!write_short(a_file,(unsigned short)a_w)) return false;
00043   if(!write_short(a_file,(unsigned short)a_h)) return false;
00044   if(!write_short(a_file,(unsigned short)nrcomponents)) return false;
00045 
00046   unsigned char buf[500];
00047   ::memset(buf,0,500);
00048   buf[7] = 255; // set maximum pixel value to 255
00049   ::strcpy((char*)buf+8,"http://www.coin3d.org");
00050   if(::fwrite(buf,1,500,a_file)!=500) {
00051 #ifdef INLIB_IVRGB_DEBUG
00052     ::printf("debug : inlib::ivrgb::write_file : write 500 failed\n");
00053 #endif
00054     return false;
00055   }
00056 
00057   unsigned char* line = new unsigned char[a_w];
00058 
00059   for (unsigned int c = 0; c < nrcomponents; c++) {
00060     for (unsigned int y = 0; y < a_h; y++) {
00061       for (unsigned int x = 0; x < a_w; x++) {
00062         line[x] = a_buffer[(x + y * a_w) * nrcomponents + c];
00063       }
00064       if(::fwrite(line,1,a_w,a_file)!=a_w) {
00065 #ifdef INLIB_IVRGB_DEBUG
00066         ::printf("debug : inlib::ivrgb::write_file : write line %d %d failed.\n",y,c);
00067 #endif
00068         delete [] line;
00069         return false;
00070       }
00071     }
00072   }
00073 
00074   delete [] line;
00075   return true;
00076 }
00077 
00078 inline bool read_short(FILE* a_file,unsigned short& a_val) {
00079   unsigned char b[2];
00080   if(::fread(b,2,1,a_file)!=1) {
00081 #ifdef INLIB_IVRGB_DEBUG
00082     ::printf("debug : inlib::ivrgb::read_short : failed\n");
00083 #endif
00084     a_val = 0;return false;
00085   }
00086   a_val = b[1];
00087   a_val += b[0] <<8;
00088   //::printf("debug : read_short %d %x : %d %d\n",a_val,a_val,b[0],b[1]);
00089   return true;
00090 }
00091 
00092 inline unsigned char* read_file(FILE* a_file,unsigned int& a_w,unsigned int& a_h,unsigned int& a_bpp) {
00093   // the returned buffer must be delete with "delete []".
00094   unsigned short imagic;
00095   if(!read_short(a_file,imagic)) {a_w = a_h = 0;a_bpp=0;return 0;}
00096   if(imagic!=0x01da) {
00097 #ifdef INLIB_IVRGB_DEBUG
00098     ::printf("debug : inlib::ivrgb::read_file : bad magic\n");
00099 #endif
00100     a_w = a_h = 0;a_bpp=0;return 0;
00101   }
00102   unsigned short raw;
00103   if(!read_short(a_file,raw)) {a_w = a_h = 0;a_bpp=0;return 0;}
00104   if(raw!=0x0001) {
00105 #ifdef INLIB_IVRGB_DEBUG
00106     ::printf("debug : inlib::ivrgb::read_file : bad raw\n");
00107 #endif
00108     a_w = a_h = 0;a_bpp=0;return 0;
00109   }
00110 
00111   unsigned short dim;
00112   if(!read_short(a_file,dim)) {a_w = a_h = 0;a_bpp=0;return 0;}
00113   //if((dim!=0x0002)&&(dim!=0x0003)) {a_w = a_h = 0;a_bpp=0;return 0;}
00114   if(dim!=0x0003) {
00115 #ifdef INLIB_IVRGB_DEBUG
00116     ::printf("debug : inlib::ivrgb::read_file : bad dim\n");
00117 #endif
00118     a_w = a_h = 0;a_bpp=0;return 0;
00119   }
00120 
00121   unsigned short w,h,nrcomponents;
00122   if(!read_short(a_file,w)) {a_w = a_h = 0;a_bpp=0;return 0;}
00123   if(!read_short(a_file,h)) {a_w = a_h = 0;a_bpp=0;return 0;}
00124   if(!read_short(a_file,nrcomponents)) {a_w = a_h = 0;a_bpp=0;return 0;}
00125 
00126 #ifdef INLIB_IVRGB_DEBUG
00127   ::printf("debug : inlib::ivrgb::read_file : w %d h %d nrc %d\n",
00128     w,h,nrcomponents);
00129 #endif
00130 
00131   unsigned char buf[500];
00132   if(::fread(buf,1,500,a_file)!=500) {
00133 #ifdef INLIB_IVRGB_DEBUG
00134     ::printf("debug : inlib::ivrgb::read_file : read 500 header failed\n");
00135 #endif
00136     a_bpp = a_w = a_h = 0;
00137     return 0;
00138   }
00139 
00140   unsigned char* b = new unsigned char[w*h*nrcomponents];
00141   if(!b) {
00142 #ifdef INLIB_IVRGB_DEBUG
00143     ::printf("debug : inlib::ivrgb::read_file : can't alloc mem %d\n",
00144       w*h*nrcomponents);
00145 #endif
00146     a_bpp = a_w = a_h = 0;
00147     return 0;
00148   }
00149 
00150   unsigned char* line = new unsigned char[w];
00151   if(!line) {
00152     delete [] b;
00153     a_bpp = a_w = a_h = 0;
00154     return 0;
00155   }
00156 
00157   for (unsigned int c = 0; c < nrcomponents; c++) {
00158     for (unsigned int y = 0; y < h; y++) {
00159       if(::fread(line,1,w,a_file)!=w) {
00160 #ifdef INLIB_IVRGB_DEBUG
00161         ::printf("debug : inlib::ivrgb::read_file : read line %d %d failed.\n",y,c);
00162 #endif
00163         delete [] line;
00164         delete [] b;
00165         a_bpp = a_w = a_h = 0;
00166         return 0;
00167       }
00168       for (unsigned int x = 0; x < w; x++) {
00169         b[(x + y * w) * nrcomponents + c] = line[x];
00170       }
00171     }
00172   }
00173 
00174   delete [] line;
00175   a_w = w;
00176   a_h = h;
00177   a_bpp = nrcomponents;
00178   return b;
00179 }
00180 
00181 }}
00182 
00183 #include <string>
00184 #include <ostream>
00185 
00186 namespace inlib {
00187 namespace ivrgb {
00188 
00189 inline bool is(const std::string& a_file){
00190   FILE* file = ::fopen(a_file.c_str(),"rb");
00191   if(!file) return false; //if file does not exist, then it is not a ivrgb !
00192   unsigned short imagic;
00193   if(!read_short(file,imagic)) {::fclose(file);return false;}
00194   ::fclose(file);
00195   if(imagic!=0x01da) return false;
00196   return true;
00197 }
00198 
00199 inline unsigned char* read(std::ostream& a_out,const std::string& a_file,unsigned int& a_width,unsigned int& a_height,unsigned int& a_bpp) {
00200   if(!is(a_file)) {
00201     a_out << "inlib::ivrgb::read :"
00202           << " file " << a_file << " is not an inventor rgb image file."
00203           << std::endl;
00204     a_width = 0;
00205     a_height = 0;
00206     a_bpp = 0;
00207     return 0;
00208   } 
00209 
00210   FILE* file = ::fopen(a_file.c_str(),"rb");
00211   if(!file) {
00212     a_out << "inlib::ivrgb::read :"
00213           << " can't open " << a_file
00214           << std::endl;
00215     a_width = 0;
00216     a_height = 0;
00217     a_bpp = 0;
00218     return 0;
00219   }
00220 
00221   unsigned int w,h,bpp;
00222   unsigned char* buffer = read_file(file,w,h,bpp);
00223 
00224   ::fclose(file);
00225 
00226   if(!buffer) {
00227     a_out << "inlib::ivrgb::read :"
00228               << " problem reading " << a_file
00229               << std::endl;
00230     a_width = 0;
00231     a_height = 0;
00232     a_bpp = 0;
00233     return 0;
00234   }
00235 
00236   a_width = w;
00237   a_height = h;
00238   a_bpp = bpp;
00239   return buffer;  
00240 }
00241 
00242 
00243 }}
00244 
00245 #include "image"
00246 #include <vector>
00247 
00248 namespace inlib {
00249 namespace ivrgb {
00250 
00251 inline bool concatenate(std::ostream& a_out,
00252                         const std::vector<std::string>& a_files,
00253                         unsigned int a_cols,unsigned int a_rows,
00254                         unsigned int a_bw,unsigned int a_bh,
00255                         unsigned char a_bc,
00256                         const std::string& a_file) {
00257   unsigned int wa,ha,bppa;
00258   unsigned char* ba = 
00259     image::concatenate(a_out,a_files,a_cols,a_rows,
00260                        a_bw,a_bh,a_bc,
00261                        read,wa,ha,bppa);
00262   if(!ba) {
00263     a_out << "inlib::ivrgb::concatenate :"
00264           << " failed to concatenate all files."
00265           << std::endl;
00266     delete [] ba;
00267     return false;
00268   } 
00269 
00270   FILE* file = ::fopen(a_file.c_str(),"wb");
00271   if(!file) {
00272     a_out << "inlib::ivrgb::concatenate :"
00273           << " can't open " << file << " for writing."
00274           << std::endl;
00275     delete [] ba;
00276     return false;
00277   }
00278 
00279 #ifdef INLIB_IVRGB_DEBUG
00280   ::printf("debug : inlib::ivrgb::concatenate : %d %d\n",wa,ha);
00281 #endif
00282 
00283   if(!write_file(file,ba,wa,ha,bppa)) {
00284     a_out << "inlib::ivrgb::concatenate :"
00285           << " can't write " << a_file 
00286           << " w " << wa
00287           << " h " << ha
00288           << "."
00289           << std::endl;
00290     delete [] ba;
00291     ::fclose(file);
00292     return false;
00293   }
00294 
00295   delete [] ba;
00296   ::fclose(file);
00297   return true;
00298 }
00299 
00300 }}
00301 
00302 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines