aboutsummaryrefslogtreecommitdiffstats
path: root/rfb/zrleEncode.h
diff options
context:
space:
mode:
Diffstat (limited to 'rfb/zrleEncode.h')
-rw-r--r--rfb/zrleEncode.h328
1 files changed, 0 insertions, 328 deletions
diff --git a/rfb/zrleEncode.h b/rfb/zrleEncode.h
deleted file mode 100644
index 9b7263b3..00000000
--- a/rfb/zrleEncode.h
+++ /dev/null
@@ -1,328 +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.
- */
-
-//
-// zrleEncode.h - zrle encoding function.
-//
-// This file is #included after having set the following macros:
-// BPP - 8, 16 or 32
-// EXTRA_ARGS - optional extra arguments
-// GET_IMAGE_INTO_BUF - gets a rectangle of pixel data into a buffer
-//
-// Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
-// bigger than the largest tile of pixel data, since the ZRLE encoding
-// algorithm writes to the position one past the end of the pixel data.
-//
-
-#include <rdr/OutStream.h>
-#include <rdr/ZlibOutStream.h>
-#include <assert.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#ifdef CPIXEL
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define WRITE_PIXEL CONCAT2E(writeOpaque,CPIXEL)
-#define ZRLE_ENCODE CONCAT2E(zrleEncode,CPIXEL)
-#define ZRLE_ENCODE_TILE CONCAT2E(zrleEncodeTile,CPIXEL)
-#define BPPOUT 24
-#else
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define WRITE_PIXEL CONCAT2E(writeOpaque,BPP)
-#define ZRLE_ENCODE CONCAT2E(zrleEncode,BPP)
-#define ZRLE_ENCODE_TILE CONCAT2E(zrleEncodeTile,BPP)
-#define BPPOUT BPP
-#endif
-
-#ifndef ZRLE_ONCE
-#define ZRLE_ONCE
-static const int bitsPerPackedPixel[] = {
- 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-};
-
-// The PaletteHelper class helps us build up the palette from pixel data by
-// storing a reverse index using a simple hash-table
-
-class PaletteHelper {
-public:
- enum { MAX_SIZE = 127 };
-
- PaletteHelper()
- {
- memset(index, 255, sizeof(index));
- size = 0;
- }
-
- inline int hash(rdr::U32 pix)
- {
- return (pix ^ (pix >> 17)) & 4095;
- }
-
- inline void insert(rdr::U32 pix)
- {
- if (size < MAX_SIZE) {
- int i = hash(pix);
- while (index[i] != 255 && key[i] != pix)
- i++;
- if (index[i] != 255) return;
-
- index[i] = size;
- key[i] = pix;
- palette[size] = pix;
- }
- size++;
- }
-
- inline int lookup(rdr::U32 pix)
- {
- assert(size <= MAX_SIZE);
- int i = hash(pix);
- while (index[i] != 255 && key[i] != pix)
- i++;
- if (index[i] != 255) return index[i];
- return -1;
- }
-
- rdr::U32 palette[MAX_SIZE];
- rdr::U8 index[4096+MAX_SIZE];
- rdr::U32 key[4096+MAX_SIZE];
- int size;
-};
-#endif
-
-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
-#ifdef EXTRA_ARGS
- , EXTRA_ARGS
-#endif
- )
-{
- zos->setUnderlying(os);
- // RLE overhead is at worst 1 byte per 64x64 (4Kpixel) block
- int worstCaseLine = r.width() * 64 * (BPPOUT/8) + 1 + r.width() / 64;
- // Zlib overhead is at worst 6 bytes plus 5 bytes per 32Kbyte block.
- worstCaseLine += 11 + 5 * (worstCaseLine >> 15);
- Rect t;
-
- for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) {
-
- t.br.y = __rfbmin(r.br.y, t.tl.y + 64);
-
- if (os->length() + worstCaseLine > maxLen) {
- if (t.tl.y == r.tl.y)
- throw Exception("ZRLE: not enough space for first line?");
- actual->tl = r.tl;
- actual->br.x = r.br.x;
- actual->br.y = t.tl.y;
- return false;
- }
-
- for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 64) {
-
- t.br.x = __rfbmin(r.br.x, t.tl.x + 64);
-
- GET_IMAGE_INTO_BUF(t,buf);
-
- ZRLE_ENCODE_TILE((PIXEL_T*)buf, t.width(), t.height(), zos);
- }
-
- zos->flush();
- }
- return true;
-}
-
-
-void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os)
-{
- // First find the palette and the number of runs
-
- PaletteHelper ph;
-
- int runs = 0;
- int singlePixels = 0;
-
- PIXEL_T* ptr = data;
- PIXEL_T* end = ptr + h * w;
- *end = ~*(end-1); // one past the end is different so the while loop ends
-
- while (ptr < end) {
- PIXEL_T pix = *ptr;
- if (*++ptr != pix) {
- singlePixels++;
- } else {
- while (*++ptr == pix) ;
- runs++;
- }
- ph.insert(pix);
- }
-
- //fprintf(stderr,"runs %d, single pixels %d, paletteSize %d\n",
- // runs, singlePixels, ph.size);
-
- // Solid tile is a special case
-
- if (ph.size == 1) {
- os->writeU8(1);
- os->WRITE_PIXEL(ph.palette[0]);
- return;
- }
-
- // Try to work out whether to use RLE and/or a palette. We do this by
- // estimating the number of bytes which will be generated and picking the
- // method which results in the fewest bytes. Of course this may not result
- // in the fewest bytes after compression...
-
- bool useRle = false;
- bool usePalette = false;
-
- int estimatedBytes = w * h * (BPPOUT/8); // start assuming raw
-
- int plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels);
-
- if (plainRleBytes < estimatedBytes) {
- useRle = true;
- estimatedBytes = plainRleBytes;
- }
-
- if (ph.size < 128) {
- int paletteRleBytes = (BPPOUT/8) * ph.size + 2 * runs + singlePixels;
-
- if (paletteRleBytes < estimatedBytes) {
- useRle = true;
- usePalette = true;
- estimatedBytes = paletteRleBytes;
- }
-
- if (ph.size < 17) {
- int packedBytes = ((BPPOUT/8) * ph.size +
- w * h * bitsPerPackedPixel[ph.size-1] / 8);
-
- if (packedBytes < estimatedBytes) {
- useRle = false;
- usePalette = true;
- estimatedBytes = packedBytes;
- }
- }
- }
-
- if (!usePalette) ph.size = 0;
-
- os->writeU8((useRle ? 128 : 0) | ph.size);
-
- for (int i = 0; i < ph.size; i++) {
- os->WRITE_PIXEL(ph.palette[i]);
- }
-
- if (useRle) {
-
- PIXEL_T* ptr = data;
- PIXEL_T* end = ptr + w * h;
- PIXEL_T* runStart;
- PIXEL_T pix;
- while (ptr < end) {
- runStart = ptr;
- pix = *ptr++;
- while (*ptr == pix && ptr < end)
- ptr++;
- int len = ptr - runStart;
- if (len <= 2 && usePalette) {
- int index = ph.lookup(pix);
- if (len == 2)
- os->writeU8(index);
- os->writeU8(index);
- continue;
- }
- if (usePalette) {
- int index = ph.lookup(pix);
- os->writeU8(index | 128);
- } else {
- os->WRITE_PIXEL(pix);
- }
- len -= 1;
- while (len >= 255) {
- os->writeU8(255);
- len -= 255;
- }
- os->writeU8(len);
- }
-
- } else {
-
- // no RLE
-
- if (usePalette) {
-
- // packed pixels
-
- assert (ph.size < 17);
-
- int bppp = bitsPerPackedPixel[ph.size-1];
-
- PIXEL_T* ptr = data;
-
- for (int i = 0; i < h; i++) {
- rdr::U8 nbits = 0;
- rdr::U8 byte = 0;
-
- PIXEL_T* eol = ptr + w;
-
- while (ptr < eol) {
- PIXEL_T pix = *ptr++;
- rdr::U8 index = ph.lookup(pix);
- byte = (byte << bppp) | index;
- nbits += bppp;
- if (nbits >= 8) {
- os->writeU8(byte);
- nbits = 0;
- }
- }
- if (nbits > 0) {
- byte <<= 8 - nbits;
- os->writeU8(byte);
- }
- }
- } else {
-
- // raw
-
-#ifdef CPIXEL
- for (PIXEL_T* ptr = data; ptr < data+w*h; ptr++) {
- os->WRITE_PIXEL(*ptr);
- }
-#else
- os->writeBytes(data, w*h*(BPP/8));
-#endif
- }
- }
-}
-
-#undef PIXEL_T
-#undef WRITE_PIXEL
-#undef ZRLE_ENCODE
-#undef ZRLE_ENCODE_TILE
-#undef BPPOUT
-}