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