Line data Source code
1 : /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 : /*
3 : Copyright (C) 2009 Red Hat, Inc.
4 :
5 : This library is free software; you can redistribute it and/or
6 : modify it under the terms of the GNU Lesser General Public
7 : License as published by the Free Software Foundation; either
8 : version 2.1 of the License, or (at your option) any later version.
9 :
10 : This library is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public
16 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 : */
18 :
19 : // Red Hat image compression based on SFALIC by Roman Starosolski
20 : // http://sun.iinf.polsl.gliwice.pl/~rstaros/sfalic/index.html
21 :
22 : #include <config.h>
23 :
24 : #include "quic_config.h"
25 : #include "quic.h"
26 : #include "log.h"
27 :
28 : /* ASCII "QUIC" */
29 : #define QUIC_MAGIC 0x43495551
30 : #define QUIC_VERSION_MAJOR 0U
31 : #define QUIC_VERSION_MINOR 0U
32 : #define QUIC_VERSION ((QUIC_VERSION_MAJOR << 16) | (QUIC_VERSION_MINOR & 0xffff))
33 :
34 : typedef uint8_t BYTE;
35 :
36 : /* maximum number of codes in family */
37 : #define MAXNUMCODES 8
38 :
39 : /* model evolution, warning: only 1,3 and 5 allowed */
40 : #define DEFevol 3
41 : #define MINevol 0
42 : #define MAXevol 5
43 :
44 : /* starting wait mask index */
45 : #define DEFwmistart 0
46 : #define MINwmistart 0
47 :
48 : /* codeword length limit */
49 : #define DEFmaxclen 26
50 :
51 : /* target wait mask index */
52 : #define DEFwmimax 6
53 :
54 : /* number of symbols to encode before increasing wait mask index */
55 : #define DEFwminext 2048
56 : #define MINwminext 1
57 : #define MAXwminext 100000000
58 :
59 : /* Maximum image size in pixels, mainly to avoid possible integer overflows */
60 : #define SPICE_MAX_IMAGE_SIZE (512 * 1024 * 1024 - 1)
61 :
62 : typedef struct QuicFamily {
63 : unsigned int nGRcodewords[MAXNUMCODES]; /* indexed by code number, contains number of
64 : unmodified GR codewords in the code */
65 : unsigned int notGRcwlen[MAXNUMCODES]; /* indexed by code number, contains codeword
66 : length of the not-GR codeword */
67 : unsigned int notGRprefixmask[MAXNUMCODES]; /* indexed by code number, contains mask to
68 : determine if the codeword is GR or not-GR */
69 : unsigned int notGRsuffixlen[MAXNUMCODES]; /* indexed by code number, contains suffix
70 : length of the not-GR codeword */
71 :
72 : unsigned int golomb_code_len[256][MAXNUMCODES];
73 : unsigned int golomb_code[256][MAXNUMCODES];
74 :
75 : /* array for translating distribution U to L for depths up to 8 bpp,
76 : initialized by decorrelate_init() */
77 : BYTE xlatU2L[256];
78 :
79 : /* array for translating distribution L to U for depths up to 8 bpp,
80 : initialized by correlate_init() */
81 : unsigned int xlatL2U[256];
82 : } QuicFamily;
83 :
84 : static QuicFamily family_8bpc;
85 : static QuicFamily family_5bpc;
86 :
87 : typedef unsigned COUNTER; /* counter in the array of counters in bucket of the data model */
88 :
89 : typedef struct s_bucket {
90 : COUNTER *pcounters; /* pointer to array of counters */
91 : unsigned int bestcode; /* best code so far */
92 : } s_bucket;
93 :
94 : typedef struct Encoder Encoder;
95 :
96 : static inline void encode(Encoder *encoder, unsigned int word, unsigned int len);
97 :
98 : typedef struct CommonState {
99 : unsigned int waitcnt;
100 : unsigned int tabrand_seed;
101 : unsigned int wm_trigger;
102 : unsigned int wmidx;
103 : unsigned int wmileft;
104 :
105 : int melcstate; /* index to the state array */
106 :
107 : int melclen; /* contents of the state array location
108 : indexed by melcstate: the "expected"
109 : run length is 2^melclen, shorter runs are
110 : encoded by a 1 followed by the run length
111 : in binary representation, wit a fixed length
112 : of melclen bits */
113 :
114 : unsigned long melcorder; /* 2^ melclen */
115 : } CommonState;
116 :
117 :
118 : #define MAX_CHANNELS 4
119 :
120 : typedef struct FamilyStat {
121 : s_bucket **buckets_ptrs;
122 : s_bucket *buckets_buf;
123 : COUNTER *counters;
124 : } FamilyStat;
125 :
126 : typedef struct Channel {
127 : int correlate_row_width;
128 : BYTE *correlate_row;
129 :
130 : s_bucket **_buckets_ptrs;
131 :
132 : FamilyStat family_stat_8bpc;
133 : FamilyStat family_stat_5bpc;
134 :
135 : CommonState state;
136 : } Channel;
137 :
138 : struct Encoder {
139 : QuicUsrContext *usr;
140 : QuicImageType type;
141 : unsigned int width;
142 : unsigned int height;
143 :
144 : unsigned int n_buckets_8bpc;
145 : unsigned int n_buckets_5bpc;
146 :
147 : unsigned int io_available_bits;
148 : uint32_t io_word;
149 : uint32_t io_next_word;
150 : uint32_t *io_now;
151 : uint32_t *io_end;
152 : uint32_t io_words_count;
153 :
154 : int rows_completed;
155 :
156 : Channel channels[MAX_CHANNELS];
157 :
158 : CommonState rgb_state;
159 : };
160 :
161 : /* bppmask[i] contains i ones as lsb-s */
162 : static const unsigned int bppmask[33] = {
163 : 0x00000000, /* [0] */
164 : 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
165 : 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
166 : 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
167 : 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
168 : 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
169 : 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
170 : 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
171 : 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff /* [32] */
172 : };
173 :
174 : #define bitat(n) (1u<<(n))
175 :
176 :
177 : #define TABRAND_TABSIZE 256
178 : #define TABRAND_SEEDMASK 0x0ff
179 :
180 : static const unsigned int tabrand_chaos[TABRAND_TABSIZE] = {
181 : 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
182 : 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
183 : 0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
184 : 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
185 : 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
186 : 0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
187 : 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
188 : 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
189 : 0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
190 : 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
191 : 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
192 : 0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
193 : 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
194 : 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
195 : 0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
196 : 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
197 : 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
198 : 0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
199 : 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
200 : 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
201 : 0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
202 : 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
203 : 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
204 : 0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
205 : 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
206 : 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
207 : 0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
208 : 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
209 : 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
210 : 0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
211 : 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
212 : 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5,
213 : };
214 :
215 60 : static unsigned int stabrand(void)
216 : {
217 : SPICE_VERIFY( !(TABRAND_SEEDMASK & TABRAND_TABSIZE));
218 : SPICE_VERIFY( TABRAND_SEEDMASK + 1 == TABRAND_TABSIZE );
219 :
220 60 : return TABRAND_SEEDMASK;
221 : }
222 :
223 113046 : static unsigned int tabrand(unsigned int *tabrand_seed)
224 : {
225 113046 : return tabrand_chaos[++*tabrand_seed & TABRAND_SEEDMASK];
226 : }
227 :
228 : static const unsigned short besttrigtab[3][11] = { /* array of wm_trigger for waitmask and DEFevol,
229 : used by set_wm_trigger() */
230 : /* 1 */ { 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160},
231 : /* 3 */ { 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140},
232 : /* 5 */ { 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160}
233 : };
234 :
235 : /* set wm_trigger knowing waitmask (param) and DEFevol (glob)*/
236 180 : static void set_wm_trigger(CommonState *state)
237 : {
238 180 : unsigned int wm = state->wmidx;
239 180 : if (wm > 10) {
240 0 : wm = 10;
241 : }
242 :
243 : SPICE_VERIFY(DEFevol < 6);
244 :
245 180 : state->wm_trigger = besttrigtab[DEFevol / 2][wm];
246 :
247 180 : spice_assert(state->wm_trigger <= 2000);
248 180 : spice_assert(state->wm_trigger >= 1);
249 180 : }
250 :
251 13 : static int ceil_log_2(int val) /* ceil(log_2(val)) */
252 : {
253 : int result;
254 :
255 : //spice_assert(val>0);
256 :
257 13 : if (val == 1) {
258 0 : return 0;
259 : }
260 :
261 13 : result = 1;
262 13 : val -= 1;
263 67 : while (val >>= 1) {
264 54 : result++;
265 : }
266 :
267 13 : return result;
268 : }
269 :
270 : /* number of leading zeroes in the byte, used by cntlzeroes(uint)*/
271 : static const BYTE lzeroes[256] = {
272 : 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
273 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
274 : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
275 : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
276 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
280 : };
281 :
282 : /* count leading zeroes */
283 1316477 : static unsigned int cnt_l_zeroes(const unsigned int bits)
284 : {
285 1316477 : spice_extra_assert(bits != 0);
286 : #if defined(__GNUC__) && __GNUC__ >= 4
287 1316477 : return __builtin_clz(bits);
288 : #else
289 : if (bits & 0xff800000) {
290 : return lzeroes[bits >> 24];
291 : } else if (bits & 0xffff8000) {
292 : return 8 + lzeroes[(bits >> 16) & 0x000000ff];
293 : } else if (bits & 0xffffff80) {
294 : return 16 + lzeroes[(bits >> 8) & 0x000000ff];
295 : } else {
296 : return 24 + lzeroes[bits & 0x000000ff];
297 : }
298 : #endif
299 : }
300 :
301 : #define QUIC_FAMILY_8BPC
302 : #include "quic_family_tmpl.c"
303 :
304 : #define QUIC_FAMILY_5BPC
305 : #include "quic_family_tmpl.c"
306 :
307 2 : static void decorrelate_init(QuicFamily *family, int bpc)
308 : {
309 2 : const unsigned int pixelbitmask = bppmask[bpc];
310 2 : const unsigned int pixelbitmaskshr = pixelbitmask >> 1;
311 : unsigned int s;
312 :
313 : //spice_assert(bpc <= 8);
314 :
315 290 : for (s = 0; s <= pixelbitmask; s++) {
316 288 : if (s <= pixelbitmaskshr) {
317 144 : family->xlatU2L[s] = s << 1;
318 : } else {
319 144 : family->xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
320 : }
321 : }
322 2 : }
323 :
324 2 : static void correlate_init(QuicFamily *family, int bpc)
325 : {
326 2 : const unsigned int pixelbitmask = bppmask[bpc];
327 : unsigned long int s;
328 :
329 : //spice_assert(bpc <= 8);
330 :
331 290 : for (s = 0; s <= pixelbitmask; s++) {
332 288 : if (s & 0x01) {
333 144 : family->xlatL2U[s] = pixelbitmask - (s >> 1);
334 : } else {
335 144 : family->xlatL2U[s] = (s >> 1);
336 : }
337 : }
338 2 : }
339 :
340 3328 : static void golomb_coding_slow(const QuicFamily *family, const BYTE n, const unsigned int l,
341 : unsigned int * const codeword,
342 : unsigned int * const codewordlen)
343 : {
344 3328 : if (n < family->nGRcodewords[l]) {
345 1173 : (*codeword) = bitat(l) | (n & bppmask[l]);
346 1173 : (*codewordlen) = (n >> l) + l + 1;
347 : } else {
348 2155 : (*codeword) = n - family->nGRcodewords[l];
349 2155 : (*codewordlen) = family->notGRcwlen[l];
350 : }
351 3328 : }
352 :
353 2 : static void family_init(QuicFamily *family, int bpc, int limit)
354 : {
355 : int l, b;
356 :
357 15 : for (l = 0; l < bpc; l++) { /* fill arrays indexed by code number */
358 : int altprefixlen, altcodewords;
359 :
360 13 : altprefixlen = limit - bpc;
361 13 : if (altprefixlen > (int)(bppmask[bpc - l])) {
362 8 : altprefixlen = bppmask[bpc - l];
363 : }
364 :
365 13 : altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
366 :
367 13 : family->nGRcodewords[l] = (altprefixlen << l);
368 13 : family->notGRsuffixlen[l] = ceil_log_2(altcodewords); /* needed for decoding only */
369 13 : family->notGRcwlen[l] = altprefixlen + family->notGRsuffixlen[l];
370 13 : family->notGRprefixmask[l] = bppmask[32 - altprefixlen]; /* needed for decoding only */
371 :
372 3341 : for (b = 0; b < 256; b++) {
373 : unsigned int code, len;
374 3328 : golomb_coding_slow(family, b, l, &code, &len);
375 3328 : family->golomb_code[b][l] = code;
376 3328 : family->golomb_code_len[b][l] = len;
377 : }
378 : }
379 :
380 2 : decorrelate_init(family, bpc);
381 2 : correlate_init(family, bpc);
382 2 : }
383 :
384 38 : static void more_io_words(Encoder *encoder)
385 : {
386 : uint32_t *io_ptr;
387 38 : int num_io_words = encoder->usr->more_space(encoder->usr, &io_ptr, encoder->rows_completed);
388 38 : if (num_io_words <= 0) {
389 0 : encoder->usr->error(encoder->usr, "%s: no more words\n", __FUNCTION__);
390 : }
391 38 : spice_assert(io_ptr);
392 38 : encoder->io_words_count += num_io_words;
393 38 : encoder->io_now = io_ptr;
394 38 : encoder->io_end = encoder->io_now + num_io_words;
395 38 : }
396 :
397 621739 : static inline void write_io_word(Encoder *encoder)
398 : {
399 621739 : if (G_UNLIKELY(encoder->io_now == encoder->io_end)) {
400 38 : more_io_words(encoder);
401 : }
402 621739 : *(encoder->io_now++) = GUINT32_TO_LE(encoder->io_word);
403 621739 : }
404 :
405 2571339 : static inline void encode(Encoder *encoder, unsigned int word, unsigned int len)
406 : {
407 : int delta;
408 :
409 2571339 : spice_extra_assert(len > 0 && len < 32);
410 2571339 : spice_extra_assert(!(word & ~bppmask[len]));
411 :
412 2571339 : if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
413 1949600 : encoder->io_available_bits = delta;
414 1949600 : encoder->io_word |= word << encoder->io_available_bits;
415 1949600 : return;
416 : }
417 621739 : delta = -delta;
418 621739 : encoder->io_word |= word >> delta;
419 621739 : write_io_word(encoder);
420 621739 : encoder->io_available_bits = 32 - delta;
421 621739 : encoder->io_word = word << encoder->io_available_bits;
422 :
423 621739 : spice_extra_assert(encoder->io_available_bits < 32);
424 621739 : spice_extra_assert((encoder->io_word & bppmask[encoder->io_available_bits]) == 0);
425 : }
426 :
427 48 : static inline void encode_32(Encoder *encoder, unsigned int word)
428 : {
429 48 : encode(encoder, word >> 16, 16);
430 48 : encode(encoder, word & 0x0000ffff, 16);
431 48 : }
432 :
433 8 : static inline void flush(Encoder *encoder)
434 : {
435 8 : if (encoder->io_available_bits > 0 && encoder->io_available_bits != 32) {
436 8 : encode(encoder, 0, encoder->io_available_bits);
437 : }
438 8 : encode_32(encoder, 0);
439 8 : encode(encoder, 0, 1);
440 8 : }
441 :
442 621731 : static inline void read_io_word(Encoder *encoder)
443 : {
444 621731 : if (G_UNLIKELY(encoder->io_now == encoder->io_end)) {
445 0 : more_io_words(encoder);
446 : }
447 621731 : spice_extra_assert(encoder->io_now < encoder->io_end);
448 :
449 621731 : encoder->io_next_word = GUINT32_FROM_LE(*(encoder->io_now));
450 621731 : encoder->io_now++;
451 621731 : }
452 :
453 2571346 : static inline void decode_eatbits(Encoder *encoder, int len)
454 : {
455 : int delta;
456 :
457 2571346 : spice_extra_assert(len > 0 && len < 32);
458 2571346 : encoder->io_word <<= len;
459 :
460 2571346 : if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
461 1949615 : encoder->io_available_bits = delta;
462 1949615 : encoder->io_word |= encoder->io_next_word >> encoder->io_available_bits;
463 1949615 : return;
464 : }
465 :
466 621731 : delta = -delta;
467 621731 : encoder->io_word |= encoder->io_next_word << delta;
468 621731 : read_io_word(encoder);
469 621731 : encoder->io_available_bits = 32 - delta;
470 621731 : encoder->io_word |= (encoder->io_next_word >> encoder->io_available_bits);
471 : }
472 :
473 40 : static inline void decode_eat32bits(Encoder *encoder)
474 : {
475 40 : decode_eatbits(encoder, 16);
476 40 : decode_eatbits(encoder, 16);
477 40 : }
478 :
479 1158 : static inline void encode_ones(Encoder *encoder, unsigned int n)
480 : {
481 : unsigned int count;
482 :
483 1158 : for (count = n >> 5; count; count--) {
484 0 : encode_32(encoder, ~0U);
485 : }
486 :
487 1158 : if ((n &= 0x1f)) {
488 1129 : encode(encoder, (1U << n) - 1, n);
489 : }
490 1158 : }
491 :
492 : #define MELCSTATES 32 /* number of melcode states */
493 :
494 : static const int J[MELCSTATES] = {
495 : 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
496 : 7, 8, 9, 10, 11, 12, 13, 14, 15
497 : };
498 :
499 60 : static void encoder_init_rle(CommonState *state)
500 : {
501 60 : state->melcstate = 0;
502 60 : state->melclen = J[0];
503 60 : state->melcorder = 1 << state->melclen;
504 60 : }
505 :
506 :
507 1158 : static void encode_state_run(Encoder *encoder, CommonState *state, unsigned int runlen)
508 : {
509 1158 : int hits = 0;
510 :
511 2434 : while (runlen >= state->melcorder) {
512 1276 : hits++;
513 1276 : runlen -= state->melcorder;
514 1276 : if (state->melcstate < MELCSTATES - 1) {
515 1276 : state->melclen = J[++state->melcstate];
516 1276 : state->melcorder = (1L << state->melclen);
517 : }
518 : }
519 :
520 : /* send the required number of "hit" bits (one per occurrence
521 : of a run of length melcorder). This number is never too big:
522 : after 31 such "hit" bits, each "hit" would represent a run of 32K
523 : pixels.
524 : */
525 1158 : encode_ones(encoder, hits);
526 :
527 1158 : encode(encoder, runlen, state->melclen + 1);
528 :
529 : /* adjust melcoder parameters */
530 1158 : if (state->melcstate) {
531 1156 : state->melclen = J[--state->melcstate];
532 1156 : state->melcorder = (1L << state->melclen);
533 : }
534 1158 : }
535 :
536 :
537 : /* decoding routine: reads bits from the input and returns a run length. */
538 : /* argument is the number of pixels left to end-of-line (bound on run length) */
539 :
540 1158 : static int decode_state_run(Encoder *encoder, CommonState *state)
541 : {
542 1158 : int runlen = 0;
543 :
544 12 : do {
545 : register int temp, hits;
546 1170 : temp = lzeroes[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
547 : input stream, up to 8 */
548 2446 : for (hits = 1; hits <= temp; hits++) {
549 1276 : runlen += state->melcorder;
550 :
551 1276 : if (state->melcstate < MELCSTATES - 1) {
552 1276 : state->melclen = J[++state->melcstate];
553 1276 : state->melcorder = (1U << state->melclen);
554 : }
555 : }
556 1170 : if (temp != 8) {
557 1158 : decode_eatbits(encoder, temp + 1); /* consume the leading
558 : 0 of the remainder encoding */
559 1158 : break;
560 : }
561 12 : decode_eatbits(encoder, 8);
562 : } while (1);
563 :
564 : /* read the length of the remainder */
565 1158 : if (state->melclen) {
566 1156 : runlen += encoder->io_word >> (32 - state->melclen);
567 1156 : decode_eatbits(encoder, state->melclen);
568 : }
569 :
570 : /* adjust melcorder parameters */
571 1158 : if (state->melcstate) {
572 1156 : state->melclen = J[--state->melcstate];
573 1156 : state->melcorder = (1U << state->melclen);
574 : }
575 :
576 1158 : return runlen;
577 : }
578 :
579 8 : static inline void init_decode_io(Encoder *encoder)
580 : {
581 8 : encoder->io_next_word = encoder->io_word = GUINT32_FROM_LE(*(encoder->io_now));
582 8 : encoder->io_now++;
583 8 : encoder->io_available_bits = 0;
584 8 : }
585 :
586 : #include <spice/start-packed.h>
587 :
588 : typedef struct SPICE_ATTR_PACKED one_byte_pixel_t {
589 : BYTE a;
590 : } one_byte_t;
591 :
592 : typedef struct SPICE_ATTR_PACKED four_bytes_pixel_t {
593 : BYTE a;
594 : BYTE b;
595 : BYTE c;
596 : BYTE d;
597 : } four_bytes_t;
598 :
599 : typedef struct SPICE_ATTR_PACKED rgb32_pixel_t {
600 : BYTE b;
601 : BYTE g;
602 : BYTE r;
603 : BYTE pad;
604 : } rgb32_pixel_t;
605 :
606 : typedef struct SPICE_ATTR_PACKED rgb24_pixel_t {
607 : BYTE b;
608 : BYTE g;
609 : BYTE r;
610 : } rgb24_pixel_t;
611 :
612 : typedef uint16_t rgb16_pixel_t;
613 :
614 : #include <spice/end-packed.h>
615 :
616 : #define ONE_BYTE
617 : #include "quic_tmpl.c"
618 :
619 : #define FOUR_BYTE
620 : #include "quic_tmpl.c"
621 :
622 : #define QUIC_RGB32
623 : #include "quic_tmpl.c"
624 :
625 : #define QUIC_RGB24
626 : #include "quic_tmpl.c"
627 :
628 : #define QUIC_RGB16
629 : #include "quic_tmpl.c"
630 :
631 : #define QUIC_RGB16_TO_32
632 : #include "quic_tmpl.c"
633 :
634 128 : static void fill_model_structures(SPICE_GNUC_UNUSED Encoder *encoder, FamilyStat *family_stat,
635 : unsigned int rep_first, unsigned int first_size,
636 : unsigned int rep_next, unsigned int mul_size,
637 : unsigned int levels, unsigned int ncounters,
638 : unsigned int nbuckets, unsigned int n_buckets_ptrs)
639 : {
640 : unsigned int
641 : bsize,
642 : bstart,
643 128 : bend = 0,
644 : repcntr,
645 : bnumber;
646 :
647 128 : COUNTER * free_counter = family_stat->counters;/* first free location in the array of
648 : counters */
649 :
650 128 : bnumber = 0;
651 :
652 128 : repcntr = rep_first + 1; /* first bucket */
653 128 : bsize = first_size;
654 :
655 : do { /* others */
656 832 : if (bnumber) {
657 704 : bstart = bend + 1;
658 : } else {
659 128 : bstart = 0;
660 : }
661 :
662 832 : if (!--repcntr) {
663 704 : repcntr = rep_next;
664 704 : bsize *= mul_size;
665 : }
666 :
667 832 : bend = bstart + bsize - 1;
668 832 : if (bend + bsize >= levels) {
669 128 : bend = levels - 1;
670 : }
671 :
672 832 : family_stat->buckets_buf[bnumber].pcounters = free_counter;
673 832 : free_counter += ncounters;
674 :
675 832 : spice_assert(bstart < n_buckets_ptrs);
676 : {
677 : unsigned int i;
678 832 : spice_assert(bend < n_buckets_ptrs);
679 19264 : for (i = bstart; i <= bend; i++) {
680 18432 : family_stat->buckets_ptrs[i] = family_stat->buckets_buf + bnumber;
681 : }
682 : }
683 :
684 832 : bnumber++;
685 832 : } while (bend < levels - 1);
686 :
687 128 : spice_assert(free_counter - family_stat->counters == (ptrdiff_t)(nbuckets * ncounters));
688 128 : }
689 :
690 128 : static void find_model_params(Encoder *encoder,
691 : const int bpc,
692 : unsigned int *ncounters,
693 : unsigned int *levels,
694 : unsigned int *n_buckets_ptrs,
695 : unsigned int *repfirst,
696 : unsigned int *firstsize,
697 : unsigned int *repnext,
698 : unsigned int *mulsize,
699 : unsigned int *nbuckets)
700 : {
701 : unsigned int bsize; /* bucket size */
702 128 : unsigned int bstart, bend = 0; /* bucket start and end, range : 0 to levels-1*/
703 : unsigned int repcntr; /* helper */
704 :
705 : /* The only valid values are 1, 3 and 5.
706 : 0, 2 and 4 are obsolete and the rest of the
707 : values are considered out of the range. */
708 : SPICE_VERIFY(DEFevol == 1 || DEFevol == 3 || DEFevol == 5);
709 128 : spice_assert(bpc <= 8 && bpc > 0);
710 :
711 128 : *ncounters = 8;
712 :
713 128 : *levels = 0x1 << bpc;
714 :
715 128 : *n_buckets_ptrs = 0; /* ==0 means: not set yet */
716 :
717 : switch (DEFevol) { /* set repfirst firstsize repnext mulsize */
718 : case 1: /* buckets contain following numbers of contexts: 1 1 1 2 2 4 4 8 8 ... */
719 : *repfirst = 3;
720 : *firstsize = 1;
721 : *repnext = 2;
722 : *mulsize = 2;
723 : break;
724 : case 3: /* 1 2 4 8 16 32 64 ... */
725 128 : *repfirst = 1;
726 128 : *firstsize = 1;
727 128 : *repnext = 1;
728 128 : *mulsize = 2;
729 128 : break;
730 : case 5: /* 1 4 16 64 256 1024 4096 16384 65536 */
731 : *repfirst = 1;
732 : *firstsize = 1;
733 : *repnext = 1;
734 : *mulsize = 4;
735 : break;
736 : default:
737 : encoder->usr->error(encoder->usr, "findmodelparams(): DEFevol out of range!!!\n");
738 : return;
739 : }
740 :
741 128 : *nbuckets = 0;
742 128 : repcntr = *repfirst + 1; /* first bucket */
743 128 : bsize = *firstsize;
744 :
745 : do { /* other buckets */
746 832 : if (*nbuckets) { /* bucket start */
747 704 : bstart = bend + 1;
748 : } else {
749 128 : bstart = 0;
750 : }
751 :
752 832 : if (!--repcntr) { /* bucket size */
753 704 : repcntr = *repnext;
754 704 : bsize *= *mulsize;
755 : }
756 :
757 832 : bend = bstart + bsize - 1; /* bucket end */
758 832 : if (bend + bsize >= *levels) { /* if following bucked was bigger than current one */
759 128 : bend = *levels - 1; /* concatenate them */
760 : }
761 :
762 832 : if (!*n_buckets_ptrs) { /* array size not set yet? */
763 128 : *n_buckets_ptrs = *levels;
764 : #if 0
765 : if (bend == *levels - 1) { /* this bucket is last - all in the first array */
766 : *n_buckets_ptrs = *levels;
767 : } else if (bsize >= 256) { /* this bucket is allowed to reside in the 2nd table */
768 : b_lo_ptrs = bstart;
769 : spice_assert(bstart); /* previous bucket exists */
770 : }
771 : #endif
772 : }
773 :
774 832 : (*nbuckets)++;
775 832 : } while (bend < *levels - 1);
776 : }
777 :
778 128 : static int init_model_structures(Encoder *encoder, FamilyStat *family_stat,
779 : unsigned int rep_first, unsigned int first_size,
780 : unsigned int rep_next, unsigned int mul_size,
781 : unsigned int levels, unsigned int ncounters,
782 : unsigned int n_buckets_ptrs, unsigned int n_buckets)
783 : {
784 256 : family_stat->buckets_ptrs = (s_bucket **)encoder->usr->malloc(encoder->usr,
785 128 : n_buckets_ptrs *
786 : sizeof(s_bucket *));
787 128 : if (!family_stat->buckets_ptrs) {
788 0 : return FALSE;
789 : }
790 :
791 256 : family_stat->counters = (COUNTER *)encoder->usr->malloc(encoder->usr,
792 128 : n_buckets * sizeof(COUNTER) *
793 : MAXNUMCODES);
794 128 : if (!family_stat->counters) {
795 0 : goto error_1;
796 : }
797 :
798 256 : family_stat->buckets_buf = (s_bucket *)encoder->usr->malloc(encoder->usr,
799 128 : n_buckets * sizeof(s_bucket));
800 128 : if (!family_stat->buckets_buf) {
801 0 : goto error_2;
802 : }
803 :
804 128 : fill_model_structures(encoder, family_stat, rep_first, first_size, rep_next, mul_size, levels,
805 : ncounters, n_buckets, n_buckets_ptrs);
806 :
807 128 : return TRUE;
808 :
809 0 : error_2:
810 0 : encoder->usr->free(encoder->usr, family_stat->counters);
811 :
812 0 : error_1:
813 0 : encoder->usr->free(encoder->usr, family_stat->buckets_ptrs);
814 :
815 0 : return FALSE;
816 : }
817 :
818 128 : static void free_family_stat(QuicUsrContext *usr, FamilyStat *family_stat)
819 : {
820 128 : usr->free(usr, family_stat->buckets_ptrs);
821 128 : usr->free(usr, family_stat->counters);
822 128 : usr->free(usr, family_stat->buckets_buf);
823 128 : }
824 :
825 64 : static int init_channel(Encoder *encoder, Channel *channel)
826 : {
827 : unsigned int ncounters;
828 : unsigned int levels;
829 : unsigned int rep_first;
830 : unsigned int first_size;
831 : unsigned int rep_next;
832 : unsigned int mul_size;
833 : unsigned int n_buckets;
834 : unsigned int n_buckets_ptrs;
835 :
836 64 : channel->correlate_row_width = 0;
837 64 : channel->correlate_row = NULL;
838 :
839 64 : find_model_params(encoder, 8, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
840 : &first_size, &rep_next, &mul_size, &n_buckets);
841 64 : encoder->n_buckets_8bpc = n_buckets;
842 64 : if (!init_model_structures(encoder, &channel->family_stat_8bpc, rep_first, first_size,
843 : rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
844 : n_buckets)) {
845 0 : return FALSE;
846 : }
847 :
848 64 : find_model_params(encoder, 5, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
849 : &first_size, &rep_next, &mul_size, &n_buckets);
850 64 : encoder->n_buckets_5bpc = n_buckets;
851 64 : if (!init_model_structures(encoder, &channel->family_stat_5bpc, rep_first, first_size,
852 : rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
853 : n_buckets)) {
854 0 : free_family_stat(encoder->usr, &channel->family_stat_8bpc);
855 0 : return FALSE;
856 : }
857 :
858 64 : return TRUE;
859 : }
860 :
861 64 : static void destroy_channel(Encoder *encoder, Channel *channel)
862 : {
863 64 : QuicUsrContext *usr = encoder->usr;
864 64 : if (channel->correlate_row) {
865 44 : usr->free(usr, channel->correlate_row - 1);
866 : }
867 64 : free_family_stat(usr, &channel->family_stat_8bpc);
868 64 : free_family_stat(usr, &channel->family_stat_5bpc);
869 64 : }
870 :
871 16 : static int init_encoder(Encoder *encoder, QuicUsrContext *usr)
872 : {
873 : int i;
874 :
875 16 : encoder->usr = usr;
876 :
877 80 : for (i = 0; i < MAX_CHANNELS; i++) {
878 64 : if (!init_channel(encoder, &encoder->channels[i])) {
879 0 : for (--i; i >= 0; i--) {
880 0 : destroy_channel(encoder, &encoder->channels[i]);
881 : }
882 0 : return FALSE;
883 : }
884 : }
885 16 : return TRUE;
886 : }
887 :
888 16 : static int encoder_reset(Encoder *encoder, uint32_t *io_ptr, uint32_t *io_ptr_end)
889 : {
890 16 : spice_assert(((uintptr_t)io_ptr % 4) == ((uintptr_t)io_ptr_end % 4));
891 16 : spice_assert(io_ptr <= io_ptr_end);
892 :
893 16 : encoder->rgb_state.waitcnt = 0;
894 16 : encoder->rgb_state.tabrand_seed = stabrand();
895 16 : encoder->rgb_state.wmidx = DEFwmistart;
896 16 : encoder->rgb_state.wmileft = DEFwminext;
897 16 : set_wm_trigger(&encoder->rgb_state);
898 :
899 16 : encoder_init_rle(&encoder->rgb_state);
900 :
901 16 : encoder->io_words_count = io_ptr_end - io_ptr;
902 16 : encoder->io_now = io_ptr;
903 16 : encoder->io_end = io_ptr_end;
904 16 : encoder->rows_completed = 0;
905 :
906 16 : return TRUE;
907 : }
908 :
909 16 : static int encoder_reset_channels(Encoder *encoder, int channels, int width, int bpc)
910 : {
911 : int i;
912 :
913 60 : for (i = 0; i < channels; i++) {
914 : s_bucket *bucket;
915 : s_bucket *end_bucket;
916 :
917 44 : if (encoder->channels[i].correlate_row_width < width) {
918 44 : encoder->channels[i].correlate_row_width = 0;
919 44 : if (encoder->channels[i].correlate_row) {
920 0 : encoder->usr->free(encoder->usr, encoder->channels[i].correlate_row - 1);
921 : }
922 44 : if (!(encoder->channels[i].correlate_row = (BYTE *)encoder->usr->malloc(encoder->usr,
923 : width + 1))) {
924 0 : return FALSE;
925 : }
926 44 : encoder->channels[i].correlate_row++;
927 44 : encoder->channels[i].correlate_row_width = width;
928 : }
929 :
930 44 : if (bpc == 8) {
931 32 : MEMCLEAR(encoder->channels[i].family_stat_8bpc.counters,
932 : encoder->n_buckets_8bpc * sizeof(COUNTER) * MAXNUMCODES);
933 32 : bucket = encoder->channels[i].family_stat_8bpc.buckets_buf;
934 32 : end_bucket = bucket + encoder->n_buckets_8bpc;
935 288 : for (; bucket < end_bucket; bucket++) {
936 256 : bucket->bestcode = /*BPC*/ 8 - 1;
937 : }
938 32 : encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_8bpc.buckets_ptrs;
939 12 : } else if (bpc == 5) {
940 12 : MEMCLEAR(encoder->channels[i].family_stat_5bpc.counters,
941 : encoder->n_buckets_5bpc * sizeof(COUNTER) * MAXNUMCODES);
942 12 : bucket = encoder->channels[i].family_stat_5bpc.buckets_buf;
943 12 : end_bucket = bucket + encoder->n_buckets_5bpc;
944 72 : for (; bucket < end_bucket; bucket++) {
945 60 : bucket->bestcode = /*BPC*/ 5 - 1;
946 : }
947 12 : encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_5bpc.buckets_ptrs;
948 : } else {
949 0 : encoder->usr->warn(encoder->usr, "%s: bad bpc %d\n", __FUNCTION__, bpc);
950 0 : return FALSE;
951 : }
952 :
953 44 : encoder->channels[i].state.waitcnt = 0;
954 44 : encoder->channels[i].state.tabrand_seed = stabrand();
955 44 : encoder->channels[i].state.wmidx = DEFwmistart;
956 44 : encoder->channels[i].state.wmileft = DEFwminext;
957 44 : set_wm_trigger(&encoder->channels[i].state);
958 :
959 44 : encoder_init_rle(&encoder->channels[i].state);
960 : }
961 16 : return TRUE;
962 : }
963 :
964 16 : static void quic_image_params(Encoder *encoder, QuicImageType type, int *channels, int *bpc)
965 : {
966 16 : spice_assert(channels && bpc);
967 16 : switch (type) {
968 4 : case QUIC_IMAGE_TYPE_GRAY:
969 4 : *channels = 1;
970 4 : *bpc = 8;
971 4 : break;
972 4 : case QUIC_IMAGE_TYPE_RGB16:
973 4 : *channels = 3;
974 4 : *bpc = 5;
975 4 : break;
976 4 : case QUIC_IMAGE_TYPE_RGB24:
977 4 : *channels = 3;
978 4 : *bpc = 8;
979 4 : break;
980 0 : case QUIC_IMAGE_TYPE_RGB32:
981 0 : *channels = 3;
982 0 : *bpc = 8;
983 0 : break;
984 4 : case QUIC_IMAGE_TYPE_RGBA:
985 4 : *channels = 4;
986 4 : *bpc = 8;
987 4 : break;
988 0 : case QUIC_IMAGE_TYPE_INVALID:
989 : default:
990 0 : *channels = 0;
991 0 : *bpc = 0;
992 0 : encoder->usr->error(encoder->usr, "bad image type\n");
993 : }
994 16 : }
995 :
996 : #define FILL_LINES() { \
997 : if (line == lines_end) { \
998 : int n = encoder->usr->more_lines(encoder->usr, &line); \
999 : if (n <= 0 || line == NULL) { \
1000 : encoder->usr->error(encoder->usr, "more lines failed\n"); \
1001 : } \
1002 : lines_end = line + n * stride; \
1003 : } \
1004 : }
1005 :
1006 : #define NEXT_LINE() { \
1007 : line += stride; \
1008 : FILL_LINES(); \
1009 : }
1010 :
1011 : #define QUIC_COMPRESS_RGB(bits) \
1012 : encoder->channels[0].correlate_row[-1] = 0; \
1013 : encoder->channels[1].correlate_row[-1] = 0; \
1014 : encoder->channels[2].correlate_row[-1] = 0; \
1015 : quic_rgb##bits##_compress_row0(encoder, (rgb##bits##_pixel_t *)(line), width); \
1016 : encoder->rows_completed++; \
1017 : for (row = 1; row < height; row++) { \
1018 : prev = line; \
1019 : NEXT_LINE(); \
1020 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
1021 : encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
1022 : encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
1023 : quic_rgb##bits##_compress_row(encoder, (rgb##bits##_pixel_t *)prev, \
1024 : (rgb##bits##_pixel_t *)line, width); \
1025 : encoder->rows_completed++; \
1026 : }
1027 :
1028 8 : int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
1029 : uint8_t *line, unsigned int num_lines, int stride,
1030 : uint32_t *io_ptr, unsigned int num_io_words)
1031 : {
1032 8 : Encoder *encoder = (Encoder *)quic;
1033 8 : uint32_t *io_ptr_end = io_ptr + num_io_words;
1034 : uint8_t *lines_end;
1035 : int row;
1036 : uint8_t *prev;
1037 : int channels;
1038 : int bpc;
1039 :
1040 8 : lines_end = line + num_lines * stride;
1041 8 : if (line == NULL && lines_end != line) {
1042 0 : spice_warn_if_reached();
1043 0 : return QUIC_ERROR;
1044 : }
1045 :
1046 8 : quic_image_params(encoder, type, &channels, &bpc);
1047 :
1048 16 : if (!encoder_reset(encoder, io_ptr, io_ptr_end) ||
1049 8 : !encoder_reset_channels(encoder, channels, width, bpc)) {
1050 0 : return QUIC_ERROR;
1051 : }
1052 :
1053 8 : encoder->io_word = 0;
1054 8 : encoder->io_available_bits = 32;
1055 :
1056 8 : encode_32(encoder, QUIC_MAGIC);
1057 8 : encode_32(encoder, QUIC_VERSION);
1058 8 : encode_32(encoder, type);
1059 8 : encode_32(encoder, width);
1060 8 : encode_32(encoder, height);
1061 :
1062 8 : FILL_LINES();
1063 :
1064 8 : switch (type) {
1065 0 : case QUIC_IMAGE_TYPE_RGB32:
1066 0 : spice_assert(ABS(stride) >= width * 4);
1067 0 : QUIC_COMPRESS_RGB(32);
1068 0 : break;
1069 2 : case QUIC_IMAGE_TYPE_RGB24:
1070 2 : spice_assert(ABS(stride) >= width * 3);
1071 454 : QUIC_COMPRESS_RGB(24);
1072 2 : break;
1073 2 : case QUIC_IMAGE_TYPE_RGB16:
1074 2 : spice_assert(ABS(stride) >= width * 2);
1075 369 : QUIC_COMPRESS_RGB(16);
1076 2 : break;
1077 2 : case QUIC_IMAGE_TYPE_RGBA:
1078 2 : spice_assert(ABS(stride) >= width * 4);
1079 :
1080 2 : encoder->channels[0].correlate_row[-1] = 0;
1081 2 : encoder->channels[1].correlate_row[-1] = 0;
1082 2 : encoder->channels[2].correlate_row[-1] = 0;
1083 2 : quic_rgb32_compress_row0(encoder, (rgb32_pixel_t *)(line), width);
1084 :
1085 2 : encoder->channels[3].correlate_row[-1] = 0;
1086 2 : quic_four_compress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(line + 3), width);
1087 :
1088 2 : encoder->rows_completed++;
1089 :
1090 302 : for (row = 1; row < height; row++) {
1091 300 : prev = line;
1092 300 : NEXT_LINE();
1093 300 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
1094 300 : encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
1095 300 : encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
1096 300 : quic_rgb32_compress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)line, width);
1097 :
1098 300 : encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
1099 300 : quic_four_compress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
1100 300 : (four_bytes_t *)(line + 3), width);
1101 300 : encoder->rows_completed++;
1102 : }
1103 2 : break;
1104 2 : case QUIC_IMAGE_TYPE_GRAY:
1105 2 : spice_assert(ABS(stride) >= width);
1106 2 : encoder->channels[0].correlate_row[-1] = 0;
1107 2 : quic_one_compress_row0(encoder, &encoder->channels[0], (one_byte_t *)line, width);
1108 2 : encoder->rows_completed++;
1109 753 : for (row = 1; row < height; row++) {
1110 751 : prev = line;
1111 751 : NEXT_LINE();
1112 751 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
1113 751 : quic_one_compress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
1114 : (one_byte_t *)line, width);
1115 751 : encoder->rows_completed++;
1116 : }
1117 2 : break;
1118 0 : case QUIC_IMAGE_TYPE_INVALID:
1119 : default:
1120 0 : encoder->usr->error(encoder->usr, "bad image type\n");
1121 : }
1122 :
1123 8 : flush(encoder);
1124 8 : encoder->io_words_count -= (encoder->io_end - encoder->io_now);
1125 :
1126 8 : return encoder->io_words_count;
1127 : }
1128 :
1129 8 : int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
1130 : QuicImageType *out_type, int *out_width, int *out_height)
1131 : {
1132 8 : Encoder *encoder = (Encoder *)quic;
1133 8 : uint32_t *io_ptr_end = io_ptr + num_io_words;
1134 : QuicImageType type;
1135 : int width;
1136 : int height;
1137 : uint32_t magic;
1138 : uint32_t version;
1139 : int channels;
1140 : int bpc;
1141 :
1142 8 : if (!num_io_words || !encoder_reset(encoder, io_ptr, io_ptr_end)) {
1143 0 : return QUIC_ERROR;
1144 : }
1145 :
1146 8 : init_decode_io(encoder);
1147 :
1148 8 : magic = encoder->io_word;
1149 8 : decode_eat32bits(encoder);
1150 8 : if (magic != QUIC_MAGIC) {
1151 0 : encoder->usr->warn(encoder->usr, "bad magic\n");
1152 0 : return QUIC_ERROR;
1153 : }
1154 :
1155 8 : version = encoder->io_word;
1156 8 : decode_eat32bits(encoder);
1157 8 : if (version != QUIC_VERSION) {
1158 0 : encoder->usr->warn(encoder->usr, "bad version\n");
1159 0 : return QUIC_ERROR;
1160 : }
1161 :
1162 8 : type = (QuicImageType)encoder->io_word;
1163 8 : decode_eat32bits(encoder);
1164 :
1165 8 : width = encoder->io_word;
1166 8 : decode_eat32bits(encoder);
1167 :
1168 8 : height = encoder->io_word;
1169 8 : decode_eat32bits(encoder);
1170 :
1171 8 : if (width <= 0 || height <= 0) {
1172 0 : encoder->usr->warn(encoder->usr, "invalid size\n");
1173 0 : return QUIC_ERROR;
1174 : }
1175 :
1176 : /* avoid too big images */
1177 8 : if ((uint64_t) width * height > SPICE_MAX_IMAGE_SIZE) {
1178 0 : encoder->usr->error(encoder->usr, "image too large\n");
1179 : }
1180 :
1181 8 : quic_image_params(encoder, type, &channels, &bpc);
1182 :
1183 8 : if (!encoder_reset_channels(encoder, channels, width, bpc)) {
1184 0 : return QUIC_ERROR;
1185 : }
1186 :
1187 8 : *out_width = encoder->width = width;
1188 8 : *out_height = encoder->height = height;
1189 8 : *out_type = encoder->type = type;
1190 8 : return QUIC_OK;
1191 : }
1192 :
1193 2 : static void uncompress_rgba(Encoder *encoder, uint8_t *buf, int stride)
1194 : {
1195 : unsigned int row;
1196 : uint8_t *prev;
1197 :
1198 2 : encoder->channels[0].correlate_row[-1] = 0;
1199 2 : encoder->channels[1].correlate_row[-1] = 0;
1200 2 : encoder->channels[2].correlate_row[-1] = 0;
1201 2 : quic_rgb32_uncompress_row0(encoder, (rgb32_pixel_t *)buf, encoder->width);
1202 :
1203 2 : encoder->channels[3].correlate_row[-1] = 0;
1204 2 : quic_four_uncompress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(buf + 3),
1205 : encoder->width);
1206 :
1207 2 : encoder->rows_completed++;
1208 302 : for (row = 1; row < encoder->height; row++) {
1209 300 : prev = buf;
1210 300 : buf += stride;
1211 :
1212 300 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
1213 300 : encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
1214 300 : encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
1215 300 : quic_rgb32_uncompress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)buf,
1216 : encoder->width);
1217 :
1218 300 : encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
1219 300 : quic_four_uncompress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
1220 300 : (four_bytes_t *)(buf + 3), encoder->width);
1221 :
1222 300 : encoder->rows_completed++;
1223 : }
1224 2 : }
1225 :
1226 2 : static void uncompress_gray(Encoder *encoder, uint8_t *buf, int stride)
1227 : {
1228 : unsigned int row;
1229 : uint8_t *prev;
1230 :
1231 2 : encoder->channels[0].correlate_row[-1] = 0;
1232 2 : quic_one_uncompress_row0(encoder, &encoder->channels[0], (one_byte_t *)buf, encoder->width);
1233 2 : encoder->rows_completed++;
1234 753 : for (row = 1; row < encoder->height; row++) {
1235 751 : prev = buf;
1236 751 : buf += stride;
1237 751 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
1238 751 : quic_one_uncompress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
1239 : (one_byte_t *)buf, encoder->width);
1240 751 : encoder->rows_completed++;
1241 : }
1242 2 : }
1243 :
1244 : #define QUIC_UNCOMPRESS_RGB(prefix, type) \
1245 : encoder->channels[0].correlate_row[-1] = 0; \
1246 : encoder->channels[1].correlate_row[-1] = 0; \
1247 : encoder->channels[2].correlate_row[-1] = 0; \
1248 : quic_rgb##prefix##_uncompress_row0(encoder, (type *)buf, encoder->width); \
1249 : encoder->rows_completed++; \
1250 : for (row = 1; row < encoder->height; row++) { \
1251 : prev = buf; \
1252 : buf += stride; \
1253 : encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
1254 : encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
1255 : encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
1256 : quic_rgb##prefix##_uncompress_row(encoder, (type *)prev, (type *)buf, \
1257 : encoder->width); \
1258 : encoder->rows_completed++; \
1259 : }
1260 :
1261 8 : int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride)
1262 : {
1263 8 : Encoder *encoder = (Encoder *)quic;
1264 : unsigned int row;
1265 : uint8_t *prev;
1266 :
1267 8 : spice_assert(buf);
1268 :
1269 8 : switch (encoder->type) {
1270 2 : case QUIC_IMAGE_TYPE_RGB32:
1271 : case QUIC_IMAGE_TYPE_RGB24:
1272 2 : if (type == QUIC_IMAGE_TYPE_RGB32) {
1273 0 : spice_assert(ABS(stride) >= (int)encoder->width * 4);
1274 0 : QUIC_UNCOMPRESS_RGB(32, rgb32_pixel_t);
1275 0 : break;
1276 2 : } else if (type == QUIC_IMAGE_TYPE_RGB24) {
1277 2 : spice_assert(ABS(stride) >= (int)encoder->width * 3);
1278 454 : QUIC_UNCOMPRESS_RGB(24, rgb24_pixel_t);
1279 2 : break;
1280 : }
1281 0 : encoder->usr->warn(encoder->usr, "unsupported output format\n");
1282 0 : return QUIC_ERROR;
1283 2 : case QUIC_IMAGE_TYPE_RGB16:
1284 2 : if (type == QUIC_IMAGE_TYPE_RGB16) {
1285 2 : spice_assert(ABS(stride) >= (int)encoder->width * 2);
1286 369 : QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
1287 0 : } else if (type == QUIC_IMAGE_TYPE_RGB32) {
1288 0 : spice_assert(ABS(stride) >= (int)encoder->width * 4);
1289 0 : QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
1290 : } else {
1291 0 : encoder->usr->warn(encoder->usr, "unsupported output format\n");
1292 0 : return QUIC_ERROR;
1293 : }
1294 :
1295 2 : break;
1296 2 : case QUIC_IMAGE_TYPE_RGBA:
1297 :
1298 2 : if (type != QUIC_IMAGE_TYPE_RGBA) {
1299 0 : encoder->usr->warn(encoder->usr, "unsupported output format\n");
1300 0 : return QUIC_ERROR;
1301 : }
1302 2 : spice_assert(ABS(stride) >= (int)encoder->width * 4);
1303 2 : uncompress_rgba(encoder, buf, stride);
1304 2 : break;
1305 2 : case QUIC_IMAGE_TYPE_GRAY:
1306 :
1307 2 : if (type != QUIC_IMAGE_TYPE_GRAY) {
1308 0 : encoder->usr->warn(encoder->usr, "unsupported output format\n");
1309 0 : return QUIC_ERROR;
1310 : }
1311 2 : spice_assert(ABS(stride) >= (int)encoder->width);
1312 2 : uncompress_gray(encoder, buf, stride);
1313 2 : break;
1314 0 : case QUIC_IMAGE_TYPE_INVALID:
1315 : default:
1316 0 : encoder->usr->error(encoder->usr, "bad image type\n");
1317 : }
1318 8 : return QUIC_OK;
1319 : }
1320 :
1321 16 : QuicContext *quic_create(QuicUsrContext *usr)
1322 : {
1323 : Encoder *encoder;
1324 :
1325 16 : if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
1326 16 : !usr->free || !usr->more_space || !usr->more_lines) {
1327 0 : return NULL;
1328 : }
1329 :
1330 16 : if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
1331 0 : return NULL;
1332 : }
1333 :
1334 16 : if (!init_encoder(encoder, usr)) {
1335 0 : usr->free(usr, encoder);
1336 0 : return NULL;
1337 : }
1338 16 : return (QuicContext *)encoder;
1339 : }
1340 :
1341 16 : void quic_destroy(QuicContext *quic)
1342 : {
1343 16 : Encoder *encoder = (Encoder *)quic;
1344 : int i;
1345 :
1346 16 : if (!quic) {
1347 0 : return;
1348 : }
1349 :
1350 80 : for (i = 0; i < MAX_CHANNELS; i++) {
1351 64 : destroy_channel(encoder, &encoder->channels[i]);
1352 : }
1353 16 : encoder->usr->free(encoder->usr, encoder);
1354 : }
1355 :
1356 1 : SPICE_CONSTRUCTOR_FUNC(quic_global_init)
1357 : {
1358 1 : family_init(&family_8bpc, 8, DEFmaxclen);
1359 1 : family_init(&family_5bpc, 5, DEFmaxclen);
1360 1 : }
|