1 
2 
3 #include "tscannerutil.h"
4 
5 #include <cstring>
6 
7 #define BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS)                                  \
8   (((UCHAR *)(BUF))[(((X) + (BITOFFS)) >> 3) + (Y) * (BYTEWRAP)])
9 
10 #define GET_BIT(X, Y, BUF, BYTEWRAP, BITOFFS)                                  \
11   ((BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS) >> (7 - (((X) + (BITOFFS)) & 7))) &  \
12    (UCHAR)1)
13 
14 namespace TScannerUtil {
15 
16 struct EP {
17   unsigned char r, g, b;
18 };
19 
20 //-----------------------------------------------------------------------------
21 
copyRGBBufferToTRaster32(unsigned char * rgbBuffer,int rgbLx,int rgbLy,const TRaster32P & rout,bool internal)22 void copyRGBBufferToTRaster32(unsigned char *rgbBuffer, int rgbLx, int rgbLy,
23                               const TRaster32P &rout, bool internal) {
24   if (internal) {
25     TPixelRGBM32 *dst = rout->pixels();
26     EP *src           = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3);
27     const int w       = rout->getWrap();
28 
29     for (int x = 0; x < rout->getLx(); ++x) {
30       dst = rout->pixels() + x;
31       for (int y = 0; y < rout->getLy(); ++y) {
32         dst->r = src->r;
33         dst->g = src->g;
34         dst->b = src->b;
35         dst->m = 0xff;
36         dst += w;
37         --src;
38       }
39     }
40   } else {
41     unsigned char *index = rgbBuffer;
42     unsigned char *end   = index + (rgbLx * rgbLy * 3);
43     TPixel32 *outPix     = rout->pixels();
44     while (index < end) {
45       outPix->r = (int)*index;
46       index++;
47       outPix->g = (int)*index;
48       index++;
49       outPix->b = (int)*index;
50       index++;
51       outPix->m = 255;
52       outPix++;
53     }
54     rout->yMirror();
55   }
56 }
57 
58 //-----------------------------------------------------------------------------
59 
copyRGBBufferToTRasterGR8(unsigned char * rgbBuffer,int rgbLx,int rgbLy,int rgbWrap,const TRasterGR8P & rout)60 void copyRGBBufferToTRasterGR8(unsigned char *rgbBuffer, int rgbLx, int rgbLy,
61                                int rgbWrap, const TRasterGR8P &rout) {
62   TPixelGR8 *dst = rout->pixels();
63   EP *src        = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3);
64   const int w    = rout->getWrap();
65 
66   for (int x = 0; x < rout->getLx(); ++x) {
67     dst = rout->pixels() + x;
68     for (int y = 0; y < rout->getLy(); ++y) {
69       *dst = TPixelGR8::from(TPixelRGBM32(src->r, src->g, src->b));
70       dst += w;
71       --src;
72     }
73   }
74 }
75 
76 //-----------------------------------------------------------------------------
77 
copyGR8BufferToTRasterGR8(unsigned char * gr8Buffer,int rgbLx,int rgbLy,const TRasterGR8P & rout,bool internal)78 void copyGR8BufferToTRasterGR8(unsigned char *gr8Buffer, int rgbLx, int rgbLy,
79                                const TRasterGR8P &rout, bool internal) {
80   if (internal) {
81     unsigned char *dst = rout->getRawData();
82     unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1);
83     const int w        = rout->getWrap();
84 
85     for (int x = 0; x < rout->getLx(); ++x) {
86       dst = rout->getRawData() + x;
87       for (int y = 0; y < rout->getLy(); ++y) {
88         *dst = (*src);
89         dst += w;
90         --src;
91       }
92     }
93   } else {
94     memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy);
95     rout->yMirror();
96   }
97 }
98 
99 //-----------------------------------------------------------------------------
100 
copyGR8BufferToTRasterBW(unsigned char * gr8Buffer,int rgbLx,int rgbLy,const TRasterGR8P & rout,bool internal,float thres)101 void copyGR8BufferToTRasterBW(unsigned char *gr8Buffer, int rgbLx, int rgbLy,
102                               const TRasterGR8P &rout, bool internal,
103                               float thres) {
104   if (internal) {
105     unsigned char *dst = rout->getRawData();
106     unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1);
107     const int w        = rout->getWrap();
108 
109     for (int x = 0; x < rout->getLx(); ++x) {
110       dst = rout->getRawData() + x;
111       for (int y = 0; y < rout->getLy(); ++y) {
112         if (*src < thres)
113           *dst = 0;
114         else
115           *dst = 255;
116         dst += w;
117         --src;
118       }
119     }
120   } else {
121     memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy);
122     rout->yMirror();
123   }
124 }
125 
126 //-----------------------------------------------------------------------------
127 
copyBWBufferToTRasterGR8(const unsigned char * buffer,int rgbLx,int rgbLy,const TRasterGR8P & rout,bool isBW,bool internal)128 void copyBWBufferToTRasterGR8(const unsigned char *buffer, int rgbLx, int rgbLy,
129                               const TRasterGR8P &rout, bool isBW,
130                               bool internal) {
131   if (0)
132     assert(0);
133   else {
134     int i      = 0;
135     UCHAR *pix = rout->getRawData();
136     const unsigned char *byte;
137     while (i < rgbLx * rgbLy) {
138       int bytePos = i / 8;
139       int bitPos  = i % 8;
140       byte        = buffer + bytePos;
141       bool bit    = (*byte) >> (7 - bitPos);
142       if (isBW)
143         *pix = (bit ? 255 : 0);
144       else
145         *pix = (bit ? 0 : 255);
146 
147       pix++;
148       i++;
149     }
150     rout->yMirror();
151   }
152 }
153 
154 //-----------------------------------------------------------------------------
155 
copy90BWBufferToRasGR8(unsigned char * bwBuffer,int bwLx,int bwLy,int bwWrap,bool isBW,TRasterGR8P & rout,int mirror,int ninety)156 void copy90BWBufferToRasGR8(unsigned char *bwBuffer, int bwLx, int bwLy,
157                             int bwWrap, bool isBW, TRasterGR8P &rout,
158                             int mirror, int ninety) {
159   int x1   = 0;
160   int y1   = 0;
161   int x2   = bwLx - 1;
162   int y2   = bwLy - 1;
163   int newx = 0;
164   int newy = 0;
165 
166   UCHAR *bufin, *bufout, /* *bytein,*/ *byteout;
167   int bytewrapin, bitoffsin, wrapout;
168   int value_for_0, value_for_1;
169   int u, v, lu, lv, su, sv, u00, v00, u0, v0, dudy, dvdy, dudx, dvdx;
170   int x, y, lx, ly;
171   int u1, v1, u2, v2;
172 
173   mirror &= 1;
174   ninety &= 3;
175 
176   if (!ninety && !mirror) {
177     assert(0);
178     return;
179   }
180 
181   if (isBW) {
182     value_for_0 = 0;
183     value_for_1 = 255;
184   } else {
185     value_for_0 = 255;
186     value_for_1 = 0;
187   }
188 
189   u1 = x1;
190   v1 = y1;
191   u2 = x2;
192   v2 = y2;
193 
194   su = u2 - u1;
195   sv = v2 - v1;
196   lu = u2 - u1 + 1;
197   lv = v2 - v1 + 1;
198 
199   if (ninety & 1) {
200     lx = lv;
201     ly = lu;
202   } else {
203     lx = lu;
204     ly = lv;
205   }
206 
207   bufin      = bwBuffer;
208   bytewrapin = (bwWrap + 7) >> 3;
209   bitoffsin  = 0;  // rin->bit_offs;
210   bufout     = rout->getRawData();
211   wrapout    = rout->getWrap();
212 
213   dudx = 0;
214   dudy = 0;
215   dvdx = 0;
216   dvdy = 0;
217 
218   switch ((mirror << 2) + ninety) {
219   case (0 << 2) + 0:
220     u00  = u1;
221     v00  = v1;
222     dudx = 1;
223     dvdy = 1;
224     break;
225   case (0 << 2) + 1:
226     u00  = u1;
227     v00  = v1 + sv;
228     dudy = 1;
229     dvdx = -1;
230     break;
231   case (0 << 2) + 2:
232     u00  = u1 + su;
233     v00  = v1 + sv;
234     dudx = -1;
235     dvdy = -1;
236     break;
237   case (0 << 2) + 3:
238     u00  = u1 + su;
239     v00  = v1;
240     dudy = -1;
241     dvdx = 1;
242     break;
243   case (1 << 2) + 0:
244     u00  = u1 + su;
245     v00  = v1;
246     dudx = -1;
247     dvdy = 1;
248     break;
249   case (1 << 2) + 1:
250     u00  = u1 + su;
251     v00  = v1 + sv;
252     dudy = -1;
253     dvdx = -1;
254     break;
255   case (1 << 2) + 2:
256     u00  = u1;
257     v00  = v1 + sv;
258     dudx = 1;
259     dvdy = -1;
260     break;
261   case (1 << 2) + 3:
262     u00  = u1;
263     v00  = v1;
264     dudy = 1;
265     dvdx = 1;
266     break;
267   default:
268     abort();
269     u00 = v00 = dudy = dvdx = 0;
270   }
271 
272   if (dudx)
273     for (u0 = u00, v0 = v00, y = newy; y < newy + ly; v0 += dvdy, y++) {
274       u       = u0;
275       v       = v0;
276       byteout = bufout + newx + y * wrapout;
277       for (x = newx; x < newx + lx; u += dudx, x++) {
278         if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin))
279           *byteout++ = value_for_1;
280         else
281           *byteout++ = value_for_0;
282       }
283     }
284   else
285     for (u0 = u00, v0 = v00, y = newy; y < newy + ly; u0 += dudy, y++) {
286       u       = u0;
287       v       = v0;
288       byteout = bufout + newx + y * wrapout;
289       for (x = newx; x < newx + lx; v += dvdx, x++) {
290         if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin))
291           *byteout++ = value_for_1;
292         else
293           *byteout++ = value_for_0;
294       }
295     }
296 }
297 };
298