blob: 83585490b8929ba487197e293370cfdcacf64945 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossmanc0397262014-03-14 15:59:46 +01002 * Copyright 2014 Pierre Ossman for Cendio AB
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00003 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19#include <rdr/OutStream.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000020#include <rfb/encodings.h>
Pierre Ossman668468b2014-01-31 12:37:32 +010021#include <rfb/SConnection.h>
Pierre Ossman0c9bd4b2014-07-09 16:44:11 +020022#include <rfb/PixelFormat.h>
23#include <rfb/PixelBuffer.h>
Pierre Ossmanc0397262014-03-14 15:59:46 +010024#include <rfb/Palette.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000025#include <rfb/RREEncoder.h>
26
27using namespace rfb;
28
29#define BPP 8
30#include <rfb/rreEncode.h>
31#undef BPP
32#define BPP 16
33#include <rfb/rreEncode.h>
34#undef BPP
35#define BPP 32
36#include <rfb/rreEncode.h>
37#undef BPP
38
Pierre Ossmanc0397262014-03-14 15:59:46 +010039RREEncoder::RREEncoder(SConnection* conn) :
Pierre Ossman4694d882018-09-20 10:49:40 +020040 Encoder(conn, encodingRRE, EncoderPlain)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000041{
42}
43
44RREEncoder::~RREEncoder()
45{
46}
47
Pierre Ossmanc0397262014-03-14 15:59:46 +010048bool RREEncoder::isSupported()
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000049{
Pierre Ossman0d3ce872018-06-18 15:59:00 +020050 return conn->client.supportsEncoding(encodingRRE);
Pierre Ossmanc0397262014-03-14 15:59:46 +010051}
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000052
Pierre Ossmanc0397262014-03-14 15:59:46 +010053void RREEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
54{
55 rdr::U8* imageBuf;
56 int stride;
57 rdr::U32 bg;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000058
Pierre Ossmanc0397262014-03-14 15:59:46 +010059 int w = pb->width();
60 int h = pb->height();
61
62 if (palette.size() == 1) {
63 Encoder::writeSolidRect(pb, palette);
Pierre Ossman717c07b2014-01-21 14:45:10 +010064 return;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000065 }
66
Pierre Ossmanc0397262014-03-14 15:59:46 +010067 // We have to have our own copy of the data as we modify it as
68 // we find subrects.
69 bufferCopy.setPF(pb->getPF());
70 bufferCopy.setSize(w, h);
71
72 imageBuf = bufferCopy.getBufferRW(pb->getRect(), &stride);
73 pb->getImage(imageBuf, pb->getRect());
74
75 if (palette.size() > 0)
76 bg = palette.getColour(0);
77 else {
78 // Some crazy person is using this encoder for high colour
79 // data. Just pick the first pixel as the background colour.
80 bg = 0;
81 memcpy(&bg, imageBuf, pb->getPF().bpp/8);
82 }
83
84 int nSubrects = -1;
85 switch (pb->getPF().bpp) {
86 case 8:
87 nSubrects = rreEncode8((rdr::U8*)imageBuf, w, h, &mos, bg);
88 break;
89 case 16:
90 nSubrects = rreEncode16((rdr::U16*)imageBuf, w, h, &mos, bg);
91 break;
92 case 32:
93 nSubrects = rreEncode32((rdr::U32*)imageBuf, w, h, &mos, bg);
94 break;
95 }
96
97 bufferCopy.commitBufferRW(pb->getRect());
98
Pierre Ossman668468b2014-01-31 12:37:32 +010099 rdr::OutStream* os = conn->getOutStream();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000100 os->writeU32(nSubrects);
101 os->writeBytes(mos.data(), mos.length());
Pierre Ossmanc0397262014-03-14 15:59:46 +0100102 mos.clear();
103}
104
105void RREEncoder::writeSolidRect(int width, int height,
106 const PixelFormat& pf,
107 const rdr::U8* colour)
108{
109 rdr::OutStream* os;
110
111 os = conn->getOutStream();
112
113 os->writeU32(0);
114 os->writeBytes(colour, pf.bpp/8);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000115}