summaryrefslogtreecommitdiffstats
path: root/rdp/rdp_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'rdp/rdp_bitmap.c')
-rw-r--r--rdp/rdp_bitmap.c1743
1 files changed, 907 insertions, 836 deletions
diff --git a/rdp/rdp_bitmap.c b/rdp/rdp_bitmap.c
index f2d31dae..adba5f6f 100644
--- a/rdp/rdp_bitmap.c
+++ b/rdp/rdp_bitmap.c
@@ -1,24 +1,22 @@
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2005-2010
-
- librdp bitmap routines
-
-*/
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2004-2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * librdp bitmap routines
+ */
#include "rdp.h"
@@ -35,891 +33,964 @@
/******************************************************************************/
#define REPEAT(statement) \
-{ \
- while ((count > 0) && (x < width)) \
- { \
- statement; \
- count--; \
- x++; \
- } \
-}
+ { \
+ while ((count > 0) && (x < width)) \
+ { \
+ statement; \
+ count--; \
+ x++; \
+ } \
+ }
/******************************************************************************/
#define MASK_UPDATE \
-{ \
- mixmask <<= 1; \
- if ((mixmask & 0xff) == 0) \
- { \
- mask = fom_mask ? fom_mask : CVAL(input); \
- mixmask = 1; \
- } \
-}
+ { \
+ mixmask <<= 1; \
+ if ((mixmask & 0xff) == 0) \
+ { \
+ mask = fom_mask ? fom_mask : CVAL(input); \
+ mixmask = 1; \
+ } \
+ }
/******************************************************************************/
/* 1 byte bitmap decompress */
/* returns boolean */
static int APP_CC
-bitmap_decompress1(char* output, int width, int height, char* input, int size)
+bitmap_decompress1(char *output, int width, int height, char *input, int size)
{
- char* prevline;
- char* line;
- char* end;
- char color1;
- char color2;
- char mix;
- int code;
- int mixmask;
- int mask;
- int opcode;
- int count;
- int offset;
- int isfillormix;
- int x;
- int lastopcode;
- int insertmix;
- int bicolor;
- int fom_mask;
-
- end = input + size;
- prevline = 0;
- line = 0;
- x = width;
- lastopcode = -1;
- insertmix = 0;
- bicolor = 0;
- color1 = 0;
- color2 = 0;
- mix = 0xff;
- mask = 0;
- fom_mask = 0;
-
- while (input < end)
- {
+ char *prevline;
+ char *line;
+ char *end;
+ char color1;
+ char color2;
+ char mix;
+ int code;
+ int mixmask;
+ int mask;
+ int opcode;
+ int count;
+ int offset;
+ int isfillormix;
+ int x;
+ int lastopcode;
+ int insertmix;
+ int bicolor;
+ int fom_mask;
+
+ end = input + size;
+ prevline = 0;
+ line = 0;
+ x = width;
+ lastopcode = -1;
+ insertmix = 0;
+ bicolor = 0;
+ color1 = 0;
+ color2 = 0;
+ mix = 0xff;
+ mask = 0;
fom_mask = 0;
- code = CVAL(input);
- opcode = code >> 4;
- /* Handle different opcode forms */
- switch (opcode)
- {
- case 0xc:
- case 0xd:
- case 0xe:
- opcode -= 6;
- count = code & 0xf;
- offset = 16;
- break;
- case 0xf:
- opcode = code & 0xf;
- if (opcode < 9)
- {
- count = CVAL(input);
- count |= CVAL(input) << 8;
- }
- else
- {
- count = (opcode < 0xb) ? 8 : 1;
- }
- offset = 0;
- break;
- default:
- opcode >>= 1;
- count = code & 0x1f;
- offset = 32;
- break;
- }
- /* Handle strange cases for counts */
- if (offset != 0)
- {
- isfillormix = ((opcode == 2) || (opcode == 7));
- if (count == 0)
- {
- if (isfillormix)
- {
- count = CVAL(input) + 1;
- }
- else
- {
- count = CVAL(input) + offset;
- }
- }
- else if (isfillormix)
- {
- count <<= 3;
- }
- }
- /* Read preliminary data */
- switch (opcode)
+
+ while (input < end)
{
- case 0: /* Fill */
- if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ fom_mask = 0;
+ code = CVAL(input);
+ opcode = code >> 4;
+
+ /* Handle different opcode forms */
+ switch (opcode)
{
- insertmix = 1;
+ case 0xc:
+ case 0xd:
+ case 0xe:
+ opcode -= 6;
+ count = code & 0xf;
+ offset = 16;
+ break;
+ case 0xf:
+ opcode = code & 0xf;
+
+ if (opcode < 9)
+ {
+ count = CVAL(input);
+ count |= CVAL(input) << 8;
+ }
+ else
+ {
+ count = (opcode < 0xb) ? 8 : 1;
+ }
+
+ offset = 0;
+ break;
+ default:
+ opcode >>= 1;
+ count = code & 0x1f;
+ offset = 32;
+ break;
}
- break;
- case 8: /* Bicolor */
- color1 = CVAL(input);
- case 3: /* Color */
- color2 = CVAL(input);
- break;
- case 6: /* SetMix/Mix */
- case 7: /* SetMix/FillOrMix */
- mix = CVAL(input);
- opcode -= 5;
- break;
- case 9: /* FillOrMix_1 */
- mask = 0x03;
- opcode = 0x02;
- fom_mask = 3;
- break;
- case 0x0a: /* FillOrMix_2 */
- mask = 0x05;
- opcode = 0x02;
- fom_mask = 5;
- break;
- }
- lastopcode = opcode;
- mixmask = 0;
- /* Output body */
- while (count > 0)
- {
- if (x >= width)
- {
- if (height <= 0)
+
+ /* Handle strange cases for counts */
+ if (offset != 0)
{
- return 0;
- }
- x = 0;
- height--;
- prevline = line;
- line = output + height * width;
- }
- switch (opcode)
- {
- case 0: /* Fill */
- if (insertmix)
- {
- if (prevline == 0)
+ isfillormix = ((opcode == 2) || (opcode == 7));
+
+ if (count == 0)
{
- line[x] = mix;
+ if (isfillormix)
+ {
+ count = CVAL(input) + 1;
+ }
+ else
+ {
+ count = CVAL(input) + offset;
+ }
}
- else
+ else if (isfillormix)
{
- line[x] = prevline[x] ^ mix;
+ count <<= 3;
}
- insertmix = 0;
- count--;
- x++;
- }
- if (prevline == 0)
- {
- REPEAT(line[x] = 0)
- }
- else
- {
- REPEAT(line[x] = prevline[x])
- }
- break;
- case 1: /* Mix */
- if (prevline == 0)
- {
- REPEAT(line[x] = mix)
- }
- else
- {
- REPEAT(line[x] = prevline[x] ^ mix)
- }
- break;
- case 2: /* Fill or Mix */
- if (prevline == 0)
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x] = mix;
- }
- else
- {
- line[x] = 0;
- }
- )
- }
- else
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x] = prevline[x] ^ mix;
- }
- else
- {
- line[x] = prevline[x];
- }
- )
- }
- break;
- case 3: /* Color */
- REPEAT(line[x] = color2)
- break;
- case 4: /* Copy */
- REPEAT(line[x] = CVAL(input))
- break;
- case 8: /* Bicolor */
- REPEAT
- (
- if (bicolor)
+ }
+
+ /* Read preliminary data */
+ switch (opcode)
+ {
+ case 0: /* Fill */
+
+ if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ {
+ insertmix = 1;
+ }
+
+ break;
+ case 8: /* Bicolor */
+ color1 = CVAL(input);
+ case 3: /* Color */
+ color2 = CVAL(input);
+ break;
+ case 6: /* SetMix/Mix */
+ case 7: /* SetMix/FillOrMix */
+ mix = CVAL(input);
+ opcode -= 5;
+ break;
+ case 9: /* FillOrMix_1 */
+ mask = 0x03;
+ opcode = 0x02;
+ fom_mask = 3;
+ break;
+ case 0x0a: /* FillOrMix_2 */
+ mask = 0x05;
+ opcode = 0x02;
+ fom_mask = 5;
+ break;
+ }
+
+ lastopcode = opcode;
+ mixmask = 0;
+
+ /* Output body */
+ while (count > 0)
+ {
+ if (x >= width)
{
- line[x] = color2;
- bicolor = 0;
+ if (height <= 0)
+ {
+ return 0;
+ }
+
+ x = 0;
+ height--;
+ prevline = line;
+ line = output + height * width;
}
- else
+
+ switch (opcode)
{
- line[x] = color1;
- bicolor = 1;
- count++;
+ case 0: /* Fill */
+
+ if (insertmix)
+ {
+ if (prevline == 0)
+ {
+ line[x] = mix;
+ }
+ else
+ {
+ line[x] = prevline[x] ^ mix;
+ }
+
+ insertmix = 0;
+ count--;
+ x++;
+ }
+
+ if (prevline == 0)
+ {
+ REPEAT(line[x] = 0)
+ }
+ else
+ {
+ REPEAT(line[x] = prevline[x])
+ }
+
+ break;
+ case 1: /* Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT(line[x] = mix)
+ }
+ else
+ {
+ REPEAT(line[x] = prevline[x] ^ mix)
+ }
+
+ break;
+ case 2: /* Fill or Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x] = mix;
+ }
+ else
+ {
+ line[x] = 0;
+ }
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x] = prevline[x] ^ mix;
+ }
+ else
+ {
+ line[x] = prevline[x];
+ }
+ )
+ }
+
+ break;
+ case 3: /* Color */
+ REPEAT(line[x] = color2)
+ break;
+ case 4: /* Copy */
+ REPEAT(line[x] = CVAL(input))
+ break;
+ case 8: /* Bicolor */
+ REPEAT
+ (
+
+ if (bicolor)
+ {
+ line[x] = color2;
+ bicolor = 0;
+ }
+ else
+ {
+ line[x] = color1;
+ bicolor = 1;
+ count++;
+ }
+ )
+ break;
+ case 0xd: /* White */
+ REPEAT(line[x] = 0xff)
+ break;
+ case 0xe: /* Black */
+ REPEAT(line[x] = 0)
+ break;
+ default:
+ return 0;
+ break;
}
- )
- break;
- case 0xd: /* White */
- REPEAT(line[x] = 0xff)
- break;
- case 0xe: /* Black */
- REPEAT(line[x] = 0)
- break;
- default:
- return 0;
- break;
- }
+ }
}
- }
- return 1;
+
+ return 1;
}
/******************************************************************************/
/* 2 byte bitmap decompress */
/* returns boolean */
static int APP_CC
-bitmap_decompress2(char* output, int width, int height, char* input, int size)
+bitmap_decompress2(char *output, int width, int height, char *input, int size)
{
- char* prevline;
- char* line;
- char* end;
- char color1[2];
- char color2[2];
- char mix[2];
- int code;
- int mixmask;
- int mask;
- int opcode;
- int count;
- int offset;
- int isfillormix;
- int x;
- int lastopcode;
- int insertmix;
- int bicolor;
- int fom_mask;
-
- end = input + size;
- prevline = 0;
- line = 0;
- x = width;
- lastopcode = -1;
- insertmix = 0;
- bicolor = 0;
- color1[0] = 0;
- color1[1] = 0;
- color2[0] = 0;
- color2[1] = 0;
- mix[0] = 0xff;
- mix[1] = 0xff;
- mask = 0;
- fom_mask = 0;
-
- while (input < end)
- {
+ char *prevline;
+ char *line;
+ char *end;
+ char color1[2];
+ char color2[2];
+ char mix[2];
+ int code;
+ int mixmask;
+ int mask;
+ int opcode;
+ int count;
+ int offset;
+ int isfillormix;
+ int x;
+ int lastopcode;
+ int insertmix;
+ int bicolor;
+ int fom_mask;
+
+ end = input + size;
+ prevline = 0;
+ line = 0;
+ x = width;
+ lastopcode = -1;
+ insertmix = 0;
+ bicolor = 0;
+ color1[0] = 0;
+ color1[1] = 0;
+ color2[0] = 0;
+ color2[1] = 0;
+ mix[0] = 0xff;
+ mix[1] = 0xff;
+ mask = 0;
fom_mask = 0;
- code = CVAL(input);
- opcode = code >> 4;
- /* Handle different opcode forms */
- switch (opcode)
- {
- case 0xc:
- case 0xd:
- case 0xe:
- opcode -= 6;
- count = code & 0xf;
- offset = 16;
- break;
- case 0xf:
- opcode = code & 0xf;
- if (opcode < 9)
- {
- count = CVAL(input);
- count |= CVAL(input) << 8;
- }
- else
- {
- count = (opcode < 0xb) ? 8 : 1;
- }
- offset = 0;
- break;
- default:
- opcode >>= 1;
- count = code & 0x1f;
- offset = 32;
- break;
- }
- /* Handle strange cases for counts */
- if (offset != 0)
- {
- isfillormix = ((opcode == 2) || (opcode == 7));
- if (count == 0)
- {
- if (isfillormix)
- {
- count = CVAL(input) + 1;
- }
- else
- {
- count = CVAL(input) + offset;
- }
- }
- else if (isfillormix)
- {
- count <<= 3;
- }
- }
- /* Read preliminary data */
- switch (opcode)
+
+ while (input < end)
{
- case 0: /* Fill */
- if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ fom_mask = 0;
+ code = CVAL(input);
+ opcode = code >> 4;
+
+ /* Handle different opcode forms */
+ switch (opcode)
{
- insertmix = 1;
+ case 0xc:
+ case 0xd:
+ case 0xe:
+ opcode -= 6;
+ count = code & 0xf;
+ offset = 16;
+ break;
+ case 0xf:
+ opcode = code & 0xf;
+
+ if (opcode < 9)
+ {
+ count = CVAL(input);
+ count |= CVAL(input) << 8;
+ }
+ else
+ {
+ count = (opcode < 0xb) ? 8 : 1;
+ }
+
+ offset = 0;
+ break;
+ default:
+ opcode >>= 1;
+ count = code & 0x1f;
+ offset = 32;
+ break;
}
- break;
- case 8: /* Bicolor */
- color1[EIK0] = CVAL(input);
- color1[EIK1] = CVAL(input);
- case 3: /* Color */
- color2[EIK0] = CVAL(input);
- color2[EIK1] = CVAL(input);
- break;
- case 6: /* SetMix/Mix */
- case 7: /* SetMix/FillOrMix */
- mix[EIK0] = CVAL(input);
- mix[EIK1] = CVAL(input);
- opcode -= 5;
- break;
- case 9: /* FillOrMix_1 */
- mask = 0x03;
- opcode = 0x02;
- fom_mask = 3;
- break;
- case 0x0a: /* FillOrMix_2 */
- mask = 0x05;
- opcode = 0x02;
- fom_mask = 5;
- break;
- }
- lastopcode = opcode;
- mixmask = 0;
- /* Output body */
- while (count > 0)
- {
- if (x >= width)
- {
- if (height <= 0)
+
+ /* Handle strange cases for counts */
+ if (offset != 0)
{
- return 0;
- }
- x = 0;
- height--;
- prevline = line;
- line = output + height * (width * 2);
- }
- switch (opcode)
- {
- case 0: /* Fill */
- if (insertmix)
- {
- if (prevline == 0)
+ isfillormix = ((opcode == 2) || (opcode == 7));
+
+ if (count == 0)
{
- line[x * 2 + 0] = mix[0];
- line[x * 2 + 1] = mix[1];
+ if (isfillormix)
+ {
+ count = CVAL(input) + 1;
+ }
+ else
+ {
+ count = CVAL(input) + offset;
+ }
}
- else
+ else if (isfillormix)
{
- line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
- line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
+ count <<= 3;
}
- insertmix = 0;
- count--;
- x++;
- }
- if (prevline == 0)
- {
- REPEAT
- (
- line[x * 2 + 0] = 0;
- line[x * 2 + 1] = 0;
- )
- }
- else
- {
- REPEAT
- (
- line[x * 2 + 0] = prevline[x * 2 + 0];
- line[x * 2 + 1] = prevline[x * 2 + 1];
- )
- }
- break;
- case 1: /* Mix */
- if (prevline == 0)
- {
- REPEAT
- (
- line[x * 2 + 0] = mix[0];
- line[x * 2 + 1] = mix[1];
- )
- }
- else
- {
- REPEAT
- (
- line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
- line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
- )
- }
- break;
- case 2: /* Fill or Mix */
- if (prevline == 0)
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x * 2 + 0] = mix[0];
- line[x * 2 + 1] = mix[1];
- }
- else
- {
- line[x * 2 + 0] = 0;
- line[x * 2 + 1] = 0;
- }
- )
- }
- else
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
- line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
- }
- else
- {
- line[x * 2 + 0] = prevline[x * 2 + 0];
- line[x * 2 + 1] = prevline[x * 2 + 1];
- }
- )
- }
- break;
- case 3: /* Color */
- REPEAT
- (
- line[x * 2 + 0] = color2[0];
- line[x * 2 + 1] = color2[1];
- )
- break;
- case 4: /* Copy */
- REPEAT
- (
- line[x * 2 + EIK0] = CVAL(input);
- line[x * 2 + EIK1] = CVAL(input);
- )
- break;
- case 8: /* Bicolor */
- REPEAT
- (
- if (bicolor)
+ }
+
+ /* Read preliminary data */
+ switch (opcode)
+ {
+ case 0: /* Fill */
+
+ if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ {
+ insertmix = 1;
+ }
+
+ break;
+ case 8: /* Bicolor */
+ color1[EIK0] = CVAL(input);
+ color1[EIK1] = CVAL(input);
+ case 3: /* Color */
+ color2[EIK0] = CVAL(input);
+ color2[EIK1] = CVAL(input);
+ break;
+ case 6: /* SetMix/Mix */
+ case 7: /* SetMix/FillOrMix */
+ mix[EIK0] = CVAL(input);
+ mix[EIK1] = CVAL(input);
+ opcode -= 5;
+ break;
+ case 9: /* FillOrMix_1 */
+ mask = 0x03;
+ opcode = 0x02;
+ fom_mask = 3;
+ break;
+ case 0x0a: /* FillOrMix_2 */
+ mask = 0x05;
+ opcode = 0x02;
+ fom_mask = 5;
+ break;
+ }
+
+ lastopcode = opcode;
+ mixmask = 0;
+
+ /* Output body */
+ while (count > 0)
+ {
+ if (x >= width)
{
- line[x * 2 + 0] = color2[0];
- line[x * 2 + 1] = color2[1];
- bicolor = 0;
+ if (height <= 0)
+ {
+ return 0;
+ }
+
+ x = 0;
+ height--;
+ prevline = line;
+ line = output + height * (width * 2);
}
- else
+
+ switch (opcode)
{
- line[x * 2 + 0] = color1[0];
- line[x * 2 + 1] = color1[1];
- bicolor = 1;
- count++;
+ case 0: /* Fill */
+
+ if (insertmix)
+ {
+ if (prevline == 0)
+ {
+ line[x * 2 + 0] = mix[0];
+ line[x * 2 + 1] = mix[1];
+ }
+ else
+ {
+ line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
+ line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
+ }
+
+ insertmix = 0;
+ count--;
+ x++;
+ }
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ line[x * 2 + 0] = 0;
+ line[x * 2 + 1] = 0;
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ line[x * 2 + 0] = prevline[x * 2 + 0];
+ line[x * 2 + 1] = prevline[x * 2 + 1];
+ )
+ }
+
+ break;
+ case 1: /* Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ line[x * 2 + 0] = mix[0];
+ line[x * 2 + 1] = mix[1];
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
+ line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
+ )
+ }
+
+ break;
+ case 2: /* Fill or Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x * 2 + 0] = mix[0];
+ line[x * 2 + 1] = mix[1];
+ }
+ else
+ {
+ line[x * 2 + 0] = 0;
+ line[x * 2 + 1] = 0;
+ }
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x * 2 + 0] = prevline[x * 2 + 0] ^ mix[0];
+ line[x * 2 + 1] = prevline[x * 2 + 1] ^ mix[1];
+ }
+ else
+ {
+ line[x * 2 + 0] = prevline[x * 2 + 0];
+ line[x * 2 + 1] = prevline[x * 2 + 1];
+ }
+ )
+ }
+
+ break;
+ case 3: /* Color */
+ REPEAT
+ (
+ line[x * 2 + 0] = color2[0];
+ line[x * 2 + 1] = color2[1];
+ )
+ break;
+ case 4: /* Copy */
+ REPEAT
+ (
+ line[x * 2 + EIK0] = CVAL(input);
+ line[x * 2 + EIK1] = CVAL(input);
+ )
+ break;
+ case 8: /* Bicolor */
+ REPEAT
+ (
+
+ if (bicolor)
+ {
+ line[x * 2 + 0] = color2[0];
+ line[x * 2 + 1] = color2[1];
+ bicolor = 0;
+ }
+ else
+ {
+ line[x * 2 + 0] = color1[0];
+ line[x * 2 + 1] = color1[1];
+ bicolor = 1;
+ count++;
+ }
+ )
+ break;
+ case 0xd: /* White */
+ REPEAT
+ (
+ line[x * 2 + 0] = 0xff;
+ line[x * 2 + 1] = 0xff;
+ )
+ break;
+ case 0xe: /* Black */
+ REPEAT
+ (
+ line[x * 2 + 0] = 0;
+ line[x * 2 + 1] = 0;
+ )
+ break;
+ default:
+ return 0;
+ break;
}
- )
- break;
- case 0xd: /* White */
- REPEAT
- (
- line[x * 2 + 0] = 0xff;
- line[x * 2 + 1] = 0xff;
- )
- break;
- case 0xe: /* Black */
- REPEAT
- (
- line[x * 2 + 0] = 0;
- line[x * 2 + 1] = 0;
- )
- break;
- default:
- return 0;
- break;
- }
+ }
}
- }
- return 1;
+
+ return 1;
}
/******************************************************************************/
/* 3 byte bitmap decompress */
/* returns boolean */
static int APP_CC
-bitmap_decompress3(char* output, int width, int height, char* input, int size)
+bitmap_decompress3(char *output, int width, int height, char *input, int size)
{
- char* prevline;
- char* line;
- char* end;
- char color1[3];
- char color2[3];
- char mix[3];
- int code;
- int mixmask;
- int mask;
- int opcode;
- int count;
- int offset;
- int isfillormix;
- int x;
- int lastopcode;
- int insertmix;
- int bicolor;
- int fom_mask;
-
- end = input + size;
- prevline = 0;
- line = 0;
- x = width;
- lastopcode = -1;
- insertmix = 0;
- bicolor = 0;
- color1[0] = 0;
- color1[1] = 0;
- color1[2] = 0;
- color2[0] = 0;
- color2[1] = 0;
- color2[2] = 0;
- mix[0] = 0xff;
- mix[1] = 0xff;
- mix[2] = 0xff;
- mask = 0;
- fom_mask = 0;
-
- while (input < end)
- {
+ char *prevline;
+ char *line;
+ char *end;
+ char color1[3];
+ char color2[3];
+ char mix[3];
+ int code;
+ int mixmask;
+ int mask;
+ int opcode;
+ int count;
+ int offset;
+ int isfillormix;
+ int x;
+ int lastopcode;
+ int insertmix;
+ int bicolor;
+ int fom_mask;
+
+ end = input + size;
+ prevline = 0;
+ line = 0;
+ x = width;
+ lastopcode = -1;
+ insertmix = 0;
+ bicolor = 0;
+ color1[0] = 0;
+ color1[1] = 0;
+ color1[2] = 0;
+ color2[0] = 0;
+ color2[1] = 0;
+ color2[2] = 0;
+ mix[0] = 0xff;
+ mix[1] = 0xff;
+ mix[2] = 0xff;
+ mask = 0;
fom_mask = 0;
- code = CVAL(input);
- opcode = code >> 4;
- /* Handle different opcode forms */
- switch (opcode)
- {
- case 0xc:
- case 0xd:
- case 0xe:
- opcode -= 6;
- count = code & 0xf;
- offset = 16;
- break;
- case 0xf:
- opcode = code & 0xf;
- if (opcode < 9)
- {
- count = CVAL(input);
- count |= CVAL(input) << 8;
- }
- else
- {
- count = (opcode < 0xb) ? 8 : 1;
- }
- offset = 0;
- break;
- default:
- opcode >>= 1;
- count = code & 0x1f;
- offset = 32;
- break;
- }
- /* Handle strange cases for counts */
- if (offset != 0)
- {
- isfillormix = ((opcode == 2) || (opcode == 7));
- if (count == 0)
- {
- if (isfillormix)
- {
- count = CVAL(input) + 1;
- }
- else
- {
- count = CVAL(input) + offset;
- }
- }
- else if (isfillormix)
- {
- count <<= 3;
- }
- }
- /* Read preliminary data */
- switch (opcode)
+
+ while (input < end)
{
- case 0: /* Fill */
- if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ fom_mask = 0;
+ code = CVAL(input);
+ opcode = code >> 4;
+
+ /* Handle different opcode forms */
+ switch (opcode)
{
- insertmix = 1;
+ case 0xc:
+ case 0xd:
+ case 0xe:
+ opcode -= 6;
+ count = code & 0xf;
+ offset = 16;
+ break;
+ case 0xf:
+ opcode = code & 0xf;
+
+ if (opcode < 9)
+ {
+ count = CVAL(input);
+ count |= CVAL(input) << 8;
+ }
+ else
+ {
+ count = (opcode < 0xb) ? 8 : 1;
+ }
+
+ offset = 0;
+ break;
+ default:
+ opcode >>= 1;
+ count = code & 0x1f;
+ offset = 32;
+ break;
}
- break;
- case 8: /* Bicolor */
- color1[0] = CVAL(input);
- color1[1] = CVAL(input);
- color1[2] = CVAL(input);
- case 3: /* Color */
- color2[0] = CVAL(input);
- color2[1] = CVAL(input);
- color2[2] = CVAL(input);
- break;
- case 6: /* SetMix/Mix */
- case 7: /* SetMix/FillOrMix */
- mix[0] = CVAL(input);
- mix[1] = CVAL(input);
- mix[2] = CVAL(input);
- opcode -= 5;
- break;
- case 9: /* FillOrMix_1 */
- mask = 0x03;
- opcode = 0x02;
- fom_mask = 3;
- break;
- case 0x0a: /* FillOrMix_2 */
- mask = 0x05;
- opcode = 0x02;
- fom_mask = 5;
- break;
- }
- lastopcode = opcode;
- mixmask = 0;
- /* Output body */
- while (count > 0)
- {
- if (x >= width)
- {
- if (height <= 0)
+
+ /* Handle strange cases for counts */
+ if (offset != 0)
{
- return 0;
- }
- x = 0;
- height--;
- prevline = line;
- line = output + height * (width * 3);
- }
- switch (opcode)
- {
- case 0: /* Fill */
- if (insertmix)
- {
- if (prevline == 0)
+ isfillormix = ((opcode == 2) || (opcode == 7));
+
+ if (count == 0)
{
- line[x * 3 + 0] = mix[0];
- line[x * 3 + 1] = mix[1];
- line[x * 3 + 2] = mix[2];
+ if (isfillormix)
+ {
+ count = CVAL(input) + 1;
+ }
+ else
+ {
+ count = CVAL(input) + offset;
+ }
}
- else
+ else if (isfillormix)
{
- line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
- line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
- line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
+ count <<= 3;
}
- insertmix = 0;
- count--;
- x++;
- }
- if (prevline == 0)
- {
- REPEAT
- (
- line[x * 3 + 0] = 0;
- line[x * 3 + 1] = 0;
- line[x * 3 + 2] = 0;
- )
- }
- else
- {
- REPEAT
- (
- line[x * 3 + 0] = prevline[x * 3 + 0];
- line[x * 3 + 1] = prevline[x * 3 + 1];
- line[x * 3 + 2] = prevline[x * 3 + 2];
- )
- }
- break;
- case 1: /* Mix */
- if (prevline == 0)
- {
- REPEAT
- (
- line[x * 3 + 0] = mix[0];
- line[x * 3 + 1] = mix[1];
- line[x * 3 + 2] = mix[2];
- )
- }
- else
- {
- REPEAT
- (
- line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
- line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
- line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
- )
- }
- break;
- case 2: /* Fill or Mix */
- if (prevline == 0)
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x * 3 + 0] = mix[0];
- line[x * 3 + 1] = mix[1];
- line[x * 3 + 2] = mix[2];
- }
- else
- {
- line[x * 3 + 0] = 0;
- line[x * 3 + 1] = 0;
- line[x * 3 + 2] = 0;
- }
- )
- }
- else
- {
- REPEAT
- (
- MASK_UPDATE;
- if (mask & mixmask)
- {
- line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
- line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
- line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
- }
- else
- {
- line[x * 3 + 0] = prevline[x * 3 + 0];
- line[x * 3 + 1] = prevline[x * 3 + 1];
- line[x * 3 + 2] = prevline[x * 3 + 2];
- }
- )
- }
- break;
- case 3: /* Color */
- REPEAT
- (
- line[x * 3 + 0] = color2[0];
- line[x * 3 + 1] = color2[1];
- line[x * 3 + 2] = color2[2];
- )
- break;
- case 4: /* Copy */
- REPEAT
- (
- line[x * 3 + 0] = CVAL(input);
- line[x * 3 + 1] = CVAL(input);
- line[x * 3 + 2] = CVAL(input);
- )
- break;
- case 8: /* Bicolor */
- REPEAT
- (
- if (bicolor)
+ }
+
+ /* Read preliminary data */
+ switch (opcode)
+ {
+ case 0: /* Fill */
+
+ if ((lastopcode == opcode) && !((x == width) && (prevline == 0)))
+ {
+ insertmix = 1;
+ }
+
+ break;
+ case 8: /* Bicolor */
+ color1[0] = CVAL(input);
+ color1[1] = CVAL(input);
+ color1[2] = CVAL(input);
+ case 3: /* Color */
+ color2[0] = CVAL(input);
+ color2[1] = CVAL(input);
+ color2[2] = CVAL(input);
+ break;
+ case 6: /* SetMix/Mix */
+ case 7: /* SetMix/FillOrMix */
+ mix[0] = CVAL(input);
+ mix[1] = CVAL(input);
+ mix[2] = CVAL(input);
+ opcode -= 5;
+ break;
+ case 9: /* FillOrMix_1 */
+ mask = 0x03;
+ opcode = 0x02;
+ fom_mask = 3;
+ break;
+ case 0x0a: /* FillOrMix_2 */
+ mask = 0x05;
+ opcode = 0x02;
+ fom_mask = 5;
+ break;
+ }
+
+ lastopcode = opcode;
+ mixmask = 0;
+
+ /* Output body */
+ while (count > 0)
+ {
+ if (x >= width)
{
- line[x * 3 + 0] = color2[0];
- line[x * 3 + 1] = color2[1];
- line[x * 3 + 2] = color2[2];
- bicolor = 0;
+ if (height <= 0)
+ {
+ return 0;
+ }
+
+ x = 0;
+ height--;
+ prevline = line;
+ line = output + height * (width * 3);
}
- else
+
+ switch (opcode)
{
- line[x * 3 + 0] = color1[0];
- line[x * 3 + 1] = color1[1];
- line[x * 3 + 2] = color1[2];
- bicolor = 1;
- count++;
+ case 0: /* Fill */
+
+ if (insertmix)
+ {
+ if (prevline == 0)
+ {
+ line[x * 3 + 0] = mix[0];
+ line[x * 3 + 1] = mix[1];
+ line[x * 3 + 2] = mix[2];
+ }
+ else
+ {
+ line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
+ line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
+ line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
+ }
+
+ insertmix = 0;
+ count--;
+ x++;
+ }
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ line[x * 3 + 0] = 0;
+ line[x * 3 + 1] = 0;
+ line[x * 3 + 2] = 0;
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ line[x * 3 + 0] = prevline[x * 3 + 0];
+ line[x * 3 + 1] = prevline[x * 3 + 1];
+ line[x * 3 + 2] = prevline[x * 3 + 2];
+ )
+ }
+
+ break;
+ case 1: /* Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ line[x * 3 + 0] = mix[0];
+ line[x * 3 + 1] = mix[1];
+ line[x * 3 + 2] = mix[2];
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
+ line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
+ line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
+ )
+ }
+
+ break;
+ case 2: /* Fill or Mix */
+
+ if (prevline == 0)
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x * 3 + 0] = mix[0];
+ line[x * 3 + 1] = mix[1];
+ line[x * 3 + 2] = mix[2];
+ }
+ else
+ {
+ line[x * 3 + 0] = 0;
+ line[x * 3 + 1] = 0;
+ line[x * 3 + 2] = 0;
+ }
+ )
+ }
+ else
+ {
+ REPEAT
+ (
+ MASK_UPDATE;
+
+ if (mask & mixmask)
+ {
+ line[x * 3 + 0] = prevline[x * 3 + 0] ^ mix[0];
+ line[x * 3 + 1] = prevline[x * 3 + 1] ^ mix[1];
+ line[x * 3 + 2] = prevline[x * 3 + 2] ^ mix[2];
+ }
+ else
+ {
+ line[x * 3 + 0] = prevline[x * 3 + 0];
+ line[x * 3 + 1] = prevline[x * 3 + 1];
+ line[x * 3 + 2] = prevline[x * 3 + 2];
+ }
+ )
+ }
+
+ break;
+ case 3: /* Color */
+ REPEAT
+ (
+ line[x * 3 + 0] = color2[0];
+ line[x * 3 + 1] = color2[1];
+ line[x * 3 + 2] = color2[2];
+ )
+ break;
+ case 4: /* Copy */
+ REPEAT
+ (
+ line[x * 3 + 0] = CVAL(input);
+ line[x * 3 + 1] = CVAL(input);
+ line[x * 3 + 2] = CVAL(input);
+ )
+ break;
+ case 8: /* Bicolor */
+ REPEAT
+ (
+
+ if (bicolor)
+ {
+ line[x * 3 + 0] = color2[0];
+ line[x * 3 + 1] = color2[1];
+ line[x * 3 + 2] = color2[2];
+ bicolor = 0;
+ }
+ else
+ {
+ line[x * 3 + 0] = color1[0];
+ line[x * 3 + 1] = color1[1];
+ line[x * 3 + 2] = color1[2];
+ bicolor = 1;
+ count++;
+ }
+ )
+ break;
+ case 0xd: /* White */
+ REPEAT
+ (
+ line[x * 3 + 0] = 0xff;
+ line[x * 3 + 1] = 0xff;
+ line[x * 3 + 2] = 0xff;
+ )
+ break;
+ case 0xe: /* Black */
+ REPEAT
+ (
+ line[x * 3 + 0] = 0;
+ line[x * 3 + 1] = 0;
+ line[x * 3 + 2] = 0;
+ )
+ break;
+ default:
+ return 0;
+ break;
}
- )
- break;
- case 0xd: /* White */
- REPEAT
- (
- line[x * 3 + 0] = 0xff;
- line[x * 3 + 1] = 0xff;
- line[x * 3 + 2] = 0xff;
- )
- break;
- case 0xe: /* Black */
- REPEAT
- (
- line[x * 3 + 0] = 0;
- line[x * 3 + 1] = 0;
- line[x * 3 + 2] = 0;
- )
- break;
- default:
- return 0;
- break;
- }
+ }
}
- }
- return 1;
+
+ return 1;
}
/*****************************************************************************/
/* returns boolean */
int APP_CC
-rdp_bitmap_decompress(char* output, int width, int height, char* input,
+rdp_bitmap_decompress(char *output, int width, int height, char *input,
int size, int Bpp)
{
- int rv;
-
- switch (Bpp)
- {
- case 1:
- rv = bitmap_decompress1(output, width, height, input, size);
- break;
- case 2:
- rv = bitmap_decompress2(output, width, height, input, size);
- break;
- case 3:
- rv = bitmap_decompress3(output, width, height, input, size);
- break;
- default:
- rv = 0;
- break;
- }
- return rv;
+ int rv;
+
+ switch (Bpp)
+ {
+ case 1:
+ rv = bitmap_decompress1(output, width, height, input, size);
+ break;
+ case 2:
+ rv = bitmap_decompress2(output, width, height, input, size);
+ break;
+ case 3:
+ rv = bitmap_decompress3(output, width, height, input, size);
+ break;
+ default:
+ rv = 0;
+ break;
+ }
+
+ return rv;
}