1 # include "bitmapConfig.h"
2
3 # include "bmintern.h"
4
5 # include <appDebugon.h>
6
7 /************************************************************************/
8 /* */
9 /* Set one run in a bitmap. */
10 /* These routines only work for 1 bit/pixel. */
11 /* */
12 /* 1) End point inclusive. */
13 /* */
14 /************************************************************************/
15
16 static unsigned char BM_BitCounts[256];
17
bmCount1Run1Bit(const unsigned char * buffer,int col0,int col1)18 static int bmCount1Run1Bit( const unsigned char * buffer,
19 int col0,
20 int col1 )
21 {
22 int d;
23 unsigned char c1, c2;
24 const unsigned char * b1= (unsigned char *)0;
25 const unsigned char * b2= (unsigned char *)0;
26
27 int count= 0;
28
29 /*
30 APP_DEB(appDebug( "bmCount1Run(,col0=%d,col1=%d)\n", col0, col1 ));
31 */
32
33 /* 1 */
34 col1++;
35
36 d= ( col0 % 8 );
37 if ( d )
38 {
39 b1= buffer+ col0/ 8;
40
41 col0= 8* ( col0/ 8 )+ 8;
42
43 c1= 0xff >> d;
44 }
45 else{ c1= 0; }
46
47 d= ( col1 % 8 );
48 if ( d )
49 {
50 b2= buffer+ col1/ 8;
51
52 col1= 8* ( col1/ 8 );
53
54 c2= 0xff << ( 8- d );
55 }
56 else{ c2= 0; }
57
58 if ( b1 )
59 {
60 if ( b1 == b2 )
61 { count += BM_BitCounts[ *b1 & c1 & c2 ]; }
62 else{
63 count += BM_BitCounts[ *b1 & c1 ];
64 }
65 }
66
67 if ( b2 && b2 != b1 )
68 { count += BM_BitCounts[ *b2 & c2 ]; }
69
70 col0 /= 8;
71 col1 /= 8;
72
73 b1= buffer+ col0;
74 while( col0++ < col1 )
75 { count += BM_BitCounts[ *(b1++) ]; }
76
77 return count;
78 }
79
80 /************************************************************************/
81 /* */
82 /* Count the number of bits set to 0 on a horizontal stretch. */
83 /* */
84 /* 1) Switch to 'upto' semantics. */
85 /* 2) If the beginning is not on a byte boundary, obtain a mask for */
86 /* the tail of the byte. Exclude this byte from the count below */
87 /* 3) If the end is not on a byte boundary, obtain a mask for the */
88 /* head of the byte. Exclude this byte from the count below */
89 /* 4) Count bits in the head byte. Handle the situation where head */
90 /* and tail refer to the same byte. */
91 /* 5) Count bits in the tail byte. (Unless head and tail are the same)*/
92 /* 6) Count bits in the bytes between head and tail. */
93 /* */
94 /************************************************************************/
95
bmCount0Run1Bit(const unsigned char * buffer,int col0,int col1)96 static int bmCount0Run1Bit( const unsigned char * buffer,
97 int col0,
98 int col1 )
99 {
100 int d;
101 unsigned char c1, c2;
102 const unsigned char * b1= (unsigned char *)0;
103 const unsigned char * b2= (unsigned char *)0;
104
105 int count= 0;
106
107 /* 1 */
108 col1++;
109
110 /* 2 */
111 d= ( col0 % 8 );
112 if ( d )
113 {
114 b1= buffer+ col0/ 8;
115
116 col0= 8* ( col0/ 8 )+ 8;
117
118 c1= 0xff >> d; c1= ~c1;
119 }
120 else{ c1= 0xff; }
121
122 /* 3 */
123 d= ( col1 % 8 );
124 if ( d )
125 {
126 b2= buffer+ col1/ 8;
127
128 col1= 8* ( col1/ 8 );
129
130 c2= 0xff << ( 8- d ); c2= ~c2;
131 }
132 else{ c2= 0xff; }
133
134 /* 4 */
135 if ( b1 )
136 {
137 if ( b1 == b2 )
138 { count += 8- BM_BitCounts[ *b1 | c1 | c2 ]; }
139 else{ count += 8- BM_BitCounts[ *b1 | c1 ]; }
140 }
141
142 if ( b2 && b2 != b1 )
143 { count += 8- BM_BitCounts[ *b2 | c2 ]; }
144
145 col0 /= 8;
146 col1 /= 8;
147
148 b1= buffer+ col0;
149 while( col0++ < col1 )
150 { count += 8- (int)BM_BitCounts[ *(b1++) ]; }
151
152 return count;
153 }
154
155 /************************************************************************/
156 /* */
157 /* count a line using Bressenham. */
158 /* */
159 /* 1) Line is supposed to be to the right. */
160 /* */
161 /************************************************************************/
162
bmCountBres1Line1Bit(const unsigned char * buffer,int x0,int y0,int x1,int y1,int bytesPerRow)163 static int bmCountBres1Line1Bit(
164 const unsigned char * buffer,
165 int x0,
166 int y0,
167 int x1,
168 int y1,
169 int bytesPerRow )
170 {
171 int dx;
172 int dy;
173 int i;
174
175 int e, d2, e2;
176
177 unsigned char byteMask;
178
179 int count= 0;
180
181 dx= x1- x0;
182 dy= y1- y0;
183
184 /* 1 */
185 if ( dx < 0 )
186 { LDEB(dx); return 0; }
187
188 buffer += y0* bytesPerRow+ x0/ 8;
189 byteMask= 0x80 >> ( x0 % 8 );
190
191 if ( dy < 0 )
192 { dy = -dy; bytesPerRow= -bytesPerRow; }
193
194 if ( dx > dy )
195 {
196 e= 2* dy- dx;
197 d2= 2* dx;
198 e2= 2* dy;
199
200 while( x0 <= x1 )
201 {
202 count += BM_BitCounts[ *buffer & byteMask ];
203
204 while( e >= 0 )
205 { buffer += bytesPerRow; e -= d2; }
206
207 byteMask >>= 1; x0++; e += e2;
208
209 if ( ! ( x0 % 8 ) )
210 { buffer++; byteMask= 0x80; }
211 }
212 }
213 else{
214 e= 2* dx- dy;
215 d2= 2* dy;
216 e2= 2* dx;
217
218 for ( i= 0; i <= dy; i++ )
219 {
220 count += BM_BitCounts[ *buffer & byteMask ];
221
222 while( e > 0 )
223 {
224 byteMask >>= 1; x0++; e -= d2;
225
226 if ( ! ( x0 % 8 ) )
227 { buffer++; byteMask= 0x80; }
228 }
229
230 buffer += bytesPerRow; e += e2;
231 }
232 }
233
234 return count;
235 }
236
bmCountBres0Line1Bit(const unsigned char * buffer,int x0,int y0,int x1,int y1,int bytesPerRow)237 static int bmCountBres0Line1Bit(
238 const unsigned char * buffer,
239 int x0,
240 int y0,
241 int x1,
242 int y1,
243 int bytesPerRow )
244 {
245 int dx;
246 int dy;
247 int i;
248
249 int e, d2, e2;
250
251 unsigned char byteMask;
252
253 int count= 0;
254
255 dx= x1- x0;
256 dy= y1- y0;
257
258 /* 1 */
259 if ( dx < 0 )
260 { LDEB(dx); return 0; }
261
262 buffer += y0* bytesPerRow+ x0/ 8;
263 byteMask= 0x80 >> ( x0 % 8 ); byteMask= ~byteMask;
264
265 if ( dy < 0 )
266 { dy = -dy; bytesPerRow= -bytesPerRow; }
267
268 if ( dx > dy )
269 {
270 e= 2* dy- dx;
271 d2= 2* dx;
272 e2= 2* dy;
273
274 while( x0 <= x1 )
275 {
276 count += 8- BM_BitCounts[ *buffer | byteMask ];
277
278 while( e >= 0 )
279 { buffer += bytesPerRow; e -= d2; }
280
281 byteMask >>= 1; byteMask |= 0x80; x0++; e += e2;
282
283 if ( ! ( x0 % 8 ) )
284 { buffer++; byteMask= 0x7f; }
285 }
286 }
287 else{
288 e= 2* dx- dy;
289 d2= 2* dy;
290 e2= 2* dx;
291
292 for ( i= 0; i <= dy; i++ )
293 {
294 count += 8- BM_BitCounts[ *buffer | byteMask ];
295
296 while( e > 0 )
297 {
298 byteMask >>= 1; byteMask |= 0x80; x0++; e -= d2;
299
300 if ( ! ( x0 % 8 ) )
301 { buffer++; byteMask= 0x7f; }
302 }
303
304 buffer += bytesPerRow; e += e2;
305 }
306 }
307
308 return count;
309 }
310
311
312 /************************************************************************/
313 /* */
314 /* Draw a line segment. */
315 /* */
316 /* 1) Make it vertical or to the right. */
317 /* */
318 /************************************************************************/
319
bmCountLinePixels(const unsigned char * buffer,const BitmapDescription * bd,int x0,int y0,int x1,int y1)320 int bmCountLinePixels( const unsigned char * buffer,
321 const BitmapDescription * bd,
322 int x0,
323 int y0,
324 int x1,
325 int y1 )
326 {
327 int i;
328 int count= 0;
329
330 int (*countRun)( const unsigned char * _buffer,
331 int _x0,
332 int _y0 );
333
334 int (*countLine)( const unsigned char * _buffer,
335 int _x0,
336 int _y0,
337 int _x1,
338 int _y1,
339 int _bytesPerRow );
340
341 switch( bd->bdColorEncoding )
342 {
343 case BMcoBLACKWHITE:
344 if ( bd->bdBitsPerPixel != 1 )
345 {
346 LLDEB(bd->bdColorEncoding,bd->bdBitsPerPixel);
347 return -1;
348 }
349
350 countLine= bmCountBres1Line1Bit;
351 countRun= bmCount1Run1Bit;
352 break;
353
354 case BMcoWHITEBLACK:
355 if ( bd->bdBitsPerPixel != 1 )
356 {
357 LLDEB(bd->bdColorEncoding,bd->bdBitsPerPixel);
358 return -1;
359 }
360
361 countLine= bmCountBres0Line1Bit;
362 countRun= bmCount0Run1Bit;
363 break;
364
365 default:
366 LDEB(bd->bdColorEncoding);
367 return -1;
368 }
369
370
371 if ( x0 < 0 || x0 >= bd->bdPixelsWide )
372 { LLDEB(x0,bd->bdPixelsWide); return -1; }
373 if ( x1 < 0 || x1 >= bd->bdPixelsWide )
374 { LLDEB(x1,bd->bdPixelsWide); return -1; }
375 if ( y0 < 0 || y0 >= bd->bdPixelsHigh )
376 { LLDEB(y0,bd->bdPixelsHigh); return -1; }
377 if ( y1 < 0 || y1 >= bd->bdPixelsHigh )
378 { LLDEB(y1,bd->bdPixelsHigh); return -1; }
379
380
381 if ( BM_BitCounts[1] == 0 )
382 {
383 int pos;
384
385 for ( pos= 0; pos < 256; pos++ )
386 {
387 unsigned int p= pos;
388
389 BM_BitCounts[pos]= 0;
390
391 while( p )
392 {
393 if ( p & 0x01 )
394 { BM_BitCounts[pos]++; }
395
396 p >>= 1;
397 }
398 }
399 }
400
401 /* 1 */
402 if ( x0 > x1 )
403 { i= x0; x0= x1; x1= i; i= y0; y0= y1; y1= i; }
404
405 if ( y1 == y0 )
406 {
407 count += (*countRun)( buffer+ y0* bd->bdBytesPerRow, x0, x1 );
408 return count;
409 }
410
411 if ( x1 == x0 )
412 {
413 if ( y1 < y0 )
414 { i= y0; y0= y1; y1= i; }
415
416 buffer += y0* bd->bdBytesPerRow;
417
418 while( y0 <= y1 )
419 {
420 count += (*countRun)( buffer, x0, x1 );
421
422 y0++; buffer += bd->bdBytesPerRow;
423 }
424
425 return count;
426 }
427
428 count += (*countLine)( buffer, x0, y0, x1, y1, bd->bdBytesPerRow );
429
430 return count;
431 }
432