1 #   include	"bitmapConfig.h"
2 
3 #   include	"bmintern.h"
4 #   include	"bmgetrow.h"
5 #   include	<appDebugon.h>
6 
7 /************************************************************************/
8 /*									*/
9 /*  Collect rows of data for image transformations.			*/
10 /*									*/
11 /************************************************************************/
12 
bmGetBytePixels(unsigned char * to,unsigned char from,int bitsPerPixel)13 static void bmGetBytePixels(	unsigned char *	to,
14 				unsigned char	from,
15 				int		bitsPerPixel )
16     {
17     unsigned	mask;
18     int		shift;
19 
20     mask= ( 1 << bitsPerPixel )- 1;
21 
22     for ( shift= 8- bitsPerPixel; shift >= 0; to++, shift -= bitsPerPixel )
23 	{ *to= ( from >> shift ) & mask;	}
24 
25     return;
26     }
27 
28 /************************************************************************/
29 /*									*/
30 /*  Fill a Depth 8 image from rgb8 palette data.			*/
31 /*									*/
32 /************************************************************************/
33 
bmGetPaletteSourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)34 static void bmGetPaletteSourceRow(	ColorValue *			cv,
35 					int				col0Out,
36 					const unsigned char *		from,
37 					int				col0In,
38 					int				colPIn,
39 					const BitmapDescription *	bdIn )
40     {
41     int				col;
42     unsigned			mask;
43 
44     int				pos;
45     int				past;
46     int				pixelsPerByte;
47     unsigned char		scratch[8];
48 
49     const ColorPalette *	cp= &(bdIn->bdPalette);
50 
51     cv += col0Out;
52 
53     switch( bdIn->bdBitsPerPixel )
54 	{
55 	case 8:
56 	    from += col0In;
57 
58 	    for ( col= col0In; col < colPIn; from++, cv++, col++ )
59 		{
60 		cv->cvR += cp->cpColors[*from].rgb8Red;
61 		cv->cvG += cp->cpColors[*from].rgb8Green;
62 		cv->cvB += cp->cpColors[*from].rgb8Blue;
63 		cv->cvN++;
64 		}
65 	    return;
66 
67 	case 4: case 2: case 1:
68 	    mask= ( 1 << bdIn->bdBitsPerPixel )- 1;
69 
70 	    pixelsPerByte= 8/ bdIn->bdBitsPerPixel;
71 
72 	    from += col0In/ pixelsPerByte;
73 
74 	    if  ( col0In % pixelsPerByte )
75 		{
76 		past= col0In+ pixelsPerByte- 1;
77 		past /= pixelsPerByte;
78 		past *= pixelsPerByte;
79 
80 		bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
81 
82 		if  ( past > colPIn )
83 		    { past=  colPIn;	}
84 
85 		pos= past- col0In;
86 		for ( col= col0In; col < past; pos++, cv++, col++ )
87 		    {
88 		    cv->cvR += cp->cpColors[scratch[pos]].rgb8Red;
89 		    cv->cvG += cp->cpColors[scratch[pos]].rgb8Green;
90 		    cv->cvB += cp->cpColors[scratch[pos]].rgb8Blue;
91 		    cv->cvN++;
92 		    }
93 
94 		col0In= past; from++;
95 		}
96 
97 	    for ( col= col0In; col+ pixelsPerByte- 1 < colPIn; from++,
98 							col += pixelsPerByte )
99 		{
100 		int	shift= 8- bdIn->bdBitsPerPixel;
101 		int	pix;
102 
103 		for ( pix= 0; pix < pixelsPerByte;
104 				    cv++, shift -= bdIn->bdBitsPerPixel, pix++ )
105 		    {
106 		    int		val= ( *from >> shift ) & mask;
107 
108 		    cv->cvR += cp->cpColors[val].rgb8Red;
109 		    cv->cvG += cp->cpColors[val].rgb8Green;
110 		    cv->cvB += cp->cpColors[val].rgb8Blue;
111 		    cv->cvN++;
112 		    }
113 		}
114 
115 	    if  ( col < colPIn )
116 		{
117 		bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
118 
119 		pos= 0;
120 		for ( ; col < colPIn; pos++, cv++, col++ )
121 		    {
122 		    cv->cvR += cp->cpColors[scratch[pos]].rgb8Red;
123 		    cv->cvG += cp->cpColors[scratch[pos]].rgb8Green;
124 		    cv->cvB += cp->cpColors[scratch[pos]].rgb8Blue;
125 		    cv->cvN++;
126 		    }
127 		}
128 
129 	    return;
130 
131 	case 16:
132 	    {
133 	    const BmUint16 *	psh= (const BmUint16 *)from;
134 
135 	    psh += col0In;
136 
137 	    for ( col= col0In; col < colPIn; psh++, cv++, col++ )
138 		{
139 		cv->cvR += cp->cpColors[*psh].rgb8Red;
140 		cv->cvG += cp->cpColors[*psh].rgb8Green;
141 		cv->cvB += cp->cpColors[*psh].rgb8Blue;
142 		cv->cvN++;
143 		}
144 
145 	    return;
146 	    }
147 
148 	case 32:
149 	    {
150 	    const BmUint32 *	plo= (const BmUint32 *)from;
151 
152 	    plo += col0In;
153 
154 	    for ( col= col0In; col < colPIn; plo++, cv++, col++ )
155 		{
156 		cv->cvR += cp->cpColors[*plo].rgb8Red;
157 		cv->cvG += cp->cpColors[*plo].rgb8Green;
158 		cv->cvB += cp->cpColors[*plo].rgb8Blue;
159 		cv->cvN++;
160 		}
161 
162 	    return;
163 	    }
164 
165 	default:
166 	    LDEB(bdIn->bdBitsPerPixel); return;
167 	}
168     }
169 
170 /************************************************************************/
171 /*									*/
172 /*  Fill a Depth 8 image from rgb8 palette data with an alpha channel.	*/
173 /*									*/
174 /************************************************************************/
175 
bmGetPaletteSourceRowAlpha(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)176 static void bmGetPaletteSourceRowAlpha(	ColorValue *			cv,
177 					int				col0Out,
178 					const unsigned char *		from,
179 					int				col0In,
180 					int				colPIn,
181 					const BitmapDescription *	bdIn )
182     {
183     int				col;
184     unsigned			mask;
185 
186     const ColorPalette *	cp= &(bdIn->bdPalette);
187 
188     cv += col0Out;
189 
190     switch( bdIn->bdBitsPerPixel )
191 	{
192 	case 32:
193 	    {
194 	    const BmUint16 *	psh= (const BmUint16 *)from;
195 
196 	    psh += 2* col0In;
197 
198 	    for ( col= col0In; col < colPIn; psh += 2, cv++, col++ )
199 		{
200 		cv->cvR += cp->cpColors[*psh].rgb8Red;
201 		cv->cvG += cp->cpColors[*psh].rgb8Green;
202 		cv->cvB += cp->cpColors[*psh].rgb8Blue;
203 		cv->cvN++;
204 		}
205 	    }
206 	return;
207 
208 	case 16:
209 	    from += 2* col0In;
210 
211 	    for ( col= col0In; col < colPIn; from += 2, cv++, col++ )
212 		{
213 		if  ( from[1] )
214 		    {
215 		    cv->cvR += cp->cpColors[*from].rgb8Red;
216 		    cv->cvG += cp->cpColors[*from].rgb8Green;
217 		    cv->cvB += cp->cpColors[*from].rgb8Blue;
218 		    }
219 		else{
220 		    /* why not white?*/
221 		    cv->cvR += 255;
222 		    cv->cvG += 255;
223 		    cv->cvB += 255;
224 		    }
225 		cv->cvN++;
226 		}
227 	    return;
228 
229 	case 8:
230 	    mask= 0x0f;
231 
232 	    from += col0In;
233 
234 	    for ( col= col0In; col < colPIn; from++, cv++, col++ )
235 		{
236 		if  ( *from & 0x0f )
237 		    {
238 		    int		val= ( *from >> 4 ) & mask;
239 
240 		    cv->cvR += cp->cpColors[val].rgb8Red;
241 		    cv->cvG += cp->cpColors[val].rgb8Green;
242 		    cv->cvB += cp->cpColors[val].rgb8Blue;
243 		    }
244 		else{
245 		    /* why not white?*/
246 		    cv->cvR += 255;
247 		    cv->cvG += 255;
248 		    cv->cvB += 255;
249 		    }
250 		cv->cvN++;
251 		}
252 	    return;
253 
254 	default:
255 	    LDEB(bdIn->bdBitsPerPixel); return;
256 	}
257     }
258 
bmGetBlackWhite124SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)259 static void bmGetBlackWhite124SourceRow(ColorValue *			cv,
260 					int				col0Out,
261 					const unsigned char *		from,
262 					int				col0In,
263 					int				colPIn,
264 					const BitmapDescription *	bdIn )
265     {
266     int			col;
267     unsigned		mask;
268 
269     int			pos;
270     int			past;
271     int			pixelsPerByte;
272     unsigned char	scratch[8];
273 
274     cv += col0Out;
275 
276     mask= ( 1 << bdIn->bdBitsPerPixel )- 1;
277 
278     pixelsPerByte= 8/ bdIn->bdBitsPerPixel;
279     from += col0In/ pixelsPerByte;
280 
281     if  ( col0In % pixelsPerByte )
282 	{
283 	past= col0In+ pixelsPerByte- 1;
284 	past /= pixelsPerByte;
285 	past *= pixelsPerByte;
286 
287 	bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
288 
289 	if  ( past > colPIn )
290 	    { past=  colPIn;	}
291 
292 	pos= past- col0In;
293 	for ( col= col0In; col < past; pos++, cv++, col++ )
294 	    {
295 	    unsigned int	val;
296 
297 	    val= ( 255* scratch[pos] )/ mask;
298 	    val= 255- val;
299 
300 	    cv->cvR += val;
301 	    cv->cvG += val;
302 	    cv->cvB += val;
303 	    cv->cvN++;
304 	    }
305 
306 	col0In= past; from++;
307 	}
308 
309     for ( col= col0In; col+ pixelsPerByte- 1 < colPIn; from++,
310 							col += pixelsPerByte )
311 	{
312 	int	shift= 8- bdIn->bdBitsPerPixel;
313 	int	pix;
314 
315 	for ( pix= 0; pix < pixelsPerByte;
316 				cv++, shift -= bdIn->bdBitsPerPixel, pix++ )
317 	    {
318 	    int		val= ( *from >> shift ) & mask;
319 
320 	    val= ( 255* val )/ mask;
321 	    val= 255- val;
322 
323 	    cv->cvR += val;
324 	    cv->cvG += val;
325 	    cv->cvB += val;
326 	    cv->cvN++;
327 	    }
328 	}
329 
330     if  ( col < colPIn )
331 	{
332 	bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
333 
334 	pos= 0;
335 	for ( ; col < colPIn; pos++, cv++, col++ )
336 	    {
337 	    unsigned int	val;
338 
339 	    val= ( 255* scratch[pos] )/ mask;
340 	    val= 255- val;
341 
342 	    cv->cvR += val;
343 	    cv->cvG += val;
344 	    cv->cvB += val;
345 	    cv->cvN++;
346 	    }
347 	}
348 
349     return;
350     }
351 
bmGetWhiteBlack124SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)352 static void bmGetWhiteBlack124SourceRow(ColorValue *			cv,
353 					int				col0Out,
354 					const unsigned char *		from,
355 					int				col0In,
356 					int				colPIn,
357 					const BitmapDescription *	bdIn )
358     {
359     int			col;
360     unsigned		mask;
361 
362     int			pos;
363     int			past;
364     int			pixelsPerByte;
365     unsigned char	scratch[8];
366 
367     cv += col0Out;
368 
369     mask= ( 1 << bdIn->bdBitsPerPixel )- 1;
370 
371     pixelsPerByte= 8/ bdIn->bdBitsPerPixel;
372     from += col0In/ pixelsPerByte;
373 
374     if  ( col0In % pixelsPerByte )
375 	{
376 	past= col0In+ pixelsPerByte- 1;
377 	past /= pixelsPerByte;
378 	past *= pixelsPerByte;
379 
380 	bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
381 
382 	if  ( past > colPIn )
383 	    { past=  colPIn;	}
384 
385 	pos= past- col0In;
386 	for ( col= col0In; col < past; pos++, cv++, col++ )
387 	    {
388 	    unsigned int	val;
389 
390 	    val= ( 255* scratch[pos] )/ mask;
391 
392 	    cv->cvR += val;
393 	    cv->cvG += val;
394 	    cv->cvB += val;
395 	    cv->cvN++;
396 	    }
397 
398 	col0In= past; from++;
399 	}
400 
401     for ( col= col0In; col+ pixelsPerByte- 1 < colPIn; from++,
402 							col += pixelsPerByte )
403 	{
404 	int	shift= 8- bdIn->bdBitsPerPixel;
405 	int	pix;
406 
407 	for ( pix= 0; pix < pixelsPerByte;
408 				cv++, shift -= bdIn->bdBitsPerPixel, pix++ )
409 	    {
410 	    int		val= ( *from >> shift ) & mask;
411 
412 	    val= ( 255* val )/ mask;
413 
414 	    cv->cvR += val;
415 	    cv->cvG += val;
416 	    cv->cvB += val;
417 	    cv->cvN++;
418 	    }
419 	}
420 
421     if  ( col < colPIn )
422 	{
423 	bmGetBytePixels( scratch, *from, bdIn->bdBitsPerPixel );
424 
425 	pos= 0;
426 	for ( ; col < colPIn; pos++, cv++, col++ )
427 	    {
428 	    unsigned int	val;
429 
430 	    val= ( 255* scratch[pos] )/ mask;
431 
432 	    cv->cvR += val;
433 	    cv->cvG += val;
434 	    cv->cvB += val;
435 	    cv->cvN++;
436 	    }
437 	}
438 
439     return;
440     }
441 
bmGetBlackWhite8SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)442 static void bmGetBlackWhite8SourceRow(	ColorValue *			cv,
443 					int				col0Out,
444 					const unsigned char *		from,
445 					int				col0In,
446 					int				colPIn,
447 					const BitmapDescription *	bdIn )
448     {
449     int			col;
450 
451     cv += col0Out;
452     from += col0In;
453 
454     for ( col= col0In; col < colPIn; cv++, from++, col++ )
455 	{
456 	int		val= 255- *from;
457 
458 	cv->cvR += val;
459 	cv->cvG += val;
460 	cv->cvB += val;
461 	cv->cvN++;
462 	}
463     }
464 
bmGetWhiteBlack8SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)465 static void bmGetWhiteBlack8SourceRow(	ColorValue *			cv,
466 					int				col0Out,
467 					const unsigned char *		from,
468 					int				col0In,
469 					int				colPIn,
470 					const BitmapDescription *	bdIn )
471     {
472     int			col;
473 
474     cv += col0Out;
475     from += col0In;
476 
477     for ( col= col0In; col < colPIn; cv++, from++, col++ )
478 	{
479 	cv->cvR += *from;
480 	cv->cvG += *from;
481 	cv->cvB += *from;
482 	cv->cvN++;
483 	}
484     }
485 
bmGetWhiteBlack16ASourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)486 static void bmGetWhiteBlack16ASourceRow(ColorValue *			cv,
487 					int				col0Out,
488 					const unsigned char *		from,
489 					int				col0In,
490 					int				colPIn,
491 					const BitmapDescription *	bdIn )
492     {
493     int			col;
494 
495     cv += col0Out;
496     from += col0In;
497 
498     for ( col= col0In; col < colPIn; cv++, from += 2, col++ )
499 	{
500 	cv->cvR += *from;
501 	cv->cvG += *from;
502 	cv->cvB += *from;
503 	cv->cvN++;
504 	}
505     }
506 
507 /************************************************************************/
508 /*									*/
509 /*  Add data from one row of a 24 bits image to an acumulator array.	*/
510 /*									*/
511 /************************************************************************/
512 
bmGetRGB24SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)513 static void bmGetRGB24SourceRow(	ColorValue *			cv,
514 					int				col0Out,
515 					const unsigned char *		from,
516 					int				col0In,
517 					int				colPIn,
518 					const BitmapDescription *	bdIn )
519     {
520     int		col;
521 
522     cv += col0Out;
523     from += 3* col0In;
524 
525     for ( col= col0In; col < colPIn; cv++, col++ )
526 	{
527 	cv->cvR += *(from++);
528 	cv->cvG += *(from++);
529 	cv->cvB += *(from++);
530 	cv->cvN++;
531 	}
532 
533     return;
534     }
535 
bmGetRGBA32SourceRow(ColorValue * cv,int col0Out,const unsigned char * from,int col0In,int colPIn,const BitmapDescription * bdIn)536 static void bmGetRGBA32SourceRow(	ColorValue *			cv,
537 					int				col0Out,
538 					const unsigned char *		from,
539 					int				col0In,
540 					int				colPIn,
541 					const BitmapDescription *	bdIn )
542     {
543     int		col;
544 
545     cv += col0Out;
546     from += 3* col0In;
547 
548     for ( col= col0In; col < colPIn; cv++, col++ )
549 	{
550 	if  ( from[3] )
551 	    {
552 	    cv->cvR += *(from++);
553 	    cv->cvG += *(from++);
554 	    cv->cvB += *(from++);
555 	    from++;
556 	    }
557 	else{
558 	    /*why not white*/
559 	    cv->cvR += 255;
560 	    cv->cvG += 255;
561 	    cv->cvB += 255;
562 	    from += 4;
563 	    }
564 	cv->cvN++;
565 	}
566 
567     return;
568     }
569 
570 /************************************************************************/
571 /*									*/
572 /*  Add data from one row of a 48 bits image to an acumulator array.	*/
573 /*									*/
574 /************************************************************************/
575 
bmGetRGB48SourceRow(ColorValue * cv,int col0Out,const unsigned char * ucFrom,int col0In,int colPIn,const BitmapDescription * bdIn)576 static void bmGetRGB48SourceRow(	ColorValue *			cv,
577 					int				col0Out,
578 					const unsigned char *		ucFrom,
579 					int				col0In,
580 					int				colPIn,
581 					const BitmapDescription *	bdIn )
582     {
583     int			col;
584     const BmUint16 *	from= (const BmUint16 *)ucFrom;
585 
586     cv += col0Out;
587     from += 3* col0In;
588 
589     for ( col= col0In; col < colPIn; cv++, col++ )
590 	{
591 	cv->cvR += *(from++)/ 256;
592 	cv->cvG += *(from++)/ 256;
593 	cv->cvB += *(from++)/ 256;
594 	cv->cvN++;
595 	}
596 
597     return;
598     }
599 
bmGetRGBA64SourceRow(ColorValue * cv,int col0Out,const unsigned char * ucFrom,int col0In,int colPIn,const BitmapDescription * bdIn)600 static void bmGetRGBA64SourceRow(	ColorValue *			cv,
601 					int				col0Out,
602 					const unsigned char *		ucFrom,
603 					int				col0In,
604 					int				colPIn,
605 					const BitmapDescription *	bdIn )
606     {
607     int			col;
608     const BmUint16 *	from= (const BmUint16 *)ucFrom;
609 
610     cv += col0Out;
611     from += 3* col0In;
612 
613     for ( col= col0In; col < colPIn; cv++, col++ )
614 	{
615 	cv->cvR += *(from++)/ 256;
616 	cv->cvG += *(from++)/ 256;
617 	cv->cvB += *(from++)/ 256;
618 	from++;
619 	cv->cvN++;
620 	}
621 
622     return;
623     }
624 
625 /************************************************************************/
626 /*									*/
627 /*  Initialize a row of color values.					*/
628 /*									*/
629 /************************************************************************/
630 
bmInitColorRow(ColorValue * cv,int wide)631 void bmInitColorRow(	ColorValue *		cv,
632 			int			wide )
633     {
634     int			col;
635 
636     for ( col= 0; col < wide; cv++, col++ )
637 	{
638 	cv->cvR= 0L;
639 	cv->cvG= 0L;
640 	cv->cvB= 0L;
641 	cv->cvN= 0;
642 	}
643     }
644 
645 /************************************************************************/
646 /*									*/
647 /*  Determine how to retrieve pixels from an input image.		*/
648 /*									*/
649 /************************************************************************/
650 
bmGetGetRow(GetSourceRow * pGetRow,const BitmapDescription * bdIn)651 int bmGetGetRow(	GetSourceRow *			pGetRow,
652 			const BitmapDescription *	bdIn )
653     {
654     GetSourceRow	getRow= (GetSourceRow)0;
655 
656     /*  4  */
657     switch( bdIn->bdColorEncoding )
658 	{
659 	case BMcoRGB8PALETTE:
660 	    if  ( bdIn->bdHasAlpha )
661 		{
662 		getRow= bmGetPaletteSourceRowAlpha;
663 		break;
664 		}
665 	    else{
666 		getRow= bmGetPaletteSourceRow;
667 		break;
668 		}
669 	    break;
670 
671 	case BMcoBLACKWHITE:
672 	    switch( bdIn->bdBitsPerPixel )
673 		{
674 		case 1:
675 		case 2:
676 		case 4:
677 		    getRow= bmGetBlackWhite124SourceRow;
678 		    break;
679 
680 		case 8:
681 		    getRow= bmGetBlackWhite8SourceRow;
682 		    break;
683 
684 		default:
685 		    LLDEB(bdIn->bdColorEncoding,bdIn->bdBitsPerPixel);
686 		    return -1;
687 		}
688 	    break;
689 
690 	case BMcoWHITEBLACK:
691 	    switch( bdIn->bdBitsPerPixel )
692 		{
693 		case 1:
694 		case 2:
695 		case 4:
696 		    getRow= bmGetWhiteBlack124SourceRow;
697 		    break;
698 
699 		case 8:
700 		    getRow= bmGetWhiteBlack8SourceRow;
701 		    break;
702 
703 		case 16:
704 		    if  ( bdIn->bdHasAlpha )
705 			{ getRow= bmGetWhiteBlack16ASourceRow;	}
706 		    else{
707 			LLDEB(bdIn->bdBitsPerPixel,bdIn->bdHasAlpha);
708 			return -1;
709 			}
710 		    break;
711 
712 		default:
713 		    LLDEB(bdIn->bdColorEncoding,bdIn->bdBitsPerPixel);
714 		    return -1;
715 		}
716 	    break;
717 
718 	case BMcoRGB:
719 	    switch( bdIn->bdBitsPerSample )
720 		{
721 		case 8:
722 		    if  ( bdIn->bdHasAlpha )
723 			{ getRow= bmGetRGBA32SourceRow;	}
724 		    else{ getRow= bmGetRGB24SourceRow;	}
725 		    break;
726 
727 		case 16:
728 		    if  ( bdIn->bdHasAlpha )
729 			{ getRow= bmGetRGBA64SourceRow;	}
730 		    else{ getRow= bmGetRGB48SourceRow;	}
731 		    break;
732 
733 		default:
734 		    LLDEB(bdIn->bdColorEncoding,bdIn->bdBitsPerSample);
735 		    return -1;
736 		}
737 	    break;
738 	default:
739 	    LDEB(bdIn->bdColorEncoding); return -1;
740 	}
741 
742     *pGetRow= getRow;
743     return 0;
744     }
745