blob: daca00aa75bb6e243b2b13005a134708602d033a [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
Peter Åstrandd69bcc42011-09-28 12:52:53 +00002 * Copyright 2004-2005 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 <rfb/CMsgReader.h>
20#include <rfb/CMsgHandler.h>
21#include <rfb/TightDecoder.h>
22#include <stdio.h> /* jpeglib.h needs FILE */
23extern "C" {
24#include <jpeglib.h>
25}
26
27using namespace rfb;
28
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000029#define TIGHT_MAX_WIDTH 2048
30
31static void JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData,
32 int compressedLen);
33static bool jpegError;
34
35#define EXTRA_ARGS CMsgHandler* handler
36#define FILL_RECT(r, p) handler->fillRect(r, p)
37#define IMAGE_RECT(r, p) handler->imageRect(r, p)
38#define BPP 8
39#include <rfb/tightDecode.h>
40#undef BPP
41#define BPP 16
42#include <rfb/tightDecode.h>
43#undef BPP
44#define BPP 32
45#include <rfb/tightDecode.h>
46#undef BPP
47
48Decoder* TightDecoder::create(CMsgReader* reader)
49{
50 return new TightDecoder(reader);
51}
52
53TightDecoder::TightDecoder(CMsgReader* reader_) : reader(reader_)
54{
55}
56
57TightDecoder::~TightDecoder()
58{
59}
60
61void TightDecoder::readRect(const Rect& r, CMsgHandler* handler)
62{
63 rdr::InStream* is = reader->getInStream();
64 /* Uncompressed RGB24 JPEG data, before translated, can be up to 3
65 times larger, if VNC bpp is 8. */
66 rdr::U8* buf = reader->getImageBuf(r.area()*3);
67 switch (reader->bpp()) {
68 case 8:
69 tightDecode8 (r, is, zis, (rdr::U8*) buf, handler); break;
70 case 16:
71 tightDecode16(r, is, zis, (rdr::U16*)buf, handler); break;
72 case 32:
73 tightDecode32(r, is, zis, (rdr::U32*)buf, handler); break;
74 }
75}
76
77
78//
79// A "Source manager" for the JPEG library.
80//
81
82static struct jpeg_source_mgr jpegSrcManager;
83static JOCTET *jpegBufferPtr;
84static size_t jpegBufferLen;
85
86static void JpegInitSource(j_decompress_ptr cinfo);
87static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
88static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
89static void JpegTermSource(j_decompress_ptr cinfo);
90
91static void
92JpegInitSource(j_decompress_ptr cinfo)
93{
94 jpegError = false;
95}
96
97static boolean
98JpegFillInputBuffer(j_decompress_ptr cinfo)
99{
100 jpegError = true;
101 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
102 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
103
104 return TRUE;
105}
106
107static void
108JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
109{
110 if (num_bytes < 0 || (size_t)num_bytes > jpegSrcManager.bytes_in_buffer) {
111 jpegError = true;
112 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
113 jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
114 } else {
115 jpegSrcManager.next_input_byte += (size_t) num_bytes;
116 jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
117 }
118}
119
120static void
121JpegTermSource(j_decompress_ptr cinfo)
122{
123 /* No work necessary here. */
124}
125
126static void
127JpegSetSrcManager(j_decompress_ptr cinfo, char *compressedData, int compressedLen)
128{
129 jpegBufferPtr = (JOCTET *)compressedData;
130 jpegBufferLen = (size_t)compressedLen;
131
132 jpegSrcManager.init_source = JpegInitSource;
133 jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
134 jpegSrcManager.skip_input_data = JpegSkipInputData;
135 jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
136 jpegSrcManager.term_source = JpegTermSource;
137 jpegSrcManager.next_input_byte = jpegBufferPtr;
138 jpegSrcManager.bytes_in_buffer = jpegBufferLen;
139
140 cinfo->src = &jpegSrcManager;
141}