Annotation of qemu/ui/vnc-enc-zywrle.h, revision 1.1.1.2

1.1       root        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.                              *
1.1.1.2 ! root       11:  * (Noriaki Yamazaki, Research & Development Center)               *
1.1       root       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++;                                       \
                    606:         }                                                    \
                    607:     } while (0)
                    608: 
                    609: #define ZYWRLE_LOAD_UNALIGN(data,TRANS)                                 \
                    610:     do {                                                                \
                    611:         top = buf + w * h;                                              \
                    612:         if (uw) {                                                       \
                    613:             p = data + w;                                               \
                    614:             end = (int*)(p + h * scanline);                             \
                    615:             while (p < (ZRLE_PIXEL*)end) {                              \
                    616:                 line = (int*)(p + uw);                                  \
                    617:                 while (p < (ZRLE_PIXEL*)line) {                         \
                    618:                     TRANS                                               \
                    619:                         p++;                                            \
                    620:                     top++;                                              \
                    621:                 }                                                       \
                    622:                 p += scanline - uw;                                     \
                    623:             }                                                           \
                    624:         }                                                               \
                    625:         if (uh) {                                                       \
                    626:             p = data + h * scanline;                                    \
                    627:             end = (int*)(p + uh * scanline);                            \
                    628:             while (p < (ZRLE_PIXEL*)end) {                              \
                    629:                 line = (int*)(p + w);                                   \
                    630:                 while (p < (ZRLE_PIXEL*)line) {                         \
                    631:                     TRANS                                               \
                    632:                         p++;                                            \
                    633:                     top++;                                              \
                    634:                 }                                                       \
                    635:                 p += scanline - w;                                      \
                    636:             }                                                           \
                    637:         }                                                               \
                    638:         if (uw && uh) {                                                 \
                    639:             p= data + w + h * scanline;                                 \
                    640:             end = (int*)(p + uh * scanline);                            \
                    641:             while (p < (ZRLE_PIXEL*)end) {                              \
                    642:                 line = (int*)(p + uw);                                  \
                    643:                 while (p < (ZRLE_PIXEL*)line) {                         \
                    644:                     TRANS                                               \
                    645:                         p++;                                            \
                    646:                     top++;                                              \
                    647:                 }                                                       \
                    648:                 p += scanline-uw;                                       \
                    649:             }                                                           \
                    650:         }                                                               \
                    651:     } while (0)
                    652: 
                    653: static inline void zywrle_calc_size(int *w, int *h, int level)
                    654: {
                    655:     *w &= ~((1 << level) - 1);
                    656:     *h &= ~((1 << level) - 1);
                    657: }
                    658: 
                    659: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.