/[rdesktop]/sourceforge.net/trunk/rdesktop/bitmap.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/bitmap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 681 - (show annotations)
Tue Apr 27 09:04:42 2004 UTC (20 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 19906 byte(s)
Only do the memcpy if NEED_ALIGNMENT is defined
TODO: configure-test which defines it

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Bitmap decompression routines
4 Copyright (C) Matthew Chapman 1999-2002
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /* three seperate function for speed when decompressing the bitmaps */
22 /* when modifing one function make the change in the others */
23 /* comment out #define BITMAP_SPEED_OVER_SIZE below for one slower function */
24 /* j@american-data.com */
25
26 #define BITMAP_SPEED_OVER_SIZE
27
28 /* indent is confused by this file */
29 /* *INDENT-OFF* */
30
31 #include "rdesktop.h"
32
33 #define CVAL(p) (*(p++))
34 #define CVAL2(p) (*(((uint16*)p)++)) /* for 16 bit */
35
36 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
37
38 #define REPEAT(statement) \
39 { \
40 while((count & ~0x7) && ((x+8) < width)) \
41 UNROLL8( statement; count--; x++; ); \
42 \
43 while((count > 0) && (x < width)) \
44 { \
45 statement; \
46 count--; \
47 x++; \
48 } \
49 }
50
51 #define MASK_UPDATE() \
52 { \
53 mixmask <<= 1; \
54 if (mixmask == 0) \
55 { \
56 mask = fom_mask ? fom_mask : CVAL(input); \
57 mixmask = 1; \
58 } \
59 }
60
61 #ifdef BITMAP_SPEED_OVER_SIZE
62
63 /* 1 byte bitmap decompress */
64 static BOOL
65 bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size)
66 {
67 uint8 *end = input + size;
68 uint8 *prevline = NULL, *line = NULL;
69 int opcode, count, offset, isfillormix, x = width;
70 int lastopcode = -1, insertmix = False, bicolour = False;
71 uint8 code;
72 uint8 colour1 = 0, colour2 = 0;
73 uint8 mixmask, mask = 0;
74 uint8 mix = 0xff;
75 int fom_mask = 0;
76
77 while (input < end)
78 {
79 fom_mask = 0;
80 code = CVAL(input);
81 opcode = code >> 4;
82 /* Handle different opcode forms */
83 switch (opcode)
84 {
85 case 0xc:
86 case 0xd:
87 case 0xe:
88 opcode -= 6;
89 count = code & 0xf;
90 offset = 16;
91 break;
92 case 0xf:
93 opcode = code & 0xf;
94 if (opcode < 9)
95 {
96 count = CVAL(input);
97 count |= CVAL(input) << 8;
98 }
99 else
100 {
101 count = (opcode < 0xb) ? 8 : 1;
102 }
103 offset = 0;
104 break;
105 default:
106 opcode >>= 1;
107 count = code & 0x1f;
108 offset = 32;
109 break;
110 }
111 /* Handle strange cases for counts */
112 if (offset != 0)
113 {
114 isfillormix = ((opcode == 2) || (opcode == 7));
115 if (count == 0)
116 {
117 if (isfillormix)
118 count = CVAL(input) + 1;
119 else
120 count = CVAL(input) + offset;
121 }
122 else if (isfillormix)
123 {
124 count <<= 3;
125 }
126 }
127 /* Read preliminary data */
128 switch (opcode)
129 {
130 case 0: /* Fill */
131 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
132 insertmix = True;
133 break;
134 case 8: /* Bicolour */
135 colour1 = CVAL(input);
136 case 3: /* Colour */
137 colour2 = CVAL(input);
138 break;
139 case 6: /* SetMix/Mix */
140 case 7: /* SetMix/FillOrMix */
141 mix = CVAL(input);
142 opcode -= 5;
143 break;
144 case 9: /* FillOrMix_1 */
145 mask = 0x03;
146 opcode = 0x02;
147 fom_mask = 3;
148 break;
149 case 0x0a: /* FillOrMix_2 */
150 mask = 0x05;
151 opcode = 0x02;
152 fom_mask = 5;
153 break;
154 }
155 lastopcode = opcode;
156 mixmask = 0;
157 /* Output body */
158 while (count > 0)
159 {
160 if (x >= width)
161 {
162 if (height <= 0)
163 return False;
164 x = 0;
165 height--;
166 prevline = line;
167 line = output + height * width;
168 }
169 switch (opcode)
170 {
171 case 0: /* Fill */
172 if (insertmix)
173 {
174 if (prevline == NULL)
175 line[x] = mix;
176 else
177 line[x] = prevline[x] ^ mix;
178 insertmix = False;
179 count--;
180 x++;
181 }
182 if (prevline == NULL)
183 {
184 REPEAT(line[x] = 0)
185 }
186 else
187 {
188 REPEAT(line[x] = prevline[x])
189 }
190 break;
191 case 1: /* Mix */
192 if (prevline == NULL)
193 {
194 REPEAT(line[x] = mix)
195 }
196 else
197 {
198 REPEAT(line[x] = prevline[x] ^ mix)
199 }
200 break;
201 case 2: /* Fill or Mix */
202 if (prevline == NULL)
203 {
204 REPEAT
205 (
206 MASK_UPDATE();
207 if (mask & mixmask)
208 line[x] = mix;
209 else
210 line[x] = 0;
211 )
212 }
213 else
214 {
215 REPEAT
216 (
217 MASK_UPDATE();
218 if (mask & mixmask)
219 line[x] = prevline[x] ^ mix;
220 else
221 line[x] = prevline[x];
222 )
223 }
224 break;
225 case 3: /* Colour */
226 REPEAT(line[x] = colour2)
227 break;
228 case 4: /* Copy */
229 REPEAT(line[x] = CVAL(input))
230 break;
231 case 8: /* Bicolour */
232 REPEAT
233 (
234 if (bicolour)
235 {
236 line[x] = colour2;
237 bicolour = False;
238 }
239 else
240 {
241 line[x] = colour1;
242 bicolour = True; count++;
243 }
244 )
245 break;
246 case 0xd: /* White */
247 REPEAT(line[x] = 0xff)
248 break;
249 case 0xe: /* Black */
250 REPEAT(line[x] = 0)
251 break;
252 default:
253 unimpl("bitmap opcode 0x%x\n", opcode);
254 return False;
255 }
256 }
257 }
258 return True;
259 }
260
261 /* 2 byte bitmap decompress */
262 static BOOL
263 bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size)
264 {
265 uint8 *end = input + size;
266 uint16 *prevline = NULL, *line = NULL;
267 int opcode, count, offset, isfillormix, x = width;
268 int lastopcode = -1, insertmix = False, bicolour = False;
269 uint8 code;
270 uint16 colour1 = 0, colour2 = 0;
271 uint8 mixmask, mask = 0;
272 uint16 mix = 0xffff;
273 int fom_mask = 0;
274
275 while (input < end)
276 {
277 fom_mask = 0;
278 code = CVAL(input);
279 opcode = code >> 4;
280 /* Handle different opcode forms */
281 switch (opcode)
282 {
283 case 0xc:
284 case 0xd:
285 case 0xe:
286 opcode -= 6;
287 count = code & 0xf;
288 offset = 16;
289 break;
290 case 0xf:
291 opcode = code & 0xf;
292 if (opcode < 9)
293 {
294 count = CVAL(input);
295 count |= CVAL(input) << 8;
296 }
297 else
298 {
299 count = (opcode < 0xb) ? 8 : 1;
300 }
301 offset = 0;
302 break;
303 default:
304 opcode >>= 1;
305 count = code & 0x1f;
306 offset = 32;
307 break;
308 }
309 /* Handle strange cases for counts */
310 if (offset != 0)
311 {
312 isfillormix = ((opcode == 2) || (opcode == 7));
313 if (count == 0)
314 {
315 if (isfillormix)
316 count = CVAL(input) + 1;
317 else
318 count = CVAL(input) + offset;
319 }
320 else if (isfillormix)
321 {
322 count <<= 3;
323 }
324 }
325 /* Read preliminary data */
326 switch (opcode)
327 {
328 case 0: /* Fill */
329 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
330 insertmix = True;
331 break;
332 case 8: /* Bicolour */
333 #ifdef NEED_ALIGNMENT
334 memcpy(&colour1,&CVAL2(input),2);
335 #else
336 colour1 = CVAL2(input);
337 #endif
338 case 3: /* Colour */
339 #ifdef NEED_ALIGNMENT
340 memcpy(&colour2,&CVAL2(input),2);
341 #else
342 colour2 = CVAL2(input);
343 #endif
344 break;
345 case 6: /* SetMix/Mix */
346 case 7: /* SetMix/FillOrMix */
347 #ifdef NEED_ALIGNMENT
348 memcpy(&mix,&CVAL2(input),2);
349 #else
350 mix = CVAL2(input);
351 #endif
352 opcode -= 5;
353 break;
354 case 9: /* FillOrMix_1 */
355 mask = 0x03;
356 opcode = 0x02;
357 fom_mask = 3;
358 break;
359 case 0x0a: /* FillOrMix_2 */
360 mask = 0x05;
361 opcode = 0x02;
362 fom_mask = 5;
363 break;
364 }
365 lastopcode = opcode;
366 mixmask = 0;
367 /* Output body */
368 while (count > 0)
369 {
370 if (x >= width)
371 {
372 if (height <= 0)
373 return False;
374 x = 0;
375 height--;
376 prevline = line;
377 line = ((uint16 *) output) + height * width;
378 }
379 switch (opcode)
380 {
381 case 0: /* Fill */
382 if (insertmix)
383 {
384 if (prevline == NULL)
385 line[x] = mix;
386 else
387 line[x] = prevline[x] ^ mix;
388 insertmix = False;
389 count--;
390 x++;
391 }
392 if (prevline == NULL)
393 {
394 REPEAT(line[x] = 0)
395 }
396 else
397 {
398 REPEAT(line[x] = prevline[x])
399 }
400 break;
401 case 1: /* Mix */
402 if (prevline == NULL)
403 {
404 REPEAT(line[x] = mix)
405 }
406 else
407 {
408 REPEAT(line[x] = prevline[x] ^ mix)
409 }
410 break;
411 case 2: /* Fill or Mix */
412 if (prevline == NULL)
413 {
414 REPEAT
415 (
416 MASK_UPDATE();
417 if (mask & mixmask)
418 line[x] = mix;
419 else
420 line[x] = 0;
421 )
422 }
423 else
424 {
425 REPEAT
426 (
427 MASK_UPDATE();
428 if (mask & mixmask)
429 line[x] = prevline[x] ^ mix;
430 else
431 line[x] = prevline[x];
432 )
433 }
434 break;
435 case 3: /* Colour */
436 REPEAT(line[x] = colour2)
437 break;
438 case 4: /* Copy */
439 #ifdef NEED_ALIGNMENT
440 REPEAT(memcpy(&line[x],&CVAL2(input),2))
441 #else
442 REPEAT(line[x] = CVAL2(input))
443 #endif
444 break;
445 case 8: /* Bicolour */
446 REPEAT
447 (
448 if (bicolour)
449 {
450 line[x] = colour2;
451 bicolour = False;
452 }
453 else
454 {
455 line[x] = colour1;
456 bicolour = True;
457 count++;
458 }
459 )
460 break;
461 case 0xd: /* White */
462 REPEAT(line[x] = 0xffff)
463 break;
464 case 0xe: /* Black */
465 REPEAT(line[x] = 0)
466 break;
467 default:
468 unimpl("bitmap opcode 0x%x\n", opcode);
469 return False;
470 }
471 }
472 }
473 return True;
474 }
475
476 /* 3 byte bitmap decompress */
477 static BOOL
478 bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
479 {
480 uint8 *end = input + size;
481 uint8 *prevline = NULL, *line = NULL;
482 int opcode, count, offset, isfillormix, x = width;
483 int lastopcode = -1, insertmix = False, bicolour = False;
484 uint8 code;
485 uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0};
486 uint8 mixmask, mask = 0;
487 uint8 mix[3] = {0xff, 0xff, 0xff};
488 int fom_mask = 0;
489
490 while (input < end)
491 {
492 fom_mask = 0;
493 code = CVAL(input);
494 opcode = code >> 4;
495 /* Handle different opcode forms */
496 switch (opcode)
497 {
498 case 0xc:
499 case 0xd:
500 case 0xe:
501 opcode -= 6;
502 count = code & 0xf;
503 offset = 16;
504 break;
505 case 0xf:
506 opcode = code & 0xf;
507 if (opcode < 9)
508 {
509 count = CVAL(input);
510 count |= CVAL(input) << 8;
511 }
512 else
513 {
514 count = (opcode <
515 0xb) ? 8 : 1;
516 }
517 offset = 0;
518 break;
519 default:
520 opcode >>= 1;
521 count = code & 0x1f;
522 offset = 32;
523 break;
524 }
525 /* Handle strange cases for counts */
526 if (offset != 0)
527 {
528 isfillormix = ((opcode == 2) || (opcode == 7));
529 if (count == 0)
530 {
531 if (isfillormix)
532 count = CVAL(input) + 1;
533 else
534 count = CVAL(input) + offset;
535 }
536 else if (isfillormix)
537 {
538 count <<= 3;
539 }
540 }
541 /* Read preliminary data */
542 switch (opcode)
543 {
544 case 0: /* Fill */
545 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
546 insertmix = True;
547 break;
548 case 8: /* Bicolour */
549 colour1[0] = CVAL(input);
550 colour1[1] = CVAL(input);
551 colour1[2] = CVAL(input);
552 case 3: /* Colour */
553 colour2[0] = CVAL(input);
554 colour2[1] = CVAL(input);
555 colour2[2] = CVAL(input);
556 break;
557 case 6: /* SetMix/Mix */
558 case 7: /* SetMix/FillOrMix */
559 mix[0] = CVAL(input);
560 mix[1] = CVAL(input);
561 mix[2] = CVAL(input);
562 opcode -= 5;
563 break;
564 case 9: /* FillOrMix_1 */
565 mask = 0x03;
566 opcode = 0x02;
567 fom_mask = 3;
568 break;
569 case 0x0a: /* FillOrMix_2 */
570 mask = 0x05;
571 opcode = 0x02;
572 fom_mask = 5;
573 break;
574 }
575 lastopcode = opcode;
576 mixmask = 0;
577 /* Output body */
578 while (count > 0)
579 {
580 if (x >= width)
581 {
582 if (height <= 0)
583 return False;
584 x = 0;
585 height--;
586 prevline = line;
587 line = output + height * (width * 3);
588 }
589 switch (opcode)
590 {
591 case 0: /* Fill */
592 if (insertmix)
593 {
594 if (prevline == NULL)
595 {
596 line[x * 3] = mix[0];
597 line[x * 3 + 1] = mix[1];
598 line[x * 3 + 2] = mix[2];
599 }
600 else
601 {
602 line[x * 3] =
603 prevline[x * 3] ^ mix[0];
604 line[x * 3 + 1] =
605 prevline[x * 3 + 1] ^ mix[1];
606 line[x * 3 + 2] =
607 prevline[x * 3 + 2] ^ mix[2];
608 }
609 insertmix = False;
610 count--;
611 x++;
612 }
613 if (prevline == NULL)
614 {
615 REPEAT
616 (
617 line[x * 3] = 0;
618 line[x * 3 + 1] = 0;
619 line[x * 3 + 2] = 0;
620 )
621 }
622 else
623 {
624 REPEAT
625 (
626 line[x * 3] = prevline[x * 3];
627 line[x * 3 + 1] = prevline[x * 3 + 1];
628 line[x * 3 + 2] = prevline[x * 3 + 2];
629 )
630 }
631 break;
632 case 1: /* Mix */
633 if (prevline == NULL)
634 {
635 REPEAT
636 (
637 line[x * 3] = mix[0];
638 line[x * 3 + 1] = mix[1];
639 line[x * 3 + 2] = mix[2];
640 )
641 }
642 else
643 {
644 REPEAT
645 (
646 line[x * 3] =
647 prevline[x * 3] ^ mix[0];
648 line[x * 3 + 1] =
649 prevline[x * 3 + 1] ^ mix[1];
650 line[x * 3 + 2] =
651 prevline[x * 3 + 2] ^ mix[2];
652 )
653 }
654 break;
655 case 2: /* Fill or Mix */
656 if (prevline == NULL)
657 {
658 REPEAT
659 (
660 MASK_UPDATE();
661 if (mask & mixmask)
662 {
663 line[x * 3] = mix[0];
664 line[x * 3 + 1] = mix[1];
665 line[x * 3 + 2] = mix[2];
666 }
667 else
668 {
669 line[x * 3] = 0;
670 line[x * 3 + 1] = 0;
671 line[x * 3 + 2] = 0;
672 }
673 )
674 }
675 else
676 {
677 REPEAT
678 (
679 MASK_UPDATE();
680 if (mask & mixmask)
681 {
682 line[x * 3] =
683 prevline[x * 3] ^ mix [0];
684 line[x * 3 + 1] =
685 prevline[x * 3 + 1] ^ mix [1];
686 line[x * 3 + 2] =
687 prevline[x * 3 + 2] ^ mix [2];
688 }
689 else
690 {
691 line[x * 3] =
692 prevline[x * 3];
693 line[x * 3 + 1] =
694 prevline[x * 3 + 1];
695 line[x * 3 + 2] =
696 prevline[x * 3 + 2];
697 }
698 )
699 }
700 break;
701 case 3: /* Colour */
702 REPEAT
703 (
704 line[x * 3] = colour2 [0];
705 line[x * 3 + 1] = colour2 [1];
706 line[x * 3 + 2] = colour2 [2];
707 )
708 break;
709 case 4: /* Copy */
710 REPEAT
711 (
712 line[x * 3] = CVAL(input);
713 line[x * 3 + 1] = CVAL(input);
714 line[x * 3 + 2] = CVAL(input);
715 )
716 break;
717 case 8: /* Bicolour */
718 REPEAT
719 (
720 if (bicolour)
721 {
722 line[x * 3] = colour2[0];
723 line[x * 3 + 1] = colour2[1];
724 line[x * 3 + 2] = colour2[2];
725 bicolour = False;
726 }
727 else
728 {
729 line[x * 3] = colour1[0];
730 line[x * 3 + 1] = colour1[1];
731 line[x * 3 + 2] = colour1[2];
732 bicolour = True;
733 count++;
734 }
735 )
736 break;
737 case 0xd: /* White */
738 REPEAT
739 (
740 line[x * 3] = 0xff;
741 line[x * 3 + 1] = 0xff;
742 line[x * 3 + 2] = 0xff;
743 )
744 break;
745 case 0xe: /* Black */
746 REPEAT
747 (
748 line[x * 3] = 0;
749 line[x * 3 + 1] = 0;
750 line[x * 3 + 2] = 0;
751 )
752 break;
753 default:
754 unimpl("bitmap opcode 0x%x\n", opcode);
755 return False;
756 }
757 }
758 }
759 return True;
760 }
761
762 #else
763
764 static uint32
765 cvalx(uint8 **input, int Bpp)
766 {
767 uint32 rv = 0;
768 memcpy(&rv, *input, Bpp);
769 *input += Bpp;
770 return rv;
771 }
772
773 static void
774 setli(uint8 *input, int offset, uint32 value, int Bpp)
775 {
776 input += offset * Bpp;
777 memcpy(input, &value, Bpp);
778 }
779
780 static uint32
781 getli(uint8 *input, int offset, int Bpp)
782 {
783 uint32 rv = 0;
784 input += offset * Bpp;
785 memcpy(&rv, input, Bpp);
786 return rv;
787 }
788
789 static BOOL
790 bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
791 {
792 uint8 *end = input + size;
793 uint8 *prevline = NULL, *line = NULL;
794 int opcode, count, offset, isfillormix, x = width;
795 int lastopcode = -1, insertmix = False, bicolour = False;
796 uint8 code;
797 uint32 colour1 = 0, colour2 = 0;
798 uint8 mixmask, mask = 0;
799 uint32 mix = 0xffffffff;
800 int fom_mask = 0;
801
802 while (input < end)
803 {
804 fom_mask = 0;
805 code = CVAL(input);
806 opcode = code >> 4;
807
808 /* Handle different opcode forms */
809 switch (opcode)
810 {
811 case 0xc:
812 case 0xd:
813 case 0xe:
814 opcode -= 6;
815 count = code & 0xf;
816 offset = 16;
817 break;
818
819 case 0xf:
820 opcode = code & 0xf;
821 if (opcode < 9)
822 {
823 count = CVAL(input);
824 count |= CVAL(input) << 8;
825 }
826 else
827 {
828 count = (opcode < 0xb) ? 8 : 1;
829 }
830 offset = 0;
831 break;
832
833 default:
834 opcode >>= 1;
835 count = code & 0x1f;
836 offset = 32;
837 break;
838 }
839
840 /* Handle strange cases for counts */
841 if (offset != 0)
842 {
843 isfillormix = ((opcode == 2) || (opcode == 7));
844
845 if (count == 0)
846 {
847 if (isfillormix)
848 count = CVAL(input) + 1;
849 else
850 count = CVAL(input) + offset;
851 }
852 else if (isfillormix)
853 {
854 count <<= 3;
855 }
856 }
857
858 /* Read preliminary data */
859 switch (opcode)
860 {
861 case 0: /* Fill */
862 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
863 insertmix = True;
864 break;
865 case 8: /* Bicolour */
866 colour1 = cvalx(&input, Bpp);
867 case 3: /* Colour */
868 colour2 = cvalx(&input, Bpp);
869 break;
870 case 6: /* SetMix/Mix */
871 case 7: /* SetMix/FillOrMix */
872 mix = cvalx(&input, Bpp);
873 opcode -= 5;
874 break;
875 case 9: /* FillOrMix_1 */
876 mask = 0x03;
877 opcode = 0x02;
878 fom_mask = 3;
879 break;
880 case 0x0a: /* FillOrMix_2 */
881 mask = 0x05;
882 opcode = 0x02;
883 fom_mask = 5;
884 break;
885
886 }
887
888 lastopcode = opcode;
889 mixmask = 0;
890
891 /* Output body */
892 while (count > 0)
893 {
894 if (x >= width)
895 {
896 if (height <= 0)
897 return False;
898
899 x = 0;
900 height--;
901
902 prevline = line;
903 line = output + height * width * Bpp;
904 }
905
906 switch (opcode)
907 {
908 case 0: /* Fill */
909 if (insertmix)
910 {
911 if (prevline == NULL)
912 setli(line, x, mix, Bpp);
913 else
914 setli(line, x,
915 getli(prevline, x, Bpp) ^ mix, Bpp);
916
917 insertmix = False;
918 count--;
919 x++;
920 }
921
922 if (prevline == NULL)
923 {
924 REPEAT(setli(line, x, 0, Bpp))}
925 else
926 {
927 REPEAT(setli
928 (line, x, getli(prevline, x, Bpp), Bpp));
929 }
930 break;
931
932 case 1: /* Mix */
933 if (prevline == NULL)
934 {
935 REPEAT(setli(line, x, mix, Bpp));
936 }
937 else
938 {
939 REPEAT(setli
940 (line, x, getli(prevline, x, Bpp) ^ mix,
941 Bpp));
942 }
943 break;
944
945 case 2: /* Fill or Mix */
946 if (prevline == NULL)
947 {
948 REPEAT(MASK_UPDATE();
949 if (mask & mixmask) setli(line, x, mix, Bpp);
950 else
951 setli(line, x, 0, Bpp););
952 }
953 else
954 {
955 REPEAT(MASK_UPDATE();
956 if (mask & mixmask)
957 setli(line, x, getli(prevline, x, Bpp) ^ mix,
958 Bpp);
959 else
960 setli(line, x, getli(prevline, x, Bpp),
961 Bpp););
962 }
963 break;
964
965 case 3: /* Colour */
966 REPEAT(setli(line, x, colour2, Bpp));
967 break;
968
969 case 4: /* Copy */
970 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
971 break;
972
973 case 8: /* Bicolour */
974 REPEAT(if (bicolour)
975 {
976 setli(line, x, colour2, Bpp); bicolour = False;}
977 else
978 {
979 setli(line, x, colour1, Bpp); bicolour = True;
980 count++;}
981 );
982 break;
983
984 case 0xd: /* White */
985 REPEAT(setli(line, x, 0xffffffff, Bpp));
986 break;
987
988 case 0xe: /* Black */
989 REPEAT(setli(line, x, 0, Bpp));
990 break;
991
992 default:
993 unimpl("bitmap opcode 0x%x\n", opcode);
994 return False;
995 }
996 }
997 }
998
999 return True;
1000 }
1001
1002 #endif
1003
1004 /* main decompress function */
1005 BOOL
1006 bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp)
1007 {
1008 #ifdef BITMAP_SPEED_OVER_SIZE
1009 BOOL rv = False;
1010 switch (Bpp)
1011 {
1012 case 1:
1013 rv = bitmap_decompress1(output, width, height, input, size);
1014 break;
1015 case 2:
1016 rv = bitmap_decompress2(output, width, height, input, size);
1017 break;
1018 case 3:
1019 rv = bitmap_decompress3(output, width, height, input, size);
1020 break;
1021 }
1022 #else
1023 BOOL rv;
1024 rv = bitmap_decompressx(output, width, height, input, size, Bpp);
1025 #endif
1026 return rv;
1027 }
1028
1029 /* *INDENT-ON* */

  ViewVC Help
Powered by ViewVC 1.1.26