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