Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbitmap.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 Bitmap decompression routines 00004 Copyright (C) Matthew Chapman 1999-2005 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 /* three seperate function for speed when decompressing the bitmaps */ 00022 /* when modifing one function make the change in the others */ 00023 /* comment out #define BITMAP_SPEED_OVER_SIZE below for one slower function */ 00024 /* j@american-data.com */ 00025 00026 #define BITMAP_SPEED_OVER_SIZE 00027 00028 /* indent is confused by this file */ 00029 /* *INDENT-OFF* */ 00030 00031 #include <precomp.h> 00032 00033 #define CVAL(p) (*(p++)) 00034 #ifdef NEED_ALIGN 00035 #ifdef L_ENDIAN 00036 #define CVAL2(p, v) { v = (*(p++)); v |= (*(p++)) << 8; } 00037 #else 00038 #define CVAL2(p, v) { v = (*(p++)) << 8; v |= (*(p++)); } 00039 #endif /* L_ENDIAN */ 00040 #else 00041 #define CVAL2(p, v) { v = (*((uint16*)p)); p += 2; } 00042 #endif /* NEED_ALIGN */ 00043 00044 #define UNROLL8(exp) { exp exp exp exp exp exp exp exp } 00045 00046 #define REPEAT(statement) \ 00047 { \ 00048 while((count & ~0x7) && ((x+8) < width)) \ 00049 UNROLL8( statement; count--; x++; ); \ 00050 \ 00051 while((count > 0) && (x < width)) \ 00052 { \ 00053 statement; \ 00054 count--; \ 00055 x++; \ 00056 } \ 00057 } 00058 00059 #define MASK_UPDATE() \ 00060 { \ 00061 mixmask <<= 1; \ 00062 if (mixmask == 0) \ 00063 { \ 00064 mask = fom_mask ? fom_mask : CVAL(input); \ 00065 mixmask = 1; \ 00066 } \ 00067 } 00068 00069 #ifdef BITMAP_SPEED_OVER_SIZE 00070 00071 /* 1 byte bitmap decompress */ 00072 static BOOL 00073 bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size) 00074 { 00075 uint8 *end = input + size; 00076 uint8 *prevline = NULL, *line = NULL; 00077 int opcode, count, offset, isfillormix, x = width; 00078 int lastopcode = -1, insertmix = False, bicolour = False; 00079 uint8 code; 00080 uint8 colour1 = 0, colour2 = 0; 00081 uint8 mixmask, mask = 0; 00082 uint8 mix = 0xff; 00083 int fom_mask = 0; 00084 00085 while (input < end) 00086 { 00087 fom_mask = 0; 00088 code = CVAL(input); 00089 opcode = code >> 4; 00090 /* Handle different opcode forms */ 00091 switch (opcode) 00092 { 00093 case 0xc: 00094 case 0xd: 00095 case 0xe: 00096 opcode -= 6; 00097 count = code & 0xf; 00098 offset = 16; 00099 break; 00100 case 0xf: 00101 opcode = code & 0xf; 00102 if (opcode < 9) 00103 { 00104 count = CVAL(input); 00105 count |= CVAL(input) << 8; 00106 } 00107 else 00108 { 00109 count = (opcode < 0xb) ? 8 : 1; 00110 } 00111 offset = 0; 00112 break; 00113 default: 00114 opcode >>= 1; 00115 count = code & 0x1f; 00116 offset = 32; 00117 break; 00118 } 00119 /* Handle strange cases for counts */ 00120 if (offset != 0) 00121 { 00122 isfillormix = ((opcode == 2) || (opcode == 7)); 00123 if (count == 0) 00124 { 00125 if (isfillormix) 00126 count = CVAL(input) + 1; 00127 else 00128 count = CVAL(input) + offset; 00129 } 00130 else if (isfillormix) 00131 { 00132 count <<= 3; 00133 } 00134 } 00135 /* Read preliminary data */ 00136 switch (opcode) 00137 { 00138 case 0: /* Fill */ 00139 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) 00140 insertmix = True; 00141 break; 00142 case 8: /* Bicolour */ 00143 colour1 = CVAL(input); 00144 case 3: /* Colour */ 00145 colour2 = CVAL(input); 00146 break; 00147 case 6: /* SetMix/Mix */ 00148 case 7: /* SetMix/FillOrMix */ 00149 mix = CVAL(input); 00150 opcode -= 5; 00151 break; 00152 case 9: /* FillOrMix_1 */ 00153 mask = 0x03; 00154 opcode = 0x02; 00155 fom_mask = 3; 00156 break; 00157 case 0x0a: /* FillOrMix_2 */ 00158 mask = 0x05; 00159 opcode = 0x02; 00160 fom_mask = 5; 00161 break; 00162 } 00163 lastopcode = opcode; 00164 mixmask = 0; 00165 /* Output body */ 00166 while (count > 0) 00167 { 00168 if (x >= width) 00169 { 00170 if (height <= 0) 00171 return False; 00172 x = 0; 00173 height--; 00174 prevline = line; 00175 line = output + height * width; 00176 } 00177 switch (opcode) 00178 { 00179 case 0: /* Fill */ 00180 if (insertmix) 00181 { 00182 if (prevline == NULL) 00183 line[x] = mix; 00184 else 00185 line[x] = prevline[x] ^ mix; 00186 insertmix = False; 00187 count--; 00188 x++; 00189 } 00190 if (prevline == NULL) 00191 { 00192 REPEAT(line[x] = 0) 00193 } 00194 else 00195 { 00196 REPEAT(line[x] = prevline[x]) 00197 } 00198 break; 00199 case 1: /* Mix */ 00200 if (prevline == NULL) 00201 { 00202 REPEAT(line[x] = mix) 00203 } 00204 else 00205 { 00206 REPEAT(line[x] = prevline[x] ^ mix) 00207 } 00208 break; 00209 case 2: /* Fill or Mix */ 00210 if (prevline == NULL) 00211 { 00212 REPEAT 00213 ( 00214 MASK_UPDATE(); 00215 if (mask & mixmask) 00216 line[x] = mix; 00217 else 00218 line[x] = 0; 00219 ) 00220 } 00221 else 00222 { 00223 REPEAT 00224 ( 00225 MASK_UPDATE(); 00226 if (mask & mixmask) 00227 line[x] = prevline[x] ^ mix; 00228 else 00229 line[x] = prevline[x]; 00230 ) 00231 } 00232 break; 00233 case 3: /* Colour */ 00234 REPEAT(line[x] = colour2) 00235 break; 00236 case 4: /* Copy */ 00237 REPEAT(line[x] = CVAL(input)) 00238 break; 00239 case 8: /* Bicolour */ 00240 REPEAT 00241 ( 00242 if (bicolour) 00243 { 00244 line[x] = colour2; 00245 bicolour = False; 00246 } 00247 else 00248 { 00249 line[x] = colour1; 00250 bicolour = True; count++; 00251 } 00252 ) 00253 break; 00254 case 0xd: /* White */ 00255 REPEAT(line[x] = 0xff) 00256 break; 00257 case 0xe: /* Black */ 00258 REPEAT(line[x] = 0) 00259 break; 00260 default: 00261 unimpl("bitmap opcode 0x%x\n", opcode); 00262 return False; 00263 } 00264 } 00265 } 00266 return True; 00267 } 00268 00269 /* 2 byte bitmap decompress */ 00270 static BOOL 00271 bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size) 00272 { 00273 uint8 *end = input + size; 00274 uint16 *prevline = NULL, *line = NULL; 00275 int opcode, count, offset, isfillormix, x = width; 00276 int lastopcode = -1, insertmix = False, bicolour = False; 00277 uint8 code; 00278 uint16 colour1 = 0, colour2 = 0; 00279 uint8 mixmask, mask = 0; 00280 uint16 mix = 0xffff; 00281 int fom_mask = 0; 00282 00283 while (input < end) 00284 { 00285 fom_mask = 0; 00286 code = CVAL(input); 00287 opcode = code >> 4; 00288 /* Handle different opcode forms */ 00289 switch (opcode) 00290 { 00291 case 0xc: 00292 case 0xd: 00293 case 0xe: 00294 opcode -= 6; 00295 count = code & 0xf; 00296 offset = 16; 00297 break; 00298 case 0xf: 00299 opcode = code & 0xf; 00300 if (opcode < 9) 00301 { 00302 count = CVAL(input); 00303 count |= CVAL(input) << 8; 00304 } 00305 else 00306 { 00307 count = (opcode < 0xb) ? 8 : 1; 00308 } 00309 offset = 0; 00310 break; 00311 default: 00312 opcode >>= 1; 00313 count = code & 0x1f; 00314 offset = 32; 00315 break; 00316 } 00317 /* Handle strange cases for counts */ 00318 if (offset != 0) 00319 { 00320 isfillormix = ((opcode == 2) || (opcode == 7)); 00321 if (count == 0) 00322 { 00323 if (isfillormix) 00324 count = CVAL(input) + 1; 00325 else 00326 count = CVAL(input) + offset; 00327 } 00328 else if (isfillormix) 00329 { 00330 count <<= 3; 00331 } 00332 } 00333 /* Read preliminary data */ 00334 switch (opcode) 00335 { 00336 case 0: /* Fill */ 00337 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) 00338 insertmix = True; 00339 break; 00340 case 8: /* Bicolour */ 00341 CVAL2(input, colour1); 00342 case 3: /* Colour */ 00343 CVAL2(input, colour2); 00344 break; 00345 case 6: /* SetMix/Mix */ 00346 case 7: /* SetMix/FillOrMix */ 00347 CVAL2(input, mix); 00348 opcode -= 5; 00349 break; 00350 case 9: /* FillOrMix_1 */ 00351 mask = 0x03; 00352 opcode = 0x02; 00353 fom_mask = 3; 00354 break; 00355 case 0x0a: /* FillOrMix_2 */ 00356 mask = 0x05; 00357 opcode = 0x02; 00358 fom_mask = 5; 00359 break; 00360 } 00361 lastopcode = opcode; 00362 mixmask = 0; 00363 /* Output body */ 00364 while (count > 0) 00365 { 00366 if (x >= width) 00367 { 00368 if (height <= 0) 00369 return False; 00370 x = 0; 00371 height--; 00372 prevline = line; 00373 line = ((uint16 *) output) + height * width; 00374 } 00375 switch (opcode) 00376 { 00377 case 0: /* Fill */ 00378 if (insertmix) 00379 { 00380 if (prevline == NULL) 00381 line[x] = mix; 00382 else 00383 line[x] = prevline[x] ^ mix; 00384 insertmix = False; 00385 count--; 00386 x++; 00387 } 00388 if (prevline == NULL) 00389 { 00390 REPEAT(line[x] = 0) 00391 } 00392 else 00393 { 00394 REPEAT(line[x] = prevline[x]) 00395 } 00396 break; 00397 case 1: /* Mix */ 00398 if (prevline == NULL) 00399 { 00400 REPEAT(line[x] = mix) 00401 } 00402 else 00403 { 00404 REPEAT(line[x] = prevline[x] ^ mix) 00405 } 00406 break; 00407 case 2: /* Fill or Mix */ 00408 if (prevline == NULL) 00409 { 00410 REPEAT 00411 ( 00412 MASK_UPDATE(); 00413 if (mask & mixmask) 00414 line[x] = mix; 00415 else 00416 line[x] = 0; 00417 ) 00418 } 00419 else 00420 { 00421 REPEAT 00422 ( 00423 MASK_UPDATE(); 00424 if (mask & mixmask) 00425 line[x] = prevline[x] ^ mix; 00426 else 00427 line[x] = prevline[x]; 00428 ) 00429 } 00430 break; 00431 case 3: /* Colour */ 00432 REPEAT(line[x] = colour2) 00433 break; 00434 case 4: /* Copy */ 00435 REPEAT(CVAL2(input, line[x])) 00436 break; 00437 case 8: /* Bicolour */ 00438 REPEAT 00439 ( 00440 if (bicolour) 00441 { 00442 line[x] = colour2; 00443 bicolour = False; 00444 } 00445 else 00446 { 00447 line[x] = colour1; 00448 bicolour = True; 00449 count++; 00450 } 00451 ) 00452 break; 00453 case 0xd: /* White */ 00454 REPEAT(line[x] = 0xffff) 00455 break; 00456 case 0xe: /* Black */ 00457 REPEAT(line[x] = 0) 00458 break; 00459 default: 00460 unimpl("bitmap opcode 0x%x\n", opcode); 00461 return False; 00462 } 00463 } 00464 } 00465 return True; 00466 } 00467 00468 /* 3 byte bitmap decompress */ 00469 static BOOL 00470 bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size) 00471 { 00472 uint8 *end = input + size; 00473 uint8 *prevline = NULL, *line = NULL; 00474 int opcode, count, offset, isfillormix, x = width; 00475 int lastopcode = -1, insertmix = False, bicolour = False; 00476 uint8 code; 00477 uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0}; 00478 uint8 mixmask, mask = 0; 00479 uint8 mix[3] = {0xff, 0xff, 0xff}; 00480 int fom_mask = 0; 00481 00482 while (input < end) 00483 { 00484 fom_mask = 0; 00485 code = CVAL(input); 00486 opcode = code >> 4; 00487 /* Handle different opcode forms */ 00488 switch (opcode) 00489 { 00490 case 0xc: 00491 case 0xd: 00492 case 0xe: 00493 opcode -= 6; 00494 count = code & 0xf; 00495 offset = 16; 00496 break; 00497 case 0xf: 00498 opcode = code & 0xf; 00499 if (opcode < 9) 00500 { 00501 count = CVAL(input); 00502 count |= CVAL(input) << 8; 00503 } 00504 else 00505 { 00506 count = (opcode < 00507 0xb) ? 8 : 1; 00508 } 00509 offset = 0; 00510 break; 00511 default: 00512 opcode >>= 1; 00513 count = code & 0x1f; 00514 offset = 32; 00515 break; 00516 } 00517 /* Handle strange cases for counts */ 00518 if (offset != 0) 00519 { 00520 isfillormix = ((opcode == 2) || (opcode == 7)); 00521 if (count == 0) 00522 { 00523 if (isfillormix) 00524 count = CVAL(input) + 1; 00525 else 00526 count = CVAL(input) + offset; 00527 } 00528 else if (isfillormix) 00529 { 00530 count <<= 3; 00531 } 00532 } 00533 /* Read preliminary data */ 00534 switch (opcode) 00535 { 00536 case 0: /* Fill */ 00537 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) 00538 insertmix = True; 00539 break; 00540 case 8: /* Bicolour */ 00541 colour1[0] = CVAL(input); 00542 colour1[1] = CVAL(input); 00543 colour1[2] = CVAL(input); 00544 case 3: /* Colour */ 00545 colour2[0] = CVAL(input); 00546 colour2[1] = CVAL(input); 00547 colour2[2] = CVAL(input); 00548 break; 00549 case 6: /* SetMix/Mix */ 00550 case 7: /* SetMix/FillOrMix */ 00551 mix[0] = CVAL(input); 00552 mix[1] = CVAL(input); 00553 mix[2] = CVAL(input); 00554 opcode -= 5; 00555 break; 00556 case 9: /* FillOrMix_1 */ 00557 mask = 0x03; 00558 opcode = 0x02; 00559 fom_mask = 3; 00560 break; 00561 case 0x0a: /* FillOrMix_2 */ 00562 mask = 0x05; 00563 opcode = 0x02; 00564 fom_mask = 5; 00565 break; 00566 } 00567 lastopcode = opcode; 00568 mixmask = 0; 00569 /* Output body */ 00570 while (count > 0) 00571 { 00572 if (x >= width) 00573 { 00574 if (height <= 0) 00575 return False; 00576 x = 0; 00577 height--; 00578 prevline = line; 00579 line = output + height * (width * 3); 00580 } 00581 switch (opcode) 00582 { 00583 case 0: /* Fill */ 00584 if (insertmix) 00585 { 00586 if (prevline == NULL) 00587 { 00588 line[x * 3] = mix[0]; 00589 line[x * 3 + 1] = mix[1]; 00590 line[x * 3 + 2] = mix[2]; 00591 } 00592 else 00593 { 00594 line[x * 3] = 00595 prevline[x * 3] ^ mix[0]; 00596 line[x * 3 + 1] = 00597 prevline[x * 3 + 1] ^ mix[1]; 00598 line[x * 3 + 2] = 00599 prevline[x * 3 + 2] ^ mix[2]; 00600 } 00601 insertmix = False; 00602 count--; 00603 x++; 00604 } 00605 if (prevline == NULL) 00606 { 00607 REPEAT 00608 ( 00609 line[x * 3] = 0; 00610 line[x * 3 + 1] = 0; 00611 line[x * 3 + 2] = 0; 00612 ) 00613 } 00614 else 00615 { 00616 REPEAT 00617 ( 00618 line[x * 3] = prevline[x * 3]; 00619 line[x * 3 + 1] = prevline[x * 3 + 1]; 00620 line[x * 3 + 2] = prevline[x * 3 + 2]; 00621 ) 00622 } 00623 break; 00624 case 1: /* Mix */ 00625 if (prevline == NULL) 00626 { 00627 REPEAT 00628 ( 00629 line[x * 3] = mix[0]; 00630 line[x * 3 + 1] = mix[1]; 00631 line[x * 3 + 2] = mix[2]; 00632 ) 00633 } 00634 else 00635 { 00636 REPEAT 00637 ( 00638 line[x * 3] = 00639 prevline[x * 3] ^ mix[0]; 00640 line[x * 3 + 1] = 00641 prevline[x * 3 + 1] ^ mix[1]; 00642 line[x * 3 + 2] = 00643 prevline[x * 3 + 2] ^ mix[2]; 00644 ) 00645 } 00646 break; 00647 case 2: /* Fill or Mix */ 00648 if (prevline == NULL) 00649 { 00650 REPEAT 00651 ( 00652 MASK_UPDATE(); 00653 if (mask & mixmask) 00654 { 00655 line[x * 3] = mix[0]; 00656 line[x * 3 + 1] = mix[1]; 00657 line[x * 3 + 2] = mix[2]; 00658 } 00659 else 00660 { 00661 line[x * 3] = 0; 00662 line[x * 3 + 1] = 0; 00663 line[x * 3 + 2] = 0; 00664 } 00665 ) 00666 } 00667 else 00668 { 00669 REPEAT 00670 ( 00671 MASK_UPDATE(); 00672 if (mask & mixmask) 00673 { 00674 line[x * 3] = 00675 prevline[x * 3] ^ mix [0]; 00676 line[x * 3 + 1] = 00677 prevline[x * 3 + 1] ^ mix [1]; 00678 line[x * 3 + 2] = 00679 prevline[x * 3 + 2] ^ mix [2]; 00680 } 00681 else 00682 { 00683 line[x * 3] = 00684 prevline[x * 3]; 00685 line[x * 3 + 1] = 00686 prevline[x * 3 + 1]; 00687 line[x * 3 + 2] = 00688 prevline[x * 3 + 2]; 00689 } 00690 ) 00691 } 00692 break; 00693 case 3: /* Colour */ 00694 REPEAT 00695 ( 00696 line[x * 3] = colour2 [0]; 00697 line[x * 3 + 1] = colour2 [1]; 00698 line[x * 3 + 2] = colour2 [2]; 00699 ) 00700 break; 00701 case 4: /* Copy */ 00702 REPEAT 00703 ( 00704 line[x * 3] = CVAL(input); 00705 line[x * 3 + 1] = CVAL(input); 00706 line[x * 3 + 2] = CVAL(input); 00707 ) 00708 break; 00709 case 8: /* Bicolour */ 00710 REPEAT 00711 ( 00712 if (bicolour) 00713 { 00714 line[x * 3] = colour2[0]; 00715 line[x * 3 + 1] = colour2[1]; 00716 line[x * 3 + 2] = colour2[2]; 00717 bicolour = False; 00718 } 00719 else 00720 { 00721 line[x * 3] = colour1[0]; 00722 line[x * 3 + 1] = colour1[1]; 00723 line[x * 3 + 2] = colour1[2]; 00724 bicolour = True; 00725 count++; 00726 } 00727 ) 00728 break; 00729 case 0xd: /* White */ 00730 REPEAT 00731 ( 00732 line[x * 3] = 0xff; 00733 line[x * 3 + 1] = 0xff; 00734 line[x * 3 + 2] = 0xff; 00735 ) 00736 break; 00737 case 0xe: /* Black */ 00738 REPEAT 00739 ( 00740 line[x * 3] = 0; 00741 line[x * 3 + 1] = 0; 00742 line[x * 3 + 2] = 0; 00743 ) 00744 break; 00745 default: 00746 unimpl("bitmap opcode 0x%x\n", opcode); 00747 return False; 00748 } 00749 } 00750 } 00751 return True; 00752 } 00753 00754 #else 00755 00756 static uint32 00757 cvalx(uint8 **input, int Bpp) 00758 { 00759 uint32 rv = 0; 00760 memcpy(&rv, *input, Bpp); 00761 *input += Bpp; 00762 return rv; 00763 } 00764 00765 static void 00766 setli(uint8 *input, int offset, uint32 value, int Bpp) 00767 { 00768 input += offset * Bpp; 00769 memcpy(input, &value, Bpp); 00770 } 00771 00772 static uint32 00773 getli(uint8 *input, int offset, int Bpp) 00774 { 00775 uint32 rv = 0; 00776 input += offset * Bpp; 00777 memcpy(&rv, input, Bpp); 00778 return rv; 00779 } 00780 00781 static BOOL 00782 bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp) 00783 { 00784 uint8 *end = input + size; 00785 uint8 *prevline = NULL, *line = NULL; 00786 int opcode, count, offset, isfillormix, x = width; 00787 int lastopcode = -1, insertmix = False, bicolour = False; 00788 uint8 code; 00789 uint32 colour1 = 0, colour2 = 0; 00790 uint8 mixmask, mask = 0; 00791 uint32 mix = 0xffffffff; 00792 int fom_mask = 0; 00793 00794 while (input < end) 00795 { 00796 fom_mask = 0; 00797 code = CVAL(input); 00798 opcode = code >> 4; 00799 00800 /* Handle different opcode forms */ 00801 switch (opcode) 00802 { 00803 case 0xc: 00804 case 0xd: 00805 case 0xe: 00806 opcode -= 6; 00807 count = code & 0xf; 00808 offset = 16; 00809 break; 00810 00811 case 0xf: 00812 opcode = code & 0xf; 00813 if (opcode < 9) 00814 { 00815 count = CVAL(input); 00816 count |= CVAL(input) << 8; 00817 } 00818 else 00819 { 00820 count = (opcode < 0xb) ? 8 : 1; 00821 } 00822 offset = 0; 00823 break; 00824 00825 default: 00826 opcode >>= 1; 00827 count = code & 0x1f; 00828 offset = 32; 00829 break; 00830 } 00831 00832 /* Handle strange cases for counts */ 00833 if (offset != 0) 00834 { 00835 isfillormix = ((opcode == 2) || (opcode == 7)); 00836 00837 if (count == 0) 00838 { 00839 if (isfillormix) 00840 count = CVAL(input) + 1; 00841 else 00842 count = CVAL(input) + offset; 00843 } 00844 else if (isfillormix) 00845 { 00846 count <<= 3; 00847 } 00848 } 00849 00850 /* Read preliminary data */ 00851 switch (opcode) 00852 { 00853 case 0: /* Fill */ 00854 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) 00855 insertmix = True; 00856 break; 00857 case 8: /* Bicolour */ 00858 colour1 = cvalx(&input, Bpp); 00859 case 3: /* Colour */ 00860 colour2 = cvalx(&input, Bpp); 00861 break; 00862 case 6: /* SetMix/Mix */ 00863 case 7: /* SetMix/FillOrMix */ 00864 mix = cvalx(&input, Bpp); 00865 opcode -= 5; 00866 break; 00867 case 9: /* FillOrMix_1 */ 00868 mask = 0x03; 00869 opcode = 0x02; 00870 fom_mask = 3; 00871 break; 00872 case 0x0a: /* FillOrMix_2 */ 00873 mask = 0x05; 00874 opcode = 0x02; 00875 fom_mask = 5; 00876 break; 00877 00878 } 00879 00880 lastopcode = opcode; 00881 mixmask = 0; 00882 00883 /* Output body */ 00884 while (count > 0) 00885 { 00886 if (x >= width) 00887 { 00888 if (height <= 0) 00889 return False; 00890 00891 x = 0; 00892 height--; 00893 00894 prevline = line; 00895 line = output + height * width * Bpp; 00896 } 00897 00898 switch (opcode) 00899 { 00900 case 0: /* Fill */ 00901 if (insertmix) 00902 { 00903 if (prevline == NULL) 00904 setli(line, x, mix, Bpp); 00905 else 00906 setli(line, x, 00907 getli(prevline, x, Bpp) ^ mix, Bpp); 00908 00909 insertmix = False; 00910 count--; 00911 x++; 00912 } 00913 00914 if (prevline == NULL) 00915 { 00916 REPEAT(setli(line, x, 0, Bpp))} 00917 else 00918 { 00919 REPEAT(setli 00920 (line, x, getli(prevline, x, Bpp), Bpp)); 00921 } 00922 break; 00923 00924 case 1: /* Mix */ 00925 if (prevline == NULL) 00926 { 00927 REPEAT(setli(line, x, mix, Bpp)); 00928 } 00929 else 00930 { 00931 REPEAT(setli 00932 (line, x, getli(prevline, x, Bpp) ^ mix, 00933 Bpp)); 00934 } 00935 break; 00936 00937 case 2: /* Fill or Mix */ 00938 if (prevline == NULL) 00939 { 00940 REPEAT(MASK_UPDATE(); 00941 if (mask & mixmask) setli(line, x, mix, Bpp); 00942 else 00943 setli(line, x, 0, Bpp);); 00944 } 00945 else 00946 { 00947 REPEAT(MASK_UPDATE(); 00948 if (mask & mixmask) 00949 setli(line, x, getli(prevline, x, Bpp) ^ mix, 00950 Bpp); 00951 else 00952 setli(line, x, getli(prevline, x, Bpp), 00953 Bpp);); 00954 } 00955 break; 00956 00957 case 3: /* Colour */ 00958 REPEAT(setli(line, x, colour2, Bpp)); 00959 break; 00960 00961 case 4: /* Copy */ 00962 REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp)); 00963 break; 00964 00965 case 8: /* Bicolour */ 00966 REPEAT(if (bicolour) 00967 { 00968 setli(line, x, colour2, Bpp); bicolour = False;} 00969 else 00970 { 00971 setli(line, x, colour1, Bpp); bicolour = True; 00972 count++;} 00973 ); 00974 break; 00975 00976 case 0xd: /* White */ 00977 REPEAT(setli(line, x, 0xffffffff, Bpp)); 00978 break; 00979 00980 case 0xe: /* Black */ 00981 REPEAT(setli(line, x, 0, Bpp)); 00982 break; 00983 00984 default: 00985 unimpl("bitmap opcode 0x%x\n", opcode); 00986 return False; 00987 } 00988 } 00989 } 00990 00991 return True; 00992 } 00993 00994 #endif 00995 00996 /* main decompress function */ 00997 BOOL 00998 bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp) 00999 { 01000 #ifdef BITMAP_SPEED_OVER_SIZE 01001 BOOL rv = False; 01002 switch (Bpp) 01003 { 01004 case 1: 01005 rv = bitmap_decompress1(output, width, height, input, size); 01006 break; 01007 case 2: 01008 rv = bitmap_decompress2(output, width, height, input, size); 01009 break; 01010 case 3: 01011 rv = bitmap_decompress3(output, width, height, input, size); 01012 break; 01013 } 01014 #else 01015 BOOL rv; 01016 rv = bitmap_decompressx(output, width, height, input, size, Bpp); 01017 #endif 01018 return rv; 01019 } 01020 01021 /* *INDENT-ON* */ Generated on Fri May 25 2012 04:15:26 for ReactOS by
1.7.6.1
|