1 | /*
|
---|
2 |
|
---|
3 | gbmmir.c - Produce Mirror Image of General Bitmap
|
---|
4 |
|
---|
5 | */
|
---|
6 |
|
---|
7 | /*...sincludes:0:*/
|
---|
8 | #include <stdio.h>
|
---|
9 | #include <string.h>
|
---|
10 | #include <stddef.h>
|
---|
11 | #include <stdlib.h>
|
---|
12 | #include "gbm.h"
|
---|
13 |
|
---|
14 | /*...vgbm\46\h:0:*/
|
---|
15 | /*...e*/
|
---|
16 |
|
---|
17 | /*...sgbm_ref_vert:0:*/
|
---|
18 | BOOLEAN gbm_ref_vert(const GBM *gbm, byte *data)
|
---|
19 | {
|
---|
20 | int stride = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
|
---|
21 | byte *p1 = data;
|
---|
22 | byte *p2 = data + (gbm->h - 1) * stride;
|
---|
23 | byte *p3;
|
---|
24 |
|
---|
25 | if ( (p3 = malloc((size_t) stride)) == NULL )
|
---|
26 | return FALSE;
|
---|
27 |
|
---|
28 | for ( ; p1 < p2; p1 += stride, p2 -= stride )
|
---|
29 | {
|
---|
30 | memcpy(p3, p1, stride);
|
---|
31 | memcpy(p1, p2, stride);
|
---|
32 | memcpy(p2, p3, stride);
|
---|
33 | }
|
---|
34 |
|
---|
35 | free(p3);
|
---|
36 |
|
---|
37 | return TRUE;
|
---|
38 | }
|
---|
39 | /*...e*/
|
---|
40 | /*...sgbm_ref_horz:0:*/
|
---|
41 | /*...sref_horz_24:0:*/
|
---|
42 | static void ref_horz_24(byte *dst, byte *src, int n)
|
---|
43 | {
|
---|
44 | dst += n * 3;
|
---|
45 | while ( n-- )
|
---|
46 | {
|
---|
47 | dst -= 3;
|
---|
48 | dst[0] = *src++;
|
---|
49 | dst[1] = *src++;
|
---|
50 | dst[2] = *src++;
|
---|
51 | }
|
---|
52 | }
|
---|
53 | /*...e*/
|
---|
54 | /*...sref_horz_8:0:*/
|
---|
55 | static void ref_horz_8(byte *dst, byte *src, int n)
|
---|
56 | {
|
---|
57 | dst += n;
|
---|
58 | while ( n-- )
|
---|
59 | *(--dst) = *src++;
|
---|
60 | }
|
---|
61 | /*...e*/
|
---|
62 | /*...sref_horz_4:0:*/
|
---|
63 | static byte rev4[0x100];
|
---|
64 |
|
---|
65 | static void table_4(void)
|
---|
66 | {
|
---|
67 | unsigned int i;
|
---|
68 |
|
---|
69 | for ( i = 0; i < 0x100; i++ )
|
---|
70 | rev4[i] = (byte) ( ((i & 0x0fU) << 4) | ((i & 0xf0U) >> 4) );
|
---|
71 | }
|
---|
72 |
|
---|
73 | static void ref_horz_4(byte *dst, byte *src, int n)
|
---|
74 | {
|
---|
75 | if ( (n & 1) == 0 )
|
---|
76 | {
|
---|
77 | n /= 2;
|
---|
78 | dst += n;
|
---|
79 | while ( n-- )
|
---|
80 | *(--dst) = rev4[*src++];
|
---|
81 | }
|
---|
82 | else
|
---|
83 | {
|
---|
84 | n /= 2;
|
---|
85 | src += n;
|
---|
86 | while ( n-- )
|
---|
87 | {
|
---|
88 | *dst = (byte) (*(src--) & 0xf0);
|
---|
89 | *dst++ |= (byte) (* src & 0x0f);
|
---|
90 | }
|
---|
91 | *dst = (byte) (*src & 0xf0);
|
---|
92 | }
|
---|
93 | }
|
---|
94 | /*...e*/
|
---|
95 | /*...sref_horz_1:0:*/
|
---|
96 | static byte rev[0x100]; /* Reverses all bits in a byte */
|
---|
97 | static byte rev_top[7][0x100]; /* Reverses top N bits of a byte */
|
---|
98 | static byte rev_bot[7][0x100]; /* Reverses bottom N bits of a byte */
|
---|
99 | static byte lmask[8] = { 0, 0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe };
|
---|
100 |
|
---|
101 | static void table_1(void)
|
---|
102 | {
|
---|
103 | unsigned int i;
|
---|
104 |
|
---|
105 | for ( i = 0; i < 0x100; i++ )
|
---|
106 | {
|
---|
107 | unsigned int j, p, q, b = 0;
|
---|
108 |
|
---|
109 | for ( p = 0x01U, q = 0x80U; p < 0x100U; p <<= 1, q >>= 1 )
|
---|
110 | if ( i & p )
|
---|
111 | b |= q;
|
---|
112 | rev[i] = b;
|
---|
113 |
|
---|
114 | for ( j = 1; j < 8U; j++ )
|
---|
115 | {
|
---|
116 | byte l = 0, r = 0;
|
---|
117 | byte lm = 0x80U, lmr = (byte) (0x80U >> (j - 1));
|
---|
118 | byte rm = 0x01U, rmr = (byte) (0x01U << (j - 1));
|
---|
119 | unsigned int k;
|
---|
120 |
|
---|
121 | for ( k = 0; k < j; k++ )
|
---|
122 | {
|
---|
123 | if ( i & (lm >> k) ) l |= (lmr << k);
|
---|
124 | if ( i & (rm << k) ) r |= (rmr >> k);
|
---|
125 | }
|
---|
126 | rev_top[j-1][i] = l;
|
---|
127 | rev_bot[j-1][i] = r;
|
---|
128 | }
|
---|
129 | }
|
---|
130 | }
|
---|
131 |
|
---|
132 | static void ref_horz_1(byte *dst, byte *src, int n)
|
---|
133 | {
|
---|
134 | int last = ( n & 7 );
|
---|
135 |
|
---|
136 | n >>= 3;
|
---|
137 | if ( last == 0 )
|
---|
138 | {
|
---|
139 | dst += n;
|
---|
140 | while ( n-- )
|
---|
141 | *(--dst) = rev[*src++];
|
---|
142 | }
|
---|
143 | else
|
---|
144 | {
|
---|
145 | byte *lrev = rev_top[ last -1];
|
---|
146 | byte *rrev = rev_bot[(8-last)-1];
|
---|
147 | byte lm = lmask[last], rm = 0xff - lm;
|
---|
148 |
|
---|
149 | src += n;
|
---|
150 | while ( n-- )
|
---|
151 | {
|
---|
152 | *dst = lrev[*(src--) & lm];
|
---|
153 | *dst++ |= rrev[* src & rm];
|
---|
154 | }
|
---|
155 | *dst = lrev[*src & lm];
|
---|
156 | }
|
---|
157 | }
|
---|
158 | /*...e*/
|
---|
159 |
|
---|
160 | BOOLEAN gbm_ref_horz(const GBM *gbm, byte *data)
|
---|
161 | {
|
---|
162 | int stride = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
|
---|
163 | int y;
|
---|
164 | byte *p = data;
|
---|
165 | byte *tmp;
|
---|
166 |
|
---|
167 | if ( (tmp = malloc((size_t) stride)) == NULL )
|
---|
168 | return FALSE;
|
---|
169 |
|
---|
170 | switch ( gbm->bpp )
|
---|
171 | {
|
---|
172 | case 24:
|
---|
173 | for ( y = 0; y < gbm->h; y++, p += stride )
|
---|
174 | {
|
---|
175 | ref_horz_24(tmp, p, gbm->w);
|
---|
176 | memcpy(p, tmp, stride);
|
---|
177 | }
|
---|
178 | break;
|
---|
179 | case 8:
|
---|
180 | for ( y = 0; y < gbm->h; y++, p += stride )
|
---|
181 | {
|
---|
182 | ref_horz_8(tmp, p, gbm->w);
|
---|
183 | memcpy(p, tmp, stride);
|
---|
184 | }
|
---|
185 | break;
|
---|
186 | case 4:
|
---|
187 | table_4();
|
---|
188 | for ( y = 0; y < gbm->h; y++, p += stride )
|
---|
189 | {
|
---|
190 | ref_horz_4(tmp, p, gbm->w);
|
---|
191 | memcpy(p, tmp, stride);
|
---|
192 | }
|
---|
193 | break;
|
---|
194 | case 1:
|
---|
195 | table_1();
|
---|
196 | for ( y = 0; y < gbm->h; y++, p += stride )
|
---|
197 | {
|
---|
198 | ref_horz_1(tmp, p, gbm->w);
|
---|
199 | memcpy(p, tmp, stride);
|
---|
200 | }
|
---|
201 | break;
|
---|
202 | }
|
---|
203 |
|
---|
204 | free(tmp);
|
---|
205 |
|
---|
206 | return TRUE;
|
---|
207 | }
|
---|
208 | /*...e*/
|
---|
209 | /*...sgbm_transpose:0:*/
|
---|
210 | void gbm_transpose(const GBM *gbm, const byte *data, byte *data_t)
|
---|
211 | {
|
---|
212 | int stride = ((gbm->w * gbm->bpp + 31) / 32) * 4;
|
---|
213 | int stride_t = ((gbm->h * gbm->bpp + 31) / 32) * 4;
|
---|
214 |
|
---|
215 | switch ( gbm->bpp )
|
---|
216 | {
|
---|
217 | /*...s24:16:*/
|
---|
218 | case 24:
|
---|
219 | {
|
---|
220 | int data_step = stride - gbm->w * 3;
|
---|
221 | int p_step = stride_t - 2;
|
---|
222 | int x, y;
|
---|
223 |
|
---|
224 | for ( y = 0; y < gbm->h; y++ )
|
---|
225 | {
|
---|
226 | byte *p = data_t; data_t += 3;
|
---|
227 |
|
---|
228 | for ( x = 0; x < gbm->w; x++ )
|
---|
229 | {
|
---|
230 | *p++ = *data++;
|
---|
231 | *p++ = *data++;
|
---|
232 | *p = *data++;
|
---|
233 | p += p_step;
|
---|
234 | }
|
---|
235 | data += data_step;
|
---|
236 | }
|
---|
237 | }
|
---|
238 | break;
|
---|
239 | /*...e*/
|
---|
240 | /*...s8:16:*/
|
---|
241 | case 8:
|
---|
242 | {
|
---|
243 | int data_step = stride - gbm->w;
|
---|
244 | int x, y;
|
---|
245 |
|
---|
246 | for ( y = 0; y < gbm->h; y++ )
|
---|
247 | {
|
---|
248 | byte *p = data_t++;
|
---|
249 |
|
---|
250 | for ( x = 0; x < gbm->w; x++ )
|
---|
251 | {
|
---|
252 | *p = *data++;
|
---|
253 | p += stride_t;
|
---|
254 | }
|
---|
255 | data += data_step;
|
---|
256 | }
|
---|
257 | }
|
---|
258 | break;
|
---|
259 | /*...e*/
|
---|
260 | /*...s4:16:*/
|
---|
261 | case 4:
|
---|
262 | {
|
---|
263 | int x, y;
|
---|
264 |
|
---|
265 | for ( y = 0; y < gbm->h; y += 2 )
|
---|
266 | {
|
---|
267 | for ( x = 0; x < gbm->w; x += 2 )
|
---|
268 | /*...s2x2 transpose to 2x2:40:*/
|
---|
269 | {
|
---|
270 | const byte *src = data + y * stride + ((unsigned)x >> 1);
|
---|
271 | byte ab = src[0 ];
|
---|
272 | byte cd = src[stride];
|
---|
273 | byte *dst = data_t + x * stride_t + ((unsigned)y >> 1);
|
---|
274 | dst[0 ] = (byte) ((ab & 0xf0) | (cd >> 4));
|
---|
275 | dst[stride_t] = (byte) ((ab << 4) | (cd & 0x0f));
|
---|
276 | }
|
---|
277 | /*...e*/
|
---|
278 | if ( x < gbm->w )
|
---|
279 | /*...s1x2 transpose to 2x1:40:*/
|
---|
280 | {
|
---|
281 | const byte *src = data + y * stride + ((unsigned)x >> 1);
|
---|
282 | byte a0 = src[0 ];
|
---|
283 | byte b0 = src[stride];
|
---|
284 | byte *dst = data_t + x * stride_t + ((unsigned)y >> 1);
|
---|
285 | dst[0 ] = (byte) ((a0 & 0xf0) | (b0 >> 4));
|
---|
286 | }
|
---|
287 | /*...e*/
|
---|
288 | }
|
---|
289 | if ( y < gbm->h )
|
---|
290 | {
|
---|
291 | for ( x = 0; x < gbm->w; x += 2 )
|
---|
292 | /*...s2x1 transpose to 1x2:40:*/
|
---|
293 | {
|
---|
294 | const byte *src = data + y * stride + ((unsigned)x >> 1);
|
---|
295 | byte ab = src[0 ];
|
---|
296 | byte *dst = data_t + x * stride_t + ((unsigned)y >> 1);
|
---|
297 | dst[0 ] = (byte) (ab & 0xf0);
|
---|
298 | dst[stride_t] = (byte) (ab << 4);
|
---|
299 | }
|
---|
300 | /*...e*/
|
---|
301 | if ( x < gbm->w )
|
---|
302 | /*...s1x1 transpose to 1x1:40:*/
|
---|
303 | {
|
---|
304 | const byte *src = data + y * stride + ((unsigned)x >> 1);
|
---|
305 | byte a0 = src[0 ];
|
---|
306 | byte *dst = data_t + x * stride_t + ((unsigned)y >> 1);
|
---|
307 | dst[0 ] = (byte) (a0 & 0xf0);
|
---|
308 | }
|
---|
309 | /*...e*/
|
---|
310 | }
|
---|
311 | }
|
---|
312 | break;
|
---|
313 | /*...e*/
|
---|
314 | /*...s1:16:*/
|
---|
315 | case 1:
|
---|
316 | {
|
---|
317 | int x, y;
|
---|
318 | byte xbit, ybit;
|
---|
319 |
|
---|
320 | memset(data_t, 0, gbm->w * stride_t);
|
---|
321 |
|
---|
322 | ybit = 0x80;
|
---|
323 | for ( y = 0; y < gbm->h; y++ )
|
---|
324 | {
|
---|
325 | xbit = 0x80;
|
---|
326 | for ( x = 0; x < gbm->w; x++ )
|
---|
327 | {
|
---|
328 | const byte *src = data + y * stride + ((unsigned)x >> 3);
|
---|
329 | byte *dst = data_t + x * stride_t + ((unsigned)y >> 3);
|
---|
330 |
|
---|
331 | if ( *src & xbit )
|
---|
332 | *dst |= ybit;
|
---|
333 |
|
---|
334 | if ( (xbit >>= 1) == 0 )
|
---|
335 | xbit = 0x80;
|
---|
336 | }
|
---|
337 | if ( (ybit >>= 1) == 0 )
|
---|
338 | ybit = 0x80;
|
---|
339 | }
|
---|
340 | }
|
---|
341 | break;
|
---|
342 | /*...e*/
|
---|
343 | }
|
---|
344 | }
|
---|
345 | /*...e*/
|
---|