diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/compext/Z.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/nxagent/compext/Z.c | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c new file mode 100644 index 000000000..6ee08e236 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c @@ -0,0 +1,309 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ +/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */ +/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */ +/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */ +/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/ +/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ +/* */ +/* NXCOMPEXT, NX protocol compression and NX extensions to this software */ +/* are copyright of the aforementioned persons and companies. */ +/* */ +/* Redistribution and use of the present software is allowed according */ +/* to terms specified in the file LICENSE which comes in the source */ +/* distribution. */ +/* */ +/* All rights reserved. */ +/* */ +/* NOTE: This software has received contributions from various other */ +/* contributors, only the core maintainers and supporters are listed as */ +/* copyright holders. Please contact us, if you feel you should be listed */ +/* as copyright holder, as well. */ +/* */ +/**************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <zlib.h> + +#include "Compext.h" + +#include "Z.h" + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG + +#define Z_COMPRESSION_LEVEL 4 +#define Z_COMPRESSION_THRESHOLD 32 +#define Z_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY + +static int zCompressionLevel = Z_COMPRESSION_LEVEL; +static int zCompressionStrategy = Z_COMPRESSION_STRATEGY; + +static z_stream *zStream; + +static int zInitialized; + +static int ZConfigure(int level, int strategy); + +static int ZDeflate(char *dest, unsigned int *destLen, + const char *source, unsigned int sourceLen); + +char *ZCompressData(const char *plainData, unsigned int plainSize, int threshold, + int level, int strategy, unsigned int *compressedSize) +{ + char *compressedData; + + /* + * Determine the size of the source image + * data and make sure there is enough + * space in the destination buffer. + */ + + *compressedSize = plainSize + (plainSize / 1000) + 12 + 1; + + compressedData = Xmalloc(*compressedSize); + + if (compressedData == NULL) + { + #ifdef PANIC + fprintf(stderr, "******ZCompressData: PANIC! Failed to allocate [%d] bytes for the destination.\n", + *compressedSize); + #endif + + *compressedSize = 0; + + return NULL; + } + + if (level == Z_NO_COMPRESSION || plainSize < threshold) + { + #ifdef TEST + fprintf(stderr, "******ZCompressData: Not compressing [%d] bytes with level [%d] and " + "threshold [%d].\n", plainSize, level, threshold); + #endif + + /* + * Tell in the first byte of the buffer + * if the remaining data is compressed + * or not. This same byte can be used + * in future to store some other flag. + */ + + *compressedData = 0; + + memcpy(compressedData + 1, plainData, plainSize); + + *compressedSize = plainSize + 1; + + return compressedData; + } + else + { + int result; + + /* + * Reconfigure the stream if needed. + */ + + if (zCompressionLevel != level || + zCompressionStrategy != strategy) + { + ZConfigure(level, strategy); + + zCompressionLevel = level; + zCompressionStrategy = strategy; + } + + result = ZDeflate(compressedData + 1, compressedSize, plainData, plainSize); + + if (result != Z_OK) + { + #ifdef PANIC + fprintf(stderr, "******ZCompressData: PANIC! Failed to compress [%d] bytes with error [%s].\n", + plainSize, zError(result)); + #endif + + Xfree(compressedData); + + *compressedSize = 0; + + return NULL; + } + + #ifdef TEST + fprintf(stderr, "******ZCompressData: Source data of [%d] bytes compressed to [%d].\n", + plainSize, *compressedSize); + #endif + + *compressedData = 1; + + *compressedSize = *compressedSize + 1; + + return compressedData; + } +} + +int ZConfigure(int level, int strategy) +{ + /* + * ZLIB wants the avail_out to be + * non zero, even if the stream was + * already flushed. + */ + + unsigned char dest[1]; + + zStream -> next_out = dest; + zStream -> avail_out = 1; + + if (deflateParams(zStream, level, strategy) != Z_OK) + { + #ifdef PANIC + fprintf(stderr, "******ZConfigure: PANIC! Failed to set level to [%d] and strategy to [%d].\n", + level, strategy); + #endif + + return -1; + } + #ifdef TEST + else + { + fprintf(stderr, "******ZConfigure: Reconfigured the stream with level [%d] and strategy [%d].\n", + level, strategy); + } + #endif + + return 1; +} + +int ZDeflate(char *dest, unsigned int *destLen, const char *source, unsigned int sourceLen) +{ + int saveOut; + int result; + + /* + * Deal with the possible overflow. + */ + + if (zStream -> total_out & 0x80000000) + { + #ifdef TEST + fprintf(stderr, "******ZDeflate: Reset Z stream counters with total in [%ld] total out [%ld].\n", + zStream -> total_in, zStream -> total_out); + #endif + + zStream -> total_in = 0; + zStream -> total_out = 0; + } + + saveOut = zStream -> total_out; + + zStream -> next_in = (Bytef *) source; + zStream -> avail_in = (uInt) sourceLen; + + #ifdef MAXSEG_64K + + /* + * Check if the source is greater + * than 64K on a 16-bit machine. + */ + + if ((uLong) zStream -> avail_in != sourceLen) return Z_BUF_ERROR; + + #endif + + zStream -> next_out = (unsigned char *) dest; + zStream -> avail_out = (uInt) *destLen; + + if ((uLong) zStream -> avail_out != *destLen) return Z_BUF_ERROR; + + result = deflate(zStream, Z_FINISH); + + if (result != Z_STREAM_END) + { + deflateReset(zStream); + + return (result == Z_OK ? Z_BUF_ERROR : result); + } + + *destLen = zStream -> total_out - saveOut; + + result = deflateReset(zStream); + + return result; +} + +int ZInitEncoder() +{ + if (zInitialized == 0) + { + int result; + + zStream = Xmalloc(sizeof(z_stream)); + + if (zStream == NULL) + { + #ifdef PANIC + fprintf(stderr, "******ZInitEncoder: PANIC! Failed to allocate memory for the stream.\n"); + #endif + + return -1; + } + + zStream -> zalloc = (alloc_func) 0; + zStream -> zfree = (free_func) 0; + zStream -> opaque = (voidpf) 0; + + #ifdef TEST + fprintf(stderr, "******ZInitEncoder: Initializing compressor with level [%d] and startegy [%d].\n", + zCompressionLevel, zCompressionStrategy); + #endif + + result = deflateInit2(zStream, zCompressionLevel, Z_DEFLATED, + 15, 9, zCompressionStrategy); + + if (result != Z_OK) + { + #ifdef PANIC + fprintf(stderr, "******ZInitEncoder: Failed to initialize the compressor with error [%s].\n", + zError(result)); + #endif + + return -1; + } + + zInitialized = 1; + } + + return zInitialized; +} + +int ZResetEncoder() +{ + int result; + + if (zInitialized == 1) + { + result = deflateEnd(zStream); + + if (result != Z_OK) + { + #ifdef WARNING + fprintf(stderr, "******ZResetEncoder: WARNING! Failed to deinitialize the compressor with error [%s].\n", + zError(result)); + #endif + } + + Xfree(zStream); + } + + zInitialized = 0; + + return 1; +} |