summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/network/TcpSocket.cxx1
-rw-r--r--common/os/CMakeLists.txt2
-rw-r--r--common/os/net.c53
-rw-r--r--common/os/net.h50
-rw-r--r--common/os/print.c104
-rw-r--r--common/os/print.h57
-rw-r--r--common/os/w32tiger.h5
-rw-r--r--common/rdr/Exception.cxx5
-rw-r--r--common/rdr/ZlibOutStream.cxx3
-rw-r--r--common/rdr/msvcwarning.h26
-rw-r--r--common/rfb/CMakeLists.txt1
-rw-r--r--common/rfb/CMsgHandler.h4
-rw-r--r--common/rfb/CMsgWriter.cxx5
-rw-r--r--common/rfb/CSecurityTLS.cxx1
-rw-r--r--common/rfb/ComparingUpdateTracker.cxx6
-rw-r--r--common/rfb/Configuration.cxx4
-rw-r--r--common/rfb/ConnParams.cxx97
-rw-r--r--common/rfb/ConnParams.h20
-rw-r--r--common/rfb/Decoder.cxx58
-rw-r--r--common/rfb/Decoder.h16
-rw-r--r--common/rfb/Encoder.cxx64
-rw-r--r--common/rfb/Encoder.h22
-rw-r--r--common/rfb/HTTPServer.cxx4
-rw-r--r--common/rfb/HextileDecoder.cxx5
-rw-r--r--common/rfb/HextileDecoder.h5
-rw-r--r--common/rfb/HextileEncoder.cxx7
-rw-r--r--common/rfb/HextileEncoder.h5
-rw-r--r--common/rfb/JpegCompressor.cxx86
-rw-r--r--common/rfb/JpegCompressor.h11
-rw-r--r--common/rfb/JpegDecompressor.cxx65
-rw-r--r--common/rfb/LogWriter.cxx3
-rw-r--r--common/rfb/Logger.cxx4
-rw-r--r--common/rfb/PixelBuffer.cxx27
-rw-r--r--common/rfb/PixelBuffer.h14
-rw-r--r--common/rfb/PixelFormat.cxx343
-rw-r--r--common/rfb/PixelFormat.h28
-rw-r--r--common/rfb/PixelFormat.inl105
-rw-r--r--common/rfb/RREDecoder.cxx5
-rw-r--r--common/rfb/RREDecoder.h5
-rw-r--r--common/rfb/RREEncoder.cxx7
-rw-r--r--common/rfb/RREEncoder.h5
-rw-r--r--common/rfb/RawDecoder.cxx5
-rw-r--r--common/rfb/RawDecoder.h5
-rw-r--r--common/rfb/RawEncoder.cxx7
-rw-r--r--common/rfb/RawEncoder.h5
-rw-r--r--common/rfb/SMsgWriter.cxx12
-rw-r--r--common/rfb/SMsgWriter.h12
-rw-r--r--common/rfb/ScaleFilters.cxx4
-rw-r--r--common/rfb/ScaledPixelBuffer.cxx225
-rw-r--r--common/rfb/ScaledPixelBuffer.h128
-rw-r--r--common/rfb/Security.cxx3
-rw-r--r--common/rfb/TightDecoder.cxx5
-rw-r--r--common/rfb/TightDecoder.h6
-rw-r--r--common/rfb/TightEncoder.cxx40
-rw-r--r--common/rfb/TightEncoder.h16
-rw-r--r--common/rfb/TransImageGetter.cxx8
-rw-r--r--common/rfb/TransImageGetter.h4
-rw-r--r--common/rfb/ZRLEDecoder.cxx5
-rw-r--r--common/rfb/ZRLEDecoder.h5
-rw-r--r--common/rfb/ZRLEEncoder.cxx34
-rw-r--r--common/rfb/ZRLEEncoder.h22
-rw-r--r--common/rfb/encodings.cxx3
-rw-r--r--common/rfb/hextileDecode.h15
-rw-r--r--common/rfb/tightDecode.h11
-rw-r--r--common/rfb/tightEncode.h15
-rw-r--r--common/rfb/util.cxx91
-rw-r--r--common/rfb/util.h13
-rw-r--r--common/rfb/zrleDecode.h66
-rw-r--r--common/rfb/zrleEncode.h5
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;