1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#ifndef VNC_ENC_ZYWRLE_H
45#define VNC_ENC_ZYWRLE_H
46
47
48#ifndef ZYWRLE_QUANTIZE
49
50static const unsigned int zywrle_param[3][3]={
51 {0x0000F000, 0x00000000, 0x00000000},
52 {0x0000C000, 0x00F0F0F0, 0x00000000},
53 {0x0000C000, 0x00C0C0C0, 0x00F0F0F0},
54
55
56
57};
58#else
59
60static const int8_t zywrle_conv[4][256]={
61{
62 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0,
94},
95{
96 0, 0, 0, 0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 32,
99 32, 32, 32, 32, 32, 32, 32, 32,
100 32, 32, 32, 32, 32, 32, 32, 32,
101 48, 48, 48, 48, 48, 48, 48, 48,
102 48, 48, 48, 56, 56, 56, 56, 56,
103 56, 56, 56, 56, 64, 64, 64, 64,
104 64, 64, 64, 64, 72, 72, 72, 72,
105 72, 72, 72, 72, 80, 80, 80, 80,
106 80, 80, 88, 88, 88, 88, 88, 88,
107 88, 88, 88, 88, 88, 88, 96, 96,
108 96, 96, 96, 104, 104, 104, 104, 104,
109 104, 104, 104, 104, 104, 112, 112, 112,
110 112, 112, 112, 112, 112, 112, 120, 120,
111 120, 120, 120, 120, 120, 120, 120, 120,
112 0, -120, -120, -120, -120, -120, -120, -120,
113 -120, -120, -120, -112, -112, -112, -112, -112,
114 -112, -112, -112, -112, -104, -104, -104, -104,
115 -104, -104, -104, -104, -104, -104, -96, -96,
116 -96, -96, -96, -88, -88, -88, -88, -88,
117 -88, -88, -88, -88, -88, -88, -88, -80,
118 -80, -80, -80, -80, -80, -72, -72, -72,
119 -72, -72, -72, -72, -72, -64, -64, -64,
120 -64, -64, -64, -64, -64, -56, -56, -56,
121 -56, -56, -56, -56, -56, -56, -48, -48,
122 -48, -48, -48, -48, -48, -48, -48, -48,
123 -48, -32, -32, -32, -32, -32, -32, -32,
124 -32, -32, -32, -32, -32, -32, -32, -32,
125 -32, -32, 0, 0, 0, 0, 0, 0,
126 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128},
129{
130 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0,
134 48, 48, 48, 48, 48, 48, 48, 48,
135 48, 48, 48, 48, 48, 48, 48, 48,
136 48, 48, 48, 48, 48, 48, 48, 48,
137 64, 64, 64, 64, 64, 64, 64, 64,
138 64, 64, 64, 64, 64, 64, 64, 64,
139 80, 80, 80, 80, 80, 80, 80, 80,
140 80, 80, 80, 80, 80, 88, 88, 88,
141 88, 88, 88, 88, 88, 88, 88, 88,
142 104, 104, 104, 104, 104, 104, 104, 104,
143 104, 104, 104, 112, 112, 112, 112, 112,
144 112, 112, 112, 112, 120, 120, 120, 120,
145 120, 120, 120, 120, 120, 120, 120, 120,
146 0, -120, -120, -120, -120, -120, -120, -120,
147 -120, -120, -120, -120, -120, -112, -112, -112,
148 -112, -112, -112, -112, -112, -112, -104, -104,
149 -104, -104, -104, -104, -104, -104, -104, -104,
150 -104, -88, -88, -88, -88, -88, -88, -88,
151 -88, -88, -88, -88, -80, -80, -80, -80,
152 -80, -80, -80, -80, -80, -80, -80, -80,
153 -80, -64, -64, -64, -64, -64, -64, -64,
154 -64, -64, -64, -64, -64, -64, -64, -64,
155 -64, -48, -48, -48, -48, -48, -48, -48,
156 -48, -48, -48, -48, -48, -48, -48, -48,
157 -48, -48, -48, -48, -48, -48, -48, -48,
158 -48, 0, 0, 0, 0, 0, 0, 0,
159 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0,
161 0, 0, 0, 0, 0, 0, 0, 0,
162},
163{
164 0, 0, 0, 0, 0, 0, 0, 0,
165 0, 0, 0, 0, 0, 0, 0, 0,
166 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0,
169 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0, 0, 0, 0,
172 88, 88, 88, 88, 88, 88, 88, 88,
173 88, 88, 88, 88, 88, 88, 88, 88,
174 88, 88, 88, 88, 88, 88, 88, 88,
175 88, 88, 88, 88, 88, 88, 88, 88,
176 88, 88, 88, 88, 88, 88, 88, 88,
177 88, 88, 88, 88, 88, 88, 88, 88,
178 88, 88, 88, 88, 88, 88, 88, 88,
179 88, 88, 88, 88, 88, 88, 88, 88,
180 0, -88, -88, -88, -88, -88, -88, -88,
181 -88, -88, -88, -88, -88, -88, -88, -88,
182 -88, -88, -88, -88, -88, -88, -88, -88,
183 -88, -88, -88, -88, -88, -88, -88, -88,
184 -88, -88, -88, -88, -88, -88, -88, -88,
185 -88, -88, -88, -88, -88, -88, -88, -88,
186 -88, -88, -88, -88, -88, -88, -88, -88,
187 -88, -88, -88, -88, -88, -88, -88, -88,
188 -88, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, 0, 0, 0,
191 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0,
193 0, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0,
196}
197};
198
199static const int8_t *zywrle_param[3][3][3]={
200 {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]},
201 {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]},
202 {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
203 {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
204 {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]},
205 {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
206 {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
207 {zywrle_conv[2], zywrle_conv[2], zywrle_conv[2]},
208 {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}},
209};
210#endif
211
212
213#define ZYWRLE_YMASK15 0xFFFFFFF8
214#define ZYWRLE_UVMASK15 0xFFFFFFF8
215#define ZYWRLE_LOAD_PIXEL15(src, r, g, b) \
216 do { \
217 r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \
218 g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \
219 g &= 0xF8; \
220 b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \
221 } while (0)
222
223#define ZYWRLE_SAVE_PIXEL15(dst, r, g, b) \
224 do { \
225 r &= 0xF8; \
226 g &= 0xF8; \
227 b &= 0xF8; \
228 ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6)); \
229 ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF); \
230 } while (0)
231
232#define ZYWRLE_YMASK16 0xFFFFFFFC
233#define ZYWRLE_UVMASK16 0xFFFFFFF8
234#define ZYWRLE_LOAD_PIXEL16(src, r, g, b) \
235 do { \
236 r = ((uint8_t*)src)[S_1] & 0xF8; \
237 g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \
238 g &= 0xFC; \
239 b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \
240 } while (0)
241
242#define ZYWRLE_SAVE_PIXEL16(dst, r, g,b) \
243 do { \
244 r &= 0xF8; \
245 g &= 0xFC; \
246 b &= 0xF8; \
247 ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \
248 ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \
249 } while (0)
250
251#define ZYWRLE_YMASK32 0xFFFFFFFF
252#define ZYWRLE_UVMASK32 0xFFFFFFFF
253#define ZYWRLE_LOAD_PIXEL32(src, r, g, b) \
254 do { \
255 r = ((uint8_t*)src)[L_2]; \
256 g = ((uint8_t*)src)[L_1]; \
257 b = ((uint8_t*)src)[L_0]; \
258 } while (0)
259#define ZYWRLE_SAVE_PIXEL32(dst, r, g, b) \
260 do { \
261 ((uint8_t*)dst)[L_2] = (uint8_t)r; \
262 ((uint8_t*)dst)[L_1] = (uint8_t)g; \
263 ((uint8_t*)dst)[L_0] = (uint8_t)b; \
264 } while (0)
265
266static inline void harr(int8_t *px0, int8_t *px1)
267{
268
269 int x0 = (int)*px0, x1 = (int)*px1;
270 int orgx0 = x0, orgx1 = x1;
271
272 if ((x0 ^ x1) & 0x80) {
273
274 x1 += x0;
275 if (((x1 ^ orgx1) & 0x80) == 0) {
276
277 x0 -= x1;
278 }
279 } else {
280
281 x0 -= x1;
282 if (((x0 ^ orgx0) & 0x80) == 0) {
283
284 x1 += x0;
285 }
286 }
287 *px0 = (int8_t)x1;
288 *px1 = (int8_t)x0;
289}
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312static inline void wavelet_level(int *data, int size, int l, int skip_pixel)
313{
314 int s, ofs;
315 int8_t *px0;
316 int8_t *end;
317
318 px0 = (int8_t*)data;
319 s = (8 << l) * skip_pixel;
320 end = px0 + (size >> (l + 1)) * s;
321 s -= 2;
322 ofs = (4 << l) * skip_pixel;
323
324 while (px0 < end) {
325 harr(px0, px0 + ofs);
326 px0++;
327 harr(px0, px0 + ofs);
328 px0++;
329 harr(px0, px0 + ofs);
330 px0 += s;
331 }
332}
333
334#ifndef ZYWRLE_QUANTIZE
335
336static inline void filter_wavelet_square(int *buf, int width, int height,
337 int level, int l)
338{
339 int r, s;
340 int x, y;
341 int *h;
342 const unsigned int *m;
343
344 m = &(zywrle_param[level - 1][l]);
345 s = 2 << l;
346
347 for (r = 1; r < 4; r++) {
348 h = buf;
349 if (r & 0x01) {
350 h += s >> 1;
351 }
352 if (r & 0x02) {
353 h += (s >> 1) * width;
354 }
355 for (y = 0; y < height / s; y++) {
356 for (x = 0; x < width / s; x++) {
357
358
359
360
361
362
363
364 if (((int8_t*)h)[0] & 0x80) {
365 ((int8_t*)h)[0] += ~((int8_t*)m)[0];
366 }
367 if (((int8_t*)h)[1] & 0x80) {
368 ((int8_t*)h)[1] += ~((int8_t*)m)[1];
369 }
370 if (((int8_t*)h)[2] & 0x80) {
371 ((int8_t*)h)[2] += ~((int8_t*)m)[2];
372 }
373 *h &= *m;
374 h += s;
375 }
376 h += (s-1)*width;
377 }
378 }
379}
380#else
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412static inline void filter_wavelet_square(int *buf, int width, int height,
413 int level, int l)
414{
415 int r, s;
416 int x, y;
417 int *h;
418 const int8_t **m;
419
420 m = zywrle_param[level - 1][l];
421 s = 2 << l;
422
423 for (r = 1; r < 4; r++) {
424 h = buf;
425 if (r & 0x01) {
426 h += s >> 1;
427 }
428 if (r & 0x02) {
429 h += (s >> 1) * width;
430 }
431 for (y = 0; y < height / s; y++) {
432 for (x = 0; x < width / s; x++) {
433 ((int8_t*)h)[0] = m[0][((uint8_t*)h)[0]];
434 ((int8_t*)h)[1] = m[1][((uint8_t*)h)[1]];
435 ((int8_t*)h)[2] = m[2][((uint8_t*)h)[2]];
436 h += s;
437 }
438 h += (s - 1) * width;
439 }
440 }
441}
442#endif
443
444static inline void wavelet(int *buf, int width, int height, int level)
445{
446 int l, s;
447 int *top;
448 int *end;
449
450 for (l = 0; l < level; l++) {
451 top = buf;
452 end = buf + height * width;
453 s = width << l;
454 while (top < end) {
455 wavelet_level(top, width, l, 1);
456 top += s;
457 }
458 top = buf;
459 end = buf + width;
460 s = 1<<l;
461 while (top < end) {
462 wavelet_level(top, height, l, width);
463 top += s;
464 }
465 filter_wavelet_square(buf, width, height, level, l);
466 }
467}
468
469
470
471
472#define ZYWRLE_LOAD_COEFF(src, r, g, b) \
473 do { \
474 r = ((int8_t*)src)[2]; \
475 g = ((int8_t*)src)[1]; \
476 b = ((int8_t*)src)[0]; \
477 } while (0)
478
479#define ZYWRLE_SAVE_COEFF(dst, r, g, b) \
480 do { \
481 ((int8_t*)dst)[2] = (int8_t)r; \
482 ((int8_t*)dst)[1] = (int8_t)g; \
483 ((int8_t*)dst)[0] = (int8_t)b; \
484 } while (0)
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503#define ZYWRLE_RGBYUV_(r, g, b, y, u, v, ymask, uvmask) \
504 do { \
505 y = (r + (g << 1) + b) >> 2; \
506 u = b - g; \
507 v = r - g; \
508 y -= 128; \
509 u >>= 1; \
510 v >>= 1; \
511 y &= ymask; \
512 u &= uvmask; \
513 v &= uvmask; \
514 if (y == -128) { \
515 y += (0xFFFFFFFF - ymask + 1); \
516 } \
517 if (u == -128) { \
518 u += (0xFFFFFFFF - uvmask + 1); \
519 } \
520 if (v == -128) { \
521 v += (0xFFFFFFFF - uvmask + 1); \
522 } \
523 } while (0)
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557#define ZYWRLE_INC_PTR(data) \
558 do { \
559 data++; \
560 if( data - p >= (w + uw) ) { \
561 data += scanline-(w + uw); \
562 p = data; \
563 } \
564 } while (0)
565
566#define ZYWRLE_TRANSFER_COEFF(buf, data, t, w, h, scanline, level, TRANS) \
567 do { \
568 ph = buf; \
569 s = 2 << level; \
570 if (t & 0x01) { \
571 ph += s >> 1; \
572 } \
573 if (t & 0x02) { \
574 ph += (s >> 1) * w; \
575 } \
576 end = ph + h * w; \
577 while (ph < end) { \
578 line = ph + w; \
579 while (ph < line) { \
580 TRANS \
581 ZYWRLE_INC_PTR(data); \
582 ph += s; \
583 } \
584 ph += (s - 1) * w; \
585 } \
586 } while (0)
587
588#define ZYWRLE_PACK_COEFF(buf, data, t, width, height, scanline, level) \
589 ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
590 ZYWRLE_LOAD_COEFF(ph, r, g, b); \
591 ZYWRLE_SAVE_PIXEL(data, r, g, b);)
592
593#define ZYWRLE_UNPACK_COEFF(buf, data, t, width, height, scanline, level) \
594 ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
595 ZYWRLE_LOAD_PIXEL(data, r, g, b); \
596 ZYWRLE_SAVE_COEFF(ph, r, g, b);)
597
598#define ZYWRLE_SAVE_UNALIGN(data, TRANS) \
599 do { \
600 top = buf + w * h; \
601 end = buf + (w + uw) * (h + uh); \
602 while (top < end) { \
603 TRANS \
604 ZYWRLE_INC_PTR(data); \
605 top++; \
606 } \
607 } while (0)
608
609#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
610 do { \
611 top = buf + w * h; \
612 if (uw) { \
613 p = data + w; \
614 end = (int*)(p + h * scanline); \
615 while (p < (ZRLE_PIXEL*)end) { \
616 line = (int*)(p + uw); \
617 while (p < (ZRLE_PIXEL*)line) { \
618 TRANS \
619 p++; \
620 top++; \
621 } \
622 p += scanline - uw; \
623 } \
624 } \
625 if (uh) { \
626 p = data + h * scanline; \
627 end = (int*)(p + uh * scanline); \
628 while (p < (ZRLE_PIXEL*)end) { \
629 line = (int*)(p + w); \
630 while (p < (ZRLE_PIXEL*)line) { \
631 TRANS \
632 p++; \
633 top++; \
634 } \
635 p += scanline - w; \
636 } \
637 } \
638 if (uw && uh) { \
639 p= data + w + h * scanline; \
640 end = (int*)(p + uh * scanline); \
641 while (p < (ZRLE_PIXEL*)end) { \
642 line = (int*)(p + uw); \
643 while (p < (ZRLE_PIXEL*)line) { \
644 TRANS \
645 p++; \
646 top++; \
647 } \
648 p += scanline-uw; \
649 } \
650 } \
651 } while (0)
652
653static inline void zywrle_calc_size(int *w, int *h, int level)
654{
655 *w &= ~((1 << level) - 1);
656 *h &= ~((1 << level) - 1);
657}
658
659#endif
660