/[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 345 by forsberg, Thu Mar 27 13:08:57 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
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++; } }  static uint32
26  #define MASK_UPDATE() { mixmask <<= 1; if (mixmask == 0) { mask = CVAL(input); mixmask = 1; } }  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  BOOL bitmap_decompress(unsigned char *output, int width, int height,  static uint32
42                         unsigned char *input, int size)  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 }
51    
52    #define REPEAT(statement) \
53    { \
54            while((count & ~0x7) && ((x+8) < width)) \
55                    UNROLL8( statement; count--; x++; ); \
56            \
57            while((count > 0) && (x < width)) { statement; count--; x++; } \
58    }
59    
60    #define MASK_UPDATE() \
61    { \
62            mixmask <<= 1; \
63            if (mixmask == 0) \
64            { \
65                    mask = fom_mask ? fom_mask : CVAL(input); \
66                    mixmask = 1; \
67            } \
68    }
69    
70    BOOL
71    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;
78          uint8 code, colour1 = 0, colour2 = 0;          uint8 code;
79          uint8 mixmask, mask = 0, mix = 0xff;          uint32 colour1 = 0, colour2 = 0;
80            uint8 mixmask, mask = 0;
81            uint32 mix = 0xffffffff;
82            int fom_mask = 0;
83    
84          while (input < end)          while (input < end)
85          {          {
86                    fom_mask = 0;
87                  code = CVAL(input);                  code = CVAL(input);
88                  opcode = code >> 4;                  opcode = code >> 4;
89    
# Line 54  BOOL bitmap_decompress(unsigned char *ou Line 100  BOOL bitmap_decompress(unsigned char *ou
100    
101                          case 0xf:                          case 0xf:
102                                  opcode = code & 0xf;                                  opcode = code & 0xf;
103                                  count = (opcode < 13) ? SVAL(input) : 1;                                  if (opcode < 9)
104                                    {
105                                            count = CVAL(input);
106                                            count |= CVAL(input) << 8;
107                                    }
108                                    else
109                                    {
110                                            count = (opcode < 0xb) ? 8 : 1;
111                                    }
112                                  offset = 0;                                  offset = 0;
113                                  break;                                  break;
114    
# Line 84  BOOL bitmap_decompress(unsigned char *ou Line 138  BOOL bitmap_decompress(unsigned char *ou
138                  }                  }
139    
140                  /* Read preliminary data */                  /* Read preliminary data */
                 mixmask = 0;  
141                  switch (opcode)                  switch (opcode)
142                  {                  {
143                          case 0: /* Fill */                          case 0: /* Fill */
144                                  if ((lastopcode == opcode)                                  if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
                                     && !((x == width) && (prevline == NULL)))  
145                                          insertmix = True;                                          insertmix = True;
146                                  break;                                  break;
147                          case 8: /* Bicolour */                          case 8: /* Bicolour */
148                                  colour1 = CVAL(input);                                  colour1 = cvalx(&input, Bpp);
149                          case 3: /* Colour */                          case 3: /* Colour */
150                                  colour2 = CVAL(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 = CVAL(input);                                  mix = cvalx(&input, Bpp);
155                                  opcode -= 5;                                  opcode -= 5;
156                                  break;                                  break;
157                            case 9: /* FillOrMix_1 */
158                                    mask = 0x03;
159                                    opcode = 0x02;
160                                    fom_mask = 3;
161                                    break;
162                            case 0x0a:      /* FillOrMix_2 */
163                                    mask = 0x05;
164                                    opcode = 0x02;
165                                    fom_mask = 5;
166                                    break;
167    
168                  }                  }
169    
170                  lastopcode = opcode;                  lastopcode = opcode;
171                    mixmask = 0;
172    
173                  /* Output body */                  /* Output body */
174                  while (count > 0)                  while (count > 0)
# Line 117  BOOL bitmap_decompress(unsigned char *ou Line 182  BOOL bitmap_decompress(unsigned char *ou
182                                  height--;                                  height--;
183    
184                                  prevline = line;                                  prevline = line;
185                                  line = output + height * width;                                  line = output + height * width * Bpp;
186                          }                          }
187    
188                          switch (opcode)                          switch (opcode)
189                          {                          {
190                                  case 0: /* Fill */                                  case 0: /* Fill */
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 136  BOOL bitmap_decompress(unsigned char *ou Line 202  BOOL bitmap_decompress(unsigned char *ou
202                                          }                                          }
203    
204                                          if (prevline == NULL)                                          if (prevline == NULL)
205                                                  REPEAT(line[x] = 0)                                          {
206                                            REPEAT(setli(line, x, 0, Bpp))}
207                                          else                                          else
208                                                  REPEAT(line[x] = prevline[x])                                          {
209                                                    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                                                  REPEAT(line[x] = mix)                                          {
217                                                    REPEAT(setli(line, x, mix, Bpp));
218                                            }
219                                          else                                          else
220                                                  REPEAT(line[x] = prevline[x] ^ mix)                                          {
221                                                    REPEAT(setli
222                                                           (line, x, getli(prevline, x, Bpp) ^ mix,
223                                                            Bpp));
224                                            }
225                                          break;                                          break;
226    
227                                  case 2: /* Fill or Mix */                                  case 2: /* Fill or Mix */
228                                          if (prevline == NULL)                                          if (prevline == NULL)
229                                              REPEAT(                                          {
230                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
231                                                           if (mask & mixmask) setli(line, x, mix, Bpp);
232                                                     if (mask & mixmask)                                                         else
233                                                          line[x] = mix;                                                         setli(line, x, 0, Bpp););
234                                                     else                                          }
                                                         line[x] = 0;  
                                             )  
235                                          else                                          else
236                                              REPEAT(                                          {
237                                                     MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
238                                                           if (mask & mixmask)
239                                                     if (mask & mixmask)                                                         setli(line, x, getli(prevline, x, Bpp) ^ mix,
240                                                          line[x] = prevline[x] ^ mix;                                                               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] = CVAL(input))                                          REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
253                                          break;                                          break;
254    
255                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
256                                          REPEAT(                                          REPEAT(if (bicolour)
257                                                  if (bicolour)                                                 {
258                                                  {                                                 setli(line, x, colour2, Bpp); bicolour = False;}
259                                                          line[x] = colour2;                                                 else
260                                                          bicolour = False;                                                 {
261                                                  }                                                 setli(line, x, colour1, Bpp); bicolour = True;
262                                                  else                                                 count++;}
263                                                  {                                          );
                                                         line[x] = colour1;  
                                                         bicolour = True;  
                                                         count++;  
                                                 }  
                                         )  
264                                          break;                                          break;
265    
266                                  case 13: /* White */                                  case 0xd:       /* White */
267                                          REPEAT(line[x] = 0xff)                                          REPEAT(setli(line, x, 0xffffffff, Bpp));
268                                          break;                                          break;
269    
270                                  case 14: /* Black */                                  case 0xe:       /* Black */
271                                          REPEAT(line[x] = 0x00)                                          REPEAT(setli(line, x, 0, Bpp));
272                                          break;                                          break;
273    
274                                  default:                                  default:
275                                          NOTIMP("bitmap opcode 0x%x\n", opcode);                                          unimpl("bitmap opcode 0x%x\n", opcode);
276                                          return False;                                          return False;
277                          }                          }
278                  }                  }

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

  ViewVC Help
Powered by ViewVC 1.1.26