/[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 7 by matty, Fri Jul 7 09:40:03 2000 UTC revision 207 by matthewc, Thu Sep 26 14:26:46 2002 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Bitmap decompression routines     Bitmap decompression routines
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #include "rdesktop.h"
22    
23  #define CVAL(p)   (*(p++))  #define CVAL(p)   (*(p++))
 #define SVAL(p)   ((*((p++) + 1) << 8) | CVAL(p))  
24    
25  #define REPEAT(statement) { while ((count > 0) && (x < width)) { statement; count--; x++; } }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
 #define MASK_UPDATE() { maskpix <<= 1; if (maskpix == 0) { mask = CVAL(input); maskpix = 1; } }  
26    
27  BOOL bitmap_decompress(unsigned char *output, int width, int height,  #define REPEAT(statement) \
28                         unsigned char *input, int size)  { \
29            while((count & ~0x7) && ((x+8) < width)) \
30                    UNROLL8( statement; count--; x++; ); \
31            \
32            while((count > 0) && (x < width)) { statement; count--; x++; } \
33    }
34    
35    #define MASK_UPDATE() \
36    { \
37            mixmask <<= 1; \
38            if (mixmask == 0) \
39            { \
40                    mask = fom_mask ? fom_mask : CVAL(input); \
41                    mixmask = 1; \
42            } \
43    }
44    
45    BOOL
46    bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size)
47  {  {
48          unsigned char *end = input + size;          unsigned char *end = input + size;
49          unsigned char *prevline, *line = NULL;          unsigned char *prevline = NULL, *line = NULL;
50          int opcode, count, offset, isfillormix, x = width;          int opcode, count, offset, isfillormix, x = width;
51          uint8 code, mask, maskpix, color1, color2;          int lastopcode = -1, insertmix = False, bicolour = False;
52          uint8 mix = 0xff;          uint8 code, colour1 = 0, colour2 = 0;
53            uint8 mixmask, mask = 0, mix = 0xff;
54            int fom_mask = 0;
55    
         dump_data(input, end-input);  
56          while (input < end)          while (input < end)
57          {          {
58                  fprintf(stderr, "Offset %d from end\n", end-input);                  fom_mask = 0;
59                  code = CVAL(input);                  code = CVAL(input);
60                  opcode = code >> 4;                  opcode = code >> 4;
61    
# Line 55  BOOL bitmap_decompress(unsigned char *ou Line 72  BOOL bitmap_decompress(unsigned char *ou
72    
73                          case 0xf:                          case 0xf:
74                                  opcode = code & 0xf;                                  opcode = code & 0xf;
75                                  count = (opcode < 13) ? SVAL(input) : 1;                                  if (opcode < 9)
76                                    {
77                                            count = CVAL(input);
78                                            count |= CVAL(input) << 8;
79                                    }
80                                    else
81                                    {
82                                            count = (opcode < 0xb) ? 8 : 1;
83                                    }
84                                  offset = 0;                                  offset = 0;
85                                  break;                                  break;
86    
# Line 85  BOOL bitmap_decompress(unsigned char *ou Line 110  BOOL bitmap_decompress(unsigned char *ou
110                  }                  }
111    
112                  /* Read preliminary data */                  /* Read preliminary data */
                 maskpix = 0;  
113                  switch (opcode)                  switch (opcode)
114                  {                  {
115                          case 3: /* Color */                          case 0: /* Fill */
116                                  color1 = CVAL(input);                                  if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
117                          case 8: /* Bicolor */                                          insertmix = True;
118                                  color2 = CVAL(input);                                  break;
119                            case 8: /* Bicolour */
120                                    colour1 = CVAL(input);
121                            case 3: /* Colour */
122                                    colour2 = CVAL(input);
123                                  break;                                  break;
124                          case 6: /* SetMix/Mix */                          case 6: /* SetMix/Mix */
125                          case 7: /* SetMix/FillOrMix */                          case 7: /* SetMix/FillOrMix */
126                                  mix = CVAL(input);                                  mix = CVAL(input);
127                                  opcode -= 5;                                  opcode -= 5;
128                                  break;                                  break;
129                            case 9: /* FillOrMix_1 */
130                                    mask = 0x03;
131                                    opcode = 0x02;
132                                    fom_mask = 3;
133                                    break;
134                            case 0x0a:      /* FillOrMix_2 */
135                                    mask = 0x05;
136                                    opcode = 0x02;
137                                    fom_mask = 5;
138                                    break;
139    
140                  }                  }
141    
142                    lastopcode = opcode;
143                    mixmask = 0;
144    
145                  /* Output body */                  /* Output body */
146                  while (count > 0)                  while (count > 0)
147                  {                  {
148                          if (x >= width)                          if (x >= width)
149                          {                          {
150                                  if (height <= 0)                                  if (height <= 0)
151                                          return True;                                          return False;
152    
153                                  x = 0;                                  x = 0;
154                                  height--;                                  height--;
# Line 117  BOOL bitmap_decompress(unsigned char *ou Line 159  BOOL bitmap_decompress(unsigned char *ou
159    
160                          switch (opcode)                          switch (opcode)
161                          {                          {
162                                  case 0: /* Fill */                                  case 0: /* Fill */
163                                          fprintf(stderr, "Fill %d\n", count);                                          if (insertmix)
164                                            {
165                                                    if (prevline == NULL)
166                                                            line[x] = mix;
167                                                    else
168                                                            line[x] = prevline[x] ^ mix;
169    
170                                                    insertmix = False;
171                                                    count--;
172                                                    x++;
173                                            }
174    
175                                          if (prevline == NULL)                                          if (prevline == NULL)
176                                                  REPEAT(line[x] = 0)                                          {
177                                                    REPEAT(line[x] = 0);
178                                            }
179                                          else                                          else
180                                                  REPEAT(line[x] = prevline[x])                                          {
181                                                    REPEAT(line[x] = prevline[x]);
182                                            }
183                                          break;                                          break;
184    
185                                  case 1: /* Mix */                                  case 1: /* Mix */
                                         fprintf(stderr, "Mix %d\n", count);  
186                                          if (prevline == NULL)                                          if (prevline == NULL)
187                                                  REPEAT(line[x] = mix)                                          {
188                                                    REPEAT(line[x] = mix);
189                                            }
190                                          else                                          else
191                                                  REPEAT(line[x] = prevline[x] ^ mix)                                          {
192                                                    REPEAT(line[x] = prevline[x] ^ mix);
193                                            }
194                                          break;                                          break;
195    
196  #if 0                                  case 2: /* Fill or Mix */
                                 case 2: /* Fill or Mix */  
                                         REPEAT(line[x] = 0);  
                                         break;  
197                                          if (prevline == NULL)                                          if (prevline == NULL)
198                                              REPEAT(                                          {
199                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
200                                                           if (mask & mixmask) line[x] = mix;
201                                                     if (mask & maskpix)                                                         else
202                                                          line[x] = mix;                                                         line[x] = 0;);
203                                                     else                                          }
                                                         line[x] = 0;  
                                             )  
204                                          else                                          else
205                                              REPEAT(                                          {
206                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
207                                                           if (mask & mixmask)
208                                                     if (mask & maskpix)                                                         line[x] = prevline[x] ^ mix;
209                                                          line[x] = prevline[x] ^ mix;                                                         else
210                                                     else                                                         line[x] = prevline[x];);
211                                                          line[x] = prevline[x];                                          }
                                             )  
212                                          break;                                          break;
 #endif  
213    
214                                  case 3: /* Colour */                                  case 3: /* Colour */
215                                          fprintf(stderr, "Colour %d\n", count);                                          REPEAT(line[x] = colour2);
                                         REPEAT(line[x] = color2)  
216                                          break;                                          break;
217    
218                                  case 4: /* Copy */                                  case 4: /* Copy */
219                                          fprintf(stderr, "Copy %d\n", count);                                          REPEAT(line[x] = CVAL(input));
                                         REPEAT(line[x] = CVAL(input))  
220                                          break;                                          break;
221    
222  #if 0                                  case 8: /* Bicolour */
223                                  case 8: /* Bicolor */                                          REPEAT(if (bicolour)
224                                          REPEAT(line[x] = color1; line[++x] = color2)                                                 {
225                                                   line[x] = colour2; bicolour = False;}
226                                                   else
227                                                   {
228                                                   line[x] = colour1; bicolour = True; count++;}
229                                            );
230                                          break;                                          break;
231    
232                                  case 13: /* White */                                  case 0xd:       /* White */
233                                          REPEAT(line[x] = 0xff)                                          REPEAT(line[x] = 0xff);
234                                          break;                                          break;
235    
236                                  case 14: /* Black */                                  case 0xe:       /* Black */
237                                          REPEAT(line[x] = 0x00)                                          REPEAT(line[x] = 0x00);
238                                          break;                                          break;
 #endif  
239    
240                                  default:                                  default:
241                                          fprintf(stderr, "Unknown bitmap opcode 0x%x\n", opcode);                                          unimpl("bitmap opcode 0x%x\n", opcode);
242                                          return False;                                          return False;
243                          }                          }
244                  }                  }

Legend:
Removed from v.7  
changed lines
  Added in v.207

  ViewVC Help
Powered by ViewVC 1.1.26