Openholo  v4.2
Open Source Digital Holographic Library
ImgControl.cpp
Go to the documentation of this file.
1 #include "ImgControl.h"
2 #include <string.h>
3 #include "sys.h"
4 #include "function.h"
5 
6 ImgControl* ImgControl::instance = nullptr;
7 
8 ImgControl::ImgControl()
9 {
10 }
11 
12 
13 ImgControl::~ImgControl()
14 {
15 }
16 
24 uint64_t ImgControl::GetPixelSize(const uint32_t width, const uint32_t height, const uint8_t channel)
25 {
26  return (((static_cast<uint64_t>(width) * channel) + 3) & ~3) * static_cast<uint64_t>(height);
27 }
28 
40 bool ImgControl::Resize(const uint8_t* src, uint8_t* dst, const uint32_t w, const uint32_t h,
41  const uint32_t neww, const uint32_t newh, const uint8_t ch)
42 {
43  if (src == nullptr) return false;
44  if (ch != 1 && ch != 3) return false;
45 
46  uint64_t newsize;
47  uint32_t nBytePerLine = ((w * ch) + 3) & ~3; // src
48  uint32_t nNewBytePerLine = ((neww * ch) + 3) & ~3; // dst
49 
50  if (dst == nullptr)
51  {
52  newsize = GetPixelSize(neww, newh, ch);
53  dst = new uint8_t[newsize];
54  }
55  else
56  newsize = nNewBytePerLine * newh;
57 
58  for (uint32_t y = 0; y < newh; y++)
59  {
60  uint32_t dst_offset_y = y * nNewBytePerLine;
61  float gy = (y / (float)newh) * (h - 1);
62  int gyi = (int)gy;
63  float dy = gy - gyi;
64 
65  for (uint32_t x = 0; x < neww; x++)
66  {
67  float gx = (x / (float)neww) * (w - 1);
68  int gxi = (int)gx;
69 
70  uint32_t src_offset_x = gxi * ch;
71  uint32_t src_offset_below = src_offset_x + gyi * nBytePerLine;
72  uint32_t src_offset_above = src_offset_x + (gyi + 1) * nBytePerLine;
73  uint32_t dst_offset_x = x * ch;
74  uint32_t dst_offset = dst_offset_y + dst_offset_x;
75  float dx = gx - gxi;
76  float w1 = (1 - dx) * (1 - dy);
77  float w2 = dx * (1 - dy);
78  float w3 = (1 - dx) * dy;
79  float w4 = dx * dy;
80 
81  if ((dst_offset + (ch - 1)) < newsize)
82  {
83  if (ch == 3)
84  {
85  // blue
86  dst[dst_offset + 0] = int(
87  src[src_offset_below + 0] * w1 +
88  src[src_offset_below + 3] * w2 +
89  src[src_offset_above + 0] * w3 +
90  src[src_offset_above + 3] * w4
91  );
92  // green
93  dst[dst_offset + 1] = int(
94  src[src_offset_below + 1] * w1 +
95  src[src_offset_below + 4] * w2 +
96  src[src_offset_above + 1] * w3 +
97  src[src_offset_above + 4] * w4
98  );
99  // red
100  dst[dst_offset + 2] = int(
101  src[src_offset_below + 2] * w1 +
102  src[src_offset_below + 5] * w2 +
103  src[src_offset_above + 2] * w3 +
104  src[src_offset_above + 5] * w4
105  );
106  }
107  else
108  {
109  // grayscale
110  dst[dst_offset] = int(
111  src[src_offset_below + 0] * w1 +
112  src[src_offset_below + 1] * w2 +
113  src[src_offset_above + 0] * w3 +
114  src[src_offset_above + 1] * w4
115  );
116  }
117  }
118 
119  }
120  }
121  return true;
122 }
123 
136 bool ImgControl::Rotate(const double rotate, const uint8_t* src, uint8_t* dst, const uint32_t w, const uint32_t h,
137  const uint32_t neww, const uint32_t newh, const uint8_t ch)
138 {
139  if (src == nullptr) return false;
140  if (ch != 1 && ch != 3) return false;
141 
142  bool bChangeSize = false;
143  if (neww != w || newh != h) {
144  bChangeSize = true;
145  }
146 
147  uint64_t nImgSize = bChangeSize ? GetPixelSize(neww, newh, ch) : GetPixelSize(w, h, ch);
148 
149  if (dst == nullptr)
150  {
151  dst = new uint8_t[nImgSize];
152  }
153 
154  uint8_t* temp = new uint8_t[nImgSize]; //src
155 
156  // step. 1
157  if (bChangeSize) {
158  Resize(src, temp, w, h, neww, newh, ch);
159  }
160  else {
161  memcpy(temp, src, nImgSize);
162  }
163 
164  uint32_t nBytePerLine = ((neww * ch) + 3) & ~3;
165  double radian = RADIAN(rotate);
166  double cc = cos(radian);
167  double ss = sin(-radian);
168  double centerX = (double)neww / 2.0;
169  double centerY = (double)newh / 2.0;
170 
171  for (uint32_t y = 0; y < newh; y++) {
172  uint32_t dstY = y * nBytePerLine;
173 
174  for (uint32_t x = 0; x < neww; x++) {
175  int origX = (int)(centerX + ((double)y - centerY) * ss + ((double)x - centerX) * cc);
176  int origY = (int)(centerY + ((double)y - centerY) * cc - ((double)x - centerX) * ss);
177 
178  uint8_t pixels[4] = { 0, };
179  if ((origY >= 0 && origY < (int)newh) && (origX >= 0 && origX < (int)neww)) {
180  int offsetX = origX * ch;
181  int offsetY = origY * nBytePerLine;
182 
183  memcpy(pixels, &temp[offsetY + offsetX], sizeof(uint8_t) * ch);
184  }
185  memcpy(&dst[dstY + (x * ch)], pixels, sizeof(uint8_t) * ch);
186  }
187  }
188  delete[] temp;
189  return true;
190 }
191 
192 
203 bool ImgControl::Flip(FLIP mode, const uint8_t* src, uint8_t* dst, const uint32_t w, const uint32_t h, const uint8_t ch)
204 {
205  if (src == nullptr) return false;
206  if (ch != 1 && ch != 3) return false;
207 
208  bool bOK = true;
209 
210 
211  if (dst == nullptr)
212  {
213  dst = new uint8_t[GetPixelSize(w, h, ch)];
214  }
215 
216  const uint32_t nBytePerLine = ((w * ch) + 3) & ~3;
217 
218  if (mode == FLIP::VERTICAL) {
219  for (uint32_t y = 0; y < h; y++) {
220  uint32_t offset = y * nBytePerLine;
221  uint32_t offset2 = (h - y - 1) * nBytePerLine;
222  for (uint32_t x = 0; x < w; x++) {
223  memcpy(&dst[offset + (x * ch)], &src[offset2 + (x * ch)], sizeof(uint8_t) * ch);
224  }
225  }
226  }
227  else if (mode == FLIP::HORIZONTAL) {
228  for (uint32_t y = 0; y < h; y++) {
229  uint32_t offset = y * nBytePerLine;
230  for (uint32_t x = 0; x < w; x++) {
231  memcpy(&dst[offset + (x * ch)], &src[offset + ((w * ch) - ((x + 1) * ch))], sizeof(uint8_t) * ch);
232  }
233  }
234  }
235  else if (mode == FLIP::BOTH) {
236  for (uint32_t y = 0; y < h; y++) {
237  uint32_t offset = y * nBytePerLine;
238  uint32_t offset2 = (h - y - 1) * nBytePerLine;
239  for (uint32_t x = 0; x < w; x++) {
240  memcpy(&dst[offset + (x * ch)], &src[offset2 + ((w * ch) - ((x + 1) * ch))], sizeof(uint8_t) * ch);
241  }
242  }
243  }
244  else {
245  // do nothing
246  bOK = false;
247  }
248 
249  return bOK;
250 }
251 
265 bool ImgControl::Crop(const uint8_t* src, uint8_t* dst, const uint32_t w, const uint32_t h, const uint8_t ch,
266  const uint32_t start_x, const uint32_t start_y, const uint32_t end_x, const uint32_t end_y)
267 {
268  if (src == nullptr) return false;
269  if (start_x < 0 || start_y < 0 || end_x > w || end_y > h ||
270  start_x >= end_x || start_y >= end_y) return false;
271 
272  uint32_t neww = end_x - start_x;
273  uint32_t newh = end_y - start_y;
274 
275  if (dst == nullptr)
276  {
277  uint64_t nImgSize = GetPixelSize(neww, newh, ch);
278  dst = new uint8_t[nImgSize];
279  memset(dst, 0, nImgSize);
280  }
281 
282  int nBytePerLineDst = ((neww * ch) + 3) & ~3;
283  int nBytePerLineSrc = ((w * ch) + 3) & ~3;
284  int offsetX = start_x * ch; // fix
285 
286  for (uint32_t i = 0; i < newh; i++) {
287  uint32_t offset = i * nBytePerLineDst;
288  uint32_t offsetY = (start_y + i) * nBytePerLineSrc;
289  memcpy(&dst[offset], &src[offsetY + offsetX], sizeof(uint8_t) * ch * neww);
290  }
291  return true;
292 }
293 
300 bool ImgControl::GetSize(const char* path, uint32_t* size)
301 {
302  bool bOK = true;
303  *size = 0;
304  FILE* fp = fopen(path, "rb");
305  if (!fp) {
306  bOK = false;
307  }
308  else
309  {
310  fseek(fp, 0, SEEK_END);
311  *size = ftell(fp);
312  fclose(fp);
313  }
314  return bOK;
315 }
#define RADIAN(theta)
Definition: define.h:60
w
Definition: Openholo.cpp:429
HORIZONTAL
Definition: ImgControl.h:25
bool Flip(FLIP mode, const uint8_t *src, uint8_t *dst, const uint32_t w, const uint32_t h, const uint8_t ch)
Flip the bitmap.
Definition: ImgControl.cpp:203
bool Rotate(const double rotate, const uint8_t *src, uint8_t *dst, const uint32_t w, const uint32_t h, const uint32_t neww, const uint32_t newh, const uint8_t ch)
Rotate the bitmap.
Definition: ImgControl.cpp:136
h
Definition: Openholo.cpp:430
VERTICAL
Definition: ImgControl.h:25
fclose(infile)
bool GetSize(const char *path, uint32_t *size)
Get file size.
Definition: ImgControl.cpp:300
FLIP
Definition: ImgEncoder.h:6
bool Resize(const uint8_t *src, uint8_t *dst, const uint32_t w, const uint32_t h, const uint32_t neww, const uint32_t newh, const uint8_t ch)
Resize the bitmap.
Definition: ImgControl.cpp:40
bool Crop(const uint8_t *src, uint8_t *dst, const uint32_t w, const uint32_t h, const uint8_t ch, const uint32_t start_x, const uint32_t start_y, const uint32_t end_x, const uint32_t end_y)
Crop the bitmap.
Definition: ImgControl.cpp:265