/[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 649 - (show annotations)
Thu Apr 15 17:28:30 2004 UTC (20 years, 1 month ago) by jsorg71
File MIME type: text/plain
File size: 19610 byte(s)
only check Bpp once when decompressing a bitmap, not for each pixel, much faster

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 colour1 = CVAL2(input);
334 case 3: /* Colour */
335 colour2 = CVAL2(input);
336 break;
337 case 6: /* SetMix/Mix */
338 case 7: /* SetMix/FillOrMix */
339 mix = CVAL2(input);
340 opcode -= 5;
341 break;
342 case 9: /* FillOrMix_1 */
343 mask = 0x03;
344 opcode = 0x02;
345 fom_mask = 3;
346 break;
347 case 0x0a: /* FillOrMix_2 */
348 mask = 0x05;
349 opcode = 0x02;
350 fom_mask = 5;
351 break;
352 }
353 lastopcode = opcode;
354 mixmask = 0;
355 /* Output body */
356 while (count > 0)
357 {
358 if (x >= width)
359 {
360 if (height <= 0)
361 return False;
362 x = 0;
363 height--;
364 prevline = line;
365 line = ((uint16 *) output) + height * width;
366 }
367 switch (opcode)
368 {
369 case 0: /* Fill */
370 if (insertmix)
371 {
372 if (prevline == NULL)
373 line[x] = mix;
374 else
375 line[x] = prevline[x] ^ mix;
376 insertmix = False;
377 count--;
378 x++;
379 }
380 if (prevline == NULL)
381 {
382 REPEAT(line[x] = 0)
383 }
384 else
385 {
386 REPEAT(line[x] = prevline[x])
387 }
388 break;
389 case 1: /* Mix */
390 if (prevline == NULL)
391 {
392 REPEAT(line[x] = mix)
393 }
394 else
395 {
396 REPEAT(line[x] = prevline[x] ^ mix)
397 }
398 break;
399 case 2: /* Fill or Mix */
400 if (prevline == NULL)
401 {
402 REPEAT
403 (
404 MASK_UPDATE();
405 if (mask & mixmask)
406 line[x] = mix;
407 else
408 line[x] = 0;
409 )
410 }
411 else
412 {
413 REPEAT
414 (
415 MASK_UPDATE();
416 if (mask & mixmask)
417 line[x] = prevline[x] ^ mix;
418 else
419 line[x] = prevline[x];
420 )
421 }
422 break;
423 case 3: /* Colour */
424 REPEAT(line[x] = colour2)
425 break;
426 case 4: /* Copy */
427 REPEAT(line[x] = CVAL2(input))
428 break;
429 case 8: /* Bicolour */
430 REPEAT
431 (
432 if (bicolour)
433 {
434 line[x] = colour2;
435 bicolour = False;
436 }
437 else
438 {
439 line[x] = colour1;
440 bicolour = True;
441 count++;
442 }
443 )
444 break;
445 case 0xd: /* White */
446 REPEAT(line[x] = 0xffff)
447 break;
448 case 0xe: /* Black */
449 REPEAT(line[x] = 0)
450 break;
451 default:
452 unimpl("bitmap opcode 0x%x\n", opcode);
453 return False;
454 }
455 }
456 }
457 return True;
458 }
459
460 /* 3 byte bitmap decompress */
461 static BOOL
462 bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
463 {
464 uint8 *end = input + size;
465 uint8 *prevline = NULL, *line = NULL;
466 int opcode, count, offset, isfillormix, x = width;
467 int lastopcode = -1, insertmix = False, bicolour = False;
468 uint8 code;
469 uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0};
470 uint8 mixmask, mask = 0;
471 uint8 mix[3] = {0xff, 0xff, 0xff};
472 int fom_mask = 0;
473
474 while (input < end)
475 {
476 fom_mask = 0;
477 code = CVAL(input);
478 opcode = code >> 4;
479 /* Handle different opcode forms */
480 switch (opcode)
481 {
482 case 0xc:
483 case 0xd:
484 case 0xe:
485 opcode -= 6;
486 count = code & 0xf;
487 offset = 16;
488 break;
489 case 0xf:
490 opcode = code & 0xf;
491 if (opcode < 9)
492 {
493 count = CVAL(input);
494 count |= CVAL(input) << 8;
495 }
496 else
497 {
498 count = (opcode <
499 0xb) ? 8 : 1;
500 }
501 offset = 0;
502 break;
503 default:
504 opcode >>= 1;
505 count = code & 0x1f;
506 offset = 32;
507 break;
508 }
509 /* Handle strange cases for counts */
510 if (offset != 0)
511 {
512 isfillormix = ((opcode == 2) || (opcode == 7));
513 if (count == 0)
514 {
515 if (isfillormix)
516 count = CVAL(input) + 1;
517 else
518 count = CVAL(input) + offset;
519 }
520 else if (isfillormix)
521 {
522 count <<= 3;
523 }
524 }
525 /* Read preliminary data */
526 switch (opcode)
527 {
528 case 0: /* Fill */
529 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
530 insertmix = True;
531 break;
532 case 8: /* Bicolour */
533 colour1[0] = CVAL(input);
534 colour1[1] = CVAL(input);
535 colour1[2] = CVAL(input);
536 case 3: /* Colour */
537 colour2[0] = CVAL(input);
538 colour2[1] = CVAL(input);
539 colour2[2] = CVAL(input);
540 break;
541 case 6: /* SetMix/Mix */
542 case 7: /* SetMix/FillOrMix */
543 mix[0] = CVAL(input);
544 mix[1] = CVAL(input);
545 mix[2] = CVAL(input);
546 opcode -= 5;
547 break;
548 case 9: /* FillOrMix_1 */
549 mask = 0x03;
550 opcode = 0x02;
551 fom_mask = 3;
552 break;
553 case 0x0a: /* FillOrMix_2 */
554 mask = 0x05;
555 opcode = 0x02;
556 fom_mask = 5;
557 break;
558 }
559 lastopcode = opcode;
560 mixmask = 0;
561 /* Output body */
562 while (count > 0)
563 {
564 if (x >= width)
565 {
566 if (height <= 0)
567 return False;
568 x = 0;
569 height--;
570 prevline = line;
571 line = output + height * (width * 3);
572 }
573 switch (opcode)
574 {
575 case 0: /* Fill */
576 if (insertmix)
577 {
578 if (prevline == NULL)
579 {
580 line[x * 3] = mix[0];
581 line[x * 3 + 1] = mix[1];
582 line[x * 3 + 2] = mix[2];
583 }
584 else
585 {
586 line[x * 3] =
587 prevline[x * 3] ^ mix[0];
588 line[x * 3 + 1] =
589 prevline[x * 3 + 1] ^ mix[1];
590 line[x * 3 + 2] =
591 prevline[x * 3 + 2] ^ mix[2];
592 }
593 insertmix = False;
594 count--;
595 x++;
596 }
597 if (prevline == NULL)
598 {
599 REPEAT
600 (
601 line[x * 3] = 0;
602 line[x * 3 + 1] = 0;
603 line[x * 3 + 2] = 0;
604 )
605 }
606 else
607 {
608 REPEAT
609 (
610 line[x * 3] = prevline[x * 3];
611 line[x * 3 + 1] = prevline[x * 3 + 1];
612 line[x * 3 + 2] = prevline[x * 3 + 2];
613 )
614 }
615 break;
616 case 1: /* Mix */
617 if (prevline == NULL)
618 {
619 REPEAT
620 (
621 line[x * 3] = mix[0];
622 line[x * 3 + 1] = mix[1];
623 line[x * 3 + 2] = mix[2];
624 )
625 }
626 else
627 {
628 REPEAT
629 (
630 line[x * 3] =
631 prevline[x * 3] ^ mix[0];
632 line[x * 3 + 1] =
633 prevline[x * 3 + 1] ^ mix[1];
634 line[x * 3 + 2] =
635 prevline[x * 3 + 2] ^ mix[2];
636 )
637 }
638 break;
639 case 2: /* Fill or Mix */
640 if (prevline == NULL)
641 {
642 REPEAT
643 (
644 MASK_UPDATE();
645 if (mask & mixmask)
646 {
647 line[x * 3] = mix[0];
648 line[x * 3 + 1] = mix[1];
649 line[x * 3 + 2] = mix[2];
650 }
651 else
652 {
653 line[x * 3] = 0;
654 line[x * 3 + 1] = 0;
655 line[x * 3 + 2] = 0;
656 }
657 )
658 }
659 else
660 {
661 REPEAT
662 (
663 MASK_UPDATE();
664 if (mask & mixmask)
665 {
666 line[x * 3] =
667 prevline[x * 3] ^ mix [0];
668 line[x * 3 + 1] =
669 prevline[x * 3 + 1] ^ mix [1];
670 line[x * 3 + 2] =
671 prevline[x * 3 + 2] ^ mix [2];
672 }
673 else
674 {
675 line[x * 3] =
676 prevline[x * 3];
677 line[x * 3 + 1] =
678 prevline[x * 3 + 1];
679 line[x * 3 + 2] =
680 prevline[x * 3 + 2];
681 }
682 )
683 }
684 break;
685 case 3: /* Colour */
686 REPEAT
687 (
688 line[x * 3] = colour2 [0];
689 line[x * 3 + 1] = colour2 [1];
690 line[x * 3 + 2] = colour2 [2];
691 )
692 break;
693 case 4: /* Copy */
694 REPEAT
695 (
696 line[x * 3] = CVAL(input);
697 line[x * 3 + 1] = CVAL(input);
698 line[x * 3 + 2] = CVAL(input);
699 )
700 break;
701 case 8: /* Bicolour */
702 REPEAT
703 (
704 if (bicolour)
705 {
706 line[x * 3] = colour2[0];
707 line[x * 3 + 1] = colour2[1];
708 line[x * 3 + 2] = colour2[2];
709 bicolour = False;
710 }
711 else
712 {
713 line[x * 3] = colour1[0];
714 line[x * 3 + 1] = colour1[1];
715 line[x * 3 + 2] = colour1[2];
716 bicolour = True;
717 count++;
718 }
719 )
720 break;
721 case 0xd: /* White */
722 REPEAT
723 (
724 line[x * 3] = 0xff;
725 line[x * 3 + 1] = 0xff;
726 line[x * 3 + 2] = 0xff;
727 )
728 break;
729 case 0xe: /* Black */
730 REPEAT
731 (
732 line[x * 3] = 0;
733 line[x * 3 + 1] = 0;
734 line[x * 3 + 2] = 0;
735 )
736 break;
737 default:
738 unimpl("bitmap opcode 0x%x\n", opcode);
739 return False;
740 }
741 }
742 }
743 return True;
744 }
745
746 #else
747
748 static uint32
749 cvalx(uint8 **input, int Bpp)
750 {
751 uint32 rv = 0;
752 memcpy(&rv, *input, Bpp);
753 *input += Bpp;
754 return rv;
755 }
756
757 static void
758 setli(uint8 *input, int offset, uint32 value, int Bpp)
759 {
760 input += offset * Bpp;
761 memcpy(input, &value, Bpp);
762 }
763
764 static uint32
765 getli(uint8 *input, int offset, int Bpp)
766 {
767 uint32 rv = 0;
768 input += offset * Bpp;
769 memcpy(&rv, input, Bpp);
770 return rv;
771 }
772
773 static BOOL
774 bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
775 {
776 uint8 *end = input + size;
777 uint8 *prevline = NULL, *line = NULL;
778 int opcode, count, offset, isfillormix, x = width;
779 int lastopcode = -1, insertmix = False, bicolour = False;
780 uint8 code;
781 uint32 colour1 = 0, colour2 = 0;
782 uint8 mixmask, mask = 0;
783 uint32 mix = 0xffffffff;
784 int fom_mask = 0;
785
786 while (input < end)
787 {
788 fom_mask = 0;
789 code = CVAL(input);
790 opcode = code >> 4;
791
792 /* Handle different opcode forms */
793 switch (opcode)
794 {
795 case 0xc:
796 case 0xd:
797 case 0xe:
798 opcode -= 6;
799 count = code & 0xf;
800 offset = 16;
801 break;
802
803 case 0xf:
804 opcode = code & 0xf;
805 if (opcode < 9)
806 {
807 count = CVAL(input);
808 count |= CVAL(input) << 8;
809 }
810 else
811 {
812 count = (opcode < 0xb) ? 8 : 1;
813 }
814 offset = 0;
815 break;
816
817 default:
818 opcode >>= 1;
819 count = code & 0x1f;
820 offset = 32;
821 break;
822 }
823
824 /* Handle strange cases for counts */
825 if (offset != 0)
826 {
827 isfillormix = ((opcode == 2) || (opcode == 7));
828
829 if (count == 0)
830 {
831 if (isfillormix)
832 count = CVAL(input) + 1;
833 else
834 count = CVAL(input) + offset;
835 }
836 else if (isfillormix)
837 {
838 count <<= 3;
839 }
840 }
841
842 /* Read preliminary data */
843 switch (opcode)
844 {
845 case 0: /* Fill */
846 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
847 insertmix = True;
848 break;
849 case 8: /* Bicolour */
850 colour1 = cvalx(&input, Bpp);
851 case 3: /* Colour */
852 colour2 = cvalx(&input, Bpp);
853 break;
854 case 6: /* SetMix/Mix */
855 case 7: /* SetMix/FillOrMix */
856 mix = cvalx(&input, Bpp);
857 opcode -= 5;
858 break;
859 case 9: /* FillOrMix_1 */
860 mask = 0x03;
861 opcode = 0x02;
862 fom_mask = 3;
863 break;
864 case 0x0a: /* FillOrMix_2 */
865 mask = 0x05;
866 opcode = 0x02;
867 fom_mask = 5;
868 break;
869
870 }
871
872 lastopcode = opcode;
873 mixmask = 0;
874
875 /* Output body */
876 while (count > 0)
877 {
878 if (x >= width)
879 {
880 if (height <= 0)
881 return False;
882
883 x = 0;
884 height--;
885
886 prevline = line;
887 line = output + height * width * Bpp;
888 }
889
890 switch (opcode)
891 {
892 case 0: /* Fill */
893 if (insertmix)
894 {
895 if (prevline == NULL)
896 setli(line, x, mix, Bpp);
897 else
898 setli(line, x,
899 getli(prevline, x, Bpp) ^ mix, Bpp);
900
901 insertmix = False;
902 count--;
903 x++;
904 }
905
906 if (prevline == NULL)
907 {
908 REPEAT(setli(line, x, 0, Bpp))}
909 else
910 {
911 REPEAT(setli
912 (line, x, getli(prevline, x, Bpp), Bpp));
913 }
914 break;
915
916 case 1: /* Mix */
917 if (prevline == NULL)
918 {
919 REPEAT(setli(line, x, mix, Bpp));
920 }
921 else
922 {
923 REPEAT(setli
924 (line, x, getli(prevline, x, Bpp) ^ mix,
925 Bpp));
926 }
927 break;
928
929 case 2: /* Fill or Mix */
930 if (prevline == NULL)
931 {
932 REPEAT(MASK_UPDATE();
933 if (mask & mixmask) setli(line, x, mix, Bpp);
934 else
935 setli(line, x, 0, Bpp););
936 }
937 else
938 {
939 REPEAT(MASK_UPDATE();
940 if (mask & mixmask)
941 setli(line, x, getli(prevline, x, Bpp) ^ mix,
942 Bpp);
943 else
944 setli(line, x, getli(prevline, x, Bpp),
945 Bpp););
946 }
947 break;
948
949 case 3: /* Colour */
950 REPEAT(setli(line, x, colour2, Bpp));
951 break;
952
953 case 4: /* Copy */
954 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
955 break;
956
957 case 8: /* Bicolour */
958 REPEAT(if (bicolour)
959 {
960 setli(line, x, colour2, Bpp); bicolour = False;}
961 else
962 {
963 setli(line, x, colour1, Bpp); bicolour = True;
964 count++;}
965 );
966 break;
967
968 case 0xd: /* White */
969 REPEAT(setli(line, x, 0xffffffff, Bpp));
970 break;
971
972 case 0xe: /* Black */
973 REPEAT(setli(line, x, 0, Bpp));
974 break;
975
976 default:
977 unimpl("bitmap opcode 0x%x\n", opcode);
978 return False;
979 }
980 }
981 }
982
983 return True;
984 }
985
986 #endif
987
988 /* main decompress function */
989 BOOL
990 bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp)
991 {
992 #ifdef BITMAP_SPEED_OVER_SIZE
993 BOOL rv = False;
994 switch (Bpp)
995 {
996 case 1:
997 rv = bitmap_decompress1(output, width, height, input, size);
998 break;
999 case 2:
1000 rv = bitmap_decompress2(output, width, height, input, size);
1001 break;
1002 case 3:
1003 rv = bitmap_decompress3(output, width, height, input, size);
1004 break;
1005 }
1006 #else
1007 BOOL rv;
1008 rv = bitmap_decompressx(output, width, height, input, size, Bpp);
1009 #endif
1010 return rv;
1011 }
1012
1013 /* *INDENT-ON* */

  ViewVC Help
Powered by ViewVC 1.1.26