/[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 828 by stargo, Sun Mar 6 21:11:18 2005 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-2002     Copyright (C) Matthew Chapman 1999-2005
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    /* three seperate function for speed when decompressing the bitmaps */
22    /* when modifing one function make the change in the others */
23    /* comment out #define BITMAP_SPEED_OVER_SIZE below for one slower function */
24    /* j@american-data.com */
25    
26    #define BITMAP_SPEED_OVER_SIZE
27    
28    /* indent is confused by this file */
29    /* *INDENT-OFF* */
30    
31  #include "rdesktop.h"  #include "rdesktop.h"
32    
33  #define CVAL(p)   (*(p++))  #define CVAL(p)   (*(p++))
34  #define CVAL16(p) (*(((uint16*)p)++))  #ifdef NEED_ALIGN
35    #ifdef L_ENDIAN
36    #define CVAL2(p, v) { v = (*(p++)); v |= (*(p++)) << 8; }
37    #else
38    #define CVAL2(p, v) { v = (*(p++)) << 8; v |= (*(p++)); }
39    #endif /* L_ENDIAN */
40    #else
41    #define CVAL2(p, v) { v = (*((uint16*)p)); p += 2; }
42    #endif /* NEED_ALIGN */
43    
44  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
45    
# Line 30  Line 48 
48          while((count & ~0x7) && ((x+8) < width)) \          while((count & ~0x7) && ((x+8) < width)) \
49                  UNROLL8( statement; count--; x++; ); \                  UNROLL8( statement; count--; x++; ); \
50          \          \
51          while((count > 0) && (x < width)) { statement; count--; x++; } \          while((count > 0) && (x < width)) \
52            { \
53                    statement; \
54                    count--; \
55                    x++; \
56            } \
57  }  }
58    
59  #define MASK_UPDATE() \  #define MASK_UPDATE() \
# Line 43  Line 66 
66          } \          } \
67  }  }
68    
69  BOOL  #ifdef BITMAP_SPEED_OVER_SIZE
70  bitmap_decompress8(unsigned char *output, int width, int height, unsigned char *input, int size)  
71    /* 1 byte bitmap decompress */
72    static BOOL
73    bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size)
74  {  {
75          unsigned char *end = input + size;          uint8 *end = input + size;
76          unsigned char *prevline = NULL, *line = NULL;          uint8 *prevline = NULL, *line = NULL;
77          int opcode, count, offset, isfillormix, x = width;          int opcode, count, offset, isfillormix, x = width;
78          int lastopcode = -1, insertmix = False, bicolour = False;          int lastopcode = -1, insertmix = False, bicolour = False;
79          uint8 code, colour1 = 0, colour2 = 0;          uint8 code;
80          uint8 mixmask, mask = 0, mix = 0xff;          uint8 colour1 = 0, colour2 = 0;
81            uint8 mixmask, mask = 0;
82            uint8 mix = 0xff;
83          int fom_mask = 0;          int fom_mask = 0;
84    
85          while (input < end)          while (input < end)
# Line 59  bitmap_decompress8(unsigned char *output Line 87  bitmap_decompress8(unsigned char *output
87                  fom_mask = 0;                  fom_mask = 0;
88                  code = CVAL(input);                  code = CVAL(input);
89                  opcode = code >> 4;                  opcode = code >> 4;
   
90                  /* Handle different opcode forms */                  /* Handle different opcode forms */
91                  switch (opcode)                  switch (opcode)
92                  {                  {
# Line 70  bitmap_decompress8(unsigned char *output Line 97  bitmap_decompress8(unsigned char *output
97                                  count = code & 0xf;                                  count = code & 0xf;
98                                  offset = 16;                                  offset = 16;
99                                  break;                                  break;
   
100                          case 0xf:                          case 0xf:
101                                  opcode = code & 0xf;                                  opcode = code & 0xf;
102                                  if (opcode < 9)                                  if (opcode < 9)
# Line 84  bitmap_decompress8(unsigned char *output Line 110  bitmap_decompress8(unsigned char *output
110                                  }                                  }
111                                  offset = 0;                                  offset = 0;
112                                  break;                                  break;
   
113                          default:                          default:
114                                  opcode >>= 1;                                  opcode >>= 1;
115                                  count = code & 0x1f;                                  count = code & 0x1f;
116                                  offset = 32;                                  offset = 32;
117                                  break;                                  break;
118                  }                  }
   
119                  /* Handle strange cases for counts */                  /* Handle strange cases for counts */
120                  if (offset != 0)                  if (offset != 0)
121                  {                  {
122                          isfillormix = ((opcode == 2) || (opcode == 7));                          isfillormix = ((opcode == 2) || (opcode == 7));
   
123                          if (count == 0)                          if (count == 0)
124                          {                          {
125                                  if (isfillormix)                                  if (isfillormix)
# Line 109  bitmap_decompress8(unsigned char *output Line 132  bitmap_decompress8(unsigned char *output
132                                  count <<= 3;                                  count <<= 3;
133                          }                          }
134                  }                  }
   
135                  /* Read preliminary data */                  /* Read preliminary data */
136                  switch (opcode)                  switch (opcode)
137                  {                  {
# Line 137  bitmap_decompress8(unsigned char *output Line 159  bitmap_decompress8(unsigned char *output
159                                  opcode = 0x02;                                  opcode = 0x02;
160                                  fom_mask = 5;                                  fom_mask = 5;
161                                  break;                                  break;
   
162                  }                  }
   
163                  lastopcode = opcode;                  lastopcode = opcode;
164                  mixmask = 0;                  mixmask = 0;
   
165                  /* Output body */                  /* Output body */
166                  while (count > 0)                  while (count > 0)
167                  {                  {
# Line 150  bitmap_decompress8(unsigned char *output Line 169  bitmap_decompress8(unsigned char *output
169                          {                          {
170                                  if (height <= 0)                                  if (height <= 0)
171                                          return False;                                          return False;
   
172                                  x = 0;                                  x = 0;
173                                  height--;                                  height--;
   
174                                  prevline = line;                                  prevline = line;
175                                  line = output + height * width;                                  line = output + height * width;
176                          }                          }
   
177                          switch (opcode)                          switch (opcode)
178                          {                          {
179                                  case 0: /* Fill */                                  case 0: /* Fill */
# Line 167  bitmap_decompress8(unsigned char *output Line 183  bitmap_decompress8(unsigned char *output
183                                                          line[x] = mix;                                                          line[x] = mix;
184                                                  else                                                  else
185                                                          line[x] = prevline[x] ^ mix;                                                          line[x] = prevline[x] ^ mix;
   
186                                                  insertmix = False;                                                  insertmix = False;
187                                                  count--;                                                  count--;
188                                                  x++;                                                  x++;
189                                          }                                          }
   
190                                          if (prevline == NULL)                                          if (prevline == NULL)
191                                          {                                          {
192                                                  REPEAT(line[x] = 0);                                                  REPEAT(line[x] = 0)
193                                          }                                          }
194                                          else                                          else
195                                          {                                          {
196                                                  REPEAT(line[x] = prevline[x]);                                                  REPEAT(line[x] = prevline[x])
197                                          }                                          }
198                                          break;                                          break;
   
199                                  case 1: /* Mix */                                  case 1: /* Mix */
200                                          if (prevline == NULL)                                          if (prevline == NULL)
201                                          {                                          {
202                                                  REPEAT(line[x] = mix);                                                  REPEAT(line[x] = mix)
203                                          }                                          }
204                                          else                                          else
205                                          {                                          {
206                                                  REPEAT(line[x] = prevline[x] ^ mix);                                                  REPEAT(line[x] = prevline[x] ^ mix)
207                                          }                                          }
208                                          break;                                          break;
   
209                                  case 2: /* Fill or Mix */                                  case 2: /* Fill or Mix */
210                                          if (prevline == NULL)                                          if (prevline == NULL)
211                                          {                                          {
212                                                  REPEAT(MASK_UPDATE();                                                  REPEAT
213                                                         if (mask & mixmask) line[x] = mix;                                                  (
214                                                         else                                                          MASK_UPDATE();
215                                                         line[x] = 0;);                                                          if (mask & mixmask)
216                                                                    line[x] = mix;
217                                                            else
218                                                                    line[x] = 0;
219                                                    )
220                                          }                                          }
221                                          else                                          else
222                                          {                                          {
223                                                  REPEAT(MASK_UPDATE();                                                  REPEAT
224                                                         if (mask & mixmask)                                                  (
225                                                         line[x] = prevline[x] ^ mix;                                                          MASK_UPDATE();
226                                                         else                                                          if (mask & mixmask)
227                                                         line[x] = prevline[x];);                                                                  line[x] = prevline[x] ^ mix;
228                                                            else
229                                                                    line[x] = prevline[x];
230                                                    )
231                                          }                                          }
232                                          break;                                          break;
   
233                                  case 3: /* Colour */                                  case 3: /* Colour */
234                                          REPEAT(line[x] = colour2);                                          REPEAT(line[x] = colour2)
235                                          break;                                          break;
   
236                                  case 4: /* Copy */                                  case 4: /* Copy */
237                                          REPEAT(line[x] = CVAL(input));                                          REPEAT(line[x] = CVAL(input))
238                                          break;                                          break;
   
239                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
240                                          REPEAT(if (bicolour)                                          REPEAT
241                                                 {                                          (
242                                                 line[x] = colour2; bicolour = False;}                                                  if (bicolour)
243                                                 else                                                  {
244                                                 {                                                          line[x] = colour2;
245                                                 line[x] = colour1; bicolour = True; count++;}                                                          bicolour = False;
246                                          );                                                  }
247                                                    else
248                                                    {
249                                                            line[x] = colour1;
250                                                            bicolour = True; count++;
251                                                    }
252                                            )
253                                          break;                                          break;
   
254                                  case 0xd:       /* White */                                  case 0xd:       /* White */
255                                          REPEAT(line[x] = 0xff);                                          REPEAT(line[x] = 0xff)
256                                          break;                                          break;
   
257                                  case 0xe:       /* Black */                                  case 0xe:       /* Black */
258                                          REPEAT(line[x] = 0x00);                                          REPEAT(line[x] = 0)
259                                          break;                                          break;
   
260                                  default:                                  default:
261                                          unimpl("bitmap opcode 0x%x\n", opcode);                                          unimpl("bitmap opcode 0x%x\n", opcode);
262                                          return False;                                          return False;
263                          }                          }
264                  }                  }
265          }          }
   
266          return True;          return True;
267  }  }
268    
269  BOOL  /* 2 byte bitmap decompress */
270  bitmap_decompress16(unsigned char *output, int width, int height, unsigned char *input, int size)  static BOOL
271    bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size)
272  {  {
273          unsigned char *end = input + size;          uint8 *end = input + size;
274          uint16 *prevline = NULL, *line = NULL;          uint16 *prevline = NULL, *line = NULL;
275          int opcode, count, offset, isfillormix, x = width;          int opcode, count, offset, isfillormix, x = width;
276          int lastopcode = -1, insertmix = False, bicolour = False;          int lastopcode = -1, insertmix = False, bicolour = False;
# Line 266  bitmap_decompress16(unsigned char *outpu Line 285  bitmap_decompress16(unsigned char *outpu
285                  fom_mask = 0;                  fom_mask = 0;
286                  code = CVAL(input);                  code = CVAL(input);
287                  opcode = code >> 4;                  opcode = code >> 4;
288                    /* Handle different opcode forms */
289                    switch (opcode)
290                    {
291                            case 0xc:
292                            case 0xd:
293                            case 0xe:
294                                    opcode -= 6;
295                                    count = code & 0xf;
296                                    offset = 16;
297                                    break;
298                            case 0xf:
299                                    opcode = code & 0xf;
300                                    if (opcode < 9)
301                                    {
302                                            count = CVAL(input);
303                                            count |= CVAL(input) << 8;
304                                    }
305                                    else
306                                    {
307                                            count = (opcode < 0xb) ? 8 : 1;
308                                    }
309                                    offset = 0;
310                                    break;
311                            default:
312                                    opcode >>= 1;
313                                    count = code & 0x1f;
314                                    offset = 32;
315                                    break;
316                    }
317                    /* Handle strange cases for counts */
318                    if (offset != 0)
319                    {
320                            isfillormix = ((opcode == 2) || (opcode == 7));
321                            if (count == 0)
322                            {
323                                    if (isfillormix)
324                                            count = CVAL(input) + 1;
325                                    else
326                                            count = CVAL(input) + offset;
327                            }
328                            else if (isfillormix)
329                            {
330                                    count <<= 3;
331                            }
332                    }
333                    /* Read preliminary data */
334                    switch (opcode)
335                    {
336                            case 0: /* Fill */
337                                    if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
338                                            insertmix = True;
339                                    break;
340                            case 8: /* Bicolour */
341                                    CVAL2(input, colour1);
342                            case 3: /* Colour */
343                                    CVAL2(input, colour2);
344                                    break;
345                            case 6: /* SetMix/Mix */
346                            case 7: /* SetMix/FillOrMix */
347                                    CVAL2(input, mix);
348                                    opcode -= 5;
349                                    break;
350                            case 9: /* FillOrMix_1 */
351                                    mask = 0x03;
352                                    opcode = 0x02;
353                                    fom_mask = 3;
354                                    break;
355                            case 0x0a:      /* FillOrMix_2 */
356                                    mask = 0x05;
357                                    opcode = 0x02;
358                                    fom_mask = 5;
359                                    break;
360                    }
361                    lastopcode = opcode;
362                    mixmask = 0;
363                    /* Output body */
364                    while (count > 0)
365                    {
366                            if (x >= width)
367                            {
368                                    if (height <= 0)
369                                            return False;
370                                    x = 0;
371                                    height--;
372                                    prevline = line;
373                                    line = ((uint16 *) output) + height * width;
374                            }
375                            switch (opcode)
376                            {
377                                    case 0: /* Fill */
378                                            if (insertmix)
379                                            {
380                                                    if (prevline == NULL)
381                                                            line[x] = mix;
382                                                    else
383                                                            line[x] = prevline[x] ^ mix;
384                                                    insertmix = False;
385                                                    count--;
386                                                    x++;
387                                            }
388                                            if (prevline == NULL)
389                                            {
390                                                    REPEAT(line[x] = 0)
391                                            }
392                                            else
393                                            {
394                                                    REPEAT(line[x] = prevline[x])
395                                            }
396                                            break;
397                                    case 1: /* Mix */
398                                            if (prevline == NULL)
399                                            {
400                                                    REPEAT(line[x] = mix)
401                                            }
402                                            else
403                                            {
404                                                    REPEAT(line[x] = prevline[x] ^ mix)
405                                            }
406                                            break;
407                                    case 2: /* Fill or Mix */
408                                            if (prevline == NULL)
409                                            {
410                                                    REPEAT
411                                                    (
412                                                            MASK_UPDATE();
413                                                            if (mask & mixmask)
414                                                                    line[x] = mix;
415                                                            else
416                                                                    line[x] = 0;
417                                                    )
418                                            }
419                                            else
420                                            {
421                                                    REPEAT
422                                                    (
423                                                            MASK_UPDATE();
424                                                            if (mask & mixmask)
425                                                                    line[x] = prevline[x] ^ mix;
426                                                            else
427                                                                    line[x] = prevline[x];
428                                                    )
429                                            }
430                                            break;
431                                    case 3: /* Colour */
432                                            REPEAT(line[x] = colour2)
433                                            break;
434                                    case 4: /* Copy */
435                                            REPEAT(CVAL2(input, line[x]))
436                                            break;
437                                    case 8: /* Bicolour */
438                                            REPEAT
439                                            (
440                                                    if (bicolour)
441                                                    {
442                                                            line[x] = colour2;
443                                                            bicolour = False;
444                                                    }
445                                                    else
446                                                    {
447                                                            line[x] = colour1;
448                                                            bicolour = True;
449                                                            count++;
450                                                    }
451                                            )
452                                            break;
453                                    case 0xd:       /* White */
454                                            REPEAT(line[x] = 0xffff)
455                                            break;
456                                    case 0xe:       /* Black */
457                                            REPEAT(line[x] = 0)
458                                            break;
459                                    default:
460                                            unimpl("bitmap opcode 0x%x\n", opcode);
461                                            return False;
462                            }
463                    }
464            }
465            return True;
466    }
467    
468    /* 3 byte bitmap decompress */
469    static BOOL
470    bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
471    {
472            uint8 *end = input + size;
473            uint8 *prevline = NULL, *line = NULL;
474            int opcode, count, offset, isfillormix, x = width;
475            int lastopcode = -1, insertmix = False, bicolour = False;
476            uint8 code;
477            uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0};
478            uint8 mixmask, mask = 0;
479            uint8 mix[3] = {0xff, 0xff, 0xff};
480            int fom_mask = 0;
481    
482            while (input < end)
483            {
484                    fom_mask = 0;
485                    code = CVAL(input);
486                    opcode = code >> 4;
487                    /* Handle different opcode forms */
488                    switch (opcode)
489                    {
490                            case 0xc:
491                            case 0xd:
492                            case 0xe:
493                                    opcode -= 6;
494                                    count = code & 0xf;
495                                    offset = 16;
496                                    break;
497                            case 0xf:
498                                    opcode = code & 0xf;
499                                    if (opcode < 9)
500                                    {
501                                            count = CVAL(input);
502                                            count |= CVAL(input) << 8;
503                                    }
504                                    else
505                                    {
506                                            count = (opcode <
507                                                     0xb) ? 8 : 1;
508                                    }
509                                    offset = 0;
510                                    break;
511                            default:
512                                    opcode >>= 1;
513                                    count = code & 0x1f;
514                                    offset = 32;
515                                    break;
516                    }
517                    /* Handle strange cases for counts */
518                    if (offset != 0)
519                    {
520                            isfillormix = ((opcode == 2) || (opcode == 7));
521                            if (count == 0)
522                            {
523                                    if (isfillormix)
524                                            count = CVAL(input) + 1;
525                                    else
526                                            count = CVAL(input) + offset;
527                            }
528                            else if (isfillormix)
529                            {
530                                    count <<= 3;
531                            }
532                    }
533                    /* Read preliminary data */
534                    switch (opcode)
535                    {
536                            case 0: /* Fill */
537                                    if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
538                                            insertmix = True;
539                                    break;
540                            case 8: /* Bicolour */
541                                    colour1[0] = CVAL(input);
542                                    colour1[1] = CVAL(input);
543                                    colour1[2] = CVAL(input);
544                            case 3: /* Colour */
545                                    colour2[0] = CVAL(input);
546                                    colour2[1] = CVAL(input);
547                                    colour2[2] = CVAL(input);
548                                    break;
549                            case 6: /* SetMix/Mix */
550                            case 7: /* SetMix/FillOrMix */
551                                    mix[0] = CVAL(input);
552                                    mix[1] = CVAL(input);
553                                    mix[2] = CVAL(input);
554                                    opcode -= 5;
555                                    break;
556                            case 9: /* FillOrMix_1 */
557                                    mask = 0x03;
558                                    opcode = 0x02;
559                                    fom_mask = 3;
560                                    break;
561                            case 0x0a:      /* FillOrMix_2 */
562                                    mask = 0x05;
563                                    opcode = 0x02;
564                                    fom_mask = 5;
565                                    break;
566                    }
567                    lastopcode = opcode;
568                    mixmask = 0;
569                    /* Output body */
570                    while (count > 0)
571                    {
572                            if (x >= width)
573                            {
574                                    if (height <= 0)
575                                            return False;
576                                    x = 0;
577                                    height--;
578                                    prevline = line;
579                                    line = output + height * (width * 3);
580                            }
581                            switch (opcode)
582                            {
583                                    case 0: /* Fill */
584                                            if (insertmix)
585                                            {
586                                                    if (prevline == NULL)
587                                                    {
588                                                            line[x * 3] = mix[0];
589                                                            line[x * 3 + 1] = mix[1];
590                                                            line[x * 3 + 2] = mix[2];
591                                                    }
592                                                    else
593                                                    {
594                                                            line[x * 3] =
595                                                             prevline[x * 3] ^ mix[0];
596                                                            line[x * 3 + 1] =
597                                                             prevline[x * 3 + 1] ^ mix[1];
598                                                            line[x * 3 + 2] =
599                                                             prevline[x * 3 + 2] ^ mix[2];
600                                                    }
601                                                    insertmix = False;
602                                                    count--;
603                                                    x++;
604                                            }
605                                            if (prevline == NULL)
606                                            {
607                                                    REPEAT
608                                                    (
609                                                            line[x * 3] = 0;
610                                                            line[x * 3 + 1] = 0;
611                                                            line[x * 3 + 2] = 0;
612                                                    )
613                                            }
614                                            else
615                                            {
616                                                    REPEAT
617                                                    (
618                                                            line[x * 3] = prevline[x * 3];
619                                                            line[x * 3 + 1] = prevline[x * 3 + 1];
620                                                            line[x * 3 + 2] = prevline[x * 3 + 2];
621                                                    )
622                                            }
623                                            break;
624                                    case 1: /* Mix */
625                                            if (prevline == NULL)
626                                            {
627                                                    REPEAT
628                                                    (
629                                                            line[x * 3] = mix[0];
630                                                            line[x * 3 + 1] = mix[1];
631                                                            line[x * 3 + 2] = mix[2];
632                                                    )
633                                            }
634                                            else
635                                            {
636                                                    REPEAT
637                                                    (
638                                                            line[x * 3] =
639                                                             prevline[x * 3] ^ mix[0];
640                                                            line[x * 3 + 1] =
641                                                             prevline[x * 3 + 1] ^ mix[1];
642                                                            line[x * 3 + 2] =
643                                                             prevline[x * 3 + 2] ^ mix[2];
644                                                    )
645                                            }
646                                            break;
647                                    case 2: /* Fill or Mix */
648                                            if (prevline == NULL)
649                                            {
650                                                    REPEAT
651                                                    (
652                                                            MASK_UPDATE();
653                                                            if (mask & mixmask)
654                                                            {
655                                                                    line[x * 3] = mix[0];
656                                                                    line[x * 3 + 1] = mix[1];
657                                                                    line[x * 3 + 2] = mix[2];
658                                                            }
659                                                            else
660                                                            {
661                                                                    line[x * 3] = 0;
662                                                                    line[x * 3 + 1] = 0;
663                                                                    line[x * 3 + 2] = 0;
664                                                            }
665                                                    )
666                                            }
667                                            else
668                                            {
669                                                    REPEAT
670                                                    (
671                                                            MASK_UPDATE();
672                                                            if (mask & mixmask)
673                                                            {
674                                                                    line[x * 3] =
675                                                                     prevline[x * 3] ^ mix [0];
676                                                                    line[x * 3 + 1] =
677                                                                     prevline[x * 3 + 1] ^ mix [1];
678                                                                    line[x * 3 + 2] =
679                                                                     prevline[x * 3 + 2] ^ mix [2];
680                                                            }
681                                                            else
682                                                            {
683                                                                    line[x * 3] =
684                                                                     prevline[x * 3];
685                                                                    line[x * 3 + 1] =
686                                                                     prevline[x * 3 + 1];
687                                                                    line[x * 3 + 2] =
688                                                                     prevline[x * 3 + 2];
689                                                            }
690                                                    )
691                                            }
692                                            break;
693                                    case 3: /* Colour */
694                                            REPEAT
695                                            (
696                                                    line[x * 3] = colour2 [0];
697                                                    line[x * 3 + 1] = colour2 [1];
698                                                    line[x * 3 + 2] = colour2 [2];
699                                            )
700                                            break;
701                                    case 4: /* Copy */
702                                            REPEAT
703                                            (
704                                                    line[x * 3] = CVAL(input);
705                                                    line[x * 3 + 1] = CVAL(input);
706                                                    line[x * 3 + 2] = CVAL(input);
707                                            )
708                                            break;
709                                    case 8: /* Bicolour */
710                                            REPEAT
711                                            (
712                                                    if (bicolour)
713                                                    {
714                                                            line[x * 3] = colour2[0];
715                                                            line[x * 3 + 1] = colour2[1];
716                                                            line[x * 3 + 2] = colour2[2];
717                                                            bicolour = False;
718                                                    }
719                                                    else
720                                                    {
721                                                            line[x * 3] = colour1[0];
722                                                            line[x * 3 + 1] = colour1[1];
723                                                            line[x * 3 + 2] = colour1[2];
724                                                            bicolour = True;
725                                                            count++;
726                                                    }
727                                            )
728                                            break;
729                                    case 0xd:       /* White */
730                                            REPEAT
731                                            (
732                                                    line[x * 3] = 0xff;
733                                                    line[x * 3 + 1] = 0xff;
734                                                    line[x * 3 + 2] = 0xff;
735                                            )
736                                            break;
737                                    case 0xe:       /* Black */
738                                            REPEAT
739                                            (
740                                                    line[x * 3] = 0;
741                                                    line[x * 3 + 1] = 0;
742                                                    line[x * 3 + 2] = 0;
743                                            )
744                                            break;
745                                    default:
746                                            unimpl("bitmap opcode 0x%x\n", opcode);
747                                            return False;
748                            }
749                    }
750            }
751            return True;
752    }
753    
754    #else
755    
756    static uint32
757    cvalx(uint8 **input, int Bpp)
758    {
759            uint32 rv = 0;
760            memcpy(&rv, *input, Bpp);
761            *input += Bpp;
762            return rv;
763    }
764    
765    static void
766    setli(uint8 *input, int offset, uint32 value, int Bpp)
767    {
768            input += offset * Bpp;
769            memcpy(input, &value, Bpp);
770    }
771    
772    static uint32
773    getli(uint8 *input, int offset, int Bpp)
774    {
775            uint32 rv = 0;
776            input += offset * Bpp;
777            memcpy(&rv, input, Bpp);
778            return rv;
779    }
780    
781    static BOOL
782    bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
783    {
784            uint8 *end = input + size;
785            uint8 *prevline = NULL, *line = NULL;
786            int opcode, count, offset, isfillormix, x = width;
787            int lastopcode = -1, insertmix = False, bicolour = False;
788            uint8 code;
789            uint32 colour1 = 0, colour2 = 0;
790            uint8 mixmask, mask = 0;
791            uint32 mix = 0xffffffff;
792            int fom_mask = 0;
793    
794            while (input < end)
795            {
796                    fom_mask = 0;
797                    code = CVAL(input);
798                    opcode = code >> 4;
799    
800                  /* Handle different opcode forms */                  /* Handle different opcode forms */
801                  switch (opcode)                  switch (opcode)
# Line 287  bitmap_decompress16(unsigned char *outpu Line 817  bitmap_decompress16(unsigned char *outpu
817                                  }                                  }
818                                  else                                  else
819                                  {                                  {
820                                          count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit                                          count = (opcode < 0xb) ? 8 : 1;
821                                  }                                  }
822                                  offset = 0;                                  offset = 0;
823                                  break;                                  break;
# Line 325  bitmap_decompress16(unsigned char *outpu Line 855  bitmap_decompress16(unsigned char *outpu
855                                          insertmix = True;                                          insertmix = True;
856                                  break;                                  break;
857                          case 8: /* Bicolour */                          case 8: /* Bicolour */
858                                  colour1 = CVAL16(input);                                  colour1 = cvalx(&input, Bpp);
859                          case 3: /* Colour */                          case 3: /* Colour */
860                                  colour2 = CVAL16(input);                                  colour2 = cvalx(&input, Bpp);
861                                  break;                                  break;
862                          case 6: /* SetMix/Mix */                          case 6: /* SetMix/Mix */
863                          case 7: /* SetMix/FillOrMix */                          case 7: /* SetMix/FillOrMix */
864                                  mix = CVAL16(input);                                  mix = cvalx(&input, Bpp);
865                                  opcode -= 5;                                  opcode -= 5;
866                                  break;                                  break;
867                          case 9: /* FillOrMix_1 */                          case 9: /* FillOrMix_1 */
# Line 362  bitmap_decompress16(unsigned char *outpu Line 892  bitmap_decompress16(unsigned char *outpu
892                                  height--;                                  height--;
893    
894                                  prevline = line;                                  prevline = line;
895                                  line = (uint16*)output + height * width;                                  line = output + height * width * Bpp;
896                          }                          }
897    
898                          switch (opcode)                          switch (opcode)
# Line 371  bitmap_decompress16(unsigned char *outpu Line 901  bitmap_decompress16(unsigned char *outpu
901                                          if (insertmix)                                          if (insertmix)
902                                          {                                          {
903                                                  if (prevline == NULL)                                                  if (prevline == NULL)
904                                                          line[x] = mix;                                                          setli(line, x, mix, Bpp);
905                                                  else                                                  else
906                                                          line[x] = prevline[x] ^ mix;                                                          setli(line, x,
907                                                                  getli(prevline, x, Bpp) ^ mix, Bpp);
908    
909                                                  insertmix = False;                                                  insertmix = False;
910                                                  count--;                                                  count--;
# Line 382  bitmap_decompress16(unsigned char *outpu Line 913  bitmap_decompress16(unsigned char *outpu
913    
914                                          if (prevline == NULL)                                          if (prevline == NULL)
915                                          {                                          {
916                                                  REPEAT(line[x] = 0);                                          REPEAT(setli(line, x, 0, Bpp))}
                                         }  
917                                          else                                          else
918                                          {                                          {
919                                                  REPEAT(line[x] = prevline[x]);                                                  REPEAT(setli
920                                                           (line, x, getli(prevline, x, Bpp), Bpp));
921                                          }                                          }
922                                          break;                                          break;
923    
924                                  case 1: /* Mix */                                  case 1: /* Mix */
925                                          if (prevline == NULL)                                          if (prevline == NULL)
926                                          {                                          {
927                                                  REPEAT(line[x] = mix);                                                  REPEAT(setli(line, x, mix, Bpp));
928                                          }                                          }
929                                          else                                          else
930                                          {                                          {
931                                                  REPEAT(line[x] = prevline[x] ^ mix);                                                  REPEAT(setli
932                                                           (line, x, getli(prevline, x, Bpp) ^ mix,
933                                                            Bpp));
934                                          }                                          }
935                                          break;                                          break;
936    
# Line 405  bitmap_decompress16(unsigned char *outpu Line 938  bitmap_decompress16(unsigned char *outpu
938                                          if (prevline == NULL)                                          if (prevline == NULL)
939                                          {                                          {
940                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
941                                                         if (mask & mixmask) line[x] = mix;                                                         if (mask & mixmask) setli(line, x, mix, Bpp);
942                                                         else                                                         else
943                                                         line[x] = 0;);                                                         setli(line, x, 0, Bpp););
944                                          }                                          }
945                                          else                                          else
946                                          {                                          {
947                                                  REPEAT(MASK_UPDATE();                                                  REPEAT(MASK_UPDATE();
948                                                         if (mask & mixmask)                                                         if (mask & mixmask)
949                                                         line[x] = prevline[x] ^ mix;                                                         setli(line, x, getli(prevline, x, Bpp) ^ mix,
950                                                                 Bpp);
951                                                         else                                                         else
952                                                         line[x] = prevline[x];);                                                         setli(line, x, getli(prevline, x, Bpp),
953                                                                 Bpp););
954                                          }                                          }
955                                          break;                                          break;
956    
957                                  case 3: /* Colour */                                  case 3: /* Colour */
958                                          REPEAT(line[x] = colour2);                                          REPEAT(setli(line, x, colour2, Bpp));
959                                          break;                                          break;
960    
961                                  case 4: /* Copy */                                  case 4: /* Copy */
962                                          REPEAT(line[x] = CVAL16(input));                                          REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
963                                          break;                                          break;
964    
965                                  case 8: /* Bicolour */                                  case 8: /* Bicolour */
966                                          REPEAT(if (bicolour)                                          REPEAT(if (bicolour)
967                                                 {                                                 {
968                                                 line[x] = colour2; bicolour = False;}                                                 setli(line, x, colour2, Bpp); bicolour = False;}
969                                                 else                                                 else
970                                                 {                                                 {
971                                                 line[x] = colour1; bicolour = True; count++;}                                                 setli(line, x, colour1, Bpp); bicolour = True;
972                                                   count++;}
973                                          );                                          );
974                                          break;                                          break;
975    
976                                  case 0xd:       /* White */                                  case 0xd:       /* White */
977                                          REPEAT(line[x] = 0xffff);                                          REPEAT(setli(line, x, 0xffffffff, Bpp));
978                                          break;                                          break;
979    
980                                  case 0xe:       /* Black */                                  case 0xe:       /* Black */
981                                          REPEAT(line[x] = 0x00);                                          REPEAT(setli(line, x, 0, Bpp));
982                                          break;                                          break;
983    
984                                  default:                                  default:
# Line 455  bitmap_decompress16(unsigned char *outpu Line 991  bitmap_decompress16(unsigned char *outpu
991          return True;          return True;
992  }  }
993    
994    #endif
995    
996    /* main decompress function */
997  BOOL  BOOL
998  bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int bpp)  bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp)
999  {  {
1000          if (bpp == 8)  #ifdef BITMAP_SPEED_OVER_SIZE
1001                  return bitmap_decompress8(output, width, height, input, size);          BOOL rv = False;
1002          else if (bpp == 16)          switch (Bpp)
1003                  return bitmap_decompress16(output, width, height, input, size);          {
1004          else                  case 1:
1005                  return False;                          rv = bitmap_decompress1(output, width, height, input, size);
1006                            break;
1007                    case 2:
1008                            rv = bitmap_decompress2(output, width, height, input, size);
1009                            break;
1010                    case 3:
1011                            rv = bitmap_decompress3(output, width, height, input, size);
1012                            break;
1013            }
1014    #else
1015            BOOL rv;
1016      rv = bitmap_decompressx(output, width, height, input, size, Bpp);
1017    #endif
1018            return rv;
1019  }  }
1020    
1021    /* *INDENT-ON* */

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

  ViewVC Help
Powered by ViewVC 1.1.26