/[rdesktop]/sourceforge.net/trunk/rdesktop/bitmap.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/bitmap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 309 by jsorg71, Tue Feb 4 05:32:13 2003 UTC revision 314 by jsorg71, Fri Feb 7 23:43:37 2003 UTC
# Line 21  Line 21 
21  #include "rdesktop.h"  #include "rdesktop.h"
22    
23  #define CVAL(p)   (*(p++))  #define CVAL(p)   (*(p++))
24  #define CVAL16(p) (*(((uint16*)p)++))  
25    uint32 cvalx(unsigned char **input, int Bpp)
26    {
27            uint32 rv = 0;
28            memcpy(&rv, *input, Bpp);
29            *input += Bpp;
30            return rv;
31    }
32    
33    void setli(unsigned char * input, int offset, uint32 value, int Bpp)
34    {
35            input += offset * Bpp;
36            memcpy(input, &value, Bpp);
37    }
38    
39    uint32 getli(unsigned char * input, int offset, int Bpp)
40    {
41            uint32 rv = 0;
42            input += offset * Bpp;
43            memcpy(&rv, input, Bpp);
44            return rv;
45    }
46    
47  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
48    
# Line 44  Line 65 
65  }  }
66    
67  BOOL  BOOL
68  bitmap_decompress8(unsigned char *output, int width, int height, unsigned char *input, int size)  bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int Bpp)
69  {  {
70          unsigned char *end = input + size;          unsigned char *end = input + size;
71          unsigned char *prevline = NULL, *line = NULL;          unsigned char *prevline = NULL, *line = NULL;
72          int opcode, count, offset, isfillormix, x = width;          int opcode, count, offset, isfillormix, x = width;
73          int lastopcode = -1, insertmix = False, bicolour = False;          int lastopcode = -1, insertmix = False, bicolour = False;
         uint8 code, colour1 = 0, colour2 = 0;  
         uint8 mixmask, mask = 0, mix = 0xff;  
         int fom_mask = 0;  
   
         while (input < end)  
         {  
                 fom_mask = 0;  
                 code = CVAL(input);  
                 opcode = code >> 4;  
   
                 /* Handle different opcode forms */  
                 switch (opcode)  
                 {  
                         case 0xc:  
                         case 0xd:  
                         case 0xe:  
                                 opcode -= 6;  
                                 count = code & 0xf;  
                                 offset = 16;  
                                 break;  
   
                         case 0xf:  
                                 opcode = code & 0xf;  
                                 if (opcode < 9)  
                                 {  
                                         count = CVAL(input);  
                                         count |= CVAL(input) << 8;  
                                 }  
                                 else  
                                 {  
                                         count = (opcode < 0xb) ? 8 : 1;  
                                 }  
                                 offset = 0;  
                                 break;  
   
                         default:  
                                 opcode >>= 1;  
                                 count = code & 0x1f;  
                                 offset = 32;  
                                 break;  
                 }  
   
                 /* Handle strange cases for counts */  
                 if (offset != 0)  
                 {  
                         isfillormix = ((opcode == 2) || (opcode == 7));  
   
                         if (count == 0)  
                         {  
                                 if (isfillormix)  
                                         count = CVAL(input) + 1;  
                                 else  
                                         count = CVAL(input) + offset;  
                         }  
                         else if (isfillormix)  
                         {  
                                 count <<= 3;  
                         }  
                 }  
   
                 /* Read preliminary data */  
                 switch (opcode)  
                 {  
                         case 0: /* Fill */  
                                 if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))  
                                         insertmix = True;  
                                 break;  
                         case 8: /* Bicolour */  
                                 colour1 = CVAL(input);  
                         case 3: /* Colour */  
                                 colour2 = CVAL(input);  
                                 break;  
                         case 6: /* SetMix/Mix */  
                         case 7: /* SetMix/FillOrMix */  
                                 mix = CVAL(input);  
                                 opcode -= 5;  
                                 break;  
                         case 9: /* FillOrMix_1 */  
                                 mask = 0x03;  
                                 opcode = 0x02;  
                                 fom_mask = 3;  
                                 break;  
                         case 0x0a:      /* FillOrMix_2 */  
                                 mask = 0x05;  
                                 opcode = 0x02;  
                                 fom_mask = 5;  
                                 break;  
   
                 }  
   
                 lastopcode = opcode;  
                 mixmask = 0;  
   
                 /* Output body */  
                 while (count > 0)  
                 {  
                         if (x >= width)  
                         {  
                                 if (height <= 0)  
                                         return False;  
   
                                 x = 0;  
                                 height--;  
   
                                 prevline = line;  
                                 line = output + height * width;  
                         }  
   
                         switch (opcode)  
                         {  
                                 case 0: /* Fill */  
                                         if (insertmix)  
                                         {  
                                                 if (prevline == NULL)  
                                                         line[x] = mix;  
                                                 else  
                                                         line[x] = prevline[x] ^ mix;  
   
                                                 insertmix = False;  
                                                 count--;  
                                                 x++;  
                                         }  
   
                                         if (prevline == NULL)  
                                         {  
                                                 REPEAT(line[x] = 0);  
                                         }  
                                         else  
                                         {  
                                                 REPEAT(line[x] = prevline[x]);  
                                         }  
                                         break;  
   
                                 case 1: /* Mix */  
                                         if (prevline == NULL)  
                                         {  
                                                 REPEAT(line[x] = mix);  
                                         }  
                                         else  
                                         {  
                                                 REPEAT(line[x] = prevline[x] ^ mix);  
                                         }  
                                         break;  
   
                                 case 2: /* Fill or Mix */  
                                         if (prevline == NULL)  
                                         {  
                                                 REPEAT(MASK_UPDATE();  
                                                        if (mask & mixmask) line[x] = mix;  
                                                        else  
                                                        line[x] = 0;);  
                                         }  
                                         else  
                                         {  
                                                 REPEAT(MASK_UPDATE();  
                                                        if (mask & mixmask)  
                                                        line[x] = prevline[x] ^ mix;  
                                                        else  
                                                        line[x] = prevline[x];);  
                                         }  
                                         break;  
   
                                 case 3: /* Colour */  
                                         REPEAT(line[x] = colour2);  
                                         break;  
   
                                 case 4: /* Copy */  
                                         REPEAT(line[x] = CVAL(input));  
                                         break;  
   
                                 case 8: /* Bicolour */  
                                         REPEAT(if (bicolour)  
                                                {  
                                                line[x] = colour2; bicolour = False;}  
                                                else  
                                                {  
                                                line[x] = colour1; bicolour = True; count++;}  
                                         );  
                                         break;  
   
                                 case 0xd:       /* White */  
                                         REPEAT(line[x] = 0xff);  
                                         break;  
   
                                 case 0xe:       /* Black */  
                                         REPEAT(line[x] = 0x00);  
                                         break;  
   
                                 default:  
                                         unimpl("bitmap opcode 0x%x\n", opcode);  
                                         return False;  
                         }  
                 }  
         }  
   
         return True;  
 }  
   
 BOOL  
 bitmap_decompress16(unsigned char *output, int width, int height, unsigned char *input, int size)  
 {  
         unsigned char *end = input + size;  
         uint16 *prevline = NULL, *line = NULL;  
         int opcode, count, offset, isfillormix, x = width;  
         int lastopcode = -1, insertmix = False, bicolour = False;  
74          uint8 code;          uint8 code;
75          uint16 colour1 = 0, colour2 = 0;          uint32 colour1 = 0, colour2 = 0;
76          uint8 mixmask, mask = 0;          uint8 mixmask, mask = 0;
77          uint16 mix = 0xffff;          uint32 mix = 0xffffffff;
78          int fom_mask = 0;          int fom_mask = 0;
79    
80          while (input < end)          while (input < end)
# Line 287  bitmap_decompress16(unsigned char *outpu Line 103  bitmap_decompress16(unsigned char *outpu
103                                  }                                  }
104                                  else                                  else
105                                  {                                  {
106                                          count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit                                          count = (opcode < 0xb) ? 8 : 1;
107                                  }                                  }
108                                  offset = 0;                                  offset = 0;
109                                  break;                                  break;
# Line 325  bitmap_decompress16(unsigned char *outpu Line 141  bitmap_decompress16(unsigned char *outpu
141                                          insertmix = True;                                          insertmix = True;
142                                  break;                                  break;
143                          case 8: /* Bicolour */                          case 8: /* Bicolour */
144                                  colour1 = CVAL16(input);                                  colour1 = cvalx(&input, Bpp);
145                          case 3: /* Colour */                          case 3: /* Colour */
146                                  colour2 = CVAL16(input);                                  colour2 = cvalx(&input, Bpp);
147                                  break;                                  break;
148                          case 6: /* SetMix/Mix */                          case 6: /* SetMix/Mix */
149                          case 7: /* SetMix/FillOrMix */                          case 7: /* SetMix/FillOrMix */
150                                  mix = CVAL16(input);                                  mix = cvalx(&input, Bpp);
151                                  opcode -= 5;                                  opcode -= 5;
152                                  break;                                  break;
153                          case 9: /* FillOrMix_1 */                          case 9: /* FillOrMix_1 */
# Line 362  bitmap_decompress16(unsigned char *outpu Line 178  bitmap_decompress16(unsigned char *outpu
178                                  height--;                                  height--;
179    
180                                  prevline = line;                                  prevline = line;
181                                  line = (uint16*)output + height * width;                                  line = output + height * width * Bpp;
182                          }                          }
183    
184                          switch (opcode)                          switch (opcode)
# Line 371  bitmap_decompress16(unsigned char *outpu Line 187  bitmap_decompress16(unsigned char *outpu
187                                          if (insertmix)                                          if (insertmix)
188                                          {                                          {
189                                                  if (prevline == NULL)                                                  if (prevline == NULL)
190                                                          line[x] = mix;                                                          setli(line, x, mix, Bpp);
191                                                  else                                                  else
192                                                          line[x] = prevline[x] ^ mix;                                                          setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
193    
194                                                  insertmix = False;                                                  insertmix = False;
195                                                  count--;                                                  count--;
# Line 382  bitmap_decompress16(unsigned char *outpu Line 198  bitmap_decompress16(unsigned char *outpu
198    
199                                          if (prevline == NULL)                                          if (prevline == NULL)
200                                          {                                          {
201                                                  REPEAT(line[x] = 0);                                                  REPEAT(setli(line, x, 0, Bpp))
202                                          }                                          }
203                                          else                                          else
204                                          {                                          {
205                                                  REPEAT(line[x] = prevline[x]);                                                  REPEAT(setli(line, x, getli(prevline, x, Bpp), Bpp));
206                                          }                                          }
207                                          break;                                          break;
208    
209                                  case 1: /* Mix */                                  case 1: /* Mix */
210                                          if (prevline == NULL)                                          if (prevline == NULL)
211                                          {                                          {
212                                                  REPEAT(line[x] = mix);                                                  REPEAT(setli(line, x, mix, Bpp));
213                                          }                                          }
214                                          else                                          else
215                                          {                                          {
216                                                  REPEAT(line[x] = prevline[x] ^ mix);                                                  REPEAT(setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp));
217                                          }                                          }
218                                          break;                                          break;
219    
# Line 405  bitmap_decompress16(unsigned char *outpu Line 221  bitmap_decompress16(unsigned char *outpu
221                                          if (prevline == NULL)                                          if (prevline == NULL)
222                                          {                                          {
223                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
224                                                         if (mask & mixmask) line[x] = mix;                                                         if (mask & mixmask) setli(line, x, mix, Bpp);
225                                                         else                                                         else
226                                                         line[x] = 0;);                                                         setli(line, x, 0, Bpp););
227                                          }                                          }
228                                          else                                          else
229                                          {                                          {
230                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
231                                                         if (mask & mixmask)                                                         if (mask & mixmask)
232                                                         line[x] = prevline[x] ^ mix;                                                         setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
233                                                         else                                                         else
234                                                         line[x] = prevline[x];);                                                         setli(line, x, getli(prevline, x, Bpp), Bpp););
235                                          }                                          }
236                                          break;                                          break;
237    
238                                  case 3: /* Colour */                                  case 3: /* Colour */
239                                          REPEAT(line[x] = colour2);                                          REPEAT(setli(line, x, colour2, Bpp));
240                                          break;                                          break;
241    
242                                  case 4: /* Copy */                                  case 4: /* Copy */
243                                          REPEAT(line[x] = CVAL16(input));                                          REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
244                                          break;                                          break;
245    
246                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
247                                          REPEAT(if (bicolour)                                          REPEAT(if (bicolour)
248                                                 {                                                 {
249                                                 line[x] = colour2; bicolour = False;}                                                 setli(line, x, colour2, Bpp); bicolour = False;}
250                                                 else                                                 else
251                                                 {                                                 {
252                                                 line[x] = colour1; bicolour = True; count++;}                                                 setli(line, x, colour1, Bpp); bicolour = True; count++;}
253                                          );                                          );
254                                          break;                                          break;
255    
256                                  case 0xd:       /* White */                                  case 0xd:       /* White */
257                                          REPEAT(line[x] = 0xffff);                                          REPEAT(setli(line, x, 0xffffffff, Bpp));
258                                          break;                                          break;
259    
260                                  case 0xe:       /* Black */                                  case 0xe:       /* Black */
261                                          REPEAT(line[x] = 0x00);                                          REPEAT(setli(line, x, 0, Bpp));
262                                          break;                                          break;
263    
264                                  default:                                  default:
# Line 455  bitmap_decompress16(unsigned char *outpu Line 271  bitmap_decompress16(unsigned char *outpu
271          return True;          return True;
272  }  }
273    
 BOOL  
 bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int bpp)  
 {  
         if (bpp == 8)  
                 return bitmap_decompress8(output, width, height, input, size);  
         else if (bpp == 16)  
                 return bitmap_decompress16(output, width, height, input, size);  
         else  
                 return False;  
 }  

Legend:
Removed from v.309  
changed lines
  Added in v.314

  ViewVC Help
Powered by ViewVC 1.1.26