CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWTEveViewer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Subsystem/Package
4 // Class : FWTEveViewer
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author:
10 // Created: Tue, 03 Feb 2015 21:46:04 GMT
11 //
12 
13 // system include files
14 
15 #include "png.h"
16 #include "jpeglib.h"
17 
18 
19 // user include files
20 
21 #include "TMath.h"
22 #include "TGLIncludes.h"
23 #define protected public
24 #include "TGLFBO.h"
25 #undef protected
26 
29 
30 //
31 // constants, enums and typedefs
32 //
33 
34 //
35 // static data member definitions
36 //
37 
38 //
39 // constructors and destructor
40 //
41 FWTEveViewer::FWTEveViewer(const char* n, const char* t) :
42  TEveViewer(n, t),
43  m_fwGlViewer(0)
44 {}
45 
46 // FWTEveViewer::FWTEveViewer(const FWTEveViewer& rhs)
47 // {
48 // // do actual copying here;
49 // }
50 
52 {}
53 
54 //
55 // assignment operators
56 //
57 // const FWTEveViewer& FWTEveViewer::operator=(const FWTEveViewer& rhs)
58 // {
59 // //An exception safe implementation is
60 // FWTEveViewer temp(rhs);
61 // swap(rhs);
62 //
63 // return *this;
64 // }
65 
66 //
67 // member functions
68 //
69 
71 {
72  TGCompositeFrame* cf = GetGUICompositeFrame();
73 
74  m_fwGlViewer = new FWTGLViewer(cf);
75  SetGLViewer(m_fwGlViewer, m_fwGlViewer->GetFrame());
76 
77  cf->AddFrame(fGLViewerFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
78 
79  fGLViewerFrame->MapWindow();
80 
81  if (fEveFrame == 0)
82  PreUndock();
83 
84  return m_fwGlViewer;
85 }
86 
87 std::thread FWTEveViewer::CaptureAndSaveImage(const TString& file, int height)
88 {
89  static const TString eh("FWTEveViewer::CaptureAndSaveImage");
90 
91  TGLFBO *fbo = 0;
92  if (height == -1)
93  fbo = m_fwGlViewer->MakeFbo();
94  else
95  fbo = m_fwGlViewer->MakeFboHeight(height);
96 
97  if (fbo == 0)
98  {
99  ::Error(eh, "Returned FBO is 0.");
100  return std::thread();
101  }
102 
103  int ww, hh;
104  if (fbo->fIsRescaled)
105  {
106  ww = TMath::Nint(fbo->fW * fbo->fWScale);
107  hh = TMath::Nint(fbo->fH * fbo->fHScale);
108  }
109  else
110  {
111  ww = fbo->fW;
112  hh = fbo->fH;
113  }
114 
115  fbo->SetAsReadBuffer();
116 
117  UChar_t* xx = new UChar_t[3 * ww * hh];
118  glPixelStorei(GL_PACK_ALIGNMENT, 1);
119  glReadPixels(0, 0, ww, hh, GL_RGB, GL_UNSIGNED_BYTE, xx);
120 
121  delete fbo;
122 
123  std::thread thr([=]()
124  {
125  if (file.EndsWith(".jpg"))
126  {
127  SaveJpg(file, xx, ww, hh);
128  }
129  else
130  {
131  SavePng(file, xx, ww, hh);
132  }
133 
134  delete [] xx;
135  });
136 
137  return thr;
138 }
139 
140 //
141 // const member functions
142 //
143 
144 //
145 // static member functions
146 //
147 
148 bool FWTEveViewer::SavePng(const TString& file, UChar_t* xx, int ww, int hh)
149 {
150  png_structp png_ptr;
151  png_infop info_ptr;
152 
153  /* Create and initialize the png_struct with the desired error handler
154  * functions. If you want to use the default stderr and longjump method,
155  * you can supply NULL for the last three parameters. We also check that
156  * the library version is compatible with the one used at compile time,
157  * in case we are using dynamically linked libraries. REQUIRED.
158  */
159  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 0, 0);
160  if (png_ptr == NULL) {
161  printf("Error creating png write struct\n");
162  return false;
163  }
164 
165  // Allocate/initialize the image information data. REQUIRED
166  info_ptr = png_create_info_struct(png_ptr);
167  if (info_ptr == NULL) {
168  printf("Error creating png info struct\n");
169  png_destroy_write_struct(&png_ptr, &info_ptr);
170  return false;
171  }
172 
173  /*// Set error handling. REQUIRED if you aren't supplying your own
174  // error handling functions in the png_create_write_struct() call.
175  if (setjmp(png_jmpbuf(png_ptr))) {
176  // If we get here, we had a problem reading the file
177  png_destroy_write_struct(&png_ptr, &info_ptr);
178  ilSetError(IL_LIB_PNG_ERROR);
179  return IL_FALSE;
180  }*/
181 
182  FILE *fp = fopen(file, "w");
183 
184  png_init_io(png_ptr, fp);
185 
186 
187  // Use PNG_INTERLACE_ADAM7 for interlacing
188  png_set_IHDR(png_ptr, info_ptr, ww, hh, 8, PNG_COLOR_TYPE_RGB,
189  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
190 
191  /* Optional gamma chunk is strongly suggested if you have any guess
192  * as to the correct gamma of the image.
193  */
194  // png_set_gAMA(png_ptr, info_ptr, gamma);
195 
196  // Optionally write comments into the image.
197  // png_text text;
198  // text.key = "Generated by";
199  // text.text = "Generated by cmsShow";
200  // text.compression = PNG_TEXT_COMPRESSION_NONE;
201  // png_set_text(png_ptr, info_ptr, &text, 1);
202 
203  // Write the file header information. REQUIRED.
204  png_write_info(png_ptr, info_ptr);
205 
206  std::vector<UChar_t*> rows(hh);
207  {
208  int j = hh - 1;
209  for (int i = 0; i < hh; i++, j--) {
210  rows[i] = xx + j * ww * 3;
211  }
212  }
213 
214  // Writes the image.
215  png_write_image(png_ptr, &rows[0]);
216 
217  // It is REQUIRED to call this to finish writing the rest of the file
218  png_write_end(png_ptr, info_ptr);
219 
220  // clean up after the write, and ifree any memory allocated
221  png_destroy_write_struct(&png_ptr, &info_ptr);
222 
223  fclose(fp);
224 
225  return true;
226 }
227 
228 bool FWTEveViewer::SaveJpg(const TString& file, UChar_t* xx, int ww, int hh)
229 {
230  struct jpeg_compress_struct JpegInfo;
231  struct jpeg_error_mgr Error;
232 
233  JpegInfo.err = jpeg_std_error(&Error);
234 
235  // Now we can initialize the JPEG compression object.
236  jpeg_create_compress(&JpegInfo);
237 
238  FILE *fp = fopen(file, "w");
239  jpeg_stdio_dest(&JpegInfo, fp);
240 
241  JpegInfo.image_width = ww;
242  JpegInfo.image_height = hh;
243  JpegInfo.input_components = 3;
244  JpegInfo.in_color_space = JCS_RGB;
245 
246  jpeg_set_defaults(&JpegInfo);
247 
248  JpegInfo.write_JFIF_header = TRUE;
249 
250  // Set the quality output
251  // const int quality = 98;
252  // jpeg_set_quality(&JpegInfo, quality, true); // bool force_baseline ????
253 
254  jpeg_start_compress(&JpegInfo, TRUE);
255 
256  std::vector<UChar_t*> rows(hh);
257  {
258  int j = hh - 1;
259  for (int i = 0; i < hh; i++, j--) {
260  rows[i] = xx + j * ww * 3;
261  }
262  }
263 
264  jpeg_write_scanlines(&JpegInfo, &rows[0], hh);
265 
266  // Step 6: Finish compression
267  jpeg_finish_compress(&JpegInfo);
268 
269  // Step 7: release JPEG compression object
270 
271  // This is an important step since it will release a good deal of memory.
272  jpeg_destroy_compress(&JpegInfo);
273 
274  return true;
275 }
int i
Definition: DBlmapReader.cc:9
#define TRUE
Definition: scimark2.h:12
TGLFBO * MakeFboHeight(Int_t height, Bool_t pixel_object_scale=kTRUE)
Definition: FWTGLViewer.cc:129
#define NULL
Definition: scimark2.h:8
FWTEveViewer(const char *n="FWTEveViewer", const char *t="")
Definition: FWTEveViewer.cc:41
int j
Definition: DBlmapReader.cc:9
static bool SaveJpg(const TString &file, UChar_t *xx, int ww, int hh)
virtual ~FWTEveViewer()
Definition: FWTEveViewer.cc:51
FWTGLViewer * m_fwGlViewer
Definition: FWTEveViewer.h:64
static bool SavePng(const TString &file, UChar_t *xx, int ww, int hh)
std::thread CaptureAndSaveImage(const TString &file, int height=-1)
Definition: FWTEveViewer.cc:87
FWTGLViewer * SpawnFWTGLViewer()
Definition: FWTEveViewer.cc:70
TGLFBO * MakeFbo()
Definition: FWTGLViewer.cc:108