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  if (m_thr) m_thr->detach();
54 
55  {
56  std::unique_lock<std::mutex> lk(m_moo);
57 
58  m_thr_exit = true;
59  m_cnd.notify_one();
60  }
61 
62  delete m_thr;
63 }
64 
65 //
66 // assignment operators
67 //
68 // const FWTEveViewer& FWTEveViewer::operator=(const FWTEveViewer& rhs)
69 // {
70 // //An exception safe implementation is
71 // FWTEveViewer temp(rhs);
72 // swap(rhs);
73 //
74 // return *this;
75 // }
76 
77 //==============================================================================
78 
79 //
80 // member functions
81 //
82 
84 {
85  std::unique_lock<std::mutex> lko(m_moo);
86 
87  m_thr = new std::thread([=]() {
88  { std::unique_lock<std::mutex> lk(m_moo); m_cnd.notify_one(); }
89  while (true)
90  {
91  {
92  std::unique_lock<std::mutex> lk(m_moo);
93  m_cnd.wait(lk);
94 
95  if (m_thr_exit)
96  {
97  return;
98  }
99  }
100  if (m_name.EndsWith(".jpg"))
101  {
103  }
104  else
105  {
107  }
108 
109  m_prom.set_value(0);
110  }
111  });
112 
113  m_cnd.wait(lko);
114 }
115 
116 //------------------------------------------------------------------------------
117 
119 {
120  TGCompositeFrame* cf = GetGUICompositeFrame();
121 
122  m_fwGlViewer = new FWTGLViewer(cf);
123  SetGLViewer(m_fwGlViewer, m_fwGlViewer->GetFrame());
124 
125  cf->AddFrame(fGLViewerFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
126 
127  fGLViewerFrame->MapWindow();
128 
129  if (fEveFrame == 0)
130  PreUndock();
131 
132  return m_fwGlViewer;
133 }
134 
135 std::future<int>
136 FWTEveViewer::CaptureAndSaveImage(const TString& file, int height)
137 {
138  static const TString eh("FWTEveViewer::CaptureAndSaveImage");
139 
140  TGLFBO *fbo = 0;
141  if (height == -1)
142  fbo = m_fwGlViewer->MakeFbo();
143  else
144  fbo = m_fwGlViewer->MakeFboHeight(height);
145 
146  if (fbo == 0)
147  {
148  ::Error(eh, "Returned FBO is 0.");
149  m_prom = std::promise<int>();
150  m_prom.set_value(-1);
151  return m_prom.get_future();
152  }
153 
154  int ww, hh;
155  if (fbo->fIsRescaled)
156  {
157  ww = TMath::Nint(fbo->fW * fbo->fWScale);
158  hh = TMath::Nint(fbo->fH * fbo->fHScale);
159  }
160  else
161  {
162  ww = fbo->fW;
163  hh = fbo->fH;
164  }
165 
166  fbo->SetAsReadBuffer();
167 
168  size_t bufsize = 3 * ww * hh;
169  if (bufsize != m_imgBuffer.size())
170  {
171  m_imgBuffer.resize(bufsize);
172  }
173 
174  glPixelStorei(GL_PACK_ALIGNMENT, 1);
175  glReadPixels(0, 0, ww, hh, GL_RGB, GL_UNSIGNED_BYTE, &m_imgBuffer[0]);
176 
177  if (m_thr == 0) spawn_image_thread();
178 
179  {
180  std::unique_lock<std::mutex> lk(m_moo);
181 
182  m_prom = std::promise<int>();
183  m_name = file;
184  m_ww = ww;
185  m_hh = hh;
186 
187  m_cnd.notify_one();
188  }
189 
190  return m_prom.get_future();
191 }
192 
193 //
194 // const member functions
195 //
196 
197 //
198 // static member functions
199 //
200 
201 bool FWTEveViewer::SavePng(const TString& file, UChar_t* xx, int ww, int hh)
202 {
203  png_structp png_ptr;
204  png_infop info_ptr;
205 
206  /* Create and initialize the png_struct with the desired error handler
207  * functions. If you want to use the default stderr and longjump method,
208  * you can supply NULL for the last three parameters. We also check that
209  * the library version is compatible with the one used at compile time,
210  * in case we are using dynamically linked libraries. REQUIRED.
211  */
212  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, 0, 0);
213  if (png_ptr == NULL) {
214  printf("Error creating png write struct\n");
215  return false;
216  }
217 
218  // Allocate/initialize the image information data. REQUIRED
219  info_ptr = png_create_info_struct(png_ptr);
220  if (info_ptr == NULL) {
221  printf("Error creating png info struct\n");
222  png_destroy_write_struct(&png_ptr, &info_ptr);
223  return false;
224  }
225 
226  /*// Set error handling. REQUIRED if you aren't supplying your own
227  // error handling functions in the png_create_write_struct() call.
228  if (setjmp(png_jmpbuf(png_ptr))) {
229  // If we get here, we had a problem reading the file
230  png_destroy_write_struct(&png_ptr, &info_ptr);
231  ilSetError(IL_LIB_PNG_ERROR);
232  return IL_FALSE;
233  }*/
234 
235  FILE *fp = fopen(file, "w");
236 
237  png_init_io(png_ptr, fp);
238 
239 
240  // Use PNG_INTERLACE_ADAM7 for interlacing
241  png_set_IHDR(png_ptr, info_ptr, ww, hh, 8, PNG_COLOR_TYPE_RGB,
242  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
243 
244  /* Optional gamma chunk is strongly suggested if you have any guess
245  * as to the correct gamma of the image.
246  */
247  // png_set_gAMA(png_ptr, info_ptr, gamma);
248 
249  // Optionally write comments into the image.
250  // png_text text;
251  // text.key = "Generated by";
252  // text.text = "Generated by cmsShow";
253  // text.compression = PNG_TEXT_COMPRESSION_NONE;
254  // png_set_text(png_ptr, info_ptr, &text, 1);
255 
256  // Write the file header information. REQUIRED.
257  png_write_info(png_ptr, info_ptr);
258 
259  std::vector<UChar_t*> rows(hh);
260  {
261  int j = hh - 1;
262  for (int i = 0; i < hh; i++, j--) {
263  rows[i] = xx + j * ww * 3;
264  }
265  }
266 
267  // Writes the image.
268  png_write_image(png_ptr, &rows[0]);
269 
270  // It is REQUIRED to call this to finish writing the rest of the file
271  png_write_end(png_ptr, info_ptr);
272 
273  // clean up after the write, and ifree any memory allocated
274  png_destroy_write_struct(&png_ptr, &info_ptr);
275 
276  fclose(fp);
277 
278  return true;
279 }
280 
281 bool FWTEveViewer::SaveJpg(const TString& file, UChar_t* xx, int ww, int hh)
282 {
283  struct jpeg_compress_struct JpegInfo;
284  struct jpeg_error_mgr Error;
285 
286  JpegInfo.err = jpeg_std_error(&Error);
287 
288  // Now we can initialize the JPEG compression object.
289  jpeg_create_compress(&JpegInfo);
290 
291  FILE *fp = fopen(file, "w");
292  jpeg_stdio_dest(&JpegInfo, fp);
293 
294  JpegInfo.image_width = ww;
295  JpegInfo.image_height = hh;
296  JpegInfo.input_components = 3;
297  JpegInfo.in_color_space = JCS_RGB;
298 
299  jpeg_set_defaults(&JpegInfo);
300 
301  JpegInfo.write_JFIF_header = TRUE;
302 
303  // Set the quality output
304  // const int quality = 98;
305  // jpeg_set_quality(&JpegInfo, quality, true); // bool force_baseline ????
306 
307  jpeg_start_compress(&JpegInfo, TRUE);
308 
309  std::vector<UChar_t*> rows(hh);
310  {
311  int j = hh - 1;
312  for (int i = 0; i < hh; i++, j--) {
313  rows[i] = xx + j * ww * 3;
314  }
315  }
316 
317  jpeg_write_scanlines(&JpegInfo, &rows[0], hh);
318 
319  // Step 6: Finish compression
320  jpeg_finish_compress(&JpegInfo);
321 
322  // Step 7: release JPEG compression object
323 
324  // This is an important step since it will release a good deal of memory.
325  jpeg_destroy_compress(&JpegInfo);
326 
327  return true;
328 }
int i
Definition: DBlmapReader.cc:9
std::mutex m_moo
Definition: FWTEveViewer.h:77
#define TRUE
Definition: scimark2.h:12
TString m_name
Definition: FWTEveViewer.h:72
TGLFBO * MakeFboHeight(Int_t height, Bool_t pixel_object_scale=kTRUE)
Definition: FWTGLViewer.cc:132
std::condition_variable m_cnd
Definition: FWTEveViewer.h:78
std::thread * m_thr
Definition: FWTEveViewer.h:75
std::vector< unsigned char > m_imgBuffer
Definition: FWTEveViewer.h:70
#define NULL
Definition: scimark2.h:8
FWTEveViewer(const char *n="FWTEveViewer", const char *t="")
Definition: FWTEveViewer.cc:41
int j
Definition: DBlmapReader.cc:9
std::promise< int > m_prom
Definition: FWTEveViewer.h:76
static bool SaveJpg(const TString &file, UChar_t *xx, int ww, int hh)
virtual ~FWTEveViewer()
Definition: FWTEveViewer.cc:51
std::future< int > CaptureAndSaveImage(const TString &file, int height=-1)
FWTGLViewer * m_fwGlViewer
Definition: FWTEveViewer.h:68
static bool SavePng(const TString &file, UChar_t *xx, int ww, int hh)
FWTGLViewer * SpawnFWTGLViewer()
TGLFBO * MakeFbo()
Definition: FWTGLViewer.cc:111
void spawn_image_thread()
Definition: FWTEveViewer.cc:83