/[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 19 by matty, Sun Oct 8 01:59:25 2000 UTC revision 314 by jsorg71, Fri Feb 7 23:43:37 2003 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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Line 21  Line 21 
21  #include "rdesktop.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++; } }  uint32 cvalx(unsigned char **input, int Bpp)
26  #define MASK_UPDATE() { mixmask <<= 1; if (mixmask == 0) { mask = CVAL(input); mixmask = 1; } }  {
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 }
48    
49    #define REPEAT(statement) \
50    { \
51            while((count & ~0x7) && ((x+8) < width)) \
52                    UNROLL8( statement; count--; x++; ); \
53            \
54            while((count > 0) && (x < width)) { statement; count--; x++; } \
55    }
56    
57    #define MASK_UPDATE() \
58    { \
59            mixmask <<= 1; \
60            if (mixmask == 0) \
61            { \
62                    mask = fom_mask ? fom_mask : CVAL(input); \
63                    mixmask = 1; \
64            } \
65    }
66    
67  BOOL bitmap_decompress(unsigned char *output, int width, int height,  BOOL
68                         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;
74          uint8 code, colour1 = 0, colour2 = 0;          uint8 code;
75          uint8 mixmask, mask = 0, mix = 0xff;          uint32 colour1 = 0, colour2 = 0;
76            uint8 mixmask, mask = 0;
77            uint32 mix = 0xffffffff;
78            int fom_mask = 0;
79    
80          while (input < end)          while (input < end)
81          {          {
82                    fom_mask = 0;
83                  code = CVAL(input);                  code = CVAL(input);
84                  opcode = code >> 4;                  opcode = code >> 4;
85    
# Line 54  BOOL bitmap_decompress(unsigned char *ou Line 96  BOOL bitmap_decompress(unsigned char *ou
96    
97                          case 0xf:                          case 0xf:
98                                  opcode = code & 0xf;                                  opcode = code & 0xf;
99                                  count = (opcode < 13) ? SVAL(input) : 1;                                  if (opcode < 9)
100                                    {
101                                            count = CVAL(input);
102                                            count |= CVAL(input) << 8;
103                                    }
104                                    else
105                                    {
106                                            count = (opcode < 0xb) ? 8 : 1;
107                                    }
108                                  offset = 0;                                  offset = 0;
109                                  break;                                  break;
110    
# Line 84  BOOL bitmap_decompress(unsigned char *ou Line 134  BOOL bitmap_decompress(unsigned char *ou
134                  }                  }
135    
136                  /* Read preliminary data */                  /* Read preliminary data */
                 mixmask = 0;  
137                  switch (opcode)                  switch (opcode)
138                  {                  {
139                          case 0: /* Fill */                          case 0: /* Fill */
140                                  if ((lastopcode == opcode)                                  if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
                                     && !((x == width) && (prevline == NULL)))  
141                                          insertmix = True;                                          insertmix = True;
142                                  break;                                  break;
143                          case 8: /* Bicolour */                          case 8: /* Bicolour */
144                                  colour1 = CVAL(input);                                  colour1 = cvalx(&input, Bpp);
145                          case 3: /* Colour */                          case 3: /* Colour */
146                                  colour2 = CVAL(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 = CVAL(input);                                  mix = cvalx(&input, Bpp);
151                                  opcode -= 5;                                  opcode -= 5;
152                                  break;                                  break;
153                            case 9: /* FillOrMix_1 */
154                                    mask = 0x03;
155                                    opcode = 0x02;
156                                    fom_mask = 3;
157                                    break;
158                            case 0x0a:      /* FillOrMix_2 */
159                                    mask = 0x05;
160                                    opcode = 0x02;
161                                    fom_mask = 5;
162                                    break;
163    
164                  }                  }
165    
166                  lastopcode = opcode;                  lastopcode = opcode;
167                    mixmask = 0;
168    
169                  /* Output body */                  /* Output body */
170                  while (count > 0)                  while (count > 0)
# Line 117  BOOL bitmap_decompress(unsigned char *ou Line 178  BOOL bitmap_decompress(unsigned char *ou
178                                  height--;                                  height--;
179    
180                                  prevline = line;                                  prevline = line;
181                                  line = output + height * width;                                  line = output + height * width * Bpp;
182                          }                          }
183    
184                          switch (opcode)                          switch (opcode)
185                          {                          {
186                                  case 0: /* Fill */                                  case 0: /* Fill */
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 136  BOOL bitmap_decompress(unsigned char *ou Line 197  BOOL bitmap_decompress(unsigned char *ou
197                                          }                                          }
198    
199                                          if (prevline == NULL)                                          if (prevline == NULL)
200                                                  REPEAT(line[x] = 0)                                          {
201                                                    REPEAT(setli(line, x, 0, Bpp))
202                                            }
203                                          else                                          else
204                                                  REPEAT(line[x] = prevline[x])                                          {
205                                                    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                                                  REPEAT(line[x] = mix)                                          {
212                                                    REPEAT(setli(line, x, mix, Bpp));
213                                            }
214                                          else                                          else
215                                                  REPEAT(line[x] = prevline[x] ^ mix)                                          {
216                                                    REPEAT(setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp));
217                                            }
218                                          break;                                          break;
219    
220                                  case 2: /* Fill or Mix */                                  case 2: /* Fill or Mix */
221                                          if (prevline == NULL)                                          if (prevline == NULL)
222                                              REPEAT(                                          {
223                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
224                                                           if (mask & mixmask) setli(line, x, mix, Bpp);
225                                                     if (mask & mixmask)                                                         else
226                                                          line[x] = mix;                                                         setli(line, x, 0, Bpp););
227                                                     else                                          }
                                                         line[x] = 0;  
                                             )  
228                                          else                                          else
229                                              REPEAT(                                          {
230                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
231                                                           if (mask & mixmask)
232                                                     if (mask & mixmask)                                                         setli(line, x, getli(prevline, x, Bpp) ^ mix, Bpp);
233                                                          line[x] = prevline[x] ^ mix;                                                         else
234                                                     else                                                         setli(line, x, getli(prevline, x, Bpp), Bpp););
235                                                          line[x] = prevline[x];                                          }
                                             )  
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] = CVAL(input))                                          REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
244                                          break;                                          break;
245    
246                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
247                                          REPEAT(                                          REPEAT(if (bicolour)
248                                                  if (bicolour)                                                 {
249                                                  {                                                 setli(line, x, colour2, Bpp); bicolour = False;}
250                                                          line[x] = colour2;                                                 else
251                                                          bicolour = False;                                                 {
252                                                  }                                                 setli(line, x, colour1, Bpp); bicolour = True; count++;}
253                                                  else                                          );
                                                 {  
                                                         line[x] = colour1;  
                                                         bicolour = True;  
                                                         count++;  
                                                 }  
                                         )  
254                                          break;                                          break;
255    
256                                  case 13: /* White */                                  case 0xd:       /* White */
257                                          REPEAT(line[x] = 0xff)                                          REPEAT(setli(line, x, 0xffffffff, Bpp));
258                                          break;                                          break;
259    
260                                  case 14: /* Black */                                  case 0xe:       /* Black */
261                                          REPEAT(line[x] = 0x00)                                          REPEAT(setli(line, x, 0, Bpp));
262                                          break;                                          break;
263    
264                                  default:                                  default:
265                                          NOTIMP("bitmap opcode 0x%x\n", opcode);                                          unimpl("bitmap opcode 0x%x\n", opcode);
266                                          return False;                                          return False;
267                          }                          }
268                  }                  }
# Line 210  BOOL bitmap_decompress(unsigned char *ou Line 270  BOOL bitmap_decompress(unsigned char *ou
270    
271          return True;          return True;
272  }  }
273    

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

  ViewVC Help
Powered by ViewVC 1.1.26