1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2005 Johannes E. Schindelin. All Rights Reserved. 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is free software; you can redistribute it and/or modify 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it under the terms of the GNU General Public License as published by 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the Free Software Foundation; either version 2 of the License, or 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (at your option) any later version. 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is distributed in the hope that it will be useful, 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * GNU General Public License for more details. 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * You should have received a copy of the GNU General Public License 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * along with this software; if not, write to the Free Software 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * USA. 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_HAVE_LIBZ 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * zrle.c - handle zrle encoding. 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This file shouldn't be compiled directly. It is included multiple times by 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * rfbproto.c, each time with a different definition of the macro BPP. For 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * each value of BPP, this file defines a function which handles an zrle 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * encoded rectangle with BPP bits per pixel. 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifndef REALBPP 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define REALBPP BPP 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !defined(UNCOMP) || UNCOMP==0 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP) 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#elif UNCOMP>0 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down) 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up) 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CARDBPP CONCAT3E(uint,BPP,_t) 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CARDREALBPP CONCAT3E(uint,REALBPP,_t) 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ENDIAN_LITTLE 0 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ENDIAN_BIG 1 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ENDIAN_NO 2 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ZYWRLE_ENDIAN ENDIAN_LITTLE 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef END_FIX 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if ZYWRLE_ENDIAN == ENDIAN_LITTLE 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# define END_FIX LE 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#elif ZYWRLE_ENDIAN == ENDIAN_BIG 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# define END_FIX BE 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat# define END_FIX NE 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define __RFB_CONCAT3E(a,b,c) CONCAT3E(a,b,c) 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define __RFB_CONCAT2E(a,b) CONCAT2E(a,b) 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef CPIXEL 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if REALBPP != BPP 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if UNCOMP == 0 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CPIXEL REALBPP 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#elif UNCOMP>0 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CPIXEL CONCAT2E(REALBPP,Down) 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define CPIXEL CONCAT2E(REALBPP,Up) 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define PIXEL_T __RFB_CONCAT3E(uint,BPP,_t) 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if BPP!=8 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define ZYWRLE_DECODE 1 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "zywrletemplate.c" 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef CPIXEL 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int HandleZRLETile(rfbClient* client, 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t* buffer,size_t buffer_length, 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x,int y,int w,int h); 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbBool 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatHandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbZRLEHeader header; 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int remaining; 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int inflateResult; 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int toRead; 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int min_buffer_size = rw * rh * (REALBPP / 8) * 2; 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* First make sure we have a large enough raw buffer to hold the 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * decompressed data. In practice, with a fixed REALBPP, fixed frame 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * buffer size and the first update containing the entire frame 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * buffer, this buffer allocation should only happen once, on the 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * first update. 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( client->raw_buffer_size < min_buffer_size) { 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( client->raw_buffer != NULL ) { 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free( client->raw_buffer ); 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->raw_buffer_size = min_buffer_size; 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->raw_buffer = (char*) malloc( client->raw_buffer_size ); 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!ReadFromRFBServer(client, (char *)&header, sz_rfbZRLEHeader)) 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remaining = rfbClientSwap32IfLE(header.length); 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Need to initialize the decompressor state. */ 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.next_in = ( Bytef * )client->buffer; 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.avail_in = 0; 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.next_out = ( Bytef * )client->raw_buffer; 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.avail_out = client->raw_buffer_size; 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.data_type = Z_BINARY; 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Initialize the decompression stream structures on the first invocation. */ 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( client->decompStreamInited == FALSE ) { 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult = inflateInit( &client->decompStream ); 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( inflateResult != Z_OK ) { 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog( 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "inflateInit returned error: %d, msg: %s\n", 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult, 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.msg); 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStreamInited = TRUE; 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult = Z_OK; 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Process buffer full of data until no more to process, or 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * some type of inflater error, or Z_STREAM_END. 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (( remaining > 0 ) && 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ( inflateResult == Z_OK )) { 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( remaining > RFB_BUFFER_SIZE ) { 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat toRead = RFB_BUFFER_SIZE; 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else { 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat toRead = remaining; 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Fill the buffer, obtaining data from the server. */ 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!ReadFromRFBServer(client, client->buffer,toRead)) 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.next_in = ( Bytef * )client->buffer; 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.avail_in = toRead; 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Need to uncompress buffer full. */ 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* We never supply a dictionary for compression. */ 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( inflateResult == Z_NEED_DICT ) { 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("zlib inflate needs a dictionary!\n"); 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( inflateResult < 0 ) { 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog( 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "zlib inflate returned error: %d, msg: %s\n", 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult, 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.msg); 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Result buffer allocated to be at least large enough. We should 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * never run out of space! 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (( client->decompStream.avail_in > 0 ) && 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ( client->decompStream.avail_out <= 0 )) { 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("zlib inflate ran out of space!\n"); 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remaining -= toRead; 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } /* while ( remaining > 0 ) */ 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ( inflateResult == Z_OK ) { 192bec50fdbf6ec2d61edda4f69913f8a8331b8b364Greg Hartman char* buf=client->raw_buffer; 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i,j; 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remaining = client->raw_buffer_size-client->decompStream.avail_out; 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j=0; j<rh; j+=rfbZRLETileHeight) 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0; i<rw; i+=rfbZRLETileWidth) { 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth; 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight; 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight); 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(result<0) { 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("ZRLE decoding failed (%d)\n",result); 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatreturn TRUE; 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buf+=result; 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat remaining-=result; 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else { 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog( 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "zlib inflate returned error: %d, msg: %s\n", 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat inflateResult, 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->decompStream.msg); 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return FALSE; 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return TRUE; 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if UNCOMP>0 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP) 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP))) 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define UncompressCPixel(pointer) (*(CARDBPP*)pointer) 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic int HandleZRLETile(rfbClient* client, 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t* buffer,size_t buffer_length, 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x,int y,int w,int h) { 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t* buffer_copy = buffer; 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t* buffer_end = buffer+buffer_length; 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t type; 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if BPP!=8 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat uint8_t zywrle_level = (client->appData.qualityLevel & 0x80) ? 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 0 : (3 - client->appData.qualityLevel / 3); 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer_length<1) 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -2; 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat type = *buffer; 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if( type == 0 ) /* raw */ 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if BPP!=8 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if( zywrle_level > 0 ){ 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CARDBPP* pFrame = (CARDBPP*)client->frameBuffer + y*client->width+x; 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int ret; 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->appData.qualityLevel |= 0x80; 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ret = HandleZRLETile(client, buffer, buffer_end-buffer, x, y, w, h); 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->appData.qualityLevel &= 0x7F; 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if( ret < 0 ){ 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return ret; 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ZYWRLE_SYNTHESIZE( pFrame, pFrame, w, h, client->width, zywrle_level, (int*)client->zlib_buffer ); 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer += ret; 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }else 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if REALBPP!=BPP 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i,j; 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(1+w*h*REALBPP/8>buffer_length) { 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h); 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -3; 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j=y*client->width; j<(y+h)*client->width; j+=client->width) 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=x; i<x+w; i++,buffer+=REALBPP/8) 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((CARDBPP*)client->frameBuffer)[j+i] = UncompressCPixel(buffer); 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CopyRectangle(client, buffer, x, y, w, h); 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer+=w*h*REALBPP/8; 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if( type == 1 ) /* solid */ 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CARDBPP color = UncompressCPixel(buffer); 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(1+REALBPP/8>buffer_length) 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -4; 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FillRectangle(client, x, y, w, h, color); 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer+=REALBPP/8; 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if( (type >= 2)&&(type <= 127) ) /* packed Palette */ 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CARDBPP palette[16]; 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i,j,shift, 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bpp=(type>4?(type>16?8:4):(type>2?2:1)), 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat mask=(1<<bpp)-1, 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat divider=(8/bpp); 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length) 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -5; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read palette */ 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0; i<type; i++,buffer+=REALBPP/8) 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat palette[i] = UncompressCPixel(buffer); 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read palettized pixels */ 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j=y*client->width; j<(y+h)*client->width; j+=client->width) { 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=x,shift=8-bpp; i<x+w; i++) { 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((CARDBPP*)client->frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask]; 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift-=bpp; 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(shift<0) { 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat shift=8-bpp; 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(shift<8-bpp) 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* case 17 ... 127: not used, but valid */ 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if( type == 128 ) /* plain RLE */ 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i=0,j=0; 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(j<h) { 332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int color,length; 333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read color */ 334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer+REALBPP/8+1>buffer_end) 335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -7; 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat color = UncompressCPixel(buffer); 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer+=REALBPP/8; 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read run length */ 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length=1; 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(*buffer==0xff) { 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer+1>=buffer_end) 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -8; 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length+=*buffer; 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length+=*buffer; 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(j<h && length>0) { 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length--; 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i++; 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i>=w) { 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i=0; 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat j++; 355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(length>0) 358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("Warning: possible ZRLE corruption\n"); 359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if( type == 129 ) /* unused */ 363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -8; 365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if( type >= 130 ) /* palette RLE */ 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat CARDBPP palette[128]; 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i,j; 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(2+(type-128)*REALBPP/8>buffer_length) 372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -9; 373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read palette */ 375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0; i<type-128; i++,buffer+=REALBPP/8) 376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat palette[i] = UncompressCPixel(buffer); 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read palettized pixels */ 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i=j=0; 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(j<h) { 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int color,length; 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read color */ 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer>=buffer_end) 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -10; 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat color = palette[(*buffer)&0x7f]; 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length=1; 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(*buffer&0x80) { 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer+1>=buffer_end) 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -11; 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read run length */ 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(*buffer==0xff) { 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buffer+1>=buffer_end) 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -8; 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length+=*buffer; 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length+=*buffer; 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat buffer++; 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(j<h && length>0) { 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length--; 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i++; 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(i>=w) { 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i=0; 406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat j++; 407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(length>0) 410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("Warning: possible ZRLE corruption\n"); 411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return buffer-buffer_copy; 416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef CARDBPP 419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef CARDREALBPP 420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef HandleZRLE 421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef HandleZRLETile 422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef UncompressCPixel 423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef REALBPP 424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef UNCOMP 428