ReactOS  0.4.15-dev-1386-g5cb9f87
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 */
72 static BOOL
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 */
293 static 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 */
481  REPEAT(CVAL2(input, line[x]))
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 */
515 static 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 
825 static uint32
826 cvalx(uint8 **input, int Bpp)
827 {
828  uint32 rv = 0;
829  memcpy(&rv, *input, Bpp);
830  *input += Bpp;
831  return rv;
832 }
833 
834 static void
835 setli(uint8 *input, int offset, uint32 value, int Bpp)
836 {
837  input += offset * Bpp;
838  memcpy(input, &value, Bpp);
839 }
840 
841 static uint32
842 getli(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 
850 static BOOL
851 bitmap_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  {
1031  REPEAT(MASK_UPDATE();
1032  if (mask & mixmask) setli(line, x, mix, Bpp);
1033  else
1034  setli(line, x, 0, Bpp););
1035  }
1036  else
1037  {
1038  REPEAT(MASK_UPDATE();
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 */
1088 BOOL
1089 bitmap_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:
1097  break;
1098  case 2:
1100  break;
1101  case 3:
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* */
GLint GLint GLsizei width
Definition: gl.h:1546
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define CVAL2(p, v)
Definition: bitmap.c:36
#define MASK_UPDATE()
Definition: bitmap.c:59
#define REPEAT(statement)
Definition: bitmap.c:46
unsigned int uint32
Definition: types.h:32
GLuint GLuint GLsizei count
Definition: gl.h:1545
static BOOL bitmap_decompress3(uint8 *output, int width, int height, uint8 *input, int size)
Definition: bitmap.c:516
#define CVAL(p)
Definition: bitmap.c:33
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static BOOL bitmap_decompress1(uint8 *output, int width, int height, uint8 *input, int size)
Definition: bitmap.c:73
GLenum GLint GLuint mask
Definition: glext.h:6028
unsigned int BOOL
Definition: ntddk_ex.h:94
RD_BOOL bitmap_decompress(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
Definition: bitmap.c:884
Definition: parser.c:48
#define True
Definition: types.h:24
#define False
Definition: types.h:25
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
unsigned char uint8
Definition: types.h:28
GLuint GLuint end
Definition: gl.h:1545
char line[200]
Definition: main.c:97
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: inflate.c:139
int code
Definition: main.c:75
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLenum GLenum GLenum input
Definition: glext.h:9031
unsigned short uint16
Definition: types.h:30
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3591
#define NULL
Definition: types.h:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static BOOL bitmap_decompress2(uint8 *output, int width, int height, uint8 *input, int size)
Definition: bitmap.c:294
void unimpl(char *format,...)
Definition: uimain.c:801