1 # include "bitmapConfig.h"
2
3 # include "bmintern.h"
4
5 # include <appDebugon.h>
6
7 /************************************************************************/
8 /* */
9 /* Draw images in another one. */
10 /* */
11 /************************************************************************/
12
13 # define PARANOIA 0
14
15 # if PARANOIA
16
17 static const BitmapDescription * bdInPara;
18 static const BitmapDescription * bdToPara;
19
20 static unsigned char * bufToSav;
21 static const unsigned char * bufInSav;
22
23 static unsigned char oo[2000];
24 static unsigned char se[2000];
25 static unsigned char no[2000];
26
27 # define CHECK_RESULT() \
28 \
29 bmInflateTo8bit( no, bufToSav, bdToPara, 0, 0 ); \
30 ocol= colTo0; \
31 for ( col= colIn0; col < colInP; ocol++, col++ ) \
32 { \
33 if ( no[ocol] != ( oo[ocol] | se[col] ) ) \
34 { LLLDEB(no[ocol],oo[ocol],se[col]);LLDEB(ocol,col);abort();} \
35 } \
36 for ( ocol= 0; ocol < colTo0; ocol++ ) \
37 { \
38 if ( no[ocol] != oo[ocol] ) \
39 { LLLDEB(ocol,no[ocol],oo[ocol]);abort();} \
40 } \
41 for ( ocol= colTo0+ colInP- colIn0; \
42 ocol < bdToPara->bdPixelsWide; ocol++ ) \
43 { \
44 if ( no[ocol] != oo[ocol] ) \
45 { LLLDEB(ocol,no[ocol],oo[ocol]);abort();} \
46 }
47
48 # define INIT_CHECK() \
49 \
50 int ocol; \
51 \
52 bufToSav= bufTo; \
53 bufInSav= bufIn; \
54 \
55 bmInflateTo8bit( oo, bufToSav, bdToPara, 0, 0 ); \
56 bmInflateTo8bit( se, bufInSav, bdInPara, 0, 0 );
57
58 # endif
59
60
61 /************************************************************************/
62 /* */
63 /* 'Or'/'And' a shifted structuring element into the output buffer. */
64 /* */
65 /* 1) Loop over the columns in the structuring element. NOTE that */
66 /* the limits in the output are dictated by the size of the image */
67 /* only, so we do not need to bother about masking off data to */
68 /* protect bits in an output byte beyond colToP. */
69 /* */
70 /* a) Contribution of the first byte in the structuring element. As */
71 /* its offset is left of the first output byte, only the left */
72 /* shift is relevant. */
73 /* b) Contribution of all middle bytes in the structuring element. */
74 /* c) Contribution of the last byte in the strucuring element. Only */
75 /* the right shift is relevant. */
76 /* */
77 /* A) Contribution of the first byte in the structuring element. As */
78 /* its offset is right of the first output byte, only the right */
79 /* shift is relevant for the first output byte. The left is for */
80 /* the second output byte. */
81 /* B) Contribution of all middle bytes in the structuring element. */
82 /* C) Contribution of the last byte in the strucuring element. Only */
83 /* the right shift is relevant. */
84 /* */
85 /************************************************************************/
86
87 typedef void (*OR_ROW) ( unsigned char * bufTo,
88 const unsigned char * bufIn,
89 const int colTo0,
90 const int colIn0,
91 const int colInP,
92 int shift0,
93 int shift1,
94 unsigned char invertMaskIn,
95 unsigned char endMask );
96
97 /********************************/
98 /* */
99 /* colIn0 % 8 > colTo0 % 8 */
100 /* */
101 /********************************/
102
bmDrawOrRowRight(unsigned char * bufTo,const unsigned char * bufIn,const int colTo0,const int colIn0,const int colInP,int shift0,int shift1,unsigned char invertMaskIn,unsigned char endMask)103 static void bmDrawOrRowRight( unsigned char * bufTo,
104 const unsigned char * bufIn,
105 const int colTo0,
106 const int colIn0,
107 const int colInP,
108 int shift0,
109 int shift1,
110 unsigned char invertMaskIn,
111 unsigned char endMask )
112 {
113 int col;
114 unsigned char mask;
115 unsigned char val;
116
117 # if PARANOIA
118 INIT_CHECK();
119 # endif
120
121 bufTo += colTo0/8;
122 bufIn += colIn0/8;
123
124 col= 8* ( colIn0/ 8 );
125 mask= 0xff;
126
127 if ( col+ 8 > colInP )
128 { mask &= endMask; }
129
130 /* a */
131 val= bufIn[0] ^ invertMaskIn;
132 bufTo[0] |= ( val & mask ) << shift0;
133 bufIn++, col += 8;
134
135 /* b */
136 for (; col+ 8 < colInP; bufIn++, col += 8 )
137 {
138 val= bufIn[0] ^ invertMaskIn;
139
140 bufTo[0] |= ( val ) >> shift1;
141 bufTo++;
142 bufTo[0] |= ( val ) << shift0;
143 }
144
145 /* c */
146 if ( col < colInP )
147 {
148 val= bufIn[0] ^ invertMaskIn;
149
150 if ( col+ 8 > colInP )
151 { mask &= endMask; }
152
153 bufTo[0] |= ( val & mask ) >> shift1;
154 bufTo++;
155 bufTo[0] |= ( val & mask ) << shift0;
156 }
157
158 # if PARANOIA
159 CHECK_RESULT();
160 # endif
161
162 return;
163 }
164
165 /********************************/
166 /* */
167 /* colIn0 % 8 < colTo0 % 8 */
168 /* */
169 /********************************/
170
bmDrawOrRowLeft(unsigned char * bufTo,const unsigned char * bufIn,const int colTo0,const int colIn0,const int colInP,int shift0,int shift1,unsigned char invertMaskIn,unsigned char endMask)171 static void bmDrawOrRowLeft( unsigned char * bufTo,
172 const unsigned char * bufIn,
173 const int colTo0,
174 const int colIn0,
175 const int colInP,
176 int shift0,
177 int shift1,
178 unsigned char invertMaskIn,
179 unsigned char endMask )
180 {
181 int col;
182 unsigned char mask;
183 unsigned char val;
184
185 # if PARANOIA
186 INIT_CHECK();
187 # endif
188
189 bufTo += colTo0/8;
190 bufIn += colIn0/8;
191
192 col= 8* ( colIn0/ 8 );
193 mask= 0xff;
194
195 if ( col+ 8 > colInP )
196 { mask &= endMask; }
197
198 /* A */
199 val= bufIn[0] ^ invertMaskIn;
200
201 bufTo[0] |= ( val & mask ) >> shift0;
202 bufTo++;
203 bufTo[0] |= ( val & mask ) << shift1;
204 bufIn++, col += 8;
205
206 /* B */
207 for (; col+ 8 < colInP; bufIn++, col += 8 )
208 {
209 val= bufIn[0] ^ invertMaskIn;
210
211 bufTo[0] |= ( val ) >> shift0;
212 bufTo++;
213 bufTo[0] |= ( val ) << shift1;
214 }
215
216 /* C */
217 if ( col < colInP )
218 {
219 val= bufIn[0] ^ invertMaskIn;
220
221 if ( col+ 8 > colInP )
222 { mask &= endMask; }
223
224 bufTo[0] |= ( val & mask ) >> shift0;
225 bufTo++;
226 bufTo[0] |= ( val & mask ) << shift1;
227 }
228
229 # if PARANOIA
230 CHECK_RESULT();
231 # endif
232
233 return;
234 }
235
236 /********************************/
237 /* */
238 /* colIn0 % 8 == colTo0 % 8 */
239 /* */
240 /********************************/
241
bmDrawOrRowEq(unsigned char * bufTo,const unsigned char * bufIn,const int colTo0,const int colIn0,const int colInP,int ign_shift0,int ign_shift1,unsigned char invertMaskIn,unsigned char endMask)242 static void bmDrawOrRowEq( unsigned char * bufTo,
243 const unsigned char * bufIn,
244 const int colTo0,
245 const int colIn0,
246 const int colInP,
247 int ign_shift0,
248 int ign_shift1,
249 unsigned char invertMaskIn,
250 unsigned char endMask )
251 {
252 int col;
253 unsigned char mask;
254 unsigned char val;
255
256 # if PARANOIA
257 INIT_CHECK();
258 # endif
259
260 bufTo += colTo0/8;
261 bufIn += colIn0/8;
262
263 col= 8* ( colIn0/ 8 );
264 mask= 0xff;
265
266 if ( col+ 8 > colInP )
267 { mask &= endMask; }
268
269 /* A */
270 val= bufIn[0] ^ invertMaskIn;
271
272 bufTo[0] |= ( val & mask );
273 bufTo++;
274 bufIn++, col += 8;
275
276 /* B */
277 for (; col+ 8 < colInP; bufIn++, col += 8 )
278 {
279 val= bufIn[0] ^ invertMaskIn;
280
281 bufTo[0] |= ( val );
282 bufTo++;
283 }
284
285 /* C */
286 if ( col < colInP )
287 {
288 val= bufIn[0] ^ invertMaskIn;
289
290 if ( col+ 8 > colInP )
291 { mask &= endMask; }
292
293 bufTo[0] |= ( val & mask );
294 }
295
296 # if PARANOIA
297 CHECK_RESULT();
298 # endif
299
300 return;
301 }
302
303 /************************************************************************/
304 /* */
305 /* Insert an image in another one. */
306 /* */
307 /* 1) Find the relevant rectangle on both images. It should not */
308 /* protrude off one of the images. */
309 /* 2) Determine how to mask the surplus bytes of the input image. */
310 /* 3) Determine the best way to set the bits. */
311 /* 4) Set the bits of the individual rows. */
312 /* */
313 /************************************************************************/
314
bmDraw1BitImage(const BitmapDescription * bdTo,unsigned char * bufTo,const RasterImage * riIn,unsigned char invertMaskIn,int rowTo0,int colTo0)315 void bmDraw1BitImage( const BitmapDescription * bdTo,
316 unsigned char * bufTo,
317 const RasterImage * riIn,
318 unsigned char invertMaskIn,
319 int rowTo0,
320 int colTo0 )
321 {
322 const BitmapDescription * bdIn= &(riIn->riDescription);
323
324 int rowToP, colToP;
325 int rowIn0, colIn0;
326 int rowInP, colInP;
327
328 int rowTo;
329 int rowIn;
330
331 int shift0;
332 int shift1;
333
334 unsigned char endMask;
335
336 OR_ROW orRow= (OR_ROW)0;
337
338 /* 1 */
339 rowToP= rowTo0+ bdIn->bdPixelsHigh;
340 colToP= colTo0+ bdIn->bdPixelsWide;
341
342 rowIn0= 0;
343 rowInP= bdIn->bdPixelsHigh;
344 colIn0= 0;
345 colInP= bdIn->bdPixelsWide;
346
347 if ( rowTo0 < 0 )
348 {
349 rowIn0 -= rowTo0;
350 rowTo0= 0;
351 }
352 if ( rowToP > bdTo->bdPixelsHigh )
353 {
354 rowInP -= rowToP- bdTo->bdPixelsHigh;
355 rowToP= bdTo->bdPixelsHigh;
356 }
357
358 if ( colTo0 < 0 )
359 {
360 colIn0 -= colTo0;
361 colTo0= 0;
362 }
363 if ( colToP > bdTo->bdPixelsWide )
364 {
365 colInP -= colToP- bdTo->bdPixelsWide;
366 colToP= bdTo->bdPixelsWide;
367 }
368
369 /* 2 */
370 endMask= 0xff;
371 if ( colInP % 8 )
372 { endMask= 0xff << ( 8- colInP % 8 ); }
373
374 /* 3 */
375 if ( colIn0 % 8 > colTo0 % 8 )
376 {
377 shift0= colIn0 % 8- colTo0 % 8;
378 shift1= 8- shift0;
379
380 orRow= bmDrawOrRowRight;
381 }
382 else{
383 shift0= colTo0 % 8- colIn0 % 8;
384 shift1= 8- shift0;
385
386 if ( colIn0 % 8 < colTo0 % 8 )
387 { orRow= bmDrawOrRowLeft; }
388 else{ orRow= bmDrawOrRowEq; }
389 }
390
391 /*
392 LLLLDEB(rowTo0,rowToP,colTo0,colToP);
393 LLLLDEB(rowIn0,rowInP,colIn0,colInP);
394 */
395
396 /* 4 */
397 rowIn= rowIn0;
398 for ( rowTo= rowTo0; rowTo < rowToP; rowIn++, rowTo++ )
399 {
400 unsigned char * rowBufTo;
401 const unsigned char * rowBufIn;
402
403 rowBufTo= bufTo+ rowTo* bdTo->bdBytesPerRow;
404 rowBufIn= riIn->riBytes+ rowIn* bdIn->bdBytesPerRow;
405
406 (*orRow)( rowBufTo, rowBufIn, colTo0, colIn0, colInP,
407 shift0, shift1, invertMaskIn, endMask );
408 }
409
410 return;
411 }
412
413