/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/bitmap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 207 by matthewc, Thu Sep 26 14:26:46 2002 UTC revision 309 by jsorg71, Tue Feb 4 05:32:13 2003 UTC
# Line 2  Line 2 
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-2002
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Line 21  Line 21 
21  #include "rdesktop.h"  #include "rdesktop.h"
22    
23  #define CVAL(p)   (*(p++))  #define CVAL(p)   (*(p++))
24    #define CVAL16(p) (*(((uint16*)p)++))
25    
26  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }  #define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
27    
# Line 43  Line 44 
44  }  }
45    
46  BOOL  BOOL
47  bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size)  bitmap_decompress8(unsigned char *output, int width, int height, unsigned char *input, int size)
48  {  {
49          unsigned char *end = input + size;          unsigned char *end = input + size;
50          unsigned char *prevline = NULL, *line = NULL;          unsigned char *prevline = NULL, *line = NULL;
# Line 246  bitmap_decompress(unsigned char *output, Line 247  bitmap_decompress(unsigned char *output,
247    
248          return True;          return True;
249  }  }
250    
251    BOOL
252    bitmap_decompress16(unsigned char *output, int width, int height, unsigned char *input, int size)
253    {
254            unsigned char *end = input + size;
255            uint16 *prevline = NULL, *line = NULL;
256            int opcode, count, offset, isfillormix, x = width;
257            int lastopcode = -1, insertmix = False, bicolour = False;
258            uint8 code;
259            uint16 colour1 = 0, colour2 = 0;
260            uint8 mixmask, mask = 0;
261            uint16 mix = 0xffff;
262            int fom_mask = 0;
263    
264            while (input < end)
265            {
266                    fom_mask = 0;
267                    code = CVAL(input);
268                    opcode = code >> 4;
269    
270                    /* Handle different opcode forms */
271                    switch (opcode)
272                    {
273                            case 0xc:
274                            case 0xd:
275                            case 0xe:
276                                    opcode -= 6;
277                                    count = code & 0xf;
278                                    offset = 16;
279                                    break;
280    
281                            case 0xf:
282                                    opcode = code & 0xf;
283                                    if (opcode < 9)
284                                    {
285                                            count = CVAL(input);
286                                            count |= CVAL(input) << 8;
287                                    }
288                                    else
289                                    {
290                                            count = (opcode < 0xd) ? 8 : 1; // was 0xb in 8 bit
291                                    }
292                                    offset = 0;
293                                    break;
294    
295                            default:
296                                    opcode >>= 1;
297                                    count = code & 0x1f;
298                                    offset = 32;
299                                    break;
300                    }
301    
302                    /* Handle strange cases for counts */
303                    if (offset != 0)
304                    {
305                            isfillormix = ((opcode == 2) || (opcode == 7));
306    
307                            if (count == 0)
308                            {
309                                    if (isfillormix)
310                                            count = CVAL(input) + 1;
311                                    else
312                                            count = CVAL(input) + offset;
313                            }
314                            else if (isfillormix)
315                            {
316                                    count <<= 3;
317                            }
318                    }
319    
320                    /* Read preliminary data */
321                    switch (opcode)
322                    {
323                            case 0: /* Fill */
324                                    if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
325                                            insertmix = True;
326                                    break;
327                            case 8: /* Bicolour */
328                                    colour1 = CVAL16(input);
329                            case 3: /* Colour */
330                                    colour2 = CVAL16(input);
331                                    break;
332                            case 6: /* SetMix/Mix */
333                            case 7: /* SetMix/FillOrMix */
334                                    mix = CVAL16(input);
335                                    opcode -= 5;
336                                    break;
337                            case 9: /* FillOrMix_1 */
338                                    mask = 0x03;
339                                    opcode = 0x02;
340                                    fom_mask = 3;
341                                    break;
342                            case 0x0a:      /* FillOrMix_2 */
343                                    mask = 0x05;
344                                    opcode = 0x02;
345                                    fom_mask = 5;
346                                    break;
347    
348                    }
349    
350                    lastopcode = opcode;
351                    mixmask = 0;
352    
353                    /* Output body */
354                    while (count > 0)
355                    {
356                            if (x >= width)
357                            {
358                                    if (height <= 0)
359                                            return False;
360    
361                                    x = 0;
362                                    height--;
363    
364                                    prevline = line;
365                                    line = (uint16*)output + height * width;
366                            }
367    
368                            switch (opcode)
369                            {
370                                    case 0: /* Fill */
371                                            if (insertmix)
372                                            {
373                                                    if (prevline == NULL)
374                                                            line[x] = mix;
375                                                    else
376                                                            line[x] = prevline[x] ^ mix;
377    
378                                                    insertmix = False;
379                                                    count--;
380                                                    x++;
381                                            }
382    
383                                            if (prevline == NULL)
384                                            {
385                                                    REPEAT(line[x] = 0);
386                                            }
387                                            else
388                                            {
389                                                    REPEAT(line[x] = prevline[x]);
390                                            }
391                                            break;
392    
393                                    case 1: /* Mix */
394                                            if (prevline == NULL)
395                                            {
396                                                    REPEAT(line[x] = mix);
397                                            }
398                                            else
399                                            {
400                                                    REPEAT(line[x] = prevline[x] ^ mix);
401                                            }
402                                            break;
403    
404                                    case 2: /* Fill or Mix */
405                                            if (prevline == NULL)
406                                            {
407                                                    REPEAT(MASK_UPDATE();
408                                                           if (mask & mixmask) line[x] = mix;
409                                                           else
410                                                           line[x] = 0;);
411                                            }
412                                            else
413                                            {
414                                                    REPEAT(MASK_UPDATE();
415                                                           if (mask & mixmask)
416                                                           line[x] = prevline[x] ^ mix;
417                                                           else
418                                                           line[x] = prevline[x];);
419                                            }
420                                            break;
421    
422                                    case 3: /* Colour */
423                                            REPEAT(line[x] = colour2);
424                                            break;
425    
426                                    case 4: /* Copy */
427                                            REPEAT(line[x] = CVAL16(input));
428                                            break;
429    
430                                    case 8: /* Bicolour */
431                                            REPEAT(if (bicolour)
432                                                   {
433                                                   line[x] = colour2; bicolour = False;}
434                                                   else
435                                                   {
436                                                   line[x] = colour1; bicolour = True; count++;}
437                                            );
438                                            break;
439    
440                                    case 0xd:       /* White */
441                                            REPEAT(line[x] = 0xffff);
442                                            break;
443    
444                                    case 0xe:       /* Black */
445                                            REPEAT(line[x] = 0x00);
446                                            break;
447    
448                                    default:
449                                            unimpl("bitmap opcode 0x%x\n", opcode);
450                                            return False;
451                            }
452                    }
453            }
454    
455            return True;
456    }
457    
458    BOOL
459    bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size, int bpp)
460    {
461            if (bpp == 8)
462                    return bitmap_decompress8(output, width, height, input, size);
463            else if (bpp == 16)
464                    return bitmap_decompress16(output, width, height, input, size);
465            else
466                    return False;
467    }

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

  ViewVC Help
Powered by ViewVC 1.1.26