CMS 3D CMS Logo

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