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