/[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 28 by matty, Wed Jun 20 13:54:48 2001 UTC revision 309 by jsorg71, Tue Feb 4 05:32:13 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++))
24  #define SVAL(p)   ((*((p++) + 1) << 8) | CVAL(p))  #define CVAL16(p) (*(((uint16*)p)++))
25    
26  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
27    
# Line 44  Line 44 
44  }  }
45    
46  BOOL  BOOL
47  bitmap_decompress(unsigned char *output, int width, int height,  bitmap_decompress8(unsigned char *output, int width, int height, unsigned char *input, int size)
                   unsigned char *input, int size)  
48  {  {
49          unsigned char *end = input + size;          unsigned char *end = input + size;
50          unsigned char *prevline = NULL, *line = NULL;          unsigned char *prevline = NULL, *line = NULL;
# Line 75  bitmap_decompress(unsigned char *output, Line 74  bitmap_decompress(unsigned char *output,
74                          case 0xf:                          case 0xf:
75                                  opcode = code & 0xf;                                  opcode = code & 0xf;
76                                  if (opcode < 9)                                  if (opcode < 9)
77                                          count = SVAL(input);                                  {
78                                            count = CVAL(input);
79                                            count |= CVAL(input) << 8;
80                                    }
81                                  else                                  else
82                                    {
83                                          count = (opcode < 0xb) ? 8 : 1;                                          count = (opcode < 0xb) ? 8 : 1;
84                                    }
85                                  offset = 0;                                  offset = 0;
86                                  break;                                  break;
87    
# Line 110  bitmap_decompress(unsigned char *output, Line 114  bitmap_decompress(unsigned char *output,
114                  switch (opcode)                  switch (opcode)
115                  {                  {
116                          case 0: /* Fill */                          case 0: /* Fill */
117                                  if ((lastopcode == opcode)                                  if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
                                     && !((x == width) && (prevline == NULL)))  
118                                          insertmix = True;                                          insertmix = True;
119                                  break;                                  break;
120                          case 8: /* Bicolour */                          case 8: /* Bicolour */
# Line 163  bitmap_decompress(unsigned char *output, Line 166  bitmap_decompress(unsigned char *output,
166                                                  if (prevline == NULL)                                                  if (prevline == NULL)
167                                                          line[x] = mix;                                                          line[x] = mix;
168                                                  else                                                  else
169                                                          line[x] =                                                          line[x] = prevline[x] ^ mix;
                                                                 prevline[x] ^  
                                                                 mix;  
170    
171                                                  insertmix = False;                                                  insertmix = False;
172                                                  count--;                                                  count--;
# Line 189  bitmap_decompress(unsigned char *output, Line 190  bitmap_decompress(unsigned char *output,
190                                          }                                          }
191                                          else                                          else
192                                          {                                          {
193                                                  REPEAT(line[x] =                                                  REPEAT(line[x] = prevline[x] ^ mix);
                                                        prevline[x] ^ mix);  
194                                          }                                          }
195                                          break;                                          break;
196    
# Line 198  bitmap_decompress(unsigned char *output, Line 198  bitmap_decompress(unsigned char *output,
198                                          if (prevline == NULL)                                          if (prevline == NULL)
199                                          {                                          {
200                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
201                                                         if (mask & mixmask)                                                         if (mask & mixmask) line[x] = mix;
                                                        line[x] = mix;  
202                                                         else                                                         else
203                                                         line[x] = 0;);                                                         line[x] = 0;);
204                                          }                                          }
# Line 207  bitmap_decompress(unsigned char *output, Line 206  bitmap_decompress(unsigned char *output,
206                                          {                                          {
207                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
208                                                         if (mask & mixmask)                                                         if (mask & mixmask)
209                                                         line[x] =                                                         line[x] = prevline[x] ^ mix;
                                                        prevline[x] ^ mix;  
210                                                         else                                                         else
211                                                         line[x] =                                                         line[x] = prevline[x];);
                                                        prevline[x];);  
212                                          }                                          }
213                                          break;                                          break;
214    
# Line 226  bitmap_decompress(unsigned char *output, Line 223  bitmap_decompress(unsigned char *output,
223                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
224                                          REPEAT(if (bicolour)                                          REPEAT(if (bicolour)
225                                                 {                                                 {
226                                                 line[x] = colour2;                                                 line[x] = colour2; bicolour = False;}
                                                bicolour = False;}  
227                                                 else                                                 else
228                                                 {                                                 {
229                                                 line[x] = colour1;                                                 line[x] = colour1; bicolour = True; count++;}
                                                bicolour = True; count++;}  
230                                          );                                          );
231                                          break;                                          break;
232    
# Line 244  bitmap_decompress(unsigned char *output, Line 239  bitmap_decompress(unsigned char *output,
239                                          break;                                          break;
240    
241                                  default:                                  default:
242                                          NOTIMP("bitmap opcode 0x%x\n",                                          unimpl("bitmap opcode 0x%x\n", opcode);
                                                opcode);  
243                                          return False;                                          return False;
244                          }                          }
245                  }                  }
# Line 253  bitmap_decompress(unsigned char *output, Line 247  bitmap_decompress(unsigned char *output,
247    
248          return True;          return True;
249  }  }
250    
251    BOOL
252    bitmap_decompress16(unsigned char *output, int width, int height, unsigned char *input, int size)
253    {
254            unsigned char *end = input + size;
255            uint16 *prevline = NULL, *line = NULL;
256            int opcode, count, offset, isfillormix, x = width;
257            int lastopcode = -1, insertmix = False, bicolour = False;
258            uint8 code;
259            uint16 colour1 = 0, colour2 = 0;
260            uint8 mixmask, mask = 0;
261            uint16 mix = 0xffff;
262            int fom_mask = 0;
263    
264            while (input < end)
265            {
266                    fom_mask = 0;
267                    code = CVAL(input);
268                    opcode = code >> 4;
269    
270                    /* Handle different opcode forms */
271                    switch (opcode)
272                    {
273                            case 0xc:
274                            case 0xd:
275                            case 0xe:
276                                    opcode -= 6;
277                                    count = code & 0xf;
278                                    offset = 16;
279                                    break;
280    
281                            case 0xf:
282                                    opcode = code & 0xf;
283                                    if (opcode < 9)
284                                    {
285                                            count = CVAL(input);
286                                            count |= CVAL(input) << 8;
287                                    }
288                                    else
289                                    {
290                                            count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit
291                                    }
292                                    offset = 0;
293                                    break;
294    
295                            default:
296                                    opcode >>= 1;
297                                    count = code & 0x1f;
298                                    offset = 32;
299                                    break;
300                    }
301    
302                    /* Handle strange cases for counts */
303                    if (offset != 0)
304                    {
305                            isfillormix = ((opcode == 2) || (opcode == 7));
306    
307                            if (count == 0)
308                            {
309                                    if (isfillormix)
310                                            count = CVAL(input) + 1;
311                                    else
312                                            count = CVAL(input) + offset;
313                            }
314                            else if (isfillormix)
315                            {
316                                    count <<= 3;
317                            }
318                    }
319    
320                    /* Read preliminary data */
321                    switch (opcode)
322                    {
323                            case 0: /* Fill */
324                                    if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
325                                            insertmix = True;
326                                    break;
327                            case 8: /* Bicolour */
328                                    colour1 = CVAL16(input);
329                            case 3: /* Colour */
330                                    colour2 = CVAL16(input);
331                                    break;
332                            case 6: /* SetMix/Mix */
333                            case 7: /* SetMix/FillOrMix */
334                                    mix = CVAL16(input);
335                                    opcode -= 5;
336                                    break;
337                            case 9: /* FillOrMix_1 */
338                                    mask = 0x03;
339                                    opcode = 0x02;
340                                    fom_mask = 3;
341                                    break;
342                            case 0x0a:      /* FillOrMix_2 */
343                                    mask = 0x05;
344                                    opcode = 0x02;
345                                    fom_mask = 5;
346                                    break;
347    
348                    }
349    
350                    lastopcode = opcode;
351                    mixmask = 0;
352    
353                    /* Output body */
354                    while (count > 0)
355                    {
356                            if (x >= width)
357                            {
358                                    if (height <= 0)
359                                            return False;
360    
361                                    x = 0;
362                                    height--;
363    
364                                    prevline = line;
365                                    line = (uint16*)output + height * width;
366                            }
367    
368                            switch (opcode)
369                            {
370                                    case 0: /* Fill */
371                                            if (insertmix)
372                                            {
373                                                    if (prevline == NULL)
374                                                            line[x] = mix;
375                                                    else
376                                                            line[x] = prevline[x] ^ mix;
377    
378                                                    insertmix = False;
379                                                    count--;
380                                                    x++;
381                                            }
382    
383                                            if (prevline == NULL)
384                                            {
385                                                    REPEAT(line[x] = 0);
386                                            }
387                                            else
388                                            {
389                                                    REPEAT(line[x] = prevline[x]);
390                                            }
391                                            break;
392    
393                                    case 1: /* Mix */
394                                            if (prevline == NULL)
395                                            {
396                                                    REPEAT(line[x] = mix);
397                                            }
398                                            else
399                                            {
400                                                    REPEAT(line[x] = prevline[x] ^ mix);
401                                            }
402                                            break;
403    
404                                    case 2: /* Fill or Mix */
405                                            if (prevline == NULL)
406                                            {
407                                                    REPEAT(MASK_UPDATE();
408                                                           if (mask & mixmask) line[x] = mix;
409                                                           else
410                                                           line[x] = 0;);
411                                            }
412                                            else
413                                            {
414                                                    REPEAT(MASK_UPDATE();
415                                                           if (mask & mixmask)
416                                                           line[x] = prevline[x] ^ mix;
417                                                           else
418                                                           line[x] = prevline[x];);
419                                            }
420                                            break;
421    
422                                    case 3: /* Colour */
423                                            REPEAT(line[x] = colour2);
424                                            break;
425    
426                                    case 4: /* Copy */
427                                            REPEAT(line[x] = CVAL16(input));
428                                            break;
429    
430                                    case 8: /* Bicolour */
431                                            REPEAT(if (bicolour)
432                                                   {
433                                                   line[x] = colour2; bicolour = False;}
434                                                   else
435                                                   {
436                                                   line[x] = colour1; bicolour = True; count++;}
437                                            );
438                                            break;
439    
440                                    case 0xd:       /* White */
441                                            REPEAT(line[x] = 0xffff);
442                                            break;
443    
444                                    case 0xe:       /* Black */
445                                            REPEAT(line[x] = 0x00);
446                                            break;
447    
448                                    default:
449                                            unimpl("bitmap opcode 0x%x\n", opcode);
450                                            return False;
451                            }
452                    }
453            }
454    
455            return True;
456    }
457    
458    BOOL
459    bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int bpp)
460    {
461            if (bpp == 8)
462                    return bitmap_decompress8(output, width, height, input, size);
463            else if (bpp == 16)
464                    return bitmap_decompress16(output, width, height, input, size);
465            else
466                    return False;
467    }

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

  ViewVC Help
Powered by ViewVC 1.1.26