00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 #ifdef G4VIS_BUILD_OI_DRIVER 00027 00028 /*----------------------------HEPVis----------------------------------------*/ 00029 /* */ 00030 /* Node: SoImageWriter */ 00031 /* Author: Guy Barrand */ 00032 /* */ 00033 /*--------------------------------------------------------------------------*/ 00034 00035 // this : 00036 #include <HEPVis/nodes/SoImageWriter.h> 00037 00038 #include <Inventor/errors/SoDebugError.h> 00039 #include <Inventor/elements/SoViewportRegionElement.h> 00040 #include <Inventor/actions/SoGLRenderAction.h> 00041 00042 #include <HEPVis/SbGL.h> 00043 #include <HEPVis/SbPainterPS.h> 00044 //#include <HEPVis/SbGIF.h> 00045 00046 #include <stdlib.h> 00047 00048 typedef struct { 00049 unsigned char red; 00050 unsigned char green; 00051 unsigned char blue; 00052 } Pixel; 00053 typedef unsigned char Uchar; 00054 00055 //static void getImagePixels(int,int,float*,int&, 00056 // Uchar*&,Uchar*&,Uchar*&,Uchar*&); 00057 00058 static int sWidth = 0; 00059 static int sHeight = 0; 00060 static float* sImage = 0; 00061 static int getRGB(unsigned int,unsigned int,double&,double&,double&); 00062 00063 SO_NODE_SOURCE(SoImageWriter) 00065 void SoImageWriter::initClass ( 00066 ) 00069 { 00070 SO_NODE_INIT_CLASS(SoImageWriter,SoNode,"Node"); 00071 } 00073 SoImageWriter::SoImageWriter( 00074 ) 00075 :fEnabled(FALSE) 00076 ,fStatus(FALSE) 00079 { 00080 SO_NODE_CONSTRUCTOR(SoImageWriter); 00081 //SO_NODE_ADD_FIELD(format,(POST_SCRIPT)); 00082 SO_NODE_ADD_FIELD(fileName,("out.ps")); 00083 00084 //SO_NODE_DEFINE_ENUM_VALUE(Format,POST_SCRIPT); 00085 //SO_NODE_DEFINE_ENUM_VALUE(Format,GIF); 00086 00087 //SO_NODE_SET_SF_ENUM_TYPE(format,Format); 00088 } 00090 SoImageWriter::~SoImageWriter ( 00091 ) 00094 { 00095 } 00097 void SoImageWriter::enable( 00098 ) 00101 { 00102 fEnabled = TRUE; 00103 } 00105 void SoImageWriter::disable( 00106 ) 00109 { 00110 fEnabled = FALSE; 00111 } 00113 SbBool SoImageWriter::getStatus( 00114 ) const 00117 { 00118 return fStatus; 00119 } 00121 void SoImageWriter::GLRender( 00122 SoGLRenderAction* aAction 00123 ) 00126 { 00127 fStatus = FALSE; 00128 //printf("debug : SoImageWriter::GLRender : enabled : %d\n",fEnabled); 00129 if(!fEnabled) return; 00130 SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState()); 00131 const SbVec2s& win = vpr.getWindowSize(); 00132 int w = win[0]; 00133 int h = win[1]; 00134 if((w*h)<=0) { 00135 SoDebugError::postInfo("SoImageWriter::GLRender","null area window !"); 00136 return; 00137 } 00138 00139 int x = 0; 00140 int y = 0; 00141 int s = 3 * w * h; 00142 float* image = new float[s]; 00143 if(!image) return; 00144 00145 //printf("debug : SoImageWriter::GLRender : %d %d %d %d\n",x,y,w,h); 00146 00147 //glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BYTE,image); Don't work ! 00148 glReadPixels(x,y,w,h,GL_RGB,GL_FLOAT,image); 00149 00150 //Format fm = (Format)format.getValue(); 00151 //if(fm==GIF) { 00152 /* 00153 FILE* file = fopen(fileName.getValue().getString(),"wb"); 00154 if(!file) { 00155 SoDebugError::postInfo("SoImageWriter::GLRender", 00156 "can't open file \"%s\".",fileName.getValue().getString()); 00157 } else { 00158 int coln; 00159 Uchar* rs; 00160 Uchar* gs; 00161 Uchar* bs; 00162 Uchar* data; 00163 getImagePixels(w,h,image,coln,rs,gs,bs,data); 00164 00165 SbGIF::putBytesInStream(file,data,w,h,coln,rs,gs,bs); 00166 00167 delete [] data; 00168 00169 if(rs) free(rs); 00170 if(gs) free(gs); 00171 if(bs) free(bs); 00172 00173 fclose(file); 00174 00175 fStatus = TRUE; 00176 } 00177 } else { 00178 */ 00179 00180 SbPainterPS painterPS; 00181 painterPS.openFileForWriting(fileName.getValue().getString()); 00182 if(!painterPS.getStream()) { 00183 SoDebugError::postInfo("SoImageWriter::GLRender", 00184 "can't open file \"%s\".",fileName.getValue().getString()); 00185 } else { 00186 painterPS.setWindowSize(w,h); 00187 //painterPS.setBitsPerPixel(8); 00188 painterPS.setBitsPerPixel(4); 00189 painterPS.beginTraversal(); 00190 painterPS.clearColorBuffer(1.,1.,1.); 00191 00192 sWidth = w; 00193 sHeight = h; 00194 sImage = image; 00195 painterPS.putImageInStream((unsigned int)w,(unsigned int)h,getRGB); 00196 00197 painterPS.endTraversal(); 00198 00199 painterPS.closeStream(); 00200 00201 fStatus = TRUE; 00202 } 00203 //} 00204 delete [] image; 00205 00206 } 00207 /* 00209 void getImagePixels ( 00210 int aWidth 00211 ,int aHeight 00212 ,float* aImage 00213 ,int& aColorn 00214 ,Uchar*& aReds 00215 ,Uchar*& aGreens 00216 ,Uchar*& aBlues 00217 ,Uchar*& aData 00218 ) 00221 { 00222 aColorn = 0; 00223 aReds = 0; 00224 aGreens = 0; 00225 aBlues = 0; 00226 aData = 0; 00227 if( (aWidth * aHeight) <=0) return; 00228 int size = 256; 00229 Uchar* rs = (Uchar*)malloc(size * sizeof(Uchar)); 00230 Uchar* gs = (Uchar*)malloc(size * sizeof(Uchar)); 00231 Uchar* bs = (Uchar*)malloc(size * sizeof(Uchar)); 00232 Uchar* data = new Uchar[aWidth * aHeight]; 00233 if( !rs || !gs || !bs || !data ) { 00234 if(rs) free(rs); 00235 if(gs) free(gs); 00236 if(bs) free(bs); 00237 delete [] data; 00238 return; 00239 } 00240 int pixeln = 0; 00241 int row,col; 00242 Uchar red,green,blue; 00243 Uchar ored = 0,ogreen = 0,oblue = 0; 00244 float* pimag = aImage; 00245 Uchar* pdata = 0; 00246 Uchar index = 0; 00247 int status = 0; 00248 for(row=0;row<aHeight;row++) { 00249 pdata = data + (aHeight - 1 - row) * aWidth; 00250 for(col=0;col<aWidth;col++){ 00251 red = (Uchar)(255 * (*pimag));pimag++; 00252 green = (Uchar)(255 * (*pimag));pimag++; 00253 blue = (Uchar)(255 * (*pimag));pimag++; 00254 //printf("debug : %d %d : %d %d %d\n",row,col,red,green,blue); 00255 if( (pixeln==0) || (red!=ored) || (green!=ogreen) || (blue!=oblue) ){ 00256 // Search exact color : 00257 int found = 0; 00258 for(int count=0;count<pixeln;count++){ 00259 if( (red==rs[count]) && (green==gs[count]) && (blue==bs[count]) ){ 00260 found = 1; 00261 index = count; 00262 break; 00263 } 00264 } 00265 if(found==0){ 00266 if(pixeln>=256) { 00267 // We can't store more than 256 on an Uchar. 00268 // Search closest color : 00269 int dr,dg,db; 00270 int PRECISION = 20; 00271 int closest = 0; 00272 for(int count=0;count<pixeln;count++){ 00273 dr = red - rs[count];dr = dr<0 ? -dr : dr; 00274 dg = green - gs[count];dg = dg<0 ? -dg : dg; 00275 db = blue - bs[count];db = db<0 ? -db : db; 00276 if( (dr<=PRECISION) && (dg<=PRECISION) && (db<=PRECISION) ){ 00277 closest = 1; 00278 index = count; 00279 break; 00280 } 00281 } 00282 if(closest==0) { 00283 index = 0; 00284 status = 1; 00285 } 00286 } else { 00287 if(pixeln>=size){ 00288 size += 256; 00289 rs = (Uchar*)realloc(rs,size * sizeof(Uchar)); 00290 gs = (Uchar*)realloc(gs,size * sizeof(Uchar)); 00291 bs = (Uchar*)realloc(bs,size * sizeof(Uchar)); 00292 if( !rs || !gs || !bs ) { 00293 if(rs) free(rs); 00294 if(gs) free(gs); 00295 if(bs) free(bs); 00296 delete [] data; 00297 return; 00298 } 00299 } 00300 //printf("debug : SoImageWriter pixeln %d : %d %d %d\n", 00301 // pixeln,red,green,blue); 00302 rs[pixeln] = red; 00303 gs[pixeln] = green; 00304 bs[pixeln] = blue; 00305 index = pixeln; 00306 pixeln++; 00307 } 00308 } 00309 } 00310 *pdata = index; 00311 pdata++; 00312 ored = red; 00313 ogreen = green; 00314 oblue = blue; 00315 } 00316 } 00317 if(status==1) 00318 printf("SoImageWriter : more than 256 colors in picture ; some colors approximated.\n"); 00319 aColorn = pixeln; 00320 aReds = rs; 00321 aGreens = gs; 00322 aBlues = bs; 00323 aData = data; 00324 } 00325 */ 00327 int getRGB( 00328 unsigned int aX 00329 ,unsigned int aY 00330 ,double& aRed 00331 ,double& aGreen 00332 ,double& aBlue 00333 ) 00335 // OpenGL image is from down to up. 00336 // PS image is up to down. 00338 { 00339 float* pimag = sImage + 3 * (sWidth * (sHeight - 1 - aY) + aX); 00340 aRed = *pimag;pimag++; 00341 aGreen = *pimag;pimag++; 00342 aBlue = *pimag;pimag++; 00343 return 1; 00344 } 00345 00346 #endif