1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * PURPOSE: RLE compression 5 * FILE: win32ss/gdi/eng/rlecomp.c 6 * PROGRAMER: Jason Filby 7 */ 8 9 #include <win32k.h> 10 11 #define NDEBUG 12 #include <debug.h> 13 14 enum Rle_EscapeCodes 15 { 16 RLE_EOL = 0, /* End of line */ 17 RLE_END = 1, /* End of bitmap */ 18 RLE_DELTA = 2 /* Delta */ 19 }; 20 21 VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, 22 LONG Delta, ULONG Format, ULONG cjSizeImage) 23 { 24 INT x = 0, y = Size.cy - 1; 25 INT i, c, c2, length; 26 INT width = Size.cx, height = y; 27 BYTE *begin = CompressedBits; 28 BYTE *bits = CompressedBits; 29 BYTE *temp; 30 BOOL is4bpp = FALSE; 31 32 if ((Format == BMF_4RLE) || (Format == BMF_4BPP)) 33 is4bpp = TRUE; 34 else if ((Format != BMF_8RLE) && (Format != BMF_8BPP)) 35 return; 36 37 _SEH2_TRY 38 { 39 while (y >= 0 && (bits - begin) <= cjSizeImage) 40 { 41 length = *bits++; 42 if (length) 43 { 44 c = *bits++; 45 for (i = 0; i < length; i++) 46 { 47 if (x >= width) break; 48 temp = UncompressedBits + (height - y) * Delta; 49 if (is4bpp) 50 { 51 temp += x / 2; 52 if (i & 1) 53 c2 = c & 0x0F; 54 else 55 c2 = c >> 4; 56 if (x & 1) 57 *temp |= c2; 58 else 59 *temp |= c2 << 4; 60 } 61 else 62 { 63 temp += x; 64 *temp = c; 65 } 66 x++; 67 } 68 } 69 else 70 { 71 length = *bits++; 72 switch (length) 73 { 74 case RLE_EOL: 75 x = 0; 76 y--; 77 break; 78 case RLE_END: 79 _SEH2_YIELD(return); 80 case RLE_DELTA: 81 x += *bits++; 82 y -= *bits++; 83 break; 84 default: 85 for (i = 0; i < length; i++) 86 { 87 if (!(is4bpp && i & 1)) 88 c = *bits++; 89 90 if (x < width) 91 { 92 temp = UncompressedBits + (height - y) * Delta; 93 if (is4bpp) 94 { 95 temp += x / 2; 96 if (i & 1) 97 c2 = c & 0x0F; 98 else 99 c2 = c >> 4; 100 if (x & 1) 101 *temp |= c2; 102 else 103 *temp |= c2 << 4; 104 } 105 else 106 { 107 temp += x; 108 *temp = c; 109 } 110 x++; 111 } 112 } 113 if ((bits - begin) & 1) 114 { 115 bits++; 116 } 117 } 118 } 119 } 120 } 121 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 122 { 123 DPRINT1("Decoding error\n"); 124 } 125 _SEH2_END; 126 127 return; 128 } 129