/[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 321 by astrand, Mon Feb 10 13:07:47 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    static uint32
26    cvalx(unsigned char **input, int Bpp)
27    {
28            uint32 rv = 0;
29            memcpy(&rv, *input, Bpp);
30            *input += Bpp;
31            return rv;
32    }
33    
34    static void
35    setli(unsigned char *input, int offset, uint32 value, int Bpp)
36    {
37            input += offset * Bpp;
38            memcpy(input, &value, Bpp);
39    }
40    
41    static uint32
42    getli(unsigned char *input, int offset, int Bpp)
43    {
44            uint32 rv = 0;
45            input += offset * Bpp;
46            memcpy(&rv, input, Bpp);
47            return rv;
48    }
49    
50  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
51    
# Line 44  Line 68 
68  }  }
69    
70  BOOL  BOOL
71  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,
72                      int Bpp)
73  {  {
74          unsigned char *end = input + size;          unsigned char *end = input + size;
75          unsigned char *prevline = NULL, *line = NULL;          unsigned char *prevline = NULL, *line = NULL;
76          int opcode, count, offset, isfillormix, x = width;          int opcode, count, offset, isfillormix, x = width;
77          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;  
78          uint8 code;          uint8 code;
79          uint16 colour1 = 0, colour2 = 0;          uint32 colour1 = 0, colour2 = 0;
80          uint8 mixmask, mask = 0;          uint8 mixmask, mask = 0;
81          uint16 mix = 0xffff;          uint32 mix = 0xffffffff;
82          int fom_mask = 0;          int fom_mask = 0;
83    
84          while (input < end)          while (input < end)
# Line 287  bitmap_decompress16(unsigned char *outpu Line 107  bitmap_decompress16(unsigned char *outpu
107                                  }                                  }
108                                  else                                  else
109                                  {                                  {
110                                          count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit                                          count = (opcode < 0xb) ? 8 : 1;
111                                  }                                  }
112                                  offset = 0;                                  offset = 0;
113                                  break;                                  break;
# Line 325  bitmap_decompress16(unsigned char *outpu Line 145  bitmap_decompress16(unsigned char *outpu
145                                          insertmix = True;                                          insertmix = True;
146                                  break;                                  break;
147                          case 8: /* Bicolour */                          case 8: /* Bicolour */
148                                  colour1 = CVAL16(input);                                  colour1 = cvalx(&input, Bpp);
149                          case 3: /* Colour */                          case 3: /* Colour */
150                                  colour2 = CVAL16(input);                                  colour2 = cvalx(&input, Bpp);
151                                  break;                                  break;
152                          case 6: /* SetMix/Mix */                          case 6: /* SetMix/Mix */
153                          case 7: /* SetMix/FillOrMix */                          case 7: /* SetMix/FillOrMix */
154                                  mix = CVAL16(input);                                  mix = cvalx(&input, Bpp);
155                                  opcode -= 5;                                  opcode -= 5;
156                                  break;                                  break;
157                          case 9: /* FillOrMix_1 */                          case 9: /* FillOrMix_1 */
# Line 362  bitmap_decompress16(unsigned char *outpu Line 182  bitmap_decompress16(unsigned char *outpu
182                                  height--;                                  height--;
183    
184                                  prevline = line;                                  prevline = line;
185                                  line = (uint16*)output + height * width;                                  line = output + height * width * Bpp;
186                          }                          }
187    
188                          switch (opcode)                          switch (opcode)
# Line 371  bitmap_decompress16(unsigned char *outpu Line 191  bitmap_decompress16(unsigned char *outpu
191                                          if (insertmix)                                          if (insertmix)
192                                          {                                          {
193                                                  if (prevline == NULL)                                                  if (prevline == NULL)
194                                                          line[x] = mix;                                                          setli(line, x, mix, Bpp);
195                                                  else                                                  else
196                                                          line[x] = prevline[x] ^ mix;                                                          setli(line, x,
197                                                                  getli(prevline, x, Bpp) ^ mix, Bpp);
198    
199                                                  insertmix = False;                                                  insertmix = False;
200                                                  count--;                                                  count--;
# Line 382  bitmap_decompress16(unsigned char *outpu Line 203  bitmap_decompress16(unsigned char *outpu
203    
204                                          if (prevline == NULL)                                          if (prevline == NULL)
205                                          {                                          {
206                                                  REPEAT(line[x] = 0);                                          REPEAT(setli(line, x, 0, Bpp))}
                                         }  
207                                          else                                          else
208                                          {                                          {
209                                                  REPEAT(line[x] = prevline[x]);                                                  REPEAT(setli
210                                                           (line, x, getli(prevline, x, Bpp), Bpp));
211                                          }                                          }
212                                          break;                                          break;
213    
214                                  case 1: /* Mix */                                  case 1: /* Mix */
215                                          if (prevline == NULL)                                          if (prevline == NULL)
216                                          {                                          {
217                                                  REPEAT(line[x] = mix);                                                  REPEAT(setli(line, x, mix, Bpp));
218                                          }                                          }
219                                          else                                          else
220                                          {                                          {
221                                                  REPEAT(line[x] = prevline[x] ^ mix);                                                  REPEAT(setli
222                                                           (line, x, getli(prevline, x, Bpp) ^ mix,
223                                                            Bpp));
224                                          }                                          }
225                                          break;                                          break;
226    
# Line 405  bitmap_decompress16(unsigned char *outpu Line 228  bitmap_decompress16(unsigned char *outpu
228                                          if (prevline == NULL)                                          if (prevline == NULL)
229                                          {                                          {
230                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
231                                                         if (mask & mixmask) line[x] = mix;                                                         if (mask & mixmask) setli(line, x, mix, Bpp);
232                                                         else                                                         else
233                                                         line[x] = 0;);                                                         setli(line, x, 0, Bpp););
234                                          }                                          }
235                                          else                                          else
236                                          {                                          {
237                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
238                                                         if (mask & mixmask)                                                         if (mask & mixmask)
239                                                         line[x] = prevline[x] ^ mix;                                                         setli(line, x, getli(prevline, x, Bpp) ^ mix,
240                                                                 Bpp);
241                                                         else                                                         else
242                                                         line[x] = prevline[x];);                                                         setli(line, x, getli(prevline, x, Bpp),
243                                                                 Bpp););
244                                          }                                          }
245                                          break;                                          break;
246    
247                                  case 3: /* Colour */                                  case 3: /* Colour */
248                                          REPEAT(line[x] = colour2);                                          REPEAT(setli(line, x, colour2, Bpp));
249                                          break;                                          break;
250    
251                                  case 4: /* Copy */                                  case 4: /* Copy */
252                                          REPEAT(line[x] = CVAL16(input));                                          REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
253                                          break;                                          break;
254    
255                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
256                                          REPEAT(if (bicolour)                                          REPEAT(if (bicolour)
257                                                 {                                                 {
258                                                 line[x] = colour2; bicolour = False;}                                                 setli(line, x, colour2, Bpp); bicolour = False;}
259                                                 else                                                 else
260                                                 {                                                 {
261                                                 line[x] = colour1; bicolour = True; count++;}                                                 setli(line, x, colour1, Bpp); bicolour = True;
262                                                   count++;}
263                                          );                                          );
264                                          break;                                          break;
265    
266                                  case 0xd:       /* White */                                  case 0xd:       /* White */
267                                          REPEAT(line[x] = 0xffff);                                          REPEAT(setli(line, x, 0xffffffff, Bpp));
268                                          break;                                          break;
269    
270                                  case 0xe:       /* Black */                                  case 0xe:       /* Black */
271                                          REPEAT(line[x] = 0x00);                                          REPEAT(setli(line, x, 0, Bpp));
272                                          break;                                          break;
273    
274                                  default:                                  default:
# Line 454  bitmap_decompress16(unsigned char *outpu Line 280  bitmap_decompress16(unsigned char *outpu
280    
281          return True;          return True;
282  }  }
   
 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.321

  ViewVC Help
Powered by ViewVC 1.1.26