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

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

  ViewVC Help
Powered by ViewVC 1.1.26