Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SoImageWriter.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 #ifdef G4VIS_BUILD_OI_DRIVER
27 
28 /*----------------------------HEPVis----------------------------------------*/
29 /* */
30 /* Node: SoImageWriter */
31 /* Author: Guy Barrand */
32 /* */
33 /*--------------------------------------------------------------------------*/
34 
35 // this :
37 
38 #include <Inventor/errors/SoDebugError.h>
39 #include <Inventor/elements/SoViewportRegionElement.h>
40 #include <Inventor/actions/SoGLRenderAction.h>
41 
42 #include <HEPVis/SbGL.h>
43 #include <HEPVis/SbPainterPS.h>
44 //#include <HEPVis/SbGIF.h>
45 
46 #include <stdlib.h>
47 
48 typedef struct {
49  unsigned char red;
50  unsigned char green;
51  unsigned char blue;
52 } Pixel;
53 typedef unsigned char Uchar;
54 
55 //static void getImagePixels(int,int,float*,int&,
56 // Uchar*&,Uchar*&,Uchar*&,Uchar*&);
57 
58 static int sWidth = 0;
59 static int sHeight = 0;
60 static float* sImage = 0;
61 static int getRGB(unsigned int,unsigned int,double&,double&,double&);
62 
63 SO_NODE_SOURCE(SoImageWriter)
65 void SoImageWriter::initClass (
66 )
69 {
70  SO_NODE_INIT_CLASS(SoImageWriter,SoNode,"Node");
71 }
74 )
75 :fEnabled(FALSE)
76 ,fStatus(FALSE)
79 {
80  SO_NODE_CONSTRUCTOR(SoImageWriter);
81  //SO_NODE_ADD_FIELD(format,(POST_SCRIPT));
82  SO_NODE_ADD_FIELD(fileName,("out.ps"));
83 
84  //SO_NODE_DEFINE_ENUM_VALUE(Format,POST_SCRIPT);
85  //SO_NODE_DEFINE_ENUM_VALUE(Format,GIF);
86 
87  //SO_NODE_SET_SF_ENUM_TYPE(format,Format);
88 }
91 )
94 {
95 }
98 )
101 {
102  fEnabled = TRUE;
103 }
106 )
109 {
110  fEnabled = FALSE;
111 }
114 ) const
117 {
118  return fStatus;
119 }
122  SoGLRenderAction* aAction
123 )
126 {
127  fStatus = FALSE;
128  //printf("debug : SoImageWriter::GLRender : enabled : %d\n",fEnabled);
129  if(!fEnabled) return;
130  SbViewportRegion vpr = SoViewportRegionElement::get(aAction->getState());
131  const SbVec2s& win = vpr.getWindowSize();
132  int w = win[0];
133  int h = win[1];
134  if((w*h)<=0) {
135  SoDebugError::postInfo("SoImageWriter::GLRender","null area window !");
136  return;
137  }
138 
139  int x = 0;
140  int y = 0;
141  int s = 3 * w * h;
142  float* image = new float[s];
143  if(!image) return;
144 
145  //printf("debug : SoImageWriter::GLRender : %d %d %d %d\n",x,y,w,h);
146 
147  //glReadPixels(x,y,w,h,GL_RGB,GL_UNSIGNED_BYTE,image); Don't work !
148  glReadPixels(x,y,w,h,GL_RGB,GL_FLOAT,image);
149 
150  //Format fm = (Format)format.getValue();
151  //if(fm==GIF) {
152 /*
153  FILE* file = fopen(fileName.getValue().getString(),"wb");
154  if(!file) {
155  SoDebugError::postInfo("SoImageWriter::GLRender",
156  "can't open file \"%s\".",fileName.getValue().getString());
157  } else {
158  int coln;
159  Uchar* rs;
160  Uchar* gs;
161  Uchar* bs;
162  Uchar* data;
163  getImagePixels(w,h,image,coln,rs,gs,bs,data);
164 
165  SbGIF::putBytesInStream(file,data,w,h,coln,rs,gs,bs);
166 
167  delete [] data;
168 
169  if(rs) free(rs);
170  if(gs) free(gs);
171  if(bs) free(bs);
172 
173  fclose(file);
174 
175  fStatus = TRUE;
176  }
177  } else {
178 */
179 
180  SbPainterPS painterPS;
181  painterPS.openFileForWriting(fileName.getValue().getString());
182  if(!painterPS.getStream()) {
183  SoDebugError::postInfo("SoImageWriter::GLRender",
184  "can't open file \"%s\".",fileName.getValue().getString());
185  } else {
186  painterPS.setWindowSize(w,h);
187  //painterPS.setBitsPerPixel(8);
188  painterPS.setBitsPerPixel(4);
189  painterPS.beginTraversal();
190  painterPS.clearColorBuffer(1.,1.,1.);
191 
192  sWidth = w;
193  sHeight = h;
194  sImage = image;
195  painterPS.putImageInStream((unsigned int)w,(unsigned int)h,getRGB);
196 
197  painterPS.endTraversal();
198 
199  painterPS.closeStream();
200 
201  fStatus = TRUE;
202  }
203  //}
204  delete [] image;
205 
206 }
207 /*
209 void getImagePixels (
210  int aWidth
211 ,int aHeight
212 ,float* aImage
213 ,int& aColorn
214 ,Uchar*& aReds
215 ,Uchar*& aGreens
216 ,Uchar*& aBlues
217 ,Uchar*& aData
218 )
221 {
222  aColorn = 0;
223  aReds = 0;
224  aGreens = 0;
225  aBlues = 0;
226  aData = 0;
227  if( (aWidth * aHeight) <=0) return;
228  int size = 256;
229  Uchar* rs = (Uchar*)malloc(size * sizeof(Uchar));
230  Uchar* gs = (Uchar*)malloc(size * sizeof(Uchar));
231  Uchar* bs = (Uchar*)malloc(size * sizeof(Uchar));
232  Uchar* data = new Uchar[aWidth * aHeight];
233  if( !rs || !gs || !bs || !data ) {
234  if(rs) free(rs);
235  if(gs) free(gs);
236  if(bs) free(bs);
237  delete [] data;
238  return;
239  }
240  int pixeln = 0;
241  int row,col;
242  Uchar red,green,blue;
243  Uchar ored = 0,ogreen = 0,oblue = 0;
244  float* pimag = aImage;
245  Uchar* pdata = 0;
246  Uchar index = 0;
247  int status = 0;
248  for(row=0;row<aHeight;row++) {
249  pdata = data + (aHeight - 1 - row) * aWidth;
250  for(col=0;col<aWidth;col++){
251  red = (Uchar)(255 * (*pimag));pimag++;
252  green = (Uchar)(255 * (*pimag));pimag++;
253  blue = (Uchar)(255 * (*pimag));pimag++;
254  //printf("debug : %d %d : %d %d %d\n",row,col,red,green,blue);
255  if( (pixeln==0) || (red!=ored) || (green!=ogreen) || (blue!=oblue) ){
256  // Search exact color :
257  int found = 0;
258  for(int count=0;count<pixeln;count++){
259  if( (red==rs[count]) && (green==gs[count]) && (blue==bs[count]) ){
260  found = 1;
261  index = count;
262  break;
263  }
264  }
265  if(found==0){
266  if(pixeln>=256) {
267  // We can't store more than 256 on an Uchar.
268  // Search closest color :
269  int dr,dg,db;
270  int PRECISION = 20;
271  int closest = 0;
272  for(int count=0;count<pixeln;count++){
273  dr = red - rs[count];dr = dr<0 ? -dr : dr;
274  dg = green - gs[count];dg = dg<0 ? -dg : dg;
275  db = blue - bs[count];db = db<0 ? -db : db;
276  if( (dr<=PRECISION) && (dg<=PRECISION) && (db<=PRECISION) ){
277  closest = 1;
278  index = count;
279  break;
280  }
281  }
282  if(closest==0) {
283  index = 0;
284  status = 1;
285  }
286  } else {
287  if(pixeln>=size){
288  size += 256;
289  rs = (Uchar*)realloc(rs,size * sizeof(Uchar));
290  gs = (Uchar*)realloc(gs,size * sizeof(Uchar));
291  bs = (Uchar*)realloc(bs,size * sizeof(Uchar));
292  if( !rs || !gs || !bs ) {
293  if(rs) free(rs);
294  if(gs) free(gs);
295  if(bs) free(bs);
296  delete [] data;
297  return;
298  }
299  }
300  //printf("debug : SoImageWriter pixeln %d : %d %d %d\n",
301  // pixeln,red,green,blue);
302  rs[pixeln] = red;
303  gs[pixeln] = green;
304  bs[pixeln] = blue;
305  index = pixeln;
306  pixeln++;
307  }
308  }
309  }
310  *pdata = index;
311  pdata++;
312  ored = red;
313  ogreen = green;
314  oblue = blue;
315  }
316  }
317  if(status==1)
318  printf("SoImageWriter : more than 256 colors in picture ; some colors approximated.\n");
319  aColorn = pixeln;
320  aReds = rs;
321  aGreens = gs;
322  aBlues = bs;
323  aData = data;
324 }
325 */
327 int getRGB(
328  unsigned int aX
329 ,unsigned int aY
330 ,double& aRed
331 ,double& aGreen
332 ,double& aBlue
333 )
335 // OpenGL image is from down to up.
336 // PS image is up to down.
338 {
339  float* pimag = sImage + 3 * (sWidth * (sHeight - 1 - aY) + aX);
340  aRed = *pimag;pimag++;
341  aGreen = *pimag;pimag++;
342  aBlue = *pimag;pimag++;
343  return 1;
344 }
345 
346 #endif