otsdaq  3.03.00
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 void recurseForBg(unsigned char*** d, int r, int c, int rm, int cm)
395 {
396  if(r == rm || c == cm || r < 0 || c < 0)
397  return;
398 
399  if(d[r][c][0] == 255 && d[r][c][1] == 0 && d[r][c][2] == 0) //already found
400  return;
401 
402  if(d[r][c][0] > 100)
403  { //white so mark & check for neighbors
404  d[r][c][0] = 255;
405  d[r][c][1] = 0;
406  d[r][c][2] = 0;
407  recurseForBg(d, r + 1, c, rm, cm); //right
408  recurseForBg(d, r - 1, c, rm, cm); //left
409  recurseForBg(d, r, c - 1, rm, cm); //up
410  recurseForBg(d, r, c + 1, rm, cm); //dn
411  }
412 }
413 
414 #include <sys/stat.h> // for mkdir
415 void PixelHistoPicGen::generateTurtle(const std::string& filepath)
416 {
417  std::string tmpPath = filepath + "generated/tmp.bmp";
418  int offSetH;
419 
420  if(firstTurtle)
421  { //create first turtle
422  firstTurtle = false;
423 
424  // attempt to make directory structure (just in case)
425  mkdir((filepath + "generated").c_str(), 0755);
426 
427  readBmpToReadImg(filepath + "turtle.bmp");
428 
429  if(readImgW_ == 0)
430  return;
431 
432  offSetH = (TUR_IMG_HEIGHT - readImgH_) / 2;
433 
434  clearTurtleBuffer(255, 255, 255, 255);
435 
436  recurseForBg(readImg_, 0, 0, readImgW_, readImgH_);
437  recurseForBg(readImg_, 150, readImgH_ - 1, readImgW_, readImgH_);
438 
439  // std::cout << "readImgW_ " << readImgW_ << std::endl;
440  // std::cout << "readImgH_ " << readImgH_ << std::endl;
441  for(int i = 0; i < readImgW_; ++i)
442  for(int j = 0; j < readImgH_; ++j)
443  {
444  if(readImg_[i][j][0] < 60 && readImg_[i][j][1] > 130)
445  {
446  turtleImg_[i][offSetH + j][0] = 0;
447  turtleImg_[i][offSetH + j][1] = 0;
448  turtleImg_[i][offSetH + j][2] = 255;
449  // cout << (int)readImg_[i][j][0] << " " << (int)readImg_[i][j][1] << " " << (int)readImg_[i][j][2] <<endl;
450  }
451  else
452  for(int k = 0; k < 3; ++k)
453  turtleImg_[i][offSetH + j][k] = readImg_[i][j][k];
454 
455  if(readImg_[i][j][0] == 255 && readImg_[i][j][1] == 0 &&
456  readImg_[i][j][2] == 0)
457  turtleImg_[i][offSetH + j][3] = 0; //invisible
458  else
459  turtleImg_[i][offSetH + j][3] = 255;
460  }
461 
462  writeTurtleToBmp((filepath + "generated/turtleBase.bmp").c_str());
463  }
464 
465  //change color
466  readBmpToReadImg(filepath + "generated/turtleBase.bmp");
467  offSetH = (TUR_IMG_HEIGHT - readImgH_) / 2;
468 
469  int rd = clock() % 256;
470  int gn = (clock() / 3) % 256;
471  int bl = (clock() * 3) % 256;
472 
473  for(int i = 0; i < readImgW_; ++i)
474  for(int j = 0; j < readImgH_; ++j)
475  if(readImg_[i][j][0] == 0 && readImg_[i][j][1] == 0 &&
476  readImg_[i][j][2] == 255)
477  {
478  turtleImg_[i][offSetH + j][0] = rd;
479  turtleImg_[i][offSetH + j][1] = gn;
480  turtleImg_[i][offSetH + j][2] = bl;
481  }
482 
483  writeTurtleToBmp(tmpPath.c_str());
484  convertBmp(tmpPath, filepath + "generated/turtle.png");
485 } //end generateTurtle()
486 
491 // {
492 //
493 // //create good/bad boxes
494 // char tmpPath[] = "images/generated/tmp.bmp";
495 //
496 // clearAuxBuffer(COLOR_GOOD_R,COLOR_GOOD_G,COLOR_GOOD_B,0);
497 // writeAuxToBmp(tmpPath);
498 // convertBmp(tmpPath,"images/generated/good.png");
499 //
500 // clearAuxBuffer(COLOR_BAD_R,COLOR_BAD_G,COLOR_BAD_B,0);
501 // writeAuxToBmp(tmpPath);
502 // convertBmp(tmpPath,"images/generated/bad.png");
503 //
504 // clearAuxBuffer(COLOR_INIT_R,COLOR_INIT_G,COLOR_INIT_B,0);
505 // writeAuxToBmp(tmpPath);
506 // convertBmp(tmpPath,"images/generated/off.png");
507 //
508 // clearAuxBuffer(0,0,0,255);
509 // writeAuxToBmp(tmpPath);
510 // convertBmp(tmpPath,"images/generated/invisible.png");
511 //
512 // clearAuxBuffer(COLOR_HIGHLIGHT_R,COLOR_HIGHLIGHT_G,COLOR_HIGHLIGHT_B,0);
513 // writeAuxToBmp(tmpPath);
514 // convertBmp(tmpPath,"images/generated/rocHighlight.png");
515 //
516 // //create alpha-background roc highlights
517 // char convertPng[1000];
518 // for(int i=0;i<6;++i){ //draw all 6 angles
519 // clearAuxBuffer(0,0,0,255);
520 //
521 // drawFillRectAngAux(AUX_IMG_WIDTH/2+1,
522 // AUX_IMG_HEIGHT/2+1,
523 // WEB_ROC_SIZE*2+8,
524 // WEB_ROC_SIZE*2+8,
525 // COLOR_HIGHLIGHT_R,COLOR_HIGHLIGHT_G,COLOR_HIGHLIGHT_B,
526 // 7.5+i*15);
527 //
528 // writeAuxToBmp(tmpPath);
529 // sprintf(convertPng,"images/generated/rocHighlight%d.png",i);
530 // convertBmp(tmpPath,convertPng);
531 // }
532 //
533 // //create summary color keys
534 // //for boolean
535 // for(int x=0;x<IMG_WIDTH;++x)
536 // for(int y=0;y<IMG_HEIGHT;++y)
537 // setImgPixel(x,y,
538 // x>IMG_WIDTH/2?COLOR_GOOD_R:COLOR_BAD_R,
539 // x>IMG_WIDTH/2?COLOR_GOOD_G:COLOR_BAD_G,
540 // x>IMG_WIDTH/2?COLOR_GOOD_B:COLOR_BAD_B);
541 //
542 // writeImgToBmp(tmpPath);
543 // convertBmp(tmpPath,"images/generated/summaryColorKeyBoolean.png");
544 //
545 // //must be the same code as invoid PixelHistoViewer::colorRocsWithField(TTree *summary, string field) to match key
546 // int numOfColors = 6;
547 // int colors[6][3] = {
548 // {255,0,255},
549 // {0,0,255},
550 // {0,255,255},
551 // {0,255,0},
552 // {255,255,0},
553 // {255,0,0},
554 // };
555 //
556 // float v;
557 // float sizeOfGrade = 1.0/(numOfColors-1);
558 // int ci;
559 //
560 // //blended color key
561 // for(int x=0;x<IMG_WIDTH;++x)
562 // for(int y=0;y<IMG_HEIGHT;++y)
563 // {
564 //
565 // v = (float)x/IMG_WIDTH;
566 // ci = (int)(v/sizeOfGrade);
567 // v -= ci*sizeOfGrade;
568 // v /= sizeOfGrade; //0-1
569 // setImgPixel(x,y,
570 // (int)(colors[ci][0]*(1-v) + colors[ci+1][0]*v),
571 // (int)(colors[ci][1]*(1-v) + colors[ci+1][1]*v),
572 // (int)(colors[ci][2]*(1-v) + colors[ci+1][2]*v));
573 // }
574 //
575 // writeImgToBmp(tmpPath);
576 // convertBmp(tmpPath,"images/generated/summaryColorKey.png");
577 //
578 // //for overflow
579 // clearAuxBuffer(COLOR_HI_R,COLOR_HI_G,COLOR_HI_B,0);
580 // writeAuxToBmp(tmpPath);
581 // convertBmp(tmpPath,"images/generated/summaryOverflowKey.png");
582 // //for underflow
583 // clearAuxBuffer(COLOR_LO_R,COLOR_LO_G,COLOR_LO_B,0);
584 // writeAuxToBmp(tmpPath);
585 // convertBmp(tmpPath,"images/generated/summaryUnderflowKey.png");
586 // }
587 
590 void PixelHistoPicGen::clearTurtleBuffer(int r, int g, int b, int a)
591 {
592  for(int x = 0; x < TUR_IMG_WIDTH; ++x)
593  for(int y = 0; y < TUR_IMG_HEIGHT; ++y)
594  {
595  turtleImg_[x][y][0] = r;
596  turtleImg_[x][y][1] = g;
597  turtleImg_[x][y][2] = b;
598  turtleImg_[x][y][3] = a; //255 is invisible, 0 is opaque
599  }
600 }
601 
603 void PixelHistoPicGen::writeTurtleToBmp(const char* fn)
604 {
605  string mthn = "[PicGen::writeTurtleToBmp()]\t";
606 
607  // BMP Header Stores general information about the BMP file.
608  // Bitmap Information (DIB header) Stores detailed information about the bitmap image.
609  // Color Palette Stores the definition of the colors being used for indexed color bitmaps.
610  // Bitmap Data Stores the actual image, pixel by pixel.
611 
612  ofstream file(fn, ofstream::binary);
613  if(!file.is_open())
614  return;
615 
616  unsigned int bmpTemp;
617 
618  //BMP Header
619  file << char(0x42) << char(0x4d); //"BM"
620  bmpTemp = TUR_IMG_FILE_SIZE;
621  for(int i = 0; i < 4; ++i) //file size in little-endian
622  file << (unsigned char)(((char*)(&bmpTemp))[i]);
623  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //reserved bytes
624  unsigned int dibHeaderSize = TUR_IMG_HEADER_SIZE + 14;
625  for(int i = 0; i < 4; ++i) //DIB header size
626  file << (unsigned char)(((char*)(&dibHeaderSize))[i]);
627  bmpTemp = TUR_IMG_HEADER_SIZE;
628  for(int i = 0; i < 4; ++i) //offset to data
629  file << (unsigned char)(((char*)(&bmpTemp))[i]);
630  bmpTemp = TUR_IMG_WIDTH;
631  for(int i = 0; i < 4; ++i) //img pixel width in little-endian
632  file << (unsigned char)(((char*)(&bmpTemp))[i]);
633  bmpTemp = TUR_IMG_HEIGHT;
634  for(int i = 0; i < 4; ++i) //img pixel height in little-endian
635  file << (unsigned char)(((char*)(&bmpTemp))[i]);
636  file << char(0x01) << char(0x00) << char(0x20)
637  << char(0x00); //color planes and bits per pixel
638  file << char(0x03) << char(0x00) << char(0x00) << char(0x00); //compression method
639  bmpTemp = TUR_IMG_RAW_SIZE;
640  for(int i = 0; i < 4; ++i) //file raw data size in little-endian
641  file << (unsigned char)(((char*)(&bmpTemp))[i]);
642  file << char(0xD6) << char(0x0D) << char(0x00)
643  << char(0x00); //horiz resol in pixels per meter
644  file << char(0xD6) << char(0x0D) << char(0x00)
645  << char(0x00); //vert resol in pixels per meter
646  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //colors used
647  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //important colors
648  file << char(0x00) << char(0x00) << char(0xFF) << char(0x00); //red mask
649  file << char(0x00) << char(0xFF) << char(0x00) << char(0x00); //green mask
650  file << char(0xFF) << char(0x00) << char(0x00) << char(0x00); //blue mask
651  file << char(0x00) << char(0x00) << char(0x00) << char(0xFF); //alpha mask
652  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //color space
653  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red X
654  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red Y
655  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //red Z
656  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green X
657  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green Y
658  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //green Z
659  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue X
660  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue Y
661  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //blue Z
662  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma red
663  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma green
664  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma blue
665 
666  //BMP Data
667 
668  int bytesToPad = (4 - TUR_IMG_WIDTH * 4 % 4) %
669  4; //each row must start on a multiple of 4 byte offset
670  for(int y = TUR_IMG_HEIGHT - 1; y >= 0; --y)
671  {
672  for(int x = 0; x < TUR_IMG_WIDTH; ++x)
673  {
674  for(int i = 2; i >= 0; --i)
675  {
676  file << turtleImg_[x][y][i];
677  }
678  file << turtleImg_[x][y][3]; //alpha byte last
679  }
680  //pad bytes
681  for(int p = 0; p < bytesToPad; ++p)
682  file << char(0x00);
683  }
684 
685  file.close();
686 }
688 void PixelHistoPicGen::writeAuxToBmp(char* fn)
689 {
690  string mthn = "[PicGen::writeAuxToBmp()]\t";
691 
692  // BMP Header Stores general information about the BMP file.
693  // Bitmap Information (DIB header) Stores detailed information about the bitmap image.
694  // Color Palette Stores the definition of the colors being used for indexed color bitmaps.
695  // Bitmap Data Stores the actual image, pixel by pixel.
696 
697  ofstream file(fn, ofstream::binary);
698  if(!file.is_open())
699  return;
700 
701  unsigned int bmpTemp;
702 
703  //BMP Header
704  file << char(0x42) << char(0x4d); //"BM"
705  bmpTemp = AUX_IMG_FILE_SIZE;
706  for(int i = 0; i < 4; ++i) //file size in little-endian
707  file << (unsigned char)(((char*)(&bmpTemp))[i]);
708  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //reserved bytes
709  unsigned int dibHeaderSize = AUX_IMG_HEADER_SIZE + 14;
710  for(int i = 0; i < 4; ++i) //DIB header size
711  file << (unsigned char)(((char*)(&dibHeaderSize))[i]);
712  bmpTemp = AUX_IMG_HEADER_SIZE;
713  for(int i = 0; i < 4; ++i) //offset to data
714  file << (unsigned char)(((char*)(&bmpTemp))[i]);
715  bmpTemp = AUX_IMG_WIDTH;
716  for(int i = 0; i < 4; ++i) //img pixel width in little-endian
717  file << (unsigned char)(((char*)(&bmpTemp))[i]);
718  bmpTemp = AUX_IMG_HEIGHT;
719  for(int i = 0; i < 4; ++i) //img pixel height in little-endian
720  file << (unsigned char)(((char*)(&bmpTemp))[i]);
721  file << char(0x01) << char(0x00) << char(0x20)
722  << char(0x00); //color planes and bits per pixel
723  file << char(0x03) << char(0x00) << char(0x00) << char(0x00); //compression method
724  bmpTemp = AUX_IMG_RAW_SIZE;
725  for(int i = 0; i < 4; ++i) //file raw data size in little-endian
726  file << (unsigned char)(((char*)(&bmpTemp))[i]);
727  file << char(0xD6) << char(0x0D) << char(0x00)
728  << char(0x00); //horiz resol in pixels per meter
729  file << char(0xD6) << char(0x0D) << char(0x00)
730  << char(0x00); //vert resol in pixels per meter
731  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //colors used
732  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //important colors
733  file << char(0x00) << char(0x00) << char(0xFF) << char(0x00); //red mask
734  file << char(0x00) << char(0xFF) << char(0x00) << char(0x00); //green mask
735  file << char(0xFF) << char(0x00) << char(0x00) << char(0x00); //blue mask
736  file << char(0x00) << char(0x00) << char(0x00) << char(0xFF); //alpha mask
737  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //color space
738  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red X
739  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //red Y
740  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //red Z
741  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green X
742  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //green Y
743  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //green Z
744  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue X
745  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //blue Y
746  file << char(0x01) << char(0x00) << char(0x00) << char(0x00); //blue Z
747  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma red
748  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma green
749  file << char(0x00) << char(0x00) << char(0x00) << char(0x00); //gamma blue
750 
751  //BMP Data
752 
753  int bytesToPad = (4 - AUX_IMG_WIDTH * 4 % 4) %
754  4; //each row must start on a multiple of 4 byte offset
755  for(int y = AUX_IMG_HEIGHT - 1; y >= 0; --y)
756  {
757  for(int x = 0; x < AUX_IMG_WIDTH; ++x)
758  {
759  for(int i = 2; i >= 0; --i)
760  {
761  file << auxImg_[x][y][i];
762  }
763  file << auxImg_[x][y][3]; //alpha byte last
764  }
765  //pad bytes
766  for(int p = 0; p < bytesToPad; ++p)
767  file << char(0x00);
768  }
769 
770  file.close();
771 }
772 
777  int y,
778  int w,
779  int h,
780  int r,
781  int g,
782  int b,
783  float m1,
784  float m2,
785  float m3,
786  float m4)
787 {
788  float up[2] = {0.0f, 1.0f};
789 
790  transform(up[0], up[1], m1, m2, m3, m4); //transform up vector
791 
792  float rt[2] = {up[1], -up[0]}; //get rt from up vector
793 
794  float px = (float)x - up[0] * 0.5 * w -
795  rt[0] * 0.5 * w; //subtract to get to bottom left corner
796  float py = (float)y - up[1] * 0.5 * h - rt[1] * 0.5 * h;
797  float tpx, tpy;
798 
799  for(int i = 0; i < w * 2; ++i)
800  {
801  tpx = px;
802  tpy = py;
803  for(float j = 0; j < h * 2; ++j)
804  {
805  setAuxPixel((int)px, (int)py, r, g, b);
806  px += up[0] / 2.0f;
807  py += up[1] / 2.0f;
808  }
809  px = tpx + rt[0] / 2.0f;
810  py = tpy + rt[1] / 2.0f;
811  }
812 }
813 
818  int x, int y, int w, int h, int r, int g, int b, float deg)
819 {
820  float rad = deg * PI / 180.0f;
821  drawFillRectAux(x, y, w, h, r, g, b, cos(rad), -sin(rad), sin(rad), cos(rad));
822 }
823 
825 void PixelHistoPicGen::setAuxPixel(int x, int y, int r, int g, int b)
826 {
827  auxImg_[x][y][0] = r;
828  auxImg_[x][y][1] = g;
829  auxImg_[x][y][2] = b;
830  auxImg_[x][y][3] = 0;
831 }
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)