Revision 148954fa

b/Makefile.objs
129 129
ui-obj-y += vnc.o d3des.o
130 130
ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
131 131
ui-obj-y += vnc-enc-tight.o vnc-palette.o
132
ui-obj-y += vnc-enc-zrle.o
132 133
ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o
133 134
ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
134 135
ui-obj-$(CONFIG_COCOA) += cocoa.o
b/ui/vnc-enc-zrle-template.c
1
/*
2
 * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
3
 *
4
 * From libvncserver/libvncserver/zrleencodetemplate.c
5
 * Copyright (C) 2002 RealVNC Ltd.  All Rights Reserved.
6
 * Copyright (C) 2003 Sun Microsystems, Inc.
7
 *
8
 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
9
 *
10
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11
 * See the COPYING file in the top-level directory.
12
 */
13

  
14
/*
15
 * Before including this file, you must define a number of CPP macros.
16
 *
17
 * ZRLE_BPP should be 8, 16 or 32 depending on the bits per pixel.
18
 *
19
 * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
20
 * bigger than the largest tile of pixel data, since the ZRLE encoding
21
 * algorithm writes to the position one past the end of the pixel data.
22
 */
23

  
24

  
25
#include <assert.h>
26

  
27
#undef ZRLE_ENDIAN_SUFFIX
28

  
29
#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
30
#define ZRLE_ENDIAN_SUFFIX le
31
#elif ZYWRLE_ENDIAN == ENDIAN_BIG
32
#define ZRLE_ENDIAN_SUFFIX be
33
#else
34
#define ZRLE_ENDIAN_SUFFIX ne
35
#endif
36

  
37
#ifndef ZRLE_CONCAT
38
#define ZRLE_CONCAT_I(a, b)    a##b
39
#define ZRLE_CONCAT2(a, b)     ZRLE_CONCAT_I(a, b)
40
#define ZRLE_CONCAT3(a, b, c)  ZRLE_CONCAT2(a, ZRLE_CONCAT2(b, c))
41
#endif
42

  
43
#ifdef ZRLE_COMPACT_PIXEL
44
#define ZRLE_ENCODE_SUFFIX   ZRLE_CONCAT2(ZRLE_COMPACT_PIXEL,ZRLE_ENDIAN_SUFFIX)
45
#define ZRLE_WRITE_SUFFIX    ZRLE_COMPACT_PIXEL
46
#define ZRLE_PIXEL           ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
47
#define ZRLE_BPP_OUT         24
48
#elif ZRLE_BPP == 15
49
#define ZRLE_ENCODE_SUFFIX   ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
50
#define ZRLE_WRITE_SUFFIX    16
51
#define ZRLE_PIXEL           uint16_t
52
#define ZRLE_BPP_OUT         16
53
#else
54
#define ZRLE_ENCODE_SUFFIX   ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
55
#define ZRLE_WRITE_SUFFIX    ZRLE_BPP
56
#define ZRLE_BPP_OUT         ZRLE_BPP
57
#define ZRLE_PIXEL           ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
58
#endif
59

  
60
#define ZRLE_WRITE_PIXEL     ZRLE_CONCAT2(zrle_write_u,       ZRLE_WRITE_SUFFIX)
61
#define ZRLE_ENCODE          ZRLE_CONCAT2(zrle_encode_,      ZRLE_ENCODE_SUFFIX)
62
#define ZRLE_ENCODE_TILE     ZRLE_CONCAT2(zrle_encode_tile,  ZRLE_ENCODE_SUFFIX)
63
#define ZRLE_WRITE_PALETTE   ZRLE_CONCAT2(zrle_write_palette,ZRLE_ENCODE_SUFFIX)
64

  
65
static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
66
                             int zywrle_level);
67

  
68
#if ZRLE_BPP != 8
69
#include "vnc-enc-zywrle-template.c"
70
#endif
71

  
72

  
73
static void ZRLE_ENCODE(VncState *vs, int x, int y, int w, int h,
74
                        int zywrle_level)
75
{
76
    int ty;
77

  
78
    for (ty = y; ty < y + h; ty += VNC_ZRLE_TILE_HEIGHT) {
79

  
80
        int tx, th;
81

  
82
        th = MIN(VNC_ZRLE_TILE_HEIGHT, y + h - ty);
83

  
84
        for (tx = x; tx < x + w; tx += VNC_ZRLE_TILE_WIDTH) {
85
            int tw;
86
            ZRLE_PIXEL *buf;
87

  
88
            tw = MIN(VNC_ZRLE_TILE_WIDTH, x + w - tx);
89

  
90
            buf = zrle_convert_fb(vs, tx, ty, tw, th, ZRLE_BPP);
91
            ZRLE_ENCODE_TILE(vs, buf, tw, th, zywrle_level);
92
        }
93
    }
94
}
95

  
96
static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
97
                             int zywrle_level)
98
{
99
    VncPalette *palette = &vs->zrle.palette;
100

  
101
    int runs = 0;
102
    int single_pixels = 0;
103

  
104
    bool use_rle;
105
    bool use_palette;
106

  
107
    int i;
108

  
109
    ZRLE_PIXEL *ptr = data;
110
    ZRLE_PIXEL *end = ptr + h * w;
111
    *end = ~*(end-1); /* one past the end is different so the while loop ends */
112

  
113
    /* Real limit is 127 but we wan't a way to know if there is more than 127 */
114
    palette_init(palette, 256, ZRLE_BPP);
115

  
116
    while (ptr < end) {
117
        ZRLE_PIXEL pix = *ptr;
118
        if (*++ptr != pix) { /* FIXME */
119
            single_pixels++;
120
        } else {
121
            while (*++ptr == pix) ;
122
            runs++;
123
        }
124
        palette_put(palette, pix);
125
    }
126

  
127
    /* Solid tile is a special case */
128

  
129
    if (palette_size(palette) == 1) {
130
        bool found;
131

  
132
        vnc_write_u8(vs, 1);
133
        ZRLE_WRITE_PIXEL(vs, palette_color(palette, 0, &found));
134
        return;
135
    }
136

  
137
    zrle_choose_palette_rle(vs, w, h, palette, ZRLE_BPP_OUT,
138
                            runs, single_pixels, zywrle_level,
139
                            &use_rle, &use_palette);
140

  
141
    if (!use_palette) {
142
        vnc_write_u8(vs, (use_rle ? 128 : 0));
143
    } else {
144
        uint32_t colors[VNC_PALETTE_MAX_SIZE];
145
        size_t size = palette_size(palette);
146

  
147
        vnc_write_u8(vs, (use_rle ? 128 : 0) | size);
148
        palette_fill(palette, colors);
149

  
150
        for (i = 0; i < size; i++) {
151
            ZRLE_WRITE_PIXEL(vs, colors[i]);
152
        }
153
    }
154

  
155
    if (use_rle) {
156
        ZRLE_PIXEL *ptr = data;
157
        ZRLE_PIXEL *end = ptr + w * h;
158
        ZRLE_PIXEL *run_start;
159
        ZRLE_PIXEL pix;
160

  
161
        while (ptr < end) {
162
            int len;
163
            int index = 0;
164

  
165
            run_start = ptr;
166
            pix = *ptr++;
167

  
168
            while (*ptr == pix && ptr < end) {
169
                ptr++;
170
            }
171

  
172
            len = ptr - run_start;
173

  
174
            if (use_palette)
175
                index = palette_idx(palette, pix);
176

  
177
            if (len <= 2 && use_palette) {
178
                if (len == 2) {
179
                    vnc_write_u8(vs, index);
180
                }
181
                vnc_write_u8(vs, index);
182
                continue;
183
            }
184
            if (use_palette) {
185
                vnc_write_u8(vs, index | 128);
186
            } else {
187
                ZRLE_WRITE_PIXEL(vs, pix);
188
            }
189

  
190
            len -= 1;
191

  
192
            while (len >= 255) {
193
                vnc_write_u8(vs, 255);
194
                len -= 255;
195
            }
196

  
197
            vnc_write_u8(vs, len);
198
        }
199
    } else if (use_palette) { /* no RLE */
200
        int bppp;
201
        ZRLE_PIXEL *ptr = data;
202

  
203
        /* packed pixels */
204

  
205
        assert (palette_size(palette) < 17);
206

  
207
        bppp = bits_per_packed_pixel[palette_size(palette)-1];
208

  
209
        for (i = 0; i < h; i++) {
210
            uint8_t nbits = 0;
211
            uint8_t byte = 0;
212

  
213
            ZRLE_PIXEL *eol = ptr + w;
214

  
215
            while (ptr < eol) {
216
                ZRLE_PIXEL pix = *ptr++;
217
                uint8_t index = palette_idx(palette, pix);
218

  
219
                byte = (byte << bppp) | index;
220
                nbits += bppp;
221
                if (nbits >= 8) {
222
                    vnc_write_u8(vs, byte);
223
                    nbits = 0;
224
                }
225
            }
226
            if (nbits > 0) {
227
                byte <<= 8 - nbits;
228
                vnc_write_u8(vs, byte);
229
            }
230
        }
231
    } else {
232

  
233
        /* raw */
234

  
235
#if ZRLE_BPP != 8
236
        if (zywrle_level > 0 && !(zywrle_level & 0x80)) {
237
            ZYWRLE_ANALYZE(data, data, w, h, w, zywrle_level, vs->zywrle.buf);
238
            ZRLE_ENCODE_TILE(vs, data, w, h, zywrle_level | 0x80);
239
        }
240
        else
241
#endif
242
        {
243
#ifdef ZRLE_COMPACT_PIXEL
244
            ZRLE_PIXEL *ptr;
245

  
246
            for (ptr = data; ptr < data + w * h; ptr++) {
247
                ZRLE_WRITE_PIXEL(vs, *ptr);
248
            }
249
#else
250
            vnc_write(vs, data, w * h * (ZRLE_BPP / 8));
251
#endif
252
        }
253
    }
254
}
255

  
256
#undef ZRLE_PIXEL
257
#undef ZRLE_WRITE_PIXEL
258
#undef ZRLE_ENCODE
259
#undef ZRLE_ENCODE_TILE
260
#undef ZYWRLE_ENCODE_TILE
261
#undef ZRLE_BPP_OUT
262
#undef ZRLE_WRITE_SUFFIX
263
#undef ZRLE_ENCODE_SUFFIX
b/ui/vnc-enc-zrle.c
1
/*
2
 * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
3
 *
4
 * From libvncserver/libvncserver/zrle.c
5
 * Copyright (C) 2002 RealVNC Ltd.  All Rights Reserved.
6
 * Copyright (C) 2003 Sun Microsystems, Inc.
7
 *
8
 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is
15
 * furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in
18
 * all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
 * THE SOFTWARE.
27
 */
28

  
29
#include "vnc.h"
30
#include "vnc-enc-zrle.h"
31

  
32
static const int bits_per_packed_pixel[] = {
33
  0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
34
};
35

  
36

  
37
static void vnc_zrle_start(VncState *vs)
38
{
39
    buffer_reset(&vs->zrle.zrle);
40

  
41
    /* make the output buffer be the zlib buffer, so we can compress it later */
42
    vs->zrle.tmp = vs->output;
43
    vs->output = vs->zrle.zrle;
44
}
45

  
46
static void vnc_zrle_stop(VncState *vs)
47
{
48
    /* switch back to normal output/zlib buffers */
49
    vs->zrle.zrle = vs->output;
50
    vs->output = vs->zrle.tmp;
51
}
52

  
53
static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
54
                             int bpp)
55
{
56
    Buffer tmp;
57

  
58
    buffer_reset(&vs->zrle.fb);
59
    buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
60

  
61
    tmp = vs->output;
62
    vs->output = vs->zrle.fb;
63

  
64
    vnc_raw_send_framebuffer_update(vs, x, y, w, h);
65

  
66
    vs->zrle.fb = vs->output;
67
    vs->output = tmp;
68
    return vs->zrle.fb.buffer;
69
}
70

  
71
static int zrle_compress_data(VncState *vs, int level)
72
{
73
    z_streamp zstream = &vs->zrle.stream;
74

  
75
    buffer_reset(&vs->zrle.zlib);
76

  
77
    if (zstream->opaque != vs) {
78
        int err;
79

  
80
        zstream->zalloc = vnc_zlib_zalloc;
81
        zstream->zfree = vnc_zlib_zfree;
82

  
83
        err = deflateInit2(zstream, level, Z_DEFLATED, MAX_WBITS,
84
                           MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
85

  
86
        if (err != Z_OK) {
87
            fprintf(stderr, "VNC: error initializing zlib\n");
88
            return -1;
89
        }
90

  
91
        zstream->opaque = vs;
92
    }
93

  
94
    /* reserve memory in output buffer */
95
    buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
96

  
97
    /* set pointers */
98
    zstream->next_in = vs->zrle.zrle.buffer;
99
    zstream->avail_in = vs->zrle.zrle.offset;
100
    zstream->next_out = vs->zrle.zlib.buffer + vs->zrle.zlib.offset;
101
    zstream->avail_out = vs->zrle.zlib.capacity - vs->zrle.zlib.offset;
102
    zstream->data_type = Z_BINARY;
103

  
104
    /* start encoding */
105
    if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
106
        fprintf(stderr, "VNC: error during zrle compression\n");
107
        return -1;
108
    }
109

  
110
    vs->zrle.zlib.offset = vs->zrle.zlib.capacity - zstream->avail_out;
111
    return vs->zrle.zlib.offset;
112
}
113

  
114
/* Try to work out whether to use RLE and/or a palette.  We do this by
115
 * estimating the number of bytes which will be generated and picking the
116
 * method which results in the fewest bytes.  Of course this may not result
117
 * in the fewest bytes after compression... */
118
static void zrle_choose_palette_rle(VncState *vs, int w, int h,
119
                                    VncPalette *palette, int bpp_out,
120
                                    int runs, int single_pixels,
121
                                    int zywrle_level,
122
                                    bool *use_rle, bool *use_palette)
123
{
124
    size_t estimated_bytes;
125
    size_t plain_rle_bytes;
126

  
127
    *use_palette = *use_rle = false;
128

  
129
    estimated_bytes = w * h * (bpp_out / 8); /* start assuming raw */
130

  
131
    if (bpp_out != 8) {
132
        if (zywrle_level > 0 && !(zywrle_level & 0x80))
133
            estimated_bytes >>= zywrle_level;
134
    }
135

  
136
    plain_rle_bytes = ((bpp_out / 8) + 1) * (runs + single_pixels);
137

  
138
    if (plain_rle_bytes < estimated_bytes) {
139
        *use_rle = true;
140
        estimated_bytes = plain_rle_bytes;
141
    }
142

  
143
    if (palette_size(palette) < 128) {
144
        int palette_rle_bytes;
145

  
146
        palette_rle_bytes = (bpp_out / 8) * palette_size(palette);
147
        palette_rle_bytes += 2 * runs + single_pixels;
148

  
149
        if (palette_rle_bytes < estimated_bytes) {
150
            *use_rle = true;
151
            *use_palette = true;
152
            estimated_bytes = palette_rle_bytes;
153
        }
154

  
155
        if (palette_size(palette) < 17) {
156
            int packed_bytes;
157

  
158
            packed_bytes = (bpp_out / 8) * palette_size(palette);
159
            packed_bytes += w * h *
160
                bits_per_packed_pixel[palette_size(palette)-1] / 8;
161

  
162
            if (packed_bytes < estimated_bytes) {
163
                *use_rle = false;
164
                *use_palette = true;
165
                estimated_bytes = packed_bytes;
166
            }
167
        }
168
    }
169
}
170

  
171
static void zrle_write_u32(VncState *vs, uint32_t value)
172
{
173
    vnc_write(vs, (uint8_t *)&value, 4);
174
}
175

  
176
static void zrle_write_u24a(VncState *vs, uint32_t value)
177
{
178
    vnc_write(vs, (uint8_t *)&value, 3);
179
}
180

  
181
static void zrle_write_u24b(VncState *vs, uint32_t value)
182
{
183
    vnc_write(vs, ((uint8_t *)&value) + 1, 3);
184
}
185

  
186
static void zrle_write_u16(VncState *vs, uint16_t value)
187
{
188
    vnc_write(vs, (uint8_t *)&value, 2);
189
}
190

  
191
static void zrle_write_u8(VncState *vs, uint8_t value)
192
{
193
    vnc_write_u8(vs, value);
194
}
195

  
196
#define ENDIAN_LITTLE 0
197
#define ENDIAN_BIG    1
198
#define ENDIAN_NO     2
199

  
200
#define ZRLE_BPP 8
201
#define ZYWRLE_ENDIAN ENDIAN_NO
202
#include "vnc-enc-zrle-template.c"
203
#undef ZRLE_BPP
204

  
205
#define ZRLE_BPP 15
206
#undef ZYWRLE_ENDIAN
207
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
208
#include "vnc-enc-zrle-template.c"
209

  
210
#undef ZYWRLE_ENDIAN
211
#define ZYWRLE_ENDIAN ENDIAN_BIG
212
#include "vnc-enc-zrle-template.c"
213

  
214
#undef ZRLE_BPP
215
#define ZRLE_BPP 16
216
#undef ZYWRLE_ENDIAN
217
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
218
#include "vnc-enc-zrle-template.c"
219

  
220
#undef ZYWRLE_ENDIAN
221
#define ZYWRLE_ENDIAN ENDIAN_BIG
222
#include "vnc-enc-zrle-template.c"
223

  
224
#undef ZRLE_BPP
225
#define ZRLE_BPP 32
226
#undef ZYWRLE_ENDIAN
227
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
228
#include "vnc-enc-zrle-template.c"
229

  
230
#undef ZYWRLE_ENDIAN
231
#define ZYWRLE_ENDIAN ENDIAN_BIG
232
#include "vnc-enc-zrle-template.c"
233

  
234
#define ZRLE_COMPACT_PIXEL 24a
235
#undef ZYWRLE_ENDIAN
236
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
237
#include "vnc-enc-zrle-template.c"
238

  
239
#undef ZYWRLE_ENDIAN
240
#define ZYWRLE_ENDIAN ENDIAN_BIG
241
#include "vnc-enc-zrle-template.c"
242

  
243
#undef ZRLE_COMPACT_PIXEL
244
#define ZRLE_COMPACT_PIXEL 24b
245
#undef ZYWRLE_ENDIAN
246
#define ZYWRLE_ENDIAN ENDIAN_LITTLE
247
#include "vnc-enc-zrle-template.c"
248

  
249
#undef ZYWRLE_ENDIAN
250
#define ZYWRLE_ENDIAN ENDIAN_BIG
251
#include "vnc-enc-zrle-template.c"
252
#undef ZRLE_COMPACT_PIXEL
253
#undef ZRLE_BPP
254

  
255
static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
256
                                        int w, int h)
257
{
258
    bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG);
259
    size_t bytes;
260
    int zywrle_level;
261

  
262
    if (vs->zrle.type == VNC_ENCODING_ZYWRLE) {
263
        if (!vs->vd->lossy || vs->tight.quality < 0 || vs->tight.quality == 9) {
264
            zywrle_level = 0;
265
            vs->zrle.type = VNC_ENCODING_ZRLE;
266
        } else if (vs->tight.quality < 3) {
267
            zywrle_level = 3;
268
        } else if (vs->tight.quality < 6) {
269
            zywrle_level = 2;
270
        } else {
271
            zywrle_level = 1;
272
        }
273
    } else {
274
        zywrle_level = 0;
275
    }
276

  
277
    vnc_zrle_start(vs);
278

  
279
    switch(vs->clientds.pf.bytes_per_pixel) {
280
    case 1:
281
        zrle_encode_8ne(vs, x, y, w, h, zywrle_level);
282
        break;
283

  
284
    case 2:
285
        if (vs->clientds.pf.gmax > 0x1F) {
286
            if (be) {
287
                zrle_encode_16be(vs, x, y, w, h, zywrle_level);
288
            } else {
289
                zrle_encode_16le(vs, x, y, w, h, zywrle_level);
290
            }
291
        } else {
292
            if (be) {
293
                zrle_encode_15be(vs, x, y, w, h, zywrle_level);
294
            } else {
295
                zrle_encode_15le(vs, x, y, w, h, zywrle_level);
296
            }
297
        }
298
        break;
299

  
300
    case 4:
301
    {
302
        bool fits_in_ls3bytes;
303
        bool fits_in_ms3bytes;
304

  
305
        fits_in_ls3bytes =
306
            ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) &&
307
             (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) &&
308
             (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24));
309

  
310
        fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 &&
311
                            vs->clientds.pf.gshift > 7 &&
312
                            vs->clientds.pf.bshift > 7);
313

  
314
        if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) {
315
            if (be) {
316
                zrle_encode_24abe(vs, x, y, w, h, zywrle_level);
317
            } else {
318
                zrle_encode_24ale(vs, x, y, w, h, zywrle_level);
319
          }
320
        } else if ((fits_in_ls3bytes && be) || (fits_in_ms3bytes && !be)) {
321
            if (be) {
322
                zrle_encode_24bbe(vs, x, y, w, h, zywrle_level);
323
            } else {
324
                zrle_encode_24ble(vs, x, y, w, h, zywrle_level);
325
            }
326
        } else {
327
            if (be) {
328
                zrle_encode_32be(vs, x, y, w, h, zywrle_level);
329
            } else {
330
                zrle_encode_32le(vs, x, y, w, h, zywrle_level);
331
            }
332
        }
333
    }
334
    break;
335
    }
336

  
337
    vnc_zrle_stop(vs);
338
    bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION);
339
    vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type);
340
    vnc_write_u32(vs, bytes);
341
    vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset);
342
    return 1;
343
}
344

  
345
int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
346
{
347
    vs->zrle.type = VNC_ENCODING_ZRLE;
348
    return zrle_send_framebuffer_update(vs, x, y, w, h);
349
}
350

  
351
int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
352
{
353
    vs->zrle.type = VNC_ENCODING_ZYWRLE;
354
    return zrle_send_framebuffer_update(vs, x, y, w, h);
355
}
356

  
357
void vnc_zrle_clear(VncState *vs)
358
{
359
    if (vs->zrle.stream.opaque) {
360
        deflateEnd(&vs->zrle.stream);
361
    }
362
    buffer_free(&vs->zrle.zrle);
363
    buffer_free(&vs->zrle.fb);
364
    buffer_free(&vs->zrle.zlib);
365
}
b/ui/vnc-enc-zrle.h
1
/*
2
 * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
3
 *
4
 * From libvncserver/libvncserver/zrle.c
5
 * Copyright (C) 2002 RealVNC Ltd.  All Rights Reserved.
6
 * Copyright (C) 2003 Sun Microsystems, Inc.
7
 *
8
 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is
15
 * furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in
18
 * all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
 * THE SOFTWARE.
27
 */
28

  
29
#ifndef VNC_ENCODING_ZRLE_H
30
#define VNC_ENCODING_ZRLE_H
31

  
32
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33
 * ZRLE - encoding combining Zlib compression, tiling, palettisation and
34
 * run-length encoding.
35
 */
36

  
37
#define VNC_ZRLE_TILE_WIDTH  64
38
#define VNC_ZRLE_TILE_HEIGHT 64
39

  
40
#endif
b/ui/vnc-enc-zywrle-template.c
1

  
2
/********************************************************************
3
 *                                                                  *
4
 * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE.         *
5
 *                                                                  *
6
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
7
 * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE.                *
8
 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING.                     *
9
 *                                                                  *
10
 * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006         *
11
 * BY Hitachi Systems & Services, Ltd.                              *
12
 * (Noriaki Yamazaki, Research & Developement Center)               *
13
 *                                                                  *
14
 *                                                                  *
15
 ********************************************************************
16
Redistribution and use in source and binary forms, with or without
17
modification, are permitted provided that the following conditions
18
are met:
19

  
20
- Redistributions of source code must retain the above copyright
21
notice, this list of conditions and the following disclaimer.
22

  
23
- Redistributions in binary form must reproduce the above copyright
24
notice, this list of conditions and the following disclaimer in the
25
documentation and/or other materials provided with the distribution.
26

  
27
- Neither the name of the Hitachi Systems & Services, Ltd. nor
28
the names of its contributors may be used to endorse or promote
29
products derived from this software without specific prior written
30
permission.
31

  
32
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35
A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
36
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
 ********************************************************************/
44

  
45
/* Change Log:
46
     V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline
47
	                     (Thanks Johannes Schindelin, author of LibVNC
48
						  Server/Client)
49
     V0.01 : 2007/02/06 : Initial release
50
*/
51

  
52
/*
53
[References]
54
 PLHarr:
55
   Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy,
56
   "An Improved N-Bit to N-Bit Reversible Haar-Like Transform,"
57
   Pacific Graphics 2004, October 2004, pp. 371-380.
58
 EZW:
59
   Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients,
60
   IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
61
*/
62

  
63

  
64
/* Template Macro stuffs. */
65
#undef ZYWRLE_ANALYZE
66
#undef ZYWRLE_SYNTHESIZE
67

  
68
#define ZYWRLE_SUFFIX     ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
69

  
70
#define ZYWRLE_ANALYZE    ZRLE_CONCAT2(zywrle_analyze_,   ZYWRLE_SUFFIX)
71
#define ZYWRLE_SYNTHESIZE ZRLE_CONCAT2(zywrle_synthesize_,ZYWRLE_SUFFIX)
72

  
73
#define ZYWRLE_RGBYUV     ZRLE_CONCAT2(zywrle_rgbyuv_,    ZYWRLE_SUFFIX)
74
#define ZYWRLE_YUVRGB     ZRLE_CONCAT2(zywrle_yuvrgb_,    ZYWRLE_SUFFIX)
75
#define ZYWRLE_YMASK      ZRLE_CONCAT2(ZYWRLE_YMASK,      ZRLE_BPP)
76
#define ZYWRLE_UVMASK     ZRLE_CONCAT2(ZYWRLE_UVMASK,     ZRLE_BPP)
77
#define ZYWRLE_LOAD_PIXEL ZRLE_CONCAT2(ZYWRLE_LOAD_PIXEL, ZRLE_BPP)
78
#define ZYWRLE_SAVE_PIXEL ZRLE_CONCAT2(ZYWRLE_SAVE_PIXEL, ZRLE_BPP)
79

  
80
/* Packing/Unpacking pixel stuffs.
81
   Endian conversion stuffs. */
82
#undef S_0
83
#undef S_1
84
#undef L_0
85
#undef L_1
86
#undef L_2
87

  
88
#if ZYWRLE_ENDIAN == ENDIAN_BIG
89
#  define S_0	1
90
#  define S_1	0
91
#  define L_0	3
92
#  define L_1	2
93
#  define L_2	1
94
#else
95
#  define S_0	0
96
#  define S_1	1
97
#  define L_0	0
98
#  define L_1	1
99
#  define L_2	2
100
#endif
101

  
102
#define ZYWRLE_QUANTIZE
103
#include "vnc-enc-zywrle.h"
104

  
105
#ifndef ZRLE_COMPACT_PIXEL
106
static inline void ZYWRLE_RGBYUV(int *buf, ZRLE_PIXEL *data,
107
                                 int width, int height, int scanline)
108
{
109
    int r, g, b;
110
    int y, u, v;
111
    int *line;
112
    int *end;
113

  
114
    end = buf + height * width;
115
    while (buf < end) {
116
        line = buf + width;
117
        while (buf < line) {
118
            ZYWRLE_LOAD_PIXEL(data, r, g, b);
119
            ZYWRLE_RGBYUV_(r, g, b, y, u, v, ZYWRLE_YMASK, ZYWRLE_UVMASK);
120
            ZYWRLE_SAVE_COEFF(buf, v, y, u);
121
            buf++;
122
            data++;
123
        }
124
        data += scanline - width;
125
    }
126
}
127

  
128
static ZRLE_PIXEL *ZYWRLE_ANALYZE(ZRLE_PIXEL *dst, ZRLE_PIXEL *src,
129
                                  int w, int h, int scanline, int level,
130
                                  int *buf) {
131
    int l;
132
    int uw = w;
133
    int uh = h;
134
    int *top;
135
    int *end;
136
    int *line;
137
    ZRLE_PIXEL *p;
138
    int r, g, b;
139
    int s;
140
    int *ph;
141

  
142
    zywrle_calc_size(&w, &h, level);
143

  
144
    if (w == 0 || h == 0) {
145
        return NULL;
146
    }
147
    uw -= w;
148
    uh -= h;
149

  
150
    p = dst;
151
    ZYWRLE_LOAD_UNALIGN(src,*(ZRLE_PIXEL*)top = *p;);
152
    ZYWRLE_RGBYUV(buf, src, w, h, scanline);
153
    wavelet(buf, w, h, level);
154
    for (l = 0; l < level; l++) {
155
        ZYWRLE_PACK_COEFF(buf, dst, 3, w, h, scanline, l);
156
        ZYWRLE_PACK_COEFF(buf, dst, 2, w, h, scanline, l);
157
        ZYWRLE_PACK_COEFF(buf, dst, 1, w, h, scanline, l);
158
        if (l == level - 1) {
159
            ZYWRLE_PACK_COEFF(buf, dst, 0, w, h, scanline, l);
160
        }
161
    }
162
    ZYWRLE_SAVE_UNALIGN(dst,*dst = *(ZRLE_PIXEL*)top;);
163
    return dst;
164
}
165
#endif  /* ZRLE_COMPACT_PIXEL */
166

  
167
#undef ZYWRLE_RGBYUV
168
#undef ZYWRLE_YUVRGB
169
#undef ZYWRLE_LOAD_PIXEL
170
#undef ZYWRLE_SAVE_PIXEL
b/ui/vnc-enc-zywrle.h
1
/********************************************************************
2
 *                                                                  *
3
 * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE.         *
4
 *                                                                  *
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.                     *
8
 *                                                                  *
9
 * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006         *
10
 * BY Hitachi Systems & Services, Ltd.                              *
11
 * (Noriaki Yamazaki, Research & Developement Center)               *
12
 *                                                                  *
13
 *                                                                  *
14
 ********************************************************************
15
Redistribution and use in source and binary forms, with or without
16
modification, are permitted provided that the following conditions
17
are met:
18

  
19
- Redistributions of source code must retain the above copyright
20
notice, this list of conditions and the following disclaimer.
21

  
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.
25

  
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
29
permission.
30

  
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
 ********************************************************************/
43

  
44
#ifndef VNC_ENCODING_ZYWRLE_H
45
#define VNC_ENCODING_ZYWRLE_H
46

  
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}, */
57
};
58
#else
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,
94
},
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,
128
},
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,
162
},
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,
196
}
197
};
198

  
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]}},
209
};
210
#endif
211

  
212
/*   Load/Save pixel stuffs. */
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

  
266
static inline void harr(int8_t *px0, int8_t *px1)
267
{
268
    /* Piecewise-Linear Harr(PLHarr) */
269
    int x0 = (int)*px0, x1 = (int)*px1;
270
    int orgx0 = x0, orgx1 = x1;
271

  
272
    if ((x0 ^ x1) & 0x80) {
273
        /* differ sign */
274
        x1 += x0;
275
        if (((x1 ^ orgx1) & 0x80) == 0) {
276
            /* |x1| > |x0| */
277
            x0 -= x1;	/* H = -B */
278
        }
279
    } else {
280
        /* same sign */
281
        x0 -= x1;
282
        if (((x0 ^ orgx0) & 0x80) == 0) {
283
            /* |x0| > |x1| */
284
            x1 += x0;	/* L = A */
285
        }
286
    }
287
    *px0 = (int8_t)x1;
288
    *px1 = (int8_t)x0;
289
}
290

  
291
/*
292
 1D-Wavelet transform.
293

  
294
 In coefficients array, the famous 'pyramid' decomposition is well used.
295

  
296
 1D Model:
297
   |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
298
   |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
299

  
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.
302

  
303
 1D Model:
304
   |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
305
   |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
306

  
307
 In this method, H/L and X0/X1 is always same position.
308
 This lead 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.
311
*/
312
static 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
/* Type A:lower bit omitting of EZW style. */
336
static 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
                  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.
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
 Type B:Non liner quantization filter.
383

  
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.
388

  
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 )
392

  
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.
396

  
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) ).
400

  
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.
405

  
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.
411
*/
412
static 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

  
444
static 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
/* Load/Save coefficients stuffs.
471
 Coefficients manages as 24 bits little-endian pixel. */
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
  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)
492

  
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)
498
*/
499

  
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)          \
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
 coefficient packing/unpacking stuffs.
528
 Wavelet transform makes 4 sub coefficient image from 1 original image.
529

  
530
 model with pyramid decomposition:
531
   +------+------+
532
   |      |      |
533
   |  L   |  Hx  |
534
   |      |      |
535
   +------+------+
536
   |      |      |
537
   |  H   |  Hxy |
538
   |      |      |
539
   +------+------+
540

  
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.)
546

  
547
   +------+------+
548
   |      L      |
549
   +------+------+
550
   |      Hx     |
551
   +------+------+
552
   |      Hy     |
553
   +------+------+
554
   |      Hxy    |
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++;                                       \
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff