1 #if P_SZ == 1
2 #define PIXTYPE unsigned char
3 #define REDSHIFT 4
4 #define GRNSHIFT 2
5 #define COLMASK 0x3
6 #define _Line Line8
7 #define _BoxBlur BoxBlur8
8 #define _CrossBlur CrossBlur8
9 #define _EraseRect EraseRect8
10 #define __Clr(r,g,b) (r >> 8)
11 #elif P_SZ == 2
12 #define PIXTYPE unsigned short
13 #define REDSHIFT 10
14 #define GRNSHIFT 5
15 #define COLMASK 0x1F
16 #define _Line Line16
17 #define _BoxBlur BoxBlur16
18 #define _CrossBlur CrossBlur16
19 #define _EraseRect EraseRect16
20 #define __Clr(r,g,b) (((r & 0xF800) >> 1) | ((g & 0xF800) >> 6) | (b >> 11))
21 #elif P_SZ == 4
22 #define PIXTYPE unsigned long
23 #define REDSHIFT 16
24 #define GRNSHIFT 8
25 #define COLMASK 0xFF
26 #define _Line Line32
27 #define _BoxBlur BoxBlur32
28 #define _CrossBlur CrossBlur32
29 #define _EraseRect EraseRect32
30 #if EG_MAC || defined(UNIX_X)
31 #define __Clr(r,g,b) (((r & 0xFF00) << 8) | (g & 0xFF00) | (b >> 8))
32 #elif EG_WIN
33 #define __Clr(r,g,b) __winRGB( b, g, r )
34 #endif
35
36 #endif
37
38
39
40
41 #define __doXerr error_term += dy; \
42 if ( error_term >= dx ) { \
43 error_term -= dx; \
44 basePtr += rowOffset; \
45 ymov--; \
46 }
47
48
49 #define __doYerr error_term += dx; \
50 if ( error_term >= dy ) { \
51 error_term -= dy; \
52 basePtr += xDirection; \
53 xmov--; \
54 }
55
56 #define __calcClr color = __Clr( R, G, B ); \
57 R += dR; \
58 G += dG; \
59 B += dB;
60
61
62 #define __circ( dia, a ) switch ( (dia) ) { \
63 case 2: a = "\0\0"; break; \
64 case 3: a = "\1\0\1"; break; \
65 case 4: a = "\1\0\0\1"; break; \
66 case 5: a = "\1\0\0\0\1"; break; \
67 case 6: a = "\1\0\0\0\0\1"; break; \
68 case 7: a = "\2\1\0\0\0\1\2"; break; \
69 case 8: a = "\2\1\0\0\0\0\1\2"; break; \
70 case 9: a = "\3\1\1\0\0\0\1\1\3"; break; \
71 case 10: a = "\3\1\1\0\0\0\0\1\1\3"; break; \
72 case 11: a = "\4\2\1\1\0\0\0\1\1\2\4"; break; \
73 case 12: a = "\4\2\1\1\0\0\0\0\1\1\2\4"; break; \
74 }
75
76
77 #define CLR_INTERP 1
78 #include "LineXX.cpp"
79 #undef CLR_INTERP
80 #include "LineXX.cpp"
81
82 /*
83 void PixPort::_Line( int sx, int sy, int ex, int ey, long inColor ) {
84 int xDirection, rowOffset, error_term;
85 char* basePtr;
86 int xmov, ymov, dx, dy, t;
87
88 // Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
89 if ( sx < 0 || sx > mX || sy < 0 || sy > mY ) {
90 t = ex; ex = sx; sx = t;
91 t = ey; ey = sy; sy = t;
92 }
93
94 // Exit if the start pt is out of bounds (wimpy clipping, eh?)
95 if ( sx < 0 || sx > mX || sy < 0 || sy > mY )
96 return;
97
98 // In Win32, everything's upside down
99 #if EG_WIN
100 sy = mY - sy;
101 ey = mY - ey;
102 #endif
103
104 dx = ex - sx;
105 dy = ey - sy;
106
107 // moving left or right?
108 xmov = dx;
109 if ( dx < 0 ) {
110 xmov = -dx;
111 if ( sx - xmov < 0 )
112 xmov = sx;
113 xDirection = - P_SZ;
114 dx = -dx; }
115 else if ( dx > 0 ) {
116 if ( sx + xmov > mX )
117 xmov = mX - sx;
118 xDirection = P_SZ; }
119 else
120 xDirection = 0;
121
122 // moving up or down?
123 ymov = dy;
124 if ( dy < 0 ) {
125 ymov = -dy;
126 if ( sy - ymov < 0 )
127 ymov = sy;
128 rowOffset = - mBytesPerRow;
129 dy = -dy; }
130 else if ( dy > 0 ) {
131 if ( sy + ymov > mY )
132 ymov = mY - sy;
133 rowOffset = mBytesPerRow; }
134 else
135 rowOffset = 0;
136
137 basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
138 error_term = 0;
139
140 // Draw the line
141 if ( dx >= dy ) {
142
143 // Start counting off in x
144 for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
145
146 *((PIXTYPE*) basePtr) = inColor;
147 basePtr += xDirection;
148
149 // Check to see if we need to move the pixelOffset in the y direction.
150 error_term += dy;
151 if ( error_term >= dx ) {
152 error_term -= dx;
153 basePtr += rowOffset;
154 ymov--;
155 }
156 } }
157 else {
158 // Start counting off in y
159 for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
160
161 *((PIXTYPE*) basePtr) = inColor;
162 basePtr += rowOffset;
163
164 // Check to see if we need to move the pixelOffset in the y direction.
165 error_term += dx;
166 if ( error_term >= dy ) {
167 error_term -= dy;
168 basePtr += xDirection;
169 xmov--;
170 }
171 }
172 }
173 }
174
175 */
176
177
178
179 /*
180 void PixPort::_LineW( int sx, int sy, int ex, int ey, int inWidth, long inColor ) {
181 int xDirection, rowOffset, error_term;
182 char* basePtr, *rowPtr;
183 int xmov, ymov, dx, dy, t, i, xDir, yDir;
184
185 // Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
186 if ( sx < 0 || sx > mX || sy < 0 || sy > mY ) {
187 t = ex; ex = sx; sx = t;
188 t = ey; ey = sy; sy = t;
189 }
190
191 // Exit if the start pt is out of bounds (wimpy clipping, eh?)
192 if ( sx < 0 || sx > mX || sy < 0 || sy > mY )
193 return;
194
195 // In Win32, everything's upside down
196 #if EG_WIN
197 sy = mY - sy;
198 ey = mY - ey;
199 #endif
200
201 dx = ex - sx;
202 dy = ey - sy;
203
204 // moving left or right?
205 xmov = dx;
206 if ( dx < 0 ) {
207 xmov = -dx;
208 if ( sx - xmov < 0 )
209 xmov = sx;
210 xDirection = - P_SZ;
211 xDir = -1;
212 dx = -dx; }
213 else if ( dx > 0 ) {
214 if ( sx + xmov > mX )
215 xmov = mX - sx;
216 xDir = 1;
217 xDirection = P_SZ; }
218 else {
219 xDirection = 0;
220 xDir = 0;
221 }
222
223 // moving up or down?
224 ymov = dy;
225 if ( dy < 0 ) {
226 ymov = -dy;
227 if ( sy - ymov < 0 )
228 ymov = sy;
229 yDir = 1;
230 rowOffset = - mBytesPerRow;
231 dy = -dy; }
232 else if ( dy > 0 ) {
233 if ( sy + ymov > mY )
234 ymov = mY - sy;
235 yDir = -1;
236 rowOffset = mBytesPerRow; }
237 else {
238 yDir = 0;
239 rowOffset = 0;
240 }
241
242
243 basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
244 error_term = 0;
245
246 // Draw the line
247 if ( dx >= dy ) {
248 bool didRow = false;
249 int limx;
250 if ( xDirection > 0 )
251 limx = ex;
252 else
253 limx = sx;
254 if ( limx > mX )
255 limx = mX;
256
257
258 // Start counting off in x
259 for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
260
261 if ( ! didRow ) {
262 for ( i = 0; i < inWidth && sx + i <= limx; i++ ) {
263 ((PIXTYPE*) basePtr)[i] = inColor;
264 }
265 didRow = true;
266 }
267 sx += xDir;
268
269 basePtr += xDirection;
270
271 // Check to see if we need to move the pixelOffset in the y direction.
272 error_term += dy;
273 if ( error_term >= dx ) {
274 error_term -= dx;
275
276 // Finish the rest of the line width, making sure we don't go off the right
277 didRow = false;
278 basePtr += rowOffset;
279 ymov--;
280 }
281 } }
282 else {
283
284 // Start counting off in y
285 for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
286
287 // Do the whole line width, making sure we don't go off the right
288 for ( i = 0; i < inWidth && sx + i < mX; i++ )
289 ((PIXTYPE*) basePtr)[i] = inColor;
290 basePtr += rowOffset;
291
292 // Check to see if we need to move the pixelOffset in the y direction.
293 error_term += dx;
294 if ( error_term >= dy ) {
295 error_term -= dy;
296 basePtr += xDirection;
297 xmov--;
298 sx += xDir;
299 }
300 }
301 }
302 }*/
303
304
305
_EraseRect(const Rect * inRect)306 void PixPort::_EraseRect( const Rect* inRect ) {
307 long width, height;
308 int x, y;
309 char* base;
310 Rect r;
311
312 // Don't let us draw in random parts of memory -- clip inRect
313 if ( inRect ) {
314 r = *inRect;
315 __clipPt( r.left, r.top )
316 __clipPt( r.right, r.bottom ) }
317 else {
318 r = mClipRect;
319 }
320
321 width = r.right - r.left;
322 height = r.bottom - r.top;
323
324
325 // In Win32, everything's upside down
326 #if EG_WIN
327 r.top = mY - r.bottom;
328 #endif
329
330 base = mBits + mBytesPerPix * r.left + r.top * mBytesPerRow;
331 for ( y = 0; y <= height; y++ ) {
332 for ( x = 0; x <= width; x++ ) {
333 *((PIXTYPE*) base) = mBackColor;
334 base += P_SZ;
335 }
336 base += mBytesPerRow - P_SZ * (width + 1);
337 }
338 }
339
340
341
_CrossBlur(char * inSrce,int inWidth,int inHeight,int inBytesPerRow,unsigned char * inRowBuf)342 void PixPort::_CrossBlur( char* inSrce, int inWidth, int inHeight, int inBytesPerRow, unsigned char* inRowBuf ) {
343 long leftR, leftG, leftB, cenR, cenG, cenB, rightR, rightG, rightB;
344 long topR, topG, topB, val, botR, botG, botB, x;
345 unsigned char *rowPos;
346
347 // Init inRowBuf[]
348 rowPos = inRowBuf;
349 for ( x = 0; x < inWidth; x++ ) {
350 val = ((PIXTYPE*) inSrce)[ x ];
351 rowPos[ 0 ] = val >> REDSHIFT;
352 rowPos[ 1 ] = (val >> GRNSHIFT) & COLMASK;
353 rowPos[ 2 ] = val & COLMASK;
354 rowPos += 3;
355 }
356
357 // Go thru row by row in the source img
358 for ( ; inHeight > 0; inHeight-- ) {
359
360 // Prime the x-loop and get left and cen pixels
361 val = *((PIXTYPE*) inSrce );
362 leftR = cenR = val >> REDSHIFT;
363 leftG = cenG = (val >> GRNSHIFT) & COLMASK;
364 leftB = cenB = val & COLMASK;
365
366 rowPos = inRowBuf;
367
368 for ( x = 0; x < inWidth; x++ ) {
369
370 // Get top pixel
371 topR = rowPos[ 0 ];
372 topG = rowPos[ 1 ];
373 topB = rowPos[ 2 ];
374
375 // Get right-most pixel
376 val = ((PIXTYPE*) inSrce)[ x + 1 ];
377 rightR = val >> REDSHIFT;
378 rightG = (val >> GRNSHIFT) & COLMASK;
379 rightB = val & COLMASK;
380
381 // Get bottom pixel
382 val = ((PIXTYPE*) (inSrce + inBytesPerRow))[ x ];
383 botR = val >> REDSHIFT;
384 botG = (val >> GRNSHIFT) & COLMASK;
385 botB = val & COLMASK;
386
387 *rowPos = cenR; rowPos++;
388 *rowPos = cenG; rowPos++;
389 *rowPos = cenB; rowPos++;
390
391 botR = ( ( cenR << 2 ) + 3 * ( leftR + rightR + topR + botR ) ) >> 4;
392 botG = ( ( cenG << 2 ) + 3 * ( leftG + rightG + topG + botG ) ) >> 4;
393 botB = ( ( cenB << 2 ) + 3 * ( leftB + rightB + topB + botB ) ) >> 4;
394 ((PIXTYPE*) inSrce )[ x ] = ( botR << REDSHIFT ) | ( botG << GRNSHIFT ) | botB;
395
396 // Re-use already-fetched memory
397 leftR = cenR; cenR = rightR;
398 leftG = cenG; cenG = rightG;
399 leftB = cenB; cenB = rightB;
400 }
401
402 inSrce += inBytesPerRow;
403 }
404 }
405
406
407
408
409
410
411
412 #define UL unsigned long
413 #define DENOM_SHIFT 14
414
415
_BoxBlur(char * inSrce,char * inDest,int inBoxWidth,int inWidth,int inHeight,int inSrceRowWidth,int inDestRowWidth,unsigned long * b,unsigned long inBackColor)416 void PixPort::_BoxBlur( char* inSrce, char* inDest, int inBoxWidth, int inWidth, int inHeight, int inSrceRowWidth, int inDestRowWidth, unsigned long* b, unsigned long inBackColor ) {
417 register unsigned long* bEnd;
418 register char *dest;
419 register unsigned long b1R, b1G, b1B, b2R, b2G, b2B, b3R, b3G, b3B, val, box9W, i, numerator;
420 register int x, half, useWidth;
421
422 i = inBoxWidth * inBoxWidth * inBoxWidth;
423 numerator = ( 1 << DENOM_SHIFT ) / ( i );
424 box9W = 9 * inBoxWidth; // 3 colors, 3 boxes
425 bEnd = b + box9W;
426
427 b1R = 0; b1G = 0; b1B = 0;
428 b2R = 0; b2G = 0; b2B = 0;
429 b3R = i >> 1; b3G = b3R; b3B = b3R; // round up when > .5
430 for ( i = 0; i < box9W; i++ ) {
431 b[ i ] = 0;
432 }
433
434 half = 3 * inBoxWidth / 2 - 1;
435 inSrce += P_SZ * half;
436 useWidth = inWidth - half - inBoxWidth % 2;
437
438 // Go thru row by row in the source img
439 for ( ; inHeight > 0; inHeight-- ) {
440
441 // Go thru the row
442 dest = inDest;
443
444 for ( x = - half - 5; x < inWidth; x++ ) {
445
446 // Maintain the circular buffer
447 if ( b == bEnd )
448 b -= box9W;
449
450 // p = fetch next pix from b1
451 if ( x >= 0 && x < useWidth ) {
452 val = *( (PIXTYPE*) inSrce );
453 inSrce += P_SZ; }
454 else
455 val = inBackColor;
456
457 // p' += new pix - end pix and store new pix
458 i = val >> REDSHIFT; b1R += i - b[0]; b[0] = i;
459 i = (val >> GRNSHIFT) & COLMASK; b1G += i - b[1]; b[1] = i;
460 i = val & COLMASK; b1B += i - b[2]; b[2] = i;
461
462 // Store the b2's new pix and calc its new pixel
463 b2R += b1R - b[3]; b[3] = b1R;
464 b2G += b1G - b[4]; b[4] = b1G;
465 b2B += b1B - b[5]; b[5] = b1B;
466
467 // Store the b3's new pix and calc its new pixel
468 b3R += b2R - b[6]; b[6] = b2R;
469 b3G += b2G - b[7]; b[7] = b2G;
470 b3B += b2B - b[8]; b[8] = b2B;
471
472 // Transpose the final pixel calculations
473 if ( x >= 0 ) {
474 *((PIXTYPE*)dest) = ( (( numerator * b3R ) >> DENOM_SHIFT) << REDSHIFT ) | ( (( numerator * b3G ) >> DENOM_SHIFT) << GRNSHIFT ) | (( numerator * b3B ) >> DENOM_SHIFT);
475 dest += inDestRowWidth;
476 }
477
478 // Maintain our circular buffer
479 b += 9;
480
481 }
482
483 // Do next row
484 inSrce += inSrceRowWidth - P_SZ * useWidth;
485 inDest += P_SZ;
486 }
487 }
488
489
490
491 /*
492 this modification to BoxBlur only blurs the x row
493 void PixPort::_BoxBlur( char* inSrce, char*, int inBoxWidth, int inWidth, int inHeight, int inSrceRowWidth, int, char* b, unsigned long inBackColor ) {
494
495 register char *bEnd;
496 register unsigned long b1R, b1G, b1B, b2R, b2G, b2B, b3R, b3G, b3B, val, box9W, i, denom;
497 register int x, half, useWidth;
498
499
500 denom = inBoxWidth * inBoxWidth * inBoxWidth;
501 box9W = 36 * inBoxWidth; // 3 colors, 3 boxes, 4 bytes per long
502 bEnd = b + box9W;
503
504 b1R = 0; b1G = 0; b1B = 0;
505 b2R = 0; b2G = 0; b2B = 0;
506 b3R = 0; b3G = 0; b3B = 0;
507 for ( i = 0; i < 9 * inBoxWidth; ) {
508 *((UL*) b + i) = 0; i++;
509 }
510
511 half = 3 * inBoxWidth / 2 - 1;
512 inSrce += P_SZ * half;
513 useWidth = inWidth - half - inBoxWidth % 2;
514
515 // Go thru row by row in the source img
516 for ( ; inHeight > 0; inHeight-- ) {
517
518 for ( x = - half - 5; x < inWidth; x++ ) {
519
520 // Maintain our circular buffer
521 if ( b == bEnd )
522 b -= box9W;
523
524 // p = fetch next pix from b1
525 if ( x >= 0 && x < useWidth ) {
526 val = *( (PIXTYPE*) inSrce );}
527 else
528 val = inBackColor;
529
530 // p' += new pix - end pix and store new pix
531 i = val >> REDSHIFT; b1R += i - *((UL*)b); *((UL*)b) = i; b += 4;
532 i = (val >> GRNSHIFT) & COLMASK; b1G += i - *((UL*)b); *((UL*)b) = i; b += 4;
533 i = val & COLMASK; b1B += i - *((UL*)b); *((UL*)b) = i; b += 4;
534
535 // Store the b2's new pix and calc its new pixel
536 b2R += b1R - *((UL*)b); *((UL*)b) = b1R; b += 4;
537 b2G += b1G - *((UL*)b); *((UL*)b) = b1G; b += 4;
538 b2B += b1B - *((UL*)b); *((UL*)b) = b1B; b += 4;
539
540 // Store the b3's new pix and calc its new pixel
541 b3R += b2R - *((UL*)b); *((UL*)b) = b2R; b += 4;
542 b3G += b2G - *((UL*)b); *((UL*)b) = b2G; b += 4;
543 b3B += b2B - *((UL*)b); *((UL*)b) = b2B; b += 4;
544
545 // Transpose the final pixel calculations
546 if ( x >= 0 ) {
547 *((PIXTYPE*)inSrce) = ( (b3R/denom) << REDSHIFT ) | ( ( b3G/denom ) << GRNSHIFT ) | ( b3B/denom );
548 inSrce += P_SZ;
549 }
550 }
551
552 // Do next row
553 inSrce += inSrceRowWidth - P_SZ * inWidth;
554 }
555 }
556 */
557
558
559
560 #undef PIXTYPE
561 #undef REDSHIFT
562 #undef GRNSHIFT
563 #undef COLMASK
564 #undef _Line
565 #undef _LineW
566 #undef _BoxBlur
567 #undef _CrossBlur
568 #undef _EraseRect
569 #undef __Clr
570