tdaq-develop-2025-02-12
PixelHistoPicGen.cc
1 #include "PixelHistoPicGen.h"
2 #include <math.h>
3 #include <fstream>
4 #include <iostream>
5 #include <sstream>
6 
7 #include <stdlib.h>
8 
9 #define PI 3.14159265
10 
11 using namespace std;
12 
15 void transform(float& x, float& y, float m1, float m2, float m3, float m4)
16 {
17  float tx, ty;
18 
19  tx = x * m1 + y * m2;
20  ty = x * m3 + y * m4;
21 
22  x = tx;
23  y = ty;
24 }
25 
26 //================================================================================
27 //================================================================================
28 //================================================================================
29 
31 PixelHistoPicGen::PixelHistoPicGen()
32 {
33  std::string mthn = "[PixelHistoPicGen::PixelHistoPicGen()]\t";
34 
35  readImg_ = 0;
36  clickMask_ = 0;
37 
38  firstTurtle = true;
39 }
40 
42 PixelHistoPicGen::~PixelHistoPicGen()
43 {
44  //dealloc
45  if(readImg_)
46  {
47  for(int x = 0; x < readImgW_; ++x)
48  {
49  for(int y = 0; y < readImgH_; ++y)
50  delete[] readImg_[x][y];
51  delete[] readImg_[x];
52  }
53  delete[] readImg_;
54  readImg_ = 0;
55  }
56 }
57 
61 // {
62 // switch(sourceKey){
63 // case 1: //FPix disc bg img
64 // readBmpToReadImg("/tmp/detector.bmp");
65 // transferReadImgToImg();
66 // break;
67 // default:
68 // for(int x=0;x<IMG_WIDTH;++x)
69 // for(int y=0;y<IMG_HEIGHT;++y){
70 // img_[x][y][0] = 0;
71 // img_[x][y][1] = 0;
72 // img_[x][y][2] = 0;
73 // }
74 // }
75 // }
76 
80 // {
81 // switch(sourceKey){
82 // case 1: //BPix layer bg img
83 // readBmpToReadImg("/tmp/detector.bmp");
84 // transferReadImgToBImg();
85 // break;
86 // default:
87 // for(int x=0;x<BIMG_WIDTH;++x)
88 // for(int y=0;y<BIMG_HEIGHT;++y){
89 // bimg_[x][y][0] = 0;
90 // bimg_[x][y][1] = 0;
91 // bimg_[x][y][2] = 0;
92 // }
93 // }
94 // }
95 
98 // {
99 // for(int x=0;x<IMG_WIDTH;++x)
100 // for(int y=0;y<IMG_HEIGHT;++y){
101 // img_[x][y][0] = r;
102 // img_[x][y][1] = g;
103 // img_[x][y][2] = b;
104 // }
105 // }
106 
109 // {
110 // for(int x=0;x<BIMG_WIDTH;++x)
111 // for(int y=0;y<BIMG_HEIGHT;++y){
112 // bimg_[x][y][0] = r;
113 // bimg_[x][y][1] = g;
114 // bimg_[x][y][2] = b;
115 // }
116 // }
117 
120 void PixelHistoPicGen::readBmpToReadImg(const string& filename)
121 {
122  // string mthn = "[PicGen::readBMPToReadImg()]\t";
123 
124  ifstream file(filename.c_str(), ifstream::binary);
125  if(!file.is_open())
126  return;
127 
128  // cout << mthn << "Has file." << endl;
129 
130  //BMP Header
131  char buffer[64];
132  file.read(buffer, 2); //"BM"
133  unsigned int size;
134  file.read((char*)(&size), 4);
135  // cout << mthn << "size: " << size << endl;
136  file.read(buffer, 4);
137  unsigned int data_offset;
138  file.read((char*)(&data_offset), 4);
139  // cout << mthn << "doff: " << data_offset << endl;
140  unsigned int header_size;
141  file.read((char*)(&header_size), 4);
142  // cout << mthn << "hsize: " << header_size << endl;
143  unsigned int w, h;
144  file.read((char*)(&w), 4);
145  file.read((char*)(&h), 4);
146  // cout << mthn << w << " " << h << endl;
147  file.read(buffer, 2);
148  unsigned int depth = 0;
149  file.read((char*)(&depth), 2);
150  // cout << mthn << depth << endl;
151  if(depth != 24 && depth != 32)
152  {
153  file.close();
154  return;
155  }
156  // cout << mthn << "Depth correct." << endl;
157  unsigned int compr_method;
158  file.read((char*)(&compr_method), 4);
159  // cout << mthn << "method: " << compr_method << endl;
160 
161  //BMP Data
162  file.seekg(data_offset, ios_base::beg); //set file position to start of data
163 
164  //dealloc old
165  if(readImg_)
166  {
167  for(int x = 0; x < readImgW_; ++x)
168  {
169  for(int y = 0; y < readImgH_; ++y)
170  delete[] readImg_[x][y];
171  delete[] readImg_[x];
172  }
173  delete[] readImg_;
174  readImg_ = 0;
175  }
176 
177  //allocate
178  readImgW_ = w;
179  readImgH_ = h;
180  readImg_ = new unsigned char**[readImgW_];
181  for(int x = 0; x < readImgW_; ++x)
182  {
183  readImg_[x] = new unsigned char*[readImgH_];
184  for(int y = 0; y < readImgH_; ++y)
185  readImg_[x][y] = new unsigned char[3];
186  }
187 
188  //read data
189  for(int y = readImgH_ - 1; y >= 0; --y)
190  for(int x = 0; x < readImgW_; ++x)
191  {
192  for(int i = 2; i >= 0; --i)
193  file.read((char*)(&(readImg_[x][y][i])), 1);
194  if(depth == 32) //skip alpha byte
195  file.seekg(1, ios_base::cur); //skip one byte
196  }
197 
198  file.close();
199 }
200 
204 // {
205 // cout << "[PicGen::transferRimgToImg()]\t" << IMG_WIDTH << " " << IMG_HEIGHT << " " << readImgW_ << " " << readImgH_ << endl;
206 // if(IMG_WIDTH != readImgW_ && IMG_HEIGHT != readImgH_){
207 // cout << "[PicGen::transferRimgToImg()]\tInvalid dimensions." << endl;
208 // return;
209 // }
210 // for(int x=0;x<IMG_WIDTH;++x)
211 // for(int y=0;y<IMG_HEIGHT;++y){
212 // img_[x][y][0] = readImg_[x][y][0];
213 // img_[x][y][1] = readImg_[x][y][1];
214 // img_[x][y][2] = readImg_[x][y][2];
215 // }
216 // }
217 
221 // {
222 // cout << "[PicGen::transferRimgToBImg()]\t" << BIMG_WIDTH << " " << BIMG_HEIGHT << " " << readImgW_ << " " << readImgH_ << endl;
223 // if(BIMG_WIDTH != readImgW_ && BIMG_HEIGHT != readImgH_){
224 // cout << "[PicGen::transferRimgToBImg()]\tInvalid dimensions." << endl;
225 // return;
226 // }
227 // for(int x=0;x<BIMG_WIDTH;++x)
228 // for(int y=0;y<BIMG_HEIGHT;++y){
229 // bimg_[x][y][0] = readImg_[x][y][0];
230 // bimg_[x][y][1] = readImg_[x][y][1];
231 // bimg_[x][y][2] = readImg_[x][y][2];
232 // }
233 // }
234 
237 void PixelHistoPicGen::writeImgToBmp(string filename)
238 {
239  // BMP Header Stores general information about the BMP file.
240  // Bitmap Information (DIB header) Stores detailed information about the bitmap image.
241  // Color Palette Stores the definition of the colors being used for indexed color bitmaps.
242  // Bitmap Data Stores the actual image, pixel by pixel.
243 
244  ofstream file(filename.c_str(), ofstream::binary);
245  if(!file.is_open())
246  return;
247 
248  unsigned int bmpTemp;
249  bmpTemp = IMG_FILE_SIZE;
250 
251  //BMP Header
252  file << char(0x42) << char(0x4d); //"BM"
253  for(int i = 0; i < 4; ++i)
254  { //file size in little-endian
255  file << (unsigned char)(((char*)(&bmpTemp))[i]);
256  }
257  file << char(0x00) << char(0x00) << char(0x00)
258  << char(0x00); //0x00000000; //reserved bytes
259  file << char(0x36) << char(0x00) << char(0x00)
260  << char(0x00); //0x36000000; //offset to data
261  file << char(0x28) << char(0x00) << char(0x00)
262  << char(0x00); //0x28000000; //size of DIB header
263  for(int i = 0, bmpTemp = IMG_WIDTH; i < 4; ++i)
264  { //img pixel width in little-endian
265  file << (unsigned char)(((char*)(&bmpTemp))[i]);
266  }
267  for(int i = 0, bmpTemp = IMG_HEIGHT; i < 4; ++i)
268  { //img pixel height in little-endian
269  file << (unsigned char)(((char*)(&bmpTemp))[i]);
270  }
271  file << char(0x01) << char(0x00) << char(0x18) << char(0x00) << char(0x00)
272  << char(0x00) << char(0x00) << char(0x00); //details and 24-bit depth
273  for(int i = 0, bmpTemp = IMG_RAW_SIZE; i < 4; ++i)
274  { //file raw data size in little-endian
275  file << (unsigned char)(((char*)(&bmpTemp))[i]);
276  }
277 
278  file << char(0x00) << char(0x00) << char(0x00) << char(0x00) << char(0x00)
279  << char(0x00) << char(0x00) << char(0x00) << char(0x00) << char(0x00)
280  << char(0x00) << char(0x00) << char(0x00) << char(0x00) << char(0x00)
281  << char(0x00); //finish header details
282 
283  //BMP Data
284 
285  for(int y = IMG_HEIGHT - 1; y >= 0; --y)
286  for(int x = 0; x < IMG_WIDTH; ++x)
287  for(int i = 2; i >= 0; --i)
288  {
289  file << img_[x][y][i];
290  }
291 
292  file.close();
293 }
294 
296 void PixelHistoPicGen::convertBmp(const std::string& fileBMP,
297  const std::string& convertFile)
298 {
299  string convertCmd = "convert " + fileBMP + " " + convertFile;
300  system(convertCmd.c_str());
301 }
302 
304 void PixelHistoPicGen::drawFillRectAng(
305  int x, int y, int w, int h, int r, int g, int b, float deg)
306 {
307  float rad = deg * PI / 180.0f;
308  drawFillRect(x, y, w, h, r, g, b, cos(rad), -sin(rad), sin(rad), cos(rad));
309 }
310 
314  int y,
315  int w,
316  int h,
317  int r,
318  int g,
319  int b,
320  float m1,
321  float m2,
322  float m3,
323  float m4)
324 {
325  float up[2] = {0.0f, 1.0f};
326 
327  transform(up[0], up[1], m1, m2, m3, m4); //transform up vector
328 
329  float rt[2] = {up[1], -up[0]}; //get rt from up vector
330 
331  float px = (float)x;
332  float py = (float)y;
333  float tpx, tpy;
334 
335  for(int i = 0; i < w * 2; ++i)
336  {
337  tpx = px;
338  tpy = py;
339  for(float j = 0; j < h * 2; ++j)
340  {
341  setImgPixel((int)px, (int)py, r, g, b);
342  px += up[0] / 2.0f;
343  py += up[1] / 2.0f;
344  }
345  px = tpx + rt[0] / 2.0f;
346  py = tpy + rt[1] / 2.0f;
347  }
348 }
349 
351 void PixelHistoPicGen::setImgPixel(int x, int y, int r, int g, int b)
352 {
353  img_[x][y][0] = r;
354  img_[x][y][1] = g;
355  img_[x][y][2] = b;
356 }
357 
360 // {
361 // //fpix_[4][2][2][12][24][3];
362 // for(int a=0;a<4;++a)
363 // for(int b=0;b<2;++b)
364 // for(int c=0;c<2;++c)
365 // for(int d=0;d<12;++d)
366 // for(int e=0;e<24;++e){
367 // fpix_[a][b][c][d][e][0] = COLOR_INIT_R;
368 // fpix_[a][b][c][d][e][1] = COLOR_INIT_G;
369 // fpix_[a][b][c][d][e][2] = COLOR_INIT_B;
370 // }
371 // }
372 
375 // {
376 // if(stdName[0] == 'F'){
377 // int a,b,c,d,e;
378 // getFPixIndices(stdName,a,b,c,d,e);
379 // fpix_[a][b][c][d][e][0] = rd;
380 // fpix_[a][b][c][d][e][1] = gn;
381 // fpix_[a][b][c][d][e][2] = bl;
382 // }
383 // else if(stdName[0] == 'B'){
384 // int a,b,c,d;
385 // getBPixIndices(stdName,a,b,c,d);
386 // bpix_(a,b,c,d,0) = rd;
387 // bpix_(a,b,c,d,1) = gn;
388 // bpix_(a,b,c,d,2) = bl;
389 // }
390 // else
391 // cout << "PixelHistoPicGen::setRocColor()\tFailed." << endl;
392 // }
393 
394 
395 void recurseForBg(unsigned char*** d, int r, int c, int rm, int cm)
396 {
397  if(r == rm || c == cm || r < 0 || c < 0)
398  return;
399 
400  if(d[r][c][0] == 255 && d[r][c][1] == 0 && d[r][c][2] == 0) //already found
401  return;
402 
403  if(d[r][c][0] > 100)
404  { //white so mark & check for neighbors
405  d[r][c][0] = 255;
406  d[r][c][1] = 0;
407  d[r][c][2] = 0;
408  recurseForBg(d, r + 1, c, rm, cm); //right
409  recurseForBg(d, r - 1, c, rm, cm); //left
410  recurseForBg(d, r, c - 1, rm, cm); //up
411  recurseForBg(d, r, c + 1, rm, cm); //dn
412  }
413 }
414 
415 #include <sys/stat.h> // for mkdir
416 void PixelHistoPicGen::generateTurtle(const std::string& filepath)
417 {
418  std::string tmpPath = filepath + "generated/tmp.bmp";
419  int offSetH;
420 
421  if(firstTurtle)
422  { //create first turtle
423  firstTurtle = false;
424 
425  // attempt to make directory structure (just in case)
426  mkdir((filepath + "generated").c_str(), 0755);
427 
428  readBmpToReadImg(filepath + "turtle.bmp");
429 
430  if(readImgW_ == 0)
431  return;
432 
433  offSetH = (TUR_IMG_HEIGHT - readImgH_) / 2;
434 
435  clearTurtleBuffer(255, 255, 255, 255);
436 
437  recurseForBg(readImg_, 0, 0, readImgW_, readImgH_);
438  recurseForBg(readImg_, 150, readImgH_ - 1, readImgW_, readImgH_);
439 
440  // std::cout << "readImgW_ " << readImgW_ << std::endl;
441  // std::cout << "readImgH_ " << readImgH_ << std::endl;
442  for(int i = 0; i < readImgW_; ++i)
443  for(int j = 0; j < readImgH_; ++j)
444  {
445  if(readImg_[i][j][0] < 60 && readImg_[i][j][1] > 130)
446  {
447  turtleImg_[i][offSetH + j][0] = 0;
448  turtleImg_[i][offSetH + j][1] = 0;
449  turtleImg_[i][offSetH + j][2] = 255;
450  // cout << (int)readImg_[i][j][0] << " " << (int)readImg_[i][j][1] << " " << (int)readImg_[i][j][2] <<endl;
451  }
452  else
453  for(int k = 0; k < 3; ++k)
454  turtleImg_[i][offSetH + j][k] = readImg_[i][j][k];
455 
456  if(readImg_[i][j][0] == 255 && readImg_[i][j][1] == 0 &&
457  readImg_[i][j][2] == 0)
458  turtleImg_[i][offSetH + j][3] = 0; //invisible
459  else
460  turtleImg_[i][offSetH + j][3] = 255;
461  }
462 
463  writeTurtleToBmp((filepath + "generated/turtleBase.bmp").c_str());
464  }
465 
466  //change color
467  readBmpToReadImg(filepath + "generated/turtleBase.bmp");
468  offSetH = (TUR_IMG_HEIGHT - readImgH_) / 2;
469 
470  int rd = clock() % 256;
471  int gn = (clock() / 3) % 256;
472  int bl = (clock() * 3) % 256;
473 
474  for(int i = 0; i < readImgW_; ++i)
475  for(int j = 0; j < readImgH_; ++j)
476  if(readImg_[i][j][0] == 0 && readImg_[i][j][1] == 0 &&
477  readImg_[i][j][2] == 255)
478  {
479  turtleImg_[i][offSetH + j][0] = rd;
480  turtleImg_[i][offSetH + j][1] = gn;
481  turtleImg_[i][offSetH + j][2] = bl;
482  }
483 
484  writeTurtleToBmp(tmpPath.c_str());
485  convertBmp(tmpPath, filepath + "generated/turtle.png");
486 } //end generateTurtle()
487 
492 // {
493 //
494 // //create good/bad boxes
495 // char tmpPath[] = "images/generated/tmp.bmp";
496 //
497 // clearAuxBuffer(COLOR_GOOD_R,COLOR_GOOD_G,COLOR_GOOD_B,0);
498 // writeAuxToBmp(tmpPath);
499 // convertBmp(tmpPath,"images/generated/good.png");
500 //
501 // clearAuxBuffer(COLOR_BAD_R,COLOR_BAD_G,COLOR_BAD_B,0);
502 // writeAuxToBmp(tmpPath);
503 // convertBmp(tmpPath,"images/generated/bad.png");
504 //
505 // clearAuxBuffer(COLOR_INIT_R,COLOR_INIT_G,COLOR_INIT_B,0);
506 // writeAuxToBmp(tmpPath);
507 // convertBmp(tmpPath,"images/generated/off.png");
508 //
509 // clearAuxBuffer(0,0,0,255);
510 // writeAuxToBmp(tmpPath);
511 // convertBmp(tmpPath,"images/generated/invisible.png");
512 //
513 // clearAuxBuffer(COLOR_HIGHLIGHT_R,COLOR_HIGHLIGHT_G,COLOR_HIGHLIGHT_B,0);
514 // writeAuxToBmp(tmpPath);
515 // convertBmp(tmpPath,"images/generated/rocHighlight.png");
516 //
517 // //create alpha-background roc highlights
518 // char convertPng[1000];
519 // for(int i=0;i<6;++i){ //draw all 6 angles
520 // clearAuxBuffer(0,0,0,255);
521 //
522 // drawFillRectAngAux(AUX_IMG_WIDTH/2+1,
523 // AUX_IMG_HEIGHT/2+1,
524 // WEB_ROC_SIZE*2+8,
525 // WEB_ROC_SIZE*2+8,
526 // COLOR_HIGHLIGHT_R,COLOR_HIGHLIGHT_G,COLOR_HIGHLIGHT_B,
527 // 7.5+i*15);
528 //
529 // writeAuxToBmp(tmpPath);
530 // sprintf(convertPng,"images/generated/rocHighlight%d.png",i);
531 // convertBmp(tmpPath,convertPng);
532 // }
533 //
534 // //create summary color keys
535 // //for boolean
536 // for(int x=0;x<IMG_WIDTH;++x)
537 // for(int y=0;y<IMG_HEIGHT;++y)
538 // setImgPixel(x,y,
539 // x>IMG_WIDTH/2?COLOR_GOOD_R:COLOR_BAD_R,
540 // x>IMG_WIDTH/2?COLOR_GOOD_G:COLOR_BAD_G,
541 // x>IMG_WIDTH/2?COLOR_GOOD_B:COLOR_BAD_B);
542 //
543 // writeImgToBmp(tmpPath);
544 // convertBmp(tmpPath,"images/generated/summaryColorKeyBoolean.png");
545 //
546 // //must be the same code as invoid PixelHistoViewer::colorRocsWithField(TTree *summary, string field) to match key
547 // int numOfColors = 6;
548 // int colors[6][3] = {
549 // {255,0,255},
550 // {0,0,255},
551 // {0,255,255},
552 // {0,255,0},
553 // {255,255,0},
554 // {255,0,0},
555 // };
556 //
557 // float v;
558 // float sizeOfGrade = 1.0/(numOfColors-1);
559 // int ci;
560 //
561 // //blended color key
562 // for(int x=0;x<IMG_WIDTH;++x)
563 // for(int y=0;y<IMG_HEIGHT;++y)
564 // {
565 //
566 // v = (float)x/IMG_WIDTH;
567 // ci = (int)(v/sizeOfGrade);
568 // v -= ci*sizeOfGrade;
569 // v /= sizeOfGrade; //0-1
570 // setImgPixel(x,y,
571 // (int)(colors[ci][0]*(1-v) + colors[ci+1][0]*v),
572 // (int)(colors[ci][1]*(1-v) + colors[ci+1][1]*v),
573 // (int)(colors[ci][2]*(1-v) + colors[ci+1][2]*v));
574 // }
575 //
576 // writeImgToBmp(tmpPath);
577 // convertBmp(tmpPath,"images/generated/summaryColorKey.png");
578 //
579 // //for overflow
580 // clearAuxBuffer(COLOR_HI_R,COLOR_HI_G,COLOR_HI_B,0);
581 // writeAuxToBmp(tmpPath);
582 // convertBmp(tmpPath,"images/generated/summaryOverflowKey.png");
583 // //for underflow
584 // clearAuxBuffer(COLOR_LO_R,COLOR_LO_G,COLOR_LO_B,0);
585 // writeAuxToBmp(tmpPath);
586 // convertBmp(tmpPath,"images/generated/summaryUnderflowKey.png");
587 // }
588 
591 void PixelHistoPicGen::clearTurtleBuffer(int r, int g, int b, int a)
592 {
593  for(int x = 0; x < TUR_IMG_WIDTH; ++x)
594  for(int y = 0; y < TUR_IMG_HEIGHT; ++y)
595  {
596  turtleImg_[x][y][0] = r;
597  turtleImg_[x][y][1] = g;
598  turtleImg_[x][y][2] = b;
599  turtleImg_[x][y][3] = a; //255 is invisible, 0 is opaque
600  }
601 }
602 
604 void PixelHistoPicGen::writeTurtleToBmp(const char* fn)
605 {
606  string mthn = "[PicGen::writeTurtleToBmp()]\t";
607 
608  // BMP Header Stores general information about the BMP file.
609  // Bitmap Information (DIB header) Stores detailed information about the bitmap image.
610  // Color Palette Stores the definition of the colors being used for indexed color bitmaps.
611  // Bitmap Data Stores the actual image, pixel by pixel.
612 
613  ofstream file(fn, ofstream::binary);
614  if(!file.is_open())
615  return;
616 
617  unsigned int bmpTemp;
618 
619  //BMP Header
620  file << char(0x42) << char(0x4d); //"BM"
621  bmpTemp = TUR_IMG_FILE_SIZE;
622  for(int i = 0; i < 4; ++i) //file size in little-endian
623  file << (unsigned char)(((char*)(&bmpTemp))[i]);
624  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //reserved bytes
625  unsigned int dibHeaderSize = TUR_IMG_HEADER_SIZE + 14;
626  for(int i = 0; i < 4; ++i) //DIB header size
627  file << (unsigned char)(((char*)(&dibHeaderSize))[i]);
628  bmpTemp = TUR_IMG_HEADER_SIZE;
629  for(int i = 0; i < 4; ++i) //offset to data
630  file << (unsigned char)(((char*)(&bmpTemp))[i]);
631  bmpTemp = TUR_IMG_WIDTH;
632  for(int i = 0; i < 4; ++i) //img pixel width in little-endian
633  file << (unsigned char)(((char*)(&bmpTemp))[i]);
634  bmpTemp = TUR_IMG_HEIGHT;
635  for(int i = 0; i < 4; ++i) //img pixel height in little-endian
636  file << (unsigned char)(((char*)(&bmpTemp))[i]);
637  file << char(0x01) << char(0x00) << char(0x20)
638  << char(0x00); //color planes and bits per pixel
639  file << char(0x03) << char(0x00) << char(0x00) << char(0x00); //compression method
640  bmpTemp = TUR_IMG_RAW_SIZE;
641  for(int i = 0; i < 4; ++i) //file raw data size in little-endian
642  file << (unsigned char)(((char*)(&bmpTemp))[i]);
643  file << char(0xD6) << char(0x0D) << char(0x00)
644  << char(0x00); //horiz resol in pixels per meter
645  file << char(0xD6) << char(0x0D) << char(0x00)
646  << char(0x00); //vert resol in pixels per meter
647  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //colors used
648  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //important colors
649  file << char(0x00) << char(0x00) << char(0xFF) << char(0x00); //red mask
650  file << char(0x00) << char(0xFF) << char(0x00) << char(0x00); //green mask
651  file << char(0xFF) << char(0x00) << char(0x00) << char(0x00); //blue mask
652  file << char(0x00) << char(0x00) << char(0x00) << char(0xFF); //alpha mask
653  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //color space
654  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red X
655  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red Y
656  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //red Z
657  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green X
658  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green Y
659  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //green Z
660  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue X
661  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue Y
662  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //blue Z
663  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma red
664  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma green
665  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma blue
666 
667  //BMP Data
668 
669  int bytesToPad = (4 - TUR_IMG_WIDTH * 4 % 4) %
670  4; //each row must start on a multiple of 4 byte offset
671  for(int y = TUR_IMG_HEIGHT - 1; y >= 0; --y)
672  {
673  for(int x = 0; x < TUR_IMG_WIDTH; ++x)
674  {
675  for(int i = 2; i >= 0; --i)
676  {
677  file << turtleImg_[x][y][i];
678  }
679  file << turtleImg_[x][y][3]; //alpha byte last
680  }
681  //pad bytes
682  for(int p = 0; p < bytesToPad; ++p)
683  file << char(0x00);
684  }
685 
686  file.close();
687 }
689 void PixelHistoPicGen::writeAuxToBmp(char* fn)
690 {
691  string mthn = "[PicGen::writeAuxToBmp()]\t";
692 
693  // BMP Header Stores general information about the BMP file.
694  // Bitmap Information (DIB header) Stores detailed information about the bitmap image.
695  // Color Palette Stores the definition of the colors being used for indexed color bitmaps.
696  // Bitmap Data Stores the actual image, pixel by pixel.
697 
698  ofstream file(fn, ofstream::binary);
699  if(!file.is_open())
700  return;
701 
702  unsigned int bmpTemp;
703 
704  //BMP Header
705  file << char(0x42) << char(0x4d); //"BM"
706  bmpTemp = AUX_IMG_FILE_SIZE;
707  for(int i = 0; i < 4; ++i) //file size in little-endian
708  file << (unsigned char)(((char*)(&bmpTemp))[i]);
709  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //reserved bytes
710  unsigned int dibHeaderSize = AUX_IMG_HEADER_SIZE + 14;
711  for(int i = 0; i < 4; ++i) //DIB header size
712  file << (unsigned char)(((char*)(&dibHeaderSize))[i]);
713  bmpTemp = AUX_IMG_HEADER_SIZE;
714  for(int i = 0; i < 4; ++i) //offset to data
715  file << (unsigned char)(((char*)(&bmpTemp))[i]);
716  bmpTemp = AUX_IMG_WIDTH;
717  for(int i = 0; i < 4; ++i) //img pixel width in little-endian
718  file << (unsigned char)(((char*)(&bmpTemp))[i]);
719  bmpTemp = AUX_IMG_HEIGHT;
720  for(int i = 0; i < 4; ++i) //img pixel height in little-endian
721  file << (unsigned char)(((char*)(&bmpTemp))[i]);
722  file << char(0x01) << char(0x00) << char(0x20)
723  << char(0x00); //color planes and bits per pixel
724  file << char(0x03) << char(0x00) << char(0x00) << char(0x00); //compression method
725  bmpTemp = AUX_IMG_RAW_SIZE;
726  for(int i = 0; i < 4; ++i) //file raw data size in little-endian
727  file << (unsigned char)(((char*)(&bmpTemp))[i]);
728  file << char(0xD6) << char(0x0D) << char(0x00)
729  << char(0x00); //horiz resol in pixels per meter
730  file << char(0xD6) << char(0x0D) << char(0x00)
731  << char(0x00); //vert resol in pixels per meter
732  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //colors used
733  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //important colors
734  file << char(0x00) << char(0x00) << char(0xFF) << char(0x00); //red mask
735  file << char(0x00) << char(0xFF) << char(0x00) << char(0x00); //green mask
736  file << char(0xFF) << char(0x00) << char(0x00) << char(0x00); //blue mask
737  file << char(0x00) << char(0x00) << char(0x00) << char(0xFF); //alpha mask
738  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //color space
739  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red X
740  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red Y
741  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //red Z
742  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green X
743  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green Y
744  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //green Z
745  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue X
746  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue Y
747  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //blue Z
748  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma red
749  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma green
750  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma blue
751 
752  //BMP Data
753 
754  int bytesToPad = (4 - AUX_IMG_WIDTH * 4 % 4) %
755  4; //each row must start on a multiple of 4 byte offset
756  for(int y = AUX_IMG_HEIGHT - 1; y >= 0; --y)
757  {
758  for(int x = 0; x < AUX_IMG_WIDTH; ++x)
759  {
760  for(int i = 2; i >= 0; --i)
761  {
762  file << auxImg_[x][y][i];
763  }
764  file << auxImg_[x][y][3]; //alpha byte last
765  }
766  //pad bytes
767  for(int p = 0; p < bytesToPad; ++p)
768  file << char(0x00);
769  }
770 
771  file.close();
772 }
773 
778  int y,
779  int w,
780  int h,
781  int r,
782  int g,
783  int b,
784  float m1,
785  float m2,
786  float m3,
787  float m4)
788 {
789  float up[2] = {0.0f, 1.0f};
790 
791  transform(up[0], up[1], m1, m2, m3, m4); //transform up vector
792 
793  float rt[2] = {up[1], -up[0]}; //get rt from up vector
794 
795  float px = (float)x - up[0] * 0.5 * w -
796  rt[0] * 0.5 * w; //subtract to get to bottom left corner
797  float py = (float)y - up[1] * 0.5 * h - rt[1] * 0.5 * h;
798  float tpx, tpy;
799 
800  for(int i = 0; i < w * 2; ++i)
801  {
802  tpx = px;
803  tpy = py;
804  for(float j = 0; j < h * 2; ++j)
805  {
806  setAuxPixel((int)px, (int)py, r, g, b);
807  px += up[0] / 2.0f;
808  py += up[1] / 2.0f;
809  }
810  px = tpx + rt[0] / 2.0f;
811  py = tpy + rt[1] / 2.0f;
812  }
813 }
814 
819  int x, int y, int w, int h, int r, int g, int b, float deg)
820 {
821  float rad = deg * PI / 180.0f;
822  drawFillRectAux(x, y, w, h, r, g, b, cos(rad), -sin(rad), sin(rad), cos(rad));
823 }
824 
826 void PixelHistoPicGen::setAuxPixel(int x, int y, int r, int g, int b)
827 {
828  auxImg_[x][y][0] = r;
829  auxImg_[x][y][1] = g;
830  auxImg_[x][y][2] = b;
831  auxImg_[x][y][3] = 0;
832 }
833 
void drawFillRect(int x, int y, int w, int h, int r, int g, int b, float m1=1.0f, float m2=0.0f, float m3=0.0f, float m4=1.0f)
draws rect to img buffer. {x,y} is lower left corner. d is degrees of rotation around z-axis.
void writeImgToBmp(std::string filename)
write img buffer to bmp file
void readBmpToReadImg(const std::string &filename)
read bmp file to readImg_ buffer
void clearTurtleBuffer(int r, int g, int b, int a)
initializes aux buffer to all invisible black pixels
void drawFillRectAngAux(int x, int y, int w, int h, int r, int g, int b, float deg)
void drawFillRectAux(int x, int y, int w, int h, int r, int g, int b, float m1=1.0f, float m2=0.0f, float m3=0.0f, float m4=1.0f)