/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 681 - (hide annotations)
Tue Apr 27 09:04:42 2004 UTC (20 years, 1 month 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 jsorg71 649 /*
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Bitmap decompression routines
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 jsorg71 309
6 matty 3 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 jsorg71 309
11 matty 3 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 jsorg71 309
16 matty 3 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 jsorg71 649 /* 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 matty 10 #include "rdesktop.h"
32 matty 3
33 matty 7 #define CVAL(p) (*(p++))
34 jsorg71 649 #define CVAL2(p) (*(((uint16*)p)++)) /* for 16 bit */
35 matty 3
36 jsorg71 649 #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 stargo 681 #ifdef NEED_ALIGNMENT
334 stargo 655 memcpy(&colour1,&CVAL2(input),2);
335 stargo 681 #else
336     colour1 = CVAL2(input);
337     #endif
338 jsorg71 649 case 3: /* Colour */
339 stargo 681 #ifdef NEED_ALIGNMENT
340 stargo 655 memcpy(&colour2,&CVAL2(input),2);
341 stargo 681 #else
342     colour2 = CVAL2(input);
343     #endif
344 jsorg71 649 break;
345     case 6: /* SetMix/Mix */
346     case 7: /* SetMix/FillOrMix */
347 stargo 681 #ifdef NEED_ALIGNMENT
348 stargo 655 memcpy(&mix,&CVAL2(input),2);
349 stargo 681 #else
350     mix = CVAL2(input);
351     #endif
352 jsorg71 649 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 stargo 681 #ifdef NEED_ALIGNMENT
440 stargo 655 REPEAT(memcpy(&line[x],&CVAL2(input),2))
441 stargo 681 #else
442     REPEAT(line[x] = CVAL2(input))
443     #endif
444 jsorg71 649 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 astrand 321 static uint32
765 jsorg71 649 cvalx(uint8 **input, int Bpp)
766 jsorg71 314 {
767     uint32 rv = 0;
768     memcpy(&rv, *input, Bpp);
769     *input += Bpp;
770     return rv;
771     }
772    
773 astrand 321 static void
774 jsorg71 649 setli(uint8 *input, int offset, uint32 value, int Bpp)
775 jsorg71 314 {
776     input += offset * Bpp;
777     memcpy(input, &value, Bpp);
778     }
779    
780 astrand 321 static uint32
781 jsorg71 649 getli(uint8 *input, int offset, int Bpp)
782 jsorg71 314 {
783     uint32 rv = 0;
784     input += offset * Bpp;
785     memcpy(&rv, input, Bpp);
786     return rv;
787     }
788    
789 jsorg71 649 static BOOL
790     bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
791 matty 3 {
792 jsorg71 649 uint8 *end = input + size;
793     uint8 *prevline = NULL, *line = NULL;
794 matty 7 int opcode, count, offset, isfillormix, x = width;
795 matty 19 int lastopcode = -1, insertmix = False, bicolour = False;
796 jsorg71 309 uint8 code;
797 jsorg71 314 uint32 colour1 = 0, colour2 = 0;
798 jsorg71 309 uint8 mixmask, mask = 0;
799 jsorg71 314 uint32 mix = 0xffffffff;
800 jsorg71 309 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 jsorg71 314 count = (opcode < 0xb) ? 8 : 1;
829 jsorg71 309 }
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 jsorg71 314 colour1 = cvalx(&input, Bpp);
867 jsorg71 309 case 3: /* Colour */
868 jsorg71 314 colour2 = cvalx(&input, Bpp);
869 jsorg71 309 break;
870     case 6: /* SetMix/Mix */
871     case 7: /* SetMix/FillOrMix */
872 jsorg71 314 mix = cvalx(&input, Bpp);
873 jsorg71 309 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 jsorg71 314 line = output + height * width * Bpp;
904 jsorg71 309 }
905    
906     switch (opcode)
907     {
908     case 0: /* Fill */
909     if (insertmix)
910     {
911     if (prevline == NULL)
912 jsorg71 314 setli(line, x, mix, Bpp);
913 jsorg71 309 else
914 astrand 318 setli(line, x,
915     getli(prevline, x, Bpp) ^ mix, Bpp);
916 jsorg71 309
917     insertmix = False;
918     count--;
919     x++;
920     }
921    
922     if (prevline == NULL)
923     {
924 astrand 318 REPEAT(setli(line, x, 0, Bpp))}
925 jsorg71 309 else
926     {
927 astrand 318 REPEAT(setli
928     (line, x, getli(prevline, x, Bpp), Bpp));
929 jsorg71 309 }
930     break;
931    
932     case 1: /* Mix */
933     if (prevline == NULL)
934     {
935 jsorg71 314 REPEAT(setli(line, x, mix, Bpp));
936 jsorg71 309 }
937     else
938     {
939 astrand 318 REPEAT(setli
940     (line, x, getli(prevline, x, Bpp) ^ mix,
941     Bpp));
942 jsorg71 309 }
943     break;
944    
945     case 2: /* Fill or Mix */
946     if (prevline == NULL)
947     {
948     REPEAT(MASK_UPDATE();
949 jsorg71 314 if (mask & mixmask) setli(line, x, mix, Bpp);
950 jsorg71 309 else
951 jsorg71 314 setli(line, x, 0, Bpp););
952 jsorg71 309 }
953     else
954     {
955     REPEAT(MASK_UPDATE();
956     if (mask & mixmask)
957 astrand 318 setli(line, x, getli(prevline, x, Bpp) ^ mix,
958     Bpp);
959 jsorg71 309 else
960 astrand 318 setli(line, x, getli(prevline, x, Bpp),
961     Bpp););
962 jsorg71 309 }
963     break;
964    
965     case 3: /* Colour */
966 jsorg71 314 REPEAT(setli(line, x, colour2, Bpp));
967 jsorg71 309 break;
968    
969     case 4: /* Copy */
970 jsorg71 314 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
971 jsorg71 309 break;
972    
973     case 8: /* Bicolour */
974     REPEAT(if (bicolour)
975     {
976 jsorg71 314 setli(line, x, colour2, Bpp); bicolour = False;}
977 jsorg71 309 else
978     {
979 astrand 318 setli(line, x, colour1, Bpp); bicolour = True;
980     count++;}
981 jsorg71 309 );
982     break;
983    
984     case 0xd: /* White */
985 jsorg71 314 REPEAT(setli(line, x, 0xffffffff, Bpp));
986 jsorg71 309 break;
987    
988     case 0xe: /* Black */
989 jsorg71 314 REPEAT(setli(line, x, 0, Bpp));
990 jsorg71 309 break;
991    
992     default:
993     unimpl("bitmap opcode 0x%x\n", opcode);
994     return False;
995     }
996     }
997     }
998    
999     return True;
1000     }
1001 jsorg71 649
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