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 : #include <config.h>
19 :
20 : #define COMPRESS_IMP
21 :
22 : #if defined(ONE_BYTE) || defined(FOUR_BYTE)
23 : # define FARGS_DECL(...) (Encoder *encoder, Channel *channel_a, __VA_ARGS__)
24 : # define FARGS_CALL(...) (encoder, channel_a, __VA_ARGS__)
25 : # define UNCOMPRESS_PIX_START(row) do { } while (0)
26 : # define SET_a(pix, val) ((pix)->a = val)
27 : # define GET_a(pix) ((pix)->a)
28 : # define SAME_PIXEL(p1, p2) (GET_a(p1) == GET_a(p2))
29 : # define COPY_PIXEL(dest, src) \
30 : SET_a(dest, GET_a(src));
31 : # define DECLARE_STATE_VARIABLES \
32 : CommonState *state = &channel_a->state
33 : # define DECLARE_CHANNEL_VARIABLES \
34 : BYTE * const correlate_row_a = channel_a->correlate_row
35 : # define APPLY_ALL_COMP(macro, ...) \
36 : macro(a, ## __VA_ARGS__)
37 : #else
38 : # define FARGS_DECL(...) (Encoder *encoder, __VA_ARGS__)
39 : # define FARGS_CALL(...) (encoder, __VA_ARGS__)
40 : # define SAME_PIXEL(p1, p2) \
41 : (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \
42 : GET_b(p1) == GET_b(p2))
43 : # define COPY_PIXEL(dest, src) \
44 : SET_r(dest, GET_r(src)); \
45 : SET_g(dest, GET_g(src)); \
46 : SET_b(dest, GET_b(src))
47 : # define DECLARE_STATE_VARIABLES \
48 : CommonState *state = &encoder->rgb_state
49 : # define DECLARE_CHANNEL_VARIABLES \
50 : Channel * const channel_r = encoder->channels; \
51 : Channel * const channel_g = channel_r + 1; \
52 : Channel * const channel_b = channel_g + 1; \
53 : BYTE * const correlate_row_r = channel_r->correlate_row; \
54 : BYTE * const correlate_row_g = channel_g->correlate_row; \
55 : BYTE * const correlate_row_b = channel_b->correlate_row
56 : # define APPLY_ALL_COMP(macro, ...) \
57 : macro(r, ## __VA_ARGS__); \
58 : macro(g, ## __VA_ARGS__); \
59 : macro(b, ## __VA_ARGS__)
60 : #endif
61 :
62 : #ifdef ONE_BYTE
63 : #undef ONE_BYTE
64 : #define FNAME(name) quic_one_##name
65 : #define PIXEL one_byte_t
66 : #define BPC 8
67 : #endif
68 :
69 : #ifdef FOUR_BYTE
70 : #undef FOUR_BYTE
71 : #define FNAME(name) quic_four_##name
72 : #define PIXEL four_bytes_t
73 : #define BPC 8
74 : #endif
75 :
76 : #ifdef QUIC_RGB32
77 : #undef QUIC_RGB32
78 : #define PIXEL rgb32_pixel_t
79 : #define FNAME(name) quic_rgb32_##name
80 : #define BPC 8
81 : #define SET_r(pix, val) ((pix)->r = val)
82 : #define GET_r(pix) ((pix)->r)
83 : #define SET_g(pix, val) ((pix)->g = val)
84 : #define GET_g(pix) ((pix)->g)
85 : #define SET_b(pix, val) ((pix)->b = val)
86 : #define GET_b(pix) ((pix)->b)
87 : #define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
88 : #endif
89 :
90 : #ifdef QUIC_RGB24
91 : #undef QUIC_RGB24
92 : #define PIXEL rgb24_pixel_t
93 : #define FNAME(name) quic_rgb24_##name
94 : #define BPC 8
95 : #define SET_r(pix, val) ((pix)->r = val)
96 : #define GET_r(pix) ((pix)->r)
97 : #define SET_g(pix, val) ((pix)->g = val)
98 : #define GET_g(pix) ((pix)->g)
99 : #define SET_b(pix, val) ((pix)->b = val)
100 : #define GET_b(pix) ((pix)->b)
101 : #define UNCOMPRESS_PIX_START(pix)
102 : #endif
103 :
104 : #ifdef QUIC_RGB16
105 : #undef QUIC_RGB16
106 : #define PIXEL rgb16_pixel_t
107 : #define FNAME(name) quic_rgb16_##name
108 : #define BPC 5
109 : #define SET_r(pix, val) (*(pix) = (*(pix) & ~(0x1f << 10)) | ((val) << 10))
110 : #define GET_r(pix) ((*(pix) >> 10) & 0x1f)
111 : #define SET_g(pix, val) (*(pix) = (*(pix) & ~(0x1f << 5)) | ((val) << 5))
112 : #define GET_g(pix) ((*(pix) >> 5) & 0x1f)
113 : #define SET_b(pix, val) (*(pix) = (*(pix) & ~0x1f) | (val))
114 : #define GET_b(pix) (*(pix) & 0x1f)
115 : #define UNCOMPRESS_PIX_START(pix) (*(pix) = 0)
116 : #endif
117 :
118 : #ifdef QUIC_RGB16_TO_32
119 : #undef QUIC_RGB16_TO_32
120 : #define PIXEL rgb32_pixel_t
121 : #define FNAME(name) quic_rgb16_to_32_##name
122 : #define BPC 5
123 : #undef COMPRESS_IMP
124 : #define SET_r(pix, val) ((pix)->r = ((val) << 3) | (((val) & 0x1f) >> 2))
125 : #define GET_r(pix) ((pix)->r >> 3)
126 : #define SET_g(pix, val) ((pix)->g = ((val) << 3) | (((val) & 0x1f) >> 2))
127 : #define GET_g(pix) ((pix)->g >> 3)
128 : #define SET_b(pix, val) ((pix)->b = ((val) << 3) | (((val) & 0x1f) >> 2))
129 : #define GET_b(pix) ((pix)->b >> 3)
130 : #define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
131 : #endif
132 :
133 : #define FNAME_DECL(name) FNAME(name) FARGS_DECL
134 : #define FNAME_CALL(name) FNAME(name) FARGS_CALL
135 :
136 : #if BPC == 5
137 : # define golomb_coding golomb_coding_5bpc
138 : # define golomb_decoding golomb_decoding_5bpc
139 : # define update_model update_model_5bpc
140 : # define find_bucket find_bucket_5bpc
141 : # define family family_5bpc
142 : # define BPC_MASK 0x1fU
143 : #elif BPC == 8
144 : # define golomb_coding golomb_coding_8bpc
145 : # define golomb_decoding golomb_decoding_8bpc
146 : # define update_model update_model_8bpc
147 : # define find_bucket find_bucket_8bpc
148 : # define family family_8bpc
149 : # define BPC_MASK 0xffU
150 : #else
151 : # error BPC must be 5 or 8
152 : #endif
153 :
154 : #define _PIXEL_A(channel, curr) ((unsigned int)GET_##channel((curr) - 1))
155 : #define _PIXEL_B(channel, prev) ((unsigned int)GET_##channel(prev))
156 :
157 : /* a */
158 :
159 : #define DECORRELATE_0(channel, curr, bpc_mask)\
160 : family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)_PIXEL_A(channel, curr)) & bpc_mask]
161 :
162 : #define CORRELATE_0(channel, curr, correlate, bpc_mask)\
163 : ((family.xlatL2U[correlate] + _PIXEL_A(channel, curr)) & bpc_mask)
164 :
165 :
166 : /* (a+b)/2 */
167 : #define DECORRELATE(channel, prev, curr, bpc_mask, r) \
168 : r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)((_PIXEL_A(channel, curr) + \
169 : _PIXEL_B(channel, prev)) >> 1)) & bpc_mask]
170 :
171 : #define CORRELATE(channel, prev, curr, correlate, bpc_mask, r) \
172 : SET_##channel(r, ((family.xlatL2U[correlate] + \
173 : (int)((_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev)) >> 1)) & bpc_mask))
174 :
175 :
176 : #define COMPRESS_ONE_ROW0_0(channel) \
177 : correlate_row_##channel[0] = family.xlatU2L[GET_##channel(cur_row)];\
178 : golomb_coding(encoder, correlate_row_##channel[0], \
179 : find_bucket(channel_##channel, \
180 : correlate_row_##channel[-1])->bestcode)
181 :
182 : #define COMPRESS_ONE_ROW0(channel, index) \
183 : correlate_row_##channel[index] = DECORRELATE_0(channel, &cur_row[index], bpc_mask); \
184 : golomb_coding(encoder, correlate_row_##channel[index], \
185 : find_bucket(channel_##channel, \
186 : correlate_row_##channel[index - 1])->bestcode)
187 :
188 : #define UPDATE_MODEL_COMP(channel, index) \
189 : update_model(state, find_bucket(channel_##channel, correlate_row_##channel[index - 1]), \
190 : correlate_row_##channel[index])
191 : #define UPDATE_MODEL(index) APPLY_ALL_COMP(UPDATE_MODEL_COMP, index)
192 :
193 : #define RLE_PRED_IMP \
194 : if (SAME_PIXEL(&prev_row[i - 1], &prev_row[i])) { \
195 : if (run_index != i && i > 2 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2])) { \
196 : goto do_run; \
197 : } \
198 : }
199 :
200 : #ifdef COMPRESS_IMP
201 :
202 10 : static void FNAME_DECL(compress_row0_seg)(int i,
203 : const PIXEL * const cur_row,
204 : const int end,
205 : const unsigned int waitmask,
206 : const unsigned int bpc_mask)
207 : {
208 10 : DECLARE_STATE_VARIABLES;
209 10 : DECLARE_CHANNEL_VARIABLES;
210 : int stopidx;
211 :
212 10 : spice_assert(end - i > 0);
213 :
214 10 : if (i == 0) {
215 10 : APPLY_ALL_COMP(COMPRESS_ONE_ROW0_0);
216 :
217 10 : if (state->waitcnt) {
218 0 : state->waitcnt--;
219 : } else {
220 10 : state->waitcnt = (tabrand(&state->tabrand_seed) & waitmask);
221 10 : UPDATE_MODEL(0);
222 : }
223 10 : stopidx = ++i + state->waitcnt;
224 : } else {
225 0 : stopidx = i + state->waitcnt;
226 : }
227 :
228 7052 : while (stopidx < end) {
229 14084 : for (; i <= stopidx; i++) {
230 7042 : APPLY_ALL_COMP(COMPRESS_ONE_ROW0, i);
231 : }
232 :
233 7042 : UPDATE_MODEL(stopidx);
234 7042 : stopidx = i + (tabrand(&state->tabrand_seed) & waitmask);
235 : }
236 :
237 10 : for (; i < end; i++) {
238 0 : APPLY_ALL_COMP(COMPRESS_ONE_ROW0, i);
239 : }
240 10 : state->waitcnt = stopidx - end;
241 10 : }
242 :
243 : #undef COMPRESS_ONE_ROW0_0
244 : #undef COMPRESS_ONE_ROW0
245 :
246 10 : static void FNAME_DECL(compress_row0)(const PIXEL *cur_row, unsigned int width)
247 : {
248 10 : DECLARE_STATE_VARIABLES;
249 10 : const unsigned int bpc_mask = BPC_MASK;
250 10 : int pos = 0;
251 :
252 10 : while ((DEFwmimax > (int)state->wmidx) && (state->wmileft <= width)) {
253 0 : if (state->wmileft) {
254 0 : FNAME_CALL(compress_row0_seg)(pos, cur_row, pos + state->wmileft,
255 : bppmask[state->wmidx], bpc_mask);
256 0 : width -= state->wmileft;
257 0 : pos += state->wmileft;
258 : }
259 :
260 0 : state->wmidx++;
261 0 : set_wm_trigger(state);
262 0 : state->wmileft = DEFwminext;
263 : }
264 :
265 10 : if (width) {
266 10 : FNAME_CALL(compress_row0_seg)(pos, cur_row, pos + width,
267 : bppmask[state->wmidx], bpc_mask);
268 10 : if (DEFwmimax > (int)state->wmidx) {
269 10 : state->wmileft -= width;
270 : }
271 : }
272 :
273 10 : spice_assert((int)state->wmidx <= DEFwmimax);
274 10 : spice_assert(state->wmidx <= 32);
275 : spice_assert(DEFwminext > 0);
276 10 : }
277 :
278 : #define COMPRESS_ONE_0(channel) \
279 : correlate_row_##channel[0] = family.xlatU2L[(unsigned)((int)GET_##channel(cur_row) - \
280 : (int)GET_##channel(prev_row) ) & bpc_mask]; \
281 : golomb_coding(encoder, correlate_row_##channel[0], \
282 : find_bucket(channel_##channel, correlate_row_##channel[-1])->bestcode)
283 :
284 : #define COMPRESS_ONE(channel, index) \
285 : DECORRELATE(channel, &prev_row[index], &cur_row[index],bpc_mask, correlate_row_##channel[index]); \
286 : golomb_coding(encoder, correlate_row_##channel[index], \
287 : find_bucket(channel_##channel, correlate_row_##channel[index - 1])->bestcode)
288 :
289 2230 : static void FNAME_DECL(compress_row_seg)(int i,
290 : const PIXEL * const prev_row,
291 : const PIXEL * const cur_row,
292 : const int end,
293 : const unsigned int waitmask,
294 : const unsigned int bpc_mask)
295 : {
296 2230 : DECLARE_STATE_VARIABLES;
297 2230 : DECLARE_CHANNEL_VARIABLES;
298 : int stopidx;
299 2230 : int run_index = 0;
300 : int run_size;
301 :
302 2230 : spice_assert(end - i > 0);
303 :
304 2230 : if (i == 0) {
305 2170 : APPLY_ALL_COMP(COMPRESS_ONE_0);
306 :
307 2170 : if (state->waitcnt) {
308 2034 : state->waitcnt--;
309 : } else {
310 136 : state->waitcnt = (tabrand(&state->tabrand_seed) & waitmask);
311 136 : UPDATE_MODEL(0);
312 : }
313 2170 : stopidx = ++i + state->waitcnt;
314 : } else {
315 60 : stopidx = i + state->waitcnt;
316 : }
317 : for (;;) {
318 51567 : while (stopidx < end) {
319 997014 : for (; i <= stopidx; i++) {
320 947679 : RLE_PRED_IMP;
321 946521 : APPLY_ALL_COMP(COMPRESS_ONE, i);
322 : }
323 :
324 49335 : UPDATE_MODEL(stopidx);
325 49335 : stopidx = i + (tabrand(&state->tabrand_seed) & waitmask);
326 : }
327 :
328 20243 : for (; i < end; i++) {
329 19169 : RLE_PRED_IMP;
330 19169 : APPLY_ALL_COMP(COMPRESS_ONE, i);
331 : }
332 1074 : state->waitcnt = stopidx - end;
333 :
334 1074 : return;
335 :
336 1158 : do_run:
337 1158 : run_index = i;
338 1158 : state->waitcnt = stopidx - i;
339 1158 : run_size = 0;
340 :
341 823340 : while (SAME_PIXEL(&cur_row[i], &cur_row[i - 1])) {
342 823338 : run_size++;
343 823338 : if (++i == end) {
344 1156 : encode_state_run(encoder, state, run_size);
345 1156 : return;
346 : }
347 : }
348 2 : encode_state_run(encoder, state, run_size);
349 2 : stopidx = i + state->waitcnt;
350 : }
351 : }
352 :
353 2170 : static void FNAME_DECL(compress_row)(const PIXEL * const prev_row,
354 : const PIXEL * const cur_row,
355 : unsigned int width)
356 :
357 : {
358 2170 : DECLARE_STATE_VARIABLES;
359 2170 : const unsigned int bpc_mask = BPC_MASK;
360 2170 : unsigned int pos = 0;
361 :
362 2230 : while ((DEFwmimax > (int)state->wmidx) && (state->wmileft <= width)) {
363 60 : if (state->wmileft) {
364 60 : FNAME_CALL(compress_row_seg)(pos, prev_row, cur_row,
365 : pos + state->wmileft, bppmask[state->wmidx],
366 : bpc_mask);
367 60 : width -= state->wmileft;
368 60 : pos += state->wmileft;
369 : }
370 :
371 60 : state->wmidx++;
372 60 : set_wm_trigger(state);
373 60 : state->wmileft = DEFwminext;
374 : }
375 :
376 2170 : if (width) {
377 2170 : FNAME_CALL(compress_row_seg)(pos, prev_row, cur_row, pos + width,
378 : bppmask[state->wmidx], bpc_mask);
379 2170 : if (DEFwmimax > (int)state->wmidx) {
380 209 : state->wmileft -= width;
381 : }
382 : }
383 :
384 2170 : spice_assert((int)state->wmidx <= DEFwmimax);
385 2170 : spice_assert(state->wmidx <= 32);
386 : spice_assert(DEFwminext > 0);
387 2170 : }
388 :
389 : #endif
390 :
391 : #define UNCOMPRESS_ONE_ROW0_0(channel) \
392 : correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
393 : correlate_row_##channel[-1])->bestcode, \
394 : encoder->io_word, &codewordlen); \
395 : SET_##channel(&cur_row[0], (BYTE)family.xlatL2U[correlate_row_##channel[0]]); \
396 : decode_eatbits(encoder, codewordlen);
397 :
398 : #define UNCOMPRESS_ONE_ROW0(channel) \
399 : correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
400 : correlate_row_##channel[i - 1])->bestcode, \
401 : encoder->io_word, &codewordlen); \
402 : SET_##channel(&cur_row[i], CORRELATE_0(channel, &cur_row[i], correlate_row_##channel[i], \
403 : bpc_mask)); \
404 : decode_eatbits(encoder, codewordlen);
405 :
406 10 : static void FNAME_DECL(uncompress_row0_seg)(int i,
407 : PIXEL * const cur_row,
408 : const int end,
409 : const unsigned int waitmask,
410 : const unsigned int bpc_mask)
411 : {
412 10 : DECLARE_STATE_VARIABLES;
413 10 : DECLARE_CHANNEL_VARIABLES;
414 : int stopidx;
415 :
416 10 : spice_assert(end - i > 0);
417 :
418 10 : if (i == 0) {
419 : unsigned int codewordlen;
420 :
421 4 : UNCOMPRESS_PIX_START(&cur_row[i]);
422 10 : APPLY_ALL_COMP(UNCOMPRESS_ONE_ROW0_0);
423 :
424 10 : if (state->waitcnt) {
425 0 : --state->waitcnt;
426 : } else {
427 10 : state->waitcnt = (tabrand(&state->tabrand_seed) & waitmask);
428 10 : UPDATE_MODEL(0);
429 : }
430 10 : stopidx = ++i + state->waitcnt;
431 : } else {
432 0 : stopidx = i + state->waitcnt;
433 : }
434 :
435 7052 : while (stopidx < end) {
436 14084 : for (; i <= stopidx; i++) {
437 : unsigned int codewordlen;
438 :
439 2171 : UNCOMPRESS_PIX_START(&cur_row[i]);
440 7042 : APPLY_ALL_COMP(UNCOMPRESS_ONE_ROW0);
441 : }
442 7042 : UPDATE_MODEL(stopidx);
443 7042 : stopidx = i + (tabrand(&state->tabrand_seed) & waitmask);
444 : }
445 :
446 10 : for (; i < end; i++) {
447 : unsigned int codewordlen;
448 :
449 0 : UNCOMPRESS_PIX_START(&cur_row[i]);
450 0 : APPLY_ALL_COMP(UNCOMPRESS_ONE_ROW0);
451 : }
452 10 : state->waitcnt = stopidx - end;
453 10 : }
454 :
455 10 : static void FNAME_DECL(uncompress_row0)(PIXEL * const cur_row,
456 : unsigned int width)
457 :
458 : {
459 10 : DECLARE_STATE_VARIABLES;
460 10 : const unsigned int bpc_mask = BPC_MASK;
461 10 : unsigned int pos = 0;
462 :
463 10 : while ((DEFwmimax > (int)state->wmidx) && (state->wmileft <= width)) {
464 0 : if (state->wmileft) {
465 0 : FNAME_CALL(uncompress_row0_seg)(pos, cur_row,
466 : pos + state->wmileft,
467 : bppmask[state->wmidx],
468 : bpc_mask);
469 0 : pos += state->wmileft;
470 0 : width -= state->wmileft;
471 : }
472 :
473 0 : state->wmidx++;
474 0 : set_wm_trigger(state);
475 0 : state->wmileft = DEFwminext;
476 : }
477 :
478 10 : if (width) {
479 10 : FNAME_CALL(uncompress_row0_seg)(pos, cur_row, pos + width,
480 : bppmask[state->wmidx], bpc_mask);
481 10 : if (DEFwmimax > (int)state->wmidx) {
482 10 : state->wmileft -= width;
483 : }
484 : }
485 :
486 10 : spice_assert((int)state->wmidx <= DEFwmimax);
487 10 : spice_assert(state->wmidx <= 32);
488 : spice_assert(DEFwminext > 0);
489 10 : }
490 :
491 : #define UNCOMPRESS_ONE_0(channel) \
492 : correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
493 : correlate_row_##channel[-1])->bestcode, \
494 : encoder->io_word, &codewordlen); \
495 : SET_##channel(&cur_row[0], (family.xlatL2U[correlate_row_##channel[0]] + \
496 : GET_##channel(prev_row)) & bpc_mask); \
497 : decode_eatbits(encoder, codewordlen);
498 :
499 : #define UNCOMPRESS_ONE(channel) \
500 : correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
501 : correlate_row_##channel[i - 1])->bestcode, \
502 : encoder->io_word, &codewordlen); \
503 : CORRELATE(channel, &prev_row[i], &cur_row[i], correlate_row_##channel[i], bpc_mask, \
504 : &cur_row[i]); \
505 : decode_eatbits(encoder, codewordlen);
506 :
507 2230 : static void FNAME_DECL(uncompress_row_seg)(const PIXEL * const prev_row,
508 : PIXEL * const cur_row,
509 : int i,
510 : const int end,
511 : const unsigned int bpc_mask)
512 : {
513 2230 : DECLARE_STATE_VARIABLES;
514 2230 : DECLARE_CHANNEL_VARIABLES;
515 2230 : const unsigned int waitmask = bppmask[state->wmidx];
516 : int stopidx;
517 2230 : int run_index = 0;
518 : int run_end;
519 :
520 2230 : spice_assert(end - i > 0);
521 :
522 2230 : if (i == 0) {
523 : unsigned int codewordlen;
524 :
525 667 : UNCOMPRESS_PIX_START(&cur_row[i]);
526 2170 : APPLY_ALL_COMP(UNCOMPRESS_ONE_0);
527 :
528 2170 : if (state->waitcnt) {
529 2034 : --state->waitcnt;
530 : } else {
531 136 : state->waitcnt = (tabrand(&state->tabrand_seed) & waitmask);
532 136 : UPDATE_MODEL(0);
533 : }
534 2170 : stopidx = ++i + state->waitcnt;
535 : } else {
536 60 : stopidx = i + state->waitcnt;
537 : }
538 : for (;;) {
539 51567 : while (stopidx < end) {
540 997014 : for (; i <= stopidx; i++) {
541 : unsigned int codewordlen;
542 947679 : RLE_PRED_IMP;
543 132179 : UNCOMPRESS_PIX_START(&cur_row[i]);
544 946521 : APPLY_ALL_COMP(UNCOMPRESS_ONE);
545 : }
546 :
547 49335 : UPDATE_MODEL(stopidx);
548 :
549 49335 : stopidx = i + (tabrand(&state->tabrand_seed) & waitmask);
550 : }
551 :
552 20243 : for (; i < end; i++) {
553 : unsigned int codewordlen;
554 19169 : RLE_PRED_IMP;
555 4605 : UNCOMPRESS_PIX_START(&cur_row[i]);
556 19169 : APPLY_ALL_COMP(UNCOMPRESS_ONE);
557 : }
558 :
559 1074 : state->waitcnt = stopidx - end;
560 :
561 1074 : return;
562 :
563 1158 : do_run:
564 1158 : state->waitcnt = stopidx - i;
565 1158 : run_index = i;
566 1158 : run_end = decode_state_run(encoder, state);
567 1158 : if (run_end < 0 || run_end > (end - i)) {
568 0 : encoder->usr->error(encoder->usr, "wrong RLE\n");
569 : }
570 1158 : run_end += i;
571 :
572 824496 : for (; i < run_end; i++) {
573 212376 : UNCOMPRESS_PIX_START(&cur_row[i]);
574 823338 : COPY_PIXEL(&cur_row[i], &cur_row[i - 1]);
575 : }
576 :
577 1158 : if (i == end) {
578 1156 : return;
579 : }
580 :
581 2 : stopidx = i + state->waitcnt;
582 : }
583 : }
584 :
585 2170 : static void FNAME_DECL(uncompress_row)(const PIXEL * const prev_row,
586 : PIXEL * const cur_row,
587 : unsigned int width)
588 :
589 : {
590 2170 : DECLARE_STATE_VARIABLES;
591 2170 : const unsigned int bpc_mask = BPC_MASK;
592 2170 : unsigned int pos = 0;
593 :
594 2230 : while ((DEFwmimax > (int)state->wmidx) && (state->wmileft <= width)) {
595 60 : if (state->wmileft) {
596 60 : FNAME_CALL(uncompress_row_seg)(prev_row, cur_row, pos,
597 : pos + state->wmileft, bpc_mask);
598 60 : pos += state->wmileft;
599 60 : width -= state->wmileft;
600 : }
601 :
602 60 : state->wmidx++;
603 60 : set_wm_trigger(state);
604 60 : state->wmileft = DEFwminext;
605 : }
606 :
607 2170 : if (width) {
608 2170 : FNAME_CALL(uncompress_row_seg)(prev_row, cur_row, pos,
609 : pos + width, bpc_mask);
610 2170 : if (DEFwmimax > (int)state->wmidx) {
611 209 : state->wmileft -= width;
612 : }
613 : }
614 :
615 2170 : spice_assert((int)state->wmidx <= DEFwmimax);
616 2170 : spice_assert(state->wmidx <= 32);
617 : spice_assert(DEFwminext > 0);
618 2170 : }
619 :
620 : #undef PIXEL
621 : #undef FARGS_CALL
622 : #undef FARGS_DECL
623 : #undef FNAME
624 : #undef FNAME_CALL
625 : #undef FNAME_DECL
626 : #undef _PIXEL_A
627 : #undef _PIXEL_B
628 : #undef SAME_PIXEL
629 : #undef RLE_PRED_IMP
630 : #undef UPDATE_MODEL
631 : #undef DECORRELATE_0
632 : #undef DECORRELATE
633 : #undef COMPRESS_ONE_0
634 : #undef COMPRESS_ONE
635 : #undef CORRELATE_0
636 : #undef CORRELATE
637 : #undef UNCOMPRESS_ONE_ROW0_0
638 : #undef UNCOMPRESS_ONE_ROW0
639 : #undef UNCOMPRESS_ONE_0
640 : #undef UNCOMPRESS_ONE
641 : #undef golomb_coding
642 : #undef golomb_decoding
643 : #undef update_model
644 : #undef find_bucket
645 : #undef family
646 : #undef BPC
647 : #undef BPC_MASK
648 : #undef COMPRESS_IMP
649 : #undef SET_r
650 : #undef GET_r
651 : #undef SET_g
652 : #undef GET_g
653 : #undef SET_b
654 : #undef GET_b
655 : #undef SET_a
656 : #undef GET_a
657 : #undef UNCOMPRESS_PIX_START
658 : #undef UPDATE_MODEL_COMP
659 : #undef APPLY_ALL_COMP
660 : #undef DECLARE_STATE_VARIABLES
661 : #undef DECLARE_CHANNEL_VARIABLES
662 : #undef COPY_PIXEL
|