xref: /qemu/ui/vnc-enc-zywrle.h (revision d4761b65)
1148954faSCorentin Chary /********************************************************************
2148954faSCorentin Chary  *                                                                  *
3148954faSCorentin Chary  * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE.         *
4148954faSCorentin Chary  *                                                                  *
5148954faSCorentin Chary  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
6148954faSCorentin Chary  * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE.                *
7148954faSCorentin Chary  * PLEASE READ THESE TERMS BEFORE DISTRIBUTING.                     *
8148954faSCorentin Chary  *                                                                  *
9148954faSCorentin Chary  * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006         *
10148954faSCorentin Chary  * BY Hitachi Systems & Services, Ltd.                              *
11e7d81004SStefan Weil  * (Noriaki Yamazaki, Research & Development Center)               *
12148954faSCorentin Chary  *                                                                  *
13148954faSCorentin Chary  *                                                                  *
14148954faSCorentin Chary  ********************************************************************
15148954faSCorentin Chary Redistribution and use in source and binary forms, with or without
16148954faSCorentin Chary modification, are permitted provided that the following conditions
17148954faSCorentin Chary are met:
18148954faSCorentin Chary 
19148954faSCorentin Chary - Redistributions of source code must retain the above copyright
20148954faSCorentin Chary notice, this list of conditions and the following disclaimer.
21148954faSCorentin Chary 
22148954faSCorentin Chary - Redistributions in binary form must reproduce the above copyright
23148954faSCorentin Chary notice, this list of conditions and the following disclaimer in the
24148954faSCorentin Chary documentation and/or other materials provided with the distribution.
25148954faSCorentin Chary 
26148954faSCorentin Chary - Neither the name of the Hitachi Systems & Services, Ltd. nor
27148954faSCorentin Chary the names of its contributors may be used to endorse or promote
28148954faSCorentin Chary products derived from this software without specific prior written
29148954faSCorentin Chary permission.
30148954faSCorentin Chary 
31148954faSCorentin Chary THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32148954faSCorentin Chary ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33148954faSCorentin Chary LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34148954faSCorentin Chary A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
35148954faSCorentin Chary OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36148954faSCorentin Chary SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37148954faSCorentin Chary LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38148954faSCorentin Chary DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39148954faSCorentin Chary THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40148954faSCorentin Chary (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41148954faSCorentin Chary OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42148954faSCorentin Chary  ********************************************************************/
43148954faSCorentin Chary 
44121d0712SMarkus Armbruster #ifndef VNC_ENC_ZYWRLE_H
45121d0712SMarkus Armbruster #define VNC_ENC_ZYWRLE_H
46148954faSCorentin Chary 
47148954faSCorentin Chary /* Tables for Coefficients filtering. */
48148954faSCorentin Chary #ifndef ZYWRLE_QUANTIZE
49148954faSCorentin Chary /* Type A:lower bit omitting of EZW style. */
50148954faSCorentin Chary static const unsigned int zywrle_param[3][3]={
51148954faSCorentin Chary         {0x0000F000, 0x00000000, 0x00000000},
52148954faSCorentin Chary         {0x0000C000, 0x00F0F0F0, 0x00000000},
53148954faSCorentin Chary         {0x0000C000, 0x00C0C0C0, 0x00F0F0F0},
54148954faSCorentin Chary /*      {0x0000FF00, 0x00000000, 0x00000000},
55148954faSCorentin Chary         {0x0000FF00, 0x00FFFFFF, 0x00000000},
56148954faSCorentin Chary         {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */
57148954faSCorentin Chary };
58148954faSCorentin Chary #else
59148954faSCorentin Chary /* Type B:Non liner quantization filter. */
60148954faSCorentin Chary static const int8_t zywrle_conv[4][256]={
61148954faSCorentin Chary {       /* bi=5, bo=5 r=0.0:PSNR=24.849 */
62148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
63148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
64148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
65148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
66148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
67148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
68148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
69148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
70148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
71148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
72148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
73148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
74148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
75148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
76148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
77148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
78148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
79148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
80148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
81148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
82148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
83148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
84148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
85148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
86148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
87148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
88148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
89148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
90148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
91148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
92148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
93148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
94148954faSCorentin Chary },
95148954faSCorentin Chary {       /* bi=5, bo=5 r=2.0:PSNR=74.031 */
96148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
97148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
98148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 32,
99148954faSCorentin Chary         32, 32, 32, 32, 32, 32, 32, 32,
100148954faSCorentin Chary         32, 32, 32, 32, 32, 32, 32, 32,
101148954faSCorentin Chary         48, 48, 48, 48, 48, 48, 48, 48,
102148954faSCorentin Chary         48, 48, 48, 56, 56, 56, 56, 56,
103148954faSCorentin Chary         56, 56, 56, 56, 64, 64, 64, 64,
104148954faSCorentin Chary         64, 64, 64, 64, 72, 72, 72, 72,
105148954faSCorentin Chary         72, 72, 72, 72, 80, 80, 80, 80,
106148954faSCorentin Chary         80, 80, 88, 88, 88, 88, 88, 88,
107148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 96, 96,
108148954faSCorentin Chary         96, 96, 96, 104, 104, 104, 104, 104,
109148954faSCorentin Chary         104, 104, 104, 104, 104, 112, 112, 112,
110148954faSCorentin Chary         112, 112, 112, 112, 112, 112, 120, 120,
111148954faSCorentin Chary         120, 120, 120, 120, 120, 120, 120, 120,
112148954faSCorentin Chary         0, -120, -120, -120, -120, -120, -120, -120,
113148954faSCorentin Chary         -120, -120, -120, -112, -112, -112, -112, -112,
114148954faSCorentin Chary         -112, -112, -112, -112, -104, -104, -104, -104,
115148954faSCorentin Chary         -104, -104, -104, -104, -104, -104, -96, -96,
116148954faSCorentin Chary         -96, -96, -96, -88, -88, -88, -88, -88,
117148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -80,
118148954faSCorentin Chary         -80, -80, -80, -80, -80, -72, -72, -72,
119148954faSCorentin Chary         -72, -72, -72, -72, -72, -64, -64, -64,
120148954faSCorentin Chary         -64, -64, -64, -64, -64, -56, -56, -56,
121148954faSCorentin Chary         -56, -56, -56, -56, -56, -56, -48, -48,
122148954faSCorentin Chary         -48, -48, -48, -48, -48, -48, -48, -48,
123148954faSCorentin Chary         -48, -32, -32, -32, -32, -32, -32, -32,
124148954faSCorentin Chary         -32, -32, -32, -32, -32, -32, -32, -32,
125148954faSCorentin Chary         -32, -32, 0, 0, 0, 0, 0, 0,
126148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
127148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
128148954faSCorentin Chary },
129148954faSCorentin Chary {       /* bi=5, bo=4 r=2.0:PSNR=64.441 */
130148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
131148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
132148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
133148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
134148954faSCorentin Chary         48, 48, 48, 48, 48, 48, 48, 48,
135148954faSCorentin Chary         48, 48, 48, 48, 48, 48, 48, 48,
136148954faSCorentin Chary         48, 48, 48, 48, 48, 48, 48, 48,
137148954faSCorentin Chary         64, 64, 64, 64, 64, 64, 64, 64,
138148954faSCorentin Chary         64, 64, 64, 64, 64, 64, 64, 64,
139148954faSCorentin Chary         80, 80, 80, 80, 80, 80, 80, 80,
140148954faSCorentin Chary         80, 80, 80, 80, 80, 88, 88, 88,
141148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
142148954faSCorentin Chary         104, 104, 104, 104, 104, 104, 104, 104,
143148954faSCorentin Chary         104, 104, 104, 112, 112, 112, 112, 112,
144148954faSCorentin Chary         112, 112, 112, 112, 120, 120, 120, 120,
145148954faSCorentin Chary         120, 120, 120, 120, 120, 120, 120, 120,
146148954faSCorentin Chary         0, -120, -120, -120, -120, -120, -120, -120,
147148954faSCorentin Chary         -120, -120, -120, -120, -120, -112, -112, -112,
148148954faSCorentin Chary         -112, -112, -112, -112, -112, -112, -104, -104,
149148954faSCorentin Chary         -104, -104, -104, -104, -104, -104, -104, -104,
150148954faSCorentin Chary         -104, -88, -88, -88, -88, -88, -88, -88,
151148954faSCorentin Chary         -88, -88, -88, -88, -80, -80, -80, -80,
152148954faSCorentin Chary         -80, -80, -80, -80, -80, -80, -80, -80,
153148954faSCorentin Chary         -80, -64, -64, -64, -64, -64, -64, -64,
154148954faSCorentin Chary         -64, -64, -64, -64, -64, -64, -64, -64,
155148954faSCorentin Chary         -64, -48, -48, -48, -48, -48, -48, -48,
156148954faSCorentin Chary         -48, -48, -48, -48, -48, -48, -48, -48,
157148954faSCorentin Chary         -48, -48, -48, -48, -48, -48, -48, -48,
158148954faSCorentin Chary         -48, 0, 0, 0, 0, 0, 0, 0,
159148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
160148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
161148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
162148954faSCorentin Chary },
163148954faSCorentin Chary {       /* bi=5, bo=2 r=2.0:PSNR=43.175 */
164148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
165148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
166148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
167148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
168148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
169148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
170148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
171148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
172148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
173148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
174148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
175148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
176148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
177148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
178148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
179148954faSCorentin Chary         88, 88, 88, 88, 88, 88, 88, 88,
180148954faSCorentin Chary         0, -88, -88, -88, -88, -88, -88, -88,
181148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
182148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
183148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
184148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
185148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
186148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
187148954faSCorentin Chary         -88, -88, -88, -88, -88, -88, -88, -88,
188148954faSCorentin Chary         -88, 0, 0, 0, 0, 0, 0, 0,
189148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
190148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
191148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
192148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
193148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
194148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
195148954faSCorentin Chary         0, 0, 0, 0, 0, 0, 0, 0,
196148954faSCorentin Chary }
197148954faSCorentin Chary };
198148954faSCorentin Chary 
199148954faSCorentin Chary static const int8_t *zywrle_param[3][3][3]={
200148954faSCorentin Chary         {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]},
201148954faSCorentin Chary          {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]},
202148954faSCorentin Chary          {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
203148954faSCorentin Chary         {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
204148954faSCorentin Chary          {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]},
205148954faSCorentin Chary          {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
206148954faSCorentin Chary         {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
207148954faSCorentin Chary          {zywrle_conv[2], zywrle_conv[2], zywrle_conv[2]},
208148954faSCorentin Chary          {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}},
209148954faSCorentin Chary };
210148954faSCorentin Chary #endif
211148954faSCorentin Chary 
212148954faSCorentin Chary /*   Load/Save pixel stuffs. */
213148954faSCorentin Chary #define ZYWRLE_YMASK15  0xFFFFFFF8
214148954faSCorentin Chary #define ZYWRLE_UVMASK15 0xFFFFFFF8
215148954faSCorentin Chary #define ZYWRLE_LOAD_PIXEL15(src, r, g, b)                               \
216148954faSCorentin Chary     do {                                                                \
217148954faSCorentin Chary         r = (((uint8_t*)src)[S_1]<< 1)& 0xF8;                           \
218148954faSCorentin Chary         g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2);    \
219148954faSCorentin Chary         g &= 0xF8;                                                      \
220148954faSCorentin Chary         b =  (((uint8_t*)src)[S_0]<< 3)& 0xF8;                          \
221148954faSCorentin Chary     } while (0)
222148954faSCorentin Chary 
223148954faSCorentin Chary #define ZYWRLE_SAVE_PIXEL15(dst, r, g, b)                               \
224148954faSCorentin Chary     do {                                                                \
225148954faSCorentin Chary         r &= 0xF8;                                                      \
226148954faSCorentin Chary         g &= 0xF8;                                                      \
227148954faSCorentin Chary         b &= 0xF8;                                                      \
228148954faSCorentin Chary         ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6));            \
229148954faSCorentin Chary         ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF);    \
230148954faSCorentin Chary     } while (0)
231148954faSCorentin Chary 
232148954faSCorentin Chary #define ZYWRLE_YMASK16  0xFFFFFFFC
233148954faSCorentin Chary #define ZYWRLE_UVMASK16 0xFFFFFFF8
234148954faSCorentin Chary #define ZYWRLE_LOAD_PIXEL16(src, r, g, b)                               \
235148954faSCorentin Chary     do {                                                                \
236148954faSCorentin Chary         r = ((uint8_t*)src)[S_1] & 0xF8;                                \
237148954faSCorentin Chary         g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3);   \
238148954faSCorentin Chary         g &= 0xFC;                                                      \
239148954faSCorentin Chary         b = (((uint8_t*)src)[S_0]<< 3) & 0xF8;                          \
240148954faSCorentin Chary     } while (0)
241148954faSCorentin Chary 
242148954faSCorentin Chary #define ZYWRLE_SAVE_PIXEL16(dst, r, g,b)                                \
243148954faSCorentin Chary     do {                                                                \
244148954faSCorentin Chary         r &= 0xF8;                                                      \
245148954faSCorentin Chary         g &= 0xFC;                                                      \
246148954faSCorentin Chary         b &= 0xF8;                                                      \
247148954faSCorentin Chary         ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5));                 \
248148954faSCorentin Chary         ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF);   \
249148954faSCorentin Chary     } while (0)
250148954faSCorentin Chary 
251148954faSCorentin Chary #define ZYWRLE_YMASK32  0xFFFFFFFF
252148954faSCorentin Chary #define ZYWRLE_UVMASK32 0xFFFFFFFF
253148954faSCorentin Chary #define ZYWRLE_LOAD_PIXEL32(src, r, g, b)     \
254148954faSCorentin Chary     do {                                      \
255148954faSCorentin Chary         r = ((uint8_t*)src)[L_2];             \
256148954faSCorentin Chary         g = ((uint8_t*)src)[L_1];             \
257148954faSCorentin Chary         b = ((uint8_t*)src)[L_0];             \
258148954faSCorentin Chary     } while (0)
259148954faSCorentin Chary #define ZYWRLE_SAVE_PIXEL32(dst, r, g, b)             \
260148954faSCorentin Chary     do {                                              \
261148954faSCorentin Chary         ((uint8_t*)dst)[L_2] = (uint8_t)r;            \
262148954faSCorentin Chary         ((uint8_t*)dst)[L_1] = (uint8_t)g;            \
263148954faSCorentin Chary         ((uint8_t*)dst)[L_0] = (uint8_t)b;            \
264148954faSCorentin Chary     } while (0)
265148954faSCorentin Chary 
harr(int8_t * px0,int8_t * px1)266148954faSCorentin Chary static inline void harr(int8_t *px0, int8_t *px1)
267148954faSCorentin Chary {
268148954faSCorentin Chary     /* Piecewise-Linear Harr(PLHarr) */
269148954faSCorentin Chary     int x0 = (int)*px0, x1 = (int)*px1;
270148954faSCorentin Chary     int orgx0 = x0, orgx1 = x1;
271148954faSCorentin Chary 
272148954faSCorentin Chary     if ((x0 ^ x1) & 0x80) {
273148954faSCorentin Chary         /* differ sign */
274148954faSCorentin Chary         x1 += x0;
275148954faSCorentin Chary         if (((x1 ^ orgx1) & 0x80) == 0) {
276148954faSCorentin Chary             /* |x1| > |x0| */
277148954faSCorentin Chary             x0 -= x1;   /* H = -B */
278148954faSCorentin Chary         }
279148954faSCorentin Chary     } else {
280148954faSCorentin Chary         /* same sign */
281148954faSCorentin Chary         x0 -= x1;
282148954faSCorentin Chary         if (((x0 ^ orgx0) & 0x80) == 0) {
283148954faSCorentin Chary             /* |x0| > |x1| */
284148954faSCorentin Chary             x1 += x0;   /* L = A */
285148954faSCorentin Chary         }
286148954faSCorentin Chary     }
287148954faSCorentin Chary     *px0 = (int8_t)x1;
288148954faSCorentin Chary     *px1 = (int8_t)x0;
289148954faSCorentin Chary }
290148954faSCorentin Chary 
291148954faSCorentin Chary /*
292148954faSCorentin Chary  1D-Wavelet transform.
293148954faSCorentin Chary 
294148954faSCorentin Chary  In coefficients array, the famous 'pyramid' decomposition is well used.
295148954faSCorentin Chary 
296148954faSCorentin Chary  1D Model:
297148954faSCorentin Chary    |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
298148954faSCorentin Chary    |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
299148954faSCorentin Chary 
300148954faSCorentin Chary  But this method needs line buffer because H/L is different position from X0/X1.
301148954faSCorentin Chary  So, I used 'interleave' decomposition instead of it.
302148954faSCorentin Chary 
303148954faSCorentin Chary  1D Model:
304148954faSCorentin Chary    |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
305148954faSCorentin Chary    |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
306148954faSCorentin Chary 
307148954faSCorentin Chary  In this method, H/L and X0/X1 is always same position.
30859b00962SStefan Weil  This leads us to more speed and less memory.
309148954faSCorentin Chary  Of cause, the result of both method is quite same
310148954faSCorentin Chary  because it's only difference that coefficient position.
311148954faSCorentin Chary */
wavelet_level(int * data,int size,int l,int skip_pixel)312148954faSCorentin Chary static inline void wavelet_level(int *data, int size, int l, int skip_pixel)
313148954faSCorentin Chary {
314148954faSCorentin Chary     int s, ofs;
315148954faSCorentin Chary     int8_t *px0;
316148954faSCorentin Chary     int8_t *end;
317148954faSCorentin Chary 
318148954faSCorentin Chary     px0 = (int8_t*)data;
319148954faSCorentin Chary     s = (8 << l) * skip_pixel;
320148954faSCorentin Chary     end = px0 + (size >> (l + 1)) * s;
321148954faSCorentin Chary     s -= 2;
322148954faSCorentin Chary     ofs = (4 << l) * skip_pixel;
323148954faSCorentin Chary 
324148954faSCorentin Chary     while (px0 < end) {
325148954faSCorentin Chary         harr(px0, px0 + ofs);
326148954faSCorentin Chary         px0++;
327148954faSCorentin Chary         harr(px0, px0 + ofs);
328148954faSCorentin Chary         px0++;
329148954faSCorentin Chary         harr(px0, px0 + ofs);
330148954faSCorentin Chary         px0 += s;
331148954faSCorentin Chary     }
332148954faSCorentin Chary }
333148954faSCorentin Chary 
334148954faSCorentin Chary #ifndef ZYWRLE_QUANTIZE
335148954faSCorentin Chary /* Type A:lower bit omitting of EZW style. */
filter_wavelet_square(int * buf,int width,int height,int level,int l)336148954faSCorentin Chary static inline void filter_wavelet_square(int *buf, int width, int height,
337148954faSCorentin Chary                                          int level, int l)
338148954faSCorentin Chary {
339148954faSCorentin Chary     int r, s;
340148954faSCorentin Chary     int x, y;
341148954faSCorentin Chary     int *h;
342148954faSCorentin Chary     const unsigned int *m;
343148954faSCorentin Chary 
344148954faSCorentin Chary     m = &(zywrle_param[level - 1][l]);
345148954faSCorentin Chary     s = 2 << l;
346148954faSCorentin Chary 
347148954faSCorentin Chary     for (r = 1; r < 4; r++) {
348148954faSCorentin Chary         h = buf;
349148954faSCorentin Chary         if (r & 0x01) {
350148954faSCorentin Chary             h += s >> 1;
351148954faSCorentin Chary         }
352148954faSCorentin Chary         if (r & 0x02) {
353148954faSCorentin Chary             h += (s >> 1) * width;
354148954faSCorentin Chary         }
355148954faSCorentin Chary         for (y = 0; y < height / s; y++) {
356148954faSCorentin Chary             for (x = 0; x < width / s; x++) {
357148954faSCorentin Chary                 /*
358148954faSCorentin Chary                   these are same following code.
359148954faSCorentin Chary                   h[x] = h[x] / (~m[x]+1) * (~m[x]+1);
360148954faSCorentin Chary                   ( round h[x] with m[x] bit )
361148954faSCorentin Chary                   '&' operator isn't 'round' but is 'floor'.
362148954faSCorentin Chary                   So, we must offset when h[x] is negative.
363148954faSCorentin Chary                 */
364148954faSCorentin Chary                 if (((int8_t*)h)[0] & 0x80) {
365148954faSCorentin Chary                     ((int8_t*)h)[0] += ~((int8_t*)m)[0];
366148954faSCorentin Chary                 }
367148954faSCorentin Chary                 if (((int8_t*)h)[1] & 0x80) {
368148954faSCorentin Chary                     ((int8_t*)h)[1] += ~((int8_t*)m)[1];
369148954faSCorentin Chary                 }
370148954faSCorentin Chary                 if (((int8_t*)h)[2] & 0x80) {
371148954faSCorentin Chary                     ((int8_t*)h)[2] += ~((int8_t*)m)[2];
372148954faSCorentin Chary                 }
373148954faSCorentin Chary                 *h &= *m;
374148954faSCorentin Chary                 h += s;
375148954faSCorentin Chary             }
376148954faSCorentin Chary             h += (s-1)*width;
377148954faSCorentin Chary         }
378148954faSCorentin Chary     }
379148954faSCorentin Chary }
380148954faSCorentin Chary #else
381148954faSCorentin Chary /*
382148954faSCorentin Chary  Type B:Non liner quantization filter.
383148954faSCorentin Chary 
384148954faSCorentin Chary  Coefficients have Gaussian curve and smaller value which is
385148954faSCorentin Chary  large part of coefficients isn't more important than larger value.
386148954faSCorentin Chary  So, I use filter of Non liner quantize/dequantize table.
387148954faSCorentin Chary  In general, Non liner quantize formula is explained as following.
388148954faSCorentin Chary 
389148954faSCorentin Chary     y=f(x)   = sign(x)*round( ((abs(x)/(2^7))^ r   )* 2^(bo-1) )*2^(8-bo)
390148954faSCorentin Chary     x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
391148954faSCorentin Chary  ( r:power coefficient  bi:effective MSB in input  bo:effective MSB in output )
392148954faSCorentin Chary 
393148954faSCorentin Chary    r < 1.0 : Smaller value is more important than larger value.
394148954faSCorentin Chary    r > 1.0 : Larger value is more important than smaller value.
395148954faSCorentin Chary    r = 1.0 : Liner quantization which is same with EZW style.
396148954faSCorentin Chary 
397148954faSCorentin Chary  r = 0.75 is famous non liner quantization used in MP3 audio codec.
398148954faSCorentin Chary  In contrast to audio data, larger value is important in wavelet coefficients.
399148954faSCorentin Chary  So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
400148954faSCorentin Chary 
401148954faSCorentin Chary  As compared with EZW style liner quantization, this filter tended to be
402148954faSCorentin Chary  more sharp edge and be more compression rate but be more blocking noise and be
403148954faSCorentin Chary  less quality. Especially, the surface of graphic objects has distinguishable
404148954faSCorentin Chary  noise in middle quality mode.
405148954faSCorentin Chary 
406148954faSCorentin Chary  We need only quantized-dequantized(filtered) value rather than quantized value
407148954faSCorentin Chary  itself because all values are packed or palette-lized in later ZRLE section.
408148954faSCorentin Chary  This lead us not to need to modify client decoder when we change
409148954faSCorentin Chary  the filtering procedure in future.
410148954faSCorentin Chary  Client only decodes coefficients given by encoder.
411148954faSCorentin Chary */
filter_wavelet_square(int * buf,int width,int height,int level,int l)412148954faSCorentin Chary static inline void filter_wavelet_square(int *buf, int width, int height,
413148954faSCorentin Chary                                          int level, int l)
414148954faSCorentin Chary {
415148954faSCorentin Chary     int r, s;
416148954faSCorentin Chary     int x, y;
417148954faSCorentin Chary     int *h;
418148954faSCorentin Chary     const int8_t **m;
419148954faSCorentin Chary 
420148954faSCorentin Chary     m = zywrle_param[level - 1][l];
421148954faSCorentin Chary     s = 2 << l;
422148954faSCorentin Chary 
423148954faSCorentin Chary     for (r = 1; r < 4; r++) {
424148954faSCorentin Chary         h = buf;
425148954faSCorentin Chary         if (r & 0x01) {
426148954faSCorentin Chary             h += s >> 1;
427148954faSCorentin Chary         }
428148954faSCorentin Chary         if (r & 0x02) {
429148954faSCorentin Chary             h += (s >> 1) * width;
430148954faSCorentin Chary         }
431148954faSCorentin Chary         for (y = 0; y < height / s; y++) {
432148954faSCorentin Chary             for (x = 0; x < width / s; x++) {
433148954faSCorentin Chary                 ((int8_t*)h)[0] = m[0][((uint8_t*)h)[0]];
434148954faSCorentin Chary                 ((int8_t*)h)[1] = m[1][((uint8_t*)h)[1]];
435148954faSCorentin Chary                 ((int8_t*)h)[2] = m[2][((uint8_t*)h)[2]];
436148954faSCorentin Chary                 h += s;
437148954faSCorentin Chary             }
438148954faSCorentin Chary             h += (s - 1) * width;
439148954faSCorentin Chary         }
440148954faSCorentin Chary     }
441148954faSCorentin Chary }
442148954faSCorentin Chary #endif
443148954faSCorentin Chary 
wavelet(int * buf,int width,int height,int level)444148954faSCorentin Chary static inline void wavelet(int *buf, int width, int height, int level)
445148954faSCorentin Chary {
446148954faSCorentin Chary         int l, s;
447148954faSCorentin Chary         int *top;
448148954faSCorentin Chary         int *end;
449148954faSCorentin Chary 
450148954faSCorentin Chary         for (l = 0; l < level; l++) {
451148954faSCorentin Chary                 top = buf;
452148954faSCorentin Chary                 end = buf + height * width;
453148954faSCorentin Chary                 s = width << l;
454148954faSCorentin Chary                 while (top < end) {
455148954faSCorentin Chary                         wavelet_level(top, width, l, 1);
456148954faSCorentin Chary                         top += s;
457148954faSCorentin Chary                 }
458148954faSCorentin Chary                 top = buf;
459148954faSCorentin Chary                 end = buf + width;
460148954faSCorentin Chary                 s = 1<<l;
461148954faSCorentin Chary                 while (top < end) {
462148954faSCorentin Chary                         wavelet_level(top, height, l, width);
463148954faSCorentin Chary                         top += s;
464148954faSCorentin Chary                 }
465148954faSCorentin Chary                 filter_wavelet_square(buf, width, height, level, l);
466148954faSCorentin Chary         }
467148954faSCorentin Chary }
468148954faSCorentin Chary 
469148954faSCorentin Chary 
470148954faSCorentin Chary /* Load/Save coefficients stuffs.
471148954faSCorentin Chary  Coefficients manages as 24 bits little-endian pixel. */
472148954faSCorentin Chary #define ZYWRLE_LOAD_COEFF(src, r, g, b)         \
473148954faSCorentin Chary     do {                                        \
474148954faSCorentin Chary         r = ((int8_t*)src)[2];                  \
475148954faSCorentin Chary         g = ((int8_t*)src)[1];                  \
476148954faSCorentin Chary         b = ((int8_t*)src)[0];                  \
477148954faSCorentin Chary     } while (0)
478148954faSCorentin Chary 
479148954faSCorentin Chary #define ZYWRLE_SAVE_COEFF(dst, r, g, b)       \
480148954faSCorentin Chary     do {                                      \
481148954faSCorentin Chary         ((int8_t*)dst)[2] = (int8_t)r;        \
482148954faSCorentin Chary         ((int8_t*)dst)[1] = (int8_t)g;        \
483148954faSCorentin Chary         ((int8_t*)dst)[0] = (int8_t)b;        \
484148954faSCorentin Chary     } while (0)
485148954faSCorentin Chary 
486148954faSCorentin Chary /*
487148954faSCorentin Chary   RGB <=> YUV conversion stuffs.
488d4761b65SMichael Tokarev   YUV conversion is explained as following formula in strict meaning:
489148954faSCorentin Chary   Y =  0.299R + 0.587G + 0.114B (   0<=Y<=255)
490148954faSCorentin Chary   U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
491148954faSCorentin Chary   V =  0.500R - 0.419G - 0.081B (-128<=V<=127)
492148954faSCorentin Chary 
493148954faSCorentin Chary   I use simple conversion RCT(reversible color transform) which is described
494148954faSCorentin Chary   in JPEG-2000 specification.
495148954faSCorentin Chary   Y = (R + 2G + B)/4 (   0<=Y<=255)
496148954faSCorentin Chary   U = B-G (-256<=U<=255)
497148954faSCorentin Chary   V = R-G (-256<=V<=255)
498148954faSCorentin Chary */
499148954faSCorentin Chary 
500148954faSCorentin Chary /* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
501148954faSCorentin Chary    For make Same N-bit, UV is lossy.
502148954faSCorentin Chary    More exact PLHarr, we reduce to odd range(-127<=x<=127). */
503148954faSCorentin Chary #define ZYWRLE_RGBYUV_(r, g, b, y, u, v, ymask, uvmask)          \
504148954faSCorentin Chary     do {                                                         \
505148954faSCorentin Chary         y = (r + (g << 1) + b) >> 2;                             \
506148954faSCorentin Chary         u =  b - g;                                              \
507148954faSCorentin Chary         v =  r - g;                                              \
508148954faSCorentin Chary         y -= 128;                                                \
509148954faSCorentin Chary         u >>= 1;                                                 \
510148954faSCorentin Chary         v >>= 1;                                                 \
511148954faSCorentin Chary         y &= ymask;                                              \
512148954faSCorentin Chary         u &= uvmask;                                             \
513148954faSCorentin Chary         v &= uvmask;                                             \
514148954faSCorentin Chary         if (y == -128) {                                         \
515148954faSCorentin Chary             y += (0xFFFFFFFF - ymask + 1);                       \
516148954faSCorentin Chary         }                                                        \
517148954faSCorentin Chary         if (u == -128) {                                         \
518148954faSCorentin Chary             u += (0xFFFFFFFF - uvmask + 1);                      \
519148954faSCorentin Chary         }                                                        \
520148954faSCorentin Chary         if (v == -128) {                                         \
521148954faSCorentin Chary             v += (0xFFFFFFFF - uvmask + 1);                      \
522148954faSCorentin Chary         }                                                        \
523148954faSCorentin Chary     } while (0)
524148954faSCorentin Chary 
525148954faSCorentin Chary 
526148954faSCorentin Chary /*
527148954faSCorentin Chary  coefficient packing/unpacking stuffs.
528148954faSCorentin Chary  Wavelet transform makes 4 sub coefficient image from 1 original image.
529148954faSCorentin Chary 
530148954faSCorentin Chary  model with pyramid decomposition:
531148954faSCorentin Chary    +------+------+
532148954faSCorentin Chary    |      |      |
533148954faSCorentin Chary    |  L   |  Hx  |
534148954faSCorentin Chary    |      |      |
535148954faSCorentin Chary    +------+------+
536148954faSCorentin Chary    |      |      |
537148954faSCorentin Chary    |  H   |  Hxy |
538148954faSCorentin Chary    |      |      |
539148954faSCorentin Chary    +------+------+
540148954faSCorentin Chary 
541148954faSCorentin Chary  So, we must transfer each sub images individually in strict meaning.
542d4761b65SMichael Tokarev  But at least ZRLE meaning, following one decomposition image is same as
543148954faSCorentin Chary  avobe individual sub image. I use this format.
544148954faSCorentin Chary  (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
545148954faSCorentin Chary   for simplified procedure for any wavelet level.)
546148954faSCorentin Chary 
547148954faSCorentin Chary    +------+------+
548148954faSCorentin Chary    |      L      |
549148954faSCorentin Chary    +------+------+
550148954faSCorentin Chary    |      Hx     |
551148954faSCorentin Chary    +------+------+
552148954faSCorentin Chary    |      Hy     |
553148954faSCorentin Chary    +------+------+
554148954faSCorentin Chary    |      Hxy    |
555148954faSCorentin Chary    +------+------+
556148954faSCorentin Chary */
557148954faSCorentin Chary #define ZYWRLE_INC_PTR(data)                         \
558148954faSCorentin Chary     do {                                             \
559148954faSCorentin Chary         data++;                                      \
560148954faSCorentin Chary         if( data - p >= (w + uw) ) {                 \
561148954faSCorentin Chary             data += scanline-(w + uw);               \
562148954faSCorentin Chary             p = data;                                \
563148954faSCorentin Chary         }                                            \
564148954faSCorentin Chary     } while (0)
565148954faSCorentin Chary 
566148954faSCorentin Chary #define ZYWRLE_TRANSFER_COEFF(buf, data, t, w, h, scanline, level, TRANS) \
567148954faSCorentin Chary     do {                                                                \
568148954faSCorentin Chary         ph = buf;                                                       \
569148954faSCorentin Chary         s = 2 << level;                                                 \
570148954faSCorentin Chary         if (t & 0x01) {                                                 \
571148954faSCorentin Chary             ph += s >> 1;                                               \
572148954faSCorentin Chary         }                                                               \
573148954faSCorentin Chary         if (t & 0x02) {                                                 \
574148954faSCorentin Chary             ph += (s >> 1) * w;                                         \
575148954faSCorentin Chary         }                                                               \
576148954faSCorentin Chary         end = ph + h * w;                                               \
577148954faSCorentin Chary         while (ph < end) {                                              \
578148954faSCorentin Chary             line = ph + w;                                              \
579148954faSCorentin Chary             while (ph < line) {                                         \
580148954faSCorentin Chary                 TRANS                                                   \
581148954faSCorentin Chary                     ZYWRLE_INC_PTR(data);                               \
582148954faSCorentin Chary                 ph += s;                                                \
583148954faSCorentin Chary             }                                                           \
584148954faSCorentin Chary             ph += (s - 1) * w;                                          \
585148954faSCorentin Chary         }                                                               \
586148954faSCorentin Chary     } while (0)
587148954faSCorentin Chary 
588148954faSCorentin Chary #define ZYWRLE_PACK_COEFF(buf, data, t, width, height, scanline, level) \
589148954faSCorentin Chary     ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
590148954faSCorentin Chary                           ZYWRLE_LOAD_COEFF(ph, r, g, b);               \
591148954faSCorentin Chary                           ZYWRLE_SAVE_PIXEL(data, r, g, b);)
592148954faSCorentin Chary 
593148954faSCorentin Chary #define ZYWRLE_UNPACK_COEFF(buf, data, t, width, height, scanline, level) \
594148954faSCorentin Chary     ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
595148954faSCorentin Chary                           ZYWRLE_LOAD_PIXEL(data, r, g, b);             \
596148954faSCorentin Chary                           ZYWRLE_SAVE_COEFF(ph, r, g, b);)
597148954faSCorentin Chary 
598148954faSCorentin Chary #define ZYWRLE_SAVE_UNALIGN(data, TRANS)                     \
599148954faSCorentin Chary     do {                                                     \
600148954faSCorentin Chary         top = buf + w * h;                                   \
601148954faSCorentin Chary         end = buf + (w + uw) * (h + uh);                     \
602148954faSCorentin Chary         while (top < end) {                                  \
603148954faSCorentin Chary             TRANS                                            \
604148954faSCorentin Chary                 ZYWRLE_INC_PTR(data);                        \
605148954faSCorentin Chary                 top++;                                       \
606148954faSCorentin Chary         }                                                    \
607148954faSCorentin Chary     } while (0)
608148954faSCorentin Chary 
609148954faSCorentin Chary #define ZYWRLE_LOAD_UNALIGN(data,TRANS)                                 \
610148954faSCorentin Chary     do {                                                                \
611148954faSCorentin Chary         top = buf + w * h;                                              \
612148954faSCorentin Chary         if (uw) {                                                       \
613148954faSCorentin Chary             p = data + w;                                               \
614148954faSCorentin Chary             end = (int*)(p + h * scanline);                             \
615148954faSCorentin Chary             while (p < (ZRLE_PIXEL*)end) {                              \
616148954faSCorentin Chary                 line = (int*)(p + uw);                                  \
617148954faSCorentin Chary                 while (p < (ZRLE_PIXEL*)line) {                         \
618148954faSCorentin Chary                     TRANS                                               \
619148954faSCorentin Chary                         p++;                                            \
620148954faSCorentin Chary                     top++;                                              \
621148954faSCorentin Chary                 }                                                       \
622148954faSCorentin Chary                 p += scanline - uw;                                     \
623148954faSCorentin Chary             }                                                           \
624148954faSCorentin Chary         }                                                               \
625148954faSCorentin Chary         if (uh) {                                                       \
626148954faSCorentin Chary             p = data + h * scanline;                                    \
627148954faSCorentin Chary             end = (int*)(p + uh * scanline);                            \
628148954faSCorentin Chary             while (p < (ZRLE_PIXEL*)end) {                              \
629148954faSCorentin Chary                 line = (int*)(p + w);                                   \
630148954faSCorentin Chary                 while (p < (ZRLE_PIXEL*)line) {                         \
631148954faSCorentin Chary                     TRANS                                               \
632148954faSCorentin Chary                         p++;                                            \
633148954faSCorentin Chary                     top++;                                              \
634148954faSCorentin Chary                 }                                                       \
635148954faSCorentin Chary                 p += scanline - w;                                      \
636148954faSCorentin Chary             }                                                           \
637148954faSCorentin Chary         }                                                               \
638148954faSCorentin Chary         if (uw && uh) {                                                 \
639148954faSCorentin Chary             p= data + w + h * scanline;                                 \
640148954faSCorentin Chary             end = (int*)(p + uh * scanline);                            \
641148954faSCorentin Chary             while (p < (ZRLE_PIXEL*)end) {                              \
642148954faSCorentin Chary                 line = (int*)(p + uw);                                  \
643148954faSCorentin Chary                 while (p < (ZRLE_PIXEL*)line) {                         \
644148954faSCorentin Chary                     TRANS                                               \
645148954faSCorentin Chary                         p++;                                            \
646148954faSCorentin Chary                     top++;                                              \
647148954faSCorentin Chary                 }                                                       \
648148954faSCorentin Chary                 p += scanline-uw;                                       \
649148954faSCorentin Chary             }                                                           \
650148954faSCorentin Chary         }                                                               \
651148954faSCorentin Chary     } while (0)
652148954faSCorentin Chary 
zywrle_calc_size(int * w,int * h,int level)653148954faSCorentin Chary static inline void zywrle_calc_size(int *w, int *h, int level)
654148954faSCorentin Chary {
655148954faSCorentin Chary     *w &= ~((1 << level) - 1);
656148954faSCorentin Chary     *h &= ~((1 << level) - 1);
657148954faSCorentin Chary }
658148954faSCorentin Chary 
659148954faSCorentin Chary #endif
660