ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bitmap.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.