diff options
Diffstat (limited to 'common')
69 files changed, 542 insertions, 1566 deletions
diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx index e494a112..d9e9376a 100644 --- a/common/network/TcpSocket.cxx +++ b/common/network/TcpSocket.cxx @@ -43,7 +43,6 @@ #include <stdlib.h> #include <network/TcpSocket.h> -#include <os/net.h> #include <rfb/util.h> #include <rfb/LogWriter.h> diff --git a/common/os/CMakeLists.txt b/common/os/CMakeLists.txt index 39d5c106..fd3794dc 100644 --- a/common/os/CMakeLists.txt +++ b/common/os/CMakeLists.txt @@ -1,8 +1,6 @@ include_directories(${CMAKE_SOURCE_DIR}/common) add_library(os STATIC - print.c - net.c w32tiger.c os.cxx tls.cxx) diff --git a/common/os/net.c b/common/os/net.c deleted file mode 100644 index 7bad36c9..00000000 --- a/common/os/net.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2008 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> - -#ifdef WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif - -#include <os/net.h> - - -#ifndef HAVE_INET_NTOP -const char *tight_inet_ntop(int af, const void *src, char *dst, - socklen_t size) { - char *tempstr; - - /* Catch bugs - we should not use IPv6 if we don't have inet_ntop */ - if (af != AF_INET) - abort(); - - /* inet_ntoa never fails */ - tempstr = inet_ntoa(*(struct in_addr *)(src)); - memcpy(dst, tempstr, strlen(tempstr) + 1); - - return dst; -} -#endif diff --git a/common/os/net.h b/common/os/net.h deleted file mode 100644 index bd8b21cc..00000000 --- a/common/os/net.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2008 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifndef OS_NET_H -#define OS_NET_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -/* IPv6 support on server side - we have to have all those functions */ -#if defined(HAVE_INET_NTOP) -#define HAVE_IPV6 -#endif - -/* IPv4-only stub implementation */ -#ifndef HAVE_INET_NTOP -const char *tight_inet_ntop(int af, const void *src, - char *dst, socklen_t size); -#define inet_ntop tight_inet_ntop -#endif - -#ifdef __cplusplus -}; -#endif - -#endif /* OS_NET_H */ diff --git a/common/os/print.c b/common/os/print.c deleted file mode 100644 index 4be22035..00000000 --- a/common/os/print.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (C) 2008 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <os/print.h> - -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#ifndef HAVE_VSNPRINTF -size_t internal_memcpy(char *dest, const char *src, size_t destsize, - size_t srcsize) { - size_t copied; - - copied = ((destsize) < (srcsize)) ? (destsize) : (srcsize); - memcpy(dest, src, copied); - - return copied; -} - -int tight_vsnprintf(char *str, size_t n, const char *format, va_list ap) { - int written = 0; - int tmpint, len; - char buf[64]; /* Is it enough? */ - char *tmpstr; - - if (format == NULL || n < 1) - return 0; - - while (*format != '\0' && written < n - 1) { - if (*format != '%') { - if (written < n) { - str[written++] = *format++; - continue; - } else - break; - } - - format++; - switch (*format) { - case '\0': - str[written++] = '%'; - continue; - case 'd': - tmpint = va_arg(ap, int); - sprintf(buf, "%d", tmpint); - len = strlen(buf); - written += internal_memcpy (&str[written], buf, - len, n - written); - break; - case 's': - tmpstr = va_arg(ap, char *); - len = strlen(tmpstr); - written += internal_memcpy (&str[written], - tmpstr, len, - n - written); - break; - /* Catch unimplemented stuff */ - default: - fprintf(stderr, "Unimplemented format: %c\n", - *format); - abort(); - } - format++; - } - - str[written] = '\0'; - - return written; -} -#endif /* HAVE_VSNPRINTF */ - -#ifndef HAVE_SNPRINTF -int tight_snprintf(char *str, size_t n, const char *format, ...) { - va_list ap; - int written; - - va_start(ap, format); - written = vsnprintf(str, n, format, ap); - va_end(ap); - - return written; -} -#endif /* HAVE_SNPRINTF */ - diff --git a/common/os/print.h b/common/os/print.h deleted file mode 100644 index 442dd642..00000000 --- a/common/os/print.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2008 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifndef OS_PRINT_H -#define OS_PRINT_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#include <stdio.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef HAVE_VSNPRINTF -/* NOTE: - * - * This is only very limited implementation for our internal purposes. It - * doesn't conform to C99/POSIX - * - limited conversion specifiers - * - returns written number of characters instead of number what would be - * written - */ -int tight_vsnprintf(char *str, size_t n, const char *format, va_list ap); -#define vsnprintf tight_vsnprintf -#endif - -#ifndef HAVE_SNPRINTF -/* Inherits tight_vsnprintf limitations if vsnprintf is not present */ -int tight_snprintf(char *str, size_t n, const char *format, ...); -#define snprintf tight_snprintf -#endif - -#ifdef __cplusplus -}; -#endif - -#endif /* OS_PRINT_H */ diff --git a/common/os/w32tiger.h b/common/os/w32tiger.h index 5e0c5de2..d09994f2 100644 --- a/common/os/w32tiger.h +++ b/common/os/w32tiger.h @@ -28,6 +28,11 @@ #include <wininet.h> +/* Windows has different names for these */ +#define strcasecmp _stricmp +#define strncasecmp _strnicmp + + /* MSLLHOOKSTRUCT structure*/ #ifndef LLMHF_INJECTED #define LLMHF_INJECTED 0x00000001 diff --git a/common/rdr/Exception.cxx b/common/rdr/Exception.cxx index fd40582f..d70cd9fc 100644 --- a/common/rdr/Exception.cxx +++ b/common/rdr/Exception.cxx @@ -22,6 +22,9 @@ #include <config.h> #endif +#include <stdio.h> +#include <stdarg.h> + #include <rdr/Exception.h> #include <rdr/TLSException.h> #ifdef _WIN32 @@ -30,8 +33,6 @@ #include <windows.h> #endif -#include <os/print.h> - #include <string.h> #ifdef HAVE_GNUTLS diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx index 260bd1a4..9d9f8ba1 100644 --- a/common/rdr/ZlibOutStream.cxx +++ b/common/rdr/ZlibOutStream.cxx @@ -17,9 +17,10 @@ * USA. */ +#include <stdio.h> + #include <rdr/ZlibOutStream.h> #include <rdr/Exception.h> -#include <os/print.h> #include <zlib.h> diff --git a/common/rdr/msvcwarning.h b/common/rdr/msvcwarning.h deleted file mode 100644 index bea8d3f4..00000000 --- a/common/rdr/msvcwarning.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// Trim out extraneous cruft from windows.h includes -#define WIN32_LEAN_AND_MEAN - -// Force all Windows NT-specific APIs to be visible -#define _WIN32_WINNT 0xffff - -#pragma warning( disable : 4800 ) // forcing bool 'true' or 'false' -#pragma warning( disable : 4786 ) // truncating debug information to 255 chars
\ No newline at end of file diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt index c2df95ad..9f5b59ec 100644 --- a/common/rfb/CMakeLists.txt +++ b/common/rfb/CMakeLists.txt @@ -52,7 +52,6 @@ set(RFB_SOURCES SSecurityStack.cxx SSecurityVncAuth.cxx SSecurityVeNCrypt.cxx - ScaledPixelBuffer.cxx ScaleFilters.cxx Timer.cxx TightDecoder.cxx diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h index d69d4f21..d7ffd65b 100644 --- a/common/rfb/CMsgHandler.h +++ b/common/rfb/CMsgHandler.h @@ -71,8 +71,8 @@ namespace rfb { virtual void imageRect(const Rect& r, void* pixels) = 0; virtual void copyRect(const Rect& r, int srcX, int srcY) = 0; - virtual rdr::U8* getRawPixelsRW(const Rect& r, int* stride) = 0; - virtual void releaseRawPixels(const Rect& r) = 0; + virtual rdr::U8* getRawBufferRW(const Rect& r, int* stride) = 0; + virtual void releaseRawBuffer(const Rect& r) = 0; virtual const PixelFormat &getPreferredPF(void) = 0; diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx index ddc25ff7..9ee7a02f 100644 --- a/common/rfb/CMsgWriter.cxx +++ b/common/rfb/CMsgWriter.cxx @@ -18,6 +18,7 @@ #include <stdio.h> #include <rdr/OutStream.h> #include <rfb/msgTypes.h> +#include <rfb/encodings.h> #include <rfb/PixelFormat.h> #include <rfb/Rect.h> #include <rfb/ConnParams.h> @@ -113,9 +114,9 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect) } } - if (cp->customCompressLevel && cp->compressLevel >= 0 && cp->compressLevel <= 9) + if (cp->compressLevel >= 0 && cp->compressLevel <= 9) encodings[nEncodings++] = pseudoEncodingCompressLevel0 + cp->compressLevel; - if (!cp->noJpeg && cp->qualityLevel >= 0 && cp->qualityLevel <= 9) + if (cp->qualityLevel >= 0 && cp->qualityLevel <= 9) encodings[nEncodings++] = pseudoEncodingQualityLevel0 + cp->qualityLevel; writeSetEncodings(nEncodings, encodings); diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index 59fd5067..a8abeeb0 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -42,7 +42,6 @@ #include <rdr/TLSInStream.h> #include <rdr/TLSOutStream.h> #include <os/os.h> -#include <os/print.h> #include <os/tls.h> #include <gnutls/x509.h> diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx index 1c2bd383..8d4311a1 100644 --- a/common/rfb/ComparingUpdateTracker.cxx +++ b/common/rfb/ComparingUpdateTracker.cxx @@ -53,7 +53,7 @@ bool ComparingUpdateTracker::compare() for (int y=0; y<fb->height(); y+=BLOCK_SIZE) { Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE)); int srcStride; - const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride); + const rdr::U8* srcData = fb->getBuffer(pos, &srcStride); oldFb.imageRect(pos, srcData, srcStride); } @@ -106,7 +106,7 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged) int bytesPerPixel = fb->getPF().bpp/8; int oldStride; - rdr::U8* oldData = oldFb.getPixelsRW(r, &oldStride); + rdr::U8* oldData = oldFb.getBufferRW(r, &oldStride); int oldStrideBytes = oldStride * bytesPerPixel; std::vector<Rect> changedBlocks; @@ -116,7 +116,7 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged) // Get a strip of the source buffer Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE)); int fbStride; - const rdr::U8* newBlockPtr = fb->getPixelsR(pos, &fbStride); + const rdr::U8* newBlockPtr = fb->getBuffer(pos, &fbStride); int newStrideBytes = fbStride * bytesPerPixel; rdr::U8* oldBlockPtr = oldData; diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx index 414b18f7..d7005221 100644 --- a/common/rfb/Configuration.cxx +++ b/common/rfb/Configuration.cxx @@ -22,10 +22,6 @@ #include <stdlib.h> #include <ctype.h> #include <string.h> -#ifdef WIN32 -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif #include <rfb/util.h> #include <rfb/Configuration.h> diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx index ed747523..6fd6668e 100644 --- a/common/rfb/ConnParams.cxx +++ b/common/rfb/ConnParams.cxx @@ -1,5 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,10 +36,8 @@ ConnParams::ConnParams() supportsDesktopRename(false), supportsLastRect(false), supportsSetDesktopSize(false), supportsFence(false), supportsContinuousUpdates(false), - customCompressLevel(false), compressLevel(2), - noJpeg(false), qualityLevel(-1), fineQualityLevel(-1), - subsampling(SUBSAMP_UNDEFINED), - name_(0), nEncodings_(0), encodings_(0), + compressLevel(2), qualityLevel(-1), fineQualityLevel(-1), + subsampling(subsampleUndefined), name_(0), currentEncoding_(encodingRaw), verStrPos(0) { setName(""); @@ -47,7 +46,6 @@ ConnParams::ConnParams() ConnParams::~ConnParams() { delete [] name_; - delete [] encodings_; } bool ConnParams::readVersion(rdr::InStream* is, bool* done) @@ -90,69 +88,80 @@ void ConnParams::setName(const char* name) void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings) { - if (nEncodings > nEncodings_) { - delete [] encodings_; - encodings_ = new rdr::S32[nEncodings]; - } - nEncodings_ = nEncodings; useCopyRect = false; supportsLocalCursor = false; supportsDesktopResize = false; supportsExtendedDesktopSize = false; supportsLocalXCursor = false; supportsLastRect = false; - customCompressLevel = false; compressLevel = -1; - noJpeg = true; qualityLevel = -1; fineQualityLevel = -1; - subsampling = SUBSAMP_UNDEFINED; + subsampling = subsampleUndefined; currentEncoding_ = encodingRaw; for (int i = nEncodings-1; i >= 0; i--) { - encodings_[i] = encodings[i]; - - if (encodings[i] == encodingCopyRect) + switch (encodings[i]) { + case encodingCopyRect: useCopyRect = true; - else if (encodings[i] == pseudoEncodingCursor) + break; + case pseudoEncodingCursor: supportsLocalCursor = true; - else if (encodings[i] == pseudoEncodingXCursor) + break; + case pseudoEncodingXCursor: supportsLocalXCursor = true; - else if (encodings[i] == pseudoEncodingDesktopSize) + break; + case pseudoEncodingDesktopSize: supportsDesktopResize = true; - else if (encodings[i] == pseudoEncodingExtendedDesktopSize) + break; + case pseudoEncodingExtendedDesktopSize: supportsExtendedDesktopSize = true; - else if (encodings[i] == pseudoEncodingDesktopName) + break; + case pseudoEncodingDesktopName: supportsDesktopRename = true; - else if (encodings[i] == pseudoEncodingLastRect) + break; + case pseudoEncodingLastRect: supportsLastRect = true; - else if (encodings[i] == pseudoEncodingFence) + break; + case pseudoEncodingFence: supportsFence = true; - else if (encodings[i] == pseudoEncodingContinuousUpdates) + break; + case pseudoEncodingContinuousUpdates: supportsContinuousUpdates = true; - else if (encodings[i] >= pseudoEncodingCompressLevel0 && - encodings[i] <= pseudoEncodingCompressLevel9) { - customCompressLevel = true; + break; + case pseudoEncodingSubsamp1X: + subsampling = subsampleNone; + break; + case pseudoEncodingSubsampGray: + subsampling = subsampleGray; + break; + case pseudoEncodingSubsamp2X: + subsampling = subsample2X; + break; + case pseudoEncodingSubsamp4X: + subsampling = subsample4X; + break; + case pseudoEncodingSubsamp8X: + subsampling = subsample8X; + break; + case pseudoEncodingSubsamp16X: + subsampling = subsample16X; + break; + } + + if (encodings[i] >= pseudoEncodingCompressLevel0 && + encodings[i] <= pseudoEncodingCompressLevel9) compressLevel = encodings[i] - pseudoEncodingCompressLevel0; - } else if (encodings[i] >= pseudoEncodingQualityLevel0 && - encodings[i] <= pseudoEncodingQualityLevel9) { - noJpeg = false; + + if (encodings[i] >= pseudoEncodingQualityLevel0 && + encodings[i] <= pseudoEncodingQualityLevel9) qualityLevel = encodings[i] - pseudoEncodingQualityLevel0; - } else if (Encoder::supported(encodings[i])) - currentEncoding_ = encodings[i]; - } - // If the TurboVNC fine quality/subsampling encodings exist, let them - // override the coarse TightVNC quality level - for (int i = nEncodings-1; i >= 0; i--) { - if (encodings[i] >= pseudoEncodingFineQualityLevel0 + 1 && - encodings[i] <= pseudoEncodingFineQualityLevel100) { - noJpeg = false; + if (encodings[i] >= pseudoEncodingFineQualityLevel0 && + encodings[i] <= pseudoEncodingFineQualityLevel100) fineQualityLevel = encodings[i] - pseudoEncodingFineQualityLevel0; - } else if (encodings[i] >= pseudoEncodingSubsamp1X && - encodings[i] <= pseudoEncodingSubsampGray) { - noJpeg = false; - subsampling = (JPEG_SUBSAMP)(encodings[i] - pseudoEncodingSubsamp1X); - } + + if (Encoder::supported(encodings[i])) + currentEncoding_ = encodings[i]; } } diff --git a/common/rfb/ConnParams.h b/common/rfb/ConnParams.h index fa0fe022..43267ffd 100644 --- a/common/rfb/ConnParams.h +++ b/common/rfb/ConnParams.h @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,12 +26,19 @@ #include <rdr/types.h> #include <rfb/PixelFormat.h> #include <rfb/ScreenSet.h> -#include <rfb/JpegCompressor.h> namespace rdr { class InStream; } namespace rfb { + const int subsampleUndefined = -1; + const int subsampleNone = 0; + const int subsampleGray = 1; + const int subsample2X = 2; + const int subsample4X = 3; + const int subsample8X = 4; + const int subsample16X = 5; + class ConnParams { public: ConnParams(); @@ -67,9 +75,9 @@ namespace rfb { void setName(const char* name); rdr::S32 currentEncoding() { return currentEncoding_; } - int nEncodings() { return nEncodings_; } - const rdr::S32* encodings() { return encodings_; } + void setEncodings(int nEncodings, const rdr::S32* encodings); + bool useCopyRect; bool supportsLocalCursor; @@ -83,19 +91,15 @@ namespace rfb { bool supportsFence; bool supportsContinuousUpdates; - bool customCompressLevel; int compressLevel; - bool noJpeg; int qualityLevel; int fineQualityLevel; - JPEG_SUBSAMP subsampling; + int subsampling; private: PixelFormat pf_; char* name_; - int nEncodings_; - rdr::S32* encodings_; int currentEncoding_; char verStr[13]; int verStrPos; diff --git a/common/rfb/Decoder.cxx b/common/rfb/Decoder.cxx index 193b61c0..e201821f 100644 --- a/common/rfb/Decoder.cxx +++ b/common/rfb/Decoder.cxx @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +17,7 @@ * USA. */ #include <stdio.h> -#include <rfb/Exception.h> +#include <rfb/encodings.h> #include <rfb/Decoder.h> #include <rfb/RawDecoder.h> #include <rfb/RREDecoder.h> @@ -30,41 +31,34 @@ Decoder::~Decoder() { } -DecoderCreateFnType Decoder::createFns[encodingMax+1] = { 0 }; - bool Decoder::supported(int encoding) { - return encoding >= 0 && encoding <= encodingMax && createFns[encoding]; + switch (encoding) { + case encodingRaw: + case encodingRRE: + case encodingHextile: + case encodingZRLE: + case encodingTight: + return true; + default: + return false; + } } Decoder* Decoder::createDecoder(int encoding, CMsgReader* reader) { - if (supported(encoding)) - return (*createFns[encoding])(reader); - return 0; -} - -void Decoder::registerDecoder(int encoding, - DecoderCreateFnType createFn) -{ - if (encoding > encodingMax) - throw Exception("Decoder::registerDecoder: encoding out of range"); - - if (createFns[encoding]) - fprintf(stderr,"Replacing existing decoder for encoding %s (%d)\n", - encodingName(encoding), encoding); - createFns[encoding] = createFn; -} - -int DecoderInit::count = 0; - -DecoderInit::DecoderInit() -{ - if (count++ != 0) return; - - Decoder::registerDecoder(encodingRaw, RawDecoder::create); - Decoder::registerDecoder(encodingRRE, RREDecoder::create); - Decoder::registerDecoder(encodingHextile, HextileDecoder::create); - Decoder::registerDecoder(encodingZRLE, ZRLEDecoder::create); - Decoder::registerDecoder(encodingTight, TightDecoder::create); + switch (encoding) { + case encodingRaw: + return new RawDecoder(reader); + case encodingRRE: + return new RREDecoder(reader); + case encodingHextile: + return new HextileDecoder(reader); + case encodingZRLE: + return new ZRLEDecoder(reader); + case encodingTight: + return new TightDecoder(reader); + default: + return NULL; + } } diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h index 50aee82f..025d63f5 100644 --- a/common/rfb/Decoder.h +++ b/common/rfb/Decoder.h @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,13 +20,10 @@ #define __RFB_DECODER_H__ #include <rfb/Rect.h> -#include <rfb/encodings.h> namespace rfb { class CMsgReader; class CMsgHandler; - class Decoder; - typedef Decoder* (*DecoderCreateFnType)(CMsgReader*); class Decoder { public: @@ -34,19 +32,7 @@ namespace rfb { static bool supported(int encoding); static Decoder* createDecoder(int encoding, CMsgReader* reader); - static void registerDecoder(int encoding, - DecoderCreateFnType createFn); - private: - static DecoderCreateFnType createFns[encodingMax+1]; }; - - class DecoderInit { - static int count; - public: - DecoderInit(); - }; - - static DecoderInit decoderInitObj; } #endif diff --git a/common/rfb/Encoder.cxx b/common/rfb/Encoder.cxx index 5de75430..1733c8ec 100644 --- a/common/rfb/Encoder.cxx +++ b/common/rfb/Encoder.cxx @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +17,7 @@ * USA. */ #include <stdio.h> +#include <rfb/encodings.h> #include <rfb/Exception.h> #include <rfb/Encoder.h> #include <rfb/RawEncoder.h> @@ -30,48 +32,34 @@ Encoder::~Encoder() { } -EncoderCreateFnType Encoder::createFns[encodingMax+1] = { 0 }; - bool Encoder::supported(int encoding) { - return encoding >= 0 && encoding <= encodingMax && createFns[encoding]; + switch (encoding) { + case encodingRaw: + case encodingRRE: + case encodingHextile: + case encodingZRLE: + case encodingTight: + return true; + default: + return false; + } } Encoder* Encoder::createEncoder(int encoding, SMsgWriter* writer) { - if (supported(encoding)) - return (*createFns[encoding])(writer); - return 0; -} - -void Encoder::registerEncoder(int encoding, - EncoderCreateFnType createFn) -{ - if (encoding > encodingMax) - throw Exception("Encoder::registerEncoder: encoding out of range"); - - if (createFns[encoding]) - fprintf(stderr,"Replacing existing encoder for encoding %s (%d)\n", - encodingName(encoding), encoding); - createFns[encoding] = createFn; -} - -void Encoder::unregisterEncoder(int encoding) -{ - if (encoding > encodingMax) - throw Exception("Encoder::unregisterEncoder: encoding out of range"); - createFns[encoding] = 0; -} - -int EncoderInit::count = 0; - -EncoderInit::EncoderInit() -{ - if (count++ != 0) return; - - Encoder::registerEncoder(encodingRaw, RawEncoder::create); - Encoder::registerEncoder(encodingRRE, RREEncoder::create); - Encoder::registerEncoder(encodingHextile, HextileEncoder::create); - Encoder::registerEncoder(encodingZRLE, ZRLEEncoder::create); - Encoder::registerEncoder(encodingTight, TightEncoder::create); + switch (encoding) { + case encodingRaw: + return new RawEncoder(writer); + case encodingRRE: + return new RREEncoder(writer); + case encodingHextile: + return new HextileEncoder(writer); + case encodingZRLE: + return new ZRLEEncoder(writer); + case encodingTight: + return new TightEncoder(writer); + default: + return NULL; + } } diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h index da2c5c09..26d57963 100644 --- a/common/rfb/Encoder.h +++ b/common/rfb/Encoder.h @@ -1,5 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,15 +21,11 @@ #define __RFB_ENCODER_H__ #include <rfb/Rect.h> -#include <rfb/encodings.h> #include <rfb/TransImageGetter.h> -#include <rfb/JpegCompressor.h> namespace rfb { class SMsgWriter; - class Encoder; - class ImageGetter; - typedef Encoder* (*EncoderCreateFnType)(SMsgWriter*); + class TransImageGetter; class Encoder { public: @@ -36,7 +33,7 @@ namespace rfb { virtual void setCompressLevel(int level) {}; virtual void setQualityLevel(int level) {}; - virtual void setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling) {}; + virtual void setFineQualityLevel(int quality, int subsampling) {}; virtual int getNumRects(const Rect &r) { return 1; } // writeRect() tries to write the given rectangle. If it is unable to @@ -47,20 +44,7 @@ namespace rfb { static bool supported(int encoding); static Encoder* createEncoder(int encoding, SMsgWriter* writer); - static void registerEncoder(int encoding, - EncoderCreateFnType createFn); - static void unregisterEncoder(int encoding); - private: - static EncoderCreateFnType createFns[encodingMax+1]; }; - - class EncoderInit { - static int count; - public: - EncoderInit(); - }; - - static EncoderInit encoderInitObj; } #endif diff --git a/common/rfb/HTTPServer.cxx b/common/rfb/HTTPServer.cxx index 94f06090..f50722ab 100644 --- a/common/rfb/HTTPServer.cxx +++ b/common/rfb/HTTPServer.cxx @@ -21,10 +21,6 @@ #include <rfb/util.h> #include <rdr/MemOutStream.h> -#ifdef WIN32 -#define strcasecmp _stricmp -#endif - using namespace rfb; using namespace rdr; diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx index e817c732..ae612676 100644 --- a/common/rfb/HextileDecoder.cxx +++ b/common/rfb/HextileDecoder.cxx @@ -34,11 +34,6 @@ using namespace rfb; #include <rfb/hextileDecode.h> #undef BPP -Decoder* HextileDecoder::create(CMsgReader* reader) -{ - return new HextileDecoder(reader); -} - HextileDecoder::HextileDecoder(CMsgReader* reader_) : reader(reader_) { } diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h index e7dd3d58..95a7f8a4 100644 --- a/common/rfb/HextileDecoder.h +++ b/common/rfb/HextileDecoder.h @@ -24,11 +24,10 @@ namespace rfb { class HextileDecoder : public Decoder { public: - static Decoder* create(CMsgReader* reader); - virtual void readRect(const Rect& r, CMsgHandler* handler); + HextileDecoder(CMsgReader* reader); virtual ~HextileDecoder(); + virtual void readRect(const Rect& r, CMsgHandler* handler); private: - HextileDecoder(CMsgReader* reader); CMsgReader* reader; }; } diff --git a/common/rfb/HextileEncoder.cxx b/common/rfb/HextileEncoder.cxx index 73f1f575..0907bab8 100644 --- a/common/rfb/HextileEncoder.cxx +++ b/common/rfb/HextileEncoder.cxx @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ -#include <rfb/ImageGetter.h> +#include <rfb/TransImageGetter.h> #include <rfb/encodings.h> #include <rfb/SMsgWriter.h> #include <rfb/HextileEncoder.h> @@ -45,11 +45,6 @@ BoolParameter improvedHextile("ImprovedHextile", #include <rfb/hextileEncodeBetter.h> #undef BPP -Encoder* HextileEncoder::create(SMsgWriter* writer) -{ - return new HextileEncoder(writer); -} - HextileEncoder::HextileEncoder(SMsgWriter* writer_) : writer(writer_) { } diff --git a/common/rfb/HextileEncoder.h b/common/rfb/HextileEncoder.h index 6b89643d..0c475a8e 100644 --- a/common/rfb/HextileEncoder.h +++ b/common/rfb/HextileEncoder.h @@ -24,11 +24,10 @@ namespace rfb { class HextileEncoder : public Encoder { public: - static Encoder* create(SMsgWriter* writer); - virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); + HextileEncoder(SMsgWriter* writer); virtual ~HextileEncoder(); + virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); private: - HextileEncoder(SMsgWriter* writer); SMsgWriter* writer; }; } diff --git a/common/rfb/JpegCompressor.cxx b/common/rfb/JpegCompressor.cxx index b3c5f7c4..c19af34e 100644 --- a/common/rfb/JpegCompressor.cxx +++ b/common/rfb/JpegCompressor.cxx @@ -1,5 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +22,7 @@ #include <rdr/Exception.h> #include <rfb/Rect.h> #include <rfb/PixelFormat.h> -#include <os/print.h> +#include <rfb/ConnParams.h> #include <stdio.h> extern "C" { @@ -32,6 +33,15 @@ extern "C" { using namespace rfb; // +// Special formats that libjpeg can have optimised code paths for +// + +static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16); +static const PixelFormat pfBGRX(32, 24, false, true, 255, 255, 255, 16, 8, 0); +static const PixelFormat pfXRGB(32, 24, false, true, 255, 255, 255, 8, 16, 24); +static const PixelFormat pfXBGR(32, 24, false, true, 255, 255, 255, 24, 16, 8); + +// // Error manager implmentation for the JPEG library // @@ -141,8 +151,8 @@ JpegCompressor::~JpegCompressor(void) delete cinfo; } -void JpegCompressor::compress(const rdr::U8 *buf, int pitch, const Rect& r, - const PixelFormat& pf, int quality, JPEG_SUBSAMP subsamp) +void JpegCompressor::compress(const rdr::U8 *buf, int stride, const Rect& r, + const PixelFormat& pf, int quality, int subsamp) { int w = r.width(); int h = r.height(); @@ -165,62 +175,58 @@ void JpegCompressor::compress(const rdr::U8 *buf, int pitch, const Rect& r, pixelsize = 3; #ifdef JCS_EXTENSIONS - // Try to have libjpeg read directly from our native format - if(pf.is888()) { - int redShift, greenShift, blueShift; - - if(pf.bigEndian) { - redShift = 24 - pf.redShift; - greenShift = 24 - pf.greenShift; - blueShift = 24 - pf.blueShift; - } else { - redShift = pf.redShift; - greenShift = pf.greenShift; - blueShift = pf.blueShift; - } - - if(redShift == 0 && greenShift == 8 && blueShift == 16) - cinfo->in_color_space = JCS_EXT_RGBX; - if(redShift == 16 && greenShift == 8 && blueShift == 0) - cinfo->in_color_space = JCS_EXT_BGRX; - if(redShift == 24 && greenShift == 16 && blueShift == 8) - cinfo->in_color_space = JCS_EXT_XBGR; - if(redShift == 8 && greenShift == 16 && blueShift == 24) - cinfo->in_color_space = JCS_EXT_XRGB; - - if (cinfo->in_color_space != JCS_RGB) { - srcBuf = (rdr::U8 *)buf; - pixelsize = 4; - } + // Try to have libjpeg output directly to our native format + // libjpeg can only handle some "standard" formats + if (pfRGBX.equal(pf)) + cinfo->in_color_space = JCS_EXT_RGBX; + else if (pfBGRX.equal(pf)) + cinfo->in_color_space = JCS_EXT_BGRX; + else if (pfXRGB.equal(pf)) + cinfo->in_color_space = JCS_EXT_XRGB; + else if (pfXBGR.equal(pf)) + cinfo->in_color_space = JCS_EXT_XBGR; + + if (cinfo->in_color_space != JCS_RGB) { + srcBuf = (rdr::U8 *)buf; + pixelsize = 4; } #endif - if (pitch == 0) pitch = w * pf.bpp / 8; + if (stride == 0) + stride = w; if (cinfo->in_color_space == JCS_RGB) { srcBuf = new rdr::U8[w * h * pixelsize]; srcBufIsTemp = true; - pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, pitch, h); - pitch = w * pixelsize; + pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, stride, h); + stride = w; } cinfo->input_components = pixelsize; jpeg_set_defaults(cinfo); - jpeg_set_quality(cinfo, quality, TRUE); - if(quality >= 96) cinfo->dct_method = JDCT_ISLOW; - else cinfo->dct_method = JDCT_FASTEST; + + if (quality >= 1 && quality <= 100) { + jpeg_set_quality(cinfo, quality, TRUE); + if (quality >= 96) + cinfo->dct_method = JDCT_ISLOW; + else + cinfo->dct_method = JDCT_FASTEST; + } switch (subsamp) { - case SUBSAMP_420: + case subsample16X: + case subsample8X: + // FIXME (fall through) + case subsample4X: cinfo->comp_info[0].h_samp_factor = 2; cinfo->comp_info[0].v_samp_factor = 2; break; - case SUBSAMP_422: + case subsample2X: cinfo->comp_info[0].h_samp_factor = 2; cinfo->comp_info[0].v_samp_factor = 1; break; - case SUBSAMP_GRAY: + case subsampleGray: jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); default: cinfo->comp_info[0].h_samp_factor = 1; @@ -229,7 +235,7 @@ void JpegCompressor::compress(const rdr::U8 *buf, int pitch, const Rect& r, rowPointer = new JSAMPROW[h]; for (int dy = 0; dy < h; dy++) - rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * pitch]); + rowPointer[dy] = (JSAMPROW)(&srcBuf[dy * stride * pixelsize]); jpeg_start_compress(cinfo, TRUE); while (cinfo->next_scanline < cinfo->image_height) diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h index d50e5871..8fbb7a9e 100644 --- a/common/rfb/JpegCompressor.h +++ b/common/rfb/JpegCompressor.h @@ -36,14 +36,6 @@ struct JPEG_DEST_MGR; namespace rfb { - enum JPEG_SUBSAMP { - SUBSAMP_UNDEFINED = -1, - SUBSAMP_NONE = 0, - SUBSAMP_420, - SUBSAMP_422, - SUBSAMP_GRAY - }; - class JpegCompressor : public rdr::MemOutStream { public: @@ -51,8 +43,7 @@ namespace rfb { JpegCompressor(int bufferLen = 128*1024); virtual ~JpegCompressor(); - void compress(const rdr::U8 *, int, const Rect&, const PixelFormat&, int, - JPEG_SUBSAMP); + void compress(const rdr::U8 *, int, const Rect&, const PixelFormat&, int, int); void writeBytes(const void*, int); diff --git a/common/rfb/JpegDecompressor.cxx b/common/rfb/JpegDecompressor.cxx index 503c030f..ca1ad226 100644 --- a/common/rfb/JpegDecompressor.cxx +++ b/common/rfb/JpegDecompressor.cxx @@ -1,6 +1,7 @@ /* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved. * Copyright (C) 2004-2005 Cendio AB. All rights reserved. * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +23,6 @@ #include <rdr/Exception.h> #include <rfb/Rect.h> #include <rfb/PixelFormat.h> -#include <os/print.h> #include <stdio.h> extern "C" { @@ -33,6 +33,14 @@ extern "C" { using namespace rfb; +// +// Special formats that libjpeg can have optimised code paths for +// + +static const PixelFormat pfRGBX(32, 24, false, true, 255, 255, 255, 0, 8, 16); +static const PixelFormat pfBGRX(32, 24, false, true, 255, 255, 255, 16, 8, 0); +static const PixelFormat pfXRGB(32, 24, false, true, 255, 255, 255, 8, 16, 24); +static const PixelFormat pfXBGR(32, 24, false, true, 255, 255, 255, 24, 16, 8); // // Error manager implmentation for the JPEG library @@ -139,12 +147,12 @@ JpegDecompressor::~JpegDecompressor(void) } void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen, - rdr::U8 *buf, int pitch, const Rect& r, const PixelFormat& pf) + rdr::U8 *buf, int stride, const Rect& r, const PixelFormat& pf) { int w = r.width(); int h = r.height(); int pixelsize; - int dstBufPitch; + int dstBufStride; rdr::U8 *dstBuf = NULL; bool dstBufIsTemp = false; JSAMPROW *rowPointer = NULL; @@ -163,50 +171,37 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen, jpeg_read_header(dinfo, TRUE); dinfo->out_color_space = JCS_RGB; pixelsize = 3; - if (pitch == 0) pitch = w * pf.bpp / 8; - dstBufPitch = pitch; + if (stride == 0) + stride = w; + dstBufStride = stride; #ifdef JCS_EXTENSIONS // Try to have libjpeg output directly to our native format - if (pf.is888()) { - int redShift, greenShift, blueShift; - - if(pf.bigEndian) { - redShift = 24 - pf.redShift; - greenShift = 24 - pf.greenShift; - blueShift = 24 - pf.blueShift; - } else { - redShift = pf.redShift; - greenShift = pf.greenShift; - blueShift = pf.blueShift; - } - - // libjpeg can only handle some "standard" formats - if(redShift == 0 && greenShift == 8 && blueShift == 16) - dinfo->out_color_space = JCS_EXT_RGBX; - if(redShift == 16 && greenShift == 8 && blueShift == 0) - dinfo->out_color_space = JCS_EXT_BGRX; - if(redShift == 24 && greenShift == 16 && blueShift == 8) - dinfo->out_color_space = JCS_EXT_XBGR; - if(redShift == 8 && greenShift == 16 && blueShift == 24) - dinfo->out_color_space = JCS_EXT_XRGB; - - if (dinfo->out_color_space != JCS_RGB) { - dstBuf = (rdr::U8 *)buf; - pixelsize = 4; - } + // libjpeg can only handle some "standard" formats + if (pfRGBX.equal(pf)) + dinfo->out_color_space = JCS_EXT_RGBX; + else if (pfBGRX.equal(pf)) + dinfo->out_color_space = JCS_EXT_BGRX; + else if (pfXRGB.equal(pf)) + dinfo->out_color_space = JCS_EXT_XRGB; + else if (pfXBGR.equal(pf)) + dinfo->out_color_space = JCS_EXT_XBGR; + + if (dinfo->out_color_space != JCS_RGB) { + dstBuf = (rdr::U8 *)buf; + pixelsize = 4; } #endif if (dinfo->out_color_space == JCS_RGB) { dstBuf = new rdr::U8[w * h * pixelsize]; dstBufIsTemp = true; - dstBufPitch = w * pixelsize; + dstBufStride = w; } rowPointer = new JSAMPROW[h]; for (int dy = 0; dy < h; dy++) - rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufPitch]); + rowPointer[dy] = (JSAMPROW)(&dstBuf[dy * dstBufStride * pixelsize]); jpeg_start_decompress(dinfo); @@ -225,7 +220,7 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf, int jpegBufLen, } if (dinfo->out_color_space == JCS_RGB) - pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, pitch, h); + pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, stride, h); jpeg_finish_decompress(dinfo); diff --git a/common/rfb/LogWriter.cxx b/common/rfb/LogWriter.cxx index c6461d14..37a9d1ce 100644 --- a/common/rfb/LogWriter.cxx +++ b/common/rfb/LogWriter.cxx @@ -19,9 +19,6 @@ // -=- LogWriter.cxx - client-side logging interface #include <string.h> -#ifdef WIN32 -#define strcasecmp _stricmp -#endif #include <rfb/LogWriter.h> #include <rfb/Configuration.h> diff --git a/common/rfb/Logger.cxx b/common/rfb/Logger.cxx index 451cee25..3daf2486 100644 --- a/common/rfb/Logger.cxx +++ b/common/rfb/Logger.cxx @@ -21,11 +21,7 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> -#ifdef WIN32 -#define strcasecmp _stricmp -#endif -#include <os/print.h> #include <rfb/Logger.h> #include <rfb/LogWriter.h> #include <rfb/util.h> diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx index 60957a25..9d151b97 100644 --- a/common/rfb/PixelBuffer.cxx +++ b/common/rfb/PixelBuffer.cxx @@ -48,7 +48,7 @@ ColourMap* PixelBuffer::getColourMap() const {return colourmap;} void PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) { int inStride; - const U8* data = getPixelsR(r, &inStride); + const U8* data = getBuffer(r, &inStride); // We assume that the specified rectangle is pre-clipped to the buffer int bytesPerPixel = format.bpp/8; int inBytesPerRow = inStride * bytesPerPixel; @@ -64,19 +64,6 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) { } } -/* *** -Pixel PixelBuffer::getPixel(const Point& p) { - int stride; - Rect r = Rect(p.x, p.y, p.x+1, p.y+1); - switch(format.bpp) { - case 8: return *((rdr::U8*)getDataAt(r, &stride)); - case 16: return *((rdr::U16*)getDataAt(r, &stride)); - case 32: return *((rdr::U32*)getDataAt(r, &stride)); - default: return 0; - }; -} -*/ - static void fillRect8(U8 *buf, int stride, const Rect& r, Pixel pix) { @@ -167,7 +154,7 @@ void FullFramePixelBuffer::setPF(const PixelFormat &pf) { int FullFramePixelBuffer::getStride() const { return width(); } -rdr::U8* FullFramePixelBuffer::getPixelsRW(const Rect& r, int* stride) +rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride) { *stride = getStride(); return &data[(r.tl.x + (r.tl.y * *stride)) * format.bpp/8]; @@ -176,14 +163,14 @@ rdr::U8* FullFramePixelBuffer::getPixelsRW(const Rect& r, int* stride) void FullFramePixelBuffer::fillRect(const Rect& r, Pixel pix) { int stride; - U8 *buf = getPixelsRW(r, &stride); + U8 *buf = getBufferRW(r, &stride); fillRectFn(buf, stride, r, pix); } void FullFramePixelBuffer::imageRect(const Rect& r, const void* pixels, int srcStride) { int bytesPerPixel = getPF().bpp/8; int destStride; - U8* dest = getPixelsRW(r, &destStride); + U8* dest = getBufferRW(r, &destStride); int bytesPerDestRow = bytesPerPixel * destStride; if (!srcStride) srcStride = r.width(); int bytesPerSrcRow = bytesPerPixel * srcStride; @@ -201,7 +188,7 @@ void FullFramePixelBuffer::maskRect(const Rect& r, const void* pixels, const voi Rect cr = getRect().intersect(r); if (cr.is_empty()) return; int stride; - U8* data = getPixelsRW(cr, &stride); + U8* data = getBufferRW(cr, &stride); U8* mask = (U8*) mask_; int w = cr.width(); int h = cr.height(); @@ -239,7 +226,7 @@ void FullFramePixelBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask Rect cr = getRect().intersect(r); if (cr.is_empty()) return; int stride; - U8* data = getPixelsRW(cr, &stride); + U8* data = getBufferRW(cr, &stride); U8* mask = (U8*) mask_; int w = cr.width(); int h = cr.height(); @@ -299,7 +286,7 @@ void FullFramePixelBuffer::copyRect(const Rect &rect, const Point &move_by_delta if (srect.is_empty()) return; - data = getPixelsRW(getRect(), &stride); + data = getBufferRW(getRect(), &stride); bytesPerPixel = getPF().bpp/8; bytesPerRow = stride * bytesPerPixel; bytesPerMemCpy = drect.width() * bytesPerPixel; diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h index e870622e..5c4f9666 100644 --- a/common/rfb/PixelBuffer.h +++ b/common/rfb/PixelBuffer.h @@ -70,18 +70,14 @@ namespace rfb { // Get a pointer into the buffer // The pointer is to the top-left pixel of the specified Rect. // The buffer stride (in pixels) is returned. - virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) = 0; - virtual rdr::U8* getPixelsRW(const Rect& r, int* stride) = 0; + virtual const rdr::U8* getBuffer(const Rect& r, int* stride) = 0; + virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0; // Get pixel data for a given part of the buffer // Data is copied into the supplied buffer, with the specified // stride. virtual void getImage(void* imageBuf, const Rect& r, int stride=0); - // Get the data at (x,y) as a Pixel. - // VERY INEFFICIENT!!! - // *** Pixel getPixel(const Point& p); - /////////////////////////////////////////////// // Framebuffer update methods // @@ -115,10 +111,10 @@ namespace rfb { virtual int getStride() const; // Get a pointer to specified pixel data - rdr::U8* getPixelsRW(const Rect& r, int* stride); - virtual const rdr::U8* getPixelsR(const Rect& r, int* stride) { - return getPixelsRW(r, stride); + virtual const rdr::U8* getBuffer(const Rect& r, int* stride) { + return getBufferRW(r, stride); } + virtual rdr::U8* getBufferRW(const Rect& r, int* stride); /////////////////////////////////////////////// // Basic rendering operations diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx index a2e94960..b11f8836 100644 --- a/common/rfb/PixelFormat.cxx +++ b/common/rfb/PixelFormat.cxx @@ -1,6 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009 Pierre Ossman for Cendio AB * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2009-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ #include <string.h> #include <rdr/InStream.h> #include <rdr/OutStream.h> +#include <rfb/Exception.h> #include <rfb/PixelFormat.h> #include <rfb/util.h> @@ -37,11 +38,7 @@ PixelFormat::PixelFormat(int b, int d, bool e, bool t, redMax(rm), greenMax(gm), blueMax(bm), redShift(rs), greenShift(gs), blueShift(bs) { - assert((bpp == 8) || (bpp == 16) || (bpp == 32)); - assert(depth <= bpp); - assert((redMax & (redMax + 1)) == 0); - assert((greenMax & (greenMax + 1)) == 0); - assert((blueMax & (blueMax + 1)) == 0); + assert(isSane()); updateState(); } @@ -82,6 +79,9 @@ void PixelFormat::read(rdr::InStream* is) blueShift = is->readU8(); is->skip(3); + if (!isSane()) + throw Exception("invalid pixel format"); + updateState(); } @@ -132,160 +132,58 @@ bool PixelFormat::isLittleEndian(void) const } -Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, - ColourMap* cm) const +void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, + int pixels, ColourMap* cm) const { - if (trueColour) { - rdr::U32 r = ((rdr::U32)red * redMax + 32767) / 65535; - rdr::U32 g = ((rdr::U32)green * greenMax + 32767) / 65535; - rdr::U32 b = ((rdr::U32)blue * blueMax + 32767) / 65535; - - return (r << redShift) | (g << greenShift) | (b << blueShift); - } else if (cm) { - // Try to find the closest pixel by Cartesian distance - int colours = 1 << depth; - int diff = 256 * 256 * 4; - int col = 0; - for (int i=0; i<colours; i++) { - int r, g, b; - cm->lookup(i, &r, &g, &b); - int rd = (r-red) >> 8; - int gd = (g-green) >> 8; - int bd = (b-blue) >> 8; - int d = rd*rd + gd*gd + bd*bd; - if (d < diff) { - col = i; - diff = d; - } - } - return col; - } - // XXX just return 0 for colour map? - return 0; + bufferFromRGB(dst, src, pixels, pixels, 1, cm); } - -Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, - ColourMap* cm) const -{ - if (trueColour) { - rdr::U32 r = ((rdr::U32)red * redMax + 127) / 255; - rdr::U32 g = ((rdr::U32)green * greenMax + 127) / 255; - rdr::U32 b = ((rdr::U32)blue * blueMax + 127) / 255; - - return (r << redShift) | (g << greenShift) | (b << blueShift); - } - - return pixelFromRGB((rdr::U16)(red << 8), (rdr::U16)(green << 8), - (rdr::U16)(blue << 8), cm); -} - - void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, - int pixels, ColourMap* cm) const + int w, int stride, int h, ColourMap* cm) const { if (is888()) { // Optimised common case - rdr::U8 *r, *g, *b; + rdr::U8 *r, *g, *b, *x; if (bigEndian) { r = dst + (24 - redShift)/8; g = dst + (24 - greenShift)/8; b = dst + (24 - blueShift)/8; + x = dst + (24 - (48 - redShift - greenShift - blueShift))/8; } else { r = dst + redShift/8; g = dst + greenShift/8; b = dst + blueShift/8; + x = dst + (48 - redShift - greenShift - blueShift)/8; } - while (pixels--) { - *r = *(src++); - *g = *(src++); - *b = *(src++); - r += 4; - g += 4; - b += 4; - } - } else { - // Generic code - Pixel p; - rdr::U8 r, g, b; - - while (pixels--) { - r = *(src++); - g = *(src++); - b = *(src++); - - p = pixelFromRGB(r, g, b, cm); - - bufferFromPixel(dst, p); - dst += bpp/8; - } - } -} - -#define trueColorBufferFromRGB(BPP) { \ - rdr::U8 r, g, b; \ - int dstPad = pitch - w * BPP / 8; \ - while (h > 0) { \ - rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * BPP / 8; \ - while (dst < dstEndOfRow) { \ - r = *(src++); \ - g = *(src++); \ - b = *(src++); \ - *(rdr::U##BPP *)dst = (((r * redMax + 127) / 255) << redShift) \ - | (((g * greenMax + 127) / 255) << greenShift) \ - | (((b * blueMax + 127) / 255) << blueShift); \ - dst += BPP / 8; \ - } \ - dst += dstPad; \ - h--; \ - } \ -} - -void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, - int w, int pitch, int h, ColourMap* cm) const -{ - if (is888()) { - // Optimised common case - int rindex, gindex, bindex; - - if (bigEndian) { - rindex = (24 - redShift)/8; - gindex = (24 - greenShift)/8; - bindex = (24 - blueShift)/8; - } else { - rindex = redShift/8; - gindex = greenShift/8; - bindex = blueShift/8; - } - - int dstPad = pitch - w * 4; - while (h > 0) { - rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * 4; - while (dst < dstEndOfRow) { - dst[rindex] = *(src++); - dst[gindex] = *(src++); - dst[bindex] = *(src++); - dst += 4; + int dstPad = (stride - w) * 4; + while (h--) { + int w_ = w; + while (w_--) { + *r = *(src++); + *g = *(src++); + *b = *(src++); + *x = 0; + r += 4; + g += 4; + b += 4; + x += 4; } - dst += dstPad; - h--; + r += dstPad; + g += dstPad; + b += dstPad; + x += dstPad; } - } else if (!cm && bpp == 16) { - trueColorBufferFromRGB(16); - } else if (!cm && bpp == 8) { - trueColorBufferFromRGB(8); } else { // Generic code - Pixel p; - rdr::U8 r, g, b; - int pixelSize = bpp/8; - - int dstPad = pitch - w * pixelSize; - while (h > 0) { - rdr::U8 *dstEndOfRow = (rdr::U8 *)dst + w * pixelSize; - while (dst < dstEndOfRow) { + int dstPad = (stride - w) * 4; + while (h--) { + int w_ = w; + while (w_--) { + Pixel p; + rdr::U8 r, g, b; + r = *(src++); g = *(src++); b = *(src++); @@ -293,10 +191,9 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, p = pixelFromRGB(r, g, b, cm); bufferFromPixel(dst, p); - dst += pixelSize; + dst += bpp/8; } dst += dstPad; - h--; } } } @@ -314,24 +211,14 @@ void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, Colour* rgb) const } -void PixelFormat::rgbFromBuffer(rdr::U16* dst, const rdr::U8* src, int pixels, ColourMap* cm) const +void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm) const { - Pixel p; - rdr::U16 r, g, b; - - while (pixels--) { - p = pixelFromBuffer(src); - src += bpp/8; - - rgbFromPixel(p, cm, &r, &g, &b); - *(dst++) = r; - *(dst++) = g; - *(dst++) = b; - } + rgbFromBuffer(dst, src, pixels, pixels, 1, cm); } -void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm) const +void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, + int w, int stride, int h, ColourMap* cm) const { if (is888()) { // Optimised common case @@ -347,81 +234,40 @@ void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, Co b = src + blueShift/8; } - while (pixels--) { - *(dst++) = *r; - *(dst++) = *g; - *(dst++) = *b; - r += 4; - g += 4; - b += 4; - } - } else { - // Generic code - Pixel p; - rdr::U8 r, g, b; - - while (pixels--) { - p = pixelFromBuffer(src); - src += bpp/8; - - rgbFromPixel(p, cm, &r, &g, &b); - *(dst++) = r; - *(dst++) = g; - *(dst++) = b; - } - } -} - - -void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, - int w, int pitch, int h, ColourMap* cm) const -{ - if (is888()) { - // Optimised common case - int rindex, gindex, bindex; - - if (bigEndian) { - rindex = (24 - redShift)/8; - gindex = (24 - greenShift)/8; - bindex = (24 - blueShift)/8; - } else { - rindex = redShift/8; - gindex = greenShift/8; - bindex = blueShift/8; - } - - int srcPad = pitch - w * 4; - while (h > 0) { - rdr::U8 *srcEndOfRow = (rdr::U8 *)src + w * 4; - while (src < srcEndOfRow) { - *(dst++) = src[rindex]; - *(dst++) = src[gindex]; - *(dst++) = src[bindex]; - src += 4; + int srcPad = (stride - w) * 4; + while (h--) { + int w_ = w; + while (w_--) { + *(dst++) = *r; + *(dst++) = *g; + *(dst++) = *b; + r += 4; + g += 4; + b += 4; } - src += srcPad; - h--; + r += srcPad; + g += srcPad; + b += srcPad; } } else { // Generic code - Pixel p; - rdr::U8 r, g, b; - int pixelSize = bpp/8; - - int srcPad = pitch - w * pixelSize; - while (h > 0) { - rdr::U8 *srcEndOfRow = (rdr::U8 *)src + w * pixelSize; - while (src < srcEndOfRow) { + int srcPad = (stride - w) * bpp/8; + while (h--) { + int w_ = w; + while (w_--) { + Pixel p; + rdr::U8 r, g, b; + p = pixelFromBuffer(src); rgbFromPixel(p, cm, &r, &g, &b); + *(dst++) = r; *(dst++) = g; *(dst++) = b; - src += pixelSize; + src += bpp/8; } src += srcPad; - h--; } } } @@ -531,6 +377,8 @@ bool PixelFormat::parse(const char* str) return false; } + assert(isSane()); + updateState(); return true; @@ -565,19 +413,72 @@ static int bits(rdr::U16 value) void PixelFormat::updateState(void) { - int redBits, greenBits, blueBits; int endianTest = 1; redBits = bits(redMax); greenBits = bits(greenMax); blueBits = bits(blueMax); - redConvShift = 16 - redBits; - greenConvShift = 16 - greenBits; - blueConvShift = 16 - blueBits; + maxBits = redBits; + if (greenBits > maxBits) + maxBits = greenBits; + if (blueBits > maxBits) + maxBits = blueBits; + + minBits = redBits; + if (greenBits < minBits) + minBits = greenBits; + if (blueBits < minBits) + minBits = blueBits; if (((*(char*)&endianTest) == 0) != bigEndian) endianMismatch = true; else endianMismatch = false; } + +bool PixelFormat::isSane(void) +{ + int totalBits; + + if ((bpp != 8) && (bpp != 16) && (bpp != 32)) + return false; + if (depth > bpp) + return false; + + if (!trueColour && (depth != 8)) + return false; + + if (trueColour) { + if ((redMax & (redMax + 1)) != 0) + return false; + if ((greenMax & (greenMax + 1)) != 0) + return false; + if ((blueMax & (blueMax + 1)) != 0) + return false; + + /* + * We don't allow individual channels > 8 bits in order to keep our + * conversions simple. + */ + if (redMax >= (1 << 8)) + return false; + if (greenMax >= (1 << 8)) + return false; + if (blueMax >= (1 << 8)) + return false; + + totalBits = bits(redMax) + bits(greenMax) + bits(blueMax); + if (totalBits > bpp) + return false; + + if (((redMax << redShift) & (greenMax << greenShift)) != 0) + return false; + if (((redMax << redShift) & (blueMax << blueShift)) != 0) + return false; + if (((greenMax << greenShift) & (blueMax << blueShift)) != 0) + return false; + } + + return true; +} diff --git a/common/rfb/PixelFormat.h b/common/rfb/PixelFormat.h index 88e80f4c..a8408ddd 100644 --- a/common/rfb/PixelFormat.h +++ b/common/rfb/PixelFormat.h @@ -1,5 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * Copyright (C) 2011 D. R. Commander. All Rights Reserved. + * Copyright 2009-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +19,16 @@ */ // // PixelFormat - structure to represent a pixel format. Also has useful -// methods for reading & writing to streams, etc. +// methods for reading & writing to streams, etc. Conversion to and from +// other formats are also handled by this class. We have three different +// representations that we refer to: +// +// a) Pixels - Unsigned native integers in the format specified by this +// PixelFormat object. +// b) Buffer - Same thing as pixels, but in the appropriate byte stream +// format. This involves endian conversion and padding. +// c) RGB - A byte stream of 8 bit red, green and blue elements, in that +// order. // #ifndef __RFB_PIXELFORMAT_H__ @@ -49,20 +59,19 @@ namespace rfb { inline Pixel pixelFromBuffer(const rdr::U8* buffer) const; inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const; - Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const; - Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const; + inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const; + inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const; void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; - void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int pitch, + void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int w, int stride, int h, ColourMap* cm=0) const; void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const; inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const; inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const; - void rgbFromBuffer(rdr::U16* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; - void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int pitch, + void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int stride, int h, ColourMap* cm=0) const; void print(char* str, int len) const; @@ -70,6 +79,7 @@ namespace rfb { protected: void updateState(void); + bool isSane(void); public: int bpp; @@ -87,9 +97,9 @@ namespace rfb { int blueShift; protected: - int redConvShift; - int greenConvShift; - int blueConvShift; + /* Pre-computed values to keep algorithms simple */ + int redBits, greenBits, blueBits; + int maxBits, minBits; bool endianMismatch; }; } diff --git a/common/rfb/PixelFormat.inl b/common/rfb/PixelFormat.inl index 90d8e6da..547fae5d 100644 --- a/common/rfb/PixelFormat.inl +++ b/common/rfb/PixelFormat.inl @@ -1,4 +1,4 @@ -/* Copyright 2009 Pierre Ossman for Cendio AB +/* Copyright 2009-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -75,13 +75,83 @@ inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const } -inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const +inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm) const { if (trueColour) { + Pixel p; + /* We don't need to mask since we shift out unwanted bits */ - *r = (p >> redShift) << redConvShift; - *g = (p >> greenShift) << greenConvShift; - *b = (p >> blueShift) << blueConvShift; + p = ((Pixel)red >> (16 - redBits)) << redShift; + p |= ((Pixel)green >> (16 - greenBits)) << greenShift; + p |= ((Pixel)blue >> (16 - blueBits)) << blueShift; + } else if (cm) { + // Try to find the closest pixel by Cartesian distance + int colours = 1 << depth; + int diff = 256 * 256 * 4; + int col = 0; + for (int i=0; i<colours; i++) { + int r, g, b; + cm->lookup(i, &r, &g, &b); + int rd = (r-red) >> 8; + int gd = (g-green) >> 8; + int bd = (b-blue) >> 8; + int d = rd*rd + gd*gd + bd*bd; + if (d < diff) { + col = i; + diff = d; + } + } + return col; + } else { + // XXX just return 0 for colour map? + return 0; + } +} + + +inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm) const +{ + if (trueColour) { + Pixel p; + + p = ((Pixel)red >> (8 - redBits)) << redShift; + p |= ((Pixel)green >> (8 - greenBits)) << greenShift; + p |= ((Pixel)blue >> (8 - blueBits)) << blueShift; + + return p; + } else { + return pixelFromRGB((rdr::U16)(red << 8 | red), + (rdr::U16)(green << 8 | green), + (rdr::U16)(blue << 8 | blue), cm); + } +} + + +inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const +{ + if (trueColour) { + int mb, rb, gb, bb; + + /* Bit replication is much cheaper than multiplication and division */ + + mb = minBits; + rb = redBits; + gb = greenBits; + bb = blueBits; + + *r = (p >> redShift) << (16 - rb); + *g = (p >> greenShift) << (16 - gb); + *b = (p >> blueShift) << (16 - bb); + + while (mb < 16) { + *r = *r | (*r >> rb); + *g = *g | (*g >> gb); + *b = *b | (*b >> bb); + mb <<= 1; + rb <<= 1; + gb <<= 1; + bb <<= 1; + } } else if (cm) { int ir, ig, ib; cm->lookup(p, &ir, &ig, &ib); @@ -100,9 +170,28 @@ inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr:: inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const { if (trueColour) { - *r = (p >> redShift) << (redConvShift - 8); - *g = (p >> greenShift) << (greenConvShift - 8); - *b = (p >> blueShift) << (blueConvShift - 8); + int mb, rb, gb, bb; + + /* Bit replication is much cheaper than multiplication and division */ + + mb = minBits; + rb = redBits; + gb = greenBits; + bb = blueBits; + + *r = (p >> redShift) << (8 - rb); + *g = (p >> greenShift) << (8 - gb); + *b = (p >> blueShift) << (8 - bb); + + while (mb < 8) { + *r = *r | (*r >> rb); + *g = *g | (*g >> gb); + *b = *b | (*b >> bb); + mb <<= 1; + rb <<= 1; + gb <<= 1; + bb <<= 1; + } } else { rdr::U16 r2, g2, b2; diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx index da56ee7c..b81a4a82 100644 --- a/common/rfb/RREDecoder.cxx +++ b/common/rfb/RREDecoder.cxx @@ -34,11 +34,6 @@ using namespace rfb; #include <rfb/rreDecode.h> #undef BPP -Decoder* RREDecoder::create(CMsgReader* reader) -{ - return new RREDecoder(reader); -} - RREDecoder::RREDecoder(CMsgReader* reader_) : reader(reader_) { } diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h index 2309f754..98abf982 100644 --- a/common/rfb/RREDecoder.h +++ b/common/rfb/RREDecoder.h @@ -24,11 +24,10 @@ namespace rfb { class RREDecoder : public Decoder { public: - static Decoder* create(CMsgReader* reader); - virtual void readRect(const Rect& r, CMsgHandler* handler); + RREDecoder(CMsgReader* reader); virtual ~RREDecoder(); + virtual void readRect(const Rect& r, CMsgHandler* handler); private: - RREDecoder(CMsgReader* reader); CMsgReader* reader; }; } diff --git a/common/rfb/RREEncoder.cxx b/common/rfb/RREEncoder.cxx index 1b86986f..36d46955 100644 --- a/common/rfb/RREEncoder.cxx +++ b/common/rfb/RREEncoder.cxx @@ -16,7 +16,7 @@ * USA. */ #include <rdr/OutStream.h> -#include <rfb/ImageGetter.h> +#include <rfb/TransImageGetter.h> #include <rfb/encodings.h> #include <rfb/SMsgWriter.h> #include <rfb/RREEncoder.h> @@ -33,11 +33,6 @@ using namespace rfb; #include <rfb/rreEncode.h> #undef BPP -Encoder* RREEncoder::create(SMsgWriter* writer) -{ - return new RREEncoder(writer); -} - RREEncoder::RREEncoder(SMsgWriter* writer_) : writer(writer_) { } diff --git a/common/rfb/RREEncoder.h b/common/rfb/RREEncoder.h index 6178d57f..f7d576eb 100644 --- a/common/rfb/RREEncoder.h +++ b/common/rfb/RREEncoder.h @@ -25,11 +25,10 @@ namespace rfb { class RREEncoder : public Encoder { public: - static Encoder* create(SMsgWriter* writer); - virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); + RREEncoder(SMsgWriter* writer); virtual ~RREEncoder(); + virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); private: - RREEncoder(SMsgWriter* writer); SMsgWriter* writer; rdr::MemOutStream mos; }; diff --git a/common/rfb/RawDecoder.cxx b/common/rfb/RawDecoder.cxx index 57cb37bc..5fd3b7c1 100644 --- a/common/rfb/RawDecoder.cxx +++ b/common/rfb/RawDecoder.cxx @@ -22,11 +22,6 @@ using namespace rfb; -Decoder* RawDecoder::create(CMsgReader* reader) -{ - return new RawDecoder(reader); -} - RawDecoder::RawDecoder(CMsgReader* reader_) : reader(reader_) { } diff --git a/common/rfb/RawDecoder.h b/common/rfb/RawDecoder.h index 9fdbb220..e09cca2d 100644 --- a/common/rfb/RawDecoder.h +++ b/common/rfb/RawDecoder.h @@ -24,11 +24,10 @@ namespace rfb { class RawDecoder : public Decoder { public: - static Decoder* create(CMsgReader* reader); - virtual void readRect(const Rect& r, CMsgHandler* handler); + RawDecoder(CMsgReader* reader); virtual ~RawDecoder(); + virtual void readRect(const Rect& r, CMsgHandler* handler); private: - RawDecoder(CMsgReader* reader); CMsgReader* reader; }; } diff --git a/common/rfb/RawEncoder.cxx b/common/rfb/RawEncoder.cxx index 5612cb8d..4b8de6ba 100644 --- a/common/rfb/RawEncoder.cxx +++ b/common/rfb/RawEncoder.cxx @@ -16,18 +16,13 @@ * USA. */ #include <rdr/OutStream.h> -#include <rfb/ImageGetter.h> +#include <rfb/TransImageGetter.h> #include <rfb/encodings.h> #include <rfb/SMsgWriter.h> #include <rfb/RawEncoder.h> using namespace rfb; -Encoder* RawEncoder::create(SMsgWriter* writer) -{ - return new RawEncoder(writer); -} - RawEncoder::RawEncoder(SMsgWriter* writer_) : writer(writer_) { } diff --git a/common/rfb/RawEncoder.h b/common/rfb/RawEncoder.h index 34dba0b5..22d45dbf 100644 --- a/common/rfb/RawEncoder.h +++ b/common/rfb/RawEncoder.h @@ -24,11 +24,10 @@ namespace rfb { class RawEncoder : public Encoder { public: - static Encoder* create(SMsgWriter* writer); - virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); + RawEncoder(SMsgWriter* writer); virtual ~RawEncoder(); + virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); private: - RawEncoder(SMsgWriter* writer); SMsgWriter* writer; }; } diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index f47f3eeb..509ffbf5 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -122,18 +122,6 @@ bool SMsgWriter::needFakeUpdate() return false; } -// FIXME: This functions is not used because it incorrectly computes -// the number of rectangles if the Tight encoder is used. -/* -void SMsgWriter::writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig, - Region* updatedRegion) -{ - writeFramebufferUpdateStart(ui.numRects()); - writeRects(ui, ig, updatedRegion); - writeFramebufferUpdateEnd(); -} -*/ - bool SMsgWriter::needNoDataUpdate() { return false; diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index 3933b38c..edf29447 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -109,18 +109,6 @@ namespace rfb { // order to flush out pseudo-rectangles to the client. virtual bool needFakeUpdate(); - // writeFramebufferUpdate() writes a framebuffer update using the given - // UpdateInfo and ImageGetter. On a V3 writer this may have - // pseudo-rectangles for setDesktopSize and setCursor added to it, and so - // may invoke writeSetCursorCallback(). - // - // FIXME: This function is not used because it incorrectly computes - // the number of rectangles if the Tight encoder is used. - /* - virtual void writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig, - Region* updatedRegion); - */ - // needNoDataUpdate() returns true when an update without any // framebuffer changes need to be sent (using writeNoDataUpdate()). // Commonly this is an update that modifies the size of the framebuffer diff --git a/common/rfb/ScaleFilters.cxx b/common/rfb/ScaleFilters.cxx index 07f3db85..3e414d90 100644 --- a/common/rfb/ScaleFilters.cxx +++ b/common/rfb/ScaleFilters.cxx @@ -23,10 +23,6 @@ #include <rfb/Rect.h> #include <rfb/ScaleFilters.h> -#ifdef _WIN32 -#define strcasecmp _stricmp -#endif - using namespace rfb; // diff --git a/common/rfb/ScaledPixelBuffer.cxx b/common/rfb/ScaledPixelBuffer.cxx deleted file mode 100644 index dc6096d7..00000000 --- a/common/rfb/ScaledPixelBuffer.cxx +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright (C) 2005 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ScaledPixelBuffer.cxx - -#include <rfb/Exception.h> -#include <rfb/ScaledPixelBuffer.h> - -#include <math.h> -#include <memory.h> -#include <stdlib.h> - -using namespace rdr; -using namespace rfb; - -ScaledPixelBuffer::ScaledPixelBuffer(U8 **src_data_, int src_width_, - int src_height_, int scale_, PixelFormat pf_) - : scale(scale_), scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBilinear), - xWeightTabs(0), yWeightTabs(0), raccum(0), gaccum(0), baccum(0), scaled_data(0) { - - setSourceBuffer(src_data_, src_width_, src_height_); - setPF(pf_); -} - -ScaledPixelBuffer::ScaledPixelBuffer() - : src_width(0), src_height(0), scaled_width(0), scaled_height(0), scale(100), - scale_ratio_x(1), scale_ratio_y(1), scaleFilterID(scaleFilterBilinear), - xWeightTabs(0), yWeightTabs(0), raccum(0), gaccum(0), baccum(0), - src_data(0), scaled_data(0) { - memset(&pf, 0, sizeof(pf)); -} - -ScaledPixelBuffer::~ScaledPixelBuffer() { - freeWeightTabs(); - if (raccum) delete [] raccum; - if (gaccum) delete [] gaccum; - if (baccum) delete [] baccum; -} - -void ScaledPixelBuffer::freeWeightTabs() { - if (xWeightTabs) { - for (int i = 0; i < scaled_width; i++) delete [] xWeightTabs[i].weight; - delete [] xWeightTabs; - xWeightTabs = 0; - } - if (yWeightTabs) { - for (int i = 0; i < scaled_height; i++) delete [] yWeightTabs[i].weight; - delete [] yWeightTabs; - yWeightTabs = 0; - } -} - -void ScaledPixelBuffer::recreateRowAccum() { - if (raccum) delete [] raccum; - if (gaccum) delete [] gaccum; - if (baccum) delete [] baccum; - raccum = new int[src_width]; - gaccum = new int[src_width]; - baccum = new int[src_width]; -} - -void ScaledPixelBuffer::setSourceBuffer(U8 **src_data_, int w, int h) { - if (w > 0 && h > 0 && src_data_ != NULL) { - freeWeightTabs(); - src_data = src_data_; - src_width = w; - src_height = h; - recreateRowAccum(); - calculateScaledBufferSize(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); - } -} - -void ScaledPixelBuffer::setPF(const PixelFormat &pf_) { - ///if (pf_.depth != 24) throw rfb::UnsupportedPixelFormatException(); - pf = pf_; -} - -void ScaledPixelBuffer::setScale(int scale_) { - if (scale != scale_ && scale_ > 0) { - scale = scale_; - freeWeightTabs(); - calculateScaledBufferSize(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); - } -} - -void ScaledPixelBuffer::setScaleFilter(unsigned int scaleFilterID_) { - if (scaleFilterID == scaleFilterID_ || scaleFilterID_ > scaleFilterMaxNumber) return; - - scaleFilterID = scaleFilterID_; - - if (src_width && src_height && scaled_width && scaled_height) { - freeWeightTabs(); - scaleFilters.makeWeightTabs(scaleFilterID, src_width, scaled_width, &xWeightTabs); - scaleFilters.makeWeightTabs(scaleFilterID, src_height, scaled_height, &yWeightTabs); - if (scale != 100 && pf.depth > 0 && scaled_data) scaleRect(Rect(0, 0, src_width, src_height)); - } -} - -inline U32 ScaledPixelBuffer::getSourcePixel(int x, int y) { - int bytes_per_pixel = pf.bpp / 8; - U8 *ptr = &(*src_data)[(x + y*src_width)*bytes_per_pixel]; - if (bytes_per_pixel == 1) { - return *ptr; - } else if (bytes_per_pixel == 2) { - int b0 = *ptr++; int b1 = *ptr; - return b1 << 8 | b0; - } else if (bytes_per_pixel == 4) { - int b0 = *ptr++; int b1 = *ptr++; - int b2 = *ptr++; int b3 = *ptr; - return b3 << 24 | b2 << 16 | b1 << 8 | b0; - } else { - return 0; - } -} - -void ScaledPixelBuffer::scaleRect(const Rect& rect) { - Rect changed_rect; - U8 *ptr, *ptrs, *px, *pxs; - U16 r, g, b; - int red, green, blue; - short *xweight, *yweight, weight; - - // Calculate the changed pixel rect in the scaled image - changed_rect = calculateScaleBoundary(rect); - - int bytesPerSrcPixel = pf.bpp / 8; - int bytesPerSrcRow = src_width * bytesPerSrcPixel; - int bytesPerScaledRow = scaled_width * 4; - - int bytesPerAccumRow = src_width * sizeof(int); - - ptrs = &(*scaled_data)[(changed_rect.tl.x + changed_rect.tl.y*scaled_width) * 4]; - for (int y = changed_rect.tl.y; y < changed_rect.br.y; y++) { - ptr = ptrs; - yweight = yWeightTabs[y].weight; - - // Clear the color accumulators - memset(raccum, 0, bytesPerAccumRow); - memset(gaccum, 0, bytesPerAccumRow); - memset(baccum, 0, bytesPerAccumRow); - - // Make the convolution the source image with scale filter weights - // by y axis and save results to the color accumulators. - pxs = &(*src_data)[(xWeightTabs[changed_rect.tl.x].i0 + yWeightTabs[y].i0*src_width) * bytesPerSrcPixel]; - for (int ys = yWeightTabs[y].i0; ys < yWeightTabs[y].i1; ys++) { - px = pxs; - for (int xs = xWeightTabs[changed_rect.tl.x].i0; xs < xWeightTabs[changed_rect.br.x-1].i1; xs++) { - pf.rgbFromPixel(*((U32*)px), NULL, &r, &g, &b); - weight = *yweight; - raccum[xs] += (int)(weight) * r; - gaccum[xs] += (int)(weight) * g; - baccum[xs] += (int)(weight) * b; - px += bytesPerSrcPixel; - } - yweight++; - pxs += bytesPerSrcRow; - } - - // Make the convolution the color accumulators with scale filter weights - // by x axis and save results to the scaled image. - for (int x = changed_rect.tl.x; x < changed_rect.br.x; x++) { - // Init the sum of colors with (1 << (shift-1)) for rounding. - red = green = blue = 1 << (FINALSHIFT-1); - xweight = xWeightTabs[x].weight; - for (int xs = xWeightTabs[x].i0; xs < xWeightTabs[x].i1; xs++) { - weight = *xweight; - red += (int)(weight) * (raccum[xs] >> BITS_OF_CHANEL); - green += (int)(weight) * (gaccum[xs] >> BITS_OF_CHANEL); - blue += (int)(weight) * (baccum[xs] >> BITS_OF_CHANEL); - xweight++; - } - *ptr++ = U8(blue >> FINALSHIFT); - *ptr++ = U8(green >> FINALSHIFT); - *ptr++ = U8(red >> FINALSHIFT); - ptr++; - } - ptrs += bytesPerScaledRow; - } -} - -Rect ScaledPixelBuffer::calculateScaleBoundary(const Rect& r) { - int x_start, y_start, x_end, y_end; - double translate_x = 0.5*scale_ratio_x - 0.5; - double translate_y = 0.5*scale_ratio_y - 0.5; - double sourceXScale = __rfbmax(1.0, 1.0/scale_ratio_x); - double sourceYScale = __rfbmax(1.0, 1.0/scale_ratio_y); - double sourceXRadius = __rfbmax(0.5, sourceXScale*scaleFilters[scaleFilterID].radius); - double sourceYRadius = __rfbmax(0.5, sourceYScale*scaleFilters[scaleFilterID].radius); - x_start = (int)ceil(scale_ratio_x*(r.tl.x-sourceXRadius) + translate_x + SCALE_ERROR); - y_start = (int)ceil(scale_ratio_y*(r.tl.y-sourceYRadius) + translate_y + SCALE_ERROR); - x_end = (int)floor(scale_ratio_x*((r.br.x-1)+sourceXRadius) + translate_x - SCALE_ERROR) + 1; - y_end = (int)floor(scale_ratio_y*((r.br.y-1)+sourceXRadius) + translate_y - SCALE_ERROR) + 1; - if (x_start < 0) x_start = 0; - if (y_start < 0) y_start = 0; - if (x_end > scaled_width) x_end = scaled_width; - if (y_end > scaled_height) y_end = scaled_height; - return Rect(x_start, y_start, x_end, y_end); -} - -void ScaledPixelBuffer::calculateScaledBufferSize() { - double scale_ratio = (double)scale / 100; - scaled_width = (int)ceil(src_width * scale_ratio); - scaled_height = (int)ceil(src_height * scale_ratio); - scale_ratio_x = (double)scaled_width / src_width; - scale_ratio_y = (double)scaled_height / src_height; -} diff --git a/common/rfb/ScaledPixelBuffer.h b/common/rfb/ScaledPixelBuffer.h deleted file mode 100644 index 453ab78c..00000000 --- a/common/rfb/ScaledPixelBuffer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2005 TightVNC Team. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ScaledPixelBuffer.h -// -// The ScaledPixelBuffer class allows to scale the image data -// from the source buffer to destination buffer using bilinear -// interpolation. - -#ifndef __RFB_SCALEDPIXELBUFFER_H__ -#define __RFB_SCALEDPIXELBUFFER_H__ - -#include <rdr/types.h> -#include <rdr/Exception.h> -#include <rfb/Rect.h> -#include <rfb/PixelFormat.h> -#include <rfb/ScaleFilters.h> - -using namespace rdr; - -namespace rfb { - - struct UnsupportedPixelFormatException : public Exception { - UnsupportedPixelFormatException(const char* s="Now supported only true colour pixel data in the scaling mode.") - : Exception(s) {} - }; - - class ScaledPixelBuffer { - public: - ScaledPixelBuffer(U8 **data, int width, int height, int scale, PixelFormat pf); - ScaledPixelBuffer(); - virtual ~ScaledPixelBuffer(); - - // Get width, height, number of pixels and scale - int width() const { return scaled_width; } - int height() const { return scaled_height; } - int getSrcWidth() const { return src_width; } - int getSrcHeight() const { return src_height; } - int area() const { return scaled_width * scaled_height; } - int getScale() const { return scale; } - double getScaleRatioX() const { return scale_ratio_x; } - double getScaleRatioY() const { return scale_ratio_y; } - - // Pixel manipulation routines - inline U32 getSourcePixel(int x, int y); - - // Get rectangle encompassing this buffer - // Top-left of rectangle is either at (0,0), or the specified point. - Rect getRect() const { return Rect(0, 0, scaled_width, scaled_height); } - Rect getRect(const Point& pos) const { - return Rect(pos, pos.translate(Point(scaled_width, scaled_height))); - } - - // Set the new source buffer and its parameters - void setSourceBuffer(U8 **src_data, int w, int h); - - void setScaledBuffer(U8 **scaled_data_) { - scaled_data = scaled_data_; - }; - - // Set the new pixel format - void setPF(const PixelFormat &pf); - - // Set the new scale, in percent - virtual void setScale(int scale); - - // Set/get the scale method - virtual void setScaleFilter(unsigned int scaleFilterID); - unsigned int getScaleFilterID() const { return scaleFilterID; } - - // Scale rect from the source image buffer to the destination buffer - // using the current interpolation method - virtual void scaleRect(const Rect& r); - - // Calculate the scaled image rectangle which depend on the source - // image rectangle. - Rect calculateScaleBoundary(const Rect& r); - - protected: - - // Calculate the scaled buffer size depending on the source buffer - // parameters (width, height, pixel format) - virtual void calculateScaledBufferSize(); - - // Free the weight tabs for x and y - virtual void freeWeightTabs(); - - // Recreates the row accumulators. - virtual void recreateRowAccum(); - - - int src_width; - int src_height; - int scaled_width; - int scaled_height; - int scale; - double scale_ratio_x; - double scale_ratio_y; - PixelFormat pf; - unsigned int scaleFilterID; - ScaleFilters scaleFilters; - SFilterWeightTab *xWeightTabs; - SFilterWeightTab *yWeightTabs; - int *raccum; - int *gaccum; - int *baccum; - U8 **src_data; - U8 **scaled_data; - }; - -}; - -#endif diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx index 238f3351..62ea50e6 100644 --- a/common/rfb/Security.cxx +++ b/common/rfb/Security.cxx @@ -24,9 +24,6 @@ #include <assert.h> #include <stdlib.h> #include <string.h> -#ifdef _WIN32 -#define strcasecmp _stricmp -#endif #include <rfb/CSecurityNone.h> #include <rfb/CSecurityStack.h> #include <rfb/CSecurityVeNCrypt.h> diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx index b3d174a3..d4ee877f 100644 --- a/common/rfb/TightDecoder.cxx +++ b/common/rfb/TightDecoder.cxx @@ -37,11 +37,6 @@ using namespace rfb; #include <rfb/tightDecode.h> #undef BPP -Decoder* TightDecoder::create(CMsgReader* reader) -{ - return new TightDecoder(reader); -} - TightDecoder::TightDecoder(CMsgReader* reader_) : reader(reader_) { } diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h index 5cdf873b..8200d2b8 100644 --- a/common/rfb/TightDecoder.h +++ b/common/rfb/TightDecoder.h @@ -28,9 +28,9 @@ namespace rfb { class TightDecoder : public Decoder { public: - static Decoder* create(CMsgReader* reader); - virtual void readRect(const Rect& r, CMsgHandler* handler); + TightDecoder(CMsgReader* reader); virtual ~TightDecoder(); + virtual void readRect(const Rect& r, CMsgHandler* handler); private: void tightDecode8(const Rect& r); @@ -54,8 +54,6 @@ namespace rfb { void directFillRect16(const Rect& r, Pixel pix); void directFillRect32(const Rect& r, Pixel pix); - TightDecoder(CMsgReader* reader); - CMsgReader* reader; CMsgHandler* handler; rdr::InStream* is; diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx index 9be4581e..733365e0 100644 --- a/common/rfb/TightEncoder.cxx +++ b/common/rfb/TightEncoder.cxx @@ -17,6 +17,7 @@ * USA. */ #include <rdr/OutStream.h> +#include <rfb/TransImageGetter.h> #include <rfb/encodings.h> #include <rfb/ConnParams.h> #include <rfb/SMsgWriter.h> @@ -63,16 +64,16 @@ using namespace rfb; // 0 = JPEG quality 15, 4:2:0 subsampling (ratio ~= 100:1) const TIGHT_CONF TightEncoder::conf[10] = { - { 65536, 2048, 6, 0, 0, 0, 4, 24, 15, SUBSAMP_420 }, // 0 - { 65536, 2048, 6, 1, 1, 1, 8, 24, 29, SUBSAMP_420 }, // 1 - { 65536, 2048, 8, 3, 3, 2, 24, 96, 41, SUBSAMP_420 }, // 2 - { 65536, 2048, 12, 5, 5, 2, 32, 96, 42, SUBSAMP_422 }, // 3 - { 65536, 2048, 12, 6, 7, 3, 32, 96, 62, SUBSAMP_422 }, // 4 - { 65536, 2048, 12, 7, 8, 4, 32, 96, 77, SUBSAMP_422 }, // 5 - { 65536, 2048, 16, 7, 8, 5, 32, 96, 79, SUBSAMP_NONE }, // 6 - { 65536, 2048, 16, 8, 9, 6, 64, 96, 86, SUBSAMP_NONE }, // 7 - { 65536, 2048, 24, 9, 9, 7, 64, 96, 92, SUBSAMP_NONE }, // 8 - { 65536, 2048, 32, 9, 9, 9, 96, 96,100, SUBSAMP_NONE } // 9 + { 65536, 2048, 6, 0, 0, 0, 4, 24, 15, subsample4X }, // 0 + { 65536, 2048, 6, 1, 1, 1, 8, 24, 29, subsample4X }, // 1 + { 65536, 2048, 8, 3, 3, 2, 24, 96, 41, subsample4X }, // 2 + { 65536, 2048, 12, 5, 5, 2, 32, 96, 42, subsample2X }, // 3 + { 65536, 2048, 12, 6, 7, 3, 32, 96, 62, subsample2X }, // 4 + { 65536, 2048, 12, 7, 8, 4, 32, 96, 77, subsample2X }, // 5 + { 65536, 2048, 16, 7, 8, 5, 32, 96, 79, subsampleNone }, // 6 + { 65536, 2048, 16, 8, 9, 6, 64, 96, 86, subsampleNone }, // 7 + { 65536, 2048, 24, 9, 9, 7, 64, 96, 92, subsampleNone }, // 8 + { 65536, 2048, 32, 9, 9, 9, 96, 96,100, subsampleNone } // 9 }; const int TightEncoder::defaultCompressLevel = 2; @@ -91,11 +92,6 @@ const int TightEncoder::defaultCompressLevel = 2; #include <rfb/tightEncode.h> #undef BPP -Encoder* TightEncoder::create(SMsgWriter* writer) -{ - return new TightEncoder(writer); -} - TightEncoder::TightEncoder(SMsgWriter* writer_) : writer(writer_) { setCompressLevel(defaultCompressLevel); @@ -122,18 +118,14 @@ void TightEncoder::setQualityLevel(int level) jpegSubsampling = conf[level].jpegSubsampling; } else { jpegQuality = -1; - jpegSubsampling = SUBSAMP_UNDEFINED; + jpegSubsampling = subsampleUndefined; } } -void TightEncoder::setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling) +void TightEncoder::setFineQualityLevel(int quality, int subsampling) { - if (quality >= 1 && quality <= 100) { - jpegQuality = quality; - } - if (subsampling >= SUBSAMP_NONE && subsampling <= SUBSAMP_GRAY) { - jpegSubsampling = subsampling; - } + jpegQuality = quality; + jpegSubsampling = subsampling; } bool TightEncoder::checkSolidTile(Rect& r, rdr::U32* colorPtr, @@ -345,7 +337,7 @@ bool TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig, sr.setXYWH(dx, dy, dw, dh); if (checkSolidTile(sr, &colorValue, false)) { - if (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1) { + if (jpegSubsampling == subsampleGray && jpegQuality != -1) { Colour rgb; serverpf.rgbFromPixel(colorValue, NULL, &rgb); rdr::U32 lum = ((257 * rgb.r) + (504 * rgb.g) + (98 * rgb.b) diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h index 4fff0832..3632539d 100644 --- a/common/rfb/TightEncoder.h +++ b/common/rfb/TightEncoder.h @@ -21,8 +21,8 @@ #include <rdr/MemOutStream.h> #include <rdr/ZlibOutStream.h> -#include <rfb/TransImageGetter.h> #include <rfb/Encoder.h> +#include <rfb/JpegCompressor.h> // FIXME: Check if specifying extern "C" is really necessary. #include <stdio.h> @@ -32,6 +32,8 @@ extern "C" { namespace rfb { + class TransImageGetter; + struct TIGHT_CONF { unsigned int maxRectSize, maxRectWidth; unsigned int monoMinRectSize; @@ -39,7 +41,7 @@ namespace rfb { int idxMaxColorsDivisor; int palMaxColorsWithJPEG; int jpegQuality; - JPEG_SUBSAMP jpegSubsampling; + int jpegSubsampling; }; // @@ -77,16 +79,16 @@ namespace rfb { class TightEncoder : public Encoder { public: - static Encoder* create(SMsgWriter* writer); + TightEncoder(SMsgWriter* writer); + virtual ~TightEncoder(); + virtual void setCompressLevel(int level); virtual void setQualityLevel(int level); - virtual void setFineQualityLevel(int quality, JPEG_SUBSAMP subsampling); + virtual void setFineQualityLevel(int quality, int subsampling); virtual int getNumRects(const Rect &r); virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); - virtual ~TightEncoder(); private: - TightEncoder(SMsgWriter* writer); bool checkSolidTile(Rect& r, rdr::U32* colorPtr, bool needSameColor); void extendSolidArea(const Rect& r, rdr::U32 colorValue, Rect& er); void findBestSolidArea(Rect& r, rdr::U32 colorValue, Rect& bestr); @@ -157,7 +159,7 @@ namespace rfb { const TIGHT_CONF* pconf; int jpegQuality; - JPEG_SUBSAMP jpegSubsampling; + int jpegSubsampling; }; } diff --git a/common/rfb/TransImageGetter.cxx b/common/rfb/TransImageGetter.cxx index c1add1ce..3900d065 100644 --- a/common/rfb/TransImageGetter.cxx +++ b/common/rfb/TransImageGetter.cxx @@ -56,18 +56,18 @@ void TransImageGetter::setColourMapEntries(int firstCol, int nCols) PixelTransformer::setColourMapEntries(firstCol, nCols); } -const rdr::U8 *TransImageGetter::getRawPixelsR(const Rect &r, int *stride) +const rdr::U8 *TransImageGetter::getRawBufferR(const Rect &r, int *stride) { if (!offset.equals(Point(0, 0))) - return pb->getPixelsR(r.translate(offset.negate()), stride); + return pb->getBuffer(r.translate(offset.negate()), stride); else - return pb->getPixelsR(r, stride); + return pb->getBuffer(r, stride); } void TransImageGetter::getImage(void* outPtr, const Rect& r, int outStride) { int inStride; - const rdr::U8* inPtr = pb->getPixelsR(r.translate(offset.negate()), &inStride); + const rdr::U8* inPtr = pb->getBuffer(r.translate(offset.negate()), &inStride); if (!outStride) outStride = r.width(); diff --git a/common/rfb/TransImageGetter.h b/common/rfb/TransImageGetter.h index f2b35b45..b241b83c 100644 --- a/common/rfb/TransImageGetter.h +++ b/common/rfb/TransImageGetter.h @@ -72,11 +72,11 @@ namespace rfb { // padding will be outStride-r.width() pixels). void getImage(void* outPtr, const Rect& r, int outStride=0); - // getRawPixelsR() gets the given rectangle of data directly from the + // getRawBufferR() gets the given rectangle of data directly from the // underlying PixelBuffer, bypassing the translation logic. Only use // this when doing something that's independent of the client's pixel // format. - const rdr::U8 *getRawPixelsR(const Rect &r, int *stride); + const rdr::U8 *getRawBufferR(const Rect &r, int *stride); // setPixelBuffer() changes the pixel buffer to be used. The new pixel // buffer MUST have the same pixel format as the old one - if not you diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx index aba7fc9f..111e2de6 100644 --- a/common/rfb/ZRLEDecoder.cxx +++ b/common/rfb/ZRLEDecoder.cxx @@ -40,11 +40,6 @@ using namespace rfb; #undef CPIXEL #undef BPP -Decoder* ZRLEDecoder::create(CMsgReader* reader) -{ - return new ZRLEDecoder(reader); -} - ZRLEDecoder::ZRLEDecoder(CMsgReader* reader_) : reader(reader_) { } diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h index fe96c737..2128ab91 100644 --- a/common/rfb/ZRLEDecoder.h +++ b/common/rfb/ZRLEDecoder.h @@ -25,11 +25,10 @@ namespace rfb { class ZRLEDecoder : public Decoder { public: - static Decoder* create(CMsgReader* reader); - virtual void readRect(const Rect& r, CMsgHandler* handler); + ZRLEDecoder(CMsgReader* reader); virtual ~ZRLEDecoder(); + virtual void readRect(const Rect& r, CMsgHandler* handler); private: - ZRLEDecoder(CMsgReader* reader); CMsgReader* reader; rdr::ZlibInStream zis; }; diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx index a83d79f3..e70706b5 100644 --- a/common/rfb/ZRLEEncoder.cxx +++ b/common/rfb/ZRLEEncoder.cxx @@ -17,7 +17,7 @@ */ #include <rdr/OutStream.h> #include <rfb/Exception.h> -#include <rfb/ImageGetter.h> +#include <rfb/TransImageGetter.h> #include <rfb/encodings.h> #include <rfb/ConnParams.h> #include <rfb/SMsgWriter.h> @@ -26,9 +26,6 @@ using namespace rfb; -rdr::MemOutStream* ZRLEEncoder::sharedMos = 0; -int ZRLEEncoder::maxLen = 4097 * 1024; // enough for width 16384 32-bit pixels - IntParameter zlibLevel("ZlibLevel","Zlib compression level",-1); #define EXTRA_ARGS ImageGetter* ig @@ -49,39 +46,28 @@ IntParameter zlibLevel("ZlibLevel","Zlib compression level",-1); #undef CPIXEL #undef BPP -Encoder* ZRLEEncoder::create(SMsgWriter* writer) -{ - return new ZRLEEncoder(writer); -} - ZRLEEncoder::ZRLEEncoder(SMsgWriter* writer_) - : writer(writer_), zos(0,0,zlibLevel) + : writer(writer_), zos(0,0,zlibLevel), mos(129*1024) { - if (sharedMos) - mos = sharedMos; - else - mos = new rdr::MemOutStream(129*1024); } ZRLEEncoder::~ZRLEEncoder() { - if (!sharedMos) - delete mos; } bool ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig, Rect* actual) { rdr::U8* imageBuf = writer->getImageBuf(64 * 64 * 4 + 4); - mos->clear(); + mos.clear(); bool wroteAll = true; *actual = r; switch (writer->bpp()) { case 8: - wroteAll = zrleEncode8(r, mos, &zos, imageBuf, maxLen, actual, ig); + wroteAll = zrleEncode8(r, &mos, &zos, imageBuf, actual, ig); break; case 16: - wroteAll = zrleEncode16(r, mos, &zos, imageBuf, maxLen, actual, ig); + wroteAll = zrleEncode16(r, &mos, &zos, imageBuf, actual, ig); break; case 32: { @@ -94,16 +80,16 @@ bool ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig, Rect* actual) if ((fitsInLS3Bytes && pf.isLittleEndian()) || (fitsInMS3Bytes && pf.isBigEndian())) { - wroteAll = zrleEncode24A(r, mos, &zos, imageBuf, maxLen, actual, ig); + wroteAll = zrleEncode24A(r, &mos, &zos, imageBuf, actual, ig); } else if ((fitsInLS3Bytes && pf.isBigEndian()) || (fitsInMS3Bytes && pf.isLittleEndian())) { - wroteAll = zrleEncode24B(r, mos, &zos, imageBuf, maxLen, actual, ig); + wroteAll = zrleEncode24B(r, &mos, &zos, imageBuf, actual, ig); } else { - wroteAll = zrleEncode32(r, mos, &zos, imageBuf, maxLen, actual, ig); + wroteAll = zrleEncode32(r, &mos, &zos, imageBuf, actual, ig); } break; } @@ -111,8 +97,8 @@ bool ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig, Rect* actual) writer->startRect(*actual, encodingZRLE); rdr::OutStream* os = writer->getOutStream(); - os->writeU32(mos->length()); - os->writeBytes(mos->data(), mos->length()); + os->writeU32(mos.length()); + os->writeBytes(mos.data(), mos.length()); writer->endRect(); return wroteAll; } diff --git a/common/rfb/ZRLEEncoder.h b/common/rfb/ZRLEEncoder.h index 3a0f52a9..e3517c13 100644 --- a/common/rfb/ZRLEEncoder.h +++ b/common/rfb/ZRLEEncoder.h @@ -26,29 +26,13 @@ namespace rfb { class ZRLEEncoder : public Encoder { public: - static Encoder* create(SMsgWriter* writer); - virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); + ZRLEEncoder(SMsgWriter* writer); virtual ~ZRLEEncoder(); - - // setMaxLen() sets the maximum size in bytes of any ZRLE rectangle. This - // can be used to stop the MemOutStream from growing too large. The value - // must be large enough to allow for at least one row of ZRLE tiles. So - // for example for a screen width of 2048 32-bit pixels this is 2K*4*64 = - // 512Kbytes plus a bit of overhead (the overhead is about 1/16 of the - // width, in this example about 128 bytes). - static void setMaxLen(int m) { maxLen = m; } - - // setSharedMos() sets a MemOutStream to be shared amongst all - // ZRLEEncoders. Should be called before any ZRLEEncoders are created. - static void setSharedMos(rdr::MemOutStream* mos_) { sharedMos = mos_; } - + virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual); private: - ZRLEEncoder(SMsgWriter* writer); SMsgWriter* writer; rdr::ZlibOutStream zos; - rdr::MemOutStream* mos; - static rdr::MemOutStream* sharedMos; - static int maxLen; + rdr::MemOutStream mos; }; } #endif diff --git a/common/rfb/encodings.cxx b/common/rfb/encodings.cxx index 97f547bf..190e0324 100644 --- a/common/rfb/encodings.cxx +++ b/common/rfb/encodings.cxx @@ -16,9 +16,6 @@ * USA. */ #include <string.h> -#ifdef _WIN32 -#define strcasecmp _stricmp -#endif #include <rfb/encodings.h> #include <rfb/util.h> diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h index 77befc7d..7aa04d91 100644 --- a/common/rfb/hextileDecode.h +++ b/common/rfb/hextileDecode.h @@ -69,13 +69,9 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf if (tileType & hextileBgSpecified) bg = is->READ_PIXEL(); -#ifdef FAVOUR_FILL_RECT - FILL_RECT(t, bg); -#else int len = t.area(); PIXEL_T* ptr = (PIXEL_T*)buf; while (len-- > 0) *ptr++ = bg; -#endif if (tileType & hextileFgSpecified) fg = is->READ_PIXEL(); @@ -91,14 +87,6 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf int xy = is->readU8(); int wh = is->readU8(); -#ifdef FAVOUR_FILL_RECT - Rect s; - s.tl.x = t.tl.x + ((xy >> 4) & 15); - s.tl.y = t.tl.y + (xy & 15); - s.br.x = s.tl.x + ((wh >> 4) & 15) + 1; - s.br.y = s.tl.y + (wh & 15) + 1; - FILL_RECT(s, fg); -#else int x = ((xy >> 4) & 15); int y = (xy & 15); int w = ((wh >> 4) & 15) + 1; @@ -110,12 +98,9 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf while (len-- > 0) *ptr++ = fg; ptr += rowAdd; } -#endif } } -#ifndef FAVOUR_FILL_RECT IMAGE_RECT(t, buf); -#endif } } } diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h index e9f5f6ba..06c84775 100644 --- a/common/rfb/tightDecode.h +++ b/common/rfb/tightDecode.h @@ -156,7 +156,7 @@ void TIGHT_DECODE (const Rect& r) PIXEL_T *buf; int stride = r.width(); - if (directDecode) buf = (PIXEL_T *)handler->getRawPixelsRW(r, &stride); + if (directDecode) buf = (PIXEL_T *)handler->getRawBufferRW(r, &stride); else buf = (PIXEL_T *)reader->getImageBuf(r.area()); if (palSize == 0) { @@ -228,7 +228,7 @@ void TIGHT_DECODE (const Rect& r) } } - if (directDecode) handler->releaseRawPixels(r); + if (directDecode) handler->releaseRawBuffer(r); else IMAGE_RECT(r, buf); delete [] netbuf; @@ -256,10 +256,9 @@ DECOMPRESS_JPEG_RECT(const Rect& r) // We always use direct decoding with JPEG images int stride; - rdr::U8 *buf = handler->getRawPixelsRW(r, &stride); - jd.decompress(netbuf, compressedLen, buf, stride * clientpf.bpp / 8, r, - clientpf); - handler->releaseRawPixels(r); + rdr::U8 *buf = handler->getRawBufferRW(r, &stride); + jd.decompress(netbuf, compressedLen, buf, stride, r, clientpf); + handler->releaseRawBuffer(r); delete [] netbuf; } diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h index 8f900b58..c121b7aa 100644 --- a/common/rfb/tightEncode.h +++ b/common/rfb/tightEncode.h @@ -191,9 +191,9 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid) { int stride; rdr::U32 solidColor; - const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawPixelsR(r, &stride); + const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawBufferR(r, &stride); PIXEL_T *pixels = NULL; - bool grayScaleJPEG = (jpegSubsampling == SUBSAMP_GRAY && jpegQuality != -1); + bool grayScaleJPEG = (jpegSubsampling == subsampleGray && jpegQuality != -1); #if (BPP == 32) // Check if it's necessary to pack 24-bit pixels, and @@ -412,7 +412,7 @@ void ENCODE_JPEG_RECT (PIXEL_T *buf, int stride, const Rect& r, rdr::OutStream *os) { jc.clear(); - jc.compress((rdr::U8 *)buf, stride * clientpf.bpp / 8, r, clientpf, + jc.compress((rdr::U8 *)buf, stride, r, clientpf, jpegQuality, jpegSubsampling); os->writeU8(0x09 << 4); os->writeCompactLength(jc.length()); @@ -540,12 +540,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r) *dataend = &data[stride * h]; bool willTransform = ig->willTransform(); - if (willTransform) { - mask = serverpf.redMax << serverpf.redShift; - mask |= serverpf.greenMax << serverpf.greenShift; - mask |= serverpf.blueMax << serverpf.blueShift; - } - else mask = ~0; + serverpf.bufferFromPixel((rdr::U8*)&mask, ~0); c0 = data[0] & mask; n0 = 0; @@ -650,7 +645,7 @@ bool CHECK_SOLID_TILE(Rect& r, rdr::U32 *colorPtr, bool needSameColor) int w = r.width(), h = r.height(); int stride = w; - buf = (const PIXEL_T *)ig->getRawPixelsR(r, &stride); + buf = (const PIXEL_T *)ig->getRawBufferR(r, &stride); colorValue = *buf; if (needSameColor && (rdr::U32)colorValue != *colorPtr) diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx index 2709f2cc..a41ad96a 100644 --- a/common/rfb/util.cxx +++ b/common/rfb/util.cxx @@ -38,97 +38,6 @@ #include <rfb/util.h> -// Provide strcasecmp() and/or strncasecmp() if absent on this system. - -#ifndef WIN32 -#if !defined(HAVE_STRCASECMP) || !defined(HAVE_STRNCASECMP) - -extern "C" { - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static unsigned char s_charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', -}; - -#ifndef HAVE_STRCASECMP -int -strcasecmp(const char *s1, const char *s2) -{ - unsigned char u1, u2; - - for (;;) { - u1 = (unsigned char) *s1++; - u2 = (unsigned char) *s2++; - if (s_charmap[u1] != s_charmap[u2]) { - return s_charmap[u1] - s_charmap[u2]; - } - if (u1 == '\0') { - return 0; - } - } -} -#endif // !defined(HAVE_STRCASECMP) - -#ifndef HAVE_STRNCASECMP -int -strncasecmp(const char *s1, const char *s2, size_t n) -{ - unsigned char u1, u2; - - for (; n != 0; --n) { - u1 = (unsigned char) *s1++; - u2 = (unsigned char) *s2++; - if (s_charmap[u1] != s_charmap[u2]) { - return s_charmap[u1] - s_charmap[u2]; - } - if (u1 == '\0') { - return 0; - } - } - return 0; -} -#endif // !defined(HAVE_STRNCASECMP) - -} // extern "C" - -#endif // !defined(HAVE_STRCASECMP) || !defined(HAVE_STRNCASECMP) -#endif // defined(WIN32) - namespace rfb { char* strDup(const char* s) { diff --git a/common/rfb/util.h b/common/rfb/util.h index 7d90a6b2..13dbe68e 100644 --- a/common/rfb/util.h +++ b/common/rfb/util.h @@ -104,17 +104,4 @@ namespace rfb { #define __rfbmin(a,b) (((a) < (b)) ? (a) : (b)) #endif -// Declare strcasecmp() and/or strncasecmp() if absent on this system. - -#if !defined(WIN32) && !defined(HAVE_STRCASECMP) -extern "C" { - int strcasecmp(const char *s1, const char *s2); -} -#endif -#if !defined(WIN32) && !defined(HAVE_STRNCASECMP) -extern "C" { - int strncasecmp(const char *s1, const char *s2, size_t n); -} -#endif - #endif diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h index 8f6f7927..d26d4d3e 100644 --- a/common/rfb/zrleDecode.h +++ b/common/rfb/zrleDecode.h @@ -121,12 +121,6 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, } } -#ifdef FAVOUR_FILL_RECT - //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n", - //t.width(),t.height(),t.tl.x,t.tl.y); - IMAGE_RECT(t,buf); -#endif - } else { if (palSize == 0) { @@ -149,36 +143,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, throw Exception ("ZRLE decode error"); } -#ifdef FAVOUR_FILL_RECT - int i = ptr - buf; - ptr += len; - - int runX = i % t.width(); - int runY = i / t.width(); - - if (runX + len > t.width()) { - if (runX != 0) { - FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, t.width()-runX, 1), - pix); - len -= t.width()-runX; - runX = 0; - runY++; - } - - if (len > t.width()) { - FILL_RECT(Rect(t.tl.x, t.tl.y+runY, t.width(), len/t.width()), - pix); - runY += len / t.width(); - len = len % t.width(); - } - } - - if (len != 0) { - FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, len, 1), pix); - } -#else while (len-- > 0) *ptr++ = pix; -#endif } } else { @@ -207,45 +172,14 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T pix = palette[index]; -#ifdef FAVOUR_FILL_RECT - int i = ptr - buf; - ptr += len; - - int runX = i % t.width(); - int runY = i / t.width(); - - if (runX + len > t.width()) { - if (runX != 0) { - FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, t.width()-runX, 1), - pix); - len -= t.width()-runX; - runX = 0; - runY++; - } - - if (len > t.width()) { - FILL_RECT(Rect(t.tl.x, t.tl.y+runY, t.width(), len/t.width()), - pix); - runY += len / t.width(); - len = len % t.width(); - } - } - - if (len != 0) { - FILL_RECT(Rect(t.tl.x+runX, t.tl.y+runY, len, 1), pix); - } -#else while (len-- > 0) *ptr++ = pix; -#endif } } } -#ifndef FAVOUR_FILL_RECT //fprintf(stderr,"copying data to screen %dx%d at %d,%d\n", //t.width(),t.height(),t.tl.x,t.tl.y); IMAGE_RECT(t,buf); -#endif } } diff --git a/common/rfb/zrleEncode.h b/common/rfb/zrleEncode.h index 9b7263b3..0c622b88 100644 --- a/common/rfb/zrleEncode.h +++ b/common/rfb/zrleEncode.h @@ -115,7 +115,7 @@ public: void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os); bool ZRLE_ENCODE (const Rect& r, rdr::OutStream* os, - rdr::ZlibOutStream* zos, void* buf, int maxLen, Rect* actual + rdr::ZlibOutStream* zos, void* buf, Rect* actual #ifdef EXTRA_ARGS , EXTRA_ARGS #endif @@ -132,7 +132,8 @@ bool ZRLE_ENCODE (const Rect& r, rdr::OutStream* os, t.br.y = __rfbmin(r.br.y, t.tl.y + 64); - if (os->length() + worstCaseLine > maxLen) { + // enough for width 16384 32-bit pixels + if (os->length() + worstCaseLine > 4097 * 1024) { if (t.tl.y == r.tl.y) throw Exception("ZRLE: not enough space for first line?"); actual->tl = r.tl; |