LCOV - code coverage report
Current view: top level - common - quic.c (source / functions) Hit Total Coverage
Test: out.info Lines: 481 551 87.3 %
Date: 2022-01-27 10:43:00 Functions: 40 40 100.0 %

          Line data    Source code
       1             : /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
       2             : /*
       3             :    Copyright (C) 2009 Red Hat, Inc.
       4             : 
       5             :    This library is free software; you can redistribute it and/or
       6             :    modify it under the terms of the GNU Lesser General Public
       7             :    License as published by the Free Software Foundation; either
       8             :    version 2.1 of the License, or (at your option) any later version.
       9             : 
      10             :    This library is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :    Lesser General Public License for more details.
      14             : 
      15             :    You should have received a copy of the GNU Lesser General Public
      16             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : 
      19             : // Red Hat image compression based on SFALIC by Roman Starosolski
      20             : // http://sun.iinf.polsl.gliwice.pl/~rstaros/sfalic/index.html
      21             : 
      22             : #include <config.h>
      23             : 
      24             : #include "quic_config.h"
      25             : #include "quic.h"
      26             : #include "log.h"
      27             : 
      28             : /* ASCII "QUIC" */
      29             : #define QUIC_MAGIC 0x43495551
      30             : #define QUIC_VERSION_MAJOR 0U
      31             : #define QUIC_VERSION_MINOR 0U
      32             : #define QUIC_VERSION ((QUIC_VERSION_MAJOR << 16) | (QUIC_VERSION_MINOR & 0xffff))
      33             : 
      34             : typedef uint8_t BYTE;
      35             : 
      36             : /* maximum number of codes in family */
      37             : #define MAXNUMCODES 8
      38             : 
      39             : /* model evolution, warning: only 1,3 and 5 allowed */
      40             : #define DEFevol 3
      41             : #define MINevol 0
      42             : #define MAXevol 5
      43             : 
      44             : /* starting wait mask index */
      45             : #define DEFwmistart 0
      46             : #define MINwmistart 0
      47             : 
      48             : /* codeword length limit */
      49             : #define DEFmaxclen 26
      50             : 
      51             : /* target wait mask index */
      52             : #define DEFwmimax 6
      53             : 
      54             : /* number of symbols to encode before increasing wait mask index */
      55             : #define DEFwminext 2048
      56             : #define MINwminext 1
      57             : #define MAXwminext 100000000
      58             : 
      59             : /* Maximum image size in pixels, mainly to avoid possible integer overflows */
      60             : #define SPICE_MAX_IMAGE_SIZE (512 * 1024 * 1024 - 1)
      61             : 
      62             : typedef struct QuicFamily {
      63             :     unsigned int nGRcodewords[MAXNUMCODES];      /* indexed by code number, contains number of
      64             :                                                     unmodified GR codewords in the code */
      65             :     unsigned int notGRcwlen[MAXNUMCODES];        /* indexed by code number, contains codeword
      66             :                                                     length of the not-GR codeword */
      67             :     unsigned int notGRprefixmask[MAXNUMCODES];   /* indexed by code number, contains mask to
      68             :                                                     determine if the codeword is GR or not-GR */
      69             :     unsigned int notGRsuffixlen[MAXNUMCODES];    /* indexed by code number, contains suffix
      70             :                                                     length of the not-GR codeword */
      71             : 
      72             :     unsigned int golomb_code_len[256][MAXNUMCODES];
      73             :     unsigned int golomb_code[256][MAXNUMCODES];
      74             : 
      75             :     /* array for translating distribution U to L for depths up to 8 bpp,
      76             :     initialized by decorrelate_init() */
      77             :     BYTE xlatU2L[256];
      78             : 
      79             :     /* array for translating distribution L to U for depths up to 8 bpp,
      80             :        initialized by correlate_init() */
      81             :     unsigned int xlatL2U[256];
      82             : } QuicFamily;
      83             : 
      84             : static QuicFamily family_8bpc;
      85             : static QuicFamily family_5bpc;
      86             : 
      87             : typedef unsigned COUNTER;   /* counter in the array of counters in bucket of the data model */
      88             : 
      89             : typedef struct s_bucket {
      90             :     COUNTER *pcounters;     /* pointer to array of counters */
      91             :     unsigned int bestcode;  /* best code so far */
      92             : } s_bucket;
      93             : 
      94             : typedef struct Encoder Encoder;
      95             : 
      96             : static inline void encode(Encoder *encoder, unsigned int word, unsigned int len);
      97             : 
      98             : typedef struct CommonState {
      99             :     unsigned int waitcnt;
     100             :     unsigned int tabrand_seed;
     101             :     unsigned int wm_trigger;
     102             :     unsigned int wmidx;
     103             :     unsigned int wmileft;
     104             : 
     105             :     int melcstate; /* index to the state array */
     106             : 
     107             :     int melclen;  /* contents of the state array location
     108             :                      indexed by melcstate: the "expected"
     109             :                      run length is 2^melclen, shorter runs are
     110             :                      encoded by a 1 followed by the run length
     111             :                      in binary representation, wit a fixed length
     112             :                      of melclen bits */
     113             : 
     114             :     unsigned long melcorder;  /* 2^ melclen */
     115             : } CommonState;
     116             : 
     117             : 
     118             : #define MAX_CHANNELS 4
     119             : 
     120             : typedef struct FamilyStat {
     121             :     s_bucket **buckets_ptrs;
     122             :     s_bucket *buckets_buf;
     123             :     COUNTER *counters;
     124             : } FamilyStat;
     125             : 
     126             : typedef struct Channel {
     127             :     int correlate_row_width;
     128             :     BYTE *correlate_row;
     129             : 
     130             :     s_bucket **_buckets_ptrs;
     131             : 
     132             :     FamilyStat family_stat_8bpc;
     133             :     FamilyStat family_stat_5bpc;
     134             : 
     135             :     CommonState state;
     136             : } Channel;
     137             : 
     138             : struct Encoder {
     139             :     QuicUsrContext *usr;
     140             :     QuicImageType type;
     141             :     unsigned int width;
     142             :     unsigned int height;
     143             : 
     144             :     unsigned int n_buckets_8bpc;
     145             :     unsigned int n_buckets_5bpc;
     146             : 
     147             :     unsigned int io_available_bits;
     148             :     uint32_t io_word;
     149             :     uint32_t io_next_word;
     150             :     uint32_t *io_now;
     151             :     uint32_t *io_end;
     152             :     uint32_t io_words_count;
     153             : 
     154             :     int rows_completed;
     155             : 
     156             :     Channel channels[MAX_CHANNELS];
     157             : 
     158             :     CommonState rgb_state;
     159             : };
     160             : 
     161             : /* bppmask[i] contains i ones as lsb-s */
     162             : static const unsigned int bppmask[33] = {
     163             :     0x00000000, /* [0] */
     164             :     0x00000001, 0x00000003, 0x00000007, 0x0000000f,
     165             :     0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
     166             :     0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
     167             :     0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
     168             :     0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
     169             :     0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
     170             :     0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
     171             :     0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff /* [32] */
     172             : };
     173             : 
     174             : #define bitat(n) (1u<<(n))
     175             : 
     176             : 
     177             : #define TABRAND_TABSIZE 256
     178             : #define TABRAND_SEEDMASK 0x0ff
     179             : 
     180             : static const unsigned int tabrand_chaos[TABRAND_TABSIZE] = {
     181             :     0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
     182             :     0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
     183             :     0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
     184             :     0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
     185             :     0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
     186             :     0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
     187             :     0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
     188             :     0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
     189             :     0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
     190             :     0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
     191             :     0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
     192             :     0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
     193             :     0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
     194             :     0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
     195             :     0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
     196             :     0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
     197             :     0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
     198             :     0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
     199             :     0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
     200             :     0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
     201             :     0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
     202             :     0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
     203             :     0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
     204             :     0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
     205             :     0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
     206             :     0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
     207             :     0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
     208             :     0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
     209             :     0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
     210             :     0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
     211             :     0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
     212             :     0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5,
     213             : };
     214             : 
     215          60 : static unsigned int stabrand(void)
     216             : {
     217             :     SPICE_VERIFY( !(TABRAND_SEEDMASK & TABRAND_TABSIZE));
     218             :     SPICE_VERIFY( TABRAND_SEEDMASK + 1 == TABRAND_TABSIZE );
     219             : 
     220          60 :     return TABRAND_SEEDMASK;
     221             : }
     222             : 
     223      113046 : static unsigned int tabrand(unsigned int *tabrand_seed)
     224             : {
     225      113046 :     return tabrand_chaos[++*tabrand_seed & TABRAND_SEEDMASK];
     226             : }
     227             : 
     228             : static const unsigned short besttrigtab[3][11] = { /* array of wm_trigger for waitmask and DEFevol,
     229             :                                                     used by set_wm_trigger() */
     230             :     /* 1 */ { 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160},
     231             :     /* 3 */ { 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140},
     232             :     /* 5 */ { 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160}
     233             : };
     234             : 
     235             : /* set wm_trigger knowing waitmask (param) and DEFevol (glob)*/
     236         180 : static void set_wm_trigger(CommonState *state)
     237             : {
     238         180 :     unsigned int wm = state->wmidx;
     239         180 :     if (wm > 10) {
     240           0 :         wm = 10;
     241             :     }
     242             : 
     243             :     SPICE_VERIFY(DEFevol < 6);
     244             : 
     245         180 :     state->wm_trigger = besttrigtab[DEFevol / 2][wm];
     246             : 
     247         180 :     spice_assert(state->wm_trigger <= 2000);
     248         180 :     spice_assert(state->wm_trigger >= 1);
     249         180 : }
     250             : 
     251          13 : static int ceil_log_2(int val) /* ceil(log_2(val)) */
     252             : {
     253             :     int result;
     254             : 
     255             :     //spice_assert(val>0);
     256             : 
     257          13 :     if (val == 1) {
     258           0 :         return 0;
     259             :     }
     260             : 
     261          13 :     result = 1;
     262          13 :     val -= 1;
     263          67 :     while (val >>= 1) {
     264          54 :         result++;
     265             :     }
     266             : 
     267          13 :     return result;
     268             : }
     269             : 
     270             : /* number of leading zeroes in the byte, used by cntlzeroes(uint)*/
     271             : static const BYTE lzeroes[256] = {
     272             :     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     273             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     274             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     275             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     276             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     277             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     278             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     279             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     280             : };
     281             : 
     282             : /* count leading zeroes */
     283     1316477 : static unsigned int cnt_l_zeroes(const unsigned int bits)
     284             : {
     285     1316477 :     spice_extra_assert(bits != 0);
     286             : #if defined(__GNUC__) && __GNUC__ >= 4
     287     1316477 :     return __builtin_clz(bits);
     288             : #else
     289             :     if (bits & 0xff800000) {
     290             :         return lzeroes[bits >> 24];
     291             :     } else if (bits & 0xffff8000) {
     292             :         return 8 + lzeroes[(bits >> 16) & 0x000000ff];
     293             :     } else if (bits & 0xffffff80) {
     294             :         return 16 + lzeroes[(bits >> 8) & 0x000000ff];
     295             :     } else {
     296             :         return 24 + lzeroes[bits & 0x000000ff];
     297             :     }
     298             : #endif
     299             : }
     300             : 
     301             : #define QUIC_FAMILY_8BPC
     302             : #include "quic_family_tmpl.c"
     303             : 
     304             : #define QUIC_FAMILY_5BPC
     305             : #include "quic_family_tmpl.c"
     306             : 
     307           2 : static void decorrelate_init(QuicFamily *family, int bpc)
     308             : {
     309           2 :     const unsigned int pixelbitmask = bppmask[bpc];
     310           2 :     const unsigned int pixelbitmaskshr = pixelbitmask >> 1;
     311             :     unsigned int s;
     312             : 
     313             :     //spice_assert(bpc <= 8);
     314             : 
     315         290 :     for (s = 0; s <= pixelbitmask; s++) {
     316         288 :         if (s <= pixelbitmaskshr) {
     317         144 :             family->xlatU2L[s] = s << 1;
     318             :         } else {
     319         144 :             family->xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
     320             :         }
     321             :     }
     322           2 : }
     323             : 
     324           2 : static void correlate_init(QuicFamily *family, int bpc)
     325             : {
     326           2 :     const unsigned int pixelbitmask = bppmask[bpc];
     327             :     unsigned long int s;
     328             : 
     329             :     //spice_assert(bpc <= 8);
     330             : 
     331         290 :     for (s = 0; s <= pixelbitmask; s++) {
     332         288 :         if (s & 0x01) {
     333         144 :             family->xlatL2U[s] = pixelbitmask - (s >> 1);
     334             :         } else {
     335         144 :             family->xlatL2U[s] = (s >> 1);
     336             :         }
     337             :     }
     338           2 : }
     339             : 
     340        3328 : static void golomb_coding_slow(const QuicFamily *family, const BYTE n, const unsigned int l,
     341             :                                unsigned int * const codeword,
     342             :                                unsigned int * const codewordlen)
     343             : {
     344        3328 :     if (n < family->nGRcodewords[l]) {
     345        1173 :         (*codeword) = bitat(l) | (n & bppmask[l]);
     346        1173 :         (*codewordlen) = (n >> l) + l + 1;
     347             :     } else {
     348        2155 :         (*codeword) = n - family->nGRcodewords[l];
     349        2155 :         (*codewordlen) = family->notGRcwlen[l];
     350             :     }
     351        3328 : }
     352             : 
     353           2 : static void family_init(QuicFamily *family, int bpc, int limit)
     354             : {
     355             :     int l, b;
     356             : 
     357          15 :     for (l = 0; l < bpc; l++) { /* fill arrays indexed by code number */
     358             :         int altprefixlen, altcodewords;
     359             : 
     360          13 :         altprefixlen = limit - bpc;
     361          13 :         if (altprefixlen > (int)(bppmask[bpc - l])) {
     362           8 :             altprefixlen = bppmask[bpc - l];
     363             :         }
     364             : 
     365          13 :         altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
     366             : 
     367          13 :         family->nGRcodewords[l] = (altprefixlen << l);
     368          13 :         family->notGRsuffixlen[l] = ceil_log_2(altcodewords); /* needed for decoding only */
     369          13 :         family->notGRcwlen[l] = altprefixlen + family->notGRsuffixlen[l];
     370          13 :         family->notGRprefixmask[l] = bppmask[32 - altprefixlen]; /* needed for decoding only */
     371             : 
     372        3341 :         for (b = 0; b < 256; b++) {
     373             :             unsigned int code, len;
     374        3328 :             golomb_coding_slow(family, b, l, &code, &len);
     375        3328 :             family->golomb_code[b][l] = code;
     376        3328 :             family->golomb_code_len[b][l] = len;
     377             :         }
     378             :     }
     379             : 
     380           2 :     decorrelate_init(family, bpc);
     381           2 :     correlate_init(family, bpc);
     382           2 : }
     383             : 
     384          38 : static void more_io_words(Encoder *encoder)
     385             : {
     386             :     uint32_t *io_ptr;
     387          38 :     int num_io_words = encoder->usr->more_space(encoder->usr, &io_ptr, encoder->rows_completed);
     388          38 :     if (num_io_words <= 0) {
     389           0 :         encoder->usr->error(encoder->usr, "%s: no more words\n", __FUNCTION__);
     390             :     }
     391          38 :     spice_assert(io_ptr);
     392          38 :     encoder->io_words_count += num_io_words;
     393          38 :     encoder->io_now = io_ptr;
     394          38 :     encoder->io_end = encoder->io_now + num_io_words;
     395          38 : }
     396             : 
     397      621739 : static inline void write_io_word(Encoder *encoder)
     398             : {
     399      621739 :     if (G_UNLIKELY(encoder->io_now == encoder->io_end)) {
     400          38 :         more_io_words(encoder);
     401             :     }
     402      621739 :     *(encoder->io_now++) = GUINT32_TO_LE(encoder->io_word);
     403      621739 : }
     404             : 
     405     2571339 : static inline void encode(Encoder *encoder, unsigned int word, unsigned int len)
     406             : {
     407             :     int delta;
     408             : 
     409     2571339 :     spice_extra_assert(len > 0 && len < 32);
     410     2571339 :     spice_extra_assert(!(word & ~bppmask[len]));
     411             : 
     412     2571339 :     if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
     413     1949600 :         encoder->io_available_bits = delta;
     414     1949600 :         encoder->io_word |= word << encoder->io_available_bits;
     415     1949600 :         return;
     416             :     }
     417      621739 :     delta = -delta;
     418      621739 :     encoder->io_word |= word >> delta;
     419      621739 :     write_io_word(encoder);
     420      621739 :     encoder->io_available_bits = 32 - delta;
     421      621739 :     encoder->io_word = word << encoder->io_available_bits;
     422             : 
     423      621739 :     spice_extra_assert(encoder->io_available_bits < 32);
     424      621739 :     spice_extra_assert((encoder->io_word & bppmask[encoder->io_available_bits]) == 0);
     425             : }
     426             : 
     427          48 : static inline void encode_32(Encoder *encoder, unsigned int word)
     428             : {
     429          48 :     encode(encoder, word >> 16, 16);
     430          48 :     encode(encoder, word & 0x0000ffff, 16);
     431          48 : }
     432             : 
     433           8 : static inline void flush(Encoder *encoder)
     434             : {
     435           8 :     if (encoder->io_available_bits > 0 && encoder->io_available_bits != 32) {
     436           8 :         encode(encoder, 0, encoder->io_available_bits);
     437             :     }
     438           8 :     encode_32(encoder, 0);
     439           8 :     encode(encoder, 0, 1);
     440           8 : }
     441             : 
     442      621731 : static inline void read_io_word(Encoder *encoder)
     443             : {
     444      621731 :     if (G_UNLIKELY(encoder->io_now == encoder->io_end)) {
     445           0 :         more_io_words(encoder);
     446             :     }
     447      621731 :     spice_extra_assert(encoder->io_now < encoder->io_end);
     448             : 
     449      621731 :     encoder->io_next_word = GUINT32_FROM_LE(*(encoder->io_now));
     450      621731 :     encoder->io_now++;
     451      621731 : }
     452             : 
     453     2571346 : static inline void decode_eatbits(Encoder *encoder, int len)
     454             : {
     455             :     int delta;
     456             : 
     457     2571346 :     spice_extra_assert(len > 0 && len < 32);
     458     2571346 :     encoder->io_word <<= len;
     459             : 
     460     2571346 :     if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
     461     1949615 :         encoder->io_available_bits = delta;
     462     1949615 :         encoder->io_word |= encoder->io_next_word >> encoder->io_available_bits;
     463     1949615 :         return;
     464             :     }
     465             : 
     466      621731 :     delta = -delta;
     467      621731 :     encoder->io_word |= encoder->io_next_word << delta;
     468      621731 :     read_io_word(encoder);
     469      621731 :     encoder->io_available_bits = 32 - delta;
     470      621731 :     encoder->io_word |= (encoder->io_next_word >> encoder->io_available_bits);
     471             : }
     472             : 
     473          40 : static inline void decode_eat32bits(Encoder *encoder)
     474             : {
     475          40 :     decode_eatbits(encoder, 16);
     476          40 :     decode_eatbits(encoder, 16);
     477          40 : }
     478             : 
     479        1158 : static inline void encode_ones(Encoder *encoder, unsigned int n)
     480             : {
     481             :     unsigned int count;
     482             : 
     483        1158 :     for (count = n >> 5; count; count--) {
     484           0 :         encode_32(encoder, ~0U);
     485             :     }
     486             : 
     487        1158 :     if ((n &= 0x1f)) {
     488        1129 :         encode(encoder, (1U << n) - 1, n);
     489             :     }
     490        1158 : }
     491             : 
     492             : #define MELCSTATES 32 /* number of melcode states */
     493             : 
     494             : static const int J[MELCSTATES] = {
     495             :     0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
     496             :     7, 8, 9, 10, 11, 12, 13, 14, 15
     497             : };
     498             : 
     499          60 : static void encoder_init_rle(CommonState *state)
     500             : {
     501          60 :     state->melcstate = 0;
     502          60 :     state->melclen = J[0];
     503          60 :     state->melcorder = 1 << state->melclen;
     504          60 : }
     505             : 
     506             : 
     507        1158 : static void encode_state_run(Encoder *encoder, CommonState *state, unsigned int runlen)
     508             : {
     509        1158 :     int hits = 0;
     510             : 
     511        2434 :     while (runlen >= state->melcorder) {
     512        1276 :         hits++;
     513        1276 :         runlen -= state->melcorder;
     514        1276 :         if (state->melcstate < MELCSTATES - 1) {
     515        1276 :             state->melclen = J[++state->melcstate];
     516        1276 :             state->melcorder = (1L << state->melclen);
     517             :         }
     518             :     }
     519             : 
     520             :     /* send the required number of "hit" bits (one per occurrence
     521             :        of a run of length melcorder). This number is never too big:
     522             :        after 31 such "hit" bits, each "hit" would represent a run of 32K
     523             :        pixels.
     524             :     */
     525        1158 :     encode_ones(encoder, hits);
     526             : 
     527        1158 :     encode(encoder, runlen, state->melclen + 1);
     528             : 
     529             :     /* adjust melcoder parameters */
     530        1158 :     if (state->melcstate) {
     531        1156 :         state->melclen = J[--state->melcstate];
     532        1156 :         state->melcorder = (1L << state->melclen);
     533             :     }
     534        1158 : }
     535             : 
     536             : 
     537             : /* decoding routine: reads bits from the input and returns a run length. */
     538             : /* argument is the number of pixels left to end-of-line (bound on run length) */
     539             : 
     540        1158 : static int decode_state_run(Encoder *encoder, CommonState *state)
     541             : {
     542        1158 :     int runlen = 0;
     543             : 
     544          12 :     do {
     545             :         register int temp, hits;
     546        1170 :         temp = lzeroes[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
     547             :                                                                       input stream, up to 8 */
     548        2446 :         for (hits = 1; hits <= temp; hits++) {
     549        1276 :             runlen += state->melcorder;
     550             : 
     551        1276 :             if (state->melcstate < MELCSTATES - 1) {
     552        1276 :                 state->melclen = J[++state->melcstate];
     553        1276 :                 state->melcorder = (1U << state->melclen);
     554             :             }
     555             :         }
     556        1170 :         if (temp != 8) {
     557        1158 :             decode_eatbits(encoder, temp + 1);  /* consume the leading
     558             :                                                             0 of the remainder encoding */
     559        1158 :             break;
     560             :         }
     561          12 :         decode_eatbits(encoder, 8);
     562             :     } while (1);
     563             : 
     564             :     /* read the length of the remainder */
     565        1158 :     if (state->melclen) {
     566        1156 :         runlen += encoder->io_word >> (32 - state->melclen);
     567        1156 :         decode_eatbits(encoder, state->melclen);
     568             :     }
     569             : 
     570             :     /* adjust melcorder parameters */
     571        1158 :     if (state->melcstate) {
     572        1156 :         state->melclen = J[--state->melcstate];
     573        1156 :         state->melcorder = (1U << state->melclen);
     574             :     }
     575             : 
     576        1158 :     return runlen;
     577             : }
     578             : 
     579           8 : static inline void init_decode_io(Encoder *encoder)
     580             : {
     581           8 :     encoder->io_next_word = encoder->io_word = GUINT32_FROM_LE(*(encoder->io_now));
     582           8 :     encoder->io_now++;
     583           8 :     encoder->io_available_bits = 0;
     584           8 : }
     585             : 
     586             : #include <spice/start-packed.h>
     587             : 
     588             : typedef struct SPICE_ATTR_PACKED one_byte_pixel_t {
     589             :     BYTE a;
     590             : } one_byte_t;
     591             : 
     592             : typedef struct SPICE_ATTR_PACKED four_bytes_pixel_t {
     593             :     BYTE a;
     594             :     BYTE b;
     595             :     BYTE c;
     596             :     BYTE d;
     597             : } four_bytes_t;
     598             : 
     599             : typedef struct SPICE_ATTR_PACKED rgb32_pixel_t {
     600             :     BYTE b;
     601             :     BYTE g;
     602             :     BYTE r;
     603             :     BYTE pad;
     604             : } rgb32_pixel_t;
     605             : 
     606             : typedef struct SPICE_ATTR_PACKED rgb24_pixel_t {
     607             :     BYTE b;
     608             :     BYTE g;
     609             :     BYTE r;
     610             : } rgb24_pixel_t;
     611             : 
     612             : typedef uint16_t rgb16_pixel_t;
     613             : 
     614             : #include <spice/end-packed.h>
     615             : 
     616             : #define ONE_BYTE
     617             : #include "quic_tmpl.c"
     618             : 
     619             : #define FOUR_BYTE
     620             : #include "quic_tmpl.c"
     621             : 
     622             : #define QUIC_RGB32
     623             : #include "quic_tmpl.c"
     624             : 
     625             : #define QUIC_RGB24
     626             : #include "quic_tmpl.c"
     627             : 
     628             : #define QUIC_RGB16
     629             : #include "quic_tmpl.c"
     630             : 
     631             : #define QUIC_RGB16_TO_32
     632             : #include "quic_tmpl.c"
     633             : 
     634         128 : static void fill_model_structures(SPICE_GNUC_UNUSED Encoder *encoder, FamilyStat *family_stat,
     635             :                                   unsigned int rep_first, unsigned int first_size,
     636             :                                   unsigned int rep_next, unsigned int mul_size,
     637             :                                   unsigned int levels, unsigned int ncounters,
     638             :                                   unsigned int nbuckets, unsigned int n_buckets_ptrs)
     639             : {
     640             :     unsigned int
     641             :     bsize,
     642             :     bstart,
     643         128 :     bend = 0,
     644             :     repcntr,
     645             :     bnumber;
     646             : 
     647         128 :     COUNTER * free_counter = family_stat->counters;/* first free location in the array of
     648             :                                                       counters */
     649             : 
     650         128 :     bnumber = 0;
     651             : 
     652         128 :     repcntr = rep_first + 1;    /* first bucket */
     653         128 :     bsize = first_size;
     654             : 
     655             :     do { /* others */
     656         832 :         if (bnumber) {
     657         704 :             bstart = bend + 1;
     658             :         } else {
     659         128 :             bstart = 0;
     660             :         }
     661             : 
     662         832 :         if (!--repcntr) {
     663         704 :             repcntr = rep_next;
     664         704 :             bsize *= mul_size;
     665             :         }
     666             : 
     667         832 :         bend = bstart + bsize - 1;
     668         832 :         if (bend + bsize >= levels) {
     669         128 :             bend = levels - 1;
     670             :         }
     671             : 
     672         832 :         family_stat->buckets_buf[bnumber].pcounters = free_counter;
     673         832 :         free_counter += ncounters;
     674             : 
     675         832 :         spice_assert(bstart < n_buckets_ptrs);
     676             :         {
     677             :             unsigned int i;
     678         832 :             spice_assert(bend < n_buckets_ptrs);
     679       19264 :             for (i = bstart; i <= bend; i++) {
     680       18432 :                 family_stat->buckets_ptrs[i] = family_stat->buckets_buf + bnumber;
     681             :             }
     682             :         }
     683             : 
     684         832 :         bnumber++;
     685         832 :     } while (bend < levels - 1);
     686             : 
     687         128 :     spice_assert(free_counter - family_stat->counters == (ptrdiff_t)(nbuckets * ncounters));
     688         128 : }
     689             : 
     690         128 : static void find_model_params(Encoder *encoder,
     691             :                               const int bpc,
     692             :                               unsigned int *ncounters,
     693             :                               unsigned int *levels,
     694             :                               unsigned int *n_buckets_ptrs,
     695             :                               unsigned int *repfirst,
     696             :                               unsigned int *firstsize,
     697             :                               unsigned int *repnext,
     698             :                               unsigned int *mulsize,
     699             :                               unsigned int *nbuckets)
     700             : {
     701             :     unsigned int bsize;              /* bucket size */
     702         128 :     unsigned int bstart, bend = 0;   /* bucket start and end, range : 0 to levels-1*/
     703             :     unsigned int repcntr;            /* helper */
     704             : 
     705             :     /* The only valid values are 1, 3 and 5.
     706             :        0, 2 and 4 are obsolete and the rest of the
     707             :        values are considered out of the range. */
     708             :     SPICE_VERIFY(DEFevol == 1 || DEFevol == 3 || DEFevol == 5);
     709         128 :     spice_assert(bpc <= 8 && bpc > 0);
     710             : 
     711         128 :     *ncounters = 8;
     712             : 
     713         128 :     *levels = 0x1 << bpc;
     714             : 
     715         128 :     *n_buckets_ptrs = 0;  /* ==0 means: not set yet */
     716             : 
     717             :     switch (DEFevol) {   /* set repfirst firstsize repnext mulsize */
     718             :     case 1: /* buckets contain following numbers of contexts: 1 1 1 2 2 4 4 8 8 ... */
     719             :         *repfirst = 3;
     720             :         *firstsize = 1;
     721             :         *repnext = 2;
     722             :         *mulsize = 2;
     723             :         break;
     724             :     case 3: /* 1 2 4 8 16 32 64 ... */
     725         128 :         *repfirst = 1;
     726         128 :         *firstsize = 1;
     727         128 :         *repnext = 1;
     728         128 :         *mulsize = 2;
     729         128 :         break;
     730             :     case 5:                     /* 1 4 16 64 256 1024 4096 16384 65536 */
     731             :         *repfirst = 1;
     732             :         *firstsize = 1;
     733             :         *repnext = 1;
     734             :         *mulsize = 4;
     735             :         break;
     736             :     default:
     737             :         encoder->usr->error(encoder->usr, "findmodelparams(): DEFevol out of range!!!\n");
     738             :         return;
     739             :     }
     740             : 
     741         128 :     *nbuckets = 0;
     742         128 :     repcntr = *repfirst + 1;    /* first bucket */
     743         128 :     bsize = *firstsize;
     744             : 
     745             :     do { /* other buckets */
     746         832 :         if (*nbuckets) {         /* bucket start */
     747         704 :             bstart = bend + 1;
     748             :         } else {
     749         128 :             bstart = 0;
     750             :         }
     751             : 
     752         832 :         if (!--repcntr) {         /* bucket size */
     753         704 :             repcntr = *repnext;
     754         704 :             bsize *= *mulsize;
     755             :         }
     756             : 
     757         832 :         bend = bstart + bsize - 1;  /* bucket end */
     758         832 :         if (bend + bsize >= *levels) {  /* if following bucked was bigger than current one */
     759         128 :             bend = *levels - 1;     /* concatenate them */
     760             :         }
     761             : 
     762         832 :         if (!*n_buckets_ptrs) {           /* array size not set yet? */
     763         128 :             *n_buckets_ptrs = *levels;
     764             :  #if 0
     765             :             if (bend == *levels - 1) {   /* this bucket is last - all in the first array */
     766             :                 *n_buckets_ptrs = *levels;
     767             :             } else if (bsize >= 256) { /* this bucket is allowed to reside in the 2nd table */
     768             :                 b_lo_ptrs = bstart;
     769             :                 spice_assert(bstart);     /* previous bucket exists */
     770             :             }
     771             :  #endif
     772             :         }
     773             : 
     774         832 :         (*nbuckets)++;
     775         832 :     } while (bend < *levels - 1);
     776             : }
     777             : 
     778         128 : static int init_model_structures(Encoder *encoder, FamilyStat *family_stat,
     779             :                                  unsigned int rep_first, unsigned int first_size,
     780             :                                  unsigned int rep_next, unsigned int mul_size,
     781             :                                  unsigned int levels, unsigned int ncounters,
     782             :                                  unsigned int n_buckets_ptrs, unsigned int n_buckets)
     783             : {
     784         256 :     family_stat->buckets_ptrs = (s_bucket **)encoder->usr->malloc(encoder->usr,
     785         128 :                                                                   n_buckets_ptrs *
     786             :                                                                   sizeof(s_bucket *));
     787         128 :     if (!family_stat->buckets_ptrs) {
     788           0 :         return FALSE;
     789             :     }
     790             : 
     791         256 :     family_stat->counters = (COUNTER *)encoder->usr->malloc(encoder->usr,
     792         128 :                                                             n_buckets * sizeof(COUNTER) *
     793             :                                                             MAXNUMCODES);
     794         128 :     if (!family_stat->counters) {
     795           0 :         goto error_1;
     796             :     }
     797             : 
     798         256 :     family_stat->buckets_buf = (s_bucket *)encoder->usr->malloc(encoder->usr,
     799         128 :                                                                 n_buckets * sizeof(s_bucket));
     800         128 :     if (!family_stat->buckets_buf) {
     801           0 :         goto error_2;
     802             :     }
     803             : 
     804         128 :     fill_model_structures(encoder, family_stat, rep_first, first_size, rep_next, mul_size, levels,
     805             :                           ncounters, n_buckets, n_buckets_ptrs);
     806             : 
     807         128 :     return TRUE;
     808             : 
     809           0 : error_2:
     810           0 :     encoder->usr->free(encoder->usr, family_stat->counters);
     811             : 
     812           0 : error_1:
     813           0 :     encoder->usr->free(encoder->usr, family_stat->buckets_ptrs);
     814             : 
     815           0 :     return FALSE;
     816             : }
     817             : 
     818         128 : static void free_family_stat(QuicUsrContext *usr, FamilyStat *family_stat)
     819             : {
     820         128 :     usr->free(usr, family_stat->buckets_ptrs);
     821         128 :     usr->free(usr, family_stat->counters);
     822         128 :     usr->free(usr, family_stat->buckets_buf);
     823         128 : }
     824             : 
     825          64 : static int init_channel(Encoder *encoder, Channel *channel)
     826             : {
     827             :     unsigned int ncounters;
     828             :     unsigned int levels;
     829             :     unsigned int rep_first;
     830             :     unsigned int first_size;
     831             :     unsigned int rep_next;
     832             :     unsigned int mul_size;
     833             :     unsigned int n_buckets;
     834             :     unsigned int n_buckets_ptrs;
     835             : 
     836          64 :     channel->correlate_row_width = 0;
     837          64 :     channel->correlate_row = NULL;
     838             : 
     839          64 :     find_model_params(encoder, 8, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
     840             :                       &first_size, &rep_next, &mul_size, &n_buckets);
     841          64 :     encoder->n_buckets_8bpc = n_buckets;
     842          64 :     if (!init_model_structures(encoder, &channel->family_stat_8bpc, rep_first, first_size,
     843             :                                rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
     844             :                                n_buckets)) {
     845           0 :         return FALSE;
     846             :     }
     847             : 
     848          64 :     find_model_params(encoder, 5, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
     849             :                       &first_size, &rep_next, &mul_size, &n_buckets);
     850          64 :     encoder->n_buckets_5bpc = n_buckets;
     851          64 :     if (!init_model_structures(encoder, &channel->family_stat_5bpc, rep_first, first_size,
     852             :                                rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
     853             :                                n_buckets)) {
     854           0 :         free_family_stat(encoder->usr, &channel->family_stat_8bpc);
     855           0 :         return FALSE;
     856             :     }
     857             : 
     858          64 :     return TRUE;
     859             : }
     860             : 
     861          64 : static void destroy_channel(Encoder *encoder, Channel *channel)
     862             : {
     863          64 :     QuicUsrContext *usr = encoder->usr;
     864          64 :     if (channel->correlate_row) {
     865          44 :         usr->free(usr, channel->correlate_row - 1);
     866             :     }
     867          64 :     free_family_stat(usr, &channel->family_stat_8bpc);
     868          64 :     free_family_stat(usr, &channel->family_stat_5bpc);
     869          64 : }
     870             : 
     871          16 : static int init_encoder(Encoder *encoder, QuicUsrContext *usr)
     872             : {
     873             :     int i;
     874             : 
     875          16 :     encoder->usr = usr;
     876             : 
     877          80 :     for (i = 0; i < MAX_CHANNELS; i++) {
     878          64 :         if (!init_channel(encoder, &encoder->channels[i])) {
     879           0 :             for (--i; i >= 0; i--) {
     880           0 :                 destroy_channel(encoder, &encoder->channels[i]);
     881             :             }
     882           0 :             return FALSE;
     883             :         }
     884             :     }
     885          16 :     return TRUE;
     886             : }
     887             : 
     888          16 : static int encoder_reset(Encoder *encoder, uint32_t *io_ptr, uint32_t *io_ptr_end)
     889             : {
     890          16 :     spice_assert(((uintptr_t)io_ptr % 4) == ((uintptr_t)io_ptr_end % 4));
     891          16 :     spice_assert(io_ptr <= io_ptr_end);
     892             : 
     893          16 :     encoder->rgb_state.waitcnt = 0;
     894          16 :     encoder->rgb_state.tabrand_seed = stabrand();
     895          16 :     encoder->rgb_state.wmidx = DEFwmistart;
     896          16 :     encoder->rgb_state.wmileft = DEFwminext;
     897          16 :     set_wm_trigger(&encoder->rgb_state);
     898             : 
     899          16 :     encoder_init_rle(&encoder->rgb_state);
     900             : 
     901          16 :     encoder->io_words_count = io_ptr_end - io_ptr;
     902          16 :     encoder->io_now = io_ptr;
     903          16 :     encoder->io_end = io_ptr_end;
     904          16 :     encoder->rows_completed = 0;
     905             : 
     906          16 :     return TRUE;
     907             : }
     908             : 
     909          16 : static int encoder_reset_channels(Encoder *encoder, int channels, int width, int bpc)
     910             : {
     911             :     int i;
     912             : 
     913          60 :     for (i = 0; i < channels; i++) {
     914             :         s_bucket *bucket;
     915             :         s_bucket *end_bucket;
     916             : 
     917          44 :         if (encoder->channels[i].correlate_row_width < width) {
     918          44 :             encoder->channels[i].correlate_row_width = 0;
     919          44 :             if (encoder->channels[i].correlate_row) {
     920           0 :                 encoder->usr->free(encoder->usr, encoder->channels[i].correlate_row - 1);
     921             :             }
     922          44 :             if (!(encoder->channels[i].correlate_row = (BYTE *)encoder->usr->malloc(encoder->usr,
     923             :                                                                                     width + 1))) {
     924           0 :                 return FALSE;
     925             :             }
     926          44 :             encoder->channels[i].correlate_row++;
     927          44 :             encoder->channels[i].correlate_row_width = width;
     928             :         }
     929             : 
     930          44 :         if (bpc == 8) {
     931          32 :             MEMCLEAR(encoder->channels[i].family_stat_8bpc.counters,
     932             :                      encoder->n_buckets_8bpc * sizeof(COUNTER) * MAXNUMCODES);
     933          32 :             bucket = encoder->channels[i].family_stat_8bpc.buckets_buf;
     934          32 :             end_bucket = bucket + encoder->n_buckets_8bpc;
     935         288 :             for (; bucket < end_bucket; bucket++) {
     936         256 :                 bucket->bestcode = /*BPC*/ 8 - 1;
     937             :             }
     938          32 :             encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_8bpc.buckets_ptrs;
     939          12 :         } else if (bpc == 5) {
     940          12 :             MEMCLEAR(encoder->channels[i].family_stat_5bpc.counters,
     941             :                      encoder->n_buckets_5bpc * sizeof(COUNTER) * MAXNUMCODES);
     942          12 :             bucket = encoder->channels[i].family_stat_5bpc.buckets_buf;
     943          12 :             end_bucket = bucket + encoder->n_buckets_5bpc;
     944          72 :             for (; bucket < end_bucket; bucket++) {
     945          60 :                 bucket->bestcode = /*BPC*/ 5 - 1;
     946             :             }
     947          12 :             encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_5bpc.buckets_ptrs;
     948             :         } else {
     949           0 :             encoder->usr->warn(encoder->usr, "%s: bad bpc %d\n", __FUNCTION__, bpc);
     950           0 :             return FALSE;
     951             :         }
     952             : 
     953          44 :         encoder->channels[i].state.waitcnt = 0;
     954          44 :         encoder->channels[i].state.tabrand_seed = stabrand();
     955          44 :         encoder->channels[i].state.wmidx = DEFwmistart;
     956          44 :         encoder->channels[i].state.wmileft = DEFwminext;
     957          44 :         set_wm_trigger(&encoder->channels[i].state);
     958             : 
     959          44 :         encoder_init_rle(&encoder->channels[i].state);
     960             :     }
     961          16 :     return TRUE;
     962             : }
     963             : 
     964          16 : static void quic_image_params(Encoder *encoder, QuicImageType type, int *channels, int *bpc)
     965             : {
     966          16 :     spice_assert(channels && bpc);
     967          16 :     switch (type) {
     968           4 :     case QUIC_IMAGE_TYPE_GRAY:
     969           4 :         *channels = 1;
     970           4 :         *bpc = 8;
     971           4 :         break;
     972           4 :     case QUIC_IMAGE_TYPE_RGB16:
     973           4 :         *channels = 3;
     974           4 :         *bpc = 5;
     975           4 :         break;
     976           4 :     case QUIC_IMAGE_TYPE_RGB24:
     977           4 :         *channels = 3;
     978           4 :         *bpc = 8;
     979           4 :         break;
     980           0 :     case QUIC_IMAGE_TYPE_RGB32:
     981           0 :         *channels = 3;
     982           0 :         *bpc = 8;
     983           0 :         break;
     984           4 :     case QUIC_IMAGE_TYPE_RGBA:
     985           4 :         *channels = 4;
     986           4 :         *bpc = 8;
     987           4 :         break;
     988           0 :     case QUIC_IMAGE_TYPE_INVALID:
     989             :     default:
     990           0 :         *channels = 0;
     991           0 :         *bpc = 0;
     992           0 :         encoder->usr->error(encoder->usr, "bad image type\n");
     993             :     }
     994          16 : }
     995             : 
     996             : #define FILL_LINES() {                                                  \
     997             :     if (line == lines_end) {                                            \
     998             :         int n = encoder->usr->more_lines(encoder->usr, &line);          \
     999             :         if (n <= 0 || line == NULL) {                                   \
    1000             :             encoder->usr->error(encoder->usr, "more lines failed\n");   \
    1001             :         }                                                               \
    1002             :         lines_end = line + n * stride;                                  \
    1003             :     }                                                                   \
    1004             : }
    1005             : 
    1006             : #define NEXT_LINE() {       \
    1007             :     line += stride;         \
    1008             :     FILL_LINES();           \
    1009             : }
    1010             : 
    1011             : #define QUIC_COMPRESS_RGB(bits)                                                                 \
    1012             :         encoder->channels[0].correlate_row[-1] = 0;                                             \
    1013             :         encoder->channels[1].correlate_row[-1] = 0;                                             \
    1014             :         encoder->channels[2].correlate_row[-1] = 0;                                             \
    1015             :         quic_rgb##bits##_compress_row0(encoder, (rgb##bits##_pixel_t *)(line), width);          \
    1016             :         encoder->rows_completed++;                                                              \
    1017             :         for (row = 1; row < height; row++) {                                                    \
    1018             :             prev = line;                                                                        \
    1019             :             NEXT_LINE();                                                                        \
    1020             :             encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];     \
    1021             :             encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];     \
    1022             :             encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];     \
    1023             :             quic_rgb##bits##_compress_row(encoder, (rgb##bits##_pixel_t *)prev,                 \
    1024             :                                           (rgb##bits##_pixel_t *)line, width);                  \
    1025             :             encoder->rows_completed++;                                                          \
    1026             :         }
    1027             : 
    1028           8 : int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
    1029             :                 uint8_t *line, unsigned int num_lines, int stride,
    1030             :                 uint32_t *io_ptr, unsigned int num_io_words)
    1031             : {
    1032           8 :     Encoder *encoder = (Encoder *)quic;
    1033           8 :     uint32_t *io_ptr_end = io_ptr + num_io_words;
    1034             :     uint8_t *lines_end;
    1035             :     int row;
    1036             :     uint8_t *prev;
    1037             :     int channels;
    1038             :     int bpc;
    1039             : 
    1040           8 :     lines_end = line + num_lines * stride;
    1041           8 :     if (line == NULL && lines_end != line) {
    1042           0 :         spice_warn_if_reached();
    1043           0 :         return QUIC_ERROR;
    1044             :     }
    1045             : 
    1046           8 :     quic_image_params(encoder, type, &channels, &bpc);
    1047             : 
    1048          16 :     if (!encoder_reset(encoder, io_ptr, io_ptr_end) ||
    1049           8 :         !encoder_reset_channels(encoder, channels, width, bpc)) {
    1050           0 :         return QUIC_ERROR;
    1051             :     }
    1052             : 
    1053           8 :     encoder->io_word = 0;
    1054           8 :     encoder->io_available_bits = 32;
    1055             : 
    1056           8 :     encode_32(encoder, QUIC_MAGIC);
    1057           8 :     encode_32(encoder, QUIC_VERSION);
    1058           8 :     encode_32(encoder, type);
    1059           8 :     encode_32(encoder, width);
    1060           8 :     encode_32(encoder, height);
    1061             : 
    1062           8 :     FILL_LINES();
    1063             : 
    1064           8 :     switch (type) {
    1065           0 :     case QUIC_IMAGE_TYPE_RGB32:
    1066           0 :         spice_assert(ABS(stride) >= width * 4);
    1067           0 :         QUIC_COMPRESS_RGB(32);
    1068           0 :         break;
    1069           2 :     case QUIC_IMAGE_TYPE_RGB24:
    1070           2 :         spice_assert(ABS(stride) >= width * 3);
    1071         454 :         QUIC_COMPRESS_RGB(24);
    1072           2 :         break;
    1073           2 :     case QUIC_IMAGE_TYPE_RGB16:
    1074           2 :         spice_assert(ABS(stride) >= width * 2);
    1075         369 :         QUIC_COMPRESS_RGB(16);
    1076           2 :         break;
    1077           2 :     case QUIC_IMAGE_TYPE_RGBA:
    1078           2 :         spice_assert(ABS(stride) >= width * 4);
    1079             : 
    1080           2 :         encoder->channels[0].correlate_row[-1] = 0;
    1081           2 :         encoder->channels[1].correlate_row[-1] = 0;
    1082           2 :         encoder->channels[2].correlate_row[-1] = 0;
    1083           2 :         quic_rgb32_compress_row0(encoder, (rgb32_pixel_t *)(line), width);
    1084             : 
    1085           2 :         encoder->channels[3].correlate_row[-1] = 0;
    1086           2 :         quic_four_compress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(line + 3), width);
    1087             : 
    1088           2 :         encoder->rows_completed++;
    1089             : 
    1090         302 :         for (row = 1; row < height; row++) {
    1091         300 :             prev = line;
    1092         300 :             NEXT_LINE();
    1093         300 :             encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
    1094         300 :             encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
    1095         300 :             encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
    1096         300 :             quic_rgb32_compress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)line, width);
    1097             : 
    1098         300 :             encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
    1099         300 :             quic_four_compress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
    1100         300 :                                    (four_bytes_t *)(line + 3), width);
    1101         300 :             encoder->rows_completed++;
    1102             :         }
    1103           2 :         break;
    1104           2 :     case QUIC_IMAGE_TYPE_GRAY:
    1105           2 :         spice_assert(ABS(stride) >= width);
    1106           2 :         encoder->channels[0].correlate_row[-1] = 0;
    1107           2 :         quic_one_compress_row0(encoder, &encoder->channels[0], (one_byte_t *)line, width);
    1108           2 :         encoder->rows_completed++;
    1109         753 :         for (row = 1; row < height; row++) {
    1110         751 :             prev = line;
    1111         751 :             NEXT_LINE();
    1112         751 :             encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
    1113         751 :             quic_one_compress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
    1114             :                                   (one_byte_t *)line, width);
    1115         751 :             encoder->rows_completed++;
    1116             :         }
    1117           2 :         break;
    1118           0 :     case QUIC_IMAGE_TYPE_INVALID:
    1119             :     default:
    1120           0 :         encoder->usr->error(encoder->usr, "bad image type\n");
    1121             :     }
    1122             : 
    1123           8 :     flush(encoder);
    1124           8 :     encoder->io_words_count -= (encoder->io_end - encoder->io_now);
    1125             : 
    1126           8 :     return encoder->io_words_count;
    1127             : }
    1128             : 
    1129           8 : int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
    1130             :                       QuicImageType *out_type, int *out_width, int *out_height)
    1131             : {
    1132           8 :     Encoder *encoder = (Encoder *)quic;
    1133           8 :     uint32_t *io_ptr_end = io_ptr + num_io_words;
    1134             :     QuicImageType type;
    1135             :     int width;
    1136             :     int height;
    1137             :     uint32_t magic;
    1138             :     uint32_t version;
    1139             :     int channels;
    1140             :     int bpc;
    1141             : 
    1142           8 :     if (!num_io_words || !encoder_reset(encoder, io_ptr, io_ptr_end)) {
    1143           0 :         return QUIC_ERROR;
    1144             :     }
    1145             : 
    1146           8 :     init_decode_io(encoder);
    1147             : 
    1148           8 :     magic = encoder->io_word;
    1149           8 :     decode_eat32bits(encoder);
    1150           8 :     if (magic != QUIC_MAGIC) {
    1151           0 :         encoder->usr->warn(encoder->usr, "bad magic\n");
    1152           0 :         return QUIC_ERROR;
    1153             :     }
    1154             : 
    1155           8 :     version = encoder->io_word;
    1156           8 :     decode_eat32bits(encoder);
    1157           8 :     if (version != QUIC_VERSION) {
    1158           0 :         encoder->usr->warn(encoder->usr, "bad version\n");
    1159           0 :         return QUIC_ERROR;
    1160             :     }
    1161             : 
    1162           8 :     type = (QuicImageType)encoder->io_word;
    1163           8 :     decode_eat32bits(encoder);
    1164             : 
    1165           8 :     width = encoder->io_word;
    1166           8 :     decode_eat32bits(encoder);
    1167             : 
    1168           8 :     height = encoder->io_word;
    1169           8 :     decode_eat32bits(encoder);
    1170             : 
    1171           8 :     if (width <= 0 || height <= 0) {
    1172           0 :         encoder->usr->warn(encoder->usr, "invalid size\n");
    1173           0 :         return QUIC_ERROR;
    1174             :     }
    1175             : 
    1176             :     /* avoid too big images */
    1177           8 :     if ((uint64_t) width * height > SPICE_MAX_IMAGE_SIZE) {
    1178           0 :         encoder->usr->error(encoder->usr, "image too large\n");
    1179             :     }
    1180             : 
    1181           8 :     quic_image_params(encoder, type, &channels, &bpc);
    1182             : 
    1183           8 :     if (!encoder_reset_channels(encoder, channels, width, bpc)) {
    1184           0 :         return QUIC_ERROR;
    1185             :     }
    1186             : 
    1187           8 :     *out_width = encoder->width = width;
    1188           8 :     *out_height = encoder->height = height;
    1189           8 :     *out_type = encoder->type = type;
    1190           8 :     return QUIC_OK;
    1191             : }
    1192             : 
    1193           2 : static void uncompress_rgba(Encoder *encoder, uint8_t *buf, int stride)
    1194             : {
    1195             :     unsigned int row;
    1196             :     uint8_t *prev;
    1197             : 
    1198           2 :     encoder->channels[0].correlate_row[-1] = 0;
    1199           2 :     encoder->channels[1].correlate_row[-1] = 0;
    1200           2 :     encoder->channels[2].correlate_row[-1] = 0;
    1201           2 :     quic_rgb32_uncompress_row0(encoder, (rgb32_pixel_t *)buf, encoder->width);
    1202             : 
    1203           2 :     encoder->channels[3].correlate_row[-1] = 0;
    1204           2 :     quic_four_uncompress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(buf + 3),
    1205             :                               encoder->width);
    1206             : 
    1207           2 :     encoder->rows_completed++;
    1208         302 :     for (row = 1; row < encoder->height; row++) {
    1209         300 :         prev = buf;
    1210         300 :         buf += stride;
    1211             : 
    1212         300 :         encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
    1213         300 :         encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
    1214         300 :         encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
    1215         300 :         quic_rgb32_uncompress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)buf,
    1216             :                                   encoder->width);
    1217             : 
    1218         300 :         encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
    1219         300 :         quic_four_uncompress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
    1220         300 :                                  (four_bytes_t *)(buf + 3), encoder->width);
    1221             : 
    1222         300 :         encoder->rows_completed++;
    1223             :     }
    1224           2 : }
    1225             : 
    1226           2 : static void uncompress_gray(Encoder *encoder, uint8_t *buf, int stride)
    1227             : {
    1228             :     unsigned int row;
    1229             :     uint8_t *prev;
    1230             : 
    1231           2 :     encoder->channels[0].correlate_row[-1] = 0;
    1232           2 :     quic_one_uncompress_row0(encoder, &encoder->channels[0], (one_byte_t *)buf, encoder->width);
    1233           2 :     encoder->rows_completed++;
    1234         753 :     for (row = 1; row < encoder->height; row++) {
    1235         751 :         prev = buf;
    1236         751 :         buf += stride;
    1237         751 :         encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
    1238         751 :         quic_one_uncompress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
    1239             :                                 (one_byte_t *)buf, encoder->width);
    1240         751 :         encoder->rows_completed++;
    1241             :     }
    1242           2 : }
    1243             : 
    1244             : #define QUIC_UNCOMPRESS_RGB(prefix, type)                                                       \
    1245             :         encoder->channels[0].correlate_row[-1] = 0;                                             \
    1246             :         encoder->channels[1].correlate_row[-1] = 0;                                             \
    1247             :         encoder->channels[2].correlate_row[-1] = 0;                                             \
    1248             :         quic_rgb##prefix##_uncompress_row0(encoder, (type *)buf, encoder->width);  \
    1249             :         encoder->rows_completed++;                                                              \
    1250             :         for (row = 1; row < encoder->height; row++) {                                           \
    1251             :             prev = buf;                                                                         \
    1252             :             buf += stride;                                                                      \
    1253             :             encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];     \
    1254             :             encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];     \
    1255             :             encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];     \
    1256             :             quic_rgb##prefix##_uncompress_row(encoder, (type *)prev, (type *)buf,               \
    1257             :                                               encoder->width);                                  \
    1258             :             encoder->rows_completed++;                                                          \
    1259             :         }
    1260             : 
    1261           8 : int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride)
    1262             : {
    1263           8 :     Encoder *encoder = (Encoder *)quic;
    1264             :     unsigned int row;
    1265             :     uint8_t *prev;
    1266             : 
    1267           8 :     spice_assert(buf);
    1268             : 
    1269           8 :     switch (encoder->type) {
    1270           2 :     case QUIC_IMAGE_TYPE_RGB32:
    1271             :     case QUIC_IMAGE_TYPE_RGB24:
    1272           2 :         if (type == QUIC_IMAGE_TYPE_RGB32) {
    1273           0 :             spice_assert(ABS(stride) >= (int)encoder->width * 4);
    1274           0 :             QUIC_UNCOMPRESS_RGB(32, rgb32_pixel_t);
    1275           0 :             break;
    1276           2 :         } else if (type == QUIC_IMAGE_TYPE_RGB24) {
    1277           2 :             spice_assert(ABS(stride) >= (int)encoder->width * 3);
    1278         454 :             QUIC_UNCOMPRESS_RGB(24, rgb24_pixel_t);
    1279           2 :             break;
    1280             :         }
    1281           0 :         encoder->usr->warn(encoder->usr, "unsupported output format\n");
    1282           0 :         return QUIC_ERROR;
    1283           2 :     case QUIC_IMAGE_TYPE_RGB16:
    1284           2 :         if (type == QUIC_IMAGE_TYPE_RGB16) {
    1285           2 :             spice_assert(ABS(stride) >= (int)encoder->width * 2);
    1286         369 :             QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
    1287           0 :         } else if (type == QUIC_IMAGE_TYPE_RGB32) {
    1288           0 :             spice_assert(ABS(stride) >= (int)encoder->width * 4);
    1289           0 :             QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
    1290             :         } else {
    1291           0 :             encoder->usr->warn(encoder->usr, "unsupported output format\n");
    1292           0 :             return QUIC_ERROR;
    1293             :         }
    1294             : 
    1295           2 :         break;
    1296           2 :     case QUIC_IMAGE_TYPE_RGBA:
    1297             : 
    1298           2 :         if (type != QUIC_IMAGE_TYPE_RGBA) {
    1299           0 :             encoder->usr->warn(encoder->usr, "unsupported output format\n");
    1300           0 :             return QUIC_ERROR;
    1301             :         }
    1302           2 :         spice_assert(ABS(stride) >= (int)encoder->width * 4);
    1303           2 :         uncompress_rgba(encoder, buf, stride);
    1304           2 :         break;
    1305           2 :     case QUIC_IMAGE_TYPE_GRAY:
    1306             : 
    1307           2 :         if (type != QUIC_IMAGE_TYPE_GRAY) {
    1308           0 :             encoder->usr->warn(encoder->usr, "unsupported output format\n");
    1309           0 :             return QUIC_ERROR;
    1310             :         }
    1311           2 :         spice_assert(ABS(stride) >= (int)encoder->width);
    1312           2 :         uncompress_gray(encoder, buf, stride);
    1313           2 :         break;
    1314           0 :     case QUIC_IMAGE_TYPE_INVALID:
    1315             :     default:
    1316           0 :         encoder->usr->error(encoder->usr, "bad image type\n");
    1317             :     }
    1318           8 :     return QUIC_OK;
    1319             : }
    1320             : 
    1321          16 : QuicContext *quic_create(QuicUsrContext *usr)
    1322             : {
    1323             :     Encoder *encoder;
    1324             : 
    1325          16 :     if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
    1326          16 :         !usr->free || !usr->more_space || !usr->more_lines) {
    1327           0 :         return NULL;
    1328             :     }
    1329             : 
    1330          16 :     if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
    1331           0 :         return NULL;
    1332             :     }
    1333             : 
    1334          16 :     if (!init_encoder(encoder, usr)) {
    1335           0 :         usr->free(usr, encoder);
    1336           0 :         return NULL;
    1337             :     }
    1338          16 :     return (QuicContext *)encoder;
    1339             : }
    1340             : 
    1341          16 : void quic_destroy(QuicContext *quic)
    1342             : {
    1343          16 :     Encoder *encoder = (Encoder *)quic;
    1344             :     int i;
    1345             : 
    1346          16 :     if (!quic) {
    1347           0 :         return;
    1348             :     }
    1349             : 
    1350          80 :     for (i = 0; i < MAX_CHANNELS; i++) {
    1351          64 :         destroy_channel(encoder, &encoder->channels[i]);
    1352             :     }
    1353          16 :     encoder->usr->free(encoder->usr, encoder);
    1354             : }
    1355             : 
    1356           1 : SPICE_CONSTRUCTOR_FUNC(quic_global_init)
    1357             : {
    1358           1 :     family_init(&family_8bpc, 8, DEFmaxclen);
    1359           1 :     family_init(&family_5bpc, 5, DEFmaxclen);
    1360           1 : }

Generated by: LCOV version 1.14