File indexing completed on 2024-06-04 04:34:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "png.h"
0016 #include "jpeglib.h"
0017
0018
0019
0020 #include "TMath.h"
0021 #include "TGLIncludes.h"
0022 #include "TGLFBO.h"
0023
0024 #include "Fireworks/Core/interface/FWTEveViewer.h"
0025 #include "Fireworks/Core/interface/FWTGLViewer.h"
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 FWTEveViewer::FWTEveViewer(const char* n, const char* t) : TEveViewer(n, t), m_fwGlViewer(nullptr) {}
0039
0040
0041
0042
0043
0044
0045 FWTEveViewer::~FWTEveViewer() {
0046 if (m_thr)
0047 m_thr->detach();
0048
0049 {
0050 std::unique_lock<std::mutex> lk(m_moo);
0051
0052 m_thr_exit = true;
0053 m_cnd.notify_one();
0054 }
0055
0056 delete m_thr;
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 void FWTEveViewer::spawn_image_thread() {
0078 std::unique_lock<std::mutex> lko(m_moo);
0079
0080 m_thr = new std::thread([this]() {
0081 {
0082 std::unique_lock<std::mutex> lk(m_moo);
0083 m_cnd.notify_one();
0084 }
0085 while (true) {
0086 {
0087 std::unique_lock<std::mutex> lk(m_moo);
0088 m_cnd.wait(lk);
0089
0090 if (m_thr_exit) {
0091 return;
0092 }
0093 }
0094 if (m_name.EndsWith(".jpg")) {
0095 SaveJpg(m_name, &m_imgBuffer[0], m_ww, m_hh);
0096 } else {
0097 SavePng(m_name, &m_imgBuffer[0], m_ww, m_hh);
0098 }
0099
0100 m_prom.set_value(0);
0101 }
0102 });
0103
0104 m_cnd.wait(lko);
0105 }
0106
0107
0108
0109 FWTGLViewer* FWTEveViewer::SpawnFWTGLViewer() {
0110 TGCompositeFrame* cf = GetGUICompositeFrame();
0111
0112 m_fwGlViewer = new FWTGLViewer(cf);
0113 SetGLViewer(m_fwGlViewer, m_fwGlViewer->GetFrame());
0114
0115 cf->AddFrame(fGLViewerFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
0116
0117 fGLViewerFrame->MapWindow();
0118
0119 if (fEveFrame == nullptr)
0120 PreUndock();
0121
0122 return m_fwGlViewer;
0123 }
0124
0125 std::future<int> FWTEveViewer::CaptureAndSaveImage(const TString& file, int height) {
0126 static const TString eh("FWTEveViewer::CaptureAndSaveImage");
0127
0128 TGLFBO* fbo = nullptr;
0129 if (height == -1)
0130 fbo = m_fwGlViewer->MakeFbo();
0131 else
0132 fbo = m_fwGlViewer->MakeFboHeight(height);
0133
0134 if (fbo == nullptr) {
0135 ::Error(eh, "Returned FBO is 0.");
0136 m_prom = std::promise<int>();
0137 m_prom.set_value(-1);
0138 return m_prom.get_future();
0139 }
0140
0141 int ww, hh;
0142 if (fbo->GetIsRescaled()) {
0143 ww = TMath::Nint(fbo->GetW() * fbo->GetWScale());
0144 hh = TMath::Nint(fbo->GetH() * fbo->GetHScale());
0145 } else {
0146 ww = fbo->GetW();
0147 hh = fbo->GetH();
0148 }
0149
0150 fbo->SetAsReadBuffer();
0151
0152 size_t bufsize = 3 * ww * hh;
0153 if (bufsize != m_imgBuffer.size()) {
0154 m_imgBuffer.resize(bufsize);
0155 }
0156
0157 glPixelStorei(GL_PACK_ALIGNMENT, 1);
0158 glReadPixels(0, 0, ww, hh, GL_RGB, GL_UNSIGNED_BYTE, &m_imgBuffer[0]);
0159
0160 if (m_thr == nullptr)
0161 spawn_image_thread();
0162
0163 {
0164 std::unique_lock<std::mutex> lk(m_moo);
0165
0166 m_prom = std::promise<int>();
0167 m_name = file;
0168 m_ww = ww;
0169 m_hh = hh;
0170
0171 m_cnd.notify_one();
0172 }
0173
0174 return m_prom.get_future();
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 bool FWTEveViewer::SavePng(const TString& file, UChar_t* xx, int ww, int hh) {
0186 png_structp png_ptr;
0187 png_infop info_ptr;
0188
0189
0190
0191
0192
0193
0194
0195 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
0196 if (png_ptr == nullptr) {
0197 printf("Error creating png write struct\n");
0198 return false;
0199 }
0200
0201
0202 info_ptr = png_create_info_struct(png_ptr);
0203 if (info_ptr == nullptr) {
0204 printf("Error creating png info struct\n");
0205 png_destroy_write_struct(&png_ptr, &info_ptr);
0206 return false;
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 FILE* fp = fopen(file, "w");
0219
0220 png_init_io(png_ptr, fp);
0221
0222
0223 png_set_IHDR(png_ptr,
0224 info_ptr,
0225 ww,
0226 hh,
0227 8,
0228 PNG_COLOR_TYPE_RGB,
0229 PNG_INTERLACE_NONE,
0230 PNG_COMPRESSION_TYPE_BASE,
0231 PNG_FILTER_TYPE_BASE);
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 png_write_info(png_ptr, info_ptr);
0247
0248 std::vector<UChar_t*> rows(hh);
0249 {
0250 int j = hh - 1;
0251 for (int i = 0; i < hh; i++, j--) {
0252 rows[i] = xx + j * ww * 3;
0253 }
0254 }
0255
0256
0257 png_write_image(png_ptr, &rows[0]);
0258
0259
0260 png_write_end(png_ptr, info_ptr);
0261
0262
0263 png_destroy_write_struct(&png_ptr, &info_ptr);
0264
0265 fclose(fp);
0266
0267 return true;
0268 }
0269
0270 bool FWTEveViewer::SaveJpg(const TString& file, UChar_t* xx, int ww, int hh) {
0271 struct jpeg_compress_struct JpegInfo;
0272 struct jpeg_error_mgr Error;
0273
0274 JpegInfo.err = jpeg_std_error(&Error);
0275
0276
0277 jpeg_create_compress(&JpegInfo);
0278
0279 FILE* fp = fopen(file, "w");
0280 jpeg_stdio_dest(&JpegInfo, fp);
0281
0282 JpegInfo.image_width = ww;
0283 JpegInfo.image_height = hh;
0284 JpegInfo.input_components = 3;
0285 JpegInfo.in_color_space = JCS_RGB;
0286
0287 jpeg_set_defaults(&JpegInfo);
0288
0289 JpegInfo.write_JFIF_header = TRUE;
0290
0291
0292
0293
0294
0295 jpeg_start_compress(&JpegInfo, TRUE);
0296
0297 std::vector<UChar_t*> rows(hh);
0298 {
0299 int j = hh - 1;
0300 for (int i = 0; i < hh; i++, j--) {
0301 rows[i] = xx + j * ww * 3;
0302 }
0303 }
0304
0305 jpeg_write_scanlines(&JpegInfo, &rows[0], hh);
0306
0307
0308 jpeg_finish_compress(&JpegInfo);
0309
0310
0311
0312
0313 jpeg_destroy_compress(&JpegInfo);
0314
0315 return true;
0316 }