inlib
1.2.0
|
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