/[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 6 by matty, Wed May 10 07:36:34 2000 UTC revision 7 by matty, Fri Jul 7 09:40:03 2000 UTC
# Line 19  Line 19 
19  */  */
20    
21  #include "includes.h"  #include "includes.h"
 #include <fcntl.h>  
22    
23  #define BITMAP_DEBUG 1  #define CVAL(p)   (*(p++))
24    #define SVAL(p)   ((*((p++) + 1) << 8) | CVAL(p))
25    
26  #if BITMAP_DEBUG  #define REPEAT(statement) { while ((count > 0) && (x < width)) { statement; count--; x++; } }
27  void hexdump(char *filename, unsigned char *data, int length);  #define MASK_UPDATE() { maskpix <<= 1; if (maskpix == 0) { mask = CVAL(input); maskpix = 1; } }
 #endif  
   
 #define RCVAL()   (*(input++))  
 #define RSVAL()   ((*((input++) + 1) << 8) | RCVAL())  
 #define SCVAL(v)  {*(output++) = (v);}  
   
 #define FILL()    {while (n-- > 0) { if (output - start < width) { SCVAL(0) } else { SCVAL(*(output-width)); }}}  
 #define MIX()     {while (n-- > 0) { if (output - start < width) { SCVAL(mix) } else { SCVAL(*(output-width) ^ mix); }}}  
 #define COPY()    {while (n-- > 0) { SCVAL(RCVAL()); }}  
 #define COLOR()   {int color = RCVAL(); \  
                    while (n-- > 0) { SCVAL(color); }}  
 #define BICOLOR() {int color1 = RCVAL(); int color2 = RCVAL(); \  
                    while (n-- > 0) { SCVAL(color1); SCVAL(color2); }}  
 #define SETMIX_MIX() {mix = RCVAL(); MIX();}  
 #define COPY_PACKED() {n++; n/=2; while (n-- > 0) \  
                       {unsigned char c = RCVAL(); SCVAL((c & 0xF0) >> 4); \  
                                                   SCVAL(c & 0x0F); }}  
28    
29  BOOL bitmap_decompress(unsigned char *input, int size,  BOOL bitmap_decompress(unsigned char *output, int width, int height,
30                         unsigned char *output, int width)                         unsigned char *input, int size)
31  {  {
         unsigned char *savedinput = input;  
         unsigned char *start = output;  
32          unsigned char *end = input + size;          unsigned char *end = input + size;
33          unsigned char code;          unsigned char *prevline, *line = NULL;
34          unsigned char mix = 0xFF;          int opcode, count, offset, isfillormix, x = width;
35          int n, savedn;          uint8 code, mask, maskpix, color1, color2;
36            uint8 mix = 0xff;
37    
38            dump_data(input, end-input);
39          while (input < end)          while (input < end)
40          {          {
41                  code = RCVAL();                  fprintf(stderr, "Offset %d from end\n", end-input);
42                  switch (code)                  code = CVAL(input);
43                    opcode = code >> 4;
44    
45                    /* Handle different opcode forms */
46                    switch (opcode)
47                    {
48                            case 0xc:
49                            case 0xd:
50                            case 0xe:
51                                    opcode -= 6;
52                                    count = code & 0xf;
53                                    offset = 16;
54                                    break;
55    
56                            case 0xf:
57                                    opcode = code & 0xf;
58                                    count = (opcode < 13) ? SVAL(input) : 1;
59                                    offset = 0;
60                                    break;
61    
62                            default:
63                                    opcode >>= 1;
64                                    count = code & 0x1f;
65                                    offset = 32;
66                                    break;
67                    }
68    
69                    /* Handle strange cases for counts */
70                    if (offset != 0)
71                  {                  {
72                  case 0x00: // Fill                          isfillormix = ((opcode == 2) || (opcode == 7));
                         n = RCVAL() + 32;  
                         FILL();  
                         break;  
                 case 0xF0: // Fill  
                         n = RSVAL();  
                         FILL();  
                         break;  
                 case 0x20: // Mix  
                         n = RCVAL() + 32;  
                         MIX();  
                         break;  
                 case 0xF1: // Mix  
                         n = RSVAL();  
                         MIX();  
                         break;  
                 case 0x40: // FillOrMix  
                         fprintf(stderr, "FillOrMix unsupported\n");  
                         savedn = n = RCVAL() + 1;  
                         MIX();  
                         input += (savedn+7)/8;  
                         break;  
                 case 0xF2:  
                         fprintf(stderr, "FillOrMix unsupported\n");  
                         savedn = n = RSVAL();  
                         MIX();  
                         input += (savedn+7)/8;  
                         break;  
                 case 0x60: // Color  
                         n = RCVAL() + 32;  
                         COLOR();  
                         break;  
                 case 0xF3:  
                         n = RSVAL();  
                         fprintf(stderr, "Color %d\n", n);  
                         COLOR();  
                         break;  
                 case 0x80: // Copy  
                         n = RCVAL() + 32;  
                         COPY();  
                         break;  
                 case 0xF4:  
                         n = RSVAL();  
                         COPY();  
                         break;  
                 case 0xA0: // Copy Packed  
                         fprintf(stderr, "CopyPacked 1\n");  
                         n = RCVAL() + 32;  
                         COPY_PACKED();  
                         break;  
                 case 0xF5:  
                         fprintf(stderr, "CopyPacked 2\n");  
                         n = RSVAL();  
                         COPY_PACKED();  
                         break;  
                 case 0xC0: // SetMix_Mix  
                         fprintf(stderr, "SetMix_Mix 1\n");  
                         n = RCVAL() + 16;  
                         SETMIX_MIX();  
                         break;  
                 case 0xF6:  
                         fprintf(stderr, "SetMix_Mix 2\n");  
                         n = RSVAL();  
                         SETMIX_MIX();  
                         break;  
                 case 0xD0: // SetMix_FillOrMix  
                         fprintf(stderr, "SetMix_FillOrMix unsupported\n");  
                         savedn = n = RCVAL() + 1;  
                         SETMIX_MIX();  
                         input += (savedn+7)/8;  
                         break;  
                 case 0xF7:  
                         fprintf(stderr, "SetMix_FillOrMix unsupported\n");  
                         savedn = n = RSVAL();  
                         SETMIX_MIX();  
                         input += (savedn+7)/8;  
                         break;  
                 case 0xE0: // Bicolor  
                         fprintf(stderr, "Bicolor 1\n");  
                         n = RCVAL() + 16;  
                         BICOLOR();  
                         break;  
                 case 0xF8:  
                         fprintf(stderr, "Bicolor 2\n");  
                         n = RSVAL();  
                         BICOLOR();  
                         break;  
                 case 0xF9: // FillOrMix_1  
                         fprintf(stderr, "FillOrMix_1 unsupported\n");  
                         return False;  
                 case 0xFA: // FillOrMix_2  
                         fprintf(stderr, "FillOrMix_2 unsupported\n");  
                         return False;  
                 case 0xFD: // White  
                         SCVAL(0xFF);  
                         break;  
                 case 0xFE: // Black  
                         SCVAL(0);  
                         break;  
                 default:  
                         n = code & 31;  
73    
74                          if (n == 0)                          if (count == 0)
75                          {                          {
76                                  fprintf(stderr, "Undefined escape 0x%X\n", code);                                  if (isfillormix)
77                                  return False;                                          count = CVAL(input) + 1;
78                                    else
79                                            count = CVAL(input) + offset;
80                          }                          }
81                            else if (isfillormix)
                         switch ((code >> 5) & 7)  
82                          {                          {
83                          case 0: // Fill                                  count <<= 3;
                                 FILL();  
                                 break;  
                         case 1: // Mix  
                                 MIX();  
                                 break;  
                         case 2: // FillOrMix  
                                 fprintf(stderr, "FillOrMix unsupported\n");  
                                 n *= 8;  
                                 savedn = n;  
                                 MIX();  
                                 input += (savedn+7)/8;  
                                 break;  
                         case 3: // Color  
                                 COLOR();  
                                 break;  
                         case 4: // Copy  
                                 COPY();  
                                 break;  
                         case 5: // Copy Packed  
                                 fprintf(stderr, "CopyPacked 3\n");  
                                 COPY_PACKED();  
                                 break;  
                         case 6:  
                                 n = code & 15;  
   
                                 switch ((code >> 4) & 15)  
                                 {  
                                 case 0xC:  
                                         fprintf(stderr, "SetMix_Mix 3\n");  
                                         SETMIX_MIX();  
                                         break;  
                                 case 0xD:  
                                         fprintf(stderr, "SetMix_FillOrMix unsupported\n");  
                                         n *= 8;  
                                         savedn = n;  
                                         SETMIX_MIX();  
                                         input += (savedn+7)/8;  
                                         break;  
                                 case 0xE:  
                                         fprintf(stderr, "Bicolor 3\n");  
                                         BICOLOR();  
                                         break;  
                                 default:  
                                         fprintf(stderr, "Undefined escape 0x%X\n", code);  
                                         return False;  
                                 }  
84                          }                          }
85                  }                  }
         }  
86    
87          printf("Uncompressed size: %d\n", output - start);                  /* Read preliminary data */
88  #if BITMAP_DEBUG                  maskpix = 0;
89          {                  switch (opcode)
90                  static int bmpno = 1;                  {
91                  char filename[64];                          case 3: /* Color */
92                                    color1 = CVAL(input);
93                            case 8: /* Bicolor */
94                                    color2 = CVAL(input);
95                                    break;
96                            case 6: /* SetMix/Mix */
97                            case 7: /* SetMix/FillOrMix */
98                                    mix = CVAL(input);
99                                    opcode -= 5;
100                                    break;
101                    }
102    
103                  snprintf(filename, sizeof(filename)-1, "in%d.raw", bmpno);                  /* Output body */
104                  hexdump(filename, savedinput, size);                  while (count > 0)
105                    {
106                            if (x >= width)
107                            {
108                                    if (height <= 0)
109                                            return True;
110    
111                  snprintf(filename, sizeof(filename)-1, "out%d.raw", bmpno);                                  x = 0;
112                  hexdump(filename, start, output-start);                                  height--;
113    
114                  bmpno++;                                  prevline = line;
115          }                                  line = output + height * width;
116                            }
117    
118                            switch (opcode)
119                            {
120                                    case 0: /* Fill */
121                                            fprintf(stderr, "Fill %d\n", count);
122                                            if (prevline == NULL)
123                                                    REPEAT(line[x] = 0)
124                                            else
125                                                    REPEAT(line[x] = prevline[x])
126                                            break;
127    
128                                    case 1: /* Mix */
129                                            fprintf(stderr, "Mix %d\n", count);
130                                            if (prevline == NULL)
131                                                    REPEAT(line[x] = mix)
132                                            else
133                                                    REPEAT(line[x] = prevline[x] ^ mix)
134                                            break;
135    
136    #if 0
137                                    case 2: /* Fill or Mix */
138                                            REPEAT(line[x] = 0);
139                                            break;
140                                            if (prevline == NULL)
141                                                REPEAT(
142                                                       MASK_UPDATE();
143    
144                                                       if (mask & maskpix)
145                                                            line[x] = mix;
146                                                       else
147                                                            line[x] = 0;
148                                                )
149                                            else
150                                                REPEAT(
151                                                       MASK_UPDATE();
152    
153                                                       if (mask & maskpix)
154                                                            line[x] = prevline[x] ^ mix;
155                                                       else
156                                                            line[x] = prevline[x];
157                                                )
158                                            break;
159  #endif  #endif
160    
161          return True;                                  case 3: /* Colour */
162  }                                          fprintf(stderr, "Colour %d\n", count);
163                                            REPEAT(line[x] = color2)
164                                            break;
165    
166                                    case 4: /* Copy */
167                                            fprintf(stderr, "Copy %d\n", count);
168                                            REPEAT(line[x] = CVAL(input))
169                                            break;
170    
171  #if BITMAP_DEBUG  #if 0
172  void hexdump(char *filename, unsigned char *data, int length)                                  case 8: /* Bicolor */
173  {                                          REPEAT(line[x] = color1; line[++x] = color2)
174          /*                                          break;
         int i;  
175    
176          for (i = 0; i < length; i++)                                  case 13: /* White */
177          {                                          REPEAT(line[x] = 0xff)
178                  printf("%02X ", data[i]);                                          break;
179    
180                  if (i % 16 == 15)                                  case 14: /* Black */
181                          printf("\n");                                          REPEAT(line[x] = 0x00)
182          }                                          break;
183          */  #endif
184    
185          int fd;                                  default:
186                                            fprintf(stderr, "Unknown bitmap opcode 0x%x\n", opcode);
187                                            return False;
188                            }
189                    }
190            }
191    
192          fd = open(filename, O_WRONLY|O_CREAT, 0600);          return True;
         write(fd, data, length);  
         close(fd);  
193  }  }
 #endif  

Legend:
Removed from v.6  
changed lines
  Added in v.7

  ViewVC Help
Powered by ViewVC 1.1.26