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