ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SoImageWriter.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SoImageWriter.cc
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