1 /********************************************************************
3 * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
7 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9 * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
10 * BY Hitachi Systems & Services, Ltd. *
11 * (Noriaki Yamazaki, Research & Development Center) *
14 ********************************************************************
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions
19 - Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
22 - Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
26 - Neither the name of the Hitachi Systems & Services, Ltd. nor
27 the names of its contributors may be used to endorse or promote
28 products derived from this software without specific prior written
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
35 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ********************************************************************/
44 #ifndef VNC_ENC_ZYWRLE_H
45 #define VNC_ENC_ZYWRLE_H
47 /* Tables for Coefficients filtering. */
48 #ifndef ZYWRLE_QUANTIZE
49 /* Type A:lower bit omitting of EZW style. */
50 static const unsigned int zywrle_param
[3][3]={
51 {0x0000F000, 0x00000000, 0x00000000},
52 {0x0000C000, 0x00F0F0F0, 0x00000000},
53 {0x0000C000, 0x00C0C0C0, 0x00F0F0F0},
54 /* {0x0000FF00, 0x00000000, 0x00000000},
55 {0x0000FF00, 0x00FFFFFF, 0x00000000},
56 {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */
59 /* Type B:Non liner quantization filter. */
60 static const int8_t zywrle_conv
[4][256]={
61 { /* bi=5, bo=5 r=0.0:PSNR=24.849 */
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,
95 { /* bi=5, bo=5 r=2.0:PSNR=74.031 */
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,
129 { /* bi=5, bo=4 r=2.0:PSNR=64.441 */
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,
163 { /* bi=5, bo=2 r=2.0:PSNR=43.175 */
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,
199 static 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]}},
212 /* Load/Save pixel stuffs. */
213 #define ZYWRLE_YMASK15 0xFFFFFFF8
214 #define ZYWRLE_UVMASK15 0xFFFFFFF8
215 #define ZYWRLE_LOAD_PIXEL15(src, r, g, b) \
217 r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \
218 g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \
220 b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \
223 #define ZYWRLE_SAVE_PIXEL15(dst, r, g, b) \
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); \
232 #define ZYWRLE_YMASK16 0xFFFFFFFC
233 #define ZYWRLE_UVMASK16 0xFFFFFFF8
234 #define ZYWRLE_LOAD_PIXEL16(src, r, g, b) \
236 r = ((uint8_t*)src)[S_1] & 0xF8; \
237 g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \
239 b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \
242 #define ZYWRLE_SAVE_PIXEL16(dst, r, g,b) \
247 ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \
248 ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \
251 #define ZYWRLE_YMASK32 0xFFFFFFFF
252 #define ZYWRLE_UVMASK32 0xFFFFFFFF
253 #define ZYWRLE_LOAD_PIXEL32(src, r, g, b) \
255 r = ((uint8_t*)src)[L_2]; \
256 g = ((uint8_t*)src)[L_1]; \
257 b = ((uint8_t*)src)[L_0]; \
259 #define ZYWRLE_SAVE_PIXEL32(dst, r, g, b) \
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; \
266 static inline void harr(int8_t *px0
, int8_t *px1
)
268 /* Piecewise-Linear Harr(PLHarr) */
269 int x0
= (int)*px0
, x1
= (int)*px1
;
270 int orgx0
= x0
, orgx1
= x1
;
272 if ((x0
^ x1
) & 0x80) {
275 if (((x1
^ orgx1
) & 0x80) == 0) {
277 x0
-= x1
; /* H = -B */
282 if (((x0
^ orgx0
) & 0x80) == 0) {
284 x1
+= x0
; /* L = A */
292 1D-Wavelet transform.
294 In coefficients array, the famous 'pyramid' decomposition is well used.
297 |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
298 |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
300 But this method needs line buffer because H/L is different position from X0/X1.
301 So, I used 'interleave' decomposition instead of it.
304 |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
305 |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
307 In this method, H/L and X0/X1 is always same position.
308 This leads us to more speed and less memory.
309 Of cause, the result of both method is quite same
310 because it's only difference that coefficient position.
312 static inline void wavelet_level(int *data
, int size
, int l
, int skip_pixel
)
319 s
= (8 << l
) * skip_pixel
;
320 end
= px0
+ (size
>> (l
+ 1)) * s
;
322 ofs
= (4 << l
) * skip_pixel
;
325 harr(px0
, px0
+ ofs
);
327 harr(px0
, px0
+ ofs
);
329 harr(px0
, px0
+ ofs
);
334 #ifndef ZYWRLE_QUANTIZE
335 /* Type A:lower bit omitting of EZW style. */
336 static inline void filter_wavelet_square(int *buf
, int width
, int height
,
342 const unsigned int *m
;
344 m
= &(zywrle_param
[level
- 1][l
]);
347 for (r
= 1; r
< 4; r
++) {
353 h
+= (s
>> 1) * width
;
355 for (y
= 0; y
< height
/ s
; y
++) {
356 for (x
= 0; x
< width
/ s
; x
++) {
358 these are same following code.
359 h[x] = h[x] / (~m[x]+1) * (~m[x]+1);
360 ( round h[x] with m[x] bit )
361 '&' operator isn't 'round' but is 'floor'.
362 So, we must offset when h[x] is negative.
364 if (((int8_t*)h
)[0] & 0x80) {
365 ((int8_t*)h
)[0] += ~((int8_t*)m
)[0];
367 if (((int8_t*)h
)[1] & 0x80) {
368 ((int8_t*)h
)[1] += ~((int8_t*)m
)[1];
370 if (((int8_t*)h
)[2] & 0x80) {
371 ((int8_t*)h
)[2] += ~((int8_t*)m
)[2];
382 Type B:Non liner quantization filter.
384 Coefficients have Gaussian curve and smaller value which is
385 large part of coefficients isn't more important than larger value.
386 So, I use filter of Non liner quantize/dequantize table.
387 In general, Non liner quantize formula is explained as following.
389 y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo)
390 x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
391 ( r:power coefficient bi:effective MSB in input bo:effective MSB in output )
393 r < 1.0 : Smaller value is more important than larger value.
394 r > 1.0 : Larger value is more important than smaller value.
395 r = 1.0 : Liner quantization which is same with EZW style.
397 r = 0.75 is famous non liner quantization used in MP3 audio codec.
398 In contrast to audio data, larger value is important in wavelet coefficients.
399 So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
401 As compared with EZW style liner quantization, this filter tended to be
402 more sharp edge and be more compression rate but be more blocking noise and be
403 less quality. Especially, the surface of graphic objects has distinguishable
404 noise in middle quality mode.
406 We need only quantized-dequantized(filtered) value rather than quantized value
407 itself because all values are packed or palette-lized in later ZRLE section.
408 This lead us not to need to modify client decoder when we change
409 the filtering procedure in future.
410 Client only decodes coefficients given by encoder.
412 static inline void filter_wavelet_square(int *buf
, int width
, int height
,
420 m
= zywrle_param
[level
- 1][l
];
423 for (r
= 1; r
< 4; r
++) {
429 h
+= (s
>> 1) * width
;
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]];
438 h
+= (s
- 1) * width
;
444 static inline void wavelet(int *buf
, int width
, int height
, int level
)
450 for (l
= 0; l
< level
; l
++) {
452 end
= buf
+ height
* width
;
455 wavelet_level(top
, width
, l
, 1);
462 wavelet_level(top
, height
, l
, width
);
465 filter_wavelet_square(buf
, width
, height
, level
, l
);
470 /* Load/Save coefficients stuffs.
471 Coefficients manages as 24 bits little-endian pixel. */
472 #define ZYWRLE_LOAD_COEFF(src, r, g, b) \
474 r = ((int8_t*)src)[2]; \
475 g = ((int8_t*)src)[1]; \
476 b = ((int8_t*)src)[0]; \
479 #define ZYWRLE_SAVE_COEFF(dst, r, g, b) \
481 ((int8_t*)dst)[2] = (int8_t)r; \
482 ((int8_t*)dst)[1] = (int8_t)g; \
483 ((int8_t*)dst)[0] = (int8_t)b; \
487 RGB <=> YUV conversion stuffs.
488 YUV coversion is explained as following formula in strict meaning:
489 Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255)
490 U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
491 V = 0.500R - 0.419G - 0.081B (-128<=V<=127)
493 I use simple conversion RCT(reversible color transform) which is described
494 in JPEG-2000 specification.
495 Y = (R + 2G + B)/4 ( 0<=Y<=255)
496 U = B-G (-256<=U<=255)
497 V = R-G (-256<=V<=255)
500 /* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
501 For make Same N-bit, UV is lossy.
502 More exact PLHarr, we reduce to odd range(-127<=x<=127). */
503 #define ZYWRLE_RGBYUV_(r, g, b, y, u, v, ymask, uvmask) \
505 y = (r + (g << 1) + b) >> 2; \
515 y += (0xFFFFFFFF - ymask + 1); \
518 u += (0xFFFFFFFF - uvmask + 1); \
521 v += (0xFFFFFFFF - uvmask + 1); \
527 coefficient packing/unpacking stuffs.
528 Wavelet transform makes 4 sub coefficient image from 1 original image.
530 model with pyramid decomposition:
541 So, we must transfer each sub images individually in strict meaning.
542 But at least ZRLE meaning, following one decompositon image is same as
543 avobe individual sub image. I use this format.
544 (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
545 for simplified procedure for any wavelet level.)
557 #define ZYWRLE_INC_PTR(data) \
560 if( data - p >= (w + uw) ) { \
561 data += scanline-(w + uw); \
566 #define ZYWRLE_TRANSFER_COEFF(buf, data, t, w, h, scanline, level, TRANS) \
574 ph += (s >> 1) * w; \
579 while (ph < line) { \
581 ZYWRLE_INC_PTR(data); \
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);)
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);)
598 #define ZYWRLE_SAVE_UNALIGN(data, TRANS) \
601 end = buf + (w + uw) * (h + uh); \
602 while (top < end) { \
604 ZYWRLE_INC_PTR(data); \
609 #define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
614 end = (int*)(p + h * scanline); \
615 while (p < (ZRLE_PIXEL*)end) { \
616 line = (int*)(p + uw); \
617 while (p < (ZRLE_PIXEL*)line) { \
622 p += scanline - uw; \
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) { \
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) { \
653 static inline void zywrle_calc_size(int *w
, int *h
, int level
)
655 *w
&= ~((1 << level
) - 1);
656 *h
&= ~((1 << level
) - 1);