FACT++  1.0
MGImage.cc
Go to the documentation of this file.
1 //
2 // This File contains the definition of the MGImage-class
3 //
4 // Author: Thomas Bretz
5 // Version: V1.0 (1-8-2000)
6 //
7 // x11/src/GX11Gui.cxx
8 //
9 
11 //
12 // MGImage
13 //
14 // If sync-mode is enabled the Redraw function is secured by a mutex (ignore
15 // error messages about it comming from root) This has the advantage that
16 // if you use a timer for screen update reading and writing the image is
17 // synchronized. In this way you don't get flickering half images.
18 //
20 #include "MGImage.h"
21 
22 #include <iostream>
23 
24 #include <TGX11.h>
25 #include <TMutex.h>
26 
27 #include <TMath.h>
28 
29 //#include "MLog.h"
30 //#include "MLogManip.h"
31 
32 using namespace std;
33 
34 MGImage::MGImage(const TGWindow* p, UInt_t w, UInt_t h, UInt_t options, ULong_t back)
35  : TGFrame(p, w, h, options, back), fWidth(w), fHeight(h)
36 {
37  // p = pointer to MainFrame (not owner)
38  // w = width of frame
39  // h = width of frame
40 
41  //
42  // Creat drawing semaphore
43  //
44  fMuxPixmap = new TMutex;
45 
46  Resize(GetWidth(), GetHeight());
47 
48  //
49  // create empty pixmap
50  //
51  fDefGC = gVirtualX->CreateGC(fId, 0);
52  fImage = (XImage*)gVirtualX->CreateImage(fWidth, fHeight);
53 
54  cout << "Detected Color Depth: " << gVirtualX->GetDepth() << endl;
55 }
56 
58 {
59 // if (fMuxPixmap->Lock()==13)
60 // cout << "MGImage::~MGImage - mutex is already locked by this thread" << endl;
61 
62  cout << "Deleting MGImage..." << endl;
63 
64  gVirtualX->DeleteGC(fDefGC);
65  gVirtualX->DeleteImage((Drawable_t)fImage);
66 
67  //cout << fMuxPixmap->UnLock() << endl;
68 
69  delete fMuxPixmap;
70 
71  cout << "MGImage destroyed." << endl;
72 }
73 
75 {
76  if (TestBit(kSyncMode))
77  while (fMuxPixmap->Lock()==13)
78  usleep(1);
79 
80  // gVirtualX->DrawLine(fId, fDefGC, 0, 0, fWidth+2, 0);
81  // gVirtualX->DrawLine(fId, fDefGC, 0, 0, 0, fHeight+2);
82  // gVirtualX->DrawLine(fId, fDefGC, fWidth+2, 0, fWidth+2, fHeight+2);
83  // gVirtualX->DrawLine(fId, fDefGC, 0, fHeight+2, fWidth+2, fHeight+2);
84 
85  // if (TestBit(kNeedRedraw))
86  {
87  gVirtualX->PutImage(fId, fDefGC, (Drawable_t)fImage, 0, 0, 0, 0,
88  fWidth, fHeight);
89  ResetBit(kNeedRedraw);
90  }
91 
92  if (TestBit(kSyncMode))
93  if (fMuxPixmap->UnLock()==13)
94  cout << "MGImage::DoRedraw - tried to unlock mutex locked by other thread." << endl;
95 }
96 
97 void MGImage::DrawImg16(unsigned short *d, char *s, char *e)
98 {
99  // d=destination, s=source, e=end
100  // rrrrrggg gggbbbbb
101  //
102  while (s<e)
103  {
104  // 11111100 11111000 11111000
105  // *d++ = (*s&0xfc) | (*s&0xf8)<<5 | (*s&0xf8)<<11;
106 
107  // 11111000 11111100 11111000
108  *d++ = (*s&0xf8)<<8 | (*s&0xfc)<<3 | (*s>>3);
109  s++;
110  }
111 }
112 
113 void MGImage::DrawImg24(char *d, char *s, char *e)
114 {
115  // d=destination, s=source, e=end
116  // rrrrrrrr gggggggg bbbbbbbb aaaaaaaa
117  //
118  while (s<e)
119  {
120  *d++ = *s;
121  *d++ = *s;
122  *d++ = *s++;
123  d++;
124  }
125 }
126 
128 {
129  if (TestBit(kSyncMode))
130  while (fMuxPixmap->Lock()==13)
131  usleep(1);
132  else
133  {
134  const Int_t rc = fMuxPixmap->Lock();
135  if (rc==13)
136  cout << "MGImage::DrawImg - mutex is already locked by this thread" << endl;
137  if (rc)
138  return;
139  }
140 
141  switch (gVirtualX->GetDepth())
142  {
143  case 8:
144  memcpy(fImage->data, buffer, fWidth*fHeight);
145  break;
146  case 16:
147  DrawImg16((unsigned short*)fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
148  break;
149  case 24:
150  DrawImg24(fImage->data, (char*)buffer, (char*)(buffer+fWidth*fHeight));
151  break;
152  default:
153  cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl;
154  }
155 
156  SetBit(kNeedRedraw);
157 
158  if (fMuxPixmap->UnLock()==13)
159  cout << "MGImage::DrawImage - tried to unlock mutex locked by other thread." << endl;
160 }
161 
162 void MGImage::DrawColImg16(unsigned short *d, char *s1, char *s2, char *e)
163 {
164  // d=destination, s1=source1, s2=source2, e=end
165  // d: rrrrrggg gggbbbbb
166  // s2: 00rrggbb
167  //
168  while (s1<e)
169  {
170  if (*s2)
171  {
172  // 00000011 00001100 00110000
173  //*d++ = (*s2&0x3) | (*s2&0xb)<<3 | (*s2&0x30)<<7;
174  *d++ = (*s2&0x3)<<3 | (*s2&0xb)<<6 | (*s2&0x30)<<10;
175  }
176  else
177  {
178  // 11111100 11111000 11111100
179  *d++ = (*s1&0xfc) | (*s1&0xf8)<<5 | (*s1&0xfc)<<11;
180  }
181  s1++;
182  s2++;
183  }
184 }
185 
186 void MGImage::DrawColImg24(char *d, char *s1, char *s2, char *e)
187 {
188  // d=destination, s1=source1, s2=source2, e=end
189  while (s1<e)
190  {
191  if (*s2)
192  {
193  *d++ = ((*s2>>4)&0x3)*85;
194  *d++ = ((*s2>>2)&0x3)*85;
195  *d++ = ((*s2++ )&0x3)*85;
196  d++;
197  s1++;
198  }
199  else
200  {
201  *d++ = *s1;
202  *d++ = *s1;
203  *d++ = *s1++;
204  d++;
205  s2++;
206  }
207  }
208 }
209 
210 void MGImage::DrawColImg(const byte *gbuf, const byte *cbuf)
211 {
212  if (TestBit(kSyncMode))
213  while (fMuxPixmap->Lock()==13)
214  usleep(1);
215  else
216  {
217  const Int_t rc = fMuxPixmap->Lock();
218  if (rc==13)
219  cout << "MGImage::DrawColImg - mutex is already locked by this thread" << endl;
220  if (rc)
221  return;
222  }
223 
224  // FROM libAfterImage:
225  // -------------------
226  //#define ALPHA_TRANSPARENT 0x00
227  //#define ALPHA_SEMI_TRANSPARENT 0x7F
228  //#define ALPHA_SOLID 0xFF
229  // * Lowermost 8 bits - Blue channel
230  // * bits 8 to 15 - Green channel
231  // * bits 16 to 23 - Red channel
232  // * bits 24 to 31 - Alpha channel
233  //#define ARGB32_White 0xFFFFFFFF
234  //#define ARGB32_Black 0xFF000000
235 
236  // FIXME: This loop depends on the screen color depth
237  switch (gVirtualX->GetDepth())
238  {
239  case 16:
240  DrawColImg16((unsigned short*)fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight));
241  break;
242  case 24:
243  DrawColImg24(fImage->data, (char*)gbuf, (char*)cbuf, (char*)(gbuf+fWidth*fHeight));
244  break;
245  default:
246  cout << "Sorry, " << gVirtualX->GetDepth() << "bit color depth not yet implemented." << endl;
247  }
248 
249  SetBit(kNeedRedraw);
250 
251  if (fMuxPixmap->UnLock()==13)
252  cout << "MGImage::DrawColImage - tried to unlock mutex locked by other thread." << endl;
253 }
254 
255 // --------------------------------------------------------------------------
256 //
257 // Convert root colors to arbitrary bitmap coordinates
258 //
259 UChar_t MGImage::Color(int col)
260 {
261  switch (col)
262  {
263  case kBlack: return 0;
264  case kWhite: return 0xff;
265  case kYellow: return 0x0f;
266  case kRed: return 2;
267  case kGreen: return 2<<2;
268  case kBlue: return 2<<4;
269  default:
270  return 0;
271  }
272 }
273 
274 // --------------------------------------------------------------------------
275 //
276 // Draw a line into the buffer (size w*h) from (x1, y1) to (x2, y2) with
277 // the color col and the line style style (default: solid)
278 //
279 void MGImage::DrawLine(UChar_t *buf, int w, int h, Float_t x1, Float_t y1, Float_t x2, Float_t y2, UChar_t col, Int_t style)
280 {
281  const Int_t step = style==kSolid?1:3;
282  const Double_t len = TMath::Hypot(x2-x1, y2-y1);
283  const Double_t dx = (x2-x1)/len*step;
284  const Double_t dy = (y2-y1)/len*step;
285 
286  Double_t x = x1;
287  Double_t y = y1;
288 
289  for (int i=0; i<len; i+=step)
290  {
291  x+= dx;
292  y+= dy;
293 
294  const Int_t iy = TMath::Nint(y);
295  if (iy<0 || iy>=h)
296  continue;
297 
298  const Int_t ix = TMath::Nint(x);
299  if (ix<0 || ix>=w)
300  continue;
301 
302  buf[ix+iy*w] = col;
303  }
304 }
305 
306 // --------------------------------------------------------------------------
307 //
308 // Draw a box into the buffer (size w*h) from (x1, y1) to (x2, y2) with
309 // the color col and the line style style (default: solid)
310 //
311 void MGImage::DrawBox(UChar_t *buf, int w, int h, Float_t x1, Float_t y1, Float_t x2, Float_t y2, UChar_t col, Int_t style)
312 {
313  DrawLine(buf, w, h, x1, y1, x2, y1, col, style);
314  DrawLine(buf, w, h, x1, y2, x2, y1, col, style);
315  DrawLine(buf, w, h, x1, y1, x1, y2, col, style);
316  DrawLine(buf, w, h, x2, y1, x2, y2, col, style);
317 }
318 
319 // --------------------------------------------------------------------------
320 //
321 // Draw a hexagon into the buffer (size w*h) around (x, y) with radius r and
322 // the color col.
323 //
324 void MGImage::DrawHexagon(UChar_t *buf, int w, int h, Float_t px, Float_t py, Float_t d, UChar_t col, Int_t style)
325 {
326  const Int_t np = 6;
327 
328  const Double_t dy[np+1] = { .5 , 0. , -.5 , -.5 , 0. , .5 , .5 };
329  const Double_t dx[np+1] = { .2886, .5772, .2886, -.2886, -.5772, -.2886, .2886 };
330 
331  //
332  // calculate the positions of the pixel corners
333  //
334  Double_t x[np+1], y[np+1];
335  for (Int_t i=0; i<np+1; i++)
336  {
337  x[i] = px + dx[i]*d;
338  y[i] = py + dy[i]*d;
339  }
340 
341  for (int i=0; i<6; i++)
342  DrawLine(buf, w, h, x[i], y[i], x[i+1], y[i+1], col, style);
343 }
344 
345 // --------------------------------------------------------------------------
346 //
347 // Draw a circle into the buffer (size w*h) around (x, y) with radius r and
348 // the color col.
349 //
350 void MGImage::DrawCircle(UChar_t *buf, int w, int h, Float_t x, Float_t y, Float_t r, UChar_t col)
351 {
352  const Int_t n = TMath::Nint(sqrt(2.)*r*TMath::Pi()/2);
353  for (int i=0; i<n-1; i++)
354  {
355  const Double_t angle = TMath::TwoPi()*i/n;
356 
357  const Double_t dx = r*cos(angle);
358  const Double_t dy = r*sin(angle);
359 
360  const Int_t x1 = TMath::Nint(x+dx);
361  const Int_t x2 = TMath::Nint(x-dx);
362 
363  const Int_t y1 = TMath::Nint(y+dy);
364  if (y1>=0 && y1<h)
365  {
366  if (x1>=0 && x1<w)
367  buf[x1+y1*w] = col;
368 
369  if (x2>=0 && x2<w)
370  buf[x2+y1*w] = col;
371  }
372 
373  const Int_t y2 = TMath::Nint(y-dy);
374  if (y2>=0 && y2<h)
375  {
376  if (x1>=0 && x1<w)
377  buf[x1+y2*w] = col;
378 
379  if (x2>=0 && x2<w)
380  buf[x2+y2*w] = col;
381  }
382  }
383 }
384 
385 // --------------------------------------------------------------------------
386 //
387 // Draw a dot into the buffer (size w*h) at (x, y) with color col.
388 //
389 void MGImage::DrawDot(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, UChar_t col)
390 {
391  const Int_t x1 = TMath::Nint(cx);
392  const Int_t y1 = TMath::Nint(cy);
393 
394  if (x1>=0 && y1>=0 && x1<w && y1<h)
395  buf[x1+y1*w] = col;
396 }
397 
398 // --------------------------------------------------------------------------
399 //
400 // Draw a line into the buffer. The TObject must be a TLine.
401 // Currently only solid and non sloid line are supported.
402 //
403 /*
404 void MGImage::DrawLine(TObject *o, UChar_t *buf, int w, int h, Double_t scale)
405 {
406  TLine *l = dynamic_cast<TLine*>(o);
407  if (!l)
408  return;
409 
410  const Double_t x1 = 0.5*w-(l->GetX1()/scale);
411  const Double_t x2 = 0.5*w-(l->GetX2()/scale);
412  const Double_t y1 = 0.5*h-(l->GetY1()/scale);
413  const Double_t y2 = 0.5*h-(l->GetY2()/scale);
414 
415  const Int_t col = Color(l->GetLineColor());
416  DrawLine(buf, w, h, x1, y1, x2, y2, col, l->GetLineStyle());
417 }
418 */
419 void MGImage::DrawMultiply(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, Float_t size, UChar_t col)
420 {
421  DrawLine(buf, w, h, cx-size, cy-size, cx+size, cy+size, col);
422  DrawLine(buf, w, h, cx+size, cy-size, cx-size, cy+size, col);
423 }
424 
425 void MGImage::DrawCross(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, Float_t size, UChar_t col)
426 {
427  DrawLine(buf, w, h, cx-size, cy, cx+size, cy, col);
428  DrawLine(buf, w, h, cx, cy-size, cx, cy+size, col);
429 }
430 
431 // --------------------------------------------------------------------------
432 //
433 // Draw marker into the buffer. The TObject must be a TMarker.
434 // Currently kCircle, kMultiply and KDot are supported.
435 /*
436 void MGImage::DrawMarker(TObject *o, UChar_t *buf, int w, int h, Double_t scale)
437 {
438  TMarker *m = dynamic_cast<TMarker*>(o);
439  if (!m)
440  return;
441 
442  Double_t x = 0.5*w-(m->GetX()/scale);
443  Double_t y = 0.5*h-(m->GetY()/scale);
444 
445  Int_t col = Color(m->GetMarkerColor());
446 
447  switch (m->GetMarkerStyle())
448  {
449  case kCircle:
450  DrawCircle(buf, w, h, x, y, m->GetMarkerSize()*2+1, col);
451  break;
452  case kDot:
453  DrawDot(buf, w, h, x, y, col);
454  break;
455  case kMultiply:
456  DrawMultiply(buf, w, h, x, y, m->GetMarkerSize()*2+1, col);
457  break;
458  case kCross:
459  DrawCross(buf, w, h, x, y, m->GetMarkerSize()*2+1, col);
460  break;
461  }
462 }
463 */
TMutex * fMuxPixmap
Definition: MGImage.h:31
static void DrawHexagon(UChar_t *buf, int w, int h, Float_t x, Float_t y, Float_t r, UChar_t col, Int_t style=1)
Definition: MGImage.cc:324
void DrawColImg(const byte *gbuf, const byte *cbuf)
Definition: MGImage.cc:210
Set color White.
Definition: WindowLog.h:23
void DrawColImg16(unsigned short *d, char *s1, char *s2, char *e)
Definition: MGImage.cc:162
void DoRedraw()
Definition: MGImage.cc:74
int i
Definition: db_dim_client.c:21
Set color Green.
Definition: WindowLog.h:18
Set color Yellow.
Definition: WindowLog.h:19
Set color Red.
Definition: WindowLog.h:17
UInt_t fHeight
Definition: MGImage.h:29
XImage * fImage
Definition: MGImage.h:23
STL namespace.
static void DrawMultiply(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, Float_t size, UChar_t col)
Definition: MGImage.cc:419
~MGImage()
Definition: MGImage.cc:57
UInt_t fWidth
Definition: MGImage.h:28
static void DrawCross(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, Float_t size, UChar_t col)
Definition: MGImage.cc:425
static UChar_t Color(int col)
Definition: MGImage.cc:259
static void DrawLine(UChar_t *buf, int w, int h, Float_t x1, Float_t y1, Float_t x2, Float_t y2, UChar_t col, Int_t style=1)
Definition: MGImage.cc:279
void DrawImg16(unsigned short *d, char *s, char *e)
Definition: MGImage.cc:97
unsigned char byte
Definition: MGImage.h:17
Set color Blue.
Definition: WindowLog.h:20
static void DrawDot(UChar_t *buf, int w, int h, Float_t cx, Float_t cy, UChar_t col)
Definition: MGImage.cc:389
MGImage(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options=kSunkenFrame, ULong_t back=fgDefaultFrameBackground)
Definition: MGImage.cc:34
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
uint16_t fId
Definition: HeadersFAD.h:93
int size
Definition: db_dim_server.c:17
void DrawColImg24(char *d, char *s1, char *s2, char *e)
Definition: MGImage.cc:186
void DrawImg(const byte *buffer)
Definition: MGImage.cc:127
static void DrawCircle(UChar_t *buf, int w, int h, Float_t x, Float_t y, Float_t r, UChar_t col)
Definition: MGImage.cc:350
void DrawImg24(char *d, char *s, char *e)
Definition: MGImage.cc:113
GContext_t fDefGC
Definition: MGImage.h:25
static void DrawBox(UChar_t *buf, int w, int h, Float_t x1, Float_t y1, Float_t x2, Float_t y2, UChar_t col, Int_t style=1)
Definition: MGImage.cc:311