mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 20:42:49 +08:00 
			
		
		
		
	 9549712056
			
		
	
	9549712056
	
	
	
		
			
			Code should make more sense now Fixes: out of array access Fixes: 58299/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEG2000_fuzzer-6627570448465920 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Pierre-Anthony Lemieux <pal@sandflow.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
		
			
				
	
	
		
			1444 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1444 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2022 Caleb Etemesi <etemesicaleb@gmail.com>
 | |
|  *
 | |
|  * This file is part of FFmpeg.
 | |
|  *
 | |
|  * FFmpeg is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * FFmpeg is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with FFmpeg; if not, write to the Free Software
 | |
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Copyright 2019 - 2021, Osamu Watanabe
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without modification,
 | |
|  * are permitted provided that the following conditions are met:
 | |
|  *
 | |
|  * 1. Redistributions of source code must retain the above copyright notice, this
 | |
|  *    list of conditions and the following disclaimer.
 | |
|  *
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright notice,
 | |
|  *    this list of conditions and the following disclaimer in the documentation
 | |
|  *    and/or other materials provided with the distribution.
 | |
|  *
 | |
|  * 3. Neither the name of the copyright holder nor the names of its contributors
 | |
|  *    may be used to endorse or promote products derived from this software without
 | |
|  *    specific prior written permission.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
 | |
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | |
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | |
|  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 | |
|  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | |
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | |
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 | |
|  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | |
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include <stdint.h>
 | |
| #include "libavutil/attributes.h"
 | |
| #include "libavutil/common.h"
 | |
| #include "libavutil/avassert.h"
 | |
| #include "jpeg2000htdec.h"
 | |
| #include "jpeg2000.h"
 | |
| #include "jpeg2000dec.h"
 | |
| 
 | |
| #define J2K_Q1 0
 | |
| #define J2K_Q2 1
 | |
| 
 | |
| #define HT_SHIFT_SIGMA 0
 | |
| #define HT_SHIFT_SCAN 4
 | |
| #define HT_SHIFT_REF 3
 | |
| #define HT_SHIFT_REF_IND 2
 | |
| 
 | |
| /* See Rec. ITU-T T.800, Table 2 */
 | |
| const static uint8_t mel_e[13] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5 };
 | |
| 
 | |
| static const uint16_t dec_cxt_vlc_table1[1024];
 | |
| static const uint16_t dec_cxt_vlc_table0[1024];
 | |
| 
 | |
| typedef struct StateVars {
 | |
|     int32_t pos;
 | |
|     uint32_t bits;
 | |
|     uint32_t tmp;
 | |
|     uint32_t last;
 | |
|     uint8_t bits_left;
 | |
|     uint64_t bit_buf;
 | |
| } StateVars;
 | |
| 
 | |
| typedef struct MelDecoderState {
 | |
|     uint8_t k;
 | |
|     uint8_t run;
 | |
|     uint8_t one;
 | |
| } MelDecoderState;
 | |
| 
 | |
| /**
 | |
|  *  Given a precomputed c, checks whether n % d == 0. c is precomputed from d
 | |
|  *  using precompute_c().
 | |
|  */
 | |
| av_always_inline
 | |
| static uint32_t is_divisible(uint32_t n, uint64_t c)
 | |
| {
 | |
|     return n * c <= c - 1;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  *  Precompute the number c used by is_divisible().
 | |
|  */
 | |
| av_always_inline
 | |
| static uint64_t precompute_c(uint32_t d)
 | |
| {
 | |
|     return 1 + (0xffffffffffffffffull / d);
 | |
| }
 | |
| 
 | |
| static void jpeg2000_init_zero(StateVars *s)
 | |
| {
 | |
|     s->bits_left = 0;
 | |
|     s->bit_buf   = 0;
 | |
|     s->tmp       = 0;
 | |
|     s->bits      = 0;
 | |
|     s->pos       = 0;
 | |
|     s->last      = 0;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_init_mel(StateVars *s, uint32_t Pcup)
 | |
| {
 | |
|     jpeg2000_init_zero(s);
 | |
|     s->pos = Pcup;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_init_mag_ref(StateVars *s, uint32_t Lref)
 | |
| {
 | |
|     s->pos       = Lref - 2;
 | |
|     s->bits      = 0;
 | |
|     s->last      = 0xFF;
 | |
|     s->tmp       = 0;
 | |
|     s->bits_left = 0;
 | |
|     s->bit_buf   = 0;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_init_mel_decoder(MelDecoderState *mel_state)
 | |
| {
 | |
|     mel_state->k   = 0;
 | |
|     mel_state->run = 0;
 | |
|     mel_state->one = 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Refill the buffer backwards in little endian while skipping over stuffing
 | |
|  * bits. Stuffing bits are those that appear in the position of any byte whose
 | |
|  * LSBs are all 1's if the last consumed byte was larger than 0x8F.
 | |
|  */
 | |
| static int jpeg2000_bitbuf_refill_backwards(StateVars *buffer, const uint8_t *array)
 | |
| {
 | |
|     uint64_t tmp = 0;
 | |
|     int32_t position = buffer->pos - 4;
 | |
|     uint32_t new_bits = 32;
 | |
| 
 | |
|     if (buffer->bits_left >= 32)
 | |
|         return 0; // enough data, no need to pull in more bits
 | |
| 
 | |
|     /**
 | |
|      *  Unstuff bits. Load a temporary byte, which precedes the position we
 | |
|      *  currently at, to ensure that we can also un-stuff if the stuffed bit is
 | |
|      *  the bottom most bits.
 | |
|      */
 | |
| 
 | |
|     for(int i = FFMAX(0, position + 1); i <= buffer->pos + 1; i++)
 | |
|         tmp = 256*tmp + array[i];
 | |
| 
 | |
|     if ((tmp & 0x7FFF000000) > 0x7F8F000000) {
 | |
|         tmp &= 0x7FFFFFFFFF;
 | |
|         new_bits--;
 | |
|     }
 | |
|     if ((tmp & 0x007FFF0000) > 0x007F8F0000) {
 | |
|         tmp = (tmp & 0x007FFFFFFF) + ((tmp & 0xFF00000000) >> 1);
 | |
|         new_bits--;
 | |
|     }
 | |
|     if ((tmp & 0x00007FFF00) > 0x00007F8F00) {
 | |
|         tmp = (tmp & 0x00007FFFFF) + ((tmp & 0xFFFF000000) >> 1);
 | |
|         new_bits--;
 | |
|     }
 | |
|     if ((tmp & 0x0000007FFF) > 0x0000007F8F) {
 | |
|         tmp = (tmp & 0x0000007FFF) + ((tmp & 0xFFFFFF0000) >> 1);
 | |
|         new_bits--;
 | |
|     }
 | |
| 
 | |
|     tmp >>= 8; // Remove temporary byte loaded
 | |
| 
 | |
|     /* Add bits to the MSB of the bit buffer */
 | |
|     buffer->bit_buf |= tmp << buffer->bits_left;
 | |
|     buffer->bits_left += new_bits;
 | |
|     buffer->pos = FFMAX(0, position);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Refill the bit-buffer reading new bits going forward
 | |
|  * in the stream while skipping over stuffed bits.
 | |
|  */
 | |
| static void jpeg2000_bitbuf_refill_forward(StateVars *buffer, const uint8_t *array,
 | |
|                                            uint32_t length)
 | |
| {
 | |
|     while (buffer->bits_left < 32) {
 | |
|         buffer->tmp = 0xFF;
 | |
|         buffer->bits = (buffer->last == 0xFF) ? 7 : 8;
 | |
|         if (buffer->pos <= length) {
 | |
|             buffer->tmp = array[buffer->pos];
 | |
|             buffer->pos += 1;
 | |
|             buffer->last = buffer->tmp;
 | |
|         }
 | |
|         buffer->bit_buf |= ((uint64_t) buffer->tmp) << buffer->bits_left;
 | |
|         buffer->bits_left += buffer->bits;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Drops bits from lower bits in the bit buffer. buf contains the bit buffers.
 | |
|  * nbits is the number of bits to remove.
 | |
|  */
 | |
| av_always_inline
 | |
| static void jpeg2000_bitbuf_drop_bits_lsb(StateVars *buf, uint8_t nbits)
 | |
| {
 | |
|     av_assert2(buf->bits_left >= nbits); // cannot read more bits than available
 | |
|     buf->bit_buf >>= nbits;
 | |
|     buf->bits_left -= nbits;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get bits from the bit buffer reading them from the least significant bits
 | |
|  * moving to the most significant bits. In case there are fewer bits, refill
 | |
|  * from buf moving backwards.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint64_t jpeg2000_bitbuf_get_bits_lsb(StateVars *bit_stream, uint8_t nbits,
 | |
|                                              const uint8_t *buf)
 | |
| {
 | |
|     uint64_t bits;
 | |
|     uint64_t mask = (1ull << nbits) - 1;
 | |
|     if (bit_stream->bits_left < nbits)
 | |
|         jpeg2000_bitbuf_refill_backwards(bit_stream, buf);
 | |
|     bits = bit_stream->bit_buf & mask;
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(bit_stream, nbits);
 | |
|     return bits;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Get bits from the bit buffer reading them from the least significant bits
 | |
|  * moving to the most significant bits. In case there are fewer bits, refill from
 | |
|  * buf moving forward.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint64_t jpeg2000_bitbuf_get_bits_lsb_forward(StateVars *bit_stream,
 | |
|                                                      uint8_t nbits, const uint8_t *buf,
 | |
|                                                      uint32_t length)
 | |
| {
 | |
|     uint64_t bits;
 | |
|     uint64_t mask = (1ull << nbits) - 1;
 | |
| 
 | |
|     if (bit_stream->bits_left <= nbits)
 | |
|         jpeg2000_bitbuf_refill_forward(bit_stream, buf, length);
 | |
|     bits = bit_stream->bit_buf & mask;
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(bit_stream, nbits);
 | |
|     return bits;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Look ahead bit buffer without discarding bits.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint64_t jpeg2000_bitbuf_peek_bits_lsb(StateVars *stream, uint8_t nbits)
 | |
| {
 | |
|     uint64_t mask = (1ull << nbits) - 1;
 | |
|     return stream->bit_buf & mask;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_init_vlc(StateVars *s, uint32_t Lcup, uint32_t Pcup,
 | |
|                               const uint8_t *Dcup)
 | |
| {
 | |
|     s->bits_left = 0;
 | |
|     s->bit_buf   = 0;
 | |
|     s->pos       = Lcup - 2 - Pcup;
 | |
|     s->last      = Dcup[Lcup - 2];
 | |
|     s->tmp       = (s->last) >> 4;
 | |
|     s->bits      = ((s->tmp & 7) < 7) ? 4 : 3;
 | |
| 
 | |
|     jpeg2000_bitbuf_refill_backwards(s, Dcup + Pcup);
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(s, 4);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Decode prefix codes for VLC segment. See Rec. ITU-T T.814, 7.3.5.
 | |
|  */
 | |
| av_always_inline
 | |
| static int  jpeg2000_decode_ctx_vlc(const Jpeg2000DecoderContext *s,
 | |
|                                     StateVars *vlc_stream, const uint16_t *table,
 | |
|                                     const uint8_t *Dcup, uint8_t *sig_pat,
 | |
|                                     uint8_t *res_off, uint8_t *emb_pat_k,
 | |
|                                     uint8_t *emb_pat_1, uint8_t pos,
 | |
|                                     uint32_t Pcup, uint16_t context)
 | |
| {
 | |
|     uint32_t value;
 | |
|     uint8_t len;
 | |
|     uint64_t index;
 | |
|     uint64_t code_word;
 | |
| 
 | |
|     jpeg2000_bitbuf_refill_backwards(vlc_stream, Dcup + Pcup);
 | |
| 
 | |
|     code_word = vlc_stream->bit_buf & 0x7f;
 | |
|     index = code_word + (context << 7);
 | |
| 
 | |
|     av_assert0(index < 1024); // The CxtVLC table has 1024 entries.
 | |
| 
 | |
|     value = table[index];
 | |
| 
 | |
|     len = (value & 0x000F) >> 1;
 | |
| 
 | |
|     res_off[pos] = (uint8_t) (value & 1);
 | |
|     sig_pat[pos] = (uint8_t) ((value & 0x00F0) >> 4);
 | |
|     emb_pat_k[pos] = (uint8_t) ((value & 0x0F00) >> 8);
 | |
|     emb_pat_1[pos] = (uint8_t) ((value & 0xF000) >> 12);
 | |
| 
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(vlc_stream, len);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Decode variable length u-vlc prefix. See decodeUPrefix procedure at Rec.
 | |
|  * ITU-T T.814, 7.3.6.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint8_t vlc_decode_u_prefix(StateVars *vlc_stream, const uint8_t *refill_array)
 | |
| {
 | |
|     static const uint8_t return_value[8] = { 5, 1, 2, 1, 3, 1, 2, 1 };
 | |
|     static const uint8_t drop_bits[8]    = { 3, 1, 2, 1, 3, 1, 2, 1 };
 | |
| 
 | |
|     uint8_t bits;
 | |
| 
 | |
|     if (vlc_stream->bits_left < 3)
 | |
|         jpeg2000_bitbuf_refill_backwards(vlc_stream, refill_array);
 | |
| 
 | |
|     bits = jpeg2000_bitbuf_peek_bits_lsb(vlc_stream, 3);
 | |
| 
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(vlc_stream, drop_bits[bits]);
 | |
|     return return_value[bits];
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Decode variable length u-vlc suffix. See decodeUSuffix procedure at Rec.
 | |
|  * ITU-T T.814, 7.3.6.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint8_t vlc_decode_u_suffix(StateVars *vlc_stream, uint8_t suffix,
 | |
|                                    const uint8_t *refill_array)
 | |
| {
 | |
|     static const int mask[]      = { 1, 31 };
 | |
|     static const int drop_bits[] = { 1, 5  };
 | |
| 
 | |
|     uint8_t bits;
 | |
|     int cond = suffix != 3;
 | |
|     if (suffix < 3)
 | |
|         return 0;
 | |
| 
 | |
|     if (vlc_stream->bits_left < 5)
 | |
|         jpeg2000_bitbuf_refill_backwards(vlc_stream, refill_array);
 | |
| 
 | |
|     bits = jpeg2000_bitbuf_peek_bits_lsb(vlc_stream, 5);
 | |
| 
 | |
|     jpeg2000_bitbuf_drop_bits_lsb(vlc_stream, drop_bits[cond]);
 | |
|     return bits & mask[cond];
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Decode u-vlc extension values. See decodeUExtension procedure at Rec. ITU-T
 | |
|  * T.814, 7.3.6.
 | |
|  */
 | |
| av_always_inline
 | |
| static uint8_t vlc_decode_u_extension(StateVars *vlc_stream, uint8_t suffix,
 | |
|                                       const uint8_t *refill_array)
 | |
| {
 | |
|     return jpeg2000_bitbuf_get_bits_lsb(vlc_stream, 4 * (suffix >= 28), refill_array);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Magnitude and Sign decode procedures. See decodeMagSgnValue procedure at Rec.
 | |
|  * ITU-T T.814, 7.3.8.
 | |
|  */
 | |
| av_always_inline
 | |
| static int32_t jpeg2000_decode_mag_sgn(StateVars *mag_sgn_stream, int32_t m_n,
 | |
|                                        int32_t i_n, const uint8_t *buf, uint32_t length)
 | |
| {
 | |
|     int32_t val = 0;
 | |
|     if (m_n > 0) {
 | |
|         val = jpeg2000_bitbuf_get_bits_lsb_forward(mag_sgn_stream,m_n,buf,length);
 | |
|         val += (i_n << m_n);
 | |
|     }
 | |
|     return val;
 | |
| }
 | |
| 
 | |
| av_always_inline
 | |
| static void recover_mag_sgn(StateVars *mag_sgn, uint8_t pos, uint16_t q, int32_t m_n[2],
 | |
|                             int32_t known_1[2], const uint8_t emb_pat_1[2],
 | |
|                             int32_t v[2][4], int32_t m[2][4], uint8_t *E,
 | |
|                             uint32_t *mu_n, const uint8_t *Dcup, uint32_t Pcup,
 | |
|                             uint32_t pLSB)
 | |
| {
 | |
|     for (int i = 0; i < 4; i++) {
 | |
|         int32_t n = 4 * q + i;
 | |
|         m_n[pos] = m[pos][i];
 | |
|         known_1[pos] = (emb_pat_1[pos] >> i) & 1;
 | |
|         v[pos][i] = jpeg2000_decode_mag_sgn(mag_sgn, m_n[pos], known_1[pos], Dcup, Pcup);
 | |
| 
 | |
|         if (m_n[pos] != 0) {
 | |
|             E[n] = 32 - ff_clz(v[pos][i] | 1);
 | |
|             mu_n[n] = (v[pos][i] >> 1) + 1;
 | |
|             mu_n[n] <<= pLSB;
 | |
|             mu_n[n] |= ((uint32_t) (v[pos][i] & 1)) << 31; // sign bit.
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int jpeg2000_import_bit(StateVars *stream, const uint8_t *array, uint32_t length)
 | |
| {
 | |
|     int cond = stream->pos <= length;
 | |
|     int pos = FFMIN(stream->pos, length);
 | |
|     if (stream->bits == 0) {
 | |
|         stream->bits = (stream->tmp == 0xFF) ? 7 : 8;
 | |
|         stream->pos += cond;
 | |
|         stream->tmp = cond ? array[pos] : 0xFF;
 | |
|     }
 | |
|     stream->bits -= 1;
 | |
|     return (stream->tmp >> stream->bits) & 1;
 | |
| }
 | |
| 
 | |
| static int jpeg2000_peek_bit(StateVars *stream, const uint8_t *array, uint32_t length)
 | |
| {
 | |
|     if (stream->bits == 0) {
 | |
|         int cond = stream->pos <= length;
 | |
|         int pos = FFMIN(stream->pos, length);
 | |
|         stream->bits = (stream->tmp == 0xFF) ? 7 : 8;
 | |
|         stream->pos += cond;
 | |
|         stream->tmp = cond ? array[pos] : 0xFF;
 | |
|     }
 | |
|     return (stream->tmp >> stream->bits) & 1;
 | |
| }
 | |
| 
 | |
| static int jpeg2000_decode_mel_sym(MelDecoderState *mel_state,
 | |
|                                    StateVars *mel_stream,
 | |
|                                    const uint8_t *Dcup,
 | |
|                                    uint32_t Lcup)
 | |
| {
 | |
| 
 | |
|     if (mel_state->run == 0 && mel_state->one == 0) {
 | |
|         uint8_t eval;
 | |
|         uint8_t bit;
 | |
| 
 | |
|         eval = mel_e[mel_state->k];
 | |
|         bit = jpeg2000_import_bit(mel_stream, Dcup, Lcup);
 | |
|         if (bit == 1) {
 | |
|             mel_state->run = 1 << eval;
 | |
|             mel_state->k = FFMIN(12, mel_state->k + 1);
 | |
|         } else {
 | |
|             mel_state->run = 0;
 | |
|             while (eval > 0) {
 | |
|                 bit = jpeg2000_import_bit(mel_stream, Dcup, Lcup);
 | |
|                 mel_state->run = (2 * (mel_state->run)) + bit;
 | |
|                 eval -= 1;
 | |
|             }
 | |
|             mel_state->k = FFMAX(0, mel_state->k - 1);
 | |
|             mel_state->one = 1;
 | |
|         }
 | |
|     }
 | |
|     if (mel_state->run > 0) {
 | |
|         mel_state->run -= 1;
 | |
|         return 0;
 | |
|     } else {
 | |
|         mel_state->one = 0;
 | |
|         return 1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Magref decoding procedures.
 | |
|  */
 | |
| av_always_inline
 | |
| static int jpeg2000_import_magref_bit(StateVars *stream, const uint8_t *array,
 | |
|                                       uint32_t length)
 | |
| {
 | |
|     return jpeg2000_bitbuf_get_bits_lsb(stream, 1, array);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Signal EMB decode.
 | |
|  */
 | |
| static int jpeg2000_decode_sig_emb(const Jpeg2000DecoderContext *s, MelDecoderState *mel_state,
 | |
|                                    StateVars *mel_stream, StateVars *vlc_stream,
 | |
|                                    const uint16_t *vlc_table, const uint8_t *Dcup,
 | |
|                                    uint8_t *sig_pat, uint8_t *res_off, uint8_t *emb_pat_k,
 | |
|                                    uint8_t *emb_pat_1, uint8_t pos, uint16_t context,
 | |
|                                    uint32_t Lcup, uint32_t Pcup)
 | |
| {
 | |
|     if (context == 0) {
 | |
|         uint8_t sym;
 | |
|         sym = jpeg2000_decode_mel_sym(mel_state, mel_stream, Dcup, Lcup);
 | |
|         if (sym == 0) {
 | |
|             sig_pat[pos] = 0;
 | |
|             res_off[pos] = 0;
 | |
|             emb_pat_k[pos] = 0;
 | |
|             emb_pat_1[pos] = 0;
 | |
|             return 0;
 | |
|         }
 | |
|     }
 | |
|     return jpeg2000_decode_ctx_vlc(s, vlc_stream, vlc_table, Dcup, sig_pat,
 | |
|                                    res_off, emb_pat_k, emb_pat_1, pos, Pcup,
 | |
|                                    context);
 | |
| }
 | |
| 
 | |
| av_always_inline
 | |
| static int jpeg2000_get_state(int x1, int x2, int width, int shift_by,
 | |
|                               const uint8_t *block_states)
 | |
| {
 | |
|     return (block_states[(x1 + 1) * (width + 2) + (x2 + 1)] >> shift_by) & 1;
 | |
| }
 | |
| 
 | |
| av_always_inline
 | |
| static void jpeg2000_modify_state(int x1, int x2, int width,
 | |
|                                  int value, uint8_t *block_states)
 | |
| {
 | |
|     block_states[(x1 + 1) * (width + 2) + (x2 + 1)] |= value;
 | |
| }
 | |
| 
 | |
| av_always_inline
 | |
| static int jpeg2000_decode_ht_cleanup_segment(const Jpeg2000DecoderContext *s,
 | |
|                                               Jpeg2000Cblk *cblk, Jpeg2000T1Context *t1,
 | |
|                                               MelDecoderState *mel_state,
 | |
|                                               StateVars *mel_stream, StateVars *vlc_stream,
 | |
|                                               StateVars *mag_sgn_stream, const uint8_t *Dcup,
 | |
|                                               uint32_t Lcup, uint32_t Pcup, uint8_t pLSB,
 | |
|                                               int width, int height, int32_t *sample_buf,
 | |
|                                               uint8_t *block_states)
 | |
| {
 | |
|     uint16_t q                      = 0;     // Represents current quad position
 | |
|     uint16_t q1, q2;
 | |
|     uint16_t context1, context2;
 | |
|     uint16_t context                = 0;
 | |
| 
 | |
|     uint8_t sig_pat[2]              = { 0 }; // significance pattern
 | |
|     uint8_t res_off[2]              = { 0 }; // residual offset
 | |
|     uint8_t emb_pat_k[2]            = { 0 }; // exponent Max Bound pattern K
 | |
|     uint8_t emb_pat_1[2]            = { 0 }; // exponent Max Bound pattern 1
 | |
|     uint8_t gamma[2]                = { 0 };
 | |
| 
 | |
|     uint8_t E_n[2]                  = { 0 };
 | |
|     uint8_t E_ne[2]                 = { 0 };
 | |
|     uint8_t E_nw[2]                 = { 0 };
 | |
|     uint8_t E_nf[2]                 = { 0 };
 | |
| 
 | |
|     uint8_t max_e[2]                = { 0 };
 | |
|     uint8_t u_pfx[2]                = { 0 };
 | |
|     uint8_t u_sfx[2]                = { 0 };
 | |
|     uint8_t u_ext[2]                = { 0 };
 | |
| 
 | |
|     int32_t u[2]                    = { 0 };
 | |
|     int32_t U[2]                    = { 0 }; // exponent bound
 | |
|     int32_t m_n[2]                  = { 0 };
 | |
|     int32_t known_1[2]              = { 0 };
 | |
| 
 | |
|     int32_t m[2][4]                 = { 0 };
 | |
|     int32_t v[2][4]                 = { 0 };
 | |
| 
 | |
|     uint8_t kappa[2]                = { 1, 1 };
 | |
| 
 | |
|     int ret                         = 0;
 | |
| 
 | |
|     int sp;
 | |
| 
 | |
|     uint64_t c;
 | |
| 
 | |
|     uint8_t *sigma;
 | |
|     uint32_t *mu;
 | |
| 
 | |
|     const uint8_t *vlc_buf = Dcup + Pcup;
 | |
| 
 | |
|     /* convert to raster-scan */
 | |
|     const uint16_t is_border_x = width % 2;
 | |
|     const uint16_t is_border_y = height % 2;
 | |
| 
 | |
|     const uint16_t quad_width  = ff_jpeg2000_ceildivpow2(width, 1);
 | |
|     const uint16_t quad_height = ff_jpeg2000_ceildivpow2(height, 1);
 | |
| 
 | |
|     size_t buf_size = 4 * quad_width * quad_height;
 | |
| 
 | |
|     uint8_t *sigma_n = av_calloc(buf_size, sizeof(uint8_t));
 | |
|     uint8_t *E       = av_calloc(buf_size, sizeof(uint8_t));
 | |
|     uint32_t *mu_n   = av_calloc(buf_size, sizeof(uint32_t));
 | |
| 
 | |
|     if (!sigma_n || !E || !mu_n) {
 | |
|         ret = AVERROR(ENOMEM);
 | |
|         goto free;
 | |
|     }
 | |
| 
 | |
|     sigma = sigma_n;
 | |
|     mu = mu_n;
 | |
| 
 | |
|     while (q < quad_width - 1) {
 | |
|         q1 = q;
 | |
|         q2 = q1 + 1;
 | |
| 
 | |
|         if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                            dec_cxt_vlc_table0, Dcup, sig_pat, res_off,
 | |
|                                            emb_pat_k, emb_pat_1, J2K_Q1, context, Lcup,
 | |
|                                            Pcup)) < 0)
 | |
|             goto free;
 | |
| 
 | |
|         for (int i = 0; i < 4; i++)
 | |
|             sigma_n[4 * q1 + i] = (sig_pat[J2K_Q1] >> i) & 1;
 | |
| 
 | |
|         /* calculate context */
 | |
|         context  = sigma_n[4 * q1];           // f
 | |
|         context |= sigma_n[4 * q1 + 1];       // sf
 | |
|         context += sigma_n[4 * q1 + 2] << 1;  // w << 1
 | |
|         context += sigma_n[4 * q1 + 3] << 2;
 | |
| 
 | |
|         if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                            dec_cxt_vlc_table0, Dcup, sig_pat, res_off,
 | |
|                                            emb_pat_k, emb_pat_1, J2K_Q2, context, Lcup,
 | |
|                                            Pcup)) < 0)
 | |
|             goto free;
 | |
| 
 | |
|         for (int i = 0; i < 4; i++)
 | |
|             sigma_n[4 * q2 + i] = (sig_pat[J2K_Q2] >> i) & 1;
 | |
| 
 | |
|         /* calculate context for the next quad */
 | |
|         context  = sigma_n[4 * q2];           // f
 | |
|         context |= sigma_n[4 * q2 + 1];       // sf
 | |
|         context += sigma_n[4 * q2 + 2] << 1;  // w << 1
 | |
|         context += sigma_n[4 * q2 + 3] << 2;  // sw << 2
 | |
| 
 | |
|         u[0] = 0;
 | |
|         u[1] = 0;
 | |
| 
 | |
|         jpeg2000_bitbuf_refill_backwards(vlc_stream, vlc_buf);
 | |
| 
 | |
|         if (res_off[J2K_Q1] == 1 && res_off[J2K_Q2] == 1) {
 | |
| 
 | |
|             if (jpeg2000_decode_mel_sym(mel_state, mel_stream, Dcup, Lcup) == 1) {
 | |
| 
 | |
|                 u_pfx[J2K_Q1] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|                 u_pfx[J2K_Q2] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
| 
 | |
|                 u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|                 u_sfx[J2K_Q2] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q2], vlc_buf);
 | |
| 
 | |
|                 u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
|                 u_ext[J2K_Q2] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q2], vlc_buf);
 | |
| 
 | |
|                 u[J2K_Q1] = 2 + u_pfx[J2K_Q1] + u_sfx[J2K_Q1] + (u_ext[J2K_Q1] * 4);
 | |
|                 u[J2K_Q2] = 2 + u_pfx[J2K_Q2] + u_sfx[J2K_Q2] + (u_ext[J2K_Q2] * 4);
 | |
| 
 | |
|             } else {
 | |
|                 u_pfx[J2K_Q1] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
| 
 | |
|                 if (u_pfx[J2K_Q1] > 2) {
 | |
|                     u[J2K_Q2] = jpeg2000_bitbuf_get_bits_lsb(vlc_stream, 1, vlc_buf) + 1;
 | |
|                     u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|                     u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
|                 } else {
 | |
|                     u_pfx[J2K_Q2] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|                     u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|                     u_sfx[J2K_Q2] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q2], vlc_buf);
 | |
|                     u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
|                     u_ext[J2K_Q2] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q2], vlc_buf);
 | |
|                     u[J2K_Q2] = u_pfx[J2K_Q2] + u_sfx[J2K_Q2] + (u_ext[J2K_Q2] * 4);
 | |
|                 }
 | |
|                 /* See Rec. ITU-T T.814, 7.3.6(3) */
 | |
|                 u[J2K_Q1] = u_pfx[J2K_Q1] + u_sfx[J2K_Q1] + (u_ext[J2K_Q1] * 4);
 | |
|             }
 | |
| 
 | |
|         } else if (res_off[J2K_Q1] == 1 || res_off[J2K_Q2] == 1) {
 | |
|             uint8_t pos = res_off[J2K_Q1] == 1 ? 0 : 1;
 | |
|             u_pfx[pos] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|             u_sfx[pos] = vlc_decode_u_suffix(vlc_stream, u_pfx[pos], vlc_buf);
 | |
|             u_ext[pos] = vlc_decode_u_extension(vlc_stream, u_sfx[pos], vlc_buf);
 | |
|             u[pos] = u_pfx[pos] + u_sfx[pos] + (u_ext[pos] * 4);
 | |
|         }
 | |
|         U[J2K_Q1] = kappa[J2K_Q1] + u[J2K_Q1];
 | |
|         U[J2K_Q2] = kappa[J2K_Q2] + u[J2K_Q2];
 | |
| 
 | |
|         for (int i = 0; i < 4; i++) {
 | |
|             m[J2K_Q1][i] = sigma_n[4 * q1 + i] * U[J2K_Q1] - ((emb_pat_k[J2K_Q1] >> i) & 1);
 | |
|             m[J2K_Q2][i] = sigma_n[4 * q2 + i] * U[J2K_Q2] - ((emb_pat_k[J2K_Q2] >> i) & 1);
 | |
|         }
 | |
| 
 | |
|         recover_mag_sgn(mag_sgn_stream, J2K_Q1, q1, m_n, known_1, emb_pat_1, v, m,
 | |
|                         E, mu_n, Dcup, Pcup, pLSB);
 | |
| 
 | |
|         recover_mag_sgn(mag_sgn_stream, J2K_Q2, q2, m_n, known_1, emb_pat_1, v, m,
 | |
|                         E, mu_n, Dcup, Pcup, pLSB);
 | |
| 
 | |
|         q += 2; // Move to the next quad pair
 | |
|     }
 | |
| 
 | |
|     if (quad_width % 2 == 1) {
 | |
|         q1 = q;
 | |
| 
 | |
|         if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                            dec_cxt_vlc_table0, Dcup, sig_pat, res_off,
 | |
|                                            emb_pat_k, emb_pat_1, J2K_Q1, context, Lcup,
 | |
|                                            Pcup)) < 0)
 | |
|             goto free;
 | |
| 
 | |
|         for (int i = 0; i < 4; i++)
 | |
|             sigma_n[4 * q1 + i] = (sig_pat[J2K_Q1] >> i) & 1;
 | |
| 
 | |
|         u[J2K_Q1] = 0;
 | |
| 
 | |
|         if (res_off[J2K_Q1] == 1) {
 | |
|             u_pfx[J2K_Q1] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|             u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|             u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
|             u[J2K_Q1] = u_pfx[J2K_Q1] + u_sfx[J2K_Q1] + (u_ext[J2K_Q1] * 4);
 | |
|         }
 | |
| 
 | |
|         U[J2K_Q1] = kappa[J2K_Q1] + u[J2K_Q1];
 | |
| 
 | |
|         for (int i = 0; i < 4; i++)
 | |
|             m[J2K_Q1][i] = sigma_n[4 * q1 + i] * U[J2K_Q1] - ((emb_pat_k[J2K_Q1] >> i) & 1);
 | |
| 
 | |
|         recover_mag_sgn(mag_sgn_stream, J2K_Q1, q1, m_n, known_1, emb_pat_1, v, m,
 | |
|                         E, mu_n, Dcup, Pcup, pLSB);
 | |
| 
 | |
|         q++; // move to next quad pair
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Initial line pair end. As an optimization, we can replace modulo
 | |
|      * operations with checking if a number is divisible , since that's the only
 | |
|      * thing we need. This is paired with is_divisible. Credits to Daniel Lemire
 | |
|      * blog post [1].
 | |
|      *
 | |
|      * [1]
 | |
|      * https://lemire.me/blog/2019/02/08/faster-remainders-when-the-divisor-is-a-constant-beating-compilers-and-libdivide/
 | |
|      *
 | |
|      * It's UB on zero, but the spec doesn't allow a quad being zero, so we
 | |
|      * error out early in case that's the case.
 | |
|      */
 | |
|     c = precompute_c(quad_width);
 | |
| 
 | |
|     for (int row = 1; row < quad_height; row++) {
 | |
|         while ((q - (row * quad_width)) < quad_width - 1 && q < (quad_height * quad_width)) {
 | |
|             q1 = q;
 | |
|             q2 = q + 1;
 | |
|             context1  = sigma_n[4 * (q1 - quad_width) + 1];
 | |
|             context1 += sigma_n[4 * (q1 - quad_width) + 3] << 2;              // ne
 | |
| 
 | |
|             if (!is_divisible(q1, c)) {
 | |
|                 context1 |= sigma_n[4 * (q1 - quad_width) - 1];               // nw
 | |
|                 context1 += (sigma_n[4 * q1 - 1] | sigma_n[4 * q1 - 2]) << 1; // sw | q
 | |
|             }
 | |
|             if (!is_divisible(q1 + 1, c))
 | |
|                 context1 |= sigma_n[4 * (q1 - quad_width) + 5] << 2;
 | |
| 
 | |
|             if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                                dec_cxt_vlc_table1, Dcup, sig_pat, res_off,
 | |
|                                                emb_pat_k, emb_pat_1, J2K_Q1, context1, Lcup,
 | |
|                                                Pcup))
 | |
|                 < 0)
 | |
|                 goto free;
 | |
| 
 | |
|             for (int i = 0; i < 4; i++)
 | |
|                 sigma_n[4 * q1 + i] = (sig_pat[J2K_Q1] >> i) & 1;
 | |
| 
 | |
|             context2  = sigma_n[4 * (q2 - quad_width) + 1];
 | |
|             context2 += sigma_n[4 * (q2 - quad_width) + 3] << 2;
 | |
| 
 | |
|             if (!is_divisible(q2, c)) {
 | |
|                 context2 |= sigma_n[4 * (q2 - quad_width) - 1];
 | |
|                 context2 += (sigma_n[4 * q2 - 1] | sigma_n[4 * q2 - 2]) << 1;
 | |
|             }
 | |
|             if (!is_divisible(q2 + 1, c))
 | |
|                 context2 |= sigma_n[4 * (q2 - quad_width) + 5] << 2;
 | |
| 
 | |
|             if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                                dec_cxt_vlc_table1, Dcup, sig_pat, res_off,
 | |
|                                                emb_pat_k, emb_pat_1, J2K_Q2, context2, Lcup,
 | |
|                                                Pcup))
 | |
|                 < 0)
 | |
|                 goto free;
 | |
| 
 | |
|             for (int i = 0; i < 4; i++)
 | |
|                 sigma_n[4 * q2 + i] = (sig_pat[J2K_Q2] >> i) & 1;
 | |
| 
 | |
|             u[J2K_Q1] = 0;
 | |
|             u[J2K_Q2] = 0;
 | |
| 
 | |
|             jpeg2000_bitbuf_refill_backwards(vlc_stream, vlc_buf);
 | |
| 
 | |
|             if (res_off[J2K_Q1] == 1 && res_off[J2K_Q2] == 1) {
 | |
|                 u_pfx[J2K_Q1] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|                 u_pfx[J2K_Q2] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
| 
 | |
|                 u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|                 u_sfx[J2K_Q2] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q2], vlc_buf);
 | |
| 
 | |
|                 u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
|                 u_ext[J2K_Q2] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q2], vlc_buf);
 | |
| 
 | |
|                 u[J2K_Q1] = u_pfx[J2K_Q1] + u_sfx[J2K_Q1] + (u_ext[J2K_Q1] << 2);
 | |
|                 u[J2K_Q2] = u_pfx[J2K_Q2] + u_sfx[J2K_Q2] + (u_ext[J2K_Q2] << 2);
 | |
| 
 | |
|             } else if (res_off[J2K_Q1] == 1 || res_off[J2K_Q2] == 1) {
 | |
|                 uint8_t pos = res_off[J2K_Q1] == 1 ? 0 : 1;
 | |
| 
 | |
|                 u_pfx[pos] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|                 u_sfx[pos] = vlc_decode_u_suffix(vlc_stream, u_pfx[pos], vlc_buf);
 | |
|                 u_ext[pos] = vlc_decode_u_extension(vlc_stream, u_sfx[pos], vlc_buf);
 | |
| 
 | |
|                 u[pos] = u_pfx[pos] + u_sfx[pos] + (u_ext[pos] << 2);
 | |
|             }
 | |
|             sp = sig_pat[J2K_Q1];
 | |
| 
 | |
|             gamma[J2K_Q1] = 1;
 | |
| 
 | |
|             if (sp == 0 || sp == 1 || sp == 2 || sp == 4 || sp == 8)
 | |
|                 gamma[J2K_Q1] = 0;
 | |
| 
 | |
|             sp = sig_pat[J2K_Q2];
 | |
| 
 | |
|             gamma[J2K_Q2] = 1;
 | |
| 
 | |
|             if (sp == 0 || sp == 1 || sp == 2 || sp == 4 || sp == 8)
 | |
|                 gamma[J2K_Q2] = 0;
 | |
| 
 | |
|             E_n[J2K_Q1] = E[4 * (q1 - quad_width) + 1];
 | |
|             E_n[J2K_Q2] = E[4 * (q2 - quad_width) + 1];
 | |
| 
 | |
|             E_ne[J2K_Q1] = E[4 * (q1 - quad_width) + 3];
 | |
|             E_ne[J2K_Q2] = E[4 * (q2 - quad_width) + 3];
 | |
| 
 | |
|             E_nw[J2K_Q1] = (!is_divisible(q1, c)) * E[FFMAX((4 * (q1 - quad_width) - 1), 0)];
 | |
|             E_nw[J2K_Q2] = (!is_divisible(q2, c)) * E[FFMAX((4 * (q2 - quad_width) - 1), 0)];
 | |
| 
 | |
|             E_nf[J2K_Q1] = (!is_divisible(q1 + 1, c)) * E[4 * (q1 - quad_width) + 5];
 | |
|             E_nf[J2K_Q2] = (!is_divisible(q2 + 1, c)) * E[4 * (q2 - quad_width) + 5];
 | |
| 
 | |
|             max_e[J2K_Q1] = FFMAX(E_nw[J2K_Q1], FFMAX3(E_n[J2K_Q1], E_ne[J2K_Q1], E_nf[J2K_Q1]));
 | |
|             max_e[J2K_Q2] = FFMAX(E_nw[J2K_Q2], FFMAX3(E_n[J2K_Q2], E_ne[J2K_Q2], E_nf[J2K_Q2]));
 | |
| 
 | |
|             kappa[J2K_Q1] = FFMAX(1, gamma[J2K_Q1] * (max_e[J2K_Q1] - 1));
 | |
|             kappa[J2K_Q2] = FFMAX(1, gamma[J2K_Q2] * (max_e[J2K_Q2] - 1));
 | |
| 
 | |
|             U[J2K_Q1] = kappa[J2K_Q1] + u[J2K_Q1];
 | |
|             U[J2K_Q2] = kappa[J2K_Q2] + u[J2K_Q2];
 | |
| 
 | |
|             for (int i = 0; i < 4; i++) {
 | |
|                 m[J2K_Q1][i] = sigma_n[4 * q1 + i] * U[J2K_Q1] - ((emb_pat_k[J2K_Q1] >> i) & 1);
 | |
|                 m[J2K_Q2][i] = sigma_n[4 * q2 + i] * U[J2K_Q2] - ((emb_pat_k[J2K_Q2] >> i) & 1);
 | |
|             }
 | |
|             recover_mag_sgn(mag_sgn_stream, J2K_Q1, q1, m_n, known_1, emb_pat_1, v, m,
 | |
|                             E, mu_n, Dcup, Pcup, pLSB);
 | |
| 
 | |
|             recover_mag_sgn(mag_sgn_stream, J2K_Q2, q2, m_n, known_1, emb_pat_1, v, m,
 | |
|                             E, mu_n, Dcup, Pcup, pLSB);
 | |
| 
 | |
|             q += 2; // Move to the next quad pair
 | |
|         }
 | |
| 
 | |
|         if (quad_width % 2 == 1) {
 | |
|             q1 = q;
 | |
| 
 | |
|             /* calculate context for current quad */
 | |
|             context1  = sigma_n[4 * (q1 - quad_width) + 1];
 | |
|             context1 += (sigma_n[4 * (q1 - quad_width) + 3] << 2);
 | |
| 
 | |
|             if (!is_divisible(q1, c)) {
 | |
|                 context1 |= sigma_n[4 * (q1 - quad_width) - 1];
 | |
|                 context1 += (sigma_n[4 * q1 - 1] | sigma_n[4 * q1 - 2]) << 1;
 | |
|             }
 | |
|             if (!is_divisible(q1 + 1, c))
 | |
|                 context1 |= sigma_n[4 * (q1 - quad_width) + 5] << 2;
 | |
| 
 | |
|             if ((ret = jpeg2000_decode_sig_emb(s, mel_state, mel_stream, vlc_stream,
 | |
|                                                dec_cxt_vlc_table1, Dcup, sig_pat, res_off,
 | |
|                                                emb_pat_k, emb_pat_1, J2K_Q1, context1, Lcup,
 | |
|                                                Pcup)) < 0)
 | |
|                 goto free;
 | |
| 
 | |
|             for (int i = 0; i < 4; i++)
 | |
|                 sigma_n[4 * q1 + i] = (sig_pat[J2K_Q1] >> i) & 1;
 | |
| 
 | |
|             u[J2K_Q1] = 0;
 | |
| 
 | |
|             /* Recover mag_sgn value */
 | |
|             if (res_off[J2K_Q1] == 1) {
 | |
|                 u_pfx[J2K_Q1] = vlc_decode_u_prefix(vlc_stream, vlc_buf);
 | |
|                 u_sfx[J2K_Q1] = vlc_decode_u_suffix(vlc_stream, u_pfx[J2K_Q1], vlc_buf);
 | |
|                 u_ext[J2K_Q1] = vlc_decode_u_extension(vlc_stream, u_sfx[J2K_Q1], vlc_buf);
 | |
| 
 | |
|                 u[J2K_Q1] = u_pfx[J2K_Q1] + u_sfx[J2K_Q1] + (u_ext[J2K_Q1] << 2);
 | |
|             }
 | |
| 
 | |
|             sp = sig_pat[J2K_Q1];
 | |
| 
 | |
|             gamma[J2K_Q1] = 1;
 | |
| 
 | |
|             if (sp == 0 || sp == 1 || sp == 2 || sp == 4 || sp == 8)
 | |
|                 gamma[J2K_Q1] = 0;
 | |
| 
 | |
|             E_n[J2K_Q1] = E[4 * (q1 - quad_width) + 1];
 | |
| 
 | |
|             E_ne[J2K_Q1] = E[4 * (q1 - quad_width) + 3];
 | |
| 
 | |
|             E_nw[J2K_Q1] = (!is_divisible(q1, c)) * E[FFMAX((4 * (q1 - quad_width) - 1), 0)];
 | |
| 
 | |
|             E_nf[J2K_Q1] = (!is_divisible(q1 + 1, c)) * E[4 * (q1 - quad_width) + 5];
 | |
| 
 | |
|             max_e[J2K_Q1] = FFMAX(E_nw[J2K_Q1], FFMAX3(E_n[J2K_Q1], E_ne[J2K_Q1], E_nf[J2K_Q1]));
 | |
| 
 | |
|             kappa[J2K_Q1] = FFMAX(1, gamma[J2K_Q1] * (max_e[J2K_Q1] - 1));
 | |
| 
 | |
|             U[J2K_Q1] = kappa[J2K_Q1] + u[J2K_Q1];
 | |
| 
 | |
|             for (int i = 0; i < 4; i++)
 | |
|                 m[J2K_Q1][i] = sigma_n[4 * q1 + i] * U[J2K_Q1] - ((emb_pat_k[J2K_Q1] >> i) & 1);
 | |
| 
 | |
|             recover_mag_sgn(mag_sgn_stream, J2K_Q1, q1, m_n, known_1, emb_pat_1, v, m,
 | |
|                             E, mu_n, Dcup, Pcup, pLSB);
 | |
|             q += 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // convert to raster-scan
 | |
|     for (int y = 0; y < quad_height; y++) {
 | |
|         for (int x = 0; x < quad_width; x++) {
 | |
|             int j1, j2;
 | |
|             int x1, x2 , x3;
 | |
| 
 | |
|             j1 = 2 * y;
 | |
|             j2 = 2 * x;
 | |
| 
 | |
|             sample_buf[j2 + (j1 * width)] = (int32_t)*mu;
 | |
|             jpeg2000_modify_state(j1, j2, width, *sigma, block_states);
 | |
|             sigma += 1;
 | |
|             mu += 1;
 | |
| 
 | |
|             x1 = y != quad_height - 1 || is_border_y == 0;
 | |
|             sample_buf[j2 + ((j1 + 1) * width)] = ((int32_t)*mu) * x1;
 | |
|             jpeg2000_modify_state(j1 + 1, j2, width, (*sigma) * x1, block_states);
 | |
|             sigma += 1;
 | |
|             mu += 1;
 | |
| 
 | |
|             x2 = x != quad_width - 1 || is_border_x == 0;
 | |
|             sample_buf[(j2 + 1) + (j1 * width)] = ((int32_t)*mu) * x2;
 | |
|             jpeg2000_modify_state(j1, j2 + 1, width, (*sigma) * x2, block_states);
 | |
|             sigma += 1;
 | |
|             mu += 1;
 | |
| 
 | |
|             x3 = x1 | x2;
 | |
|             sample_buf[(j2 + 1) + (j1 + 1) * width] = ((int32_t)*mu) * x3;
 | |
|             jpeg2000_modify_state(j1 + 1, j2 + 1, width, (*sigma) * x3, block_states);
 | |
|             sigma += 1;
 | |
|             mu += 1;
 | |
|         }
 | |
|     }
 | |
|     ret = 1;
 | |
| free:
 | |
|     av_freep(&sigma_n);
 | |
|     av_freep(&E);
 | |
|     av_freep(&mu_n);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_calc_mbr(uint8_t *mbr, const uint16_t i, const uint16_t j,
 | |
|                               const uint32_t mbr_info, uint8_t causal_cond,
 | |
|                               uint8_t *block_states, int width)
 | |
| {
 | |
|     int local_mbr = 0;
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j - 1, width, HT_SHIFT_SIGMA, block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j + 0, width, HT_SHIFT_SIGMA, block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j + 1, width, HT_SHIFT_SIGMA, block_states);
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i + 0, j - 1, width, HT_SHIFT_SIGMA, block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i + 0, j + 1, width, HT_SHIFT_SIGMA, block_states);
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j - 1, width, HT_SHIFT_SIGMA, block_states) * causal_cond;
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j + 0, width, HT_SHIFT_SIGMA, block_states) * causal_cond;
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j + 1, width, HT_SHIFT_SIGMA, block_states) * causal_cond;
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j - 1, width, HT_SHIFT_REF,   block_states) *
 | |
|                  jpeg2000_get_state(i - 1, j - 1, width, HT_SHIFT_SCAN,  block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j + 0, width, HT_SHIFT_REF,   block_states) *
 | |
|                  jpeg2000_get_state(i - 1, j - 1, width, HT_SHIFT_SCAN,  block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i - 1, j + 1, width, HT_SHIFT_REF,   block_states) *
 | |
|                  jpeg2000_get_state(i - 1, j + 1, width, HT_SHIFT_SCAN,  block_states);
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i + 0, j - 1, width, HT_SHIFT_REF,   block_states) *
 | |
|                  jpeg2000_get_state(i + 0, j - 1, width, HT_SHIFT_SCAN,  block_states);
 | |
|     local_mbr |= jpeg2000_get_state(i + 0, j + 1, width, HT_SHIFT_REF,   block_states) *
 | |
|                  jpeg2000_get_state(i + 0, j + 1, width, HT_SHIFT_SCAN,  block_states);
 | |
| 
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j - 1, width, HT_SHIFT_REF,  block_states) *
 | |
|                  jpeg2000_get_state(i + 1, j - 1, width, HT_SHIFT_SCAN, block_states) * causal_cond;
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j + 0, width, HT_SHIFT_REF,  block_states) *
 | |
|                  jpeg2000_get_state(i + 1, j + 0, width, HT_SHIFT_SCAN, block_states) * causal_cond;
 | |
|     local_mbr |= jpeg2000_get_state(i + 1, j + 1, width, HT_SHIFT_REF,  block_states) *
 | |
|                  jpeg2000_get_state(i + 1, j + 1, width, HT_SHIFT_SCAN, block_states) * causal_cond;
 | |
| 
 | |
|     *mbr |= local_mbr;
 | |
| }
 | |
| 
 | |
| static void jpeg2000_process_stripes_block(StateVars *sig_prop, int i_s, int j_s,
 | |
|                                            int width, int height, int stride, int pLSB,
 | |
|                                            int32_t *sample_buf, uint8_t *block_states,
 | |
|                                            uint8_t *magref_segment, uint32_t magref_length)
 | |
| {
 | |
|     for (int j = j_s; j < j_s + width; j++) {
 | |
|         uint32_t  mbr_info = 0;
 | |
|         for (int i = i_s; i < i_s + height; i++) {
 | |
|             int modify_state, cond;
 | |
|             uint8_t bit;
 | |
|             uint8_t causal_cond = i != (i_s + height - 1);
 | |
|             int32_t *sp = &sample_buf[j + (i * (stride - 2))];
 | |
|             uint8_t mbr = 0;
 | |
| 
 | |
|             if (jpeg2000_get_state(i, j, stride - 2, HT_SHIFT_SIGMA, block_states) == 0)
 | |
|                 jpeg2000_calc_mbr(&mbr, i, j, mbr_info & 0x1EF, causal_cond, block_states, stride - 2);
 | |
|             mbr_info >>= 3;
 | |
|             cond = mbr != 0;
 | |
|             bit = jpeg2000_peek_bit(sig_prop, magref_segment, magref_length);
 | |
|             *sp |= (bit * cond) << pLSB;
 | |
|             sig_prop->bits -= cond;
 | |
|             modify_state = (((1 << HT_SHIFT_REF_IND) | (1 << HT_SHIFT_REF)) * cond) | 1 << HT_SHIFT_SCAN;
 | |
|             jpeg2000_modify_state(i, j, stride - 2, modify_state, block_states);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.4.
 | |
| */
 | |
| av_noinline
 | |
| static void jpeg2000_decode_sigprop_segment(Jpeg2000Cblk *cblk, uint16_t width,
 | |
|                                             uint16_t height, uint8_t *magref_segment,
 | |
|                                             uint32_t magref_length, uint8_t pLSB,
 | |
|                                             int32_t *sample_buf, uint8_t *block_states)
 | |
| {
 | |
|     StateVars sp_dec;
 | |
| 
 | |
|     const uint16_t num_v_stripe = height / 4;
 | |
|     const uint16_t num_h_stripe = width / 4;
 | |
|     int b_width                 = 4;
 | |
|     int b_height                = 4;
 | |
|     int stride                  = width + 2;
 | |
| 
 | |
|     int last_width;
 | |
|     uint16_t i = 0, j = 0;
 | |
| 
 | |
|     jpeg2000_init_zero(&sp_dec);
 | |
| 
 | |
|     for (int n1 = 0; n1 < num_v_stripe; n1++) {
 | |
|         j = 0;
 | |
|         for (int n2 = 0; n2 < num_h_stripe; n2++) {
 | |
|             jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,
 | |
|                                            pLSB, sample_buf, block_states, magref_segment,
 | |
|                                            magref_length);
 | |
|             j += 4;
 | |
|         }
 | |
|         last_width = width % 4;
 | |
|         if (last_width)
 | |
|             jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,
 | |
|                                            pLSB, sample_buf, block_states, magref_segment,
 | |
|                                            magref_length);
 | |
|         i += 4;
 | |
|     }
 | |
| 
 | |
|     /* Decode remaining height stripes */
 | |
|     b_height = height % 4;
 | |
|     j = 0;
 | |
|     for (int n2 = 0; n2 < num_h_stripe; n2++) {
 | |
|         jpeg2000_process_stripes_block(&sp_dec, i, j, b_width, b_height, stride,
 | |
|                                        pLSB, sample_buf, block_states, magref_segment,
 | |
|                                        magref_length);
 | |
|         j += 4;
 | |
|     }
 | |
|     last_width = width % 4;
 | |
|     if (last_width)
 | |
|         jpeg2000_process_stripes_block(&sp_dec, i, j, last_width, b_height, stride,
 | |
|                                        pLSB, sample_buf, block_states, magref_segment,
 | |
|                                        magref_length);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * See procedure decodeSigPropMag at Rec. ITU-T T.814, 7.5.
 | |
| */
 | |
| static int
 | |
| jpeg2000_decode_magref_segment( uint16_t width, uint16_t block_height,
 | |
|                                 uint8_t *magref_segment,uint32_t magref_length,
 | |
|                                 uint8_t pLSB, int32_t *sample_buf, uint8_t *block_states)
 | |
| {
 | |
| 
 | |
|     StateVars mag_ref           = { 0 };
 | |
|     const uint16_t num_v_stripe = block_height / 4;
 | |
|     uint16_t height             = 4;
 | |
|     uint16_t i_start            = 0;
 | |
|     int32_t *sp;
 | |
| 
 | |
|     jpeg2000_init_mag_ref(&mag_ref, magref_length);
 | |
| 
 | |
|     for (int n1 = 0; n1 < num_v_stripe; n1++) {
 | |
|         for (int j = 0; j < width; j++) {
 | |
|             for (int i = i_start; i < i_start + height; i++) {
 | |
|                 /**
 | |
|                  *  We move column wise, going from one quad to another. See
 | |
|                  *  Rec. ITU-T T.814, Figure 7.
 | |
|                  */
 | |
|                 sp = &sample_buf[j + i * width];
 | |
|                 if (jpeg2000_get_state(i, j, width, HT_SHIFT_SIGMA, block_states) != 0) {
 | |
|                     jpeg2000_modify_state(i, j, width, 1 << HT_SHIFT_REF_IND, block_states);
 | |
|                     *sp |= jpeg2000_import_magref_bit(&mag_ref, magref_segment, magref_length) << pLSB;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         i_start += 4;
 | |
|     }
 | |
|     height = block_height % 4;
 | |
|     for (int j = 0; j < width; j++) {
 | |
|         for (int i = i_start; i < i_start + height; i++) {
 | |
|             sp = &sample_buf[j + i * width];
 | |
|             if (jpeg2000_get_state(i, j, width, HT_SHIFT_SIGMA, block_states) != 0) {
 | |
|                 jpeg2000_modify_state(i, j, width, 1 << HT_SHIFT_REF_IND, block_states);
 | |
|                 *sp |= jpeg2000_import_magref_bit(&mag_ref, magref_segment, magref_length) << pLSB;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| int
 | |
| ff_jpeg2000_decode_htj2k(const Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
 | |
|                          int width, int height, int magp, uint8_t roi_shift)
 | |
| {
 | |
|     uint8_t p0 = 0;             // Number of placeholder passes
 | |
|     uint32_t Lcup;              // Length of HT cleanup segment
 | |
|     uint32_t Lref;              // Length of Refinement segment
 | |
|     uint32_t Scup;              // HT cleanup segment suffix length
 | |
|     uint32_t Pcup;              // HT cleanup segment prefix length
 | |
| 
 | |
|     uint8_t S_blk;              // Number of skipped magnitude bitplanes
 | |
|     uint8_t pLSB;
 | |
| 
 | |
|     uint8_t *Dcup;              // Byte of an HT cleanup segment
 | |
|     uint8_t *Dref;              // Byte of an HT refinement segment
 | |
| 
 | |
|     int z_blk;                  // Number of ht coding pass
 | |
| 
 | |
|     uint8_t empty_passes;
 | |
| 
 | |
|     StateVars mag_sgn;          // Magnitude and Sign
 | |
|     StateVars mel;              // Adaptive run-length coding
 | |
|     StateVars vlc;              // Variable Length coding
 | |
|     StateVars sig_prop;         // Significance propagation
 | |
| 
 | |
|     MelDecoderState mel_state;
 | |
| 
 | |
|     int ret;
 | |
| 
 | |
|     /* Temporary buffers */
 | |
|     int32_t *sample_buf = NULL;
 | |
|     uint8_t *block_states = NULL;
 | |
| 
 | |
|     int32_t n, val;             // Post-processing
 | |
| 
 | |
|     int32_t M_b = magp;
 | |
| 
 | |
|     /* codeblock size as constrained by Rec. ITU-T T.800, Table A.18 */
 | |
|     av_assert0(width <= 1024U && height <= 1024U);
 | |
|     av_assert0(width * height <= 4096);
 | |
|     av_assert0(width * height > 0);
 | |
| 
 | |
|     memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));
 | |
|     memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));
 | |
| 
 | |
|     if (cblk->npasses == 0)
 | |
|         return 0;
 | |
| 
 | |
|     if (cblk->npasses > 3)
 | |
|         p0 = 0;
 | |
|     else if (cblk->length == 0)
 | |
|         p0 = 1;
 | |
| 
 | |
|     empty_passes = p0 * 3;
 | |
|     z_blk = cblk->npasses - empty_passes;
 | |
| 
 | |
|     if (z_blk <= 0)
 | |
|         return 0; // No passes within this set, continue
 | |
| 
 | |
|     Lcup = cblk->pass_lengths[0];
 | |
|     Lref = cblk->pass_lengths[1];
 | |
| 
 | |
|     if (Lcup < 2) {
 | |
|         av_log(s->avctx, AV_LOG_ERROR,
 | |
|                "Cleanup pass length must be at least 2 bytes in length\n");
 | |
|         return AVERROR_INVALIDDATA;
 | |
|     }
 | |
|     Dcup = cblk->data;
 | |
|     Dref  = cblk->data + Lcup; // Dref comes after the refinement segment
 | |
|     S_blk = p0 + cblk->zbp;
 | |
|     pLSB  = 30 - S_blk;
 | |
| 
 | |
|     Scup = (Dcup[Lcup - 1] << 4) + (Dcup[Lcup - 2] & 0x0F);
 | |
| 
 | |
|     if (Scup < 2 || Scup > Lcup || Scup > 4079) {
 | |
|         av_log(s->avctx, AV_LOG_ERROR, "Cleanup pass suffix length is invalid %d\n",
 | |
|                Scup);
 | |
|         ret = AVERROR_INVALIDDATA;
 | |
|         goto free;
 | |
|     }
 | |
|     Pcup = Lcup - Scup;
 | |
| 
 | |
|     /* modDcup shall be done before the creation of vlc instance. */
 | |
|     Dcup[Lcup - 1] = 0xFF;
 | |
|     Dcup[Lcup - 2] |= 0x0F;
 | |
| 
 | |
|     /* Magnitude and refinement */
 | |
|     jpeg2000_init_zero(&mag_sgn);
 | |
|     jpeg2000_bitbuf_refill_forward(&mag_sgn, Dcup, Pcup);
 | |
| 
 | |
|     /* Significance propagation */
 | |
|     jpeg2000_init_zero(&sig_prop);
 | |
| 
 | |
|     /* Adaptive run length */
 | |
|     jpeg2000_init_mel(&mel, Pcup);
 | |
| 
 | |
|     /* Variable Length coding */
 | |
|     jpeg2000_init_vlc(&vlc, Lcup, Pcup, Dcup);
 | |
| 
 | |
|     jpeg2000_init_mel_decoder(&mel_state);
 | |
| 
 | |
|     sample_buf = av_calloc((width + 4) * (height + 4), sizeof(int32_t));
 | |
|     block_states = av_calloc((width + 4) * (height + 4), sizeof(uint8_t));
 | |
| 
 | |
|     if (!sample_buf || !block_states) {
 | |
|         ret = AVERROR(ENOMEM);
 | |
|         goto free;
 | |
|     }
 | |
|     if ((ret = jpeg2000_decode_ht_cleanup_segment(s, cblk, t1, &mel_state, &mel, &vlc,
 | |
|                                           &mag_sgn, Dcup, Lcup, Pcup, pLSB, width,
 | |
|                                           height, sample_buf, block_states)) < 0)
 | |
|         goto free;
 | |
| 
 | |
|     if (cblk->npasses > 1)
 | |
|         jpeg2000_decode_sigprop_segment(cblk, width, height, Dref, Lref,
 | |
|                                 pLSB - 1, sample_buf, block_states);
 | |
| 
 | |
|     if (cblk->npasses > 2) {
 | |
| 
 | |
|         if (Lref < 2){
 | |
|             av_log(s->avctx,AV_LOG_ERROR,"Invalid magnitude refinement length\n");
 | |
|             ret = AVERROR_INVALIDDATA;
 | |
|             goto free;
 | |
|         }
 | |
|         if ((ret = jpeg2000_decode_magref_segment(width, height, Dref, Lref,
 | |
|                                                   pLSB - 1, sample_buf, block_states)) < 0)
 | |
|             goto free;
 | |
|     }
 | |
| 
 | |
|     pLSB = 31 - M_b;
 | |
| 
 | |
|     /* Reconstruct the sample values */
 | |
|     for (int y = 0; y < height; y++) {
 | |
|         for (int x = 0; x < width; x++) {
 | |
|             n = x + (y * t1->stride);
 | |
|             val = sample_buf[x + (y * width)];
 | |
|             /* Convert sign-magnitude to two's complement. */
 | |
|             val = val >> 31 ? 0x80000000 - val : val;
 | |
|             val >>= (pLSB - 1);
 | |
|             t1->data[n] = val;
 | |
|         }
 | |
|     }
 | |
| free:
 | |
|     av_freep(&sample_buf);
 | |
|     av_freep(&block_states);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * CtxVLC tables (see Rec. ITU-T T.800, Annex C) as found at
 | |
|  * https://github.com/osamu620/OpenHTJ2K (author: Osamu Watanabe)
 | |
|  */
 | |
| static const uint16_t dec_cxt_vlc_table1[1024] = {
 | |
|         0x0016, 0x006A, 0x0046, 0x00DD, 0x0086, 0x888B, 0x0026, 0x444D, 0x0016, 0x00AA, 0x0046, 0x88AD, 0x0086,
 | |
|         0x003A, 0x0026, 0x00DE, 0x0016, 0x00CA, 0x0046, 0x009D, 0x0086, 0x005A, 0x0026, 0x222D, 0x0016, 0x009A,
 | |
|         0x0046, 0x007D, 0x0086, 0x01FD, 0x0026, 0x007E, 0x0016, 0x006A, 0x0046, 0x88CD, 0x0086, 0x888B, 0x0026,
 | |
|         0x111D, 0x0016, 0x00AA, 0x0046, 0x005D, 0x0086, 0x003A, 0x0026, 0x00EE, 0x0016, 0x00CA, 0x0046, 0x00BD,
 | |
|         0x0086, 0x005A, 0x0026, 0x11FF, 0x0016, 0x009A, 0x0046, 0x003D, 0x0086, 0x04ED, 0x0026, 0x2AAF, 0x0016,
 | |
|         0x006A, 0x0046, 0x00DD, 0x0086, 0x888B, 0x0026, 0x444D, 0x0016, 0x00AA, 0x0046, 0x88AD, 0x0086, 0x003A,
 | |
|         0x0026, 0x44EF, 0x0016, 0x00CA, 0x0046, 0x009D, 0x0086, 0x005A, 0x0026, 0x222D, 0x0016, 0x009A, 0x0046,
 | |
|         0x007D, 0x0086, 0x01FD, 0x0026, 0x00BE, 0x0016, 0x006A, 0x0046, 0x88CD, 0x0086, 0x888B, 0x0026, 0x111D,
 | |
|         0x0016, 0x00AA, 0x0046, 0x005D, 0x0086, 0x003A, 0x0026, 0x4CCF, 0x0016, 0x00CA, 0x0046, 0x00BD, 0x0086,
 | |
|         0x005A, 0x0026, 0x00FE, 0x0016, 0x009A, 0x0046, 0x003D, 0x0086, 0x04ED, 0x0026, 0x006F, 0x0002, 0x0088,
 | |
|         0x0002, 0x005C, 0x0002, 0x0018, 0x0002, 0x00DE, 0x0002, 0x0028, 0x0002, 0x009C, 0x0002, 0x004A, 0x0002,
 | |
|         0x007E, 0x0002, 0x0088, 0x0002, 0x00CC, 0x0002, 0x0018, 0x0002, 0x888F, 0x0002, 0x0028, 0x0002, 0x00FE,
 | |
|         0x0002, 0x003A, 0x0002, 0x222F, 0x0002, 0x0088, 0x0002, 0x04FD, 0x0002, 0x0018, 0x0002, 0x00BE, 0x0002,
 | |
|         0x0028, 0x0002, 0x00BF, 0x0002, 0x004A, 0x0002, 0x006E, 0x0002, 0x0088, 0x0002, 0x00AC, 0x0002, 0x0018,
 | |
|         0x0002, 0x444F, 0x0002, 0x0028, 0x0002, 0x00EE, 0x0002, 0x003A, 0x0002, 0x113F, 0x0002, 0x0088, 0x0002,
 | |
|         0x005C, 0x0002, 0x0018, 0x0002, 0x00CF, 0x0002, 0x0028, 0x0002, 0x009C, 0x0002, 0x004A, 0x0002, 0x006F,
 | |
|         0x0002, 0x0088, 0x0002, 0x00CC, 0x0002, 0x0018, 0x0002, 0x009F, 0x0002, 0x0028, 0x0002, 0x00EF, 0x0002,
 | |
|         0x003A, 0x0002, 0x233F, 0x0002, 0x0088, 0x0002, 0x04FD, 0x0002, 0x0018, 0x0002, 0x00AF, 0x0002, 0x0028,
 | |
|         0x0002, 0x44FF, 0x0002, 0x004A, 0x0002, 0x005F, 0x0002, 0x0088, 0x0002, 0x00AC, 0x0002, 0x0018, 0x0002,
 | |
|         0x007F, 0x0002, 0x0028, 0x0002, 0x00DF, 0x0002, 0x003A, 0x0002, 0x111F, 0x0002, 0x0028, 0x0002, 0x005C,
 | |
|         0x0002, 0x008A, 0x0002, 0x00BF, 0x0002, 0x0018, 0x0002, 0x00FE, 0x0002, 0x00CC, 0x0002, 0x007E, 0x0002,
 | |
|         0x0028, 0x0002, 0x8FFF, 0x0002, 0x004A, 0x0002, 0x007F, 0x0002, 0x0018, 0x0002, 0x00DF, 0x0002, 0x00AC,
 | |
|         0x0002, 0x133F, 0x0002, 0x0028, 0x0002, 0x222D, 0x0002, 0x008A, 0x0002, 0x00BE, 0x0002, 0x0018, 0x0002,
 | |
|         0x44EF, 0x0002, 0x2AAD, 0x0002, 0x006E, 0x0002, 0x0028, 0x0002, 0x15FF, 0x0002, 0x004A, 0x0002, 0x009E,
 | |
|         0x0002, 0x0018, 0x0002, 0x00CF, 0x0002, 0x003C, 0x0002, 0x223F, 0x0002, 0x0028, 0x0002, 0x005C, 0x0002,
 | |
|         0x008A, 0x0002, 0x2BBF, 0x0002, 0x0018, 0x0002, 0x04EF, 0x0002, 0x00CC, 0x0002, 0x006F, 0x0002, 0x0028,
 | |
|         0x0002, 0x27FF, 0x0002, 0x004A, 0x0002, 0x009F, 0x0002, 0x0018, 0x0002, 0x00DE, 0x0002, 0x00AC, 0x0002,
 | |
|         0x444F, 0x0002, 0x0028, 0x0002, 0x222D, 0x0002, 0x008A, 0x0002, 0x8AAF, 0x0002, 0x0018, 0x0002, 0x00EE,
 | |
|         0x0002, 0x2AAD, 0x0002, 0x005F, 0x0002, 0x0028, 0x0002, 0x44FF, 0x0002, 0x004A, 0x0002, 0x888F, 0x0002,
 | |
|         0x0018, 0x0002, 0xAAAF, 0x0002, 0x003C, 0x0002, 0x111F, 0x0004, 0x8FFD, 0x0028, 0x005C, 0x0004, 0x00BC,
 | |
|         0x008A, 0x66FF, 0x0004, 0x00CD, 0x0018, 0x111D, 0x0004, 0x009C, 0x003A, 0x8AAF, 0x0004, 0x00FC, 0x0028,
 | |
|         0x133D, 0x0004, 0x00AC, 0x004A, 0x3BBF, 0x0004, 0x2BBD, 0x0018, 0x5FFF, 0x0004, 0x006C, 0x157D, 0x455F,
 | |
|         0x0004, 0x2FFD, 0x0028, 0x222D, 0x0004, 0x22AD, 0x008A, 0x44EF, 0x0004, 0x00CC, 0x0018, 0x4FFF, 0x0004,
 | |
|         0x007C, 0x003A, 0x447F, 0x0004, 0x04DD, 0x0028, 0x233D, 0x0004, 0x009D, 0x004A, 0x00DE, 0x0004, 0x88BD,
 | |
|         0x0018, 0xAFFF, 0x0004, 0x115D, 0x1FFD, 0x444F, 0x0004, 0x8FFD, 0x0028, 0x005C, 0x0004, 0x00BC, 0x008A,
 | |
|         0x8CEF, 0x0004, 0x00CD, 0x0018, 0x111D, 0x0004, 0x009C, 0x003A, 0x888F, 0x0004, 0x00FC, 0x0028, 0x133D,
 | |
|         0x0004, 0x00AC, 0x004A, 0x44DF, 0x0004, 0x2BBD, 0x0018, 0x8AFF, 0x0004, 0x006C, 0x157D, 0x006F, 0x0004,
 | |
|         0x2FFD, 0x0028, 0x222D, 0x0004, 0x22AD, 0x008A, 0x00EE, 0x0004, 0x00CC, 0x0018, 0x2EEF, 0x0004, 0x007C,
 | |
|         0x003A, 0x277F, 0x0004, 0x04DD, 0x0028, 0x233D, 0x0004, 0x009D, 0x004A, 0x1BBF, 0x0004, 0x88BD, 0x0018,
 | |
|         0x37FF, 0x0004, 0x115D, 0x1FFD, 0x333F, 0x0002, 0x0088, 0x0002, 0x02ED, 0x0002, 0x00CA, 0x0002, 0x4CCF,
 | |
|         0x0002, 0x0048, 0x0002, 0x23FF, 0x0002, 0x001A, 0x0002, 0x888F, 0x0002, 0x0088, 0x0002, 0x006C, 0x0002,
 | |
|         0x002A, 0x0002, 0x00AF, 0x0002, 0x0048, 0x0002, 0x22EF, 0x0002, 0x00AC, 0x0002, 0x005F, 0x0002, 0x0088,
 | |
|         0x0002, 0x444D, 0x0002, 0x00CA, 0x0002, 0xCCCF, 0x0002, 0x0048, 0x0002, 0x00FE, 0x0002, 0x001A, 0x0002,
 | |
|         0x006F, 0x0002, 0x0088, 0x0002, 0x005C, 0x0002, 0x002A, 0x0002, 0x009F, 0x0002, 0x0048, 0x0002, 0x00DF,
 | |
|         0x0002, 0x03FD, 0x0002, 0x222F, 0x0002, 0x0088, 0x0002, 0x02ED, 0x0002, 0x00CA, 0x0002, 0x8CCF, 0x0002,
 | |
|         0x0048, 0x0002, 0x11FF, 0x0002, 0x001A, 0x0002, 0x007E, 0x0002, 0x0088, 0x0002, 0x006C, 0x0002, 0x002A,
 | |
|         0x0002, 0x007F, 0x0002, 0x0048, 0x0002, 0x00EE, 0x0002, 0x00AC, 0x0002, 0x003E, 0x0002, 0x0088, 0x0002,
 | |
|         0x444D, 0x0002, 0x00CA, 0x0002, 0x00BE, 0x0002, 0x0048, 0x0002, 0x00BF, 0x0002, 0x001A, 0x0002, 0x003F,
 | |
|         0x0002, 0x0088, 0x0002, 0x005C, 0x0002, 0x002A, 0x0002, 0x009E, 0x0002, 0x0048, 0x0002, 0x00DE, 0x0002,
 | |
|         0x03FD, 0x0002, 0x111F, 0x0004, 0x8AED, 0x0048, 0x888D, 0x0004, 0x00DC, 0x00CA, 0x3FFF, 0x0004, 0xCFFD,
 | |
|         0x002A, 0x003D, 0x0004, 0x00BC, 0x005A, 0x8DDF, 0x0004, 0x8FFD, 0x0048, 0x006C, 0x0004, 0x027D, 0x008A,
 | |
|         0x99FF, 0x0004, 0x00EC, 0x00FA, 0x003C, 0x0004, 0x00AC, 0x001A, 0x009F, 0x0004, 0x2FFD, 0x0048, 0x007C,
 | |
|         0x0004, 0x44CD, 0x00CA, 0x67FF, 0x0004, 0x1FFD, 0x002A, 0x444D, 0x0004, 0x00AD, 0x005A, 0x8CCF, 0x0004,
 | |
|         0x4FFD, 0x0048, 0x445D, 0x0004, 0x01BD, 0x008A, 0x4EEF, 0x0004, 0x45DD, 0x00FA, 0x111D, 0x0004, 0x009C,
 | |
|         0x001A, 0x222F, 0x0004, 0x8AED, 0x0048, 0x888D, 0x0004, 0x00DC, 0x00CA, 0xAFFF, 0x0004, 0xCFFD, 0x002A,
 | |
|         0x003D, 0x0004, 0x00BC, 0x005A, 0x11BF, 0x0004, 0x8FFD, 0x0048, 0x006C, 0x0004, 0x027D, 0x008A, 0x22EF,
 | |
|         0x0004, 0x00EC, 0x00FA, 0x003C, 0x0004, 0x00AC, 0x001A, 0x227F, 0x0004, 0x2FFD, 0x0048, 0x007C, 0x0004,
 | |
|         0x44CD, 0x00CA, 0x5DFF, 0x0004, 0x1FFD, 0x002A, 0x444D, 0x0004, 0x00AD, 0x005A, 0x006F, 0x0004, 0x4FFD,
 | |
|         0x0048, 0x445D, 0x0004, 0x01BD, 0x008A, 0x11DF, 0x0004, 0x45DD, 0x00FA, 0x111D, 0x0004, 0x009C, 0x001A,
 | |
|         0x155F, 0x0006, 0x00FC, 0x0018, 0x111D, 0x0048, 0x888D, 0x00AA, 0x4DDF, 0x0006, 0x2AAD, 0x005A, 0x67FF,
 | |
|         0x0028, 0x223D, 0x00BC, 0xAAAF, 0x0006, 0x00EC, 0x0018, 0x5FFF, 0x0048, 0x006C, 0x008A, 0xCCCF, 0x0006,
 | |
|         0x009D, 0x00CA, 0x44EF, 0x0028, 0x003C, 0x8FFD, 0x137F, 0x0006, 0x8EED, 0x0018, 0x1FFF, 0x0048, 0x007C,
 | |
|         0x00AA, 0x4CCF, 0x0006, 0x227D, 0x005A, 0x1DDF, 0x0028, 0x444D, 0x4FFD, 0x155F, 0x0006, 0x00DC, 0x0018,
 | |
|         0x2EEF, 0x0048, 0x445D, 0x008A, 0x22BF, 0x0006, 0x009C, 0x00CA, 0x8CDF, 0x0028, 0x222D, 0x2FFD, 0x226F,
 | |
|         0x0006, 0x00FC, 0x0018, 0x111D, 0x0048, 0x888D, 0x00AA, 0x1BBF, 0x0006, 0x2AAD, 0x005A, 0x33FF, 0x0028,
 | |
|         0x223D, 0x00BC, 0x8AAF, 0x0006, 0x00EC, 0x0018, 0x9BFF, 0x0048, 0x006C, 0x008A, 0x8ABF, 0x0006, 0x009D,
 | |
|         0x00CA, 0x4EEF, 0x0028, 0x003C, 0x8FFD, 0x466F, 0x0006, 0x8EED, 0x0018, 0xCFFF, 0x0048, 0x007C, 0x00AA,
 | |
|         0x8CCF, 0x0006, 0x227D, 0x005A, 0xAEEF, 0x0028, 0x444D, 0x4FFD, 0x477F, 0x0006, 0x00DC, 0x0018, 0xAFFF,
 | |
|         0x0048, 0x445D, 0x008A, 0x2BBF, 0x0006, 0x009C, 0x00CA, 0x44DF, 0x0028, 0x222D, 0x2FFD, 0x133F, 0x00F6,
 | |
|         0xAFFD, 0x1FFB, 0x003C, 0x0008, 0x23BD, 0x007A, 0x11DF, 0x00F6, 0x45DD, 0x2FFB, 0x4EEF, 0x00DA, 0x177D,
 | |
|         0xCFFD, 0x377F, 0x00F6, 0x3FFD, 0x8FFB, 0x111D, 0x0008, 0x009C, 0x005A, 0x1BBF, 0x00F6, 0x00CD, 0x00BA,
 | |
|         0x8DDF, 0x4FFB, 0x006C, 0x9BFD, 0x455F, 0x00F6, 0x67FD, 0x1FFB, 0x002C, 0x0008, 0x00AC, 0x007A, 0x009F,
 | |
|         0x00F6, 0x00AD, 0x2FFB, 0x7FFF, 0x00DA, 0x004C, 0x5FFD, 0x477F, 0x00F6, 0x00EC, 0x8FFB, 0x001C, 0x0008,
 | |
|         0x008C, 0x005A, 0x888F, 0x00F6, 0x00CC, 0x00BA, 0x2EEF, 0x4FFB, 0x115D, 0x8AED, 0x113F, 0x00F6, 0xAFFD,
 | |
|         0x1FFB, 0x003C, 0x0008, 0x23BD, 0x007A, 0x1DDF, 0x00F6, 0x45DD, 0x2FFB, 0xBFFF, 0x00DA, 0x177D, 0xCFFD,
 | |
|         0x447F, 0x00F6, 0x3FFD, 0x8FFB, 0x111D, 0x0008, 0x009C, 0x005A, 0x277F, 0x00F6, 0x00CD, 0x00BA, 0x22EF,
 | |
|         0x4FFB, 0x006C, 0x9BFD, 0x444F, 0x00F6, 0x67FD, 0x1FFB, 0x002C, 0x0008, 0x00AC, 0x007A, 0x11BF, 0x00F6,
 | |
|         0x00AD, 0x2FFB, 0xFFFF, 0x00DA, 0x004C, 0x5FFD, 0x233F, 0x00F6, 0x00EC, 0x8FFB, 0x001C, 0x0008, 0x008C,
 | |
|         0x005A, 0x006F, 0x00F6, 0x00CC, 0x00BA, 0x8BBF, 0x4FFB, 0x115D, 0x8AED, 0x222F};
 | |
| 
 | |
| static const uint16_t dec_cxt_vlc_table0[1024] = {
 | |
|         0x0026, 0x00AA, 0x0046, 0x006C, 0x0086, 0x8AED, 0x0018, 0x8DDF, 0x0026, 0x01BD, 0x0046, 0x5FFF, 0x0086,
 | |
|         0x027D, 0x005A, 0x155F, 0x0026, 0x003A, 0x0046, 0x444D, 0x0086, 0x4CCD, 0x0018, 0xCCCF, 0x0026, 0x2EFD,
 | |
|         0x0046, 0x99FF, 0x0086, 0x009C, 0x00CA, 0x133F, 0x0026, 0x00AA, 0x0046, 0x445D, 0x0086, 0x8CCD, 0x0018,
 | |
|         0x11DF, 0x0026, 0x4FFD, 0x0046, 0xCFFF, 0x0086, 0x009D, 0x005A, 0x007E, 0x0026, 0x003A, 0x0046, 0x1FFF,
 | |
|         0x0086, 0x88AD, 0x0018, 0x00BE, 0x0026, 0x8FFD, 0x0046, 0x4EEF, 0x0086, 0x888D, 0x00CA, 0x111F, 0x0026,
 | |
|         0x00AA, 0x0046, 0x006C, 0x0086, 0x8AED, 0x0018, 0x45DF, 0x0026, 0x01BD, 0x0046, 0x22EF, 0x0086, 0x027D,
 | |
|         0x005A, 0x227F, 0x0026, 0x003A, 0x0046, 0x444D, 0x0086, 0x4CCD, 0x0018, 0x11BF, 0x0026, 0x2EFD, 0x0046,
 | |
|         0x00FE, 0x0086, 0x009C, 0x00CA, 0x223F, 0x0026, 0x00AA, 0x0046, 0x445D, 0x0086, 0x8CCD, 0x0018, 0x00DE,
 | |
|         0x0026, 0x4FFD, 0x0046, 0xABFF, 0x0086, 0x009D, 0x005A, 0x006F, 0x0026, 0x003A, 0x0046, 0x6EFF, 0x0086,
 | |
|         0x88AD, 0x0018, 0x2AAF, 0x0026, 0x8FFD, 0x0046, 0x00EE, 0x0086, 0x888D, 0x00CA, 0x222F, 0x0004, 0x00CA,
 | |
|         0x0088, 0x027D, 0x0004, 0x4CCD, 0x0028, 0x00FE, 0x0004, 0x2AFD, 0x0048, 0x005C, 0x0004, 0x009D, 0x0018,
 | |
|         0x00DE, 0x0004, 0x01BD, 0x0088, 0x006C, 0x0004, 0x88AD, 0x0028, 0x11DF, 0x0004, 0x8AED, 0x0048, 0x003C,
 | |
|         0x0004, 0x888D, 0x0018, 0x111F, 0x0004, 0x00CA, 0x0088, 0x006D, 0x0004, 0x88CD, 0x0028, 0x88FF, 0x0004,
 | |
|         0x8BFD, 0x0048, 0x444D, 0x0004, 0x009C, 0x0018, 0x00BE, 0x0004, 0x4EFD, 0x0088, 0x445D, 0x0004, 0x00AC,
 | |
|         0x0028, 0x00EE, 0x0004, 0x45DD, 0x0048, 0x222D, 0x0004, 0x003D, 0x0018, 0x007E, 0x0004, 0x00CA, 0x0088,
 | |
|         0x027D, 0x0004, 0x4CCD, 0x0028, 0x1FFF, 0x0004, 0x2AFD, 0x0048, 0x005C, 0x0004, 0x009D, 0x0018, 0x11BF,
 | |
|         0x0004, 0x01BD, 0x0088, 0x006C, 0x0004, 0x88AD, 0x0028, 0x22EF, 0x0004, 0x8AED, 0x0048, 0x003C, 0x0004,
 | |
|         0x888D, 0x0018, 0x227F, 0x0004, 0x00CA, 0x0088, 0x006D, 0x0004, 0x88CD, 0x0028, 0x4EEF, 0x0004, 0x8BFD,
 | |
|         0x0048, 0x444D, 0x0004, 0x009C, 0x0018, 0x2AAF, 0x0004, 0x4EFD, 0x0088, 0x445D, 0x0004, 0x00AC, 0x0028,
 | |
|         0x8DDF, 0x0004, 0x45DD, 0x0048, 0x222D, 0x0004, 0x003D, 0x0018, 0x155F, 0x0004, 0x005A, 0x0088, 0x006C,
 | |
|         0x0004, 0x88DD, 0x0028, 0x23FF, 0x0004, 0x11FD, 0x0048, 0x444D, 0x0004, 0x00AD, 0x0018, 0x00BE, 0x0004,
 | |
|         0x137D, 0x0088, 0x155D, 0x0004, 0x00CC, 0x0028, 0x00DE, 0x0004, 0x02ED, 0x0048, 0x111D, 0x0004, 0x009D,
 | |
|         0x0018, 0x007E, 0x0004, 0x005A, 0x0088, 0x455D, 0x0004, 0x44CD, 0x0028, 0x00EE, 0x0004, 0x1FFD, 0x0048,
 | |
|         0x003C, 0x0004, 0x00AC, 0x0018, 0x555F, 0x0004, 0x47FD, 0x0088, 0x113D, 0x0004, 0x02BD, 0x0028, 0x477F,
 | |
|         0x0004, 0x4CDD, 0x0048, 0x8FFF, 0x0004, 0x009C, 0x0018, 0x222F, 0x0004, 0x005A, 0x0088, 0x006C, 0x0004,
 | |
|         0x88DD, 0x0028, 0x00FE, 0x0004, 0x11FD, 0x0048, 0x444D, 0x0004, 0x00AD, 0x0018, 0x888F, 0x0004, 0x137D,
 | |
|         0x0088, 0x155D, 0x0004, 0x00CC, 0x0028, 0x8CCF, 0x0004, 0x02ED, 0x0048, 0x111D, 0x0004, 0x009D, 0x0018,
 | |
|         0x006F, 0x0004, 0x005A, 0x0088, 0x455D, 0x0004, 0x44CD, 0x0028, 0x1DDF, 0x0004, 0x1FFD, 0x0048, 0x003C,
 | |
|         0x0004, 0x00AC, 0x0018, 0x227F, 0x0004, 0x47FD, 0x0088, 0x113D, 0x0004, 0x02BD, 0x0028, 0x22BF, 0x0004,
 | |
|         0x4CDD, 0x0048, 0x22EF, 0x0004, 0x009C, 0x0018, 0x233F, 0x0006, 0x4DDD, 0x4FFB, 0xCFFF, 0x0018, 0x113D,
 | |
|         0x005A, 0x888F, 0x0006, 0x23BD, 0x008A, 0x00EE, 0x002A, 0x155D, 0xAAFD, 0x277F, 0x0006, 0x44CD, 0x8FFB,
 | |
|         0x44EF, 0x0018, 0x467D, 0x004A, 0x2AAF, 0x0006, 0x00AC, 0x555B, 0x99DF, 0x1FFB, 0x003C, 0x5FFD, 0x266F,
 | |
|         0x0006, 0x1DDD, 0x4FFB, 0x6EFF, 0x0018, 0x177D, 0x005A, 0x1BBF, 0x0006, 0x88AD, 0x008A, 0x5DDF, 0x002A,
 | |
|         0x444D, 0x2FFD, 0x667F, 0x0006, 0x00CC, 0x8FFB, 0x2EEF, 0x0018, 0x455D, 0x004A, 0x119F, 0x0006, 0x009C,
 | |
|         0x555B, 0x8CCF, 0x1FFB, 0x111D, 0x8CED, 0x006E, 0x0006, 0x4DDD, 0x4FFB, 0x3FFF, 0x0018, 0x113D, 0x005A,
 | |
|         0x11BF, 0x0006, 0x23BD, 0x008A, 0x8DDF, 0x002A, 0x155D, 0xAAFD, 0x222F, 0x0006, 0x44CD, 0x8FFB, 0x00FE,
 | |
|         0x0018, 0x467D, 0x004A, 0x899F, 0x0006, 0x00AC, 0x555B, 0x00DE, 0x1FFB, 0x003C, 0x5FFD, 0x446F, 0x0006,
 | |
|         0x1DDD, 0x4FFB, 0x9BFF, 0x0018, 0x177D, 0x005A, 0x00BE, 0x0006, 0x88AD, 0x008A, 0xCDDF, 0x002A, 0x444D,
 | |
|         0x2FFD, 0x007E, 0x0006, 0x00CC, 0x8FFB, 0x4EEF, 0x0018, 0x455D, 0x004A, 0x377F, 0x0006, 0x009C, 0x555B,
 | |
|         0x8BBF, 0x1FFB, 0x111D, 0x8CED, 0x233F, 0x0004, 0x00AA, 0x0088, 0x047D, 0x0004, 0x01DD, 0x0028, 0x11DF,
 | |
|         0x0004, 0x27FD, 0x0048, 0x005C, 0x0004, 0x8AAD, 0x0018, 0x2BBF, 0x0004, 0x009C, 0x0088, 0x006C, 0x0004,
 | |
|         0x00CC, 0x0028, 0x00EE, 0x0004, 0x8CED, 0x0048, 0x222D, 0x0004, 0x888D, 0x0018, 0x007E, 0x0004, 0x00AA,
 | |
|         0x0088, 0x006D, 0x0004, 0x88CD, 0x0028, 0x00FE, 0x0004, 0x19FD, 0x0048, 0x003C, 0x0004, 0x2AAD, 0x0018,
 | |
|         0xAAAF, 0x0004, 0x8BFD, 0x0088, 0x005D, 0x0004, 0x00BD, 0x0028, 0x4CCF, 0x0004, 0x44ED, 0x0048, 0x4FFF,
 | |
|         0x0004, 0x223D, 0x0018, 0x111F, 0x0004, 0x00AA, 0x0088, 0x047D, 0x0004, 0x01DD, 0x0028, 0x99FF, 0x0004,
 | |
|         0x27FD, 0x0048, 0x005C, 0x0004, 0x8AAD, 0x0018, 0x00BE, 0x0004, 0x009C, 0x0088, 0x006C, 0x0004, 0x00CC,
 | |
|         0x0028, 0x00DE, 0x0004, 0x8CED, 0x0048, 0x222D, 0x0004, 0x888D, 0x0018, 0x444F, 0x0004, 0x00AA, 0x0088,
 | |
|         0x006D, 0x0004, 0x88CD, 0x0028, 0x2EEF, 0x0004, 0x19FD, 0x0048, 0x003C, 0x0004, 0x2AAD, 0x0018, 0x447F,
 | |
|         0x0004, 0x8BFD, 0x0088, 0x005D, 0x0004, 0x00BD, 0x0028, 0x009F, 0x0004, 0x44ED, 0x0048, 0x67FF, 0x0004,
 | |
|         0x223D, 0x0018, 0x133F, 0x0006, 0x00CC, 0x008A, 0x9DFF, 0x2FFB, 0x467D, 0x1FFD, 0x99BF, 0x0006, 0x2AAD,
 | |
|         0x002A, 0x66EF, 0x4FFB, 0x005C, 0x2EED, 0x377F, 0x0006, 0x89BD, 0x004A, 0x00FE, 0x8FFB, 0x006C, 0x67FD,
 | |
|         0x889F, 0x0006, 0x888D, 0x001A, 0x5DDF, 0x00AA, 0x222D, 0x89DD, 0x444F, 0x0006, 0x2BBD, 0x008A, 0xCFFF,
 | |
|         0x2FFB, 0x226D, 0x009C, 0x00BE, 0x0006, 0xAAAD, 0x002A, 0x1DDF, 0x4FFB, 0x003C, 0x4DDD, 0x466F, 0x0006,
 | |
|         0x8AAD, 0x004A, 0xAEEF, 0x8FFB, 0x445D, 0x8EED, 0x177F, 0x0006, 0x233D, 0x001A, 0x4CCF, 0x00AA, 0xAFFF,
 | |
|         0x88CD, 0x133F, 0x0006, 0x00CC, 0x008A, 0x77FF, 0x2FFB, 0x467D, 0x1FFD, 0x3BBF, 0x0006, 0x2AAD, 0x002A,
 | |
|         0x00EE, 0x4FFB, 0x005C, 0x2EED, 0x007E, 0x0006, 0x89BD, 0x004A, 0x4EEF, 0x8FFB, 0x006C, 0x67FD, 0x667F,
 | |
|         0x0006, 0x888D, 0x001A, 0x00DE, 0x00AA, 0x222D, 0x89DD, 0x333F, 0x0006, 0x2BBD, 0x008A, 0x57FF, 0x2FFB,
 | |
|         0x226D, 0x009C, 0x199F, 0x0006, 0xAAAD, 0x002A, 0x99DF, 0x4FFB, 0x003C, 0x4DDD, 0x155F, 0x0006, 0x8AAD,
 | |
|         0x004A, 0xCEEF, 0x8FFB, 0x445D, 0x8EED, 0x277F, 0x0006, 0x233D, 0x001A, 0x1BBF, 0x00AA, 0x3FFF, 0x88CD,
 | |
|         0x111F, 0x0006, 0x45DD, 0x2FFB, 0x111D, 0x0018, 0x467D, 0x8FFD, 0xCCCF, 0x0006, 0x19BD, 0x004A, 0x22EF,
 | |
|         0x002A, 0x222D, 0x3FFD, 0x888F, 0x0006, 0x00CC, 0x008A, 0x00FE, 0x0018, 0x115D, 0xCFFD, 0x8AAF, 0x0006,
 | |
|         0x00AC, 0x003A, 0x8CDF, 0x1FFB, 0x133D, 0x66FD, 0x466F, 0x0006, 0x8CCD, 0x2FFB, 0x5FFF, 0x0018, 0x006C,
 | |
|         0x4FFD, 0xABBF, 0x0006, 0x22AD, 0x004A, 0x00EE, 0x002A, 0x233D, 0xAEFD, 0x377F, 0x0006, 0x2BBD, 0x008A,
 | |
|         0x55DF, 0x0018, 0x005C, 0x177D, 0x119F, 0x0006, 0x009C, 0x003A, 0x4CCF, 0x1FFB, 0x333D, 0x8EED, 0x444F,
 | |
|         0x0006, 0x45DD, 0x2FFB, 0x111D, 0x0018, 0x467D, 0x8FFD, 0x99BF, 0x0006, 0x19BD, 0x004A, 0x2EEF, 0x002A,
 | |
|         0x222D, 0x3FFD, 0x667F, 0x0006, 0x00CC, 0x008A, 0x4EEF, 0x0018, 0x115D, 0xCFFD, 0x899F, 0x0006, 0x00AC,
 | |
|         0x003A, 0x00DE, 0x1FFB, 0x133D, 0x66FD, 0x226F, 0x0006, 0x8CCD, 0x2FFB, 0x9BFF, 0x0018, 0x006C, 0x4FFD,
 | |
|         0x00BE, 0x0006, 0x22AD, 0x004A, 0x1DDF, 0x002A, 0x233D, 0xAEFD, 0x007E, 0x0006, 0x2BBD, 0x008A, 0xCEEF,
 | |
|         0x0018, 0x005C, 0x177D, 0x277F, 0x0006, 0x009C, 0x003A, 0x8BBF, 0x1FFB, 0x333D, 0x8EED, 0x455F, 0x1FF9,
 | |
|         0x1DDD, 0xAFFB, 0x00DE, 0x8FF9, 0x001C, 0xFFFB, 0x477F, 0x4FF9, 0x177D, 0x3FFB, 0x3BBF, 0x2FF9, 0xAEEF,
 | |
|         0x8EED, 0x444F, 0x1FF9, 0x22AD, 0x000A, 0x8BBF, 0x8FF9, 0x00FE, 0xCFFD, 0x007E, 0x4FF9, 0x115D, 0x5FFB,
 | |
|         0x577F, 0x2FF9, 0x8DDF, 0x2EED, 0x333F, 0x1FF9, 0x2BBD, 0xAFFB, 0x88CF, 0x8FF9, 0xBFFF, 0xFFFB, 0x377F,
 | |
|         0x4FF9, 0x006D, 0x3FFB, 0x00BE, 0x2FF9, 0x66EF, 0x9FFD, 0x133F, 0x1FF9, 0x009D, 0x000A, 0xABBF, 0x8FF9,
 | |
|         0xDFFF, 0x6FFD, 0x006E, 0x4FF9, 0x002C, 0x5FFB, 0x888F, 0x2FF9, 0xCDDF, 0x4DDD, 0x222F, 0x1FF9, 0x1DDD,
 | |
|         0xAFFB, 0x4CCF, 0x8FF9, 0x001C, 0xFFFB, 0x277F, 0x4FF9, 0x177D, 0x3FFB, 0x99BF, 0x2FF9, 0xCEEF, 0x8EED,
 | |
|         0x004E, 0x1FF9, 0x22AD, 0x000A, 0x00AE, 0x8FF9, 0x7FFF, 0xCFFD, 0x005E, 0x4FF9, 0x115D, 0x5FFB, 0x009E,
 | |
|         0x2FF9, 0x5DDF, 0x2EED, 0x003E, 0x1FF9, 0x2BBD, 0xAFFB, 0x00CE, 0x8FF9, 0xEFFF, 0xFFFB, 0x667F, 0x4FF9,
 | |
|         0x006D, 0x3FFB, 0x8AAF, 0x2FF9, 0x00EE, 0x9FFD, 0x233F, 0x1FF9, 0x009D, 0x000A, 0x1BBF, 0x8FF9, 0x4EEF,
 | |
|         0x6FFD, 0x455F, 0x4FF9, 0x002C, 0x5FFB, 0x008E, 0x2FF9, 0x99DF, 0x4DDD, 0x111F};
 |