ReactOS 0.4.15-dev-8390-g075894b
bitmap.c File Reference
#include "rdesktop.h"
Include dependency graph for bitmap.c:

Go to the source code of this file.

Macros

#define BITMAP_SPEED_OVER_SIZE
 
#define CVAL(p)   (*(p++))
 
#define CVAL2(p, v)   { v = (*(p++)); v |= (*(p++)) << 8; }
 
#define UNROLL8(exp)   { exp exp exp exp exp exp exp exp }
 
#define REPEAT(statement)
 
#define MASK_UPDATE()
 

Functions

static BOOL bitmap_decompress1 (uint8 *output, int width, int height, uint8 *input, int size)
 
static BOOL bitmap_decompress2 (uint8 *output, int width, int height, uint8 *input, int size)
 
static BOOL bitmap_decompress3 (uint8 *output, int width, int height, uint8 *input, int size)
 
BOOL bitmap_decompress (uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
 

Macro Definition Documentation

◆ BITMAP_SPEED_OVER_SIZE

#define BITMAP_SPEED_OVER_SIZE

Definition at line 26 of file bitmap.c.

◆ CVAL

#define CVAL (   p)    (*(p++))

Definition at line 33 of file bitmap.c.

◆ CVAL2

#define CVAL2 (   p,
  v 
)    { v = (*(p++)); v |= (*(p++)) << 8; }

Definition at line 36 of file bitmap.c.

◆ MASK_UPDATE

#define MASK_UPDATE ( )
Value:
{ \
mixmask <<= 1; \
if (mixmask == 0) \
{ \
mask = fom_mask ? fom_mask : CVAL(input); \
mixmask = 1; \
} \
}
#define CVAL(p)
Definition: bitmap.c:29
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLenum GLenum input
Definition: glext.h:9031

Definition at line 59 of file bitmap.c.

◆ REPEAT

#define REPEAT (   statement)
Value:
{ \
while((count & ~0x7) && ((x+8) < width)) \
UNROLL8( statement; count--; x++; ); \
\
while((count > 0) && (x < width)) \
{ \
statement; \
count--; \
x++; \
} \
}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei width
Definition: gl.h:1546

Definition at line 46 of file bitmap.c.

◆ UNROLL8

#define UNROLL8 (   exp)    { exp exp exp exp exp exp exp exp }

Definition at line 44 of file bitmap.c.

Function Documentation

◆ bitmap_decompress()

BOOL bitmap_decompress ( uint8 output,
int  width,
int  height,
uint8 input,
int  size,
int  Bpp 
)

Definition at line 1089 of file bitmap.c.

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}
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
static RD_BOOL bitmap_decompress2(uint8 *output, int width, int height, uint8 *input, int size)
Definition: bitmap.c:265
#define False
Definition: types.h:25
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919

◆ bitmap_decompress1()

static BOOL bitmap_decompress1 ( uint8 output,
int  width,
int  height,
uint8 input,
int  size 
)
static

Definition at line 73 of file bitmap.c.

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);
286 }
287 }
288 }
289 return True;
290}
#define MASK_UPDATE()
Definition: bitmap.c:55
#define REPEAT(statement)
Definition: bitmap.c:42
void unimpl(char *format,...)
Definition: uimain.c:801
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
return
Definition: dirsup.c:529
#define NULL
Definition: types.h:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLintptr offset
Definition: glext.h:5920
Definition: uimain.c:89
Definition: inflate.c:139
Definition: parser.c:49
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3595

◆ bitmap_decompress2()

static BOOL bitmap_decompress2 ( uint8 output,
int  width,
int  height,
uint8 input,
int  size 
)
static

Definition at line 294 of file bitmap.c.

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);
508 }
509 }
510 }
511 return True;
512}
#define CVAL2(p, v)
Definition: bitmap.c:32
unsigned short uint16
Definition: types.h:30

◆ bitmap_decompress3()

static BOOL bitmap_decompress3 ( uint8 output,
int  width,
int  height,
uint8 input,
int  size 
)
static

Definition at line 516 of file bitmap.c.

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}