a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* -*- c-basic-offset: 8 -*-
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdesktop: A Remote Desktop Protocol client.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Bitmap decompression routines
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is free software: you can redistribute it and/or modify
a180a41bba1d50822df23fff0099e90b86638b89vboxsync it under the terms of the GNU General Public License as published by
a180a41bba1d50822df23fff0099e90b86638b89vboxsync the Free Software Foundation, either version 3 of the License, or
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (at your option) any later version.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is distributed in the hope that it will be useful,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync but WITHOUT ANY WARRANTY; without even the implied warranty of
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a180a41bba1d50822df23fff0099e90b86638b89vboxsync GNU General Public License for more details.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync You should have received a copy of the GNU General Public License
a180a41bba1d50822df23fff0099e90b86638b89vboxsync along with this program. If not, see <http://www.gnu.org/licenses/>.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync*/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync/*
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * the General Public License version 2 (GPLv2) at this time for any software where
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * a choice of GPL license versions is made available with the language indicating
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * that GPLv2 or any later version may be used, or where a choice of which version
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * of the GPL is applied is otherwise unspecified.
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync */
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* three seperate function for speed when decompressing the bitmaps
a180a41bba1d50822df23fff0099e90b86638b89vboxsync when modifing one function make the change in the others
a180a41bba1d50822df23fff0099e90b86638b89vboxsync jay.sorg@gmail.com */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* indent is confused by this file */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* *INDENT-OFF* */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include "rdesktop.h"
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define CVAL(p) (*(p++))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef NEED_ALIGN
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef L_ENDIAN
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define CVAL2(p, v) { v = (*(p++)); v |= (*(p++)) << 8; }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define CVAL2(p, v) { v = (*(p++)) << 8; v |= (*(p++)); }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif /* L_ENDIAN */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define CVAL2(p, v) { v = (*((uint16*)p)); p += 2; }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif /* NEED_ALIGN */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define UNROLL8(exp) { exp exp exp exp exp exp exp exp }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define REPEAT(statement) \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{ \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while((count & ~0x7) && ((x+8) < width)) \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync UNROLL8( statement; count--; x++; ); \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while((count > 0) && (x < width)) \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync { \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync statement; \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count--; \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x++; \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync } \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define MASK_UPDATE() \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{ \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mixmask <<= 1; \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mixmask == 0) \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync { \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = fom_mask ? fom_mask : CVAL(input); \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mixmask = 1; \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync } \
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* 1 byte bitmap decompress */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncbitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *end = input + size;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *prevline = NULL, *line = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int opcode, count, offset, isfillormix, x = width;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int lastopcode = -1, insertmix = False, bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 code;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 colour1 = 0, colour2 = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 mixmask, mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 mix = 0xff;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (input < end)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code >> 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle different opcode forms */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xc:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 6;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 16;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xf:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (opcode < 9)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count |= CVAL(input) << 8;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = (opcode < 0xb) ? 8 : 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode >>= 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0x1f;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 32;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle strange cases for counts */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (offset != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync isfillormix = ((opcode == 2) || (opcode == 7));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (count == 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + offset;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count <<= 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Read preliminary data */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour1 = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour2 = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 6: /* SetMix/Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 7: /* SetMix/FillOrMix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mix = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 9: /* FillOrMix_1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x03;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0x0a: /* FillOrMix_2 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x05;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync lastopcode = opcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mixmask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Output body */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (count > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (x >= width)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (height <= 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync height--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline = line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line = output + height * width;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (insertmix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x] ^ mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = prevline[x])
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 1: /* Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = mix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = prevline[x] ^ mix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 2: /* Fill or Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x] ^ mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = colour2)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 4: /* Copy */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = CVAL(input))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (bicolour)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = colour2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = colour1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = True; count++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd: /* White */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0xff)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe: /* Black */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("bitmap opcode 0x%x\n", opcode);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* 2 byte bitmap decompress */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncbitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *end = input + size;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 *prevline = NULL, *line = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int opcode, count, offset, isfillormix, x = width;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int lastopcode = -1, insertmix = False, bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 code;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 colour1 = 0, colour2 = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 mixmask, mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 mix = 0xffff;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (input < end)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code >> 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle different opcode forms */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xc:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 6;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 16;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xf:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (opcode < 9)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count |= CVAL(input) << 8;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = (opcode < 0xb) ? 8 : 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode >>= 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0x1f;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 32;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle strange cases for counts */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (offset != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync isfillormix = ((opcode == 2) || (opcode == 7));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (count == 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + offset;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count <<= 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Read preliminary data */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync CVAL2(input, colour1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync CVAL2(input, colour2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 6: /* SetMix/Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 7: /* SetMix/FillOrMix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync CVAL2(input, mix);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 9: /* FillOrMix_1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x03;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0x0a: /* FillOrMix_2 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x05;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync lastopcode = opcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mixmask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Output body */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (count > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (x >= width)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (height <= 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync height--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline = line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line = ((uint16 *) output) + height * width;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (insertmix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x] ^ mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = prevline[x])
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 1: /* Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = mix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = prevline[x] ^ mix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 2: /* Fill or Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x] ^ mix;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = prevline[x];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = colour2)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 4: /* Copy */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(CVAL2(input, line[x]))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (bicolour)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = colour2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x] = colour1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd: /* White */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0xffff)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe: /* Black */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT(line[x] = 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("bitmap opcode 0x%x\n", opcode);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* 3 byte bitmap decompress */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncbitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *end = input + size;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *prevline = NULL, *line = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int opcode, count, offset, isfillormix, x = width;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int lastopcode = -1, insertmix = False, bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 code;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0};
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 mixmask, mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 mix[3] = {0xff, 0xff, 0xff};
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (input < end)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code >> 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle different opcode forms */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xc:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 6;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 16;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xf:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (opcode < 9)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count |= CVAL(input) << 8;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = (opcode <
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 0xb) ? 8 : 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode >>= 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = code & 0x1f;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset = 32;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Handle strange cases for counts */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (offset != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync isfillormix = ((opcode == 2) || (opcode == 7));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (count == 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count = CVAL(input) + offset;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (isfillormix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count <<= 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Read preliminary data */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour1[0] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour1[1] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour1[2] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour2[0] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour2[1] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync colour2[2] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 6: /* SetMix/Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 7: /* SetMix/FillOrMix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mix[0] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mix[1] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mix[2] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode -= 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 9: /* FillOrMix_1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x03;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 3;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0x0a: /* FillOrMix_2 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mask = 0x05;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync opcode = 0x02;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fom_mask = 5;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync lastopcode = opcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync mixmask = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Output body */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (count > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (x >= width)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (height <= 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync height--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline = line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line = output + height * (width * 3);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (opcode)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* Fill */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (insertmix)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = mix[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = mix[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = mix[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3] ^ mix[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 1] ^ mix[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 2] ^ mix[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync insertmix = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = prevline[x * 3];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = prevline[x * 3 + 1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = prevline[x * 3 + 2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 1: /* Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = mix[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = mix[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = mix[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3] ^ mix[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 1] ^ mix[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 2] ^ mix[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 2: /* Fill or Mix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prevline == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = mix[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = mix[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = mix[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MASK_UPDATE();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mask & mixmask)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3] ^ mix [0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 1] ^ mix [1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 2] ^ mix [2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prevline[x * 3 + 2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3: /* Colour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = colour2 [0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = colour2 [1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = colour2 [2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 4: /* Copy */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 8: /* Bicolour */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (bicolour)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = colour2[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = colour2[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = colour2[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = colour1[0];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = colour1[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = colour1[2];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bicolour = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync count++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xd: /* White */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = 0xff;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = 0xff;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = 0xff;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0xe: /* Black */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync REPEAT
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 1] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync line[x * 3 + 2] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("bitmap opcode 0x%x\n", opcode);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* decompress a colour plane */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic int
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncprocess_plane(uint8 * in, int width, int height, uint8 * out, int size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int indexw;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int indexh;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int code;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int collen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int replen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int color;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int x;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int revcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 * last_line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 * this_line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 * org_in;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 * org_out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync org_in = in;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync org_out = out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync last_line = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexh = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (indexh < height)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out = (org_out + width * height * 4) - ((indexh + 1) * width * 4);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync color = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync this_line = out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexw = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (last_line == 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (indexw < width)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen = (code >> 4) & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync revcode = (replen << 4) | collen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((revcode <= 47) && (revcode >= 16))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen = revcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (collen > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync color = CVAL(in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *out = color;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out += 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexw++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (replen > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *out = color;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out += 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexw++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (indexw < width)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen = code & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen = (code >> 4) & 0xf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync revcode = (replen << 4) | collen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((revcode <= 47) && (revcode >= 16))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen = revcode;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (collen > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = CVAL(in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (x & 1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = x >> 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = x + 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync color = -x;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = x >> 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync color = x;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = last_line[indexw * 4] + color;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *out = x;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out += 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexw++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync collen--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (replen > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync x = last_line[indexw * 4] + color;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *out = x;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out += 4;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexw++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync replen--;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync indexh++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync last_line = this_line;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return (int) (in - org_in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* 4 byte bitmap decompress */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncbitmap_decompress4(uint8 * output, int width, int height, uint8 * input, int size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int code;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int total_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync code = CVAL(input);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (code != 0x10)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync total_pro = 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_pro = process_plane(input, width, height, output + 3, size - total_pro);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync total_pro += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync input += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_pro = process_plane(input, width, height, output + 2, size - total_pro);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync total_pro += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync input += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_pro = process_plane(input, width, height, output + 1, size - total_pro);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync total_pro += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync input += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_pro = process_plane(input, width, height, output + 0, size - total_pro);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync total_pro += bytes_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return size == total_pro;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* main decompress function */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncbitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RD_BOOL rv = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (Bpp)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 1:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rv = bitmap_decompress1(output, width, height, input, size);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 2:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rv = bitmap_decompress2(output, width, height, input, size);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 3:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rv = bitmap_decompress3(output, width, height, input, size);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 4:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rv = bitmap_decompress4(output, width, height, input, size);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("Bpp %d\n", Bpp);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return rv;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* *INDENT-ON* */