OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PortableBitmapReader.cpp
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <fstream>
5 #include <iomanip>
6 #include <sstream>
7 
8 PortableBitmapReader::PortableBitmapReader(const std::string &input) {
9 
10  std::ifstream in(input);
11  readHeader(in);
12  pixels_m.resize(width_m * height_m);
13 
14  if (type_m == ASCII) {
15  readImageAscii(in);
16  } else {
17  readImageBinary(in);
18  }
19 }
20 
21 std::string PortableBitmapReader::getNextPart(std::istream &in) {
22  char c;
23  do {
24  c = in.get();
25  if (c == '#') {
26  do {
27  c = in.get();
28  } while (c != '\n');
29  } else if (!(c == ' ' ||
30  c == '\t' ||
31  c == '\n' ||
32  c == '\r')) {
33  in.putback(c);
34  break;
35  }
36  } while (true);
37 
38  std::string nextPart;
39  in >> nextPart;
40 
41  return nextPart;
42 }
43 
44 void PortableBitmapReader::readHeader(std::istream &in) {
45  std::string magicValue = getNextPart(in);
46 
47  if (magicValue == "P1") {
48  type_m = ASCII;
49  } else if (magicValue == "P4") {
50  type_m = BINARY;
51  } else {
52  throw OpalException("PortableBitmapReader::readHeader",
53  "Unknown magic value: '" + magicValue + "'");
54  }
55 
56  {
57  std::string tmp = getNextPart(in);
58  std::istringstream conv;
59  conv.str(tmp);
60  conv >> width_m;
61  }
62 
63  {
64  std::string tmp = getNextPart(in);
65  std::istringstream conv;
66  conv.str(tmp);
67  conv >> height_m;
68  }
69 
70  char tmp;
71  in.read(&tmp, 1);
72 }
73 
74 void PortableBitmapReader::readImageAscii(std::istream &in) {
75  unsigned int size = height_m * width_m;
76  unsigned int i = 0;
77  while (i < size) {
78  char c;
79  in >> c;
80 
81  if (!(c == ' ' ||
82  c == '\n' ||
83  c == '\t' ||
84  c == '\r')) {
85  pixels_m[i] = (c == '1');
86  ++ i;
87  }
88  }
89 }
90 
91 void PortableBitmapReader::readImageBinary(std::istream &in) {
92  static const unsigned int sizeChar = sizeof(char) * 8;
93 
94  unsigned int numPixels = 0;
95  unsigned char c = 0;
96  for (unsigned int row = 0; row < height_m; ++ row) {
97  for (unsigned int col = 0; col < width_m; ++ col) {
98  if ( col % sizeChar == 0) {
99  char c2 = 0;
100  in.read(&c2, 1);
101  c = (unsigned char) c2;
102  }
103  unsigned int k = sizeChar - 1 - (col % sizeChar);
104  pixels_m[numPixels] = (c >> k & 1);
105  ++ numPixels;
106  }
107  }
108 }
109 
110 void PortableBitmapReader::print(std::ostream &out) const {
111  for (unsigned int i = 0; i < height_m; ++ i) {
112  for (unsigned int j = 0; j < width_m; ++ j) {
113  if (j % 8 == 0) {
114  unsigned int byte = 0;
115  for (unsigned int k = 0; k < 8 && j + k < width_m; ++ k) {
116  unsigned int idx = getIdx(i, j + k);
117  if (pixels_m[idx])
118  byte = byte | (1 << (7 - k));
119  }
120  std::cout << " " << std::hex << std::setw(2) << std::setfill('0') << byte << ": ";
121  }
122  unsigned int idx = getIdx(i, j);
123  std::cout << pixels_m[idx];
124  }
125  std::cout << std::endl;
126  }
127 }
PortableBitmapReader(const std::string &input)
std::vector< bool > pixels_m
std::string getNextPart(std::istream &in)
The base class for all OPAL exceptions.
Definition: OpalException.h:28
void readImageAscii(std::istream &in)
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void readImageBinary(std::istream &in)
void readHeader(std::istream &in)
unsigned int getIdx(unsigned int h, unsigned int w) const
void print(std::ostream &out) const
Inform & endl(Inform &inf)
Definition: Inform.cpp:42