diff options
Diffstat (limited to 'xddm/display/quic_rgb_tmpl.c')
-rw-r--r-- | xddm/display/quic_rgb_tmpl.c | 766 |
1 files changed, 766 insertions, 0 deletions
diff --git a/xddm/display/quic_rgb_tmpl.c b/xddm/display/quic_rgb_tmpl.c new file mode 100644 index 0000000..b256d18 --- /dev/null +++ b/xddm/display/quic_rgb_tmpl.c @@ -0,0 +1,766 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This software is licensed under the GNU General Public License, + version 2 (GPLv2) (see COPYING for details), subject to the + following clarification. + + With respect to binaries built using the Microsoft(R) Windows + Driver Kit (WDK), GPLv2 does not extend to any code contained in or + derived from the WDK ("WDK Code"). As to WDK Code, by using or + distributing such binaries you agree to be bound by the Microsoft + Software License Terms for the WDK. All WDK Code is considered by + the GPLv2 licensors to qualify for the special exception stated in + section 3 of GPLv2 (commonly known as the system library + exception). + + There is NO WARRANTY for this software, express or implied, + including the implied warranties of NON-INFRINGEMENT, TITLE, + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#ifdef QUIC_RGB32 +#undef QUIC_RGB32 +#define PIXEL rgb32_pixel_t +#define FNAME(name) quic_rgb32_##name +#define golomb_coding golomb_coding_8bpc +#define golomb_decoding golomb_decoding_8bpc +#define update_model update_model_8bpc +#define find_bucket find_bucket_8bpc +#define family family_8bpc +#define BPC 8 +#define BPC_MASK 0xffU +#define COMPRESS_IMP +#define SET_r(pix, val) ((pix)->r = val) +#define GET_r(pix) ((pix)->r) +#define SET_g(pix, val) ((pix)->g = val) +#define GET_g(pix) ((pix)->g) +#define SET_b(pix, val) ((pix)->b = val) +#define GET_b(pix) ((pix)->b) +#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0) +#endif + +#ifdef QUIC_RGB24 +#undef QUIC_RGB24 +#define PIXEL rgb24_pixel_t +#define FNAME(name) quic_rgb24_##name +#define golomb_coding golomb_coding_8bpc +#define golomb_decoding golomb_decoding_8bpc +#define update_model update_model_8bpc +#define find_bucket find_bucket_8bpc +#define family family_8bpc +#define BPC 8 +#define BPC_MASK 0xffU +#define COMPRESS_IMP +#define SET_r(pix, val) ((pix)->r = val) +#define GET_r(pix) ((pix)->r) +#define SET_g(pix, val) ((pix)->g = val) +#define GET_g(pix) ((pix)->g) +#define SET_b(pix, val) ((pix)->b = val) +#define GET_b(pix) ((pix)->b) +#define UNCOMPRESS_PIX_START(pix) +#endif + +#ifdef QUIC_RGB16 +#undef QUIC_RGB16 +#define PIXEL rgb16_pixel_t +#define FNAME(name) quic_rgb16_##name +#define golomb_coding golomb_coding_5bpc +#define golomb_decoding golomb_decoding_5bpc +#define update_model update_model_5bpc +#define find_bucket find_bucket_5bpc +#define family family_5bpc +#define BPC 5 +#define BPC_MASK 0x1fU +#define COMPRESS_IMP +#define SET_r(pix, val) (*(pix) = (*(pix) & ~(0x1f << 10)) | ((val) << 10)) +#define GET_r(pix) ((*(pix) >> 10) & 0x1f) +#define SET_g(pix, val) (*(pix) = (*(pix) & ~(0x1f << 5)) | ((val) << 5)) +#define GET_g(pix) ((*(pix) >> 5) & 0x1f) +#define SET_b(pix, val) (*(pix) = (*(pix) & ~0x1f) | (val)) +#define GET_b(pix) (*(pix) & 0x1f) +#define UNCOMPRESS_PIX_START(pix) (*(pix) = 0) +#endif + +#ifdef QUIC_RGB16_TO_32 +#undef QUIC_RGB16_TO_32 +#define PIXEL rgb32_pixel_t +#define FNAME(name) quic_rgb16_to_32_##name +#define golomb_coding golomb_coding_5bpc +#define golomb_decoding golomb_decoding_5bpc +#define update_model update_model_5bpc +#define find_bucket find_bucket_5bpc +#define family family_5bpc +#define BPC 5 +#define BPC_MASK 0x1fU + +#define SET_r(pix, val) ((pix)->r = ((val) << 3) | (((val) & 0x1f) >> 2)) +#define GET_r(pix) ((pix)->r >> 3) +#define SET_g(pix, val) ((pix)->g = ((val) << 3) | (((val) & 0x1f) >> 2)) +#define GET_g(pix) ((pix)->g >> 3) +#define SET_b(pix, val) ((pix)->b = ((val) << 3) | (((val) & 0x1f) >> 2)) +#define GET_b(pix) ((pix)->b >> 3) +#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0) +#endif + +#define SAME_PIXEL(p1, p2) \ + (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \ + GET_b(p1) == GET_b(p2)) + + +#define _PIXEL_A(channel, curr) ((unsigned int)GET_##channel((curr) - 1)) +#define _PIXEL_B(channel, prev) ((unsigned int)GET_##channel(prev)) +#define _PIXEL_C(channel, prev) ((unsigned int)GET_##channel((prev) - 1)) + +/* a */ + +#define DECORELATE_0(channel, curr, bpc_mask)\ + family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)_PIXEL_A(channel, curr)) & bpc_mask] + +#define CORELATE_0(channel, curr, correlate, bpc_mask)\ + ((family.xlatL2U[correlate] + _PIXEL_A(channel, curr)) & bpc_mask) + +#ifdef PRED_1 + +/* (a+b)/2 */ +#define DECORELATE(channel, prev, curr, bpc_mask, r) \ + r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)((_PIXEL_A(channel, curr) + \ + _PIXEL_B(channel, prev)) >> 1)) & bpc_mask] + +#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) \ + SET_##channel(r, ((family.xlatL2U[correlate] + \ + (int)((_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev)) >> 1)) & bpc_mask)) +#endif + +#ifdef PRED_2 + +/* .75a+.75b-.5c */ +#define DECORELATE(channel, prev, curr, bpc_mask, r) { \ + int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \ + (int)(_PIXEL_C(channel, prev) << 1)) >> 2; \ + if (p < 0) { \ + p = 0; \ + } else if ((unsigned)p > bpc_mask) { \ + p = bpc_mask; \ + } \ + r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - p) & bpc_mask]; \ +} + +#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) { \ + const int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \ + (int)(_PIXEL_C(channel, prev) << 1) ) >> 2; \ + const unsigned int s = family.xlatL2U[correlate]; \ + if (!(p & ~bpc_mask)) { \ + SET_##channel(r, (s + (unsigned)p) & bpc_mask); \ + } else if (p < 0) { \ + SET_##channel(r, s); \ + } else { \ + SET_##channel(r, (s + bpc_mask) & bpc_mask); \ + } \ +} + +#endif + + +#define COMPRESS_ONE_ROW0_0(channel) \ + correlate_row_##channel[0] = family.xlatU2L[GET_##channel(cur_row)]; \ + golomb_coding(correlate_row_##channel[0], find_bucket(channel_##channel, \ + correlate_row_##channel[-1])->bestcode, \ + &codeword, &codewordlen); \ + encode(encoder, codeword, codewordlen); + +#define COMPRESS_ONE_ROW0(channel, index) \ + correlate_row_##channel[index] = DECORELATE_0(channel, &cur_row[index], bpc_mask); \ + golomb_coding(correlate_row_##channel[index], find_bucket(channel_##channel, \ + correlate_row_##channel[index -1])->bestcode, \ + &codeword, &codewordlen); \ + encode(encoder, codeword, codewordlen); + +#define UPDATE_MODEL(index) \ + update_model(&encoder->rgb_state, find_bucket(channel_r, correlate_row_r[index - 1]), \ + correlate_row_r[index], bpc); \ + update_model(&encoder->rgb_state, find_bucket(channel_g, correlate_row_g[index - 1]), \ + correlate_row_g[index], bpc); \ + update_model(&encoder->rgb_state, find_bucket(channel_b, correlate_row_b[index - 1]), \ + correlate_row_b[index], bpc); + + +#ifdef RLE_PRED_1 +#define RLE_PRED_1_IMP \ +if (SAME_PIXEL(&cur_row[i - 1], &prev_row[i])) { \ + if (run_index != i && SAME_PIXEL(&prev_row[i - 1], &prev_row[i]) && \ + i + 1 < end && SAME_PIXEL(&prev_row[i], &prev_row[i + 1])) { \ + goto do_run; \ + } \ +} +#else +#define RLE_PRED_1_IMP +#endif + +#ifdef RLE_PRED_2 +#define RLE_PRED_2_IMP \ +if (SAME_PIXEL(&prev_row[i - 1], &prev_row[i])) { \ + if (run_index != i && i > 2 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2])) { \ + goto do_run; \ + } \ +} +#else +#define RLE_PRED_2_IMP +#endif + +#ifdef RLE_PRED_3 +#define RLE_PRED_3_IMP \ +if (i > 1 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2]) && i != run_index) { \ + goto do_run; \ +} +#else +#define RLE_PRED_3_IMP +#endif + +#ifdef COMPRESS_IMP + +static void FNAME(compress_row0_seg)(Encoder *encoder, int i, + const PIXEL * const cur_row, + const int end, + const unsigned int waitmask, + const unsigned int bpc, + const unsigned int bpc_mask) +{ + Channel * const channel_r = encoder->channels; + Channel * const channel_g = channel_r + 1; + Channel * const channel_b = channel_g + 1; + + BYTE * const correlate_row_r = channel_r->correlate_row; + BYTE * const correlate_row_g = channel_g->correlate_row; + BYTE * const correlate_row_b = channel_b->correlate_row; + int stopidx; + + ASSERT(encoder->usr, end - i > 0); + + if (!i) { + unsigned int codeword, codewordlen; + + COMPRESS_ONE_ROW0_0(r); + COMPRESS_ONE_ROW0_0(g); + COMPRESS_ONE_ROW0_0(b); + + if (encoder->rgb_state.waitcnt) { + encoder->rgb_state.waitcnt--; + } else { + encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + UPDATE_MODEL(0); + } + stopidx = ++i + encoder->rgb_state.waitcnt; + } else { + stopidx = i + encoder->rgb_state.waitcnt; + } + + while (stopidx < end) { + for (; i <= stopidx; i++) { + unsigned int codeword, codewordlen; + COMPRESS_ONE_ROW0(r, i); + COMPRESS_ONE_ROW0(g, i); + COMPRESS_ONE_ROW0(b, i); + } + + UPDATE_MODEL(stopidx); + stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + } + + for (; i < end; i++) { + unsigned int codeword, codewordlen; + + COMPRESS_ONE_ROW0(r, i); + COMPRESS_ONE_ROW0(g, i); + COMPRESS_ONE_ROW0(b, i); + } + encoder->rgb_state.waitcnt = stopidx - end; +} + +static void FNAME(compress_row0)(Encoder *encoder, const PIXEL *cur_row, + unsigned int width) +{ + const unsigned int bpc = BPC; + const unsigned int bpc_mask = BPC_MASK; + int pos = 0; + + while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) { + if (encoder->rgb_state.wmileft) { + FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + encoder->rgb_state.wmileft, + bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask); + width -= encoder->rgb_state.wmileft; + pos += encoder->rgb_state.wmileft; + } + + encoder->rgb_state.wmidx++; + set_wm_trigger(&encoder->rgb_state); + encoder->rgb_state.wmileft = wminext; + } + + if (width) { + FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + width, + bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask); + if (wmimax > (int)encoder->rgb_state.wmidx) { + encoder->rgb_state.wmileft -= width; + } + } + + ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax); + ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32); + ASSERT(encoder->usr, wminext > 0); +} + +#define COMPRESS_ONE_0(channel) \ + correlate_row_##channel[0] = family.xlatU2L[(unsigned)((int)GET_##channel(cur_row) - \ + (int)GET_##channel(prev_row) ) & bpc_mask]; \ + golomb_coding(correlate_row_##channel[0], \ + find_bucket(channel_##channel, correlate_row_##channel[-1])->bestcode, \ + &codeword, &codewordlen); \ + encode(encoder, codeword, codewordlen); + +#define COMPRESS_ONE(channel, index) \ + DECORELATE(channel, &prev_row[index], &cur_row[index],bpc_mask, \ + correlate_row_##channel[index]); \ + golomb_coding(correlate_row_##channel[index], \ + find_bucket(channel_##channel, correlate_row_##channel[index - 1])->bestcode, \ + &codeword, &codewordlen); \ + encode(encoder, codeword, codewordlen); + +static void FNAME(compress_row_seg)(Encoder *encoder, int i, + const PIXEL * const prev_row, + const PIXEL * const cur_row, + const int end, + const unsigned int waitmask, + const unsigned int bpc, + const unsigned int bpc_mask) +{ + Channel * const channel_r = encoder->channels; + Channel * const channel_g = channel_r + 1; + Channel * const channel_b = channel_g + 1; + + BYTE * const correlate_row_r = channel_r->correlate_row; + BYTE * const correlate_row_g = channel_g->correlate_row; + BYTE * const correlate_row_b = channel_b->correlate_row; + int stopidx; +#ifdef RLE + int run_index = 0; + int run_size; +#endif + + ASSERT(encoder->usr, end - i > 0); + + if (!i) { + unsigned int codeword, codewordlen; + + COMPRESS_ONE_0(r); + COMPRESS_ONE_0(g); + COMPRESS_ONE_0(b); + + if (encoder->rgb_state.waitcnt) { + encoder->rgb_state.waitcnt--; + } else { + encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + UPDATE_MODEL(0); + } + stopidx = ++i + encoder->rgb_state.waitcnt; + } else { + stopidx = i + encoder->rgb_state.waitcnt; + } + for (;;) { + while (stopidx < end) { + for (; i <= stopidx; i++) { + unsigned int codeword, codewordlen; +#ifdef RLE + RLE_PRED_1_IMP; + RLE_PRED_2_IMP; + RLE_PRED_3_IMP; +#endif + COMPRESS_ONE(r, i); + COMPRESS_ONE(g, i); + COMPRESS_ONE(b, i); + } + + UPDATE_MODEL(stopidx); + stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + } + + for (; i < end; i++) { + unsigned int codeword, codewordlen; +#ifdef RLE + RLE_PRED_1_IMP; + RLE_PRED_2_IMP; + RLE_PRED_3_IMP; +#endif + COMPRESS_ONE(r, i); + COMPRESS_ONE(g, i); + COMPRESS_ONE(b, i); + } + encoder->rgb_state.waitcnt = stopidx - end; + + return; + +#ifdef RLE +do_run: + run_index = i; + encoder->rgb_state.waitcnt = stopidx - i; + run_size = 0; + + while (SAME_PIXEL(&cur_row[i], &cur_row[i - 1])) { + run_size++; + if (++i == end) { + encode_run(encoder, run_size); + return; + } + } + encode_run(encoder, run_size); + stopidx = i + encoder->rgb_state.waitcnt; +#endif + } +} + +static void FNAME(compress_row)(Encoder *encoder, + const PIXEL * const prev_row, + const PIXEL * const cur_row, + unsigned int width) + +{ + const unsigned int bpc = BPC; + const unsigned int bpc_mask = BPC_MASK; + unsigned int pos = 0; + + while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) { + if (encoder->rgb_state.wmileft) { + FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row, + pos + encoder->rgb_state.wmileft, + bppmask[encoder->rgb_state.wmidx], + bpc, bpc_mask); + width -= encoder->rgb_state.wmileft; + pos += encoder->rgb_state.wmileft; + } + + encoder->rgb_state.wmidx++; + set_wm_trigger(&encoder->rgb_state); + encoder->rgb_state.wmileft = wminext; + } + + if (width) { + FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row, pos + width, + bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask); + if (wmimax > (int)encoder->rgb_state.wmidx) { + encoder->rgb_state.wmileft -= width; + } + } + + ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax); + ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32); + ASSERT(encoder->usr, wminext > 0); +} + +#endif + +#define UNCOMPRESS_ONE_ROW0_0(channel) \ + correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \ + correlate_row_##channel[-1])->bestcode, \ + encoder->io_word, &codewordlen); \ + SET_##channel(&cur_row[0], (BYTE)family.xlatL2U[correlate_row_##channel[0]]); \ + decode_eatbits(encoder, codewordlen); + +#define UNCOMPRESS_ONE_ROW0(channel) \ + correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \ + correlate_row_##channel[i - 1])->bestcode, \ + encoder->io_word, \ + &codewordlen); \ + SET_##channel(&cur_row[i], CORELATE_0(channel, &cur_row[i], correlate_row_##channel[i], \ + bpc_mask)); \ + decode_eatbits(encoder, codewordlen); + +static void FNAME(uncompress_row0_seg)(Encoder *encoder, int i, + PIXEL * const cur_row, + const int end, + const unsigned int waitmask, + const unsigned int bpc, + const unsigned int bpc_mask) +{ + Channel * const channel_r = encoder->channels; + Channel * const channel_g = channel_r + 1; + Channel * const channel_b = channel_g + 1; + + BYTE * const correlate_row_r = channel_r->correlate_row; + BYTE * const correlate_row_g = channel_g->correlate_row; + BYTE * const correlate_row_b = channel_b->correlate_row; + int stopidx; + + ASSERT(encoder->usr, end - i > 0); + + if (!i) { + unsigned int codewordlen; + + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE_ROW0_0(r); + UNCOMPRESS_ONE_ROW0_0(g); + UNCOMPRESS_ONE_ROW0_0(b); + + if (encoder->rgb_state.waitcnt) { + --encoder->rgb_state.waitcnt; + } else { + encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + UPDATE_MODEL(0); + } + stopidx = ++i + encoder->rgb_state.waitcnt; + } else { + stopidx = i + encoder->rgb_state.waitcnt; + } + + while (stopidx < end) { + for (; i <= stopidx; i++) { + unsigned int codewordlen; + + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE_ROW0(r); + UNCOMPRESS_ONE_ROW0(g); + UNCOMPRESS_ONE_ROW0(b); + } + UPDATE_MODEL(stopidx); + stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + } + + for (; i < end; i++) { + unsigned int codewordlen; + + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE_ROW0(r); + UNCOMPRESS_ONE_ROW0(g); + UNCOMPRESS_ONE_ROW0(b); + } + encoder->rgb_state.waitcnt = stopidx - end; +} + +static void FNAME(uncompress_row0)(Encoder *encoder, + PIXEL * const cur_row, + unsigned int width) + +{ + const unsigned int bpc = BPC; + const unsigned int bpc_mask = BPC_MASK; + unsigned int pos = 0; + + while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) { + if (encoder->rgb_state.wmileft) { + FNAME(uncompress_row0_seg)(encoder, pos, cur_row, + pos + encoder->rgb_state.wmileft, + bppmask[encoder->rgb_state.wmidx], + bpc, bpc_mask); + pos += encoder->rgb_state.wmileft; + width -= encoder->rgb_state.wmileft; + } + + encoder->rgb_state.wmidx++; + set_wm_trigger(&encoder->rgb_state); + encoder->rgb_state.wmileft = wminext; + } + + if (width) { + FNAME(uncompress_row0_seg)(encoder, pos, cur_row, pos + width, + bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask); + if (wmimax > (int)encoder->rgb_state.wmidx) { + encoder->rgb_state.wmileft -= width; + } + } + + ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax); + ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32); + ASSERT(encoder->usr, wminext > 0); +} + +#define UNCOMPRESS_ONE_0(channel) \ + correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \ + correlate_row_##channel[-1])->bestcode, \ + encoder->io_word, &codewordlen); \ + SET_##channel(&cur_row[0], (family.xlatL2U[correlate_row_##channel[0]] + \ + GET_##channel(prev_row)) & bpc_mask); \ + decode_eatbits(encoder, codewordlen); + +#define UNCOMPRESS_ONE(channel) \ + correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \ + correlate_row_##channel[i - 1])->bestcode, \ + encoder->io_word, \ + &codewordlen); \ + CORELATE(channel, &prev_row[i], &cur_row[i], correlate_row_##channel[i], bpc_mask, \ + &cur_row[i]); \ + decode_eatbits(encoder, codewordlen); + +static void FNAME(uncompress_row_seg)(Encoder *encoder, + const PIXEL * const prev_row, + PIXEL * const cur_row, + int i, + const int end, + const unsigned int bpc, + const unsigned int bpc_mask) +{ + Channel * const channel_r = encoder->channels; + Channel * const channel_g = channel_r + 1; + Channel * const channel_b = channel_g + 1; + + BYTE * const correlate_row_r = channel_r->correlate_row; + BYTE * const correlate_row_g = channel_g->correlate_row; + BYTE * const correlate_row_b = channel_b->correlate_row; + const unsigned int waitmask = bppmask[encoder->rgb_state.wmidx]; + int stopidx; +#ifdef RLE + int run_index = 0; + int run_end; +#endif + + ASSERT(encoder->usr, end - i > 0); + + if (!i) { + unsigned int codewordlen; + + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE_0(r); + UNCOMPRESS_ONE_0(g); + UNCOMPRESS_ONE_0(b); + + if (encoder->rgb_state.waitcnt) { + --encoder->rgb_state.waitcnt; + } else { + encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + UPDATE_MODEL(0); + } + stopidx = ++i + encoder->rgb_state.waitcnt; + } else { + stopidx = i + encoder->rgb_state.waitcnt; + } + for (;;) { + while (stopidx < end) { + for (; i <= stopidx; i++) { + unsigned int codewordlen; +#ifdef RLE + RLE_PRED_1_IMP; + RLE_PRED_2_IMP; + RLE_PRED_3_IMP; +#endif + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE(r); + UNCOMPRESS_ONE(g); + UNCOMPRESS_ONE(b); + } + + UPDATE_MODEL(stopidx); + + stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask); + } + + for (; i < end; i++) { + unsigned int codewordlen; +#ifdef RLE + RLE_PRED_1_IMP; + RLE_PRED_2_IMP; + RLE_PRED_3_IMP; +#endif + UNCOMPRESS_PIX_START(&cur_row[i]); + UNCOMPRESS_ONE(r); + UNCOMPRESS_ONE(g); + UNCOMPRESS_ONE(b); + } + + encoder->rgb_state.waitcnt = stopidx - end; + + return; + +#ifdef RLE +do_run: + encoder->rgb_state.waitcnt = stopidx - i; + run_index = i; + run_end = i + decode_run(encoder); + + for (; i < run_end; i++) { + UNCOMPRESS_PIX_START(&cur_row[i]); + SET_r(&cur_row[i], GET_r(&cur_row[i - 1])); + SET_g(&cur_row[i], GET_g(&cur_row[i - 1])); + SET_b(&cur_row[i], GET_b(&cur_row[i - 1])); + } + + if (i == end) { + return; + } + + stopidx = i + encoder->rgb_state.waitcnt; +#endif + } +} + +static void FNAME(uncompress_row)(Encoder *encoder, + const PIXEL * const prev_row, + PIXEL * const cur_row, + unsigned int width) + +{ + const unsigned int bpc = BPC; + const unsigned int bpc_mask = BPC_MASK; + unsigned int pos = 0; + + while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) { + if (encoder->rgb_state.wmileft) { + FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos, + pos + encoder->rgb_state.wmileft, bpc, bpc_mask); + pos += encoder->rgb_state.wmileft; + width -= encoder->rgb_state.wmileft; + } + + encoder->rgb_state.wmidx++; + set_wm_trigger(&encoder->rgb_state); + encoder->rgb_state.wmileft = wminext; + } + + if (width) { + FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos, + pos + width, bpc, bpc_mask); + if (wmimax > (int)encoder->rgb_state.wmidx) { + encoder->rgb_state.wmileft -= width; + } + } + + ASSERT(encoder->usr, (int)encoder->rgb_state.wmidx <= wmimax); + ASSERT(encoder->usr, encoder->rgb_state.wmidx <= 32); + ASSERT(encoder->usr, wminext > 0); +} + +#undef PIXEL +#undef FNAME +#undef _PIXEL_A +#undef _PIXEL_B +#undef _PIXEL_C +#undef SAME_PIXEL +#undef RLE_PRED_1_IMP +#undef RLE_PRED_2_IMP +#undef RLE_PRED_3_IMP +#undef UPDATE_MODEL +#undef DECORELATE_0 +#undef DECORELATE +#undef COMPRESS_ONE_ROW0_0 +#undef COMPRESS_ONE_ROW0 +#undef COMPRESS_ONE_0 +#undef COMPRESS_ONE +#undef CORELATE_0 +#undef CORELATE +#undef UNCOMPRESS_ONE_ROW0_0 +#undef UNCOMPRESS_ONE_ROW0 +#undef UNCOMPRESS_ONE_0 +#undef UNCOMPRESS_ONE +#undef golomb_coding +#undef golomb_decoding +#undef update_model +#undef find_bucket +#undef family +#undef BPC +#undef BPC_MASK +#undef COMPRESS_IMP +#undef SET_r +#undef GET_r +#undef SET_g +#undef GET_g +#undef SET_b +#undef GET_b +#undef UNCOMPRESS_PIX_START + |