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