Openholo  v4.0
Open Source Digital Holographic Library
ImgControl.cpp
Go to the documentation of this file.
1 #include "ImgControl.h"
2 #include <string.h>
3 #include <omp.h>
4 #include "sys.h"
5 #include "function.h"
6 
7 ImgControl* ImgControl::instance = nullptr;
8 
9 ImgControl::ImgControl()
10 {
11 }
12 
13 
14 ImgControl::~ImgControl()
15 {
16 }
17 
18 
19 unsigned long long ImgControl::GetBitmapSize(int width, int height, int channel)
20 {
21  return (((width * channel) + 3) & ~3) * height;
22 }
23 
24 void ImgControl::Resize(unsigned char* src, unsigned char* dst, int w, int h, int neww, int newh, int ch)
25 {
26  if (src == nullptr) return;
27 
28  unsigned long long newsize;
29  uint nBytePerLine = ((w * ch) + 3) & ~3; // src
30  uint nNewBytePerLine = ((neww * ch) + 3) & ~3; // dst
31 
32  if (dst == nullptr)
33  {
34  newsize = GetBitmapSize(neww, newh, ch);
35  dst = new unsigned char[newsize];
36  }
37  else
38  newsize = nNewBytePerLine * newh;
39 
40 #ifdef _OPENMP
41 #pragma omp parallel for firstprivate(nNewBytePerLine, nBytePerLine)
42 #endif
43  for (int y = 0; y < newh; y++)
44  {
45  uint nbppY = y * nNewBytePerLine;
46  for (int x = 0; x < neww; x++)
47  {
48  float gx = (x / (float)neww) * (w - 1);
49  float gy = (y / (float)newh) * (h - 1);
50 
51  int gxi = (int)gx;
52  int gyi = (int)gy;
53 
54  if (ch == 1) {
55  uint32_t a00, a01, a10, a11;
56 
57  a00 = src[gxi + 0 + gyi * nBytePerLine];
58  a01 = src[gxi + 1 + gyi * nBytePerLine];
59  a10 = src[gxi + 0 + (gyi + 1) * nBytePerLine];
60  a11 = src[gxi + 1 + (gyi + 1) * nBytePerLine];
61 
62  float dx = gx - gxi;
63  float dy = gy - gyi;
64 
65  float w1 = (1 - dx) * (1 - dy);
66  float w2 = dx * (1 - dy);
67  float w3 = (1 - dx) * dy;
68  float w4 = dx * dy;
69  if ( x + y * neww < newsize)
70  dst[x + y * neww] = int(a00 * w1 + a01 * w2 + a10 * w3 + a11 * w4);
71  }
72  else if (ch == 3) {
73  uint32_t b00[3], b01[3], b10[3], b11[3];
74  uint srcX = gxi * ch;
75  uint dstX = x * ch;
76 
77  b00[0] = src[srcX + 0 + gyi * nBytePerLine];
78  b00[1] = src[srcX + 1 + gyi * nBytePerLine];
79  b00[2] = src[srcX + 2 + gyi * nBytePerLine];
80 
81  b01[0] = src[srcX + 3 + gyi * nBytePerLine];
82  b01[1] = src[srcX + 4 + gyi * nBytePerLine];
83  b01[2] = src[srcX + 5 + gyi * nBytePerLine];
84 
85  b10[0] = src[srcX + 0 + (gyi + 1) * nBytePerLine];
86  b10[1] = src[srcX + 1 + (gyi + 1) * nBytePerLine];
87  b10[2] = src[srcX + 2 + (gyi + 1) * nBytePerLine];
88 
89  b11[0] = src[srcX + 3 + (gyi + 1) * nBytePerLine];
90  b11[1] = src[srcX + 4 + (gyi + 1) * nBytePerLine];
91  b11[2] = src[srcX + 5 + (gyi + 1) * nBytePerLine];
92 
93  float dx = gx - gxi;
94  float dy = gy - gyi;
95 
96  float w1 = (1 - dx) * (1 - dy);
97  float w2 = dx * (1 - dy);
98  float w3 = (1 - dx) * dy;
99  float w4 = dx * dy;
100  if ((dstX + 2 + nbppY) < newsize)
101  {
102  dst[dstX + 0 + nbppY] = int(b00[0] * w1 + b01[0] * w2 + b10[0] * w3 + b11[0] * w4); // blue
103  dst[dstX + 1 + nbppY] = int(b00[1] * w1 + b01[1] * w2 + b10[1] * w3 + b11[1] * w4); // green
104  dst[dstX + 2 + nbppY] = int(b00[2] * w1 + b01[2] * w2 + b10[2] * w3 + b11[2] * w4); // red
105  }
106  }
107  }
108  }
109 }
110 
111 bool ImgControl::Rotate(double rotate, unsigned char *src, unsigned char *dst, int w, int h, int neww, int newh, int ch)
112 {
113  if (src == nullptr) return false;
114  if (ch > 4) return false;
115 
116  bool bChangeSize = false;
117  if (neww != w || newh != h) {
118  bChangeSize = true;
119  }
120 
121  unsigned long long nImgSize = bChangeSize ? GetBitmapSize(neww, newh, ch) : GetBitmapSize(w, h, ch);
122 
123  if (dst == nullptr)
124  {
125  dst = new unsigned char[nImgSize];
126  }
127 
128  unsigned char *temp = new unsigned char[nImgSize]; //src
129  //unsigned char *temp2 = new unsigned char[nImgSize]; // dst
130 
131  if (bChangeSize) {
132  Resize(src, temp, w, h, neww, newh, ch);
133  w = neww;
134  h = newh;
135  }
136  else {
137  memcpy(temp, src, nImgSize);
138  }
139 
140  int nBytePerLine = ((w * ch) + 3) & ~3;
141  double radian = RADIAN(rotate);
142  double cc = cos(radian);
143  double ss = sin(-radian);
144  double centerX = (double)w / 2.0;
145  double centerY = (double)h / 2.0;
146 #ifdef _OPENMP
147 #pragma omp parallel for firstprivate(nBytePerLine, ss, cc, centerX, centerY)
148 #endif
149  for (int y = 0; y < h; y++) {
150  int dstY = y * nBytePerLine;
151  for (int x = 0; x < w; x++) {
152  int origX = (int)(centerX + ((double)y - centerY)*ss + ((double)x - centerX)*cc);
153  int origY = (int)(centerY + ((double)y - centerY)*cc - ((double)x - centerX)*ss);
154 
155  unsigned char pixels[4] = { 0, };
156  if ((origY >= 0 && origY < h) && (origX >= 0 && origX < w)) {
157  int offsetX = origX * ch;
158  int offsetY = origY * nBytePerLine;
159 
160  memcpy(pixels, &temp[offsetY + offsetX], sizeof(unsigned char) * ch);
161  }
162  //memcpy(&temp2[dstY + (x * ch)], pixels, sizeof(unsigned char) * ch);
163  memcpy(&dst[dstY + (x * ch)], pixels, sizeof(unsigned char) * ch);
164  }
165  }
166 
167  //memcpy(dst, temp2, nImgSize);
168  delete[] temp;
169  //delete[] temp2;
170  return true;
171 }
172 
173 bool ImgControl::Flip(FLIP mode, unsigned char *src, unsigned char *dst, int w, int h, int ch)
174 {
175  if (src == nullptr) return false;
176 
177  bool bOK = true;
178 
179  if (dst == nullptr)
180  {
181  dst = new unsigned char[GetBitmapSize(w, h, ch)];
182  }
183 
184  int nBytePerLine = ((w * ch) + 3) & ~3;
185  if (mode == FLIP::VERTICAL) {
186 #ifdef _OPENMP
187 #pragma omp parallel for firstprivate(nBytePerLine)
188 #endif
189  for (int y = 0; y < h; y++) {
190  int offset = y * nBytePerLine;
191  int offset2 = (h - y - 1) * nBytePerLine;
192  for (int x = 0; x < w; x++) {
193  memcpy(&dst[offset + (x * ch)], &src[offset2 + (x * ch)], sizeof(unsigned char) * ch);
194  }
195  }
196  }
197  else if (mode == FLIP::HORIZONTAL) {
198 #ifdef _OPENMP
199 #pragma omp parallel for firstprivate(nBytePerLine)
200 #endif
201  for (int y = 0; y < h; y++) {
202  int offset = y * nBytePerLine;
203  for (int x = 0; x < w; x++) {
204  memcpy(&dst[offset + (x * ch)], &src[offset + ((w * ch) - ((x + 1) * ch))], sizeof(unsigned char) * ch);
205  }
206  }
207  }
208  else if (mode == FLIP::BOTH) {
209 #ifdef _OPENMP
210 #pragma omp parallel for firstprivate(nBytePerLine)
211 #endif
212  for (int y = 0; y < h; y++) {
213  int offset = y * nBytePerLine;
214  int offset2 = (h - y - 1) * nBytePerLine;
215  for (int x = 0; x < w; x++) {
216  memcpy(&dst[offset + (x * ch)], &src[offset2 + ((w * ch) - ((x + 1) * ch))], sizeof(unsigned char) * ch);
217  }
218  }
219  }
220  else {
221  // do nothing
222  bOK = false;
223  }
224 
225  return bOK;
226 }
227 
228 bool ImgControl::Crop(unsigned char *src, unsigned char *dst, int w, int h, int ch, int x, int y, int neww, int newh)
229 {
230  if (src == nullptr) return false;
231  if (x < 0 || y < 0 || x + neww > w || y + newh > h) return false;
232 
233  if (dst == nullptr)
234  {
235  unsigned long long nImgSize = GetBitmapSize(neww, newh, ch);
236  dst = new unsigned char[nImgSize];
237  memset(dst, 0, nImgSize);
238  }
239 
240  bool bOK = true;
241  int nBytePerLine = ((neww * ch) + 3) & ~3;
242  int nBytePerLine2 = ((w * ch) + 3) & ~3;
243  int offsetX = x * ch; // fix
244 
245 #ifdef _OPENMP
246 #pragma omp parallel for firstprivate(nBytePerLine, nBytePerLine2, y, ch, neww)
247 #endif
248  for (int i = 0; i < newh; i++) {
249  int offset = i * nBytePerLine;
250  int offsetY = (y + i) * nBytePerLine2;
251  memcpy(&dst[offset], &src[offsetY + offsetX], sizeof(unsigned char) * ch * neww);
252  }
253  return bOK;
254 }
255 
256 bool ImgControl::GetSize(const char* path, unsigned int *size)
257 {
258  bool bOK = true;
259  *size = 0;
260  FILE *fp = fopen(path, "rb");
261  if (!fp) {
262  bOK = false;
263  }
264  else
265  {
266  fseek(fp, 0, SEEK_END);
267  *size = ftell(fp);
268  fclose(fp);
269  }
270  return bOK;
271 }
bool Rotate(double rotate, unsigned char *src, unsigned char *dst, int w, int h, int neww, int newh, int ch)
Definition: ImgControl.cpp:111
bool Crop(unsigned char *src, unsigned char *dst, int w, int h, int ch, int x, int y, int neww, int newh)
Definition: ImgControl.cpp:228
VERTICAL
Definition: ImgControl.h:24
HORIZONTAL
Definition: ImgControl.h:24
bool GetSize(const char *path, unsigned int *size)
Definition: ImgControl.cpp:256
fclose(infile)
#define RADIAN(theta)
Definition: define.h:60
bool Flip(FLIP mode, unsigned char *src, unsigned char *dst, int w, int h, int ch)
Definition: ImgControl.cpp:173
void Resize(unsigned char *src, unsigned char *dst, int w, int h, int neww, int newh, int ch)
Definition: ImgControl.cpp:24
w
Definition: Openholo.cpp:429
unsigned int uint
Definition: typedef.h:62
h
Definition: Openholo.cpp:430