diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dca.c b/src/add-ons/media/plugins/avcodec/libavcodec/dca.c new file mode 100644 index 0000000000..ef691f2117 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dca.c @@ -0,0 +1,1269 @@ +/* + * DCA compatible decoder + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2004 Benjamin Zores + * Copyright (C) 2006 Benjamin Larsson + * Copyright (C) 2007 Konstantin Shishkov + * + * 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 + */ + +/** + * @file dca.c + */ + +#include +#include +#include + +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" +#include "dcadata.h" +#include "dcahuff.h" +#include "dca.h" + +//#define TRACE + +#define DCA_PRIM_CHANNELS_MAX (5) +#define DCA_SUBBANDS (32) +#define DCA_ABITS_MAX (32) /* Should be 28 */ +#define DCA_SUBSUBFAMES_MAX (4) +#define DCA_LFE_MAX (3) + +enum DCAMode { + DCA_MONO = 0, + DCA_CHANNEL, + DCA_STEREO, + DCA_STEREO_SUMDIFF, + DCA_STEREO_TOTAL, + DCA_3F, + DCA_2F1R, + DCA_3F1R, + DCA_2F2R, + DCA_3F2R, + DCA_4F2R +}; + +#define DCA_DOLBY 101 /* FIXME */ + +#define DCA_CHANNEL_BITS 6 +#define DCA_CHANNEL_MASK 0x3F + +#define DCA_LFE 0x80 + +#define HEADER_SIZE 14 +#define CONVERT_BIAS 384 + +#define DCA_MAX_FRAME_SIZE 16384 + +/** Bit allocation */ +typedef struct { + int offset; ///< code values offset + int maxbits[8]; ///< max bits in VLC + int wrap; ///< wrap for get_vlc2() + VLC vlc[8]; ///< actual codes +} BitAlloc; + +static BitAlloc dca_bitalloc_index; ///< indexes for samples VLC select +static BitAlloc dca_tmode; ///< transition mode VLCs +static BitAlloc dca_scalefactor; ///< scalefactor VLCs +static BitAlloc dca_smpl_bitalloc[11]; ///< samples VLCs + +/** Pre-calculated cosine modulation coefs for the QMF */ +static float cos_mod[544]; + +static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx) +{ + return get_vlc2(gb, ba->vlc[idx].table, ba->vlc[idx].bits, ba->wrap) + ba->offset; +} + +typedef struct { + AVCodecContext *avctx; + /* Frame header */ + int frame_type; ///< type of the current frame + int samples_deficit; ///< deficit sample count + int crc_present; ///< crc is present in the bitstream + int sample_blocks; ///< number of PCM sample blocks + int frame_size; ///< primary frame byte size + int amode; ///< audio channels arrangement + int sample_rate; ///< audio sampling rate + int bit_rate; ///< transmission bit rate + + int downmix; ///< embedded downmix enabled + int dynrange; ///< embedded dynamic range flag + int timestamp; ///< embedded time stamp flag + int aux_data; ///< auxiliary data flag + int hdcd; ///< source material is mastered in HDCD + int ext_descr; ///< extension audio descriptor flag + int ext_coding; ///< extended coding flag + int aspf; ///< audio sync word insertion flag + int lfe; ///< low frequency effects flag + int predictor_history; ///< predictor history flag + int header_crc; ///< header crc check bytes + int multirate_inter; ///< multirate interpolator switch + int version; ///< encoder software revision + int copy_history; ///< copy history + int source_pcm_res; ///< source pcm resolution + int front_sum; ///< front sum/difference flag + int surround_sum; ///< surround sum/difference flag + int dialog_norm; ///< dialog normalisation parameter + + /* Primary audio coding header */ + int subframes; ///< number of subframes + int total_channels; ///< number of channels including extensions + int prim_channels; ///< number of primary audio channels + int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count + int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband + int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index + int transient_huffman[DCA_PRIM_CHANNELS_MAX]; ///< transient mode code book + int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; ///< scale factor code book + int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; ///< bit allocation quantizer select + int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< quantization index codebook select + float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment + + /* Primary audio coding side information */ + int subsubframes; ///< number of subsubframes + int partial_samples; ///< partial subsubframe samples count + int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not) + int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs + int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index + int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< transition mode (transients) + int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) + int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook + int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors + int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients + int dynrange_coef; ///< dynamic range coefficient + + int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands + + float lfe_data[2 * DCA_SUBSUBFAMES_MAX * DCA_LFE_MAX * + 2 /*history */ ]; ///< Low frequency effect data + int lfe_scale_factor; + + /* Subband samples history (for ADPCM) */ + float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; + float subband_fir_hist[DCA_PRIM_CHANNELS_MAX][512]; + float subband_fir_noidea[DCA_PRIM_CHANNELS_MAX][64]; + + int output; ///< type of output + int bias; ///< output bias + + DECLARE_ALIGNED_16(float, samples[1536]); /* 6 * 256 = 1536, might only need 5 */ + DECLARE_ALIGNED_16(int16_t, tsamples[1536]); + + uint8_t dca_buffer[DCA_MAX_FRAME_SIZE]; + int dca_buffer_size; ///< how much data is in the dca_buffer + + GetBitContext gb; + /* Current position in DCA frame */ + int current_subframe; + int current_subsubframe; + + int debug_flag; ///< used for suppressing repeated error messages output + DSPContext dsp; +} DCAContext; + +static av_cold void dca_init_vlcs(void) +{ + static int vlcs_initialized = 0; + int i, j; + + if (vlcs_initialized) + return; + + dca_bitalloc_index.offset = 1; + dca_bitalloc_index.wrap = 2; + for (i = 0; i < 5; i++) + init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12, + bitalloc_12_bits[i], 1, 1, + bitalloc_12_codes[i], 2, 2, 1); + dca_scalefactor.offset = -64; + dca_scalefactor.wrap = 2; + for (i = 0; i < 5; i++) + init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129, + scales_bits[i], 1, 1, + scales_codes[i], 2, 2, 1); + dca_tmode.offset = 0; + dca_tmode.wrap = 1; + for (i = 0; i < 4; i++) + init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4, + tmode_bits[i], 1, 1, + tmode_codes[i], 2, 2, 1); + + for(i = 0; i < 10; i++) + for(j = 0; j < 7; j++){ + if(!bitalloc_codes[i][j]) break; + dca_smpl_bitalloc[i+1].offset = bitalloc_offsets[i]; + dca_smpl_bitalloc[i+1].wrap = 1 + (j > 4); + init_vlc(&dca_smpl_bitalloc[i+1].vlc[j], bitalloc_maxbits[i][j], + bitalloc_sizes[i], + bitalloc_bits[i][j], 1, 1, + bitalloc_codes[i][j], 2, 2, 1); + } + vlcs_initialized = 1; +} + +static inline void get_array(GetBitContext *gb, int *dst, int len, int bits) +{ + while(len--) + *dst++ = get_bits(gb, bits); +} + +static int dca_parse_frame_header(DCAContext * s) +{ + int i, j; + static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 }; + static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; + static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; + + s->bias = CONVERT_BIAS; + + init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); + + /* Sync code */ + get_bits(&s->gb, 32); + + /* Frame header */ + s->frame_type = get_bits(&s->gb, 1); + s->samples_deficit = get_bits(&s->gb, 5) + 1; + s->crc_present = get_bits(&s->gb, 1); + s->sample_blocks = get_bits(&s->gb, 7) + 1; + s->frame_size = get_bits(&s->gb, 14) + 1; + if (s->frame_size < 95) + return -1; + s->amode = get_bits(&s->gb, 6); + s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)]; + if (!s->sample_rate) + return -1; + s->bit_rate = dca_bit_rates[get_bits(&s->gb, 5)]; + if (!s->bit_rate) + return -1; + + s->downmix = get_bits(&s->gb, 1); + s->dynrange = get_bits(&s->gb, 1); + s->timestamp = get_bits(&s->gb, 1); + s->aux_data = get_bits(&s->gb, 1); + s->hdcd = get_bits(&s->gb, 1); + s->ext_descr = get_bits(&s->gb, 3); + s->ext_coding = get_bits(&s->gb, 1); + s->aspf = get_bits(&s->gb, 1); + s->lfe = get_bits(&s->gb, 2); + s->predictor_history = get_bits(&s->gb, 1); + + /* TODO: check CRC */ + if (s->crc_present) + s->header_crc = get_bits(&s->gb, 16); + + s->multirate_inter = get_bits(&s->gb, 1); + s->version = get_bits(&s->gb, 4); + s->copy_history = get_bits(&s->gb, 2); + s->source_pcm_res = get_bits(&s->gb, 3); + s->front_sum = get_bits(&s->gb, 1); + s->surround_sum = get_bits(&s->gb, 1); + s->dialog_norm = get_bits(&s->gb, 4); + + /* FIXME: channels mixing levels */ + s->output = s->amode; + if(s->lfe) s->output |= DCA_LFE; + +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "frame type: %i\n", s->frame_type); + av_log(s->avctx, AV_LOG_DEBUG, "samples deficit: %i\n", s->samples_deficit); + av_log(s->avctx, AV_LOG_DEBUG, "crc present: %i\n", s->crc_present); + av_log(s->avctx, AV_LOG_DEBUG, "sample blocks: %i (%i samples)\n", + s->sample_blocks, s->sample_blocks * 32); + av_log(s->avctx, AV_LOG_DEBUG, "frame size: %i bytes\n", s->frame_size); + av_log(s->avctx, AV_LOG_DEBUG, "amode: %i (%i channels)\n", + s->amode, dca_channels[s->amode]); + av_log(s->avctx, AV_LOG_DEBUG, "sample rate: %i (%i Hz)\n", + s->sample_rate, dca_sample_rates[s->sample_rate]); + av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i (%i bits/s)\n", + s->bit_rate, dca_bit_rates[s->bit_rate]); + av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix); + av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange); + av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp); + av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data); + av_log(s->avctx, AV_LOG_DEBUG, "hdcd: %i\n", s->hdcd); + av_log(s->avctx, AV_LOG_DEBUG, "ext descr: %i\n", s->ext_descr); + av_log(s->avctx, AV_LOG_DEBUG, "ext coding: %i\n", s->ext_coding); + av_log(s->avctx, AV_LOG_DEBUG, "aspf: %i\n", s->aspf); + av_log(s->avctx, AV_LOG_DEBUG, "lfe: %i\n", s->lfe); + av_log(s->avctx, AV_LOG_DEBUG, "predictor history: %i\n", + s->predictor_history); + av_log(s->avctx, AV_LOG_DEBUG, "header crc: %i\n", s->header_crc); + av_log(s->avctx, AV_LOG_DEBUG, "multirate inter: %i\n", + s->multirate_inter); + av_log(s->avctx, AV_LOG_DEBUG, "version number: %i\n", s->version); + av_log(s->avctx, AV_LOG_DEBUG, "copy history: %i\n", s->copy_history); + av_log(s->avctx, AV_LOG_DEBUG, + "source pcm resolution: %i (%i bits/sample)\n", + s->source_pcm_res, dca_bits_per_sample[s->source_pcm_res]); + av_log(s->avctx, AV_LOG_DEBUG, "front sum: %i\n", s->front_sum); + av_log(s->avctx, AV_LOG_DEBUG, "surround sum: %i\n", s->surround_sum); + av_log(s->avctx, AV_LOG_DEBUG, "dialog norm: %i\n", s->dialog_norm); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); +#endif + + /* Primary audio coding header */ + s->subframes = get_bits(&s->gb, 4) + 1; + s->total_channels = get_bits(&s->gb, 3) + 1; + s->prim_channels = s->total_channels; + if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) + s->prim_channels = DCA_PRIM_CHANNELS_MAX; /* We only support DTS core */ + + + for (i = 0; i < s->prim_channels; i++) { + s->subband_activity[i] = get_bits(&s->gb, 5) + 2; + if (s->subband_activity[i] > DCA_SUBBANDS) + s->subband_activity[i] = DCA_SUBBANDS; + } + for (i = 0; i < s->prim_channels; i++) { + s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; + if (s->vq_start_subband[i] > DCA_SUBBANDS) + s->vq_start_subband[i] = DCA_SUBBANDS; + } + get_array(&s->gb, s->joint_intensity, s->prim_channels, 3); + get_array(&s->gb, s->transient_huffman, s->prim_channels, 2); + get_array(&s->gb, s->scalefactor_huffman, s->prim_channels, 3); + get_array(&s->gb, s->bitalloc_huffman, s->prim_channels, 3); + + /* Get codebooks quantization indexes */ + memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); + for (j = 1; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); + + /* Get scale factor adjustment */ + for (j = 0; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + s->scalefactor_adj[i][j] = 1; + + for (j = 1; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + if (s->quant_index_huffman[i][j] < thr[j]) + s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)]; + + if (s->crc_present) { + /* Audio header CRC check */ + get_bits(&s->gb, 16); + } + + s->current_subframe = 0; + s->current_subsubframe = 0; + +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "subframes: %i\n", s->subframes); + av_log(s->avctx, AV_LOG_DEBUG, "prim channels: %i\n", s->prim_channels); + for(i = 0; i < s->prim_channels; i++){ + av_log(s->avctx, AV_LOG_DEBUG, "subband activity: %i\n", s->subband_activity[i]); + av_log(s->avctx, AV_LOG_DEBUG, "vq start subband: %i\n", s->vq_start_subband[i]); + av_log(s->avctx, AV_LOG_DEBUG, "joint intensity: %i\n", s->joint_intensity[i]); + av_log(s->avctx, AV_LOG_DEBUG, "transient mode codebook: %i\n", s->transient_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "scale factor codebook: %i\n", s->scalefactor_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "bit allocation quantizer: %i\n", s->bitalloc_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "quant index huff:"); + for (j = 0; j < 11; j++) + av_log(s->avctx, AV_LOG_DEBUG, " %i", + s->quant_index_huffman[i][j]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + av_log(s->avctx, AV_LOG_DEBUG, "scalefac adj:"); + for (j = 0; j < 11; j++) + av_log(s->avctx, AV_LOG_DEBUG, " %1.3f", s->scalefactor_adj[i][j]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } +#endif + + return 0; +} + + +static inline int get_scale(GetBitContext *gb, int level, int value) +{ + if (level < 5) { + /* huffman encoded */ + value += get_bitalloc(gb, &dca_scalefactor, level); + } else if(level < 8) + value = get_bits(gb, level + 1); + return value; +} + +static int dca_subframe_header(DCAContext * s) +{ + /* Primary audio coding side information */ + int j, k; + + s->subsubframes = get_bits(&s->gb, 2) + 1; + s->partial_samples = get_bits(&s->gb, 3); + for (j = 0; j < s->prim_channels; j++) { + for (k = 0; k < s->subband_activity[j]; k++) + s->prediction_mode[j][k] = get_bits(&s->gb, 1); + } + + /* Get prediction codebook */ + for (j = 0; j < s->prim_channels; j++) { + for (k = 0; k < s->subband_activity[j]; k++) { + if (s->prediction_mode[j][k] > 0) { + /* (Prediction coefficient VQ address) */ + s->prediction_vq[j][k] = get_bits(&s->gb, 12); + } + } + } + + /* Bit allocation index */ + for (j = 0; j < s->prim_channels; j++) { + for (k = 0; k < s->vq_start_subband[j]; k++) { + if (s->bitalloc_huffman[j] == 6) + s->bitalloc[j][k] = get_bits(&s->gb, 5); + else if (s->bitalloc_huffman[j] == 5) + s->bitalloc[j][k] = get_bits(&s->gb, 4); + else if (s->bitalloc_huffman[j] == 7) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid bit allocation index\n"); + return -1; + } else { + s->bitalloc[j][k] = + get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]); + } + + if (s->bitalloc[j][k] > 26) { +// av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n", +// j, k, s->bitalloc[j][k]); + return -1; + } + } + } + + /* Transition mode */ + for (j = 0; j < s->prim_channels; j++) { + for (k = 0; k < s->subband_activity[j]; k++) { + s->transition_mode[j][k] = 0; + if (s->subsubframes > 1 && + k < s->vq_start_subband[j] && s->bitalloc[j][k] > 0) { + s->transition_mode[j][k] = + get_bitalloc(&s->gb, &dca_tmode, s->transient_huffman[j]); + } + } + } + + for (j = 0; j < s->prim_channels; j++) { + const uint32_t *scale_table; + int scale_sum; + + memset(s->scale_factor[j], 0, s->subband_activity[j] * sizeof(s->scale_factor[0][0][0]) * 2); + + if (s->scalefactor_huffman[j] == 6) + scale_table = scale_factor_quant7; + else + scale_table = scale_factor_quant6; + + /* When huffman coded, only the difference is encoded */ + scale_sum = 0; + + for (k = 0; k < s->subband_activity[j]; k++) { + if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) { + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); + s->scale_factor[j][k][0] = scale_table[scale_sum]; + } + + if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) { + /* Get second scale factor */ + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); + s->scale_factor[j][k][1] = scale_table[scale_sum]; + } + } + } + + /* Joint subband scale factor codebook select */ + for (j = 0; j < s->prim_channels; j++) { + /* Transmitted only if joint subband coding enabled */ + if (s->joint_intensity[j] > 0) + s->joint_huff[j] = get_bits(&s->gb, 3); + } + + /* Scale factors for joint subband coding */ + for (j = 0; j < s->prim_channels; j++) { + int source_channel; + + /* Transmitted only if joint subband coding enabled */ + if (s->joint_intensity[j] > 0) { + int scale = 0; + source_channel = s->joint_intensity[j] - 1; + + /* When huffman coded, only the difference is encoded + * (is this valid as well for joint scales ???) */ + + for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) { + scale = get_scale(&s->gb, s->joint_huff[j], 0); + scale += 64; /* bias */ + s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */ + } + + if (!s->debug_flag & 0x02) { + av_log(s->avctx, AV_LOG_DEBUG, + "Joint stereo coding not supported\n"); + s->debug_flag |= 0x02; + } + } + } + + /* Stereo downmix coefficients */ + if (s->prim_channels > 2) { + if(s->downmix) { + for (j = 0; j < s->prim_channels; j++) { + s->downmix_coef[j][0] = get_bits(&s->gb, 7); + s->downmix_coef[j][1] = get_bits(&s->gb, 7); + } + } else { + int am = s->amode & DCA_CHANNEL_MASK; + for (j = 0; j < s->prim_channels; j++) { + s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; + s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; + } + } + } + + /* Dynamic range coefficient */ + if (s->dynrange) + s->dynrange_coef = get_bits(&s->gb, 8); + + /* Side information CRC check word */ + if (s->crc_present) { + get_bits(&s->gb, 16); + } + + /* + * Primary audio data arrays + */ + + /* VQ encoded high frequency subbands */ + for (j = 0; j < s->prim_channels; j++) + for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) + /* 1 vector -> 32 samples */ + s->high_freq_vq[j][k] = get_bits(&s->gb, 10); + + /* Low frequency effect data */ + if (s->lfe) { + /* LFE samples */ + int lfe_samples = 2 * s->lfe * s->subsubframes; + float lfe_scale; + + for (j = lfe_samples; j < lfe_samples * 2; j++) { + /* Signed 8 bits int */ + s->lfe_data[j] = get_sbits(&s->gb, 8); + } + + /* Scale factor index */ + s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 8)]; + + /* Quantization step size * scale factor */ + lfe_scale = 0.035 * s->lfe_scale_factor; + + for (j = lfe_samples; j < lfe_samples * 2; j++) + s->lfe_data[j] *= lfe_scale; + } + +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "subsubframes: %i\n", s->subsubframes); + av_log(s->avctx, AV_LOG_DEBUG, "partial samples: %i\n", + s->partial_samples); + for (j = 0; j < s->prim_channels; j++) { + av_log(s->avctx, AV_LOG_DEBUG, "prediction mode:"); + for (k = 0; k < s->subband_activity[j]; k++) + av_log(s->avctx, AV_LOG_DEBUG, " %i", s->prediction_mode[j][k]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for (j = 0; j < s->prim_channels; j++) { + for (k = 0; k < s->subband_activity[j]; k++) + av_log(s->avctx, AV_LOG_DEBUG, + "prediction coefs: %f, %f, %f, %f\n", + (float) adpcm_vb[s->prediction_vq[j][k]][0] / 8192, + (float) adpcm_vb[s->prediction_vq[j][k]][1] / 8192, + (float) adpcm_vb[s->prediction_vq[j][k]][2] / 8192, + (float) adpcm_vb[s->prediction_vq[j][k]][3] / 8192); + } + for (j = 0; j < s->prim_channels; j++) { + av_log(s->avctx, AV_LOG_DEBUG, "bitalloc index: "); + for (k = 0; k < s->vq_start_subband[j]; k++) + av_log(s->avctx, AV_LOG_DEBUG, "%2.2i ", s->bitalloc[j][k]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for (j = 0; j < s->prim_channels; j++) { + av_log(s->avctx, AV_LOG_DEBUG, "Transition mode:"); + for (k = 0; k < s->subband_activity[j]; k++) + av_log(s->avctx, AV_LOG_DEBUG, " %i", s->transition_mode[j][k]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for (j = 0; j < s->prim_channels; j++) { + av_log(s->avctx, AV_LOG_DEBUG, "Scale factor:"); + for (k = 0; k < s->subband_activity[j]; k++) { + if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) + av_log(s->avctx, AV_LOG_DEBUG, " %i", s->scale_factor[j][k][0]); + if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) + av_log(s->avctx, AV_LOG_DEBUG, " %i(t)", s->scale_factor[j][k][1]); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for (j = 0; j < s->prim_channels; j++) { + if (s->joint_intensity[j] > 0) { + int source_channel = s->joint_intensity[j] - 1; + av_log(s->avctx, AV_LOG_DEBUG, "Joint scale factor index:\n"); + for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) + av_log(s->avctx, AV_LOG_DEBUG, " %i", s->joint_scale_factor[j][k]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + } + if (s->prim_channels > 2 && s->downmix) { + av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); + for (j = 0; j < s->prim_channels; j++) { + av_log(s->avctx, AV_LOG_DEBUG, "Channel 0,%d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][0]]); + av_log(s->avctx, AV_LOG_DEBUG, "Channel 1,%d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][1]]); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for (j = 0; j < s->prim_channels; j++) + for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) + av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); + if(s->lfe){ + int lfe_samples = 2 * s->lfe * s->subsubframes; + av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n"); + for (j = lfe_samples; j < lfe_samples * 2; j++) + av_log(s->avctx, AV_LOG_DEBUG, " %f", s->lfe_data[j]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } +#endif + + return 0; +} + +static void qmf_32_subbands(DCAContext * s, int chans, + float samples_in[32][8], float *samples_out, + float scale, float bias) +{ + const float *prCoeff; + int i, j, k; + float praXin[33], *raXin = &praXin[1]; + + float *subband_fir_hist = s->subband_fir_hist[chans]; + float *subband_fir_hist2 = s->subband_fir_noidea[chans]; + + int chindex = 0, subindex; + + praXin[0] = 0.0; + + /* Select filter */ + if (!s->multirate_inter) /* Non-perfect reconstruction */ + prCoeff = fir_32bands_nonperfect; + else /* Perfect reconstruction */ + prCoeff = fir_32bands_perfect; + + /* Reconstructed channel sample index */ + for (subindex = 0; subindex < 8; subindex++) { + float t1, t2, sum[16], diff[16]; + + /* Load in one sample from each subband and clear inactive subbands */ + for (i = 0; i < s->subband_activity[chans]; i++) + raXin[i] = samples_in[i][subindex]; + for (; i < 32; i++) + raXin[i] = 0.0; + + /* Multiply by cosine modulation coefficients and + * create temporary arrays SUM and DIFF */ + for (j = 0, k = 0; k < 16; k++) { + t1 = 0.0; + t2 = 0.0; + for (i = 0; i < 16; i++, j++){ + t1 += (raXin[2 * i] + raXin[2 * i + 1]) * cos_mod[j]; + t2 += (raXin[2 * i] + raXin[2 * i - 1]) * cos_mod[j + 256]; + } + sum[k] = t1 + t2; + diff[k] = t1 - t2; + } + + j = 512; + /* Store history */ + for (k = 0; k < 16; k++) + subband_fir_hist[k] = cos_mod[j++] * sum[k]; + for (k = 0; k < 16; k++) + subband_fir_hist[32-k-1] = cos_mod[j++] * diff[k]; + + /* Multiply by filter coefficients */ + for (k = 31, i = 0; i < 32; i++, k--) + for (j = 0; j < 512; j += 64){ + subband_fir_hist2[i] += prCoeff[i+j] * ( subband_fir_hist[i+j] - subband_fir_hist[j+k]); + subband_fir_hist2[i+32] += prCoeff[i+j+32]*(-subband_fir_hist[i+j] - subband_fir_hist[j+k]); + } + + /* Create 32 PCM output samples */ + for (i = 0; i < 32; i++) + samples_out[chindex++] = subband_fir_hist2[i] * scale + bias; + + /* Update working arrays */ + memmove(&subband_fir_hist[32], &subband_fir_hist[0], (512 - 32) * sizeof(float)); + memmove(&subband_fir_hist2[0], &subband_fir_hist2[32], 32 * sizeof(float)); + memset(&subband_fir_hist2[32], 0, 32 * sizeof(float)); + } +} + +static void lfe_interpolation_fir(int decimation_select, + int num_deci_sample, float *samples_in, + float *samples_out, float scale, + float bias) +{ + /* samples_in: An array holding decimated samples. + * Samples in current subframe starts from samples_in[0], + * while samples_in[-1], samples_in[-2], ..., stores samples + * from last subframe as history. + * + * samples_out: An array holding interpolated samples + */ + + int decifactor, k, j; + const float *prCoeff; + + int interp_index = 0; /* Index to the interpolated samples */ + int deciindex; + + /* Select decimation filter */ + if (decimation_select == 1) { + decifactor = 128; + prCoeff = lfe_fir_128; + } else { + decifactor = 64; + prCoeff = lfe_fir_64; + } + /* Interpolation */ + for (deciindex = 0; deciindex < num_deci_sample; deciindex++) { + /* One decimated sample generates decifactor interpolated ones */ + for (k = 0; k < decifactor; k++) { + float rTmp = 0.0; + //FIXME the coeffs are symetric, fix that + for (j = 0; j < 512 / decifactor; j++) + rTmp += samples_in[deciindex - j] * prCoeff[k + j * decifactor]; + samples_out[interp_index++] = rTmp / scale + bias; + } + } +} + +/* downmixing routines */ +#define MIX_REAR1(samples, si1, rs, coef) \ + samples[i] += samples[si1] * coef[rs][0]; \ + samples[i+256] += samples[si1] * coef[rs][1]; + +#define MIX_REAR2(samples, si1, si2, rs, coef) \ + samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \ + samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1]; + +#define MIX_FRONT3(samples, coef) \ + t = samples[i]; \ + samples[i] = t * coef[0][0] + samples[i+256] * coef[1][0] + samples[i+512] * coef[2][0]; \ + samples[i+256] = t * coef[0][1] + samples[i+256] * coef[1][1] + samples[i+512] * coef[2][1]; + +#define DOWNMIX_TO_STEREO(op1, op2) \ + for(i = 0; i < 256; i++){ \ + op1 \ + op2 \ + } + +static void dca_downmix(float *samples, int srcfmt, + int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]) +{ + int i; + float t; + float coef[DCA_PRIM_CHANNELS_MAX][2]; + + for(i=0; i> 1; + + for (i = 0; i < 4; i++) { + values[i] = (code % levels) - offset; + code /= levels; + } + + if (code == 0) + return 0; + else { + av_log(NULL, AV_LOG_ERROR, "ERROR: block code look-up failed\n"); + return -1; + } +} + +static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 }; +static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 }; + +static int dca_subsubframe(DCAContext * s) +{ + int k, l; + int subsubframe = s->current_subsubframe; + + const float *quant_step_table; + + /* FIXME */ + float subband_samples[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8]; + + /* + * Audio data + */ + + /* Select quantization step size table */ + if (s->bit_rate == 0x1f) + quant_step_table = lossless_quant_d; + else + quant_step_table = lossy_quant_d; + + for (k = 0; k < s->prim_channels; k++) { + for (l = 0; l < s->vq_start_subband[k]; l++) { + int m; + + /* Select the mid-tread linear quantizer */ + int abits = s->bitalloc[k][l]; + + float quant_step_size = quant_step_table[abits]; + float rscale; + + /* + * Determine quantization index code book and its type + */ + + /* Select quantization index code book */ + int sel = s->quant_index_huffman[k][abits]; + + /* + * Extract bits from the bit stream + */ + if(!abits){ + memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0])); + }else if(abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table){ + if(abits <= 7){ + /* Block code */ + int block_code1, block_code2, size, levels; + int block[8]; + + size = abits_sizes[abits-1]; + levels = abits_levels[abits-1]; + + block_code1 = get_bits(&s->gb, size); + /* FIXME Should test return value */ + decode_blockcode(block_code1, levels, block); + block_code2 = get_bits(&s->gb, size); + decode_blockcode(block_code2, levels, &block[4]); + for (m = 0; m < 8; m++) + subband_samples[k][l][m] = block[m]; + }else{ + /* no coding */ + for (m = 0; m < 8; m++) + subband_samples[k][l][m] = get_sbits(&s->gb, abits - 3); + } + }else{ + /* Huffman coded */ + for (m = 0; m < 8; m++) + subband_samples[k][l][m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel); + } + + /* Deal with transients */ + if (s->transition_mode[k][l] && + subsubframe >= s->transition_mode[k][l]) + rscale = quant_step_size * s->scale_factor[k][l][1]; + else + rscale = quant_step_size * s->scale_factor[k][l][0]; + + rscale *= s->scalefactor_adj[k][sel]; + + for (m = 0; m < 8; m++) + subband_samples[k][l][m] *= rscale; + + /* + * Inverse ADPCM if in prediction mode + */ + if (s->prediction_mode[k][l]) { + int n; + for (m = 0; m < 8; m++) { + for (n = 1; n <= 4; n++) + if (m >= n) + subband_samples[k][l][m] += + (adpcm_vb[s->prediction_vq[k][l]][n - 1] * + subband_samples[k][l][m - n] / 8192); + else if (s->predictor_history) + subband_samples[k][l][m] += + (adpcm_vb[s->prediction_vq[k][l]][n - 1] * + s->subband_samples_hist[k][l][m - n + + 4] / 8192); + } + } + } + + /* + * Decode VQ encoded high frequencies + */ + for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) { + /* 1 vector -> 32 samples but we only need the 8 samples + * for this subsubframe. */ + int m; + + if (!s->debug_flag & 0x01) { + av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n"); + s->debug_flag |= 0x01; + } + + for (m = 0; m < 8; m++) { + subband_samples[k][l][m] = + high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 + + m] + * (float) s->scale_factor[k][l][0] / 16.0; + } + } + } + + /* Check for DSYNC after subsubframe */ + if (s->aspf || subsubframe == s->subsubframes - 1) { + if (0xFFFF == get_bits(&s->gb, 16)) { /* 0xFFFF */ +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "Got subframe DSYNC\n"); +#endif + } else { + av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); + } + } + + /* Backup predictor history for adpcm */ + for (k = 0; k < s->prim_channels; k++) + for (l = 0; l < s->vq_start_subband[k]; l++) + memcpy(s->subband_samples_hist[k][l], &subband_samples[k][l][4], + 4 * sizeof(subband_samples[0][0][0])); + + /* 32 subbands QMF */ + for (k = 0; k < s->prim_channels; k++) { +/* static float pcm_to_double[8] = + {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/ + qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * k], + M_SQRT1_2 /*pcm_to_double[s->source_pcm_res] */ , + 0 /*s->bias */ ); + } + + /* Down mixing */ + + if (s->prim_channels > dca_channels[s->output & DCA_CHANNEL_MASK]) { + dca_downmix(s->samples, s->amode, s->downmix_coef); + } + + /* Generate LFE samples for this subsubframe FIXME!!! */ + if (s->output & DCA_LFE) { + int lfe_samples = 2 * s->lfe * s->subsubframes; + int i_channels = dca_channels[s->output & DCA_CHANNEL_MASK]; + + lfe_interpolation_fir(s->lfe, 2 * s->lfe, + s->lfe_data + lfe_samples + + 2 * s->lfe * subsubframe, + &s->samples[256 * i_channels], + 256.0, 0 /* s->bias */); + /* Outputs 20bits pcm samples */ + } + + return 0; +} + + +static int dca_subframe_footer(DCAContext * s) +{ + int aux_data_count = 0, i; + int lfe_samples; + + /* + * Unpack optional information + */ + + if (s->timestamp) + get_bits(&s->gb, 32); + + if (s->aux_data) + aux_data_count = get_bits(&s->gb, 6); + + for (i = 0; i < aux_data_count; i++) + get_bits(&s->gb, 8); + + if (s->crc_present && (s->downmix || s->dynrange)) + get_bits(&s->gb, 16); + + lfe_samples = 2 * s->lfe * s->subsubframes; + for (i = 0; i < lfe_samples; i++) { + s->lfe_data[i] = s->lfe_data[i + lfe_samples]; + } + + return 0; +} + +/** + * Decode a dca frame block + * + * @param s pointer to the DCAContext + */ + +static int dca_decode_block(DCAContext * s) +{ + + /* Sanity check */ + if (s->current_subframe >= s->subframes) { + av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i", + s->current_subframe, s->subframes); + return -1; + } + + if (!s->current_subsubframe) { +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n"); +#endif + /* Read subframe header */ + if (dca_subframe_header(s)) + return -1; + } + + /* Read subsubframe */ +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n"); +#endif + if (dca_subsubframe(s)) + return -1; + + /* Update state */ + s->current_subsubframe++; + if (s->current_subsubframe >= s->subsubframes) { + s->current_subsubframe = 0; + s->current_subframe++; + } + if (s->current_subframe >= s->subframes) { +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n"); +#endif + /* Read subframe footer */ + if (dca_subframe_footer(s)) + return -1; + } + + return 0; +} + +/** + * Convert bitstream to one representation based on sync marker + */ +static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * dst, + int max_size) +{ + uint32_t mrk; + int i, tmp; + const uint16_t *ssrc = (const uint16_t *) src; + uint16_t *sdst = (uint16_t *) dst; + PutBitContext pb; + + if((unsigned)src_size > (unsigned)max_size) { + av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n"); + return -1; + } + + mrk = AV_RB32(src); + switch (mrk) { + case DCA_MARKER_RAW_BE: + memcpy(dst, src, src_size); + return src_size; + case DCA_MARKER_RAW_LE: + for (i = 0; i < (src_size + 1) >> 1; i++) + *sdst++ = bswap_16(*ssrc++); + return src_size; + case DCA_MARKER_14B_BE: + case DCA_MARKER_14B_LE: + init_put_bits(&pb, dst, max_size); + for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { + tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; + put_bits(&pb, 14, tmp); + } + flush_put_bits(&pb); + return (put_bits_count(&pb) + 7) >> 3; + default: + return -1; + } +} + +/** + * Main frame decoding function + * FIXME add arguments + */ +static int dca_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + const uint8_t * buf, int buf_size) +{ + + int i, j, k; + int16_t *samples = data; + DCAContext *s = avctx->priv_data; + int channels; + + + s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE); + if (s->dca_buffer_size == -1) { + av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); + return -1; + } + + init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); + if (dca_parse_frame_header(s) < 0) { + //seems like the frame is corrupt, try with the next one + *data_size=0; + return buf_size; + } + //set AVCodec values with parsed data + avctx->sample_rate = s->sample_rate; + avctx->bit_rate = s->bit_rate; + + channels = s->prim_channels + !!s->lfe; + if(avctx->request_channels == 2 && s->prim_channels > 2) { + channels = 2; + s->output = DCA_STEREO; + } + + /* There is nothing that prevents a dts frame to change channel configuration + but FFmpeg doesn't support that so only set the channels if it is previously + unset. Ideally during the first probe for channels the crc should be checked + and only set avctx->channels when the crc is ok. Right now the decoder could + set the channels based on a broken first frame.*/ + if (!avctx->channels) + avctx->channels = channels; + + if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) + return -1; + *data_size = 0; + for (i = 0; i < (s->sample_blocks / 8); i++) { + dca_decode_block(s); + s->dsp.float_to_int16(s->tsamples, s->samples, 256 * channels); + /* interleave samples */ + for (j = 0; j < 256; j++) { + for (k = 0; k < channels; k++) + samples[k] = s->tsamples[j + k * 256]; + samples += channels; + } + *data_size += 256 * sizeof(int16_t) * channels; + } + + return buf_size; +} + + + +/** + * Build the cosine modulation tables for the QMF + * + * @param s pointer to the DCAContext + */ + +static av_cold void pre_calc_cosmod(DCAContext * s) +{ + int i, j, k; + static int cosmod_initialized = 0; + + if(cosmod_initialized) return; + for (j = 0, k = 0; k < 16; k++) + for (i = 0; i < 16; i++) + cos_mod[j++] = cos((2 * i + 1) * (2 * k + 1) * M_PI / 64); + + for (k = 0; k < 16; k++) + for (i = 0; i < 16; i++) + cos_mod[j++] = cos((i) * (2 * k + 1) * M_PI / 32); + + for (k = 0; k < 16; k++) + cos_mod[j++] = 0.25 / (2 * cos((2 * k + 1) * M_PI / 128)); + + for (k = 0; k < 16; k++) + cos_mod[j++] = -0.25 / (2.0 * sin((2 * k + 1) * M_PI / 128)); + + cosmod_initialized = 1; +} + + +/** + * DCA initialization + * + * @param avctx pointer to the AVCodecContext + */ + +static av_cold int dca_decode_init(AVCodecContext * avctx) +{ + DCAContext *s = avctx->priv_data; + + s->avctx = avctx; + dca_init_vlcs(); + pre_calc_cosmod(s); + + dsputil_init(&s->dsp, avctx); + + /* allow downmixing to stereo */ + if (avctx->channels > 0 && avctx->request_channels < avctx->channels && + avctx->request_channels == 2) { + avctx->channels = avctx->request_channels; + } + + avctx->sample_fmt = SAMPLE_FMT_S16; + return 0; +} + + +AVCodec dca_decoder = { + .name = "dca", + .type = CODEC_TYPE_AUDIO, + .id = CODEC_ID_DTS, + .priv_data_size = sizeof(DCAContext), + .init = dca_decode_init, + .decode = dca_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dca.h b/src/add-ons/media/plugins/avcodec/libavcodec/dca.h new file mode 100644 index 0000000000..e2197a4408 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dca.h @@ -0,0 +1,34 @@ +/* + * DCA compatible decoder + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2004 Benjamin Zores + * Copyright (C) 2006 Benjamin Larsson + * Copyright (C) 2007 Konstantin Shishkov + * + * 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 + */ + +#ifndef FFMPEG_DCA_H +#define FFMPEG_DCA_H + +/** DCA syncwords, also used for bitstream type detection */ +#define DCA_MARKER_RAW_BE 0x7FFE8001 +#define DCA_MARKER_RAW_LE 0xFE7F0180 +#define DCA_MARKER_14B_BE 0x1FFFE800 +#define DCA_MARKER_14B_LE 0xFF1F00E8 + +#endif /* FFMPEG_DCA_H */ diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dca_parser.c b/src/add-ons/media/plugins/avcodec/libavcodec/dca_parser.c new file mode 100644 index 0000000000..f182506f8a --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dca_parser.c @@ -0,0 +1,131 @@ +/* + * DCA parser + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2004 Benjamin Zores + * Copyright (C) 2006 Benjamin Larsson + * Copyright (C) 2007 Konstantin Shishkov + * + * 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 + */ + +/** + * @file dca_parser.c + */ + +#include "parser.h" +#include "dca.h" + +typedef struct DCAParseContext { + ParseContext pc; + uint32_t lastmarker; + int size; + int framesize; +} DCAParseContext; + +#define IS_MARKER(state, i, buf, buf_size) \ + ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \ + || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \ + || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE) + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, + int buf_size) +{ + int start_found, i; + uint32_t state; + ParseContext *pc = &pc1->pc; + + start_found = pc->frame_start_found; + state = pc->state; + + i = 0; + if (!start_found) { + for (i = 0; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (IS_MARKER(state, i, buf, buf_size)) { + if (pc1->lastmarker && state == pc1->lastmarker) { + start_found = 1; + break; + } else if (!pc1->lastmarker) { + start_found = 1; + pc1->lastmarker = state; + break; + } + } + } + } + if (start_found) { + for (; i < buf_size; i++) { + pc1->size++; + state = (state << 8) | buf[i]; + if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size) && (!pc1->framesize || pc1->framesize == pc1->size)) { + pc->frame_start_found = 0; + pc->state = -1; + pc1->framesize = pc1->size; + pc1->size = 0; + return i - 3; + } + } + } + pc->frame_start_found = start_found; + pc->state = state; + return END_NOT_FOUND; +} + +static av_cold int dca_parse_init(AVCodecParserContext * s) +{ + DCAParseContext *pc1 = s->priv_data; + + pc1->lastmarker = 0; + return 0; +} + +static int dca_parse(AVCodecParserContext * s, + AVCodecContext * avctx, + const uint8_t ** poutbuf, int *poutbuf_size, + const uint8_t * buf, int buf_size) +{ + DCAParseContext *pc1 = s->priv_data; + ParseContext *pc = &pc1->pc; + int next; + + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = dca_find_frame_end(pc1, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser dca_parser = { + {CODEC_ID_DTS}, + sizeof(DCAParseContext), + dca_parse_init, + dca_parse, + ff_parse_close, +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dcadata.h b/src/add-ons/media/plugins/avcodec/libavcodec/dcadata.h new file mode 100644 index 0000000000..40e78360dc --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dcadata.h @@ -0,0 +1,8474 @@ +/* + * DCA compatible decoder data + * Copyright (C) 2004 Gildas Bazin + * Copyright (c) 2006 Benjamin Larsson + * + * 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 + */ + +/** + * @file dcadata.c + */ + +#ifndef FFMPEG_DCADATA_H +#define FFMPEG_DCADATA_H + +#include + +/* Generic tables */ + +static const uint32_t dca_sample_rates[16] = +{ + 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, + 12000, 24000, 48000, 96000, 192000 +}; + +static const uint32_t dca_bit_rates[32] = +{ + 32000, 56000, 64000, 96000, 112000, 128000, + 192000, 224000, 256000, 320000, 384000, + 448000, 512000, 576000, 640000, 768000, + 896000, 1024000, 1152000, 1280000, 1344000, + 1408000, 1411200, 1472000, 1536000, 1920000, + 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/ +}; + +static const uint8_t dca_channels[16] = +{ + 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8 +}; + +static const uint8_t dca_bits_per_sample[7] = +{ + 16, 16, 20, 20, 0, 24, 24 +}; + + +/* Adpcm data */ + +/* 16bits signed fractional Q13 binary codes */ +static const int16_t adpcm_vb[4096][4] = +{ + { 9928, -2618, -1093, -1263 }, + { 11077, -2876, -1747, -308 }, + { 10503, -1082, -1426, -1167 }, + { 9337, -2403, -1495, 274 }, + { 10698, -2529, -532, -1122 }, + { 10368, -3974, -1264, -750 }, + { 10070, -3667, 346, 863 }, + { 10278, -3093, 311, -576 }, + { 9894, -1330, -1428, -860 }, + { 10544, -1923, -1058, -971 }, + { 10996, -1632, -841, -1404 }, + { 11832, -3465, 1658, -1990 }, + { 10852, -688, -2658, -499 }, + { 10546, -1749, -147, -1733 }, + { 10801, -1004, -708, -1453 }, + { 10588, -441, -2113, -952 }, + { 10141, -3331, -582, -1432 }, + { 9608, -2590, 383, 258 }, + { 11422, -3265, 229, -1544 }, + { 10460, -1338, -713, -1568 }, + { 10306, -1721, -1660, -603 }, + { 9580, -1812, -1235, -1061 }, + { 11471, -2285, -1617, -607 }, + { 10081, -2225, -1408, -868 }, + { 10715, -2624, -1367, -704 }, + { 10616, -1871, -2770, -35 }, + { 9352, -2340, -1024, -1566 }, + { 11065, -1458, -1926, -735 }, + { 11334, -2056, -1041, -1144 }, + { 9825, -2048, -794, -1536 }, + { 11850, -2695, -1123, -867 }, + { 10654, -2226, -1891, -373 }, + { 10024, -1557, -808, -1069 }, + { 11142, -1266, -3238, 128 }, + { 11729, -3282, -514, -1011 }, + { 11402, -2094, -2335, -189 }, + { 10195, -3658, 181, -1875 }, + { 11431, -2626, -404, -1377 }, + { 11001, -3868, -619, -1077 }, + { 10894, -2559, 274, -1758 }, + { 9633, -1482, -2253, -773 }, + { 11245, -3321, 830, -1972 }, + { 9768, -2701, -199, -1859 }, + { 10500, -2042, 525, -2043 }, + { 11669, -4069, 293, -1468 }, + { 9192, -1991, -583, -61 }, + { 10057, -3220, -2015, -473 }, + { 9497, -2315, -2490, -467 }, + { 10455, -3069, -1194, -1007 }, + { 9994, -1936, -60, -1225 }, + { 9295, -2156, -1761, -1134 }, + { 10085, -3748, -1026, 197 }, + { 9334, -2360, 804, -351 }, + { 11561, -2553, 1352, -2313 }, + { 12837, -3998, 1195, -1958 }, + { 10114, -1100, -2414, -394 }, + { 9341, -2530, 315, 755 }, + { 10131, -3164, 1411, -674 }, + { 9535, -905, -1551, 579 }, + { 11717, -1519, -3051, 91 }, + { 9824, -2911, -2775, 192 }, + { 9662, -2934, -561, 1450 }, + { 11085, -3392, -1298, -659 }, + { 8955, -2102, -1899, 703 }, + { 8607, -1742, -4348, 814 }, + { 7640, -2063, -3617, 52 }, + { 7074, -826, -4325, 4375 }, + { 7714, 584, -4238, 1927 }, + { 6355, -952, -4912, 3127 }, + { 7069, -660, -6413, 4087 }, + { 8313, -132, -2964, -876 }, + { 6952, -1422, -3962, -24 }, + { 9299, -734, -3088, -263 }, + { 9484, -574, -4513, 466 }, + { 7246, -91, -3735, -704 }, + { 8325, -1417, -3090, -530 }, + { 6469, -1226, -4757, 829 }, + { 6652, -368, -5682, 1393 }, + { 7971, -1278, -2284, 1205 }, + { 7229, -699, -3556, 1840 }, + { 7994, 1284, -2729, 732 }, + { 9005, -698, -4522, 2189 }, + { 6963, 197, -2727, 380 }, + { 8527, 135, -3991, -213 }, + { 8840, 934, -3014, -567 }, + { 10125, 418, -3284, -371 }, + { 6367, 361, -2318, 2554 }, + { 7892, 172, -5247, 4673 }, + { 6674, 387, -5424, 4398 }, + { 6240, 684, -4047, 1219 }, + { 11170, -794, -5081, 1195 }, + { 11765, -648, -6265, 2052 }, + { 10845, -775, -3837, 366 }, + { 12496, -689, -8260, 3562 }, + { 7893, -1166, -4972, 988 }, + { 8592, 1052, -5986, 3087 }, + { 7277, 1874, -5685, 3579 }, + { 6900, 2016, -4809, 3491 }, + { 8530, -2405, -3250, 1986 }, + { 9426, 494, -7067, 5038 }, + { 10285, 564, -8210, 5370 }, + { 8749, -2207, -3980, 2852 }, + { 9653, -2686, -4300, 1400 }, + { 9770, -2286, -5663, 4233 }, + { 8490, -4, -7048, 4496 }, + { 7697, -1209, -5328, 3183 }, + { 6451, 801, -4324, -554 }, + { 7387, 1806, -5265, 545 }, + { 7450, -2302, -4445, 1418 }, + { 8817, -1370, -5827, 2168 }, + { 10324, -2406, -5629, 2579 }, + { 8863, -2578, -3537, 467 }, + { 6901, -1624, -3169, 3392 }, + { 7846, 156, -6948, 3381 }, + { 7928, -1115, -5972, 4816 }, + { 6089, -599, -4368, -320 }, + { 7833, 1246, -3960, -621 }, + { 8931, 2521, -6768, 2052 }, + { 8900, 1944, -4126, 40 }, + { 7661, -34, -2855, 2480 }, + { 5873, 474, -3262, 3712 }, + { 7535, -234, -4699, 216 }, + { 5856, 143, -5142, 73 }, + { 8944, -106, -5874, 3663 }, + { 7134, 426, -5879, 2895 }, + { 10199, 1011, -4762, 369 }, + { 8454, 264, -5971, 1291 }, + { 7822, -2449, -4333, 4540 }, + { 6200, -2758, -2632, 1497 }, + { 6070, -4315, -2699, 414 }, + { 7047, -3739, -3210, 1060 }, + { 5675, -3801, -2717, -407 }, + { 4789, -4063, -2628, -744 }, + { 4023, -3366, -3133, -726 }, + { 4296, -2407, -3381, -513 }, + { 4388, -2931, -2820, 1512 }, + { 4559, -4233, -1941, 1976 }, + { 6702, -3208, -1755, 1680 }, + { 4416, -3521, -1052, 2984 }, + { 7154, -4266, -1203, 3732 }, + { 3625, -4242, -3244, 1395 }, + { 6518, -2856, -1304, 2887 }, + { 6170, -1949, -3014, 3973 }, + { 5189, -2451, -4020, 3477 }, + { 6218, -2988, -1921, 3844 }, + { 4827, -3688, -1928, 3343 }, + { 6668, -3991, -2805, 3095 }, + { 5297, -3115, -3684, 2390 }, + { 5354, -4614, -2662, 1504 }, + { 4196, -3091, -4147, 1135 }, + { 3540, -2893, -4007, 100 }, + { 5569, -1602, -4007, 1909 }, + { 4341, -2091, -4272, 252 }, + { 5559, -2878, -3832, 498 }, + { 4548, -4479, -2898, -27 }, + { 5176, -2494, -4635, 1476 }, + { 3294, -3485, -3738, 716 }, + { 4920, -1229, -4195, -365 }, + { 3257, -3518, -3349, 2862 }, + { 5286, -1948, -3485, -778 }, + { 6502, -3051, -152, 2854 }, + { 5864, -4192, -1076, 3451 }, + { 4656, -3122, -3448, 179 }, + { 5907, -754, -1596, 3116 }, + { 7229, -3680, -1590, 2892 }, + { 5107, -3888, -3364, 806 }, + { 6764, -2635, -3450, 134 }, + { 5258, -2827, -2844, -1052 }, + { 5798, -1725, -4305, 205 }, + { 5404, -1213, -3362, 449 }, + { 6224, -2738, -3046, -581 }, + { 4223, -2438, -2725, 3745 }, + { 4751, -3411, -2123, 116 }, + { 3868, -3000, -3954, 2297 }, + { 6819, -2899, -4277, 2825 }, + { 4207, -4754, -2808, 865 }, + { 4804, -1494, -1997, 4688 }, + { 5282, -2213, -548, 3559 }, + { 5580, -1912, -566, 4370 }, + { 6168, -2857, -672, 4053 }, + { 6583, -4515, -2850, 1670 }, + { 6511, -3093, -3988, 1421 }, + { 4646, -1790, -1443, 3650 }, + { 5915, -924, -2020, 896 }, + { 7814, -4181, -3152, 2007 }, + { 6190, -2238, -4817, 2279 }, + { 4737, -4034, -3288, 1835 }, + { 8161, -3633, -3423, 3137 }, + { 7415, -2351, -2088, 4290 }, + { 4106, -2517, -62, 2905 }, + { 4909, -3145, -614, 4112 }, + { 4938, -3281, -397, 1100 }, + { -173, 919, 1589, -5363 }, + { -13, 796, -295, -6655 }, + { -1860, -829, 1141, -4555 }, + { 2298, -838, -664, -5005 }, + { -884, -1097, 2074, -4613 }, + { -101, 281, 2846, -4535 }, + { 1166, 453, 2429, -5910 }, + { 879, -664, 2370, -5452 }, + { 1415, -370, -1699, -4727 }, + { -1413, 1277, -669, -6649 }, + { 2133, 304, -968, -4624 }, + { 380, 586, -2087, -4892 }, + { 1336, 275, -82, -5789 }, + { -2459, 1057, -34, -5416 }, + { 2278, -1758, 866, -5653 }, + { 1945, -2295, -149, -5302 }, + { 1287, -3525, 996, -5255 }, + { 2297, 803, 1177, -6067 }, + { 187, -180, -619, -6202 }, + { -793, -2537, 1554, -5057 }, + { -2703, -204, -629, -5853 }, + { -1007, -146, 313, -5582 }, + { 830, 357, 869, -6363 }, + { -228, -575, -3177, -4433 }, + { -1001, -1553, -142, -5708 }, + { -1644, 1683, 1721, -4533 }, + { 893, 1924, -15, -5791 }, + { 2195, 2061, -262, -5471 }, + { 3031, 270, 311, -5096 }, + { 1912, 1638, -1523, -4677 }, + { -3142, -55, 253, -4914 }, + { 356, -1680, 343, -6123 }, + { -2241, -1734, -976, -5939 }, + { -2196, -2893, 547, -4938 }, + { -1245, 126, -1916, -5419 }, + { -249, -3755, -1422, -5594 }, + { 575, -2683, -1926, -4566 }, + { -762, 1885, 192, -5880 }, + { -811, -2562, -1068, -6013 }, + { -2264, -3086, -976, -4775 }, + { 70, -1215, 2880, -4410 }, + { 714, -3760, 2916, -4691 }, + { -244, -3404, 1740, -4493 }, + { 684, -5137, -328, -5608 }, + { -529, -3825, -1786, -4535 }, + { -713, -4743, -1118, -5546 }, + { 2718, -3788, 1798, -5708 }, + { -1639, -3679, -1564, -6095 }, + { 1693, -2642, -1389, -4539 }, + { 505, -1573, -1651, -4878 }, + { -835, -2256, -1941, -5352 }, + { 1464, -411, 1993, -6441 }, + { 493, -3184, -145, -6148 }, + { -1413, 499, -1617, -6479 }, + { -294, 1722, -1419, -5725 }, + { -2937, -1528, -175, -4624 }, + { -594, -5911, -56, -6146 }, + { -300, -4275, 1156, -5947 }, + { 552, -2643, 2669, -3959 }, + { 905, -4158, 1789, -5809 }, + { 1336, -2009, 2108, -5903 }, + { 1555, -3600, 1110, -6759 }, + { -1294, -3464, 77, -6084 }, + { -1139, -4006, -1270, -4181 }, + { -5094, -3296, 1092, -2847 }, + { -5503, -2883, 1984, -2067 }, + { -4671, -4218, -1417, -4132 }, + { -3763, -3818, 1262, -3082 }, + { -5132, -3430, 2928, -728 }, + { -5957, -2877, 1251, -2446 }, + { -4425, -2319, -212, -4276 }, + { -6201, -1993, 1774, -2182 }, + { -5500, -3836, 2201, -1396 }, + { -6934, -2334, 2366, -1293 }, + { -6124, -4140, 1337, -1977 }, + { -6553, -4186, 1756, -1325 }, + { -5126, -1258, 744, -3656 }, + { -5167, -1390, 1581, -2895 }, + { -4525, -3398, 2429, -1865 }, + { -4076, -3183, 2027, -2510 }, + { -6191, -3274, 1838, -1814 }, + { -4454, -2753, 2723, -1185 }, + { -6655, -4797, 251, -2595 }, + { -6332, -2232, 1832, 217 }, + { -5869, -1698, 134, 340 }, + { -6614, -1045, 2126, -1932 }, + { -4859, -2107, 2010, -2435 }, + { -6274, -1622, 2808, -1374 }, + { -3119, -3209, 521, -3988 }, + { -5676, -2082, -420, -2711 }, + { -7073, -3623, 696, -2343 }, + { -5986, -4224, 572, -2454 }, + { -4340, -4521, 882, -2771 }, + { -6178, -1933, 535, -1444 }, + { -4923, -4163, 1744, -2066 }, + { -6410, -1519, 1058, -2683 }, + { -5077, -1185, 856, -2216 }, + { -7091, -2444, 687, -2597 }, + { -5284, -2165, 3239, -993 }, + { -4763, -1497, 197, -3179 }, + { -4128, -4958, -396, -3578 }, + { -5054, -3878, -647, -2672 }, + { -7005, -3348, 1679, -1579 }, + { -5767, -1017, 2582, -1915 }, + { -7069, -2787, 1331, -2070 }, + { -5532, -2296, 706, -2950 }, + { -5059, -3543, -821, -3637 }, + { -6639, -1835, 1016, -696 }, + { -5611, -5220, -694, -3371 }, + { -5994, -2803, 2933, -729 }, + { -5948, -619, 1596, -2676 }, + { -5486, -4419, 153, -3265 }, + { -4329, -3440, 1646, -1439 }, + { -4083, -3978, 177, -3569 }, + { -4289, -2599, 1224, -3075 }, + { -5707, -3253, 1912, -759 }, + { -6606, -3437, 2562, -571 }, + { -5254, -2444, 769, -352 }, + { -6545, -3154, 582, -1103 }, + { -5328, -2241, 2566, -1775 }, + { -7216, -1936, 1538, -1983 }, + { -3730, -2451, 426, -3869 }, + { -5110, -1385, 2031, -1169 }, + { -6470, -2715, 269, -3123 }, + { -5806, -2480, -97, -3832 }, + { -3683, -4916, -490, -4330 }, + { -6341, -2083, -669, -115 }, + { -4913, -4079, -837, -4673 }, + { -3274, -2497, 2334, -2652 }, + { -1286, -1731, 2550, -3756 }, + { -3375, -877, 926, -3977 }, + { -2525, -2079, 2879, -2625 }, + { -5308, -504, 3111, -1607 }, + { -4904, 460, 4093, -1232 }, + { -1993, 1616, 4656, -1913 }, + { -3481, -1176, 3119, -2236 }, + { -4132, -1502, 2339, -2545 }, + { -2542, 1151, 3569, -2550 }, + { -4381, 430, 3147, -2082 }, + { -3888, 867, 3899, -1657 }, + { -2861, 1290, 4202, -1979 }, + { -3893, -253, 2363, -2764 }, + { -1705, 688, 3827, -2923 }, + { -2223, 2312, 3700, -3148 }, + { -1986, -720, 5021, -795 }, + { -3177, 242, 1952, -3352 }, + { -1854, 1509, 2528, -3815 }, + { -3173, 97, 5019, -706 }, + { -2689, -145, 1375, -3915 }, + { -4838, -385, 2488, -2427 }, + { -4557, -355, 1603, -3060 }, + { -3522, 1832, 3292, -2674 }, + { -3769, 780, 2378, -2704 }, + { -4323, -1932, 3414, -1169 }, + { -2740, 1158, 2729, -3273 }, + { -3647, 210, 1464, -2892 }, + { -2342, -2097, 1513, -3727 }, + { -4422, -1242, 3130, -1833 }, + { -1308, -1039, 4290, -1875 }, + { -1754, -2535, 3298, -2314 }, + { -4102, -186, 4037, -1094 }, + { -1008, 1570, 3290, 171 }, + { -3322, -2621, 2791, -1536 }, + { -2539, -2597, 3442, -1672 }, + { -3411, -2015, 3670, -1174 }, + { -2097, 730, 5581, -1399 }, + { -1510, -74, 4820, -2004 }, + { -4086, -868, 4425, -771 }, + { -956, -986, 3640, -2925 }, + { -2087, -1250, 3464, -2458 }, + { -3308, -2411, 1334, -3667 }, + { -2264, -389, 4004, -1854 }, + { -680, 239, 4058, -3388 }, + { -1357, 30, 2993, -3658 }, + { -3601, -552, 1177, -1136 }, + { -2641, 442, 4374, -1625 }, + { -2525, 770, 1640, -3895 }, + { -3172, -891, 3893, -1608 }, + { -2996, 13, 3277, -2414 }, + { -899, 1055, 4470, -2501 }, + { -422, -584, 3475, -3787 }, + { -1978, -593, 2566, -3415 }, + { -3150, -1280, 2362, -3047 }, + { -3592, 224, 1026, -3932 }, + { -4840, -1189, 3633, -879 }, + { -3952, -2255, 2916, -1826 }, + { -1695, 28, 1810, -349 }, + { -745, -2484, 3308, -3293 }, + { -1016, 1563, 5365, -1823 }, + { -2172, -1787, 4266, -1287 }, + { -1241, -1951, 3982, -2413 }, + { -2009, -2639, 2330, -3480 }, + { 5105, -1618, -2588, -2015 }, + { 6497, -1523, -3218, -910 }, + { 6526, -2305, -2029, -1790 }, + { 5289, -99, -3436, -400 }, + { 5781, -1623, -1577, -2617 }, + { 5259, -670, -3125, -1700 }, + { 6343, -1256, -331, -3222 }, + { 7967, -678, -2195, -1462 }, + { 6119, -695, -2988, -1538 }, + { 6108, 494, -3359, -1548 }, + { 5067, 969, -2328, -2707 }, + { 7595, -435, -1497, -2056 }, + { 6929, -719, -2420, -1665 }, + { 5190, 584, -2982, -2103 }, + { 6106, -444, -1411, -2739 }, + { 5584, 289, -1804, -2803 }, + { 5276, 227, -1180, -3361 }, + { 7544, -1525, -1834, -1725 }, + { 5986, -1470, -2606, -1701 }, + { 5096, -765, -1712, -3006 }, + { 5423, -149, -3933, -1157 }, + { 7651, 26, -2445, -1507 }, + { 4745, -464, -1735, -2362 }, + { 5352, -1011, -1094, -1999 }, + { 6300, -672, -542, -1950 }, + { 6675, -1020, -1318, -1059 }, + { 7218, -2036, -603, -2462 }, + { 7755, -1514, -2430, -1229 }, + { 5041, 449, -1056, -2405 }, + { 6710, -2277, -1344, -2284 }, + { 6824, -1347, -2254, 251 }, + { 6068, -1857, -983, -1316 }, + { 5603, -2177, -2730, -1477 }, + { 5838, -1059, -3604, -970 }, + { 5076, -789, -335, -2413 }, + { 6191, -1634, -2000, -2129 }, + { 5092, -1292, -2543, -1034 }, + { 5305, 435, -1710, -1850 }, + { 6140, 561, -2176, -2380 }, + { 6752, 348, -2496, -1890 }, + { 6405, 273, -1098, -2778 }, + { 6942, -1340, -496, -1381 }, + { 5238, -687, -2454, -2349 }, + { 6959, -882, -1833, -2061 }, + { 6292, -253, -2125, -2199 }, + { 5838, -574, -759, -3215 }, + { 6954, -1484, -640, -2771 }, + { 7498, -1706, -1210, -2154 }, + { 6772, -1003, -1235, -2532 }, + { 6014, 228, -2154, -1108 }, + { 6943, -2178, -2644, -1122 }, + { 7262, -763, -3056, -1090 }, + { 6273, -1478, -1072, 177 }, + { 4734, 425, -2912, 357 }, + { 7129, 168, -1537, -2327 }, + { 7204, -434, -746, -2660 }, + { 6879, 57, -3087, -1310 }, + { 4623, -610, -718, -3459 }, + { 6565, -543, -1998, -339 }, + { 4752, -277, -2066, -1405 }, + { 7435, -1416, -1904, -505 }, + { 4076, 150, -1222, -3556 }, + { 7082, -28, -1456, -1174 }, + { 5941, -446, -1326, -1158 }, + { 3870, -1648, -2474, -2589 }, + { 858, 37, -3387, -3721 }, + { 3557, -1503, -1664, -3383 }, + { 3336, -1972, -3079, -2216 }, + { 3186, 60, -4185, -863 }, + { 3456, -773, -3066, -2457 }, + { 4131, -913, -2060, -2601 }, + { 4431, -691, -4114, -972 }, + { 3461, -334, -3680, -1751 }, + { 2006, -459, -2214, -3827 }, + { 1322, 32, -2816, -3203 }, + { 4425, -1897, -2791, -1946 }, + { 4504, 23, -3421, -1909 }, + { 3090, -885, -2366, -3264 }, + { 3209, -2363, -3730, -834 }, + { 3312, -1471, -3641, -1579 }, + { 4184, -1669, -3323, -1248 }, + { 2190, -931, -3302, -2944 }, + { 2947, -229, -4791, -1195 }, + { 2020, -1626, -2700, -3125 }, + { 2214, -326, -4352, -1683 }, + { 3286, -2619, -2412, -2458 }, + { 1000, -2571, -4129, -2158 }, + { 2496, -2627, -3611, -1433 }, + { 2043, -2191, -2167, -3827 }, + { 2571, -2544, -1915, -3222 }, + { 2022, -1501, -3856, -2165 }, + { 2685, -1180, -1461, -4038 }, + { 1610, -2313, -4391, -1173 }, + { 2340, -2490, -4215, -516 }, + { 1742, -2615, -3632, -2146 }, + { 523, -1293, -4246, -2442 }, + { 3725, -2723, -3014, -1576 }, + { 3554, -1381, -4200, -824 }, + { 1291, -1594, -4777, -1430 }, + { 1452, 515, -2960, -3830 }, + { 4264, -894, -3305, -1826 }, + { 2606, -1452, -4522, -966 }, + { 1196, -830, -4807, -1816 }, + { 1054, -775, -2616, -4071 }, + { 4206, 415, -4344, -1132 }, + { 3044, 491, -4126, -1934 }, + { 988, -901, -3353, -3443 }, + { 1729, -3063, -2267, -3370 }, + { 3915, 912, -2989, -2387 }, + { 3781, 300, -2457, -3050 }, + { 2712, 924, -1350, -1206 }, + { 4230, 405, -2343, 665 }, + { 1878, -873, -225, -29 }, + { 3510, 56, -1334, -3420 }, + { 2850, 1447, -2651, -3150 }, + { 1510, -706, -4125, -2483 }, + { 3115, 793, -1692, -3894 }, + { 2667, 213, -2973, -2786 }, + { 1184, -2384, -3051, -3173 }, + { 2139, 796, -2079, -3697 }, + { 1464, -1483, -3726, -2754 }, + { 2407, -1148, -3915, -1569 }, + { 2612, -1779, -3217, -2271 }, + { 2406, -2870, -2937, -2496 }, + { 2140, 126, -3646, -2758 }, + { 2952, -1036, 268, -1423 }, + { 93, -1931, -3841, -3535 }, + { 389, -2953, -3383, -3343 }, + { 8652, -5511, -1662, 565 }, + { 7427, -2791, -2535, -842 }, + { 8541, -4253, -1407, -988 }, + { 8018, -3203, -2998, 105 }, + { 7231, -3926, -958, 1308 }, + { 7331, -3690, -363, 2586 }, + { 6803, -3646, -2226, -903 }, + { 8163, -2811, -477, -2235 }, + { 9356, -3818, -1685, -684 }, + { 8466, -2854, -302, -698 }, + { 8458, -3224, 517, 279 }, + { 8074, -2619, -1326, 2596 }, + { 8779, -2761, -2527, -441 }, + { 6533, -2887, -899, -696 }, + { 7394, -2305, -1642, -120 }, + { 8281, -3780, -22, 1305 }, + { 9158, -4413, -779, 901 }, + { 9031, -5240, -1109, 1678 }, + { 8717, -3650, 410, -1075 }, + { 7317, -3197, -818, -2264 }, + { 7934, -2385, -1214, -1886 }, + { 8256, -4441, -291, -587 }, + { 7358, -3395, 1090, -270 }, + { 9446, -4910, -1343, -473 }, + { 8187, -4726, -808, 1166 }, + { 7504, -3845, -47, 267 }, + { 8029, -2146, -1283, -383 }, + { 7461, -2705, -853, 783 }, + { 9367, -3636, -645, -354 }, + { 8955, -3473, -308, -1947 }, + { 8676, -2683, -2099, 1485 }, + { 7481, -3003, -871, -444 }, + { 8015, -2839, -1673, 1175 }, + { 6947, -4643, -1527, -1047 }, + { 7622, -2575, -137, -960 }, + { 9388, -4279, -707, -1322 }, + { 8382, -5259, -1283, -565 }, + { 6856, -4138, -1030, 630 }, + { 8659, -2571, -1124, -1666 }, + { 8763, -3807, -537, 2543 }, + { 8049, -3578, -2186, -604 }, + { 8272, -2351, -1985, -1214 }, + { 6855, -3796, -1527, -1631 }, + { 7178, -2896, -1600, -1756 }, + { 7040, -2888, -89, -1586 }, + { 6261, -3403, -264, 998 }, + { 7756, -4699, -1543, -834 }, + { 7682, -4622, -758, -1721 }, + { 8839, -4232, -2932, 1959 }, + { 9363, -4679, -1956, 39 }, + { 7883, -3616, -1414, -1432 }, + { 8828, -3188, -1356, -1312 }, + { 7746, -3987, -121, -2424 }, + { 9262, -3256, -693, 818 }, + { 7670, -3420, -148, 3504 }, + { 7344, -3183, 608, 1595 }, + { 8976, -4139, -1848, 1304 }, + { 6708, -4131, 33, -852 }, + { 7840, -4429, -2275, 79 }, + { 8980, -3858, -2838, 453 }, + { 7815, -4604, -2563, 944 }, + { 8372, -4422, -1783, 3071 }, + { 8623, -5128, -1754, 2888 }, + { 7462, -3281, 889, 920 }, + { 8416, -59, -1320, -1825 }, + { 7928, -1488, -414, -2499 }, + { 8110, -977, -1047, -2042 }, + { 8278, -687, -1597, -1550 }, + { 7988, -174, -977, -2106 }, + { 8609, -1547, -1628, -1527 }, + { 9000, -1798, -946, -1761 }, + { 8954, -872, -1404, -1594 }, + { 8939, 466, -748, -1212 }, + { 9549, -329, -177, -1360 }, + { 9411, -18, -1126, -1568 }, + { 8859, -782, -488, -1338 }, + { 8955, -218, -43, -1209 }, + { 9131, -69, -453, -1001 }, + { 9069, -1519, -1091, -1199 }, + { 9247, -1309, -566, -1146 }, + { 8528, -1617, -287, -1313 }, + { 7763, -745, -149, -2040 }, + { 8294, -343, 257, -2633 }, + { 10149, -893, -552, -1649 }, + { 9398, -915, 218, -2042 }, + { 9703, -1194, -675, -1592 }, + { 9586, -700, -427, -1710 }, + { 8930, 497, -1445, -1218 }, + { 9285, -1323, -163, -1552 }, + { 8431, -1289, -985, -1404 }, + { 8965, -655, 653, -1483 }, + { 9542, -1001, -951, -1128 }, + { 9205, -647, -37, -882 }, + { 8603, -56, 514, -1793 }, + { 9300, -12, -1324, -567 }, + { 8773, 238, -184, -1456 }, + { 9941, -1306, -69, -1792 }, + { 9360, 279, -376, -1919 }, + { 9180, -285, 95, -2170 }, + { 9922, -501, -970, -1570 }, + { 8341, -1493, -856, -2092 }, + { 8780, -981, -850, -1014 }, + { 9721, -548, -1504, -1094 }, + { 9973, -1493, 482, -2105 }, + { 8707, -333, -1027, -1087 }, + { 9098, -469, -315, -1723 }, + { 8879, -1050, -661, -2020 }, + { 8857, 602, -866, -1918 }, + { 8945, -1025, -2154, -1071 }, + { 8484, -1930, -468, -2179 }, + { 9177, -1903, -224, -2112 }, + { 8652, -137, -2097, -1214 }, + { 9063, -973, -1405, -772 }, + { 9328, -456, 662, -2469 }, + { 10101, -697, 127, -2113 }, + { 9685, 811, -2359, -1024 }, + { 8586, -94, -460, -1982 }, + { 7924, -141, -509, -2513 }, + { 7773, -669, -107, -2835 }, + { 8636, -1064, -46, -2409 }, + { 9748, 596, -1815, -1349 }, + { 8924, 304, 547, -2614 }, + { 9442, 746, -1153, -1679 }, + { 9454, -278, -529, -1976 }, + { 8488, 561, -32, -2160 }, + { 10083, -63, -1544, -1364 }, + { 9390, -1278, 568, -1131 }, + { 9740, -49, -2253, -910 }, + { 3636, -2391, -1115, -3614 }, + { 6014, -3204, -1902, -1808 }, + { 5787, -3497, -1116, -2590 }, + { 4365, -3046, -1632, -2668 }, + { 4733, -2192, -2029, -2468 }, + { 5412, -2753, -1633, -2464 }, + { 4455, -3375, -767, -3399 }, + { 4456, -1644, -983, -2841 }, + { 4039, -2523, 38, -3967 }, + { 3406, -2662, 72, -4757 }, + { 4279, -2005, 1055, -4399 }, + { 4321, -1377, -860, -3786 }, + { 3743, -5739, -651, -3047 }, + { 3528, -5510, 361, -4060 }, + { 6496, -4886, -136, -2689 }, + { 4513, -5254, 551, -4010 }, + { 6557, -3413, -92, -3063 }, + { 4186, -2059, 187, 47 }, + { 6210, -4117, -1256, -1985 }, + { 6038, -4343, 351, -2124 }, + { 4305, -4780, -2077, -1897 }, + { 4480, -3815, -2228, -1533 }, + { 5582, -3689, 1221, -3429 }, + { 5532, -4874, 1195, -2765 }, + { 6518, -2853, -905, -2568 }, + { 5467, -2192, 470, -4115 }, + { 4139, -1577, 240, -3493 }, + { 5281, -1926, -729, -3340 }, + { 5214, -2870, 1359, -4289 }, + { 3046, -3510, -1536, -3214 }, + { 5433, -2881, -1230, -1184 }, + { 4861, -3932, -1071, -2791 }, + { 5693, -4234, -1906, -1502 }, + { 4004, -3935, -1804, -2383 }, + { 3728, -3792, 681, -4773 }, + { 3621, -3030, -1951, -2598 }, + { 5133, -3903, 44, -3700 }, + { 3561, -3451, 1183, -5301 }, + { 5026, -2762, -2341, -1780 }, + { 5841, -2492, -467, -3210 }, + { 5591, -1791, 497, -2472 }, + { 5054, -3898, -1822, -2097 }, + { 5813, -2792, 83, -1469 }, + { 4432, -4497, 1670, -5193 }, + { 5338, -4653, -1109, -2200 }, + { 3239, -4401, -648, -3655 }, + { 2147, -3598, -1200, -4242 }, + { 4417, -2271, -1552, -3210 }, + { 6494, -4360, 852, -3565 }, + { 2393, -6358, -856, -4524 }, + { 4959, -4196, -847, -1403 }, + { 4924, -5438, -226, -3026 }, + { 4254, -5303, -1306, -2424 }, + { 4121, -3126, -2334, -1981 }, + { 3437, -4443, -1464, -2953 }, + { 3203, -3459, -529, -4339 }, + { 5896, -5945, 543, -3246 }, + { 1987, -4733, -220, -4863 }, + { 4358, -4431, -514, -3081 }, + { 4583, -2416, -492, -2287 }, + { 2943, -5035, 419, -4927 }, + { 5358, -5129, 987, -4309 }, + { 4460, -3392, 1752, -5634 }, + { 3415, -4633, 1507, -5945 }, + { 811, -4692, -445, 2333 }, + { 1009, -5613, -1857, 1360 }, + { 1338, -2712, -2720, 3036 }, + { 1002, -3754, -2582, 2344 }, + { 750, -4608, -2334, 714 }, + { 2043, -3207, -2822, 2173 }, + { -140, -4654, -2953, 357 }, + { -54, -4026, -2376, 2695 }, + { 1858, -5022, -717, 2287 }, + { 2064, -3894, -722, 3255 }, + { 2727, -4558, -332, 2603 }, + { 1810, -5378, 283, 1826 }, + { 3935, -4326, 762, 3383 }, + { -767, -4697, -2510, 1922 }, + { 2146, -4312, -3090, 1641 }, + { 54, -5881, -2114, 921 }, + { 1992, -5766, -640, 1574 }, + { 1200, -5371, -1114, 1828 }, + { 2973, -5337, 34, 2266 }, + { 1531, -5018, -2817, 1192 }, + { 3078, -4570, 117, 1990 }, + { 924, -4286, -1388, 2713 }, + { 142, -5058, -2848, 1487 }, + { -106, -6180, -881, 842 }, + { 673, -5433, -229, 1596 }, + { 783, -5710, -2784, 562 }, + { 1935, -5729, -2009, 856 }, + { -410, -3375, -3326, 2734 }, + { 234, -3000, -2628, 3260 }, + { 733, -3405, -3806, 1589 }, + { 771, -4285, -3544, 1314 }, + { 1192, -3563, -3960, 2178 }, + { 206, -5555, -1250, 1546 }, + { -130, -3815, -1210, 3041 }, + { 646, -3940, -393, 2992 }, + { -184, -4931, -1767, 1925 }, + { 2746, -5120, -2275, 1464 }, + { 2440, -3731, -3352, 2729 }, + { -490, -4942, -3779, 997 }, + { 68, -2636, -4167, 3778 }, + { 48, -3986, -4118, 2106 }, + { -978, -5486, -1336, 1390 }, + { 1126, -5297, -855, 640 }, + { -472, -3975, -3622, 1557 }, + { 2456, -5344, -1523, 1648 }, + { -774, -5652, -2417, 1147 }, + { 995, -6122, -812, 1132 }, + { 3282, -4571, -1763, 2175 }, + { 3655, -3862, -676, 3568 }, + { 3038, -3647, -1672, 3381 }, + { 2595, -2964, -2772, 3263 }, + { 4176, -3353, -1148, 4354 }, + { 1603, -3442, -1500, 3444 }, + { 828, -6226, -1783, 678 }, + { 1421, -3333, -3080, 3403 }, + { 1121, -4727, -1924, 1984 }, + { -186, -5083, -682, 1796 }, + { 819, -2778, -3488, 530 }, + { 421, -2873, -3832, 2596 }, + { 2164, -4263, -1605, 2282 }, + { 585, -4437, -682, -491 }, + { -644, -4452, -1157, 2325 }, + { 1991, -4299, 210, 2834 }, + { 2135, -3632, -2113, 665 }, + { -7482, -2724, -2662, -1380 }, + { -6983, -2166, -3756, -3509 }, + { -7085, -1439, -2397, -3112 }, + { -7760, -3049, -3319, -2822 }, + { -8413, -2760, -4406, -3298 }, + { -5995, -3943, -1260, -3750 }, + { -7879, -1554, -3464, -2606 }, + { -6314, -2034, -3878, -1681 }, + { -8849, -2084, -1399, -1231 }, + { -7153, -2602, -1384, -817 }, + { -8041, -2571, -407, -2785 }, + { -7246, -2233, -1578, 260 }, + { -7336, -3883, -4061, -1342 }, + { -7619, -3908, -2342, 382 }, + { -8684, -3724, -1662, -727 }, + { -7850, -2922, -1770, -3449 }, + { -6766, -2034, -1293, -1988 }, + { -6895, -2116, -968, -3744 }, + { -7136, -5147, -2618, -2809 }, + { -8224, -3724, -2519, -1589 }, + { -6711, -2750, -3021, -219 }, + { -8059, -1638, -1102, -3175 }, + { -8710, -4839, -3963, -3143 }, + { -9363, -4965, -3257, -1002 }, + { -6099, -1751, -3157, -395 }, + { -6453, -3216, -4597, -483 }, + { -7879, -5477, -839, -2638 }, + { -7202, -4038, -526, -2856 }, + { -8022, -1228, -1910, -1646 }, + { -9117, -1393, -1582, -2535 }, + { -9095, -2693, -636, -2605 }, + { -9076, -2580, -3481, -2519 }, + { -8327, -4859, -2422, 83 }, + { -8368, -2129, -2324, -2173 }, + { -8554, -4563, -3842, -2007 }, + { -10462, -4261, -1934, -2084 }, + { -9717, -3187, -2294, -1896 }, + { -9625, -3889, -3020, -3224 }, + { -9857, -4955, -4239, -2184 }, + { -9752, -2351, -2277, -3129 }, + { -7219, -1302, -2639, -1603 }, + { -7477, -4360, -3718, -559 }, + { -5680, -2033, -2326, -3078 }, + { -10190, -5548, -4643, -3601 }, + { -9431, -4121, -879, -2479 }, + { -8365, -5450, -2020, -1439 }, + { -6289, -5178, -1605, -3845 }, + { -8319, -3866, -687, -2792 }, + { -8131, -1031, -3608, -3947 }, + { -10510, -2560, -1199, -2082 }, + { -11015, -3640, -2748, -3041 }, + { -8762, -5022, -5231, -1162 }, + { -10153, -2715, -4648, -4859 }, + { -7930, -5205, -1900, -3600 }, + { -9561, -3548, -4812, -3722 }, + { -7663, -4709, -1180, -1475 }, + { -9073, -5707, -1815, -2980 }, + { -8602, -2363, -2675, -3770 }, + { -9967, -5614, -3575, -3838 }, + { -8324, -1005, -2131, -3254 }, + { -10331, -5737, -2550, -2940 }, + { -8234, -3354, -3361, -4479 }, + { -8140, -1951, -4526, -4545 }, + { -6679, -2662, -2284, -4182 }, + { -1122, -1514, -6427, -212 }, + { 54, -1660, -5424, -1404 }, + { 254, -2778, -5222, 846 }, + { -267, -1661, -6577, 814 }, + { -305, -2021, -5759, 1484 }, + { -1791, -2446, -6867, -86 }, + { -2929, -3158, -6603, -1799 }, + { -1391, -3189, -5557, -1053 }, + { -1602, -884, -6767, -1213 }, + { -361, -318, -6219, -44 }, + { -4078, -2635, -5523, -433 }, + { -956, 478, -4382, 1470 }, + { -3300, -2462, -6021, -2721 }, + { 708, -2434, -5085, -540 }, + { -2435, -3607, -5647, -2110 }, + { -491, -1134, -4681, -2886 }, + { 87, -3435, -4641, -1194 }, + { -586, -2927, -4784, 366 }, + { -1394, -2326, -6021, 350 }, + { 97, -2519, -4678, -2120 }, + { -1547, -1907, -5069, -2993 }, + { 268, -3724, -4719, 127 }, + { -827, -1190, -5912, 1144 }, + { -3959, -2322, -6898, -1974 }, + { -2728, -2228, -6426, -562 }, + { -456, -666, -5785, -1609 }, + { 531, -1096, -5731, -656 }, + { -3569, -688, -3915, 110 }, + { -4752, -1725, -4393, -377 }, + { -3210, -3315, -6960, -840 }, + { -688, -3416, -4971, 1221 }, + { -1833, 77, -6491, -2434 }, + { -239, -255, -6850, -886 }, + { -2112, -1490, -6291, -2689 }, + { -1544, -4579, -5198, -1261 }, + { -2771, -4014, -5520, 683 }, + { -1635, -2829, -5512, 1214 }, + { -958, -2582, -4823, 2360 }, + { -2077, -4566, -4642, 365 }, + { -3112, -4214, -5960, -823 }, + { -2467, -2510, -4858, 1467 }, + { -1561, -3399, -5822, 211 }, + { -775, -1081, -4424, 2636 }, + { -1263, 25, -6378, -1392 }, + { -3476, -366, -5417, -1393 }, + { -3176, -1476, -4149, 1466 }, + { -2479, 518, -4448, -257 }, + { -2992, 158, -4660, -1279 }, + { -1320, -3872, -4479, 1147 }, + { -1475, -312, -5318, 539 }, + { -3527, -1679, -5860, -1681 }, + { -3397, -3438, -5593, 1866 }, + { -4089, -2439, -4763, 1275 }, + { -748, -4513, -4687, -48 }, + { -2166, -4531, -4691, -2856 }, + { -2385, -853, -6035, -627 }, + { -1194, -4091, -4472, -1963 }, + { -682, -3234, -4084, -3033 }, + { -3255, -5015, -5328, -12 }, + { -2313, -3436, -4601, -155 }, + { -2792, -1038, -6947, -2019 }, + { -1244, -1526, -5771, -1882 }, + { -4679, -3731, -5506, 283 }, + { -3062, -66, -3558, -758 }, + { -4895, -1187, 4751, 3728 }, + { -7600, -2752, 3320, 4613 }, + { -5703, -2975, 3944, 2659 }, + { -4972, -1257, -246, 2952 }, + { -4221, -2487, 1702, 4295 }, + { -2900, -1529, 2458, 4935 }, + { -5061, 407, 2416, 4050 }, + { -6931, -3478, 2761, 2213 }, + { -6037, -3921, 3192, 1866 }, + { -6113, -811, 2407, 3782 }, + { -5878, -1716, 1207, 3478 }, + { -5953, -2853, 2207, 2712 }, + { -6807, -3223, 2749, 3595 }, + { -3272, -3157, 1389, 3788 }, + { -5368, -1904, 1980, 5077 }, + { -7235, -1398, 3075, 4548 }, + { -4765, -3487, 2755, 2796 }, + { -7658, -4435, 2694, 2582 }, + { -6997, -4282, 456, 3832 }, + { -5563, -3115, -63, 3713 }, + { -4244, -4220, 1450, 2767 }, + { -3801, -2194, 190, 4303 }, + { -5458, -4119, 1958, 2274 }, + { -7300, -3469, 3514, 3193 }, + { -4594, -2067, 775, 4752 }, + { -3389, -1654, 1464, 5412 }, + { -4845, -3483, 964, 3437 }, + { -6007, -2818, 1666, 4659 }, + { -8709, -5007, 1757, 3287 }, + { -5833, -4389, 1025, 3171 }, + { -5788, -1780, 3944, 3661 }, + { -4430, -920, 1938, 4753 }, + { -7066, -1857, 4591, 4538 }, + { -3549, -513, 1427, 5317 }, + { -7517, -1220, 2883, 3049 }, + { -7605, -2687, 1874, 2735 }, + { -8718, -4035, 2676, 3730 }, + { -7990, -3907, 1185, 2607 }, + { -6058, -1744, 3349, 5157 }, + { -5954, 565, 3161, 3250 }, + { -6478, -612, 1930, 2271 }, + { -6535, -1445, -2, 1618 }, + { -8963, -4151, 1192, 4044 }, + { -7227, -3570, 1600, 4234 }, + { -4674, 79, 595, 3015 }, + { -3974, 430, 2727, 5137 }, + { -5299, 9, 3714, 4779 }, + { -6779, -2699, -8, 2436 }, + { -7016, -1145, 1293, 2310 }, + { -6955, -3312, 1534, 1801 }, + { -4025, 740, 1850, 4054 }, + { -9589, -3460, 4154, 5270 }, + { -4404, -1181, 4298, 5173 }, + { -7356, -4583, -18, 2644 }, + { -6516, -1235, 4439, 6234 }, + { -3453, -301, 4344, 4464 }, + { -4643, 1530, 3315, 4340 }, + { -4575, -2557, 3754, 3682 }, + { -3643, -3501, 2051, 2997 }, + { -5412, -2475, 2301, 1579 }, + { -5846, 259, 1360, 2348 }, + { -5258, -1358, 1050, 838 }, + { -5542, -219, 6377, 5750 }, + { -5713, -2952, 922, 899 }, + { -2049, -1135, 5206, 1033 }, + { -1693, -1886, 4835, -106 }, + { -2344, -3504, 4232, -13 }, + { -2475, -2334, 5043, 1126 }, + { -787, -2549, 3880, 2138 }, + { -3159, -2341, 4830, 2887 }, + { -1780, -1009, 6240, 2061 }, + { -4327, -3363, 2818, 886 }, + { -3376, -2743, 4104, 207 }, + { -3250, -4640, 2718, 1498 }, + { -382, -1075, 4382, 3460 }, + { -2416, -4168, 3530, 816 }, + { -1756, -2708, 4861, 622 }, + { -1879, -2097, 5156, 2889 }, + { -2496, -2418, 3722, 2671 }, + { -2717, -3252, 3341, 1944 }, + { -4063, -4091, 3306, 267 }, + { -3549, -3808, 3747, 842 }, + { -2635, 546, 5794, 1894 }, + { -1857, -1121, 4383, 3964 }, + { -2226, -2166, 3489, 3678 }, + { -3492, -660, 5323, 1063 }, + { -3033, -3130, 4382, 1828 }, + { -2703, -625, 6369, 2851 }, + { -1656, -2842, 4584, -528 }, + { -4781, -2622, 4390, 2097 }, + { -413, -2045, 5081, 3035 }, + { -3810, -2662, 4532, 1095 }, + { -3144, -1858, 5215, 1880 }, + { -3562, -1795, 4928, 670 }, + { -4800, -1509, 5189, 1859 }, + { -1085, -3832, 4169, 900 }, + { -1969, -3270, 2857, 2878 }, + { -4267, -4140, 3176, 1805 }, + { -5145, -3727, 3524, 1168 }, + { -1346, -1876, 5501, 1748 }, + { -4998, -2945, 3699, 338 }, + { -3458, -3096, 3406, -635 }, + { -1751, -3209, 3508, 395 }, + { -2507, 170, 5987, 705 }, + { -3756, -1072, 5647, 3536 }, + { -2870, -1439, 5026, 3212 }, + { -3913, -3225, 3669, 2144 }, + { -3739, 226, 5747, 764 }, + { -2052, -820, 5266, 3093 }, + { -3214, -3820, 2409, 2391 }, + { -4398, -2588, 3501, -218 }, + { -4484, -1763, 4180, -198 }, + { -3368, -1525, 4362, -134 }, + { -2407, 224, 4905, 3533 }, + { -1369, -2937, 4728, 1788 }, + { -4848, -1707, 4159, 851 }, + { -3454, -1749, 4281, 3230 }, + { -1990, -3853, 3487, 1735 }, + { -3117, 92, 6155, 4075 }, + { -2676, -2472, 4078, -589 }, + { -1547, -2012, 2626, 1835 }, + { -4275, -588, 4824, 725 }, + { -601, -2249, 3736, 3548 }, + { -4060, -61, 5333, 3097 }, + { -4303, 7, 6551, 3054 }, + { -5003, -1029, 5786, 3319 }, + { -2810, -728, 5392, 199 }, + { -1232, -200, 5228, 3121 }, + { 2621, 165, -6255, 298 }, + { 3669, 537, -6844, 1564 }, + { 1598, -1190, -6235, 2523 }, + { 2164, -32, -6894, 1383 }, + { 853, -1597, -6069, 1449 }, + { 1377, -1661, -5266, 108 }, + { 2660, 48, -5172, -517 }, + { 1903, -391, -5677, 1010 }, + { 3792, 206, -5274, -11 }, + { 1239, 2776, -2929, 2721 }, + { 4071, 149, -7259, 3125 }, + { 1436, -480, -6156, -196 }, + { 1373, -1960, -5005, 3122 }, + { 3413, -1271, -5176, 3283 }, + { 3060, -68, -6495, 2238 }, + { 2700, -2075, -4681, 91 }, + { 2928, -1728, -5168, 1858 }, + { 4424, 828, -4471, 88 }, + { 2672, -2604, -4038, 2753 }, + { 5223, -123, -6749, 2295 }, + { 4237, -420, -5538, 1353 }, + { 4744, -1281, -4097, 4708 }, + { 1103, -2764, -4751, 2024 }, + { 3747, -1913, -3911, 3960 }, + { 2470, -1416, -5542, 615 }, + { 4847, -1354, -5334, 1733 }, + { 5336, 88, -7593, 4007 }, + { 2388, -2880, -4807, 1037 }, + { 4495, 1391, -5685, -139 }, + { 5253, 1637, -6450, 1533 }, + { 1199, 795, -5515, 1261 }, + { 1397, -1259, -4252, 3838 }, + { 746, 70, -6640, 604 }, + { 1584, 166, -4972, 3072 }, + { 380, -999, -5397, 2267 }, + { 2974, 1707, -3242, 5360 }, + { 5202, -403, -5453, 2832 }, + { 3718, -1731, -4760, 714 }, + { 4150, -975, -4792, 61 }, + { 2925, -818, -4841, 15 }, + { 5301, 577, -4006, 3259 }, + { 5265, 1986, -5679, 3028 }, + { 3752, 1928, -4509, 3729 }, + { 3278, 1925, -6370, 1247 }, + { 5107, 1721, -4853, 3127 }, + { 3279, 2982, -2515, 4005 }, + { 4622, 668, -6204, 759 }, + { 6034, 317, -5763, 4818 }, + { -558, 57, -3785, 2817 }, + { 4476, 1616, -3965, 4536 }, + { 5953, 2056, -8215, 2715 }, + { 4387, 2613, -7463, 868 }, + { 5834, 1088, -4736, 4924 }, + { 6473, -856, -6991, 4172 }, + { 4959, -293, -5162, 76 }, + { 2731, -843, -6119, 3847 }, + { 3245, 1202, -6833, 616 }, + { 2553, 1383, -3829, 3859 }, + { 4332, 2099, -3480, 3622 }, + { 2110, 2683, -2728, 3990 }, + { 876, 1167, -3290, 3466 }, + { 3991, 1709, -2410, 4077 }, + { 5105, 939, -2584, 3256 }, + { 4719, 688, -1566, 3040 }, + { -3632, 4335, 1266, -3303 }, + { -4956, 3207, 1312, -2806 }, + { -4669, 2627, 2663, -2435 }, + { -4282, 3708, 2303, -3038 }, + { -4536, 2297, -175, -3350 }, + { -5234, 2503, -139, -880 }, + { -3978, 1512, 1092, -3619 }, + { -4519, 4649, 1363, -2455 }, + { -5118, 3132, 1961, -1577 }, + { -5196, 3379, -182, -1378 }, + { -6420, 4486, 2397, -1993 }, + { -5030, 5046, 1292, -1118 }, + { -4559, 2573, -927, -1406 }, + { -3501, 3730, 691, -4930 }, + { -4364, 2758, 1007, -3909 }, + { -4026, 2839, -1559, -2340 }, + { -5037, 4053, 836, -1571 }, + { -4727, 5136, 1110, -3588 }, + { -5245, 2799, -999, -2164 }, + { -4954, 1501, 422, -3963 }, + { -5994, 2726, 1462, -2833 }, + { -5621, 5159, 2038, -2512 }, + { -4991, 2291, 1917, -3151 }, + { -5469, 4382, -148, -2978 }, + { -5858, 1983, 807, -2720 }, + { -4709, 3556, 952, -467 }, + { -2489, 2362, 1714, -4230 }, + { -4717, 5004, -1180, -3672 }, + { -5914, 3653, 1359, -1317 }, + { -5506, 2995, 780, -1059 }, + { -5287, 3945, 2480, -2293 }, + { -3849, 4358, 322, -1770 }, + { -3911, 3570, 252, -3185 }, + { -3660, 5128, 158, -3719 }, + { -4599, 3277, -503, -2727 }, + { -3673, 3760, -1252, -3339 }, + { -5161, 2337, 388, -1943 }, + { -3529, 2216, 2156, -3080 }, + { -4309, 4331, 1808, -1460 }, + { -4782, 3820, 480, -2504 }, + { -4166, 3544, -378, -1567 }, + { -5572, 2466, -418, -2909 }, + { -6096, 2930, 119, -1878 }, + { -5963, 3554, 1011, -2233 }, + { -6433, 4335, 935, -2930 }, + { -5004, 3314, -1352, -3430 }, + { -6042, 3463, -1008, -3940 }, + { -4671, 2214, -640, -5040 }, + { -2795, 3759, 1412, -3803 }, + { -3647, 4436, 729, -515 }, + { -3594, 1033, 56, -4148 }, + { -2908, 3027, 2889, -3485 }, + { -3338, 2234, 313, -4285 }, + { -3825, 4497, -561, -2634 }, + { -6167, 3012, -48, -3149 }, + { -4828, 3515, -969, -4475 }, + { -5789, 2757, -539, -4173 }, + { -2452, 3067, 564, -4249 }, + { -4921, 1358, 1331, -2889 }, + { -3127, 4239, -1045, -1523 }, + { -4780, 2326, -1118, -3446 }, + { -3908, 5546, 152, -2622 }, + { -6972, 2976, 337, -2809 }, + { -4839, 4613, -35, -4077 }, + { -1408, 4822, -1149, -4997 }, + { -981, 4979, -912, -6304 }, + { -2098, 5689, -888, -2878 }, + { -3343, 4814, -657, -4434 }, + { -2461, 3601, -967, -4869 }, + { -2652, 3944, 87, -5520 }, + { -1104, 6076, 174, -6407 }, + { 355, 5370, -1721, -5869 }, + { 1242, 4497, -1107, -5091 }, + { -89, 4002, -1491, -5182 }, + { 1059, 5693, -1591, -4905 }, + { 1323, 4682, -2078, -4768 }, + { 818, 3996, -549, -5468 }, + { -287, 4529, 929, -5543 }, + { -919, 5519, -2791, -2844 }, + { -1407, 5679, -3289, -3974 }, + { -189, 6530, -3547, -4002 }, + { -900, 7039, -3371, -4855 }, + { -2983, 7211, -363, -4835 }, + { -814, 6503, -104, -5106 }, + { -2386, 6896, 809, -4919 }, + { 845, 4492, 352, -6621 }, + { -1998, 7237, -1646, -4231 }, + { -3380, 6251, 471, -4577 }, + { -1908, 7059, 84, -5726 }, + { -340, 6346, -803, -6265 }, + { -2279, 5834, -47, -4633 }, + { -1532, 5286, -1748, -1901 }, + { -2757, 6188, -453, -3415 }, + { -1255, 6405, -2043, -6357 }, + { 918, 5581, -121, -5667 }, + { 1840, 5336, -821, -5034 }, + { -2475, 4992, -1825, -3104 }, + { -2413, 5606, -1789, -4298 }, + { 132, 5128, -2389, -4442 }, + { 223, 6400, -2653, -4742 }, + { -673, 5012, 680, -4582 }, + { -1657, 6624, -349, -3596 }, + { -755, 6289, -1860, -3978 }, + { -572, 6894, -1946, -5207 }, + { -1141, 4756, -2665, -5586 }, + { -1073, 4269, -431, -4030 }, + { 186, 5761, 916, -5868 }, + { -1907, 4836, 1017, -5106 }, + { -963, 3363, -1248, -6348 }, + { -3262, 4774, -1818, -5858 }, + { 847, 3812, -2538, -4302 }, + { -1223, 5903, 1360, -5479 }, + { -1094, 6923, -1244, -2381 }, + { 267, 6276, -709, -2846 }, + { -157, 5840, 1124, -4266 }, + { 889, 3206, -910, -5305 }, + { -1736, 3344, 582, -4838 }, + { -2357, 5676, -2695, -6277 }, + { -1916, 6901, -986, -5397 }, + { -3062, 6028, -695, -5687 }, + { 1836, 3566, -1357, -5226 }, + { -2176, 4938, 646, -3872 }, + { -2199, 3055, -208, -6124 }, + { -236, 3032, -821, -5325 }, + { -3989, 7277, -565, -3899 }, + { -595, 4362, 74, -5975 }, + { 684, 5874, -841, -4424 }, + { -2731, 6305, -2389, -5465 }, + { -5775, 1325, -56, -2528 }, + { -7029, -534, -1890, -3278 }, + { -5798, -15, -2734, -2210 }, + { -5504, -1198, -353, -3659 }, + { -5079, 960, -894, -4336 }, + { -6073, -36, -133, -3014 }, + { -5782, -259, -1025, -3986 }, + { -6843, 1262, -807, -1639 }, + { -5263, -918, -3290, -579 }, + { -4840, 461, -2158, -533 }, + { -6014, -50, -620, 504 }, + { -5843, 241, -1359, -282 }, + { -5898, 577, 769, -3271 }, + { -6833, -946, -466, -3347 }, + { -6026, 1459, -512, -729 }, + { -7361, 747, -388, -1110 }, + { -6391, 2142, -1160, -2513 }, + { -6995, 304, 498, -2673 }, + { -6757, 679, -386, -433 }, + { -5222, 1688, -1093, -1032 }, + { -5019, 575, 184, -3627 }, + { -4237, 628, -3507, -1243 }, + { -7479, -456, -1722, -1486 }, + { -6464, 713, -1273, -1153 }, + { -6255, 1682, -606, -3607 }, + { -7033, 1497, -71, -1955 }, + { -6694, 1556, -1721, -3214 }, + { -6114, -356, 813, -2575 }, + { -5308, 632, -1851, -1636 }, + { -5742, -911, -1733, 383 }, + { -6083, -387, -2313, -879 }, + { -6535, -530, -1505, -2083 }, + { -4896, 1223, -2750, -1816 }, + { -6392, -463, -3247, -2093 }, + { -5373, 1264, -2706, -3042 }, + { -3894, -1390, -1020, -891 }, + { -6179, 1168, -1966, -1922 }, + { -5162, 1668, -1617, -1916 }, + { -6453, 920, -1169, -2432 }, + { -6130, 2005, -536, -1519 }, + { -6552, -98, -518, -1938 }, + { -7528, 355, -1101, -1772 }, + { -5745, 610, -247, -1360 }, + { -7003, 177, -2064, -1958 }, + { -6956, -570, -2220, -4225 }, + { -7830, 791, -1394, -2774 }, + { -7634, 480, -3171, -4224 }, + { -7913, 1154, -350, -2381 }, + { -5063, 1704, -1804, -2977 }, + { -4887, -524, -2703, 188 }, + { -5551, 406, -1620, -3063 }, + { -7109, 1342, 381, -3021 }, + { -6846, 631, -458, -3398 }, + { -4606, -605, 11, -3930 }, + { -8134, -225, -1738, -2648 }, + { -7043, 402, -2734, -3059 }, + { -7417, 1825, -2545, -4389 }, + { -6971, -236, -1031, -665 }, + { -5752, 2111, -1632, -3808 }, + { -7660, -78, -624, -3135 }, + { -6358, 619, -1951, -3911 }, + { -8134, 408, -1935, -3695 }, + { -6335, 1911, -2368, -4505 }, + { -7116, 2163, -344, -2753 }, + { 2357, 4488, 2220, -5682 }, + { 1385, 3206, 2300, -5305 }, + { 1419, 2557, 5203, -3516 }, + { 262, 4315, 3920, -1847 }, + { 3316, 3187, 1612, -5609 }, + { 1729, 2350, 1673, -6068 }, + { 1603, 6126, 1467, -2839 }, + { -1339, 3316, 3691, -3530 }, + { -563, 4618, 3180, -4548 }, + { 463, 4624, 3111, -5614 }, + { 1246, 5455, 3356, -5720 }, + { 480, 2149, 5422, -2893 }, + { 1768, 4827, 913, -5579 }, + { -149, 5381, 4366, -3297 }, + { 985, 3672, 2644, -92 }, + { -258, 2911, 5817, -2213 }, + { 3428, 3289, 3351, -3541 }, + { -666, 3295, 4727, -2869 }, + { 35, 6641, 4160, -4052 }, + { 623, 6787, 3156, -4560 }, + { 2654, 4360, 4676, -4632 }, + { 1386, 5246, 4834, -4497 }, + { 3488, 4574, 3856, -5946 }, + { 383, 4481, 4168, -4110 }, + { 1753, 3652, 4288, -3326 }, + { 1344, 4905, 2508, -4660 }, + { 1580, 4106, 3104, -2224 }, + { 2027, 5038, 1683, -1554 }, + { 446, 3699, 5872, -3013 }, + { 4637, 4087, 3578, -5018 }, + { 2629, 3560, 5331, -4900 }, + { 1527, 6674, 2523, -4131 }, + { -1437, 2804, 2528, -4464 }, + { -229, 3355, 2016, -5537 }, + { 3666, 3418, 4374, -4581 }, + { 1192, 3799, 923, -6596 }, + { 2040, 2956, 448, -5322 }, + { 2468, 5768, 4029, -5869 }, + { 3438, 6516, 3529, -6667 }, + { 2737, 5495, 680, -5535 }, + { 3896, 5727, 1801, -4958 }, + { 4988, 4957, 3592, -6518 }, + { -542, 4416, 5794, -2787 }, + { 4136, 4354, 2064, -4696 }, + { 3067, 5936, 1207, -3396 }, + { 2789, 4966, 2405, -3854 }, + { 1731, 3270, 3251, -1063 }, + { 1767, 5537, 2084, -2349 }, + { 465, 3116, 4532, -837 }, + { 1499, 2627, 4610, -2212 }, + { 122, 3095, 3642, -3552 }, + { 2542, 2866, 2705, -6402 }, + { 3134, 4323, 698, -4785 }, + { 731, 1859, 3112, -5242 }, + { 2553, 2980, 3241, -4846 }, + { 1329, 5310, 1607, -6624 }, + { 2468, 1858, 3476, -1034 }, + { -172, 4996, 2000, -5562 }, + { 2621, 4220, 1574, -3386 }, + { -333, 1832, 3362, -4117 }, + { 2169, 6762, 3065, -6225 }, + { 2844, 5528, 3223, -4765 }, + { 526, 5175, 1644, -4267 }, + { 2922, 4426, 2414, -2610 }, + { 452, 1399, -4516, -2636 }, + { 2872, 1720, -4667, -1435 }, + { 1279, 702, -5424, -1984 }, + { 2187, 870, -5021, -1341 }, + { 583, -144, -4628, -2464 }, + { 3, 2237, -5284, -2827 }, + { -19, 1005, -5460, -1819 }, + { 2897, 2084, -5885, -515 }, + { -400, 3370, -5527, -2947 }, + { 1505, 2593, -5518, -1802 }, + { 1341, 4534, -5094, -1899 }, + { 3241, 3670, -5493, -1252 }, + { -1287, 921, -5994, -1675 }, + { 627, 408, -6652, -364 }, + { -260, 1127, -4849, -3247 }, + { 371, 3400, -5976, -2285 }, + { 1533, 1566, -6373, -610 }, + { 2462, 4274, -6184, -1254 }, + { 1782, 3363, -6222, -1381 }, + { 572, 4650, -5673, -2754 }, + { 2674, 3414, -4460, -2154 }, + { 3614, 3820, -6883, -398 }, + { 1136, -1, -5511, -1112 }, + { -1773, 1137, -5647, -2377 }, + { -753, 2104, -6085, -2565 }, + { -204, 3025, -4731, -1418 }, + { -1486, 1438, -4380, -216 }, + { 302, 858, -5786, -264 }, + { 3486, 1495, -5234, -783 }, + { 888, 2327, -3423, -3720 }, + { -259, 772, -6596, -1311 }, + { -1197, 2073, -5174, -1826 }, + { 1500, 3470, -4462, -2645 }, + { 3072, 1960, -3277, -2264 }, + { 1841, 952, -4324, -2340 }, + { 1994, 2200, -3940, -2923 }, + { -1782, 1699, -4667, -1075 }, + { -1464, 2906, -3468, -375 }, + { 366, 2380, -3747, 1467 }, + { -545, 1645, -4619, 376 }, + { 1724, 2350, -2374, -3512 }, + { 3184, 2628, -2996, -3275 }, + { 734, 2010, -6239, -1479 }, + { 524, 3756, -4496, -3263 }, + { 1492, 3570, -3494, -3600 }, + { -932, 618, -5389, -2894 }, + { -133, 2161, -4083, -3267 }, + { 786, 774, -3279, -3731 }, + { 1078, 803, -3843, -3007 }, + { -332, 3405, -3347, 40 }, + { -17, 6, -4005, -3690 }, + { -189, 4372, -4488, -2561 }, + { -450, 3846, -3790, -1370 }, + { 362, 2212, -5272, -15 }, + { -1529, 791, -6802, -2296 }, + { 2145, 4241, -4474, 376 }, + { 1813, 2426, -2932, -2726 }, + { -542, 4557, -3140, -1080 }, + { 1192, 3784, -4371, -20 }, + { 2784, 5188, -6399, -1394 }, + { 431, 4561, -3673, -1398 }, + { 1382, 3096, -4083, 1253 }, + { 1209, 4224, -2930, 1500 }, + { 2798, 2684, -6676, -606 }, + { -2396, 1510, -5381, -2713 }, + { -2625, 2542, -4032, -2880 }, + { -1231, 3967, -4098, -2886 }, + { -1393, 2374, -3862, -4525 }, + { -2495, 1665, -1637, -5445 }, + { -3854, 1759, -1750, -4944 }, + { -2373, 1668, -2856, -6251 }, + { -2668, 1981, -886, -4557 }, + { -2927, 4427, -3451, -6172 }, + { -1925, 2596, -4696, -2527 }, + { -3202, 2847, -3928, -5896 }, + { -3332, 1665, -5025, -3412 }, + { -3212, 3115, -4155, -4062 }, + { -1013, 3205, -5133, -3751 }, + { -2022, 4595, -3947, -5611 }, + { -3556, 1755, -3715, -2300 }, + { -1784, 4114, -2723, -1773 }, + { -3586, 4081, -2733, -4942 }, + { -1608, 3685, -4154, -4573 }, + { -3368, 4042, -4452, -6227 }, + { -1407, 3881, -5729, -3719 }, + { -2751, 3281, -5077, -4999 }, + { -3791, 2410, -4906, -5288 }, + { -730, 2303, -4217, -3755 }, + { -1812, 2311, -5492, -3709 }, + { -610, 4336, -3915, -3783 }, + { -2841, 4337, -4278, -4430 }, + { -1662, 4666, -4661, -3964 }, + { -589, 5209, -4923, -3682 }, + { -4155, 2234, -4076, -4218 }, + { -3951, 2770, -2665, -2805 }, + { -2302, 3228, -3717, -1908 }, + { -3129, 4373, -2264, -2851 }, + { -447, 1363, -3578, -4323 }, + { -2648, 4237, -3159, -3071 }, + { -4072, 3241, -3541, -4605 }, + { -4507, 3458, -2339, -3838 }, + { -1646, 997, -4926, -3970 }, + { -3025, 1614, -3940, -1242 }, + { -1337, 1756, -3163, -5529 }, + { -3203, 1865, -3282, -4354 }, + { -1646, 2118, -2203, -6018 }, + { 174, 1871, -2707, -4639 }, + { -2607, 1485, -4778, -4750 }, + { -2199, 3991, -3134, -4879 }, + { -2962, 3323, -2816, -2419 }, + { -5286, 2495, -4548, -5395 }, + { -2810, 3710, -2274, -4211 }, + { -330, 3006, -2993, -4678 }, + { -1187, 2411, -2743, -5196 }, + { -664, 4033, -3101, -5641 }, + { -1458, 3602, -2816, -5371 }, + { -4116, 4923, -3321, -5630 }, + { -4165, 2528, -2592, -4798 }, + { -2759, 3080, -2333, -5719 }, + { -5157, 3011, -5526, -6348 }, + { -3095, 2126, -5881, -4234 }, + { -4377, 3849, -3600, -6099 }, + { -1994, 4947, -5235, -4753 }, + { -1067, 600, -3258, -5133 }, + { -4992, 3302, -2208, -5051 }, + { -3377, 2981, -1655, -4815 }, + { -3325, 2446, -1787, -6116 }, + { -2341, 2737, -3240, -6347 }, + { -2258, -3732, 3710, -1235 }, + { -1558, -3849, 2694, -3012 }, + { -599, -4837, 3050, -2951 }, + { -2246, -5433, 2798, -1910 }, + { -2255, -4989, 3260, 270 }, + { -3026, -5353, 2693, -1036 }, + { -1151, -6097, 1097, -3782 }, + { -3391, -6012, 2130, -1303 }, + { -2850, -4422, 3375, -480 }, + { -1138, -3779, 1491, -4162 }, + { -551, -3892, 3787, -2082 }, + { -3221, -3676, 3144, -1202 }, + { -3023, -5196, 2650, 605 }, + { -1756, -5729, 2646, 321 }, + { -2693, -4409, 494, -4797 }, + { -1913, -4573, 3372, -1730 }, + { -1277, -3604, 4061, -993 }, + { -420, -4993, 1351, -4796 }, + { -3052, -5333, 1435, -1242 }, + { -602, -5034, 3869, -1141 }, + { -2436, -4680, 1665, -3019 }, + { -2657, -3658, 1459, -3391 }, + { -1220, -6246, 2749, -525 }, + { -3838, -4844, 2265, -1735 }, + { -1247, -5679, 3356, -1417 }, + { -917, -5448, 3342, 105 }, + { -1756, -6839, 2276, -2350 }, + { -412, -5206, 1764, -3539 }, + { -1439, -6915, 1442, -3750 }, + { -1381, -4439, 3863, -282 }, + { -3482, -4953, 2726, -336 }, + { -1376, -5931, 1714, -1987 }, + { -1716, -4405, 2608, 105 }, + { -1590, -5191, 2652, -2704 }, + { -2149, -6442, 2453, -1263 }, + { -3426, -3832, 2334, -1829 }, + { -2747, -5948, 2362, -173 }, + { -2435, -3267, 2966, -1710 }, + { -3979, -4282, 2705, -775 }, + { -356, -4238, 2544, -4343 }, + { -1363, -6471, 2817, -1836 }, + { -2878, -5117, 218, -3149 }, + { -3539, -5196, 1710, -2356 }, + { -2888, -4537, 2746, -1701 }, + { -1870, -4439, 1496, -4121 }, + { -1486, -3388, 3349, -2145 }, + { -3333, -4138, 1467, -2876 }, + { -345, -5340, 1012, -1190 }, + { -1672, -4992, 2289, -1029 }, + { -2146, -5528, 3038, -635 }, + { -316, -3656, 3426, -3152 }, + { -2695, -5812, 2336, -2050 }, + { -2067, -6052, 737, -3258 }, + { -2664, -4205, -350, -1266 }, + { -617, -5406, 80, -4853 }, + { -2418, -3825, 1853, -1326 }, + { -1961, -4339, 583, -4315 }, + { -1495, -5141, -133, -5205 }, + { -3208, -6440, 1691, -2069 }, + { -2632, -3633, 2325, -2761 }, + { -2624, -5670, 1252, -3676 }, + { -3687, -5608, 687, -2833 }, + { -3320, -5707, 16, -3877 }, + { -2738, -6112, 84, -5135 }, + { 2277, -5661, 3076, 843 }, + { 1555, -5769, 2821, -5236 }, + { 536, -6381, 603, -4910 }, + { 734, -4609, 3314, -4092 }, + { 1836, -4547, 3267, -4322 }, + { -13, -5976, 3752, -1607 }, + { 1423, -6318, 2336, 398 }, + { 365, -7779, 1498, -534 }, + { 2104, -8366, 2946, -1345 }, + { 143, -5545, 1898, -3756 }, + { 655, -6852, 1430, 148 }, + { 4, -6653, 2397, -59 }, + { 2346, -5996, 4562, -934 }, + { 1229, -7104, 2963, -598 }, + { -528, -7048, 2887, -1790 }, + { 1451, -6857, 3900, -1637 }, + { 554, -6018, 3336, 9 }, + { 3278, -5758, 4034, 129 }, + { 3541, -7145, 4905, -1575 }, + { 2339, -6907, 3464, -301 }, + { 2775, -7301, 1667, -3894 }, + { 539, -7887, 991, -4156 }, + { 2115, -7421, 3131, -3075 }, + { 2803, -8546, 2564, -5836 }, + { 2869, -5833, 1620, -4561 }, + { 2591, -7281, 3215, -4719 }, + { -1228, -8477, 706, -4782 }, + { 1967, -5243, 4813, -1940 }, + { 701, -7010, 2273, -3893 }, + { 915, -8470, 1918, -5620 }, + { -94, -6715, 156, -3873 }, + { 1074, -5607, 4389, -1017 }, + { 2739, -6551, 1227, -3521 }, + { 725, -7835, 2701, -1291 }, + { -493, -7475, 2263, -1075 }, + { -412, -6508, 2984, -744 }, + { 665, -5451, 3725, -2692 }, + { 1499, -8129, 3564, -2072 }, + { 2870, -6333, 4487, -2108 }, + { 706, -5007, 3911, -152 }, + { -482, -8660, 1483, -2900 }, + { 2481, -6596, 2518, -1715 }, + { 1403, -6414, 1398, -5387 }, + { 652, -6267, 583, -5942 }, + { 694, -7540, 646, -6272 }, + { 2275, -7614, 256, -5015 }, + { 1416, -9727, 1900, -3153 }, + { 2760, -6433, 3875, -3771 }, + { 2325, -11196, 2182, -5155 }, + { 1223, -11061, 1377, -5097 }, + { 108, -10603, 307, -4952 }, + { -118, -8268, 1650, -1572 }, + { 1839, -7943, 1755, -612 }, + { 2501, -9056, 981, -2969 }, + { 2902, -8476, 1491, -5780 }, + { 1995, -11175, 1585, -3643 }, + { 696, -8212, 828, -2474 }, + { 1526, -8649, 1380, -1210 }, + { 461, -7253, 3222, -2229 }, + { 2966, -8641, 4121, -3271 }, + { 833, -6039, 2361, -1086 }, + { 3565, -7312, 1980, -5427 }, + { 2850, -8671, 3760, -1846 }, + { 2643, -7281, 2163, -173 }, + { 3463, -3706, -3132, -923 }, + { 1315, -3825, -3443, 2 }, + { 2594, -4083, -3815, 670 }, + { 1826, -4291, -2741, -155 }, + { 868, -3749, -4175, -298 }, + { 2008, -4237, -3897, -517 }, + { 1242, -3493, -4335, -1335 }, + { -88, -4142, -3390, -1529 }, + { 2176, -3488, -3822, -975 }, + { 1706, -5188, -3415, -637 }, + { 2717, -6159, -2333, -882 }, + { 1276, -3978, -4361, 537 }, + { 2471, -5556, -2866, -208 }, + { 799, -4673, -4086, 56 }, + { 1901, -4786, -3533, 270 }, + { 3036, -3902, -3606, -333 }, + { 2249, -3317, -4319, -144 }, + { 2594, -4207, -2105, -2930 }, + { 4008, -4774, -2626, -902 }, + { 1038, -3659, -3496, -2454 }, + { 2725, -3597, -3298, -1535 }, + { 1662, -5803, -2813, 175 }, + { 705, -3757, -3441, -1484 }, + { 1860, -5987, -2821, -886 }, + { 3786, -4918, -2199, -1929 }, + { 3683, -4235, -2547, -1287 }, + { 2531, -4896, -2956, -1593 }, + { 1005, -5585, -3324, -180 }, + { 1625, -5229, -1756, -3642 }, + { 1494, -5041, -2989, -2685 }, + { 2718, -4655, -3224, -867 }, + { 2374, -6640, -1745, -2975 }, + { 2133, -6436, -2477, -1499 }, + { 1833, -4418, -3523, -1512 }, + { 1128, -4910, -2658, -1106 }, + { 689, -4777, -2831, -2085 }, + { 3593, -5280, -2627, -315 }, + { 3264, -3771, -2673, -1861 }, + { 3202, -5602, -2409, 402 }, + { 552, -4618, -2221, -3002 }, + { 3095, -5356, -2666, -1083 }, + { 3401, -4609, -3146, 45 }, + { 3051, -4662, -2192, -2232 }, + { 2798, -5552, -2462, -1941 }, + { 2354, -5815, -2223, -2619 }, + { 192, -3708, -2807, -2658 }, + { 1886, -4226, -1862, -3529 }, + { 2526, -3976, -2819, -2332 }, + { 1577, -3870, -2711, -2806 }, + { 1288, -5588, -3382, -1403 }, + { 2711, -5399, -1564, -3253 }, + { 1459, -5492, -2222, -322 }, + { 2823, -5091, -2886, 776 }, + { 3559, -5821, -2109, -1360 }, + { 1587, -6331, -2760, -1909 }, + { 2139, -5213, -2874, -2120 }, + { 1318, -4337, -3695, -2098 }, + { 821, -4471, -1849, -565 }, + { 3329, -4782, -1725, -89 }, + { 582, -4914, -4105, -1119 }, + { 417, -4144, -4072, -2529 }, + { -199, -3803, -2765, -4042 }, + { 2731, -4283, -2143, 1 }, + { 2911, -6187, -1951, -2116 }, + { 1573, -6094, -493, -2838 }, + { 2081, -6927, -864, -3211 }, + { 1058, -7826, 79, -364 }, + { 3147, -5570, -684, -978 }, + { 3572, -5856, 1060, 1824 }, + { 1143, -6702, -1478, 338 }, + { 2341, -7220, -88, 260 }, + { 3639, -6861, 668, 815 }, + { 2227, -6268, -1706, 446 }, + { 3390, -6082, -353, 1302 }, + { 1123, -7556, -1237, -430 }, + { 1729, -7742, 729, -218 }, + { 1457, -6774, 587, 579 }, + { 505, -6919, -569, 371 }, + { 1106, -7245, 78, 158 }, + { 2755, -6745, -1122, 338 }, + { 3069, -6040, -1415, 986 }, + { 2174, -7064, -1430, -283 }, + { 1390, -8626, -446, -3031 }, + { 3534, -6890, -431, 547 }, + { 2267, -9618, 475, -2994 }, + { 3672, -7673, 75, -115 }, + { 2131, -7560, -1206, -750 }, + { 2972, -7477, -685, -262 }, + { 1604, -6637, -672, 699 }, + { 1666, -7577, -577, -240 }, + { 1591, -6554, -2158, -94 }, + { 2348, -6286, -353, 1123 }, + { 2017, -8810, -412, -1805 }, + { 2892, -6713, -1765, -554 }, + { 2500, -6828, -1995, -1197 }, + { 3877, -6639, -224, -1655 }, + { 2392, -7872, -91, -333 }, + { 3562, -7370, -532, -2836 }, + { 2552, -7614, 164, -1805 }, + { 990, -6104, 218, 438 }, + { 910, -7861, 312, -1195 }, + { 1472, -6327, 372, -640 }, + { 1576, -7143, -1983, -843 }, + { 422, -7625, -457, -278 }, + { 1797, -8532, 405, -1011 }, + { 1088, -7396, -238, -2277 }, + { 3209, -6753, -1431, -2072 }, + { 2617, -6839, 100, -2573 }, + { 2575, -8573, -387, -3188 }, + { 3618, -6971, -1190, -321 }, + { 2205, -7361, -1695, -2008 }, + { 2985, -6297, 1464, 1179 }, + { 2804, -7310, 1053, 338 }, + { 1362, -6074, -1163, -840 }, + { 3336, -6325, -1794, 21 }, + { 2836, -8109, 818, -329 }, + { 2791, -5879, 560, 1546 }, + { 2392, -6064, 135, 100 }, + { 1838, -6194, 596, 1085 }, + { 1926, -7515, -414, -4901 }, + { 3225, -7298, -1202, -1189 }, + { 3960, -7558, -659, -719 }, + { 3442, -6647, -1692, -1095 }, + { 3381, -6441, 262, -886 }, + { 1431, -8150, -1186, -1406 }, + { 340, -8498, -150, -899 }, + { 3004, -8149, -260, -953 }, + { 2749, -6611, 563, 873 }, + { -6647, -1325, -4517, -4691 }, + { -6005, -1657, -4089, -3797 }, + { -3157, 588, -5213, -3068 }, + { -3311, -1425, -6329, -3726 }, + { -5866, -819, -3857, -2744 }, + { -5001, -1799, -1075, -4621 }, + { -5330, -2650, -2672, -4664 }, + { -4930, -539, -2363, -4010 }, + { -2984, 10, -3863, -5749 }, + { -1055, -2106, -3713, -4267 }, + { -5476, -502, -4279, -6504 }, + { -5231, -1543, -5018, -6425 }, + { -5134, -363, -3165, -5109 }, + { -3953, -771, -4107, -6393 }, + { -2159, -563, -3652, -5342 }, + { -3888, -2321, -919, -5057 }, + { -1236, -597, -4235, -4193 }, + { -4053, 675, -3083, -6174 }, + { -2793, -1089, -5396, -3460 }, + { -3000, -44, -2209, -6575 }, + { -3336, -1531, -4313, -5160 }, + { -2127, 128, -4851, -3692 }, + { -3321, 136, -2067, -5660 }, + { -5215, 1404, -4374, -4356 }, + { -2747, 400, -6340, -3691 }, + { -3926, -599, -5361, -5006 }, + { -2875, -2592, -5143, -4092 }, + { -4991, -1958, -5322, -4891 }, + { -4965, -1318, -6652, -5333 }, + { -4920, -1691, -3388, -5561 }, + { -3644, -3354, -2688, -5982 }, + { -5076, -919, -4563, -2984 }, + { -6114, 250, -3884, -3915 }, + { -4014, 744, -3973, -1924 }, + { -5543, -1041, -5557, -3847 }, + { -4711, -1352, -5649, -2603 }, + { -3362, 775, -5305, -4879 }, + { -5001, 107, -3554, -2888 }, + { -6258, -1651, -6356, -6566 }, + { -4529, 407, -5003, -3865 }, + { -5154, 550, -5278, -5465 }, + { -4195, -467, -1894, -3129 }, + { -5022, 1127, -3349, -3314 }, + { -6075, 1250, -4313, -5641 }, + { -2677, -2283, -2312, -5903 }, + { -4113, 193, -1195, -4833 }, + { -3940, -1048, -1389, -5079 }, + { -3703, 917, -4043, -4451 }, + { -3366, -4231, -1534, -5488 }, + { -3326, -3583, -2091, -4903 }, + { -5144, 1254, -2532, -4949 }, + { -5982, -870, -2545, -4555 }, + { -3925, -157, -5367, -2281 }, + { -6419, -746, -5668, -4371 }, + { -5787, 518, -7096, -5805 }, + { -4258, 954, -6453, -4321 }, + { -4771, -695, -4158, -1639 }, + { -7078, -760, -5195, -5877 }, + { -7348, 83, -4101, -4586 }, + { -2430, 184, -2874, -1679 }, + { -2284, -3943, -2924, -5034 }, + { -1804, -1785, -3002, -4710 }, + { -4399, -2772, -1815, -4637 }, + { -6340, -2626, -2824, -5191 }, + { -4998, -5168, -3480, 1905 }, + { -3958, -5492, -1599, 1579 }, + { -2471, -3755, -276, 3182 }, + { -3033, -5779, -1063, 1554 }, + { -2936, -4829, -1290, 2386 }, + { -1835, -5073, -3051, 1299 }, + { -1724, -3771, -3935, 2324 }, + { -5070, -2550, -3692, 768 }, + { -4326, -5333, -297, 1878 }, + { -3472, -5619, -3094, 992 }, + { -3027, -4384, -3038, 2265 }, + { -3201, -5332, 67, 2200 }, + { -1681, -4373, -1947, 2461 }, + { -3221, -3329, -4238, 2564 }, + { -1262, -2968, -2915, 3227 }, + { -3419, -1878, -3373, 2110 }, + { -2244, -5583, -2012, 1288 }, + { -1971, -5266, -990, 1812 }, + { -2975, -2778, -452, 4063 }, + { -2198, -1165, -3298, 2965 }, + { -4782, -4894, -4767, 664 }, + { -6002, -3950, -2806, 2025 }, + { -3142, -3162, -2859, 3295 }, + { -3262, -3340, -4123, 1596 }, + { -4014, -3918, -1955, 3361 }, + { -1700, -3463, -1346, 3449 }, + { -4245, -4445, -4743, 1644 }, + { -4180, -3969, -401, 3281 }, + { -2782, -5240, -4117, 1156 }, + { -5744, -4040, -1439, 3470 }, + { -5063, -4663, -323, 3172 }, + { -4531, -3319, -844, 3988 }, + { -6226, -5125, -2064, 2976 }, + { -3115, -3267, -1531, 3898 }, + { -4628, -4421, -2864, 2808 }, + { -4559, -2989, -3442, 2024 }, + { -1775, -4487, -656, 2477 }, + { -2664, -1865, -1884, 4081 }, + { -1828, -2575, -3894, 3378 }, + { -6441, -3677, -2025, 1677 }, + { -4141, -2156, -1191, 3474 }, + { -4802, -1623, -1727, 2160 }, + { -5474, -2745, -1475, 2498 }, + { -3664, -1056, -1975, 2491 }, + { -4672, -3062, -2235, 2933 }, + { -4205, -5960, -2849, 1517 }, + { -4995, -5708, -1739, 1805 }, + { -4892, -6080, -4793, 872 }, + { -4270, -4172, -4263, 2185 }, + { -4687, -1470, -2905, 1023 }, + { -6446, -5017, -3919, 1000 }, + { -6046, -5538, -3943, 2006 }, + { -6028, -3750, -3953, 771 }, + { -5959, -4582, -5024, 824 }, + { -5818, -2576, -2249, 1326 }, + { -5659, -5345, -1119, 2500 }, + { -3346, -4155, 606, 2749 }, + { -5680, -4827, -2501, 1838 }, + { -6193, -2543, -1295, 840 }, + { -6871, -4925, -3512, 1801 }, + { -5605, -1788, -1895, 779 }, + { -3922, -5712, -4644, 510 }, + { -4745, -3869, -4533, 99 }, + { -2984, -4907, -399, 1497 }, + { 1847, -478, 3061, -5812 }, + { 4450, -1116, 3609, -6570 }, + { 3139, 99, 3007, -5532 }, + { 2590, -3782, 3138, -4770 }, + { 1881, 1204, 5778, -3404 }, + { 3631, 2060, 5566, -5038 }, + { 3461, 1961, 5167, -3800 }, + { 2947, 273, 4536, -4389 }, + { 4453, -1730, 5788, -4370 }, + { 4032, 1805, 2666, -4534 }, + { 3487, -944, 2313, -6028 }, + { 1313, 34, 4210, -4067 }, + { 5632, -1502, 5825, -5855 }, + { 7736, -547, 4879, -5476 }, + { 4906, -1512, 4760, -5760 }, + { 3843, 447, 1091, -4958 }, + { 2982, -1135, 5442, -4386 }, + { 3579, 271, 3031, -6770 }, + { 3932, -211, 4688, -5507 }, + { 4411, 1720, 2387, -5584 }, + { 5379, -479, 4575, -6280 }, + { 3613, -362, 2012, -4885 }, + { 3744, -2013, 4493, -5073 }, + { 5693, 109, 4379, -3362 }, + { 5475, -621, 5317, -3985 }, + { 6411, -673, 5708, -4752 }, + { 4933, -796, 7262, -4290 }, + { 2804, 444, 6276, -3655 }, + { 4120, -517, 6078, -4531 }, + { 5119, 841, 3486, -3910 }, + { 4738, 1539, 3525, -2970 }, + { 5086, 370, 5895, -5640 }, + { 4235, 2716, 4589, -5044 }, + { 3691, 682, 6199, -4700 }, + { 6111, -570, 6271, -6528 }, + { 2611, 1277, 3756, -4802 }, + { 4395, 970, 3807, -5879 }, + { 5225, 2299, 3242, -4333 }, + { 5144, 1778, 4946, -5545 }, + { 2989, -3016, 3247, -5495 }, + { 2983, 920, 2071, -6059 }, + { 5270, -903, 4434, -2350 }, + { 6415, -585, 3970, -3554 }, + { 3866, -197, 5216, -2884 }, + { 3767, -1298, 6702, -3315 }, + { 6299, 2620, 5284, -6824 }, + { 6654, 646, 3653, -4927 }, + { 4770, 3047, 5160, -6287 }, + { 5364, 434, 2919, -5207 }, + { 2998, 1344, 4801, -2456 }, + { 3896, 1013, 3773, -1864 }, + { 2115, 655, 2999, -6344 }, + { 5170, -981, 2849, -4464 }, + { 2735, -2159, 2717, -5776 }, + { 2430, -1952, 4392, -4559 }, + { 6143, -1180, 3659, -4746 }, + { 4978, -1483, 1726, -4875 }, + { 3486, -2383, 3306, -4301 }, + { 1434, -1372, 4171, -4770 }, + { 3354, -2627, 1525, -5093 }, + { 6790, 2386, 3995, -5909 }, + { 1475, -2674, 3451, -4204 }, + { 1999, -3494, 3693, -5556 }, + { 4764, -2848, 2856, -5589 }, + { -3677, 5131, 2827, -2934 }, + { -2844, 7078, 2852, -3580 }, + { -3902, 6434, 4118, -1911 }, + { -1769, 7530, 3492, -3541 }, + { -1937, 5679, -447, -1127 }, + { -2456, 4680, 4196, -2407 }, + { -2778, 8241, 1698, -4288 }, + { -2876, 6104, 5182, -2387 }, + { -2802, 7341, 4463, -2938 }, + { -1025, 6267, 4752, -3201 }, + { -2349, 5413, 2041, -3794 }, + { -2252, 8225, 2856, -4269 }, + { -1465, 4967, 4976, -2500 }, + { -636, 7565, 3517, -4233 }, + { -1905, 5618, 3904, -2942 }, + { -302, 6816, 3343, -3316 }, + { -2210, 4156, 2817, -3511 }, + { -717, 6568, 1863, -2951 }, + { -3873, 5682, 2164, -575 }, + { -2878, 5835, 440, -2597 }, + { -3228, 7701, 2610, -2514 }, + { -3608, 8888, 3377, -2468 }, + { -2582, 9717, 2519, -3126 }, + { -5238, 6202, 2866, -2831 }, + { -3428, 7370, 3056, -335 }, + { -1681, 8836, 1210, -2010 }, + { -3276, 6724, 1156, -3930 }, + { -894, 8149, 827, -1258 }, + { -2965, 8631, 2549, -1320 }, + { -3961, 6902, 3581, 55 }, + { -1894, 7745, 1750, -841 }, + { -821, 6844, 850, -676 }, + { -608, 6948, -4, -1376 }, + { 615, 6524, 1089, -1147 }, + { -2972, 5668, 1091, -489 }, + { -157, 4649, 2904, -413 }, + { 673, 5121, 1498, -66 }, + { -390, 5902, 1611, -245 }, + { -2349, 5478, 4772, -1320 }, + { 88, 6798, 1972, -1859 }, + { -1213, 5120, 2991, 200 }, + { -2347, 6040, 2839, 376 }, + { -578, 5976, 3364, -1796 }, + { -1391, 5872, 3002, -965 }, + { -564, 4496, 3946, -1186 }, + { -2299, 6386, 3135, -2176 }, + { -2131, 5641, 2011, 1223 }, + { -772, 5807, 1124, 895 }, + { -2837, 6758, 2297, -740 }, + { -3091, 6298, 1415, -2126 }, + { -4197, 6036, 1843, -3022 }, + { -41, 6459, 92, 344 }, + { -2241, 6860, 2095, -4396 }, + { -1931, 7088, 2117, -2135 }, + { -2375, 4422, 1688, -3169 }, + { -1742, 6674, 1538, -119 }, + { -4818, 7749, 4192, -1577 }, + { -2004, 5672, 193, -430 }, + { -3825, 6042, 2128, -1898 }, + { -1108, 8033, 2119, -3013 }, + { -2370, 5453, 1721, 266 }, + { -1570, 7134, 614, -2638 }, + { -1519, 8752, 3503, -4330 }, + { -2050, 3845, 2907, -1126 }, + { 5085, 4412, -335, -1923 }, + { 3618, 1423, -613, -4012 }, + { 4481, 3729, 589, -4631 }, + { 4270, 3216, -1763, -3168 }, + { 4241, 1796, -1701, -2796 }, + { 4787, 2338, -487, -3639 }, + { 2915, 3429, -621, -4753 }, + { 5175, 1660, -1265, -3223 }, + { 4280, 4057, -684, -4079 }, + { 4980, 4419, -1455, -2719 }, + { 5436, 2464, 387, -4197 }, + { 4507, 4018, 1121, -3314 }, + { 6020, 2401, -413, -3201 }, + { 4200, 3789, -333, -2813 }, + { 5229, 2493, -1194, -1878 }, + { 5851, 2695, -492, -2292 }, + { 5743, 3288, -697, -1221 }, + { 5692, 2612, 979, -2227 }, + { 5085, 2067, 1046, -1214 }, + { 3163, 2240, -2098, -3435 }, + { 5228, 1898, 145, -2397 }, + { 5860, 3976, -418, -2872 }, + { 6008, 3399, 1027, -3506 }, + { 4126, 2035, 1865, -893 }, + { 5375, 3596, 511, -2362 }, + { 1937, 1493, -852, -122 }, + { 3473, 4849, 547, -2603 }, + { 4631, 2977, 1141, -1768 }, + { 6149, 3050, -71, -1886 }, + { 4069, 4353, -289, -1429 }, + { 2884, 1225, -1388, 365 }, + { 5485, 2518, -235, -571 }, + { 1216, 4375, 1443, 398 }, + { 4988, 3106, 107, -1435 }, + { 4511, 2801, 307, -444 }, + { 3235, 4386, 327, -676 }, + { 2055, 3708, 1657, -305 }, + { 5839, 2374, 290, -1385 }, + { 5110, 3305, 1936, -4206 }, + { 6416, 2920, 338, -2736 }, + { 3350, 2824, -1269, -3881 }, + { 4840, 1815, 464, 186 }, + { 2399, 3332, 238, 1238 }, + { 3516, 1363, 1582, 688 }, + { 3582, 1874, 154, -4770 }, + { 3261, 2878, 886, 283 }, + { 3877, 2658, -327, 884 }, + { 4151, 3436, 2173, -2923 }, + { 3592, 3674, 1281, -1295 }, + { 4561, 3730, -1114, -1747 }, + { 4595, 3625, -558, -575 }, + { 2577, 2348, 2267, 120 }, + { 5242, 3299, 32, -3412 }, + { 4264, 3637, 709, -2320 }, + { 6556, 3570, -838, -2472 }, + { 5745, 4014, -940, -1973 }, + { 5629, 4475, 477, -3328 }, + { 5269, 3199, 1682, -3085 }, + { 4432, 2416, 1145, -3299 }, + { 4465, 2505, 2162, -2186 }, + { 4643, 4941, -88, -2885 }, + { 4568, 5231, 552, -3915 }, + { 5667, 3075, -1406, -2963 }, + { 5418, 5259, -771, -2818 }, + { -256, -7875, 511, -471 }, + { -1813, -7971, -424, -396 }, + { -306, -7006, 862, 282 }, + { -2306, -6422, -1440, 508 }, + { -245, -6787, 375, -100 }, + { -1309, -6065, -20, 779 }, + { -1656, -6047, -641, 1307 }, + { -1496, -6522, 964, 726 }, + { -2291, -6588, -202, 795 }, + { -762, -7522, 1454, -558 }, + { -2270, -7004, -834, -580 }, + { -1139, -7078, 259, 362 }, + { -2535, -7568, -1040, 49 }, + { -3786, -7280, 934, -476 }, + { -3336, -6368, 606, 1056 }, + { -3602, -6924, 52, 714 }, + { -2278, -6550, 1674, 204 }, + { -2855, -5765, 930, 1530 }, + { -2889, -7325, -215, 305 }, + { -2749, -6080, -237, 1452 }, + { -985, -6667, 1577, 400 }, + { -2036, -6083, 380, 1267 }, + { -2077, -7460, 380, -30 }, + { -1775, -7175, 1540, -386 }, + { -3065, -6927, 989, 168 }, + { -2836, -7602, 117, -3392 }, + { -1058, -6396, 593, -3078 }, + { -844, -6062, 999, -236 }, + { -3261, -6951, 1491, -720 }, + { -2186, -8484, 75, -1287 }, + { -2882, -7756, 456, -510 }, + { -1800, -6879, 960, -1183 }, + { -2554, -7241, 1614, -1474 }, + { -2608, -5305, 392, 851 }, + { -2973, -6562, -859, 858 }, + { -2640, -5989, 1031, -416 }, + { -977, -8366, 705, -1434 }, + { -1213, -7409, -77, -1390 }, + { -1335, -6657, 2125, -123 }, + { -2544, -6862, 1852, -737 }, + { -3235, -6422, 1752, -103 }, + { -1300, -7557, 939, -348 }, + { -3476, -7579, 202, -109 }, + { -2482, -6572, 753, 619 }, + { -2554, -8136, -648, -429 }, + { -1012, -7870, -3, -421 }, + { -3604, -6247, 32, -3102 }, + { -1486, -7271, 2013, -1021 }, + { -578, -6799, -523, 405 }, + { -2841, -5948, 1644, 911 }, + { -2411, -7473, 1084, -484 }, + { -2238, -6033, 294, -1059 }, + { -3459, -6470, -201, -790 }, + { -2027, -6009, 1833, 805 }, + { -1433, -8047, 1531, -1754 }, + { -3258, -7884, 763, -1422 }, + { -1544, -6928, -729, 478 }, + { -2314, -8415, 74, -3757 }, + { -3201, -5684, 95, -2214 }, + { -2423, -8694, 725, -3631 }, + { -3545, -7071, 1162, -1798 }, + { -294, -9662, 403, -2274 }, + { -2290, -5460, 1196, 402 }, + { -1603, -6713, 903, -2363 }, + { 4121, 2491, -3142, -2482 }, + { 4500, 3305, -3671, -1567 }, + { 5973, 3172, -1348, -534 }, + { 4830, 3379, -1549, 643 }, + { 5214, 3938, -2641, -2302 }, + { 4639, 4826, -5532, -847 }, + { 5639, 2731, -2170, -963 }, + { 6084, 3487, -3525, -1346 }, + { 5971, 3154, -2190, -2316 }, + { 5618, 4865, -6927, 116 }, + { 5345, 3568, -7391, 709 }, + { 5429, 5078, -3811, -1524 }, + { 6960, 2037, -3515, -1096 }, + { 7092, 2531, -4557, -588 }, + { 6061, 4247, -5651, -478 }, + { 4595, 3684, -4907, -827 }, + { 7497, 3213, -3048, -424 }, + { 5996, 2137, -3098, -1745 }, + { 6198, 5199, -2223, -2274 }, + { 6888, 2851, -2768, -1675 }, + { 6114, 4210, -2316, -954 }, + { 7127, 4242, -3041, -1408 }, + { 6126, 3668, -1517, -1427 }, + { 6245, 6129, -4225, -1186 }, + { 6816, 3213, -2101, -964 }, + { 5345, 5276, -2643, -847 }, + { 6592, 4665, -4338, 484 }, + { 6746, 3751, -3443, 124 }, + { 5453, 1980, -2738, 2606 }, + { 4662, 2179, -4226, -1059 }, + { 5571, 3208, -3554, 174 }, + { 5256, 4447, -1815, -1481 }, + { 5400, 2570, -1210, 235 }, + { 7056, 2549, -2674, 318 }, + { 4574, 4340, -2892, -130 }, + { 6203, 4587, -3273, -305 }, + { 5103, 1925, -2715, -2137 }, + { 3905, 4296, -1700, 247 }, + { 4421, 4605, -3299, 811 }, + { 5671, 1273, -3870, -924 }, + { 5486, 1805, -4901, 133 }, + { 6437, 2578, -1828, -106 }, + { 5530, 5253, -5058, 1223 }, + { 4816, 2025, -1215, 1443 }, + { 3457, 3525, -2456, 3217 }, + { 3316, 2595, -1108, 2459 }, + { 3068, 3810, -2207, 1926 }, + { 6351, 5436, -6470, 600 }, + { 6324, 4240, -5365, 2416 }, + { 4851, 4774, -4075, 1878 }, + { 4900, 3679, -5198, 1078 }, + { 8347, 3633, -4565, -171 }, + { 5244, 5718, -3853, 173 }, + { 3960, 3492, -2939, 2105 }, + { 6070, 3473, -2351, 161 }, + { 8228, 3034, -3360, -901 }, + { 7006, 3985, -1940, -1926 }, + { 7123, 4681, -4301, -878 }, + { 5122, 4097, -1851, -449 }, + { 6200, 2060, -2251, 1049 }, + { 7106, 3844, -7209, 2625 }, + { 7108, 3370, -6734, 533 }, + { 6859, 2849, -3992, 1360 }, + { 5458, 2278, -3253, 1131 }, + { -1072, -2109, 4783, -1073 }, + { -319, -2604, 4257, -2418 }, + { 2466, 1300, 3476, -314 }, + { 2847, -1502, 5296, -141 }, + { 1667, -1273, 5559, -2725 }, + { 2877, -3402, 6434, 204 }, + { 53, -2637, 5275, -1181 }, + { 1091, -2215, 5803, -1549 }, + { 2397, -922, 4327, 1182 }, + { 219, -3747, 4647, -1564 }, + { -29, -2705, 4812, 1277 }, + { 1499, -2608, 5648, 1407 }, + { 2139, -2399, 4202, 2791 }, + { -426, -2064, 5528, 151 }, + { 2560, -2803, 6179, -2806 }, + { 4537, -2479, 3797, 1095 }, + { 888, -3357, 5341, -415 }, + { 4460, -1814, 5388, -1227 }, + { 3920, -3268, 6364, -703 }, + { 3343, -4698, 4410, 784 }, + { 309, -1897, 6306, 1223 }, + { 958, -3318, 4254, -3167 }, + { -99, 1596, 6018, -1983 }, + { -429, -853, 6407, 878 }, + { 1170, -1322, 6290, -417 }, + { 2288, -505, 6303, -1999 }, + { 3312, -1674, 6749, -2494 }, + { -415, -3401, 4721, -371 }, + { -189, -1210, 4844, -2002 }, + { 888, -4142, 4377, 130 }, + { 2469, -4381, 5398, -2492 }, + { 2879, -2912, 5094, -2598 }, + { -717, -617, 5650, -685 }, + { 1470, -3863, 5352, -1684 }, + { 3935, -96, 3823, -730 }, + { 3769, -430, 3168, 694 }, + { 2556, 385, 3539, 512 }, + { 77, -1415, 5111, 2655 }, + { 2724, -2158, 6715, -822 }, + { 1832, 1001, 5385, -1900 }, + { 900, 2198, 4464, -559 }, + { 441, 69, 5921, -1743 }, + { -1161, 738, 6732, -308 }, + { 257, 2035, 4091, 736 }, + { 1607, 1288, 4355, -23 }, + { -13, 1316, 4180, 1672 }, + { 1511, 1336, 3057, 1435 }, + { 2189, -3813, 4530, 939 }, + { 3632, -706, 2646, 1375 }, + { 4266, -3761, 4241, 1077 }, + { 3101, -427, 5273, -1202 }, + { 2293, 276, 4810, -313 }, + { 3430, -1851, 3101, 2045 }, + { 3453, -2979, 5142, 942 }, + { 1683, -3281, 4802, 2002 }, + { 3954, -4715, 5611, 578 }, + { 1272, -155, 5085, 454 }, + { 128, -194, 5095, 1409 }, + { 820, 880, 5797, -2658 }, + { -1095, 656, 5774, 1095 }, + { 813, -1669, 4320, -3251 }, + { -119, 518, 6372, -651 }, + { 2922, -4299, 6115, -877 }, + { 4205, -4273, 4004, 2642 }, + { -1211, -3892, 224, 3127 }, + { -34, -4371, 1321, 2318 }, + { 77, -6326, 1201, 828 }, + { 3995, -3775, 1958, 3233 }, + { 178, -3301, 1985, 3318 }, + { 2330, -3801, 1033, 3195 }, + { 1413, -5536, 826, 1709 }, + { 2468, -3499, 3653, 3631 }, + { 741, -4617, 1723, 2008 }, + { 1246, -3043, 2978, 3949 }, + { -343, -4308, 2258, 2189 }, + { -682, -4640, 454, 2272 }, + { 1236, -4829, 2491, 1642 }, + { -512, -3766, 1182, 3052 }, + { 119, -3939, 3712, 971 }, + { -1145, -4624, 1360, 2281 }, + { 101, -4746, 2866, 1255 }, + { -1500, -5455, 539, 1637 }, + { -969, -5909, 1414, 1128 }, + { -1261, -4939, -231, 2022 }, + { -226, -5345, 1207, 705 }, + { 2712, -5109, 3205, 1866 }, + { -476, -5913, 273, 1208 }, + { -2039, -4464, 624, 2545 }, + { -2351, -3930, 2019, 2673 }, + { -2675, -4849, 1522, 1990 }, + { -1524, -3461, 1446, 3204 }, + { 477, -5314, 1710, 1577 }, + { 656, -3729, 2346, 2511 }, + { 550, -5917, 1975, 1040 }, + { 1728, -4704, 3067, 1058 }, + { -9, -5247, 506, 1760 }, + { -574, -5135, 1675, 1672 }, + { 2129, -3781, 3444, 2313 }, + { 1144, -4439, 2214, 2529 }, + { 1292, -4160, 3185, 1833 }, + { 2445, -3262, 2534, 3227 }, + { 2266, -4401, 2023, 2400 }, + { -587, -3602, 3408, 2067 }, + { -885, -4951, 3228, 1174 }, + { -728, -2711, 2807, 3552 }, + { 1019, -3043, 3195, 2954 }, + { 1888, -4615, 1140, 2454 }, + { 660, -5616, 754, 800 }, + { -1975, -5371, 1649, 1585 }, + { -1544, -5436, 2422, 1081 }, + { -422, -5882, 2390, 750 }, + { 1336, -5557, 2441, 1230 }, + { 136, -4001, 267, 2854 }, + { -522, -3289, 2226, 2728 }, + { -971, -4580, 2471, 708 }, + { 704, -5306, 3300, 1001 }, + { 325, -3464, 3555, 2398 }, + { 794, -3686, 848, 3169 }, + { 660, -3017, 4584, 3242 }, + { -1486, -3978, 2170, 1644 }, + { -1615, -4650, 2688, 1844 }, + { 750, -4578, 538, 2239 }, + { 1668, -5849, 1455, 1031 }, + { 3486, -4681, 2030, 2183 }, + { 2642, -5429, 1696, 1761 }, + { 4491, -4502, 3538, 2767 }, + { 3545, -4528, 3514, 2982 }, + { 3269, -3676, 2758, 3966 }, + { 5572, 1146, 209, -3379 }, + { 7459, 1053, 593, -1896 }, + { 4480, 200, -310, -4259 }, + { 5577, -939, 242, -3992 }, + { 8142, 442, 1257, -3083 }, + { 5442, 1261, 1424, -3236 }, + { 6260, -183, 3125, -2532 }, + { 7179, 889, 1618, -2548 }, + { 6416, 932, 2379, -2487 }, + { 7094, 2560, 961, -3392 }, + { 7322, 463, 2732, -3735 }, + { 6632, 1577, 1912, -3272 }, + { 6312, 1349, 3028, -3460 }, + { 6105, 386, 1213, -977 }, + { 5478, 1158, 1114, -486 }, + { 6493, 410, 1686, -2180 }, + { 6378, 1881, 1333, -2240 }, + { 5711, 812, 1958, -1300 }, + { 6844, 877, 730, -1189 }, + { 6824, -245, 2249, -2000 }, + { 7515, 1521, 1251, -3058 }, + { 6697, 1051, 1300, -1749 }, + { 6476, 1425, 811, -2773 }, + { 7350, 465, -76, -2849 }, + { 6975, 2095, 567, -2492 }, + { 4691, 1736, 2660, -2289 }, + { 7837, 1456, 340, -2767 }, + { 7930, 507, 838, -2074 }, + { 6106, 1502, 766, -1110 }, + { 4891, -659, 835, -3954 }, + { 7250, 141, 1369, -1523 }, + { 7651, 67, 1651, -2298 }, + { 7364, -305, 601, -3132 }, + { 7179, 193, 2491, -2871 }, + { 6504, -272, 2167, -1322 }, + { 4456, 983, 2300, -421 }, + { 4817, 457, 1695, 371 }, + { 6914, 555, 850, -3159 }, + { 5904, 1030, 202, -1959 }, + { 6258, 880, 2233, -4503 }, + { 6029, 10, 2130, -3600 }, + { 6449, 985, 1129, -3963 }, + { 6616, -18, -111, -3285 }, + { 4496, 775, 817, -4276 }, + { 6134, 2338, 1470, -2973 }, + { 6911, 152, 430, -1946 }, + { 4053, 991, 3218, -1193 }, + { 5435, 1285, 3124, -2412 }, + { 5507, 1836, 1935, -1988 }, + { 5240, 689, 2189, -2670 }, + { 6638, 1719, 606, -1799 }, + { 5556, -180, 129, -2595 }, + { 5644, 1918, 1281, -4316 }, + { 6410, 1088, -282, -3117 }, + { 6503, 1841, 312, -3514 }, + { 6947, 20, 1358, -3886 }, + { 5464, 2109, 2398, -3194 }, + { 5616, -407, 2140, -498 }, + { 6121, 2707, 2379, -4096 }, + { 7303, 1846, 2266, -4095 }, + { 5444, 470, 2718, -1553 }, + { 5817, -645, 3285, -1349 }, + { 5625, 1427, 1103, -1991 }, + { 6041, -806, 1196, -2943 }, + { 3050, -5722, 4070, -5460 }, + { 3420, -4386, 4078, -5155 }, + { 6020, -3982, 7268, -2689 }, + { 7502, -4317, 7894, -3973 }, + { 4156, -3558, 5247, -4316 }, + { 4725, -4401, 7290, -1540 }, + { 6688, -5122, 8216, -3210 }, + { 9176, -6576, 9276, -4963 }, + { 8706, -5708, 7987, -4621 }, + { 7060, -3535, 6532, -3308 }, + { 5600, -2719, 5363, -1568 }, + { 4661, -2803, 6263, -4716 }, + { 3673, -3636, 6147, -3433 }, + { 5305, -2585, 6073, -2638 }, + { 7614, -1962, 6079, -5266 }, + { 6760, -3366, 7382, -4322 }, + { 6385, -3883, 4797, -1353 }, + { 8182, -5120, 4298, -4641 }, + { 9130, -6198, 4975, -3063 }, + { 7421, -5436, 5576, -3713 }, + { 3483, -4898, 5443, -2745 }, + { 4907, -5643, 6390, -4105 }, + { 8119, -7008, 7992, -6764 }, + { 6528, -6122, 6967, -5590 }, + { 5890, -4190, 6624, -5688 }, + { 6815, -7934, 7275, -5456 }, + { 5434, -4306, 5169, -5378 }, + { 4364, -6436, 5376, -2604 }, + { 8152, -3404, 5913, -5048 }, + { 7983, -4863, 4262, -2461 }, + { 8023, -6188, 6238, -5062 }, + { 6753, -3692, 3935, -3723 }, + { 6826, -4760, 3284, -4051 }, + { 7224, -7423, 4492, -3875 }, + { 6904, -2590, 6587, -6248 }, + { 6106, -1944, 7345, -5506 }, + { 4956, -2990, 7808, -3146 }, + { 6908, -6885, 5949, -1288 }, + { 7162, -6058, 3419, -3401 }, + { 7015, -7080, 6907, -3018 }, + { 6971, -6832, 5646, -3273 }, + { 8014, -5546, 5471, -1544 }, + { 6792, -2220, 5105, -2879 }, + { 8494, -3974, 4408, -3999 }, + { 9591, -4866, 6027, -4558 }, + { 5264, -5161, 6101, -738 }, + { 5803, -6141, 5197, -5231 }, + { 4657, -6822, 3232, -5189 }, + { 4791, -5135, 3809, -4665 }, + { 6108, -5103, 2379, -3873 }, + { 4680, -3909, 3234, -5093 }, + { 5802, -3853, 3795, -4984 }, + { 4360, -7483, 4802, -3877 }, + { 5429, -7517, 5911, -3717 }, + { 6866, -2280, 4880, -4634 }, + { 10131, -4628, 4414, -4092 }, + { 10811, -5189, 7746, -5337 }, + { 5663, -8941, 5287, -5680 }, + { 8023, -5991, 7403, -2796 }, + { 9669, -6919, 6525, -4932 }, + { 7275, -3796, 4962, -2547 }, + { 8848, -4806, 5677, -3080 }, + { 8128, -4308, 7749, -6569 }, + { 4032, -5196, 2282, -6239 }, + { 6593, 700, -229, 304 }, + { 8260, 539, -66, -1259 }, + { 6605, 176, -814, -109 }, + { 8057, 0, -1, -136 }, + { 7382, -38, -484, -1129 }, + { 8373, -929, 682, -454 }, + { 7674, 690, -1278, 546 }, + { 7326, -517, 406, -1283 }, + { 7612, -1715, -1167, 1175 }, + { 8590, 441, -782, -710 }, + { 8572, -1202, -291, 260 }, + { 7308, -147, -1785, 414 }, + { 6787, -353, -672, 934 }, + { 5177, -133, 179, 82 }, + { 4161, -34, 447, 1497 }, + { 5997, -902, 1533, -121 }, + { 5727, -871, -1370, 945 }, + { 8386, -252, 293, -823 }, + { 6573, -1354, 682, 616 }, + { 7650, -2096, 725, 457 }, + { 8122, 78, 636, -1400 }, + { 8421, 428, -1620, 131 }, + { 7341, -1292, -717, 186 }, + { 7998, -49, -720, 266 }, + { 5987, -351, 669, 844 }, + { 7314, -1620, 250, -603 }, + { 7219, -1562, -572, 1994 }, + { 8682, -358, -290, -388 }, + { 5810, 155, -178, 1199 }, + { 7246, -12, 1042, -786 }, + { 7357, -923, 1468, -475 }, + { 7801, 621, -212, -724 }, + { 5346, -514, 1210, 1356 }, + { 8459, 36, -127, -779 }, + { 6878, -2429, 854, 1750 }, + { 7280, -1401, -1353, 2845 }, + { 7579, -2148, -1463, 2087 }, + { 6637, 946, -872, 750 }, + { 4807, -1100, 1289, 2602 }, + { 4495, 219, 1551, 1128 }, + { 7639, 506, 446, -1107 }, + { 6359, 188, 1009, -115 }, + { 6641, -1820, 1655, 723 }, + { 5394, -2382, 1604, 2542 }, + { 6021, -2644, 2396, 1407 }, + { 4698, 882, 245, 1525 }, + { 8103, 573, -798, -349 }, + { 8045, -519, 997, -1092 }, + { 7571, -122, 227, -338 }, + { 5347, -1200, 630, 1718 }, + { 7070, 790, 218, -544 }, + { 7440, 728, -527, -20 }, + { 6402, -355, 197, -736 }, + { 4031, 771, 866, 1895 }, + { 6009, 896, 445, -31 }, + { 5160, 1098, -856, 1784 }, + { 7980, -886, -1293, 1396 }, + { 6318, -1361, 2423, 252 }, + { 7547, -699, 133, 506 }, + { 8562, -2344, 940, 264 }, + { 5890, 1187, -1425, 2194 }, + { 6558, -645, -1311, 2621 }, + { 4634, -1671, 2075, 1623 }, + { 5614, 105, -816, 2376 }, + { 6646, 1558, -1365, 630 }, + { 6998, 1150, -2117, -990 }, + { 6555, 2311, -1093, -1783 }, + { 6682, 1430, -2391, -1940 }, + { 7861, 1555, -2977, -1188 }, + { 6745, 1723, -459, -2085 }, + { 7504, 1229, -1666, -2060 }, + { 7937, 671, -2128, -1529 }, + { 7139, 991, -735, -2632 }, + { 6867, 1592, -1303, -2324 }, + { 6401, 2230, -1732, -2508 }, + { 7201, 2184, -2169, -1988 }, + { 6636, 2190, -995, -2840 }, + { 7620, 2306, -2089, -651 }, + { 7584, 1875, -1438, -631 }, + { 9214, 1561, -2464, -1139 }, + { 6154, 1318, -1237, -2917 }, + { 7917, 2847, -1797, -1599 }, + { 8309, 2029, -2555, -465 }, + { 8204, 1282, -584, -2405 }, + { 8440, 1035, -1147, -1137 }, + { 7107, 1858, -60, -1568 }, + { 6781, 2912, -873, -1463 }, + { 7603, 1316, -319, -1249 }, + { 7833, 1335, -78, -1849 }, + { 7930, 1141, -1016, -695 }, + { 7883, 1610, -1017, -1314 }, + { 8069, 1409, -1811, -196 }, + { 8319, 1031, -582, -1590 }, + { 5948, 1537, -2153, -2373 }, + { 8684, 1171, -1871, -850 }, + { 8357, 2484, -2411, -1292 }, + { 6516, 2092, -193, -1167 }, + { 6112, 1697, 22, -525 }, + { 7161, 703, -602, -1879 }, + { 6047, 2351, -807, -219 }, + { 8072, 1854, -1817, -1553 }, + { 6956, 1304, 76, -1011 }, + { 6607, 1481, -544, -162 }, + { 6958, 2541, -265, -1938 }, + { 6416, 2514, -777, -850 }, + { 7272, 2110, -899, -1171 }, + { 7741, 2153, -283, -2614 }, + { 6482, 2041, -1758, -1221 }, + { 6762, 940, -1862, -2281 }, + { 5610, 1194, -1691, -1561 }, + { 7833, 2164, -823, -1952 }, + { 5460, 1438, -848, 1189 }, + { 6011, 1377, -771, -1557 }, + { 7679, 544, -1134, -2214 }, + { 7209, 1292, -2714, -1564 }, + { 5567, 1200, -404, -169 }, + { 5853, 1461, -1465, -518 }, + { 6782, 689, -844, -860 }, + { 7330, 1337, -1152, -71 }, + { 7189, 1506, -653, -685 }, + { 6860, 2116, -1403, -240 }, + { 8804, 1516, -1391, -1760 }, + { 7210, 2689, -1498, -989 }, + { 7030, 3022, -1441, -2083 }, + { 5649, 1836, -407, 525 }, + { 7451, 3099, -717, -2464 }, + { 7384, 1656, -2007, 398 }, + { 6504, 707, -1919, -134 }, + { -1851, 3639, -2279, -695 }, + { -4037, 1644, -77, 1329 }, + { -4025, 1960, -1565, -567 }, + { -3430, 2495, -795, 368 }, + { -4771, 2480, 993, 756 }, + { -3431, 2058, -2539, -971 }, + { -3802, 3418, 380, 217 }, + { -3074, 3350, -1652, -1056 }, + { -3705, 326, -1650, 1535 }, + { -3122, 1281, -1192, 1607 }, + { -4601, 1367, -968, 53 }, + { -3808, 958, 44, 2560 }, + { -2079, 2530, -1485, 1166 }, + { -3707, 343, -2889, 180 }, + { -5249, 1431, -31, 688 }, + { -4990, 125, -704, 1270 }, + { -2771, 1334, -2446, 746 }, + { -2292, 994, -1527, 2630 }, + { -1261, 3070, -2519, 268 }, + { -2544, 3890, -1057, -552 }, + { -4421, 255, -1980, 530 }, + { -2951, 454, -13, 3643 }, + { -2262, 1815, -370, 2880 }, + { -2383, 3657, -649, 576 }, + { -3541, -161, -1389, 2550 }, + { -4241, 1575, 1325, 2561 }, + { -2767, 4037, 1221, 1578 }, + { -3748, 2697, 1148, 1801 }, + { -4686, 2385, -220, 0 }, + { -1531, 1645, -2751, 1327 }, + { -45, 4032, -799, 2298 }, + { -2915, 2280, 709, 2495 }, + { -1199, 3278, -406, 2346 }, + { -2471, 116, -2706, 2060 }, + { -2440, 2173, -2894, -344 }, + { -3375, 2287, 1781, 3226 }, + { -2153, 3568, 1827, 2918 }, + { -862, 2267, -1626, 2527 }, + { -2698, 1135, 301, 4239 }, + { -2364, 2123, 1010, 3710 }, + { -2447, 3281, -81, 1408 }, + { -2660, 4735, 472, 258 }, + { -1053, 3097, 2682, 2398 }, + { -3366, -1037, -1152, -868 }, + { -643, 4242, 2212, 1259 }, + { 971, 3991, 934, 643 }, + { -1617, 2002, 2139, 2195 }, + { -4897, 972, 784, 1719 }, + { -1275, 2992, 1039, 3821 }, + { -392, 4973, -209, 1821 }, + { -1028, 4718, -1479, -137 }, + { 50, 3914, 553, 2210 }, + { 678, 4364, 359, 1303 }, + { -582, 4911, 514, 1671 }, + { 1276, 3914, -1252, 2934 }, + { -1496, 3984, 857, 2330 }, + { 772, 4744, -655, 2332 }, + { -799, 5283, -439, 624 }, + { 1341, 2937, 650, 2027 }, + { -1739, 4892, 1275, 1702 }, + { -892, 2596, -151, 3951 }, + { -3532, 1090, 1292, 32 }, + { 321, 3146, 2647, 1475 }, + { 264, 4199, -1591, 1317 }, + { -452, -2357, 2266, 4192 }, + { 3022, -1033, -2389, 5678 }, + { -1162, -1342, 3543, 4990 }, + { -474, -1477, -1223, 5016 }, + { -699, -2857, 900, 3835 }, + { -461, -2255, -117, 4626 }, + { 1204, -2062, -1211, 4403 }, + { 2192, -3035, -337, 3966 }, + { 108, -831, 279, 5643 }, + { 1457, -620, -2908, 5276 }, + { -2527, -78, 1085, 5460 }, + { -1978, -1918, -949, 4733 }, + { 32, 367, -1904, 5166 }, + { 1890, -1665, 440, 4752 }, + { -518, -348, 2816, 4891 }, + { 3695, -2490, -1374, 4603 }, + { 246, -1965, 3549, 3969 }, + { 1100, -3111, 656, 3737 }, + { -1379, 870, -414, 4575 }, + { 628, -357, -1227, 6179 }, + { -1129, -1318, -2457, 4576 }, + { -425, -98, -73, 6336 }, + { 367, -887, 2990, 4207 }, + { 2091, -1251, 2444, 3557 }, + { -1759, -1610, 2046, 5273 }, + { 3210, 1414, -20, 2616 }, + { 3303, -2636, 1005, 4237 }, + { -327, -3107, -640, 3687 }, + { -197, 764, 572, 5486 }, + { 646, -767, 1388, 5464 }, + { 104, 2742, -228, 3907 }, + { -236, 1829, -579, 4585 }, + { -2150, -474, -1525, 4006 }, + { -23, -2632, -2400, 3892 }, + { -12, -1739, -2910, 4867 }, + { -2310, -368, -102, 4583 }, + { -1991, -2061, 533, 4531 }, + { 3884, -1446, -153, 4393 }, + { 1568, 14, -289, 5268 }, + { -1376, -253, -2797, 3417 }, + { 3193, -2577, 2475, 3566 }, + { 3418, 617, 1350, 1857 }, + { 3792, -24, -272, 3370 }, + { 153, 1159, 2906, 2877 }, + { 511, 2162, 1548, 2741 }, + { 262, 819, -2791, 3734 }, + { 4232, -2015, 1486, 3477 }, + { 2943, -1110, -1014, 5480 }, + { 2842, 369, 703, 3476 }, + { 3011, 1634, -933, 3553 }, + { 4412, -1548, -942, 5021 }, + { -1405, 593, 2372, 5267 }, + { 2093, 2129, 896, 2365 }, + { 4845, -1980, 0, 3823 }, + { -2140, 81, 3278, 5637 }, + { 1484, 2665, -324, 3653 }, + { 10, 192, 1620, 5291 }, + { 2152, 738, -2269, 5000 }, + { 2102, 2748, -1652, 4707 }, + { 2855, -2131, -387, 5188 }, + { 1173, 676, 1338, 3277 }, + { 2340, -2329, -2064, 4095 }, + { 861, -2024, 1296, 5055 }, + { 2189, 3225, -695, 2626 }, + { 6196, -7079, 1943, -822 }, + { 4547, -4813, 3261, 1856 }, + { 4243, -6904, 3443, 448 }, + { 4581, -7503, 946, 506 }, + { 6626, -7754, 3427, 470 }, + { 3407, -9088, 3269, -1496 }, + { 4079, -6464, 2304, 777 }, + { 5621, -9336, 2684, -768 }, + { 5351, -6464, 5238, -214 }, + { 5961, -8007, 1724, -3091 }, + { 4213, -8067, 603, -246 }, + { 7208, -7403, 3168, -1738 }, + { 6098, -7700, 329, -1379 }, + { 6525, -6735, 4248, -1072 }, + { 6073, -6241, 2167, -2378 }, + { 4609, -9218, 3051, -1033 }, + { 6813, -7283, 1581, -1897 }, + { 6126, -6275, 2789, 681 }, + { 4423, -6538, 1621, -1692 }, + { 6272, -8298, 3167, -1855 }, + { 6172, -8558, 4498, -1169 }, + { 4844, -8588, 1647, -366 }, + { 6209, -8807, 1581, -369 }, + { 5389, -8059, 550, -192 }, + { 6654, -9775, 2504, -1063 }, + { 7103, -7998, 806, 530 }, + { 5662, -6736, 1565, -3620 }, + { 4165, -9564, 4191, -2131 }, + { 4526, -7181, 576, -2875 }, + { 4633, -8623, 2807, -4742 }, + { 3709, -7794, 1815, 34 }, + { 3634, -8622, 2313, -826 }, + { 6991, -8447, 2063, -3198 }, + { 7757, -9486, 2255, -558 }, + { 4149, -7778, 4728, -1696 }, + { 5767, -7427, 1113, 707 }, + { 4592, -6261, 2329, 1864 }, + { 3159, -10498, 1677, -4273 }, + { 3534, -9010, 2437, -3565 }, + { 4479, -10821, 2715, -4942 }, + { 3207, -9805, 3054, -3886 }, + { 4627, -8189, 3018, -2354 }, + { 5527, -10566, 3244, -2749 }, + { 4346, -10127, 3335, -3084 }, + { 6132, -10085, 3316, -1308 }, + { 5629, -9704, 2178, -3058 }, + { 3603, -8538, 1246, -624 }, + { 3737, -8488, 395, -3167 }, + { 5465, -11414, 2810, -4640 }, + { 5306, -7745, 2721, -3988 }, + { 7000, -9111, 1695, -1409 }, + { 6663, -7741, 2466, -4079 }, + { 4083, -7175, 1836, -4831 }, + { 3613, -9926, 1342, -3455 }, + { 6588, -8033, 457, -258 }, + { 4720, -8102, 17, -1209 }, + { 7414, -8709, 1294, -344 }, + { 5437, -10030, 4043, -1704 }, + { 4862, -9281, 1558, -1431 }, + { 6800, -6403, 5113, 862 }, + { 4623, -8242, 2667, -228 }, + { 5919, -5083, 3348, 2135 }, + { 5985, -8889, 2733, -5105 }, + { 5029, -5767, 4407, 719 }, + { 354, -6158, -838, -3001 }, + { 351, -5943, -2104, -1534 }, + { -633, -7190, -25, -4798 }, + { -1595, -7235, -3812, -1400 }, + { 103, -6197, -2933, -78 }, + { -1722, -5020, -3441, -4333 }, + { -1963, -5644, -4365, -270 }, + { -846, -5743, -3477, 196 }, + { -191, -5348, -4054, -469 }, + { -2515, -7754, -3495, -818 }, + { -2090, -6710, -2701, 117 }, + { -546, -7036, -1398, 163 }, + { -278, -7091, -2662, -536 }, + { -622, -7962, -2731, -1464 }, + { -1555, -8118, -3612, -2057 }, + { -1094, -6280, -2314, 505 }, + { -2556, -8538, -4024, -2247 }, + { 109, -7134, -3107, -1823 }, + { -900, -6954, -3340, -717 }, + { -605, -7113, -3656, -2154 }, + { 837, -6263, -3211, -2177 }, + { -417, -5810, -3871, -1469 }, + { -1318, -5649, -4207, -3198 }, + { 413, -6765, -2082, -33 }, + { -3101, -6450, -4362, -766 }, + { 755, -6489, -2967, -846 }, + { 1117, -7106, -2452, -1352 }, + { -1202, -8387, -3072, -2897 }, + { -365, -4894, -3561, -2937 }, + { -2372, -8776, -265, -4441 }, + { -1224, -8678, -896, -5074 }, + { -755, -10096, -600, -6623 }, + { 300, -8206, -225, -4568 }, + { -1176, -6824, -2633, -3527 }, + { -2006, -5443, -1526, -5849 }, + { -1115, -5540, -2363, -4785 }, + { 1059, -6812, -2543, -2654 }, + { -1976, -6861, -3062, -5508 }, + { -379, -5328, -2321, -3624 }, + { -2108, -5860, -4518, -1915 }, + { -379, -7885, -1329, -594 }, + { 774, -5389, -581, -5213 }, + { -2601, -5083, -1849, -4921 }, + { -176, -5580, 74, -5075 }, + { -204, -6780, -190, -6232 }, + { 418, -7594, -1987, -820 }, + { -1873, -8529, -2926, -1609 }, + { 1340, -6362, -919, -4975 }, + { 577, -7990, -2044, -1873 }, + { -2572, -7413, -1745, -2224 }, + { -2037, -7030, -1461, -7138 }, + { -2559, -8756, -2039, -5836 }, + { -2079, -6764, -1209, -5669 }, + { -1613, -7801, -2006, -685 }, + { -1865, -6583, -722, -3529 }, + { -589, -6358, -1377, -1003 }, + { -540, -7514, -1331, -3542 }, + { 419, -6192, -1677, -4927 }, + { -2786, -8763, -2966, -5065 }, + { -2172, -8411, -1726, -4675 }, + { -3382, -9833, -3497, -5722 }, + { -2433, -10169, -2077, -5775 }, + { -424, -9451, -1096, -3658 }, + { -537, -8522, -910, -1897 }, + { -5550, 2807, 1683, -693 }, + { -6395, 635, 3573, -1246 }, + { -7544, 2280, 2140, 44 }, + { -8751, 1136, 2951, -794 }, + { -5605, 2709, 2052, 916 }, + { -7650, 654, 869, 135 }, + { -6939, 967, 1409, 870 }, + { -7834, 2123, 3310, 974 }, + { -6935, 2818, 1274, -1678 }, + { -5605, 2233, 1013, 471 }, + { -7095, 1849, 1648, 198 }, + { -6636, 1634, 712, -37 }, + { -7279, 978, 296, -315 }, + { -7664, 3504, 3292, -216 }, + { -7836, 1209, 1221, -257 }, + { -7913, 2201, 1765, -1529 }, + { -7077, 3783, 2632, -1407 }, + { -5565, 1645, 1410, -622 }, + { -6494, 2879, 1181, -759 }, + { -7073, 3137, 3010, 550 }, + { -7249, 1839, 847, -805 }, + { -6630, 2197, 282, -1096 }, + { -8836, 1573, 1988, -1090 }, + { -7809, 1274, 836, -1198 }, + { -7895, 2970, 3511, -1097 }, + { -6960, 1664, 1356, -2442 }, + { -6582, 2866, 2273, 307 }, + { -7221, 821, 2851, -1435 }, + { -6015, 1703, 2001, -2367 }, + { -8082, 1034, 2103, 239 }, + { -5952, 1912, 301, -465 }, + { -6099, 841, 379, 567 }, + { -6343, 50, 494, 658 }, + { -6586, 983, 591, -893 }, + { -5500, 869, 2187, -2479 }, + { -6482, 60, 1545, -979 }, + { -6705, 515, 1974, -53 }, + { -6460, 1755, 1325, -1275 }, + { -6093, 2617, 2465, -623 }, + { -7330, 2161, 594, -2115 }, + { -7324, 762, 1593, -2004 }, + { -6385, 679, 1510, -2514 }, + { -6159, 241, 2976, -1631 }, + { -8583, 3030, 4045, -162 }, + { -6299, 66, 2209, -2103 }, + { -5428, 1279, 3267, -1846 }, + { -6438, 1335, 2728, -1631 }, + { -8012, 1070, 2428, -1151 }, + { -6201, 2781, 2349, -1918 }, + { -5918, 1139, 3121, -148 }, + { -6314, 2481, 3137, -1808 }, + { -7180, 1722, 2435, -1602 }, + { -6750, 1829, 3763, -1145 }, + { -6713, 1777, 2221, 1212 }, + { -7479, 1835, 3627, -479 }, + { -7299, 10, 2406, -1593 }, + { -8249, 3129, 996, -2870 }, + { -8374, 1534, 1333, -1882 }, + { -7507, 3353, 1598, -2299 }, + { -7379, 2701, 2326, -1167 }, + { -8440, 2276, 2796, -542 }, + { -10348, 1527, 2649, -1165 }, + { -8184, 3614, 2574, -1738 }, + { -5539, 1574, 1733, 1138 }, + { 9404, -7652, 67, 79 }, + { 8654, -3972, 1358, -60 }, + { 8617, -4794, 117, 2318 }, + { 7886, -4505, 1784, 1200 }, + { 8636, -6125, 3879, -1003 }, + { 9654, -6836, 1816, 205 }, + { 9374, -6553, 913, 1875 }, + { 8020, -6150, 1134, 2390 }, + { 7786, -4970, 2078, -1857 }, + { 8691, -6119, 711, 708 }, + { 9039, -5568, 2944, -1902 }, + { 9955, -5048, 1433, -601 }, + { 8089, -6927, 3093, -2846 }, + { 8487, -7024, 2415, 19 }, + { 9388, -5287, 3577, -2655 }, + { 8591, -7371, 2300, -996 }, + { 9104, -4763, 1453, -2558 }, + { 7615, -5457, 596, 164 }, + { 9860, -7047, 3433, -614 }, + { 8756, -4404, 2235, -964 }, + { 9462, -4660, 299, -1822 }, + { 10119, -5550, 2689, -1273 }, + { 10915, -7471, 2705, -1007 }, + { 11433, -7090, 1410, -1198 }, + { 9882, -7431, 2965, -1895 }, + { 7628, -5219, 769, -2661 }, + { 8169, -5318, 2262, 70 }, + { 8846, -6320, 1939, -754 }, + { 7147, -5593, 1248, -971 }, + { 10652, -5485, 935, 137 }, + { 7778, -6533, 2564, -1932 }, + { 8878, -5173, 1214, -361 }, + { 9828, -4943, 282, 510 }, + { 10042, -6134, 3895, -1914 }, + { 7965, -6630, 3566, -433 }, + { 8573, -4502, 3574, -1209 }, + { 8398, -4801, 1031, -1347 }, + { 10136, -7772, 2612, 1547 }, + { 9890, -7280, 1768, -1083 }, + { 8407, -6585, -706, -58 }, + { 7976, -7582, 229, -131 }, + { 10481, -8866, 1166, -147 }, + { 10914, -4342, 3189, -2412 }, + { 10440, -5198, -104, -1109 }, + { 11227, -6530, 2381, -2449 }, + { 8487, -8064, 1086, 230 }, + { 9975, -6123, -857, -134 }, + { 8339, -6498, 1232, -2337 }, + { 11042, -4506, 1119, -2098 }, + { 12563, -5592, 1837, -2062 }, + { 11801, -5590, 632, -1296 }, + { 10152, -5617, 1511, -1917 }, + { 7800, -6473, 51, -1337 }, + { 7941, -5560, 2438, -3270 }, + { 6554, -3834, 2100, 1476 }, + { 9065, -5520, -226, -1120 }, + { 10794, -7120, -243, 122 }, + { 10429, -6968, 272, -806 }, + { 8942, -8914, 1442, -392 }, + { 9969, -5051, 2033, -2953 }, + { 7275, -4152, 3058, -64 }, + { 11127, -5488, 4589, -3227 }, + { 9626, -6666, 2739, -2958 }, + { 6943, -5362, 4470, 1008 }, + { -7456, -967, 2936, -1002 }, + { -8622, -333, 6962, 2606 }, + { -7486, -3392, 3668, 1287 }, + { -8053, -827, 5148, 1097 }, + { -6610, 454, 4952, 96 }, + { -7701, -1982, 3161, -468 }, + { -7307, -1132, 4071, -36 }, + { -8125, -271, 5199, 3862 }, + { -9182, -1950, 2813, 1878 }, + { -9855, -952, 4794, 3010 }, + { -7241, 1431, 4202, 2468 }, + { -9646, 157, 4766, 1046 }, + { -9371, 1230, 6009, 2958 }, + { -11514, -64, 8630, 5248 }, + { -6766, 565, 2766, 2140 }, + { -8426, -9, 2852, 1271 }, + { -11291, -1113, 5087, 2937 }, + { -8297, 2092, 4495, 1264 }, + { -9983, 735, 3809, -51 }, + { -9048, -1000, 3191, -308 }, + { -7331, -1987, 2655, 1391 }, + { -7144, -21, 4333, 2161 }, + { -6032, -1540, 3543, 896 }, + { -7987, -1036, 1985, 1529 }, + { -9264, 2004, 5194, 290 }, + { -11308, -840, 5754, 1654 }, + { -9130, -2398, 4292, 2973 }, + { -6248, 838, 3563, 1223 }, + { -6819, -2760, 3511, 119 }, + { -7213, -2006, 4364, 762 }, + { -5431, -1047, 4533, 166 }, + { -7098, -641, 2021, 639 }, + { -8628, -2249, 3588, 399 }, + { -6352, -1498, 3560, -648 }, + { -7033, -2190, 4870, 2562 }, + { -7405, -46, 3772, -581 }, + { -6104, 796, 5143, 1965 }, + { -5787, 943, 5784, 3030 }, + { -8367, 1465, 7192, 4097 }, + { -8259, 789, 5694, 1963 }, + { -10614, -1899, 5748, 2645 }, + { -8258, -805, 3698, 2275 }, + { -6877, -972, 6431, 3160 }, + { -6483, 363, 7018, 3129 }, + { -6283, -1358, 5191, 1524 }, + { -8853, -3157, 4119, 1741 }, + { -6086, -267, 3883, -835 }, + { -7254, 1032, 6613, 4017 }, + { -11470, -3350, 4649, 3426 }, + { -6743, 481, 6148, 1239 }, + { -5394, -166, 5309, 3165 }, + { -7958, 1068, 4268, -240 }, + { -10520, 2256, 7916, 2828 }, + { -5132, -4, 5739, 1176 }, + { -8643, 120, 3255, -629 }, + { -9631, 1974, 8870, 4362 }, + { -10663, -1221, 3733, 589 }, + { -8224, -1843, 5806, 2655 }, + { -8282, 1255, 8647, 3478 }, + { -12311, -1505, 9043, 6256 }, + { -11312, -856, 7136, 4681 }, + { -11944, -722, 7941, 3309 }, + { -7868, -463, 6846, 4196 }, + { -8679, -241, 7410, 5347 }, + { 6759, -4680, -508, 1220 }, + { 5176, -6111, 944, 121 }, + { 6843, -5667, -1368, -533 }, + { 5616, -5884, -1471, -695 }, + { 6030, -5089, -1808, -940 }, + { 7444, -5463, -52, 1881 }, + { 4207, -6079, -506, 1571 }, + { 6785, -4410, -649, 3084 }, + { 4838, -5214, 2026, 2998 }, + { 4201, -5790, 645, 1811 }, + { 6930, -5129, -1940, 1698 }, + { 6332, -4627, 692, 3027 }, + { 6285, -4314, -106, 3644 }, + { 6255, -5450, -1975, 742 }, + { 4199, -4676, -459, 1796 }, + { 5592, -5500, 1345, 1300 }, + { 4358, -5556, -2236, 114 }, + { 4620, -5875, -1563, 888 }, + { 4892, -7550, -327, -419 }, + { 4734, -7085, 7, 613 }, + { 3883, -5562, -1969, 1080 }, + { 5610, -4990, -204, 834 }, + { 4117, -6482, -1271, 341 }, + { 6585, -5107, 892, 1169 }, + { 6632, -3683, 302, 3002 }, + { 6326, -5351, -983, -1250 }, + { 4382, -7192, -730, -158 }, + { 5227, -6540, -451, 1123 }, + { 5468, -6472, -870, -1471 }, + { 5191, -6402, -1365, -127 }, + { 7407, -6317, -973, -336 }, + { 4611, -6530, -820, -1980 }, + { 4963, -5159, -2050, -966 }, + { 4414, -5691, -211, -998 }, + { 5954, -5873, 750, -1749 }, + { 4394, -4796, -1268, 254 }, + { 7161, -6214, -1010, 689 }, + { 4965, -3598, 2372, 1711 }, + { 6248, -6180, 981, 864 }, + { 6473, -5336, 525, -600 }, + { 4591, -6864, -1131, -900 }, + { 6314, -6440, -1021, -375 }, + { 5838, -6209, -1199, 944 }, + { 5308, -5283, -2100, 1267 }, + { 4342, -5860, -1637, -1356 }, + { 5680, -4388, -1227, -104 }, + { 4900, -4098, 1449, 4046 }, + { 4677, -4284, -106, 3190 }, + { 7574, -6173, -848, 1859 }, + { 6493, -7207, -131, 726 }, + { 5513, -5261, -2117, 4 }, + { 6191, -7352, -193, -505 }, + { 5885, -4333, 324, -134 }, + { 6162, -6081, -312, -2044 }, + { 4216, -6200, -1810, -572 }, + { 5652, -7035, -696, -197 }, + { 7131, -7189, -366, -60 }, + { 5032, -4803, -1514, 2832 }, + { 7386, -4610, -606, 3489 }, + { 4211, -5031, 1221, 3047 }, + { 4050, -4653, 1584, 1469 }, + { 6852, -5302, -1861, 206 }, + { 7736, -4816, -1794, 3359 }, + { 6290, -3439, 1522, 2454 }, + { 1768, 5990, -5560, -2594 }, + { 3903, 5326, -1530, -1501 }, + { 2472, 3738, -2117, -4240 }, + { 3260, 5448, -904, -4733 }, + { 1435, 7297, -3676, -4102 }, + { 4096, 5951, -656, -3312 }, + { 2178, 6009, -3146, -3724 }, + { 3787, 5493, -5473, -1633 }, + { 2998, 7286, -3334, -3571 }, + { 2894, 6576, -4708, -2804 }, + { 830, 6163, -4286, -3348 }, + { 4755, 5569, -1730, -2739 }, + { 4604, 6065, -3562, -2605 }, + { 2749, 5141, -3986, -2775 }, + { 3942, 4875, -2143, -3340 }, + { 2819, 8517, -2004, -2724 }, + { 2146, 6298, -689, -3093 }, + { 5196, 6504, -3393, -1475 }, + { 1851, 8386, -1748, -1420 }, + { 3474, 8572, -3534, -2688 }, + { 4503, 7560, -3561, -2245 }, + { 4433, 6219, -2393, -1575 }, + { 3506, 7248, -2275, -1977 }, + { 3490, 7409, -3147, -604 }, + { 4214, 6447, -3520, 516 }, + { 619, 7034, -829, -1705 }, + { 1732, 7395, -356, -2208 }, + { 1226, 5204, -3294, -3732 }, + { 2027, 5619, -1813, -4146 }, + { 3078, 5877, 47, -2651 }, + { 1654, 5458, 424, -682 }, + { 3163, 5464, -2026, -270 }, + { 2884, 5375, -685, -530 }, + { 2950, 7286, -35, -2967 }, + { 1986, 5066, -597, 482 }, + { 3459, 4308, -3845, -2333 }, + { 3155, 7037, -1346, -4345 }, + { 2193, 6696, -717, -1319 }, + { 3677, 5089, -3892, -487 }, + { 2186, 5136, -4186, -1492 }, + { 773, 5796, -917, 817 }, + { 2489, 6546, -3570, -2117 }, + { 1223, 6469, -1362, -33 }, + { 271, 6061, -1466, -1725 }, + { 2540, 5171, -1847, 1032 }, + { 2548, 5251, -2697, 1677 }, + { 771, 7600, -768, -632 }, + { 4710, 6647, -4736, -1275 }, + { 1369, 5917, -2971, -1056 }, + { 163, 5239, -3499, -2275 }, + { 2104, 4285, -3211, -3286 }, + { 1107, 7411, -1972, -1671 }, + { 2196, 7262, -2310, -1926 }, + { -244, 6439, -1745, -839 }, + { 3293, 3832, -2890, -3000 }, + { 419, 6443, -379, -407 }, + { 3077, 4930, -1156, -2869 }, + { 2131, 5874, -2330, 224 }, + { 690, 6538, -2212, -2841 }, + { 1602, 4421, -2515, 1542 }, + { 3318, 9373, -3032, -3477 }, + { 5646, 7462, -5153, -1463 }, + { 4139, 7137, -1539, -3321 }, + { 3481, 9077, -1645, -3653 }, + { -7747, 375, -106, -543 }, + { -8587, -1379, -586, -461 }, + { -10146, -892, 2094, 694 }, + { -8103, 382, 504, -325 }, + { -8548, -92, 94, -656 }, + { -7460, 38, 152, 388 }, + { -8266, -271, -459, -883 }, + { -7935, -664, -1026, -802 }, + { -8341, -109, 853, 161 }, + { -8802, -1355, 1099, 630 }, + { -8957, -6, 1108, -669 }, + { -7260, -1520, -43, -407 }, + { -7555, -174, 668, -2562 }, + { -9014, -126, 227, -1191 }, + { -8184, 769, 290, -1375 }, + { -9476, 55, 962, -1528 }, + { -8679, 541, 755, -1030 }, + { -9842, -1626, 838, -1588 }, + { -8513, -702, 788, -1998 }, + { -10101, -1558, -366, -1841 }, + { -8135, 78, 1479, -1813 }, + { -9128, -454, 313, -1786 }, + { -7554, -1084, 831, -2442 }, + { -7576, -701, 2068, -1665 }, + { -7791, -1481, 1587, -1808 }, + { -6701, -596, -97, 802 }, + { -7418, -15, 684, -963 }, + { -7127, -477, -139, -426 }, + { -8097, -110, -36, -264 }, + { -7620, -1922, -590, -101 }, + { -7647, -1201, 279, 660 }, + { -7856, -1974, 758, -2271 }, + { -8496, -167, 2232, -1143 }, + { -8506, -1359, 624, -740 }, + { -7274, -1052, 1062, -139 }, + { -7800, -217, 91, -1794 }, + { -7030, -1694, -955, 615 }, + { -9020, -1864, 101, -2182 }, + { -9400, -740, 598, -667 }, + { -8448, -1184, 2024, -1272 }, + { -8812, -570, -897, -2384 }, + { -10559, -1286, 538, -1536 }, + { -8728, -888, -1089, -1397 }, + { -7080, -1185, 636, -1252 }, + { -9880, 233, 2344, -782 }, + { -7952, -1326, -378, -1947 }, + { -7207, -378, 1408, -2237 }, + { -8467, -1545, 902, -1987 }, + { -9163, -1474, 924, -1739 }, + { -8159, -992, -77, -2744 }, + { -8343, 148, -423, -1573 }, + { -9105, -649, -254, -1214 }, + { -8939, 456, 281, -1905 }, + { -8837, 179, -394, -2634 }, + { -9145, 757, 1547, -1319 }, + { -9775, -723, 441, -1680 }, + { -8910, -686, 1529, -1525 }, + { -9492, -1134, 2064, -938 }, + { -6111, -943, 677, -31 }, + { -7411, -613, -814, 46 }, + { -9479, -922, -430, -2061 }, + { -11298, -1268, 1318, -1117 }, + { -8190, 832, 671, -2214 }, + { -10453, -550, 1672, -886 }, + { 1044, 9353, -1651, -5423 }, + { 1034, 8149, -455, -6166 }, + { 761, 8293, -3214, -4838 }, + { 938, 8077, 164, -5130 }, + { 1295, 8673, 2582, -5490 }, + { -314, 7973, -2395, -5231 }, + { -507, 9012, -2497, -5775 }, + { 2396, 8314, -1022, -4673 }, + { -1516, 8501, 1950, -4969 }, + { -308, 7401, 1549, -4866 }, + { -112, 8340, 3003, -4920 }, + { -50, 9315, 1371, -5666 }, + { -659, 9449, 2496, -5547 }, + { 2573, 9148, -2270, -4783 }, + { 830, 7104, -438, -3907 }, + { 522, 10672, -677, -6483 }, + { -1190, 10108, -510, -6518 }, + { -427, 8271, -579, -6315 }, + { 1602, 8113, -1927, -4418 }, + { -2266, 8180, 448, -5190 }, + { -1633, 8816, -226, -5771 }, + { 759, 9481, -105, -5813 }, + { 2254, 6679, -466, -5662 }, + { -88, 6946, 895, -5958 }, + { -1705, 10009, 1394, -5574 }, + { 748, 7943, 540, -6692 }, + { 1411, 7009, 232, -6145 }, + { 697, 7290, -1221, -5342 }, + { -1764, 10580, 1944, -3981 }, + { -1334, 9124, 1195, -3903 }, + { -905, 10067, 635, -5039 }, + { 664, 10680, 49, -4625 }, + { 1374, 9536, -777, -3591 }, + { 252, 9698, -597, -2931 }, + { 824, 9164, -1014, -2144 }, + { 2438, 10569, -2289, -4424 }, + { 2101, 7102, 507, -3614 }, + { 294, 8051, -432, -1518 }, + { -665, 10337, 547, -2852 }, + { 1168, 11989, -492, -5427 }, + { 1344, 6416, 302, -5061 }, + { -1727, 12264, 1507, -4543 }, + { 674, 10889, -902, -3605 }, + { -582, 9504, 300, -3618 }, + { 641, 7654, 689, -2109 }, + { 2065, 9243, 508, -4367 }, + { 1055, 8373, 688, -3144 }, + { -641, 8185, 986, -3307 }, + { 1120, 7426, 1785, -3757 }, + { 1660, 8070, -593, -3104 }, + { 2002, 9467, -1722, -3475 }, + { 2361, 8368, 100, -3709 }, + { -772, 7845, -613, -4988 }, + { 1485, 7430, 1896, -6127 }, + { -432, 7823, -947, -2882 }, + { 313, 11122, -760, -4871 }, + { 412, 8412, -283, -4231 }, + { 1585, 10402, -1884, -3267 }, + { 321, 6952, 773, -3016 }, + { -105, 9014, 121, -2249 }, + { 1585, 10313, -977, -4812 }, + { 1619, 11869, 1306, -6876 }, + { -1168, 8886, -81, -2500 }, + { -395, 10886, 733, -6490 }, + { -4949, 4274, 3992, -1054 }, + { -4241, 5299, 4262, -1584 }, + { -2710, 3862, 4552, -1673 }, + { -4608, 2472, 3672, -1715 }, + { -2843, 2816, 4003, -2326 }, + { -5229, 2964, 5636, 90 }, + { -4924, 3442, 5015, -1096 }, + { -1281, 3313, 5537, -2066 }, + { -3808, 1939, 4351, -919 }, + { -1915, 2585, 4939, -1614 }, + { -3470, 1843, 5562, -682 }, + { -3800, 870, 5827, 144 }, + { -4985, 1452, 4728, -709 }, + { -3745, 2750, 7220, 259 }, + { -1875, 1900, 6514, -826 }, + { -4329, 1574, 7192, 1304 }, + { -5408, 1444, 6208, 631 }, + { -3327, 5312, 5707, -1541 }, + { -6966, 3334, 4034, 1028 }, + { -7484, 4245, 4218, -212 }, + { -6567, 5839, 4539, -512 }, + { -5715, 5935, 3747, -1186 }, + { -6410, 4881, 3356, -1610 }, + { -5146, 2590, 2850, 2172 }, + { -5196, 4095, 2569, -373 }, + { -5043, 6025, 4318, 692 }, + { -5525, 4884, 3513, 370 }, + { -6804, 7533, 5812, -488 }, + { -5657, 2480, 4061, 1234 }, + { -3155, 1472, 6071, 1188 }, + { -3427, 5217, 3442, 858 }, + { -4698, 3013, 5517, 2586 }, + { -4449, 2226, 5418, 3580 }, + { -6395, 3547, 5487, 2028 }, + { -3500, 5019, 4787, 1 }, + { -4038, 2578, 3073, 3151 }, + { -2750, 1955, 4469, 3856 }, + { -5696, 1659, 6118, 2469 }, + { -4350, 1241, 6840, 3126 }, + { -5565, 5058, 5196, 1314 }, + { -1642, 4190, 3948, 607 }, + { -1233, 4108, 4850, -640 }, + { -997, 3428, 3239, 1378 }, + { -6488, 2741, 6926, 2792 }, + { -4188, 3763, 4235, 2018 }, + { -3210, 3224, 5646, 1427 }, + { -5526, 6909, 5070, -627 }, + { -2815, 3994, 3425, 1903 }, + { -2163, 2734, 5423, 145 }, + { -4149, 4247, 2355, 734 }, + { -410, 2521, 4138, -16 }, + { -2411, 2385, 4927, 2105 }, + { -6077, 3591, 3114, 594 }, + { -4186, 4834, 5926, -1004 }, + { -7315, 3369, 5966, 448 }, + { -7042, 5721, 5771, 238 }, + { -4466, 3907, 3535, -1751 }, + { -2116, 3970, 6163, -1392 }, + { -7239, 2143, 8407, 3630 }, + { -5431, 4486, 6486, -42 }, + { -1874, 1617, 6333, 519 }, + { -6478, 2629, 4634, -505 }, + { -7784, 2342, 7216, 1365 }, + { -1154, 1432, 4831, 1544 }, + { -4964, -5801, 1797, 506 }, + { -4436, -6905, 1059, -1237 }, + { -5400, -6886, 884, -290 }, + { -6259, -7103, 523, -227 }, + { -4819, -6450, 1412, -450 }, + { -4056, -6213, 1725, -943 }, + { -5642, -6091, 1357, 605 }, + { -4196, -5678, 2187, -173 }, + { -4726, -5126, 2470, 321 }, + { -6642, -5091, 1507, -1005 }, + { -5304, -5250, 1944, 1579 }, + { -7179, -5520, 1468, -425 }, + { -6033, -4895, 1876, -955 }, + { -6595, -5143, 2207, 1291 }, + { -4224, -4943, 1846, 1792 }, + { -7128, -6950, 539, 724 }, + { -4369, -4901, 2590, 1103 }, + { -7413, -5696, 1712, 1440 }, + { -5885, -6821, 418, 871 }, + { -6828, -5599, 710, -1563 }, + { -6123, -5817, 1358, 1631 }, + { -5291, -5622, 578, 2138 }, + { -7171, -6004, 347, 2208 }, + { -6083, -5251, 2132, 425 }, + { -4329, -5721, 407, -2993 }, + { -5326, -5056, 1119, -1837 }, + { -5485, -5856, 185, -2389 }, + { -6529, -5178, 403, -697 }, + { -6719, -4412, 2726, 871 }, + { -5126, -5629, 1835, -771 }, + { -5622, -4361, 2973, 858 }, + { -5282, -5895, 45, -335 }, + { -4357, -5656, 1696, -1558 }, + { -7139, -6659, 627, -409 }, + { -4415, -6328, 35, 1306 }, + { -7639, -6110, 1134, 197 }, + { -3626, -5592, 2019, 901 }, + { -3547, -5064, 1176, 1738 }, + { -5075, -3899, 2087, 266 }, + { -4086, -6311, 1479, 360 }, + { -6210, -5220, -199, -1477 }, + { -3910, -5063, 1356, -15 }, + { -7616, -4977, 461, 2401 }, + { -6118, -6131, 1258, -563 }, + { -6127, -4968, 1286, -27 }, + { -4121, -5852, 1113, 1476 }, + { -5157, -4881, 1162, -662 }, + { -4637, -5031, 1179, 709 }, + { -5509, -5452, -397, 1224 }, + { -4597, -6861, 646, 467 }, + { -6247, -4043, 468, 278 }, + { -5336, -6465, 874, -1472 }, + { -6998, -6346, 78, -1798 }, + { -4915, -4530, 2756, -203 }, + { -6048, -4373, 1468, 1052 }, + { -4273, -7100, 942, -323 }, + { -6552, -4287, 2351, 69 }, + { -6954, -4613, 722, 1521 }, + { -4201, -5361, 763, -1562 }, + { -6881, -5596, -748, 669 }, + { -6695, -3547, -34, 1299 }, + { -3981, -5728, 84, 111 }, + { -4663, -4809, 2173, -1031 }, + { -6599, -6077, 1303, 256 }, + { -7596, -4265, -5791, -4140 }, + { -6610, -2758, -5288, -3936 }, + { -5880, -3865, -6563, -3088 }, + { -7228, -5510, -7677, -3912 }, + { -8854, -6553, -8318, -5361 }, + { -9362, -5249, -6413, -4319 }, + { -4418, -3110, -6368, -4358 }, + { -5544, -4203, -6863, -5013 }, + { -3056, -4316, -5567, -3181 }, + { -3078, -5999, -5051, -2657 }, + { -5884, -6292, -5756, -4013 }, + { -4825, -4549, -5535, -4053 }, + { -4443, -6126, -5316, -1368 }, + { -3972, -6341, -6098, -2686 }, + { -5751, -2781, -5398, -6230 }, + { -4466, -6135, -5570, -3679 }, + { -4291, -5992, -3564, -5189 }, + { -7189, -4429, -7279, -6082 }, + { -5076, -4433, -2748, -5366 }, + { -6225, -2825, -6833, -5663 }, + { -2989, -4792, -3960, -4492 }, + { -7836, -7773, -7722, -5741 }, + { -6559, -5703, -5844, -5589 }, + { -7612, -5438, -4136, -3774 }, + { -4218, -4176, -6591, -2333 }, + { -4837, -5063, -6581, 322 }, + { -6590, -5990, -2980, -3847 }, + { -5558, -2971, -5489, -1932 }, + { -7001, -5323, -4975, -1697 }, + { -4694, -2688, -6904, -3044 }, + { -8511, -5379, -5767, -2549 }, + { -7548, -5412, -6522, -2572 }, + { -6597, -4973, -6423, -1274 }, + { -6415, -4022, -5168, -1072 }, + { -5528, -5530, -7218, -2345 }, + { -4845, -4805, -5943, -1227 }, + { -6049, -7150, -6744, -2161 }, + { -9061, -7299, -8542, -4375 }, + { -5010, -5546, -5416, -82 }, + { -4135, -4205, -5109, -3373 }, + { -3311, -5869, -4007, -5061 }, + { -5993, -6472, -3962, -4718 }, + { -2966, -5832, -2821, -6305 }, + { -4851, -5152, -2067, -3930 }, + { -3620, -4441, -3362, -5836 }, + { -4469, -5221, -4534, -5592 }, + { -4022, -6335, -4321, -6107 }, + { -4899, -4503, -3084, -3725 }, + { -4490, -8276, -4620, -6236 }, + { -6591, -4342, -7365, -4063 }, + { -6498, -5057, -5553, 485 }, + { -6060, -2714, -7093, -4144 }, + { -6199, -7774, -7094, -4057 }, + { -7536, -6424, -6415, -4265 }, + { -7439, -2454, -6348, -4827 }, + { -5333, -7565, -4417, -4639 }, + { -4353, -7103, -4197, -2689 }, + { -5229, -6549, -5129, -6804 }, + { -6129, -7701, -5236, -4836 }, + { -6797, -3983, -3884, -4406 }, + { -6624, -4467, -4745, -5052 }, + { -3324, -7596, -2720, -6553 }, + { -5473, -6284, -1704, -4511 }, + { -4131, -7263, -3180, -5196 }, + { -7116, -5565, -3469, 685 }, + { -6002, -6021, -3858, 576 }, + { -3144, -8203, -1291, -434 }, + { -6096, -7027, -4004, 1353 }, + { -3943, -7709, -2344, -36 }, + { -4510, -6767, -2642, 631 }, + { -3657, -11541, -2570, -3984 }, + { -5959, -8854, -1333, -867 }, + { -6699, -8866, -1606, -344 }, + { -3836, -7961, -2334, -2028 }, + { -3430, -8045, -3037, -672 }, + { -3868, -9184, -3635, -1819 }, + { -4258, -9060, -2621, -1008 }, + { -3595, -8693, -2022, -752 }, + { -4573, -8048, -3166, -2622 }, + { -4852, -7903, -1405, 256 }, + { -4591, -7057, -1560, 965 }, + { -6963, -7655, -980, 808 }, + { -5179, -6641, -3356, 1196 }, + { -7102, -6941, -2798, 2123 }, + { -6867, -5834, -3320, -770 }, + { -5977, -7369, -2500, -778 }, + { -6160, -6400, -934, -2543 }, + { -6741, -7608, -355, -1289 }, + { -6856, -6466, -1433, -1643 }, + { -4786, -6292, -4970, 376 }, + { -5407, -8866, -2255, -400 }, + { -3814, -6506, -1387, -3620 }, + { -4998, -6137, -1200, -4092 }, + { -5123, -9557, -2849, -1306 }, + { -4259, -6444, -4395, -338 }, + { -5221, -6810, -883, 1225 }, + { -6137, -6215, -2165, 554 }, + { -3895, -6557, -3176, -1829 }, + { -3886, -8188, -87, -954 }, + { -7243, -6707, -2216, -316 }, + { -5592, -7606, 85, -432 }, + { -3957, -7945, -504, -144 }, + { -4617, -7624, 218, -312 }, + { -4797, -8737, -844, -1051 }, + { -4478, -8516, -1401, -454 }, + { -4557, -7058, -302, -2332 }, + { -6623, -7736, -271, -50 }, + { -3157, -7532, -1111, -2207 }, + { -3590, -7300, -1271, 517 }, + { -4442, -7306, -507, 590 }, + { -6458, -7524, -2807, 666 }, + { -4991, -8466, -3363, -785 }, + { -7474, -7541, -1056, -1839 }, + { -7501, -8316, -938, -180 }, + { -5329, -7739, -579, -2341 }, + { -4549, -7063, -176, -3539 }, + { -5191, -8612, -1504, -4250 }, + { -3083, -7058, -2251, 32 }, + { -4003, -7043, -1093, -791 }, + { -5523, -8093, -678, -114 }, + { -3022, -10265, -2070, -3109 }, + { -3905, -6274, -182, -3652 }, + { -3269, -9217, -551, -2650 }, + { -3138, -9314, -1726, -1704 }, + { -4420, -10339, -1744, -3459 }, + { -4163, -8609, -2298, -4113 }, + { -5566, -6505, -1241, -463 }, + { -3130, -9746, -2352, -4884 }, + { -7825, -3439, 1451, -1468 }, + { -8451, -3318, 2360, -435 }, + { -8462, -4130, 1438, -1024 }, + { -9425, -4564, 1328, -689 }, + { -11014, -3202, 2278, 2080 }, + { -8269, -2761, -146, -440 }, + { -7497, -2618, -166, 413 }, + { -8250, -3060, 522, -2133 }, + { -8365, -5366, 1347, -451 }, + { -8589, -3979, 2943, 714 }, + { -8111, -2572, 1272, -1748 }, + { -7830, -5193, 605, -1484 }, + { -8119, -4736, 2141, 256 }, + { -7724, -4769, 1463, -812 }, + { -7363, -3911, 2540, 4 }, + { -7974, -3397, 2363, 1366 }, + { -7359, -4204, 1752, -958 }, + { -7622, -3505, 660, 916 }, + { -9934, -3665, 3165, 828 }, + { -8721, -4162, 62, 1718 }, + { -9433, -4768, 2722, 1234 }, + { -7960, -4496, 138, 1528 }, + { -8198, -3454, -443, 631 }, + { -7756, -2246, 655, 1137 }, + { -8841, -3145, 1113, 829 }, + { -7817, -3298, 1251, 230 }, + { -9413, -2733, 323, -1862 }, + { -9408, -4168, 1270, 1549 }, + { -9037, -3892, -942, 283 }, + { -8255, -3849, 1301, 1762 }, + { -9057, -3987, -41, -682 }, + { -9441, -4187, 2019, -111 }, + { -9740, -3178, 1602, -871 }, + { -8344, -2474, 1461, 1506 }, + { -9752, -2925, 1996, 1243 }, + { -9199, -3796, 180, 537 }, + { -9060, -2405, 1140, -1562 }, + { -9348, -2376, 309, -162 }, + { -10786, -3182, -5, -1500 }, + { -8142, -4540, -434, -826 }, + { -7528, -2341, 1104, -73 }, + { -9360, -2658, 3062, 56 }, + { -8267, -2335, 2000, -1193 }, + { -12169, -3154, 1287, -640 }, + { -11398, -2120, 946, -1163 }, + { -8940, -4559, 328, -1696 }, + { -11025, -4213, 2813, 840 }, + { -9224, -3581, 2224, 2039 }, + { -8943, -3337, 1248, -1298 }, + { -7900, -4042, 485, -2080 }, + { -9221, -1947, 2191, -880 }, + { -10762, -1800, 2516, -324 }, + { -10095, -2238, 981, -1335 }, + { -11908, -2808, 3255, 645 }, + { -10640, -4105, 1283, -595 }, + { -7663, -2863, 2467, -797 }, + { -10712, -3854, 3710, 1538 }, + { -10823, -2893, 1408, -801 }, + { -9874, -3832, 256, -1638 }, + { -10394, -3391, 2315, -94 }, + { -11525, -4079, 4153, 2122 }, + { -9546, -2088, 1541, 481 }, + { -8731, -2433, 1042, 2160 }, + { -7852, -3977, -1370, 1677 }, + { 7072, -3420, 1398, -1741 }, + { 6180, -1976, 1280, -3557 }, + { 7692, -1793, 2844, -1700 }, + { 8363, -1773, 3104, -2679 }, + { 9213, -3266, 3756, -3542 }, + { 9650, -2644, 1426, -1318 }, + { 7712, -2796, 3686, -1975 }, + { 7316, -3517, 2821, -622 }, + { 7434, -2594, 2305, -2264 }, + { 7237, -1797, 255, -3114 }, + { 8663, -1983, 1338, -3056 }, + { 6616, -952, 4059, -2652 }, + { 8823, -1327, 1362, -1356 }, + { 9938, -1722, 1287, -2362 }, + { 7207, -1057, 1913, -1315 }, + { 7508, -1585, 870, -1982 }, + { 8217, -3680, 1417, -3170 }, + { 8329, -2541, 1684, -585 }, + { 8062, -2335, 252, -2800 }, + { 8204, -4108, 3097, -2569 }, + { 7701, -3367, 576, -3008 }, + { 7350, -786, 2414, -2129 }, + { 6948, -2568, 1607, -225 }, + { 7684, -2387, 1308, -3449 }, + { 8306, -3458, 2394, -1454 }, + { 8438, -2781, 1043, -1362 }, + { 9175, -2076, 2144, -1987 }, + { 8347, -2709, 3489, -4301 }, + { 5696, -2377, 2870, 851 }, + { 8825, -1243, 2219, -2603 }, + { 8801, -1614, 584, -2513 }, + { 8413, -384, 1421, -2244 }, + { 9228, -3050, 3279, -2164 }, + { 6342, -2698, 3547, -107 }, + { 10053, -2476, 2837, -3168 }, + { 7439, -604, 3177, -3991 }, + { 7749, -1064, 4329, -4855 }, + { 8655, -2177, 2252, -3519 }, + { 8490, -228, 1958, -3233 }, + { 10513, -2968, 1911, -2340 }, + { 8146, -862, 1884, -1723 }, + { 7788, -666, 3004, -2891 }, + { 7785, -1620, 4133, -3417 }, + { 10262, -3731, 3455, -2971 }, + { 8570, -905, 4519, -4649 }, + { 9129, -2562, 463, -2465 }, + { 9451, -3587, 1904, -3056 }, + { 6549, -2236, 3010, -4523 }, + { 7175, -2684, 2967, -3458 }, + { 9872, -3278, 1054, -2472 }, + { 9153, -931, 1217, -2565 }, + { 8789, -3469, 753, -2568 }, + { 6683, -3791, 1797, -3968 }, + { 6801, -1977, 2311, -452 }, + { 6336, -1572, 2612, -3264 }, + { 7996, -1008, 730, -2964 }, + { 7521, -1059, 1573, -3694 }, + { 8148, -3973, 2600, -3572 }, + { 7765, -1532, 2528, -3856 }, + { 7404, -3918, 4472, -143 }, + { 8894, -1398, 3299, -3685 }, + { 5768, -2041, 1487, -637 }, + { 5131, -2865, 2463, -811 }, + { 6439, -1568, 3500, -1550 }, + { -8878, -6798, -5319, -1452 }, + { -6332, -9713, -3112, -990 }, + { -8444, -6316, -3694, -687 }, + { -6123, -10840, -3637, -4358 }, + { -4784, -9580, -4577, -2581 }, + { -6108, -10515, -4859, -2524 }, + { -7605, -7518, -2327, -2797 }, + { -9662, -8775, -2467, -2010 }, + { -6494, -7523, -4715, -118 }, + { -8290, -8982, -1672, -317 }, + { -8798, -11051, -3888, -1426 }, + { -6273, -6623, -6791, -142 }, + { -8313, -7668, -2141, -1275 }, + { -6453, -8412, -3589, -4102 }, + { -6747, -7750, -5690, -2498 }, + { -7814, -6693, -3174, -2446 }, + { -10383, -10130, -3931, -2364 }, + { -10606, -8467, -5539, -2772 }, + { -9475, -6671, -3305, -2271 }, + { -8982, -9457, -5635, -4005 }, + { -10111, -7965, -6515, -4180 }, + { -7301, -6479, -5364, 720 }, + { -9543, -8999, -7921, -912 }, + { -9534, -8562, -3469, -384 }, + { -7601, -10344, -3205, -1127 }, + { -8088, -8620, -4954, -2888 }, + { -8202, -8406, -7038, -3775 }, + { -7312, -8324, -3334, -1775 }, + { -8566, -9262, -8071, -4174 }, + { -7068, -11300, -5573, -2907 }, + { -8295, -8952, -4366, -1544 }, + { -11104, -10210, -2285, -384 }, + { -5213, -7520, -5008, -1339 }, + { -5889, -7940, -5987, -1385 }, + { -10816, -8201, -4153, -1485 }, + { -10277, -8919, -6315, -1652 }, + { -5888, -10320, -3821, -1733 }, + { -10497, -7181, -6083, -3032 }, + { -7721, -9724, -6591, -5336 }, + { -5688, -7894, -3486, -2552 }, + { -10014, -10500, -3247, -820 }, + { -6301, -8765, -4506, -2923 }, + { -8261, -7847, -6213, -1552 }, + { -10212, -7481, -8113, -3954 }, + { -6938, -10874, -6074, -4703 }, + { -7183, -10968, -4446, -1773 }, + { -7120, -9193, -1966, -2509 }, + { -6234, -9263, -2313, -4284 }, + { -8503, -9857, -2429, -608 }, + { -9372, -7844, -8391, -2120 }, + { -7951, -7157, -6535, -11 }, + { -7256, -9473, -2172, -660 }, + { -10063, -9612, -2515, -15 }, + { -6684, -9134, -6109, -4206 }, + { -8204, -11932, -5220, -2306 }, + { -9710, -6706, -4115, -3275 }, + { -6855, -7078, -2409, -4447 }, + { -7344, -7673, -4479, -4116 }, + { -8851, -6842, -4927, -2948 }, + { -8927, -10452, -5633, -2194 }, + { -8627, -9002, -7176, -1575 }, + { -8209, -9722, -7021, -3324 }, + { -3770, -10249, -3623, -4816 }, + { -8183, -7465, -4090, 646 }, + { -8163, -7149, 200, 498 }, + { -8289, -6266, 686, -206 }, + { -10030, -6241, -1032, -1864 }, + { -8793, -8327, -773, -169 }, + { -9149, -6215, 969, -15 }, + { -8303, -5859, -7, 2006 }, + { -9682, -7283, 255, 1322 }, + { -9293, -7227, 71, -231 }, + { -8525, -6215, 287, -837 }, + { -10477, -5379, 1159, 1449 }, + { -10726, -7856, -130, 102 }, + { -8694, -7461, -1210, 690 }, + { -9367, -5324, 1103, 3170 }, + { -10686, -8055, -831, 1633 }, + { -9201, -6873, -2704, 2258 }, + { -8421, -5358, -1405, 226 }, + { -9066, -5830, -307, -1571 }, + { -11150, -7381, -2746, -900 }, + { -9978, -5925, -2006, -437 }, + { -9464, -4741, -273, 1061 }, + { -10543, -6684, -1113, 1660 }, + { -10073, -5576, 1083, -269 }, + { -8826, -5763, 1600, 1486 }, + { -10445, -9071, -1253, -64 }, + { -12085, -5799, 2, 769 }, + { -12939, -6663, 1650, 1437 }, + { -10932, -6434, -1252, -649 }, + { -11650, -7826, -2053, 710 }, + { -12122, -6733, -1889, -731 }, + { -9093, -6095, -2463, -842 }, + { -10977, -4364, 469, 420 }, + { -11488, -6908, -521, 893 }, + { -9669, -5478, -842, 337 }, + { -10606, -5203, -632, -1361 }, + { -10198, -6284, 1662, 1277 }, + { -10135, -5292, 2435, 3493 }, + { -11027, -6561, 655, 56 }, + { -10977, -5030, 1127, -358 }, + { -12766, -3986, 1348, -335 }, + { -14244, -7731, 264, 317 }, + { -15124, -10309, -508, 1447 }, + { -12821, -8638, -608, 137 }, + { -13076, -8693, -2852, -431 }, + { -11156, -5546, -2252, -1600 }, + { -8692, -7366, -819, -1223 }, + { -12507, -9816, -1714, -121 }, + { -10712, -6666, 544, 3349 }, + { -12462, -5890, -2491, -2318 }, + { -12468, -7226, 437, 232 }, + { -11300, -5226, 2068, 687 }, + { -11994, -8320, -626, 2728 }, + { -12222, -5476, 1142, 18 }, + { -10277, -8122, -2418, 2003 }, + { -13418, -6115, -3563, -2802 }, + { -14759, -9834, -1243, 21 }, + { -13699, -5665, 1525, 507 }, + { -16269, -9476, -701, 163 }, + { -12677, -5437, -247, -1019 }, + { -11827, -4295, -181, -1243 }, + { -12847, -4496, 2984, 1123 }, + { -13860, -7915, -1166, -547 }, + { -12276, -8145, -2290, -1527 }, + { -11417, -4830, 2983, 1854 }, + { -11793, -6002, 1163, 1940 }, + { 11443, -4920, -3235, 3151 }, + { 11300, -6616, -1506, 1175 }, + { 9198, -4628, -2060, 2390 }, + { 10532, -4027, -643, 912 }, + { 9902, -3573, -1606, 1327 }, + { 9653, -3536, -2240, 1869 }, + { 9948, -5171, -423, 2662 }, + { 12316, -4004, -1989, 281 }, + { 12125, -4800, -1265, -163 }, + { 10650, -2617, -2337, 1462 }, + { 9909, -4968, -2376, 916 }, + { 12944, -4647, -1958, 460 }, + { 12988, -5283, -1141, 41 }, + { 12321, -2915, -3621, 1025 }, + { 11449, -2894, -2728, 351 }, + { 12087, -3041, -2002, -32 }, + { 11558, -4031, -1343, -399 }, + { 12983, -3740, -3516, 1245 }, + { 12099, -2515, -2752, 225 }, + { 12515, -3465, -2701, 550 }, + { 14683, -5022, -5272, 2996 }, + { 12260, -3383, -1215, -528 }, + { 13810, -5422, -2443, 1166 }, + { 13421, -5378, -1886, 721 }, + { 12961, -4259, -2594, 796 }, + { 12266, -2104, -4768, 1591 }, + { 13523, -4710, -3045, 1342 }, + { 12437, -2099, -5610, 2117 }, + { 11850, -2183, -3497, 661 }, + { 12275, -3936, -597, -697 }, + { 12459, -5253, -517, -544 }, + { 12835, -4094, -1322, -168 }, + { 14360, -5677, -3305, 1859 }, + { 13905, -4552, -4309, 2117 }, + { 11559, -3412, -1847, -81 }, + { 13379, -3167, -5764, 2746 }, + { 11910, -1634, -4342, 1052 }, + { 12662, -4742, 71, -974 }, + { 13057, -3254, -4424, 1705 }, + { 15046, -5706, -4851, 3019 }, + { 14162, -4142, -5514, 2843 }, + { 12764, -1845, -6684, 2888 }, + { 13714, -2374, -7838, 3857 }, + { 13295, -1663, -8293, 4073 }, + { 10032, -4152, -3403, 1421 }, + { 10942, -5386, -2222, 950 }, + { 10532, -6385, -1750, 1925 }, + { 10273, -5972, -1534, 643 }, + { 10605, -4782, -1695, 27 }, + { 10988, -5153, -1123, -341 }, + { 11629, -5884, -1060, 48 }, + { 10441, -4045, -2431, 311 }, + { 10788, -3595, -4171, 1807 }, + { 12110, -5686, -2127, 976 }, + { 11746, -4773, -2639, 891 }, + { 11541, -5299, -3031, 1732 }, + { 11416, -2559, -5359, 2198 }, + { 11583, -5376, -704, 677 }, + { 10416, -3214, -3516, 872 }, + { 9651, -5435, -1618, 3255 }, + { 9973, -5133, -996, 3923 }, + { 11707, -4643, -430, -796 }, + { 10994, -2709, -3587, 2302 }, + { 10716, -5118, -645, 270 }, + { 14100, -10314, 1095, 1531 }, + { 12944, -8049, 1105, -741 }, + { 13276, -7035, -511, 274 }, + { 14008, -7254, -283, 139 }, + { 11594, -6536, -91, 1671 }, + { 11732, -8645, 746, 15 }, + { 14613, -7085, -1578, 1183 }, + { 13083, -6224, -750, -4 }, + { 13988, -6256, -1592, 820 }, + { 14678, -8683, 441, 126 }, + { 15571, -8872, -521, 1139 }, + { 15642, -9533, 341, 697 }, + { 15960, -9586, -168, 1121 }, + { 15464, -10239, 1433, -1 }, + { 14934, -7887, -1046, 1080 }, + { 15252, -7630, -1899, 1628 }, + { 15485, -8384, -1234, 1484 }, + { 15962, -8638, -1815, 1931 }, + { 16501, -10664, 398, 1167 }, + { 16146, -10145, 411, 918 }, + { 14573, -7475, -697, 601 }, + { 14302, -7996, 28, 257 }, + { 14769, -6792, -2286, 1574 }, + { 14144, -6137, -2169, 1257 }, + { 14770, -6271, -3111, 1933 }, + { 14110, -8312, 1083, -531 }, + { 15235, -6991, -2993, 2174 }, + { 13222, -5805, 547, -891 }, + { 14796, -8762, 1254, -246 }, + { 16040, -9181, -1005, 1551 }, + { 16487, -10086, -373, 1420 }, + { 15077, -9479, 966, 51 }, + { 13026, -6468, 932, -1080 }, + { 12703, -6152, -33, -573 }, + { 15641, -6810, -4128, 2874 }, + { 13282, -7673, 1583, -1283 }, + { 12373, -7150, 1512, -917 }, + { 12992, -7751, -678, 783 }, + { 10907, -6858, -313, 2597 }, + { 13026, -8963, 125, 2152 }, + { 12770, -9946, 1957, -505 }, + { 12482, -6849, -1268, 833 }, + { 13790, -6181, -138, -279 }, + { 12709, -8382, 2044, 227 }, + { 12244, -6630, 203, -457 }, + { 14209, -6816, -1032, 632 }, + { 15134, -8267, -288, 640 }, + { 13619, -6157, -1090, 356 }, + { 14044, -7413, 725, -484 }, + { 12958, -7753, 2585, -1980 }, + { 13188, -8396, 2306, -1558 }, + { 14379, -9980, 2132, -688 }, + { 14275, -9857, 1162, 179 }, + { 13690, -8648, 1621, -889 }, + { 11770, -6829, -746, 278 }, + { 12732, -8202, 286, 90 }, + { 13630, -10146, 1867, -207 }, + { 12072, -8740, 1299, -645 }, + { 12852, -9492, 1226, 62 }, + { 11792, -7382, -54, -116 }, + { 13779, -9014, 487, 351 }, + { 11951, -7729, 121, 834 }, + { 11970, -9781, 2276, -4 }, + { 12680, -7984, 2787, -787 }, + { 13300, -14488, 6408, -1927 }, + { 13635, -15355, 9153, -3073 }, + { 12804, -13566, 5517, -1625 }, + { 16624, -10854, 1690, 28 }, + { 20387, -18532, 6162, -261 }, + { 16515, -12642, 3392, -519 }, + { 15800, -11095, 2151, -202 }, + { 16824, -11790, 1651, 599 }, + { 17604, -13213, 2563, 538 }, + { 17892, -14177, 3562, 147 }, + { 16987, -11399, 869, 1052 }, + { 17003, -12456, 2442, 265 }, + { 21657, -21806, 9198, -1250 }, + { 16825, -13341, 3980, -686 }, + { 17525, -12714, 1887, 805 }, + { 16419, -11034, 1216, 617 }, + { 20931, -19939, 7469, -684 }, + { 18452, -15390, 4573, -191 }, + { 14778, -10077, 2841, -1209 }, + { 17402, -13319, 3042, 160 }, + { 19365, -17922, 7087, -1061 }, + { 16298, -11941, 2810, -351 }, + { 19087, -16176, 4775, -84 }, + { 17666, -12289, 938, 1224 }, + { 18581, -15894, 5132, -430 }, + { 19823, -16717, 4142, 545 }, + { 19960, -19423, 8400, -1492 }, + { 18973, -16817, 5906, -594 }, + { 19079, -15431, 3528, 503 }, + { 16667, -12485, 4467, -1302 }, + { 19791, -17797, 6196, -529 }, + { 20005, -17606, 5354, -20 }, + { 20123, -18599, 6886, -728 }, + { 19068, -14805, 2394, 1105 }, + { 14443, -13723, 5631, -2029 }, + { 14730, -14231, 5631, -1450 }, + { 16089, -15959, 7271, -2029 }, + { 13473, -11200, 3236, -924 }, + { 14413, -10902, 2347, -267 }, + { 17666, -18662, 11381, -3496 }, + { 14749, -11042, 3305, -275 }, + { 15304, -10486, 1869, -240 }, + { 14809, -12126, 3369, -616 }, + { 16896, -16561, 7307, -1845 }, + { 15782, -14336, 5380, -1264 }, + { 16395, -15520, 6415, -1588 }, + { 13681, -11114, 2584, -320 }, + { 14244, -12326, 4480, -1632 }, + { 15247, -13119, 4265, -898 }, + { 13987, -12091, 3469, -597 }, + { 13941, -12770, 4240, -839 }, + { 13771, -13627, 5252, -1384 }, + { 15010, -16074, 7592, -2249 }, + { 15852, -17226, 8619, -2655 }, + { 18921, -16916, 6875, -1501 }, + { 14909, -11678, 2768, -295 }, + { 18988, -18353, 8424, -2070 }, + { 15457, -15080, 6218, -1513 }, + { 14916, -15512, 6949, -1883 }, + { 18108, -14702, 4681, -701 }, + { 17600, -15733, 5616, -775 }, + { 14070, -13683, 6472, -2626 }, + { 13832, -11914, 5201, -2232 }, + { 18846, -19009, 9192, -1961 }, + { -11981, -10994, -6324, -2264 }, + { -10976, -9047, -6546, -3828 }, + { -11288, -10532, -7014, -4191 }, + { -10139, -10189, -7799, -2688 }, + { -10555, -9988, -9181, -2040 }, + { -11596, -11339, -10022, -2707 }, + { -13400, -13395, -11306, -4206 }, + { -9774, -12281, -7466, -4133 }, + { -10842, -13125, -8777, -4956 }, + { -11964, -15082, -9779, -5095 }, + { -9382, -10188, -9053, -4927 }, + { -11562, -11296, -3651, -985 }, + { -9287, -10083, -7918, -4069 }, + { -12821, -16556, -11410, -6195 }, + { -12628, -8959, -4521, -1113 }, + { -13845, -11581, -3649, -681 }, + { -12685, -10269, -5483, -1275 }, + { -14988, -12874, -5107, -1189 }, + { -13761, -11367, -6202, -1804 }, + { -13225, -11249, -7820, -3354 }, + { -14809, -11992, -3202, -312 }, + { -15620, -15519, -10210, -3433 }, + { -12954, -10200, -3139, -611 }, + { -11536, -9981, -5284, -923 }, + { -13034, -12417, -4612, -1098 }, + { -16911, -15505, -6123, -1352 }, + { -17396, -17685, -8330, -2171 }, + { -14120, -10764, -2265, -99 }, + { -12598, -7367, -5406, -3530 }, + { -14143, -12793, -10909, -5226 }, + { -14692, -16871, -11626, -5554 }, + { -12581, -11197, -9194, -3837 }, + { -16752, -16726, -9746, -2808 }, + { -10600, -10358, -6560, -1227 }, + { -14573, -13312, -8957, -3393 }, + { -10172, -8463, -8579, -3387 }, + { -11418, -12421, -5522, -1842 }, + { -11855, -14204, -6669, -2625 }, + { -13308, -8191, -3941, -2194 }, + { -10007, -12266, -5022, -1811 }, + { -13532, -15771, -9497, -3175 }, + { -11760, -11148, -10339, -5529 }, + { -12149, -12763, -11198, -3697 }, + { -12029, -12119, -8555, -1792 }, + { -16995, -19957, -11447, -3471 }, + { -13144, -14504, -9988, -3191 }, + { -9938, -11064, -6139, -3162 }, + { -8873, -11550, -8294, -6550 }, + { -9303, -13010, -6150, -2711 }, + { -15463, -10469, -1766, -170 }, + { -15985, -11693, -3007, -650 }, + { -17142, -10671, -1434, 47 }, + { -16063, -13858, -4817, -1058 }, + { -19446, -19599, -9594, -2464 }, + { -20076, -18744, -8313, -1889 }, + { -15047, -16085, -7590, -2250 }, + { -13481, -16195, -8552, -2998 }, + { -13829, -14869, -6704, -1932 }, + { -16357, -18484, -9802, -2959 }, + { -10551, -8393, -9303, -5070 }, + { -11345, -9156, -5641, -3107 }, + { -13217, -13449, -9270, -4541 }, + { -11988, -13732, -9995, -6374 }, + { -11007, -9519, -5168, -4107 }, + { 9930, -7858, 8061, -4375 }, + { 8274, -7867, 5992, -2096 }, + { 9692, -9675, 7621, -3670 }, + { 9589, -8110, 6509, -3010 }, + { 12617, -11976, 10122, -5360 }, + { 11867, -8895, 7948, -5323 }, + { 10388, -10482, 9234, -4324 }, + { 8188, -8220, 7810, -2737 }, + { 10407, -8787, 4806, -1930 }, + { 10348, -8845, 9233, -6614 }, + { 9422, -7091, 4820, -2878 }, + { 9758, -9796, 5584, -2256 }, + { 10188, -7994, 5347, -3343 }, + { 11133, -7455, 4015, -2306 }, + { 10676, -10744, 6093, -2629 }, + { 11522, -12184, 7848, -3375 }, + { 8805, -9883, 5317, -3071 }, + { 9498, -9654, 6555, -3592 }, + { 10488, -8008, 4066, -1252 }, + { 11261, -8930, 6068, -2738 }, + { 12180, -10397, 5027, -1531 }, + { 9138, -8531, 3601, -1959 }, + { 8107, -8380, 4970, -2061 }, + { 9737, -13248, 6438, -2617 }, + { 11178, -10423, 2622, -522 }, + { 9572, -12372, 5199, -2019 }, + { 12057, -12144, 4147, -1099 }, + { 9047, -9925, 2516, -665 }, + { 10790, -8030, 5882, -4386 }, + { 7199, -8426, 6337, -2841 }, + { 7778, -8285, 3529, -3442 }, + { 7559, -10569, 3484, -1332 }, + { 9404, -8115, 7484, -5541 }, + { 7792, -11976, 5546, -2573 }, + { 9313, -10264, 7661, -5195 }, + { 6701, -10725, 4370, -1784 }, + { 4918, -11361, 4507, -4527 }, + { 5147, -12305, 3978, -5556 }, + { 6525, -9899, 4481, -3129 }, + { 7538, -12855, 6060, -4826 }, + { 8659, -12111, 7159, -4430 }, + { 8440, -11304, 4547, -1747 }, + { 9216, -10918, 3507, -1195 }, + { 6165, -9254, 4771, -4677 }, + { 9163, -11019, 5637, -4935 }, + { 13441, -11509, 6676, -2434 }, + { 7912, -9398, 6663, -4048 }, + { 11723, -13745, 8131, -4148 }, + { 6065, -10257, 5005, -6327 }, + { 11618, -12417, 5336, -1894 }, + { 8891, -13924, 8407, -6131 }, + { 9622, -12563, 7908, -5109 }, + { 11479, -10315, 8349, -3991 }, + { 11676, -14103, 6611, -2330 }, + { 11951, -8953, 3829, -1550 }, + { 10486, -8044, 10493, -5920 }, + { 11801, -10769, 9763, -5305 }, + { 6109, -8676, 5827, -1346 }, + { 7030, -9611, 5624, -5761 }, + { 12808, -12886, 8683, -4148 }, + { 13213, -10464, 6381, -3189 }, + { 11796, -13681, 10703, -6075 }, + { 9639, -7949, 9625, -3944 }, + { 8538, -6997, 5309, 453 } +}; + +/* quantization tables */ + +static const uint32_t scale_factor_quant6[64] = { + 1, 2, 2, 3, 3, 4, 6, 7, + 10, 12, 16, 20, 26, 34, 44, 56, + 72, 93, 120, 155, 200, 257, 331, 427, + 550, 708, 912, 1175, 1514, 1950, 2512, 3236, + 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547, + 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209, + 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538, + 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0 +}; + +static const uint32_t scale_factor_quant7[128] = { + 1, 1, 2, 2, 2, 2, 3, 3, + 3, 4, 4, 5, 6, 7, 7, 8, + 10, 11, 12, 14, 16, 18, 20, 23, + 26, 30, 34, 38, 44, 50, 56, 64, + 72, 82, 93, 106, 120, 136, 155, 176, + 200, 226, 257, 292, 331, 376, 427, 484, + 550, 624, 708, 804, 912, 1035, 1175, 1334, + 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673, + 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116, + 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861, + 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736, + 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349, + 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103, + 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245, + 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704, + 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0 +}; + +/* 20bits unsigned fractional binary codes */ +static const uint32_t lossy_quant[32] = { + 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063, + 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777, + 10486, 5872, 3355, 1887, 1258, 713, 336, 168, + 84, 42, 21, 0, 0, 0, 0, 0 +}; + +static const float lossy_quant_d[32] = { + 0, 1.6, 1.0, 0.8, 0.59, 0.50, 0.42, 0.34, + 0.19, 0.11, 0.06, 0.035, 0.019, 0.011, 0.0065, 0.0040, + 0.0025, 0.0014, 0.0008, 0.00045, 0.00030, 0.00017, 0.00008, 0.00004, + 0.00002, 0.00001, 0.000005, 0, 0, 0, 0, 0 +}; + +/* 20bits unsigned fractional binary codes */ +static const uint32_t lossless_quant[32] = { + 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127, + 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049, + 1024, 512, 256, 128, 64, 32, 16, 8, + 4, 2, 1, 0, 0, 0, 0, 0 +}; + +static const float lossless_quant_d[32] = { + 0, 1.0, 0.5, 0.33, 0.25, 0.166, 0.125, + 0.083, 0.0625, 0.03125, 0.0156, 7.874E-3, 3.922E-3, 1.957E-3, + 9.775E-4, 4.885E-4, 2.442E-4, 1.221E-4, 6.104E-5, 3.052E-5, 1.526E-5, + 7.629E-6, 3.815E-6, 1.907E-6, 9.537E-7, 4.768E-7, 2.384E-7, 0, + 0, 0, 0, 0 +}; + + +/* Vector quantization tables */ + +static const int8_t high_freq_vq[1024][32] = +{ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { -4, -2, 2, 1, -16, -10, 1, 3, 1, 0, 6, 1, -3, 7, 1, -22, + 2, -4, -3, 11, 14, 6, -1, 1, -13, 29, -28, 10, 10, -8, 0, -9 }, + { -8, 8, -7, 10, -3, -12, -5, -8, 1, -2, 9, -2, -5, -18, 1, 9, + -8, -8, 3, 41, 7, -9, -9, 22, -42, -29, 14, -18, -14, -32, 1, -15 }, + { -16, 8, 15, 16, -16, 5, 2, 7, -6, -16, -7, 1, 1, -3, -2, 0, + 8, 20, -26, -11, 2, -17, 0, -3, -34, -37, 10, 44, -2, 22, 2, -4 }, + { 7, 14, 5, 6, 15, -1, 3, -3, -9, -23, -5, -14, 8, -1, -14, -6, + -5, -8, 54, 31, -6, 18, 2, -19, -2, -11, -30, -6, -19, 2, -2, -14 }, + { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1, + 3, 7, -5, -4, -3, -12, 3, -2, -3, 12, -53, -51, 6, -1, 6, 8 }, + { 0, -1, 5, 1, -6, -8, 7, 5, -18, -4, -1, 1, 0, -3, -3, -14, + -1, -6, 0, -14, -1, -1, 5, -3, -11, 1, -20, 10, 2, 19, -2, -2 }, + { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3, + -7, 0, -34, 4, -43, 17, 0, -53, -13, -7, 24, 14, 5, -18, 9, -20 }, + { 1, 0, -3, 2, 3, -5, -2, 7, -21, 5, -25, 23, 11, -28, 2, 1, + -11, 9, 13, -6, -12, 5, 7, 2, 4, -11, -6, -1, 8, 0, 1, -2 }, + { 2, -4, -6, -4, 0, -5, -29, 13, -6, -22, -3, -43, 12, -41, 5, 24, + 18, -9, -36, -6, 4, -7, -4, 13, 4, -15, -1, -5, 1, 2, -5, 4 }, + { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19, -22, 31, -27, 4, -15, + -6, 15, 9, -13, 1, -9, 10, -17, 4, -1, -1, 4, 2, 0, -3, -5 }, + { -7, 3, -8, 13, 19, -12, 8, -19, -3, -2, -24, 31, 14, 0, 7, -13, + -18, 0, 3, 6, 13, -2, 1, -12, -21, 9, -2, 30, 21, -14, 2, -14 }, + { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1, -10, 30, 4, + -10, 12, 5, 6, -13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 }, + { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4, -16, -13, 3, 23, -27, + 18, 46, -38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 }, + { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4, -11, 40, -7, + -3, -13, -14, -7, -10, 14, 7, 5, -14, 11, -5, 7, 21, -2, 9, -3 }, + { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2, + -1, 1, -3, -1, -15, -2, -63, -27, -21, -47, -14, 1, -14, 10, 0, 2 }, + { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7, -15, 6, + -7, -6, 3, 7, -15, -5, 23, -13, -6, 12, -8, 9, 2, -3, 3, 4 }, + { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4, -22, -15, + -46, -66, 10, 20, 2, -17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 }, + { -1, 0, 0, 1, 0, -4, 0, 1, -10, -3, -8, 5, 7, -11, 2, -11, + 29, -25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 }, + { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1, + -14, -7, 3, -30, -15, -14, 3, -4, -1, 3, -13, -1, -3, 1, 2, 3 }, + { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10, + -57, 3, 22, -50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 }, + { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4, + 24, -35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 }, + { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0, + 0, -1, -2, -1, -5, -2, -43, -3, 46, -52, -10, 7, -8, 11, -2, -1 }, + { 0, 0, -1, 0, -1, 2, -41, 33, -44, -48, -15, -26, -9, 6, 3, 3, + -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 }, + { -4, 1, 6, 1, -6, -1, -2, 1, -14, -4, 0, -5, -2, 2, -2, 0, + -6, 1, 0, 8, -21, 32, -3, -36, -6, -2, -1, -7, 3, 0, 1, -6 }, + { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3, + 13, 0, -12, -1, 25, -20, -2, -23, -15, 7, -3, -11, -3, 6, -1, 0 }, + { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3, + -2, 3, 3, -7, -6, -5, 0, -4, -60, -16, -6, 38, 5, 6, -5, 0 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1, + 0, 0, -1, 0, -8, 2, -9, 10, 40, 31, -56, -21, 4, 20, -4, 7 }, + { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5, + 1, -2, 14, 5, 4, 5, 5, 5, -5, 9, -66, 0, -20, -2, -8, 4 }, + { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2, + 45, 31, -17, -16, -2, -2, -1, -22, 1, -1, -3, 3, 5, -3, 5, -1 }, + { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7, -11, -3, -8, 17, -4, + 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 }, + { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38, + 15, -1, 16, -11, 5, 8, 4, -10, 3, -10, -17, 5, 3, 3, 3, 1 }, + { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1, + 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 }, + { -5, 2, -3, -7, 2, -8, -4, 10, 17, -18, -7, 4, -4, -7, -6, -6, + -5, 5, -12, 2, 0, 6, 8, -2, 1, 4, -11, 2, 1, 8, 31, 19 }, + { 6, 9, 16, -6, -6, -1, -2, -3, -11, -2, 7, 7, 17, 3, 4, 10, + 2, 5, -13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 }, + { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10, + -16, 12, 1, -6, 3, 8, -1, 10, -13, -6, -12, -23, 12, -3, 30, 14 }, + { -2, -15, 0, 8, 3, -19, 5, -3, 2, 3, 13, 7, 14, -3, -10, 0, + 8, 5, -6, -16, -8, -8, 14, 2, -1, 1, -9, -11, 11, -5, 27, 9 }, + { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4, -15, 1, 9, 0, + 8, 4, 1, -17, 11, -2, -19, -1, -6, -8, 3, -12, 3, -17, 33, -10 }, + { -3, -1, 2, 7, 7, -2, 9, 8, -18, -1, -13, -10, -3, -3, 11, 8, + -2, -12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 }, + { -3, -10, 8, -1, -5, -11, 7, -5, 3, 6, 1, 4, -16, 10, 5, -4, + -2, -10, -1, 13, 6, -5, -7, 12, 7, -3, -17, 1, 12, -4, 29, 8 }, + { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2, + -2, -8, -6, -11, 14, -13, 27, 3, -2, -12, 5, -16, 2, -26, 20, 15 }, + { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1, + 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8, -25, -8, -4, 34, 23 }, + { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1, + 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68, -16 }, + { 10, 0, -8, 14, -6, 1, -12, 0, 0, -3, -5, -11, -6, 12, 9, -10, + -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 }, + { -12, 13, -5, 7, -11, -2, -1, 1, -4, -14, -21, 3, -3, -3, -4, -7, + -9, -4, 3, -17, -2, -13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 }, + { -10, 6, 5, 6, 4, -7, 10, 0, -28, -3, 0, -11, -1, -5, 16, -10, + -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5, -10, 7, -9, 20, 4 }, + { 1, -7, -2, -7, 4, -3, -2, -7, -1, -14, 6, -16, 4, -5, -4, -6, + -5, 0, -2, 2, -6, 9, -5, 4, -18, 8, -10, 8, 15, 0, 32, 1 }, + { -5, 7, -3, 7, 15, -4, 0, -16, 9, 5, -5, 5, 4, -3, -12, -9, + -18, 10, 2, 2, -3, 7, 3, -1, 6, -9, -10, 3, 15, -4, 35, -7 }, + { -1, -10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1, -14, -11, 3, + -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 }, + { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1, + -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4, -12, 21, -39, 24, -2 }, + { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2, -11, -8, -1, 4, 2, 2, + -4, -10, 12, -5, -11, 1, -15, -34, -11, -7, -11, -1, 7, -14, 38, -1 }, + { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11, -15, 20, -1, + -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11, -12, 27, -4 }, + { 0, 8, -4, 3, -11, 6, -11, 2, 3, 0, 5, -8, -7, -6, -9, -21, + 4, -11, -1, -16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 }, + { 1, 3, 4, 11, -11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4, + 0, 4, -8, 13, -6, -13, -1, -5, -1, 4, 0, 0, 9, -22, 24, 18 }, + { -7, 3, 10, -13, -6, 6, -6, 6, 22, 1, 0, -14, 2, 3, 7, -1, + 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 }, + { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2, + 5, 2, -11, 4, 0, -1, 12, 0, -3, -13, 15, 8, -6, -27, 34, 0 }, + { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1, + 3, -6, -7, -6, -5, 4, -19, -6, -8, -34, -4, -8, 10, -7, 23, 10 }, + { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7, + -6, 1, -12, -12, -1, -16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 }, + { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1, -11, 6, -5, 0, 2, -6, + -3, -6, 4, -1, 5, -5, -12, -6, 7, -5, 9, 3, 6, -7, 29, 1 }, + { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5, + -1, 0, 4, 2, 11, 6, 2, -3, 13, -9, -19, 18, -15, -10, 36, 21 }, + { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0, + -2, 0, -2, 6, -19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28, -10 }, + { -5, 1, -3, -7, -12, -4, 1, 1, -1, 13, -10, -1, -9, -5, -13, 6, + 13, 3, -4, 2, 3, 11, 2, 6, -25, -16, -6, 0, 14, -1, 27, 16 }, + { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8, -12, -6, 5, + -6, 5, 3, -9, 1, 4, -7, -10, -9, -7, -17, -5, -15, -23, 25, 3 }, + { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1, + -7, -4, -5, -16, 3, -6, 18, -13, -9, 16, -15, 8, 15, -10, 24, 5 }, + { 1, -38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7, + -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 }, + { 1, -22, 15, 18, -2, 10, -16, -9, -8, -11, 8, 4, 0, 7, -14, -5, + -1, -7, 12, 17, 9, 5, -7, -4, -12, -6, 7, 0, 7, 2, -2, 1 }, + { -11, -29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7, -14, 8, + -3, -11, -13, 0, -7, -23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 }, + { -24, -27, -11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3, + 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 }, + { -9, -24, 11, 13, -10, -12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9, + -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 }, + { -8, -15, 7, 14, -4, -5, 2, -18, -19, -2, 2, 17, 16, 6, -10, 10, + -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5, -12, 3, 2 }, + { -10, -37, 13, 1, 3, -14, 0, -20, 4, -3, 8, 2, -2, -3, -9, -5, + -3, -17, -1, 13, -11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 }, + { -2, -22, -5, 46, -8, 5, 9, -11, 8, 7, 7, -1, -1, -2, -7, 2, + -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 }, + { -16, -27, 15, 16, -4, 14, -7, -26, 2, -2, 6, 5, -3, 11, 0, 2, + 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 }, + { -3, -22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1, -21, -4, 5, + 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 }, + { -9, -25, 3, 18, 9, -6, -11, 0, -5, -12, 9, -8, -7, -6, -6, 22, + 2, -6, -3, 15, 3, 2, -2, 9, 14, -10, -7, 15, 13, 6, -2, 11 }, + { 5, -20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2, + 6, 10, 9, -9, -18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 }, + { -8, -30, 7, 12, 10, 8, 7, -13, -16, 0, 1, -1, -6, -11, -15, 4, + 1, -2, 10, -15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7, -18 }, + { -10, -32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5, -15, + -11, 6, 20, 4, 0, -12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 }, + { 1, -25, -14, 12, -11, 9, 9, -16, -24, -17, 22, -9, 11, -30, -3, -4, + 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 }, + { -14, -26, -6, 9, 8, 17, -11, -24, -7, -4, -8, -2, 10, 2, 2, -1, + 2, 13, 12, -7, 4, -6, -10, 6, 6, -13, -11, -7, -16, 0, -2, 5 }, + { -4, -30, -13, 12, 16, -6, 12, -16, -13, 5, 15, -2, -2, -10, -7, 7, + 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 }, + { -4, -21, 20, 22, 2, 20, -8, 1, -12, -5, -9, 4, -10, -17, -3, -8, + -3, 3, -12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 }, + { -12, -20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17, -13, -2, -10, + -17, -1, -18, 2, 0, 14, -6, 1, 0, 3, 2, -10, 1, -5, -2, 5 }, + { 16, -37, -1, 26, -2, -14, 1, -5, -14, 2, 2, 3, 6, 1, 1, 4, + 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 }, + { -9, -24, -12, 5, 5, 3, -17, -14, 4, 3, 2, -4, 10, -22, -8, -3, + 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 }, + { -14, -33, -2, 20, -13, -10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8, + 0, -2, 10, 7, -2, -13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 }, + { -10, -23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15, -14, + 13, 14, 2, 5, -13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 }, + { -13, -25, -10, 13, -17, -24, -7, -13, -6, -10, -8, 2, 0, -13, -10, -4, + -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 }, + { -12, -23, 1, 18, -11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2, + -2, 11, -13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 }, + { -5, -18, 16, 22, 2, 0, 8, -6, -9, -7, 10, -16, 23, 10, -11, -1, + 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 }, + { -3, -26, 14, 11, 2, -9, 17, -2, -1, -5, -16, -9, -5, 10, -13, 1, + 6, 12, 10, 11, 0, 0, -3, -14, 6, -2, 0, 4, -5, -1, -7, -1 }, + { -10, -33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2, -10, -5, + -6, 12, -11, 5, -10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16, -17 }, + { -14, -37, 7, 7, -2, 5, -8, -11, 2, -13, 4, -19, 1, 8, 8, 4, + -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 }, + { -6, -30, 18, 17, 1, -22, -3, 4, -7, -10, 7, 0, -8, 8, -1, 4, + 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 }, + { -17, -18, -3, 22, -8, 1, 9, -2, -17, 20, -5, -5, -12, -5, 4, -5, + -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 }, + { -9, -23, 3, 10, 4, 4, -3, -2, -2, -2, 1, -22, 11, 0, -2, 5, + -2, 14, -9, -11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 }, + { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1, + -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5, -69, -19 }, + { -3, -5, -8, -12, 4, -3, -19, -11, -5, 0, -14, 7, 18, -6, 7, 22, + 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3, -26, -11 }, + { -1, -6, 4, -4, -5, -16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3, + -4, -33, -4, 4, -7, 0, 1, 6, -11, -2, -13, -2, -18, 20, -25, -16 }, + { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11, -10, 4, -10, 7, 16, 2, + 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0, -33, -2 }, + { -3, -15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4, + 12, 13, -13, -14, 10, -6, 9, 22, -27, 23, -1, 5, -24, 2, -30, 5 }, + { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1, + 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4, -37, 9 }, + { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7, -10, -10, -1, -4, 11, -3, + 7, -6, 4, -12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3, -40, 13 }, + { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1, + 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1, -32, -7 }, + { -16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15, -13, -11, 11, 9, 4, + 3, -8, -10, 12, 12, 0, 0, -16, -9, 13, 2, 9, 4, -13, -33, 3 }, + { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2, -11, -1, -15, -11, -1, 1, + 11, -3, -2, 24, -4, -6, -25, -10, -15, -8, 0, 0, -5, 4, -30, 2 }, + { 10, -3, -6, 1, -9, -5, 6, 9, -10, -3, 8, -1, 4, -1, 11, -11, + 3, 9, 11, -3, 6, -17, 5, -8, -33, 9, -13, 19, -2, 9, -25, 2 }, + { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2, + 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0, -15, 12, -63, 27 }, + { -2, 14, 9, -1, 3, 0, 1, 1, -19, 15, 3, 4, 0, -10, 1, -5, + 3, 0, -5, -10, 2, -16, -4, 8, -12, -6, 7, -5, -10, -1, -33, -4 }, + { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1, -12, 3, 8, + -10, 6, -1, 1, 13, -5, -5, 2, -4, 13, -18, -10, -7, -9, -33, 10 }, + { -6, -3, -12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2, + 1, 8, -10, 7, -1, -3, 3, 0, 13, 1, 6, 7, -16, -7, -39, 8 }, + { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2, + -3, 13, -11, 1, 7, 5, 19, -5, -3, -15, -1, 7, -1, 6, -33, 8 }, + { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6, + -2, 1, 7, 0, 1, 1, -5, 2, -2, 0, -13, -2, -31, -14, -39, -12 }, + { -10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7, + 18, -8, -2, -19, -7, -7, -12, -14, -11, -1, -9, -13, -7, -12, -31, -9 }, + { -3, -16, 10, 9, 1, -10, -12, 2, -2, 2, 7, -3, -3, 1, -4, -5, + -9, 5, 7, 3, -1, 4, -11, -8, 4, 13, -10, 13, 10, -4, -36, 1 }, + { -7, -12, 4, -20, -7, -7, 2, 11, -1, -2, 3, -12, 1, 0, -6, -7, + 6, 4, 13, 3, -3, 4, 3, -6, -12, 5, -5, -22, -13, -8, -37, -6 }, + { -7, 5, 3, 5, 7, 9, -14, -3, 10, 17, -1, 1, -12, 5, -6, 0, + -4, -9, 0, -11, -14, 3, 13, 6, -25, -8, -12, 4, -10, 18, -30, -1 }, + { -10, 6, -10, 6, 6, 1, -10, 0, -7, 5, -2, 17, -18, -4, 0, -3, + -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0, -32, -11 }, + { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4, + -6, 0, 2, -3, -1, 5, 10, 0, 12, -10, -18, -3, -1, 14, -33, 2 }, + { 4, -8, -18, -4, -5, -11, 4, -10, -4, 9, 13, -12, 1, -6, 1, 2, + 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0, -30, 1 }, + { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3, + -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2, -33, -8 }, + { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8, + 7, -11, -4, 6, -10, 7, -1, -1, -2, -1, 16, 32, -7, 20, -33, -6 }, + { -18, 2, 6, 13, 9, 9, -1, 3, -17, 24, -2, -6, 28, 8, -2, 6, + 3, -10, -34, -16, -13, -4, -15, -11, -12, -3, -10, 4, -8, 4, -31, -4 }, + { -11, 0, 18, 2, -16, -9, -13, -2, -2, -12, -3, -22, 30, 0, 8, 3, + 9, -4, -16, 1, 0, -11, 15, -2, -4, 6, -5, 6, 1, 2, -25, -12 }, + { 14, -1, 5, 7, 3, -15, -8, 1, 5, -2, 12, 13, 11, -25, 3, 1, + 0, -2, -4, -16, -23, 0, -5, -17, 7, 5, -9, 6, -5, 2, -32, -7 }, + { 3, -1, 6, 14, 2, -12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2, + 4, 5, -2, 8, 8, -6, 0, 10, -20, -1, 3, -1, 8, 23, -33, -5 }, + { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1, + 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1, -12, 0, -34, 18 }, + { -17, 13, 0, 1, 9, -4, -11, 0, 7, 0, -10, -4, -1, 6, -6, 4, + 1, 6, -9, 3, -5, -6, -11, 2, -4, 14, 23, -3, 2, 5, -30, 12 }, + { -14, 5, -27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5, + 8, -10, 48, -11, 12, 33, 6, 8, -15, 20, -2, -5, 32, 5, -19, 10 }, + { -16, -4, -12, -7, -2, 0, 8, -6, -20, -18, 16, -3, 0, 31, -2, 11, + 2, -9, 49, -19, -12, -23, 10, 26, 16, -2, 4, -21, -14, 13, -11, -9 }, + { -5, -9, -1, 3, -5, -21, 2, 10, 0, 0, 10, -21, -7, 7, -26, -9, + 22, 32, 58, 11, -3, 11, -5, -8, -13, 6, -5, -9, 1, 10, 14, -8 }, + { 7, 7, 10, 3, -2, -1, -11, -11, -6, -43, -3, 14, -19, -18, 19, 18, + -32, 10, 45, -6, 6, 21, -20, -12, 2, 4, 6, 6, -4, 3, 3, 1 }, + { 21, 22, -3, -2, -11, -6, -1, -2, 8, 8, 32, -21, 7, 28, -4, -6, + -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4, -17, 27, 6 }, + { 13, 7, 2, -6, -12, 2, -10, -5, -17, 11, 4, 17, -12, -2, 5, -17, + 37, -16, 48, -14, -18, 29, 8, 24, 11, -5, -9, 11, -1, 1, -13, -3 }, + { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6, + 2, 10, 54, -25, 7, 54, -5, -6, -1, -15, 9, 13, -24, -15, -12, 3 }, + { 21, 5, 8, 3, -3, -4, -2, -4, 3, -11, -5, -8, 9, 16, 8, -9, + -10, -3, 46, -46, 2, 1, -10, 10, 17, 11, -20, -36, 10, 14, 0, -5 }, + { 7, -13, -6, -9, -24, 45, 2, 8, 8, 0, 17, 20, 12, -24, 1, -7, + -15, -3, 46, -13, -2, 20, 1, -13, -11, -13, 2, 15, 1, 10, -1, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1, + -16, -9, 31, -69, -34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, + -5, -20, 18, -82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1, + 15, -5, 62, -36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 }, + { 3, -19, 19, -20, 13, -4, -11, 8, 8, -16, 10, 1, -14, 30, 1, -33, + 10, -11, 45, -30, 3, -4, -3, -13, 7, 12, 3, -22, 3, -2, -4, -2 }, + { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, + 11, 8, 70, 48, -10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 2, -1, 80, 2, -15, -36, -10, -5, -2, 8, -2, 2, 0, 0, 0, 0 }, + { 10, 8, -8, -8, -24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12, -10, + -2, -13, 35, -43, 44, 15, -10, -25, 4, 10, -3, -5, -5, 7, -1, 3 }, + { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1, + -18, 9, 49, -72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 }, + { -1, 4, -3, 10, 19, 4, 3, 20, 6, -24, 6, 9, 8, 15, 18, 18, + -36, 19, 57, -11, 4, -3, 8, 7, 2, -3, -2, -9, -15, -2, 12, -4 }, + { 20, 3, 11, -9, -4, 22, 42, -25, 1, 5, -10, -19, 0, 9, -16, 5, + 2, 10, 44, -29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 }, + { -7, 16, -11, 12, 6, 33, -15, 14, -23, 2, -26, 8, 2, 10, 0, -5, + 8, -8, 38, -38, -4, 5, 5, 5, 1, 22, -15, 7, 6, 0, 4, 28 }, + { -1, -12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18, + 4, 1, 27, -39, 31, 17, 2, 2, 22, -23, 13, 16, 1, -7, -4, -5 }, + { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0, -14, 0, + -7, -11, 49, -22, -4, 19, 17, -39, 4, -29, 10, 2, 36, -4, 23, -1 }, + { -2, -2, -2, -2, 1, 15, -5, -7, -16, -8, -19, 16, -3, -20, 36, -9, + -3, 20, 39, -20, 0, 2, 27, -16, 10, 10, -14, -22, -16, -3, 13, -8 }, + { 5, -9, 6, -25, 7, 37, 13, -10, -5, 3, -5, 7, 18, -22, -7, 9, + -5, -4, 50, -11, -4, -5, -5, 8, -4, -2, -4, -27, 14, 20, 7, -9 }, + { 0, -14, -10, -27, -14, -17, -6, 26, 10, 2, 14, -12, -5, 0, 8, 9, + 0, -28, 55, -7, -12, -7, 4, -10, 10, 7, -12, 11, 3, 5, 9, -8 }, + { 2, 23, 4, -2, -1, -20, -2, 14, 10, -9, -9, -24, 10, 0, 11, -12, + 12, 11, 49, -25, -2, 29, 7, -13, 21, -10, 11, -17, 3, 1, -8, 5 }, + { 3, 0, -14, -6, 18, -2, 17, -9, -19, 9, -5, 9, 14, 6, 19, -3, + 27, 1, 41, -21, 20, -15, 33, 0, 26, 14, 7, 10, 3, 20, -3, -12 }, + { -1, 16, 15, -8, 3, -8, -8, 21, -5, -16, -29, 4, 1, -6, -4, -28, + 2, 31, 37, -26, -2, 13, 24, 8, -9, -6, -29, 10, 7, 2, 7, 8 }, + { -10, -10, 11, 13, -32, 2, 16, 9, 14, 23, -15, -13, 24, 13, 4, -27, + 14, 12, 31, -18, 17, 23, -2, -7, -14, 9, -17, -6, -10, 20, 9, 6 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, + 4, -7, 64, -50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, + { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1, + 6, -2, 50, -35, -7, 43, 7, -7, -5, -26, 24, 21, 3, -15, 5, 6 }, + { -8, 21, -19, 33, -8, 22, -11, 17, 3, 0, 0, -2, 1, -3, 6, -1, + 10, -8, 4, -11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 }, + { -7, 5, -20, 9, -22, 3, -14, 1, 6, 13, 23, -2, -4, -7, 2, 0, + 11, 4, 6, 3, -7, -11, -7, 4, 5, 5, -12, 8, 2, 4, 7, -3 }, + { -7, 6, -4, 20, -20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3, + -9, -4, 1, 2, 5, 2, 1, -9, -2, -17, -4, 6, -10, 7, -7, -6 }, + { -9, 18, -17, 12, -24, 1, -1, 4, 14, 9, 4, 3, 2, 8, -12, -14, + 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 }, + { -25, 2, -11, 6, -5, 24, -28, -5, 8, 12, -2, 6, 8, -3, 8, -9, + -1, -5, -1, -5, 6, -1, -1, -1, -4, 8, -12, -2, -13, 7, 2, 1 }, + { -14, 14, -18, 20, -10, 12, -2, 9, 1, 0, 12, -2, 15, -10, 26, -17, + 16, -11, 10, -10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 }, + { -18, 12, -18, 21, -6, 12, -6, 13, -25, 18, 1, 11, -9, -5, 0, 10, + -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 }, + { -4, 16, 1, 18, -30, 9, 1, 6, -8, 13, 13, -12, -6, -1, 13, 7, + 6, 2, -15, -3, 5, 5, 1, -6, 1, -5, 0, 2, -16, 0, 3, -4 }, + { -21, 1, -2, 6, -43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3, + 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 }, + { -23, 10, 4, 7, -32, -11, -18, 2, -2, -7, -6, -3, -3, -12, 19, 3, + -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8, -15, -11, 2, 10 }, + { -8, 2, -13, 2, -29, 24, -20, 19, 1, 10, -4, 10, 1, 2, -9, 11, + -1, -2, 9, -5, 19, -7, 16, -9, -2, -18, 11, 1, 1, 0, 7, -3 }, + { -6, 3, 4, 13, -26, 10, -10, 28, -7, 28, 1, 7, 0, -14, 5, 7, + 4, -4, 3, -2, 3, 3, -11, 7, 6, 4, 0, -1, 2, -1, -3, 2 }, + { -6, 16, -31, 13, -10, 17, -6, 4, -14, 4, 4, -1, -10, 12, -5, 1, + -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7, -20, 7, 4, 11, -5 }, + { -19, 3, -17, 14, -12, 16, -22, 18, 14, 8, -2, 4, 10, 12, -14, 4, + -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 }, + { -9, -7, -11, 24, -36, -9, -11, 5, 7, -12, -13, 18, -2, 20, 1, -4, + -1, -10, 15, -6, 14, 1, 0, 2, 1, 2, -9, -16, -11, 7, 13, 0 }, + { -24, 24, -18, 18, -22, 14, -11, 13, -12, 11, -10, 11, -7, 11, -5, -4, + -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 }, + { -6, 18, -22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15, + -6, -18, 0, -33, -9, -12, -1, 6, 5, 2, 5, 5, -5, -17, -3, -3 }, + { 1, 11, -16, 9, -18, 11, -4, 18, 20, 26, -10, 8, 1, -11, 8, -4, + 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 }, + { -10, 6, -1, 18, -17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7, + -12, -1, -7, -6, -1, 8, 3, -15, 8, 9, 3, -7, 4, -1, 1, -1 }, + { -14, 6, -16, 22, 2, 5, 0, 5, -18, 11, 6, -3, 22, -20, -9, -3, + 6, -6, -7, -15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 }, + { -21, 5, -19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3, -22, -13, -6, + -1, -3, -2, -14, 6, -3, 1, -8, -7, -5, -6, 11, -3, -10, -5, 2 }, + { -1, 9, -12, 15, -6, 6, -19, 14, -9, 11, 3, 12, -17, -3, 8, -4, + -3, -4, 1, -5, 4, 5, -7, -15, -7, 15, -6, -5, 1, -5, -3, 1 }, + { -12, 20, -15, 20, -14, 3, -14, 9, -6, 33, -13, 6, -2, 8, -6, 7, + -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 }, + { -7, 12, -18, 12, -18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3, + 6, -12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 }, + { -18, 12, -10, 11, -22, 0, -15, 5, -2, 2, -3, 6, -4, -4, -3, -15, + -2, -3, 21, 6, -12, -11, 19, 3, 3, -14, 7, 0, -11, -22, -10, 0 }, + { -15, 2, -30, 15, -17, 13, -16, 8, -7, 10, -8, 2, 11, 3, 10, -7, + 7, -22, 12, -10, 3, -12, 6, -10, 12, -10, 7, -8, 5, 2, 9, 1 }, + { -9, 11, -14, 6, -10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1, + -1, 4, 2, -20, -18, -1, -14, 3, -1, 4, -7, 10, 1, 11, 4, -4 }, + { -22, 8, -30, 13, -21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4, -13, + -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 }, + { -6, -4, -35, 16, -13, 15, -11, 14, -7, 9, -1, 11, 7, 0, 13, 10, + -1, 8, 1, 1, -2, 8, -1, 2, 2, 3, -10, -1, 7, -13, -3, -7 }, + { -15, 7, -16, 14, -18, 17, -6, 14, 3, 4, 7, -3, 10, -22, 5, -15, + 4, -4, -11, 15, -15, 11, -11, 20, 1, 0, 2, 1, 11, -3, 11, -7 }, + { -12, 3, 5, 16, -37, -1, 15, 15, -15, 10, 3, -10, 1, 15, 7, -15, + -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 }, + { -16, 26, -4, 14, -22, 26, 6, -3, -8, 4, 21, 6, 16, -4, -11, 7, + -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 }, + { -7, -10, 4, 3, 2, -4, -12, -10, -4, -5, 16, 19, -16, 1, 2, -9, + -10, 0, 9, 7, -8, 3, 12, 8, -6, -11, -13, -1, -3, -20, 6, -5 }, + { -14, -17, 3, -5, 14, -12, -12, 8, -6, -25, 21, 21, 10, -8, -12, 4, + 10, -4, 3, -9, 11, 9, 0, 4, 2, -15, 1, -14, 4, 1, 0, -4 }, + { -4, -9, -3, -1, 6, 3, -6, 6, -10, -4, 14, 8, 2, -3, -12, -19, + 0, 11, -20, 1, 6, -2, -27, -6, 10, -17, -14, -17, -9, 8, -8, 3 }, + { -12, -13, 16, -4, -2, 12, -7, -11, 2, -13, 3, 7, -16, -18, -1, -12, + -2, 1, -12, -9, -2, -6, 2, 9, -22, -3, -4, -14, -7, 7, -1, 2 }, + { -7, -8, -8, 15, 15, 18, 15, 16, -4, -37, 11, 15, -12, -1, -3, 3, + 6, 6, 0, -5, -3, -5, 9, 1, 1, -11, -1, -8, -6, 2, 3, 0 }, + { -6, 7, -5, -12, 13, 10, -18, -4, -3, -21, 6, 16, -15, -7, -12, -9, + 1, -12, -1, 10, -2, -1, -3, 4, -4, 1, -16, -1, 12, -9, 5, 9 }, + { -14, -5, 9, 3, 4, 26, -28, 3, -6, -24, 4, 5, 3, 13, 5, -1, + 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 }, + { -4, 2, -10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7, + 5, 14, 9, -1, 0, -12, 4, -4, -10, 1, -3, 3, -2, -2, -6, -1 }, + { -10, 8, -15, -10, 19, 17, -8, 0, -3, -7, 7, 5, -13, -1, 7, -7, + 1, 13, -12, -13, 17, -12, 1, 26, -18, -3, -5, -6, 4, 5, 8, 1 }, + { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5, + 4, -1, -11, -8, -4, 0, -13, 2, -47, -23, -8, -11, -4, 4, -2, -3 }, + { -18, -4, 4, 5, -1, 17, -12, -8, 1, -12, 7, 20, -12, 3, -2, -11, + 16, 12, -6, 1, -13, -16, -6, -3, -3, -5, 4, -12, -5, -9, 10, 1 }, + { -11, 0, 4, 7, 7, 8, 3, -1, 3, -19, 32, 8, -19, -8, 2, 4, + -12, 15, -16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 }, + { 3, -1, 4, -2, 14, 32, -9, -23, -10, -12, 22, 15, -1, -2, 10, 0, + 4, 6, -8, 4, -15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 }, + { -17, -12, 6, -8, 16, 13, -20, -8, -1, -16, 10, 21, -19, 11, -9, -5, + 7, 18, -6, 7, -7, -18, 13, 2, -2, 8, -12, -9, 2, 4, -5, 16 }, + { 4, 0, 17, -11, 12, 7, -12, 5, -1, -25, 30, -8, -7, -6, -4, -7, + 9, 8, 7, 3, 3, -16, 8, 0, -2, -2, -18, -3, -4, -5, 1, 4 }, + { -3, -6, 6, -16, 17, 6, -3, 2, -9, -17, 12, 11, 11, 2, -20, 8, + 1, 1, 0, 2, -2, -6, -21, -13, -9, -15, -1, -8, -6, -8, 0, -2 }, + { -11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26, -10, -3, 4, 0, + 2, 2, -4, 4, -2, -12, 12, 10, -11, 0, -10, -16, 3, 0, 0, -10 }, + { -5, -16, 10, -6, 27, 13, -3, 4, -2, -13, 15, 5, 2, 5, 3, -4, + 13, 12, -11, -7, 0, 1, 11, 12, 2, 13, -15, -8, 9, -2, 3, 8 }, + { -5, -8, 4, 3, 9, 3, -11, 10, 14, -25, 14, 8, -2, 5, -12, -21, + 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1, -16, 2, 8 }, + { -1, 5, 1, -11, 5, 9, -7, 8, -13, -12, 4, 12, -4, 1, -1, -1, + 27, 29, 10, 15, 2, -6, -3, 4, -21, 10, -9, -11, -6, -1, -9, -3 }, + { -6, -3, -1, -6, 11, -5, 0, -2, -5, -31, 11, 3, -1, 5, -3, 4, + 5, 7, -10, 5, -10, -13, 4, 12, -15, -2, 2, -7, 1, -9, -3, -10 }, + { -3, -7, 17, -8, -5, 36, 8, -7, -8, -20, 12, 8, 1, -1, 3, 0, + 1, 4, -10, 3, 1, 4, -2, -3, -2, -3, -10, 4, -1, -7, 3, 2 }, + { -13, -3, -5, 9, 22, 6, -23, 3, -10, -7, 17, 17, 18, -14, -8, -8, + 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0, -12, -3 }, + { -3, -10, -15, -3, 9, 3, -23, -9, -13, -18, 12, 13, -2, 0, 1, 8, + -1, 2, -7, -12, -5, 14, 2, 1, -22, 6, -10, -8, -9, 28, -7, -14 }, + { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2, + 2, 1, -10, -2, -2, -22, -2, -7, -10, -5, -11, -27, -12, -16, 4, -7 }, + { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15, -10, -4, -2, 2, + -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 }, + { 10, -1, 0, 5, 21, 7, -14, 6, -3, -16, 15, 17, -16, 13, 3, -6, + -4, 6, -12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 }, + { -6, -2, -8, -11, 15, 10, 0, 8, -6, -15, 33, 8, -2, 18, -15, -11, + 5, -1, 0, 15, -15, -4, -4, -1, 10, 7, -13, 4, -4, 0, 8, 3 }, + { -7, -2, 0, -2, 0, -2, -4, -5, -14, -16, 12, 38, 7, 12, 6, -4, + 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 }, + { -8, -4, 18, 1, 14, 5, -12, -3, 20, -17, 5, 19, -11, -8, 11, -3, + 3, 9, -7, -8, 9, -17, 2, 15, -10, -11, 5, -5, 7, 15, -6, -2 }, + { -7, 2, 38, 5, 19, 16, -5, 4, -13, -20, 0, 4, -4, 6, 4, 2, + -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 }, + { -11, -12, 8, -15, -3, 14, -7, -22, -11, 2, 22, 14, -19, 2, -19, -6, + 1, 3, -18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 }, + { 8, 7, 25, -21, 12, -6, -5, -4, -10, 6, 0, 10, 1, -12, 18, -5, + -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 }, + { 9, 10, 32, -15, 8, 2, 11, -7, -18, -8, 2, -6, -9, -16, -3, 3, + -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3, -11, 1, 5, 0, 0 }, + { 14, 0, 23, -25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0, + 3, 2, 3, -10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 }, + { 12, 0, 25, -18, -5, -4, 13, -10, 3, -6, 7, 21, 0, -16, 3, -10, + -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 }, + { 31, 15, 27, -20, 10, -7, 15, -10, 9, -8, 4, -5, 3, -3, 5, 6, + 11, -2, -12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 }, + { 12, -4, 13, -23, 12, -6, 2, 4, -3, 13, 6, -7, 5, -19, -7, 18, + 1, -7, 7, 1, 16, -7, 3, 0, 3, 0, -12, 8, -11, 9, 4, 7 }, + { 29, 1, 3, -22, -5, 6, 0, 12, -14, 11, 1, 6, -3, 4, 6, -2, + 4, -13, 12, 1, 1, 3, -11, 9, -10, -1, -7, 16, -11, -1, 3, 9 }, + { 4, 4, 36, -23, -5, -8, -15, 1, -6, 3, 13, -1, -5, -7, 4, 9, + 2, -11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 }, + { 19, 10, 6, -17, 2, -4, -2, -4, -3, 13, 2, 2, -13, -7, -3, -11, + 9, -6, 1, -9, -5, 4, -5, -9, -18, -7, -11, 9, 4, -11, 8, 4 }, + { 16, -3, 9, -16, 18, -2, -12, -16, -11, 11, -18, 16, -13, 6, 2, 8, + 3, 8, -4, -16, 10, -11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 }, + { 14, 15, 3, -23, -5, 7, -8, -6, 2, 17, 2, 12, -8, -12, 13, -1, + -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 }, + { 32, 5, -10, -47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4, + 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 }, + { 20, 8, 10, -21, -7, -9, -16, 12, 1, 4, 6, -5, 9, -11, -7, 4, + -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 }, + { 38, 3, 23, -25, -6, -18, 3, -10, -8, 6, -10, 1, -10, 2, 2, 0, + -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 }, + { 20, 5, 16, -22, 24, -18, 2, -12, -14, -7, -3, 10, 2, 7, -10, 2, + -8, 1, 8, -1, 4, 1, 4, -2, 5, -9, -18, -8, -13, 5, -11, 10 }, + { 14, 8, -12, -16, 9, -11, -3, -6, -25, -7, 6, 5, -7, -16, 10, 2, + -7, -1, -9, -3, 16, 4, 3, 3, -3, -3, -15, 13, -3, 4, 13, -7 }, + { 16, -9, 19, -23, 7, -19, -3, -5, -15, 11, -21, 21, -16, 18, -1, 6, + 10, -10, 18, -14, 16, -15, 6, -5, -9, 5, -17, 13, -10, 13, 0, 10 }, + { 8, -4, 4, -24, 8, -21, -18, 9, -11, 4, -6, 17, 5, -9, -2, -2, + 2, 15, -2, -3, -2, 1, 7, -13, 15, -10, -8, -11, 3, 3, -1, -1 }, + { 14, 17, 6, -32, 5, -17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9, + -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 }, + { 24, 6, 22, -12, 8, 3, -14, 4, -7, 8, 6, 5, 6, 1, 6, -12, + 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 }, + { 17, 12, 3, -23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17, + 11, 0, -2, -11, 7, 4, 0, -27, -7, 1, 2, -8, 9, 7, 5, 3 }, + { 12, 10, 12, -10, -4, 5, -1, 2, -24, 5, -8, 2, 6, -17, 19, 5, + 12, -2, 16, -7, -6, -14, 4, 1, -3, 13, -16, 5, -1, 4, 1, 1 }, + { 31, 9, 11, -17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4, + -5, -8, 1, 4, 15, -6, -28, 1, 8, 3, -6, 5, 17, -2, 2, -4 }, + { 11, 19, 16, -26, 0, -7, -7, 2, -13, -15, -12, 9, -3, 27, 8, 4, + -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 }, + { 10, 18, 16, -32, 19, -9, -4, -3, -7, 8, 8, -3, -11, -2, -6, -16, + 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 }, + { 9, 4, 19, -33, 4, 7, -12, 36, -3, -1, 8, -2, 2, -8, -9, -4, + -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 }, + { 25, 7, 15, -12, 2, -24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6, + 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 }, + { 19, 6, 8, -20, 9, -9, 5, -4, -13, 7, 11, -3, 5, -13, -9, 6, + -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 }, + { 15, 6, 19, -23, -3, -9, 3, 16, -6, -4, 6, -5, -10, 1, 16, -14, + 2, 0, 2, -13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 }, + { 14, 4, 16, -20, 1, 12, 0, 6, -3, 9, 4, 16, 10, -16, 5, 7, + 5, -4, -4, -18, -3, -11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 }, + { 22, 3, -1, -30, 18, -3, -9, 9, -2, 11, -16, -2, -14, 12, 0, 4, + -5, 4, -1, 3, -20, 12, 4, -10, -2, -2, -12, -12, 10, 6, 11, -3 }, + { 15, 7, 2, -21, 5, 4, 9, -9, -33, 7, 7, 3, -6, -14, -8, 10, + 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 }, + { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14, -15, 2, -7, -31, -3, + 14, 0, 14, -15, -1, -4, -15, 10, 1, -3, 1, 2, 5, 2, -8, 1 }, + { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1, -19, 0, -11, 18, + 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 }, + { -9, 1, -5, 0, 0, -15, 8, 4, 8, 3, 8, 12, -13, -2, -39, -2, + 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 }, + { -9, 6, 6, -8, 12, -12, 23, -18, 4, -15, -5, 2, -20, 13, -7, 7, + 7, -12, 14, -12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 }, + { -18, 13, 4, 3, -10, -30, -10, -6, -14, 1, -7, -4, -35, 5, -25, 11, + 9, 8, 19, -4, -7, -3, -18, -8, 1, 5, 10, -4, -14, -9, 3, -4 }, + { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7, -16, -17, -20, 11, + -6, -14, 1, 4, 19, 2, -8, 6, -15, 3, 6, -5, -14, 3, 7, 2 }, + { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16, -14, -2, -9, -4, + 13, -2, 18, 14, 14, 19, -13, 5, -10, 2, -3, 3, 5, 5, 1, -1 }, + { -1, -5, -6, -2, -11, -7, 5, -4, 5, -1, 0, 3, -3, 2, -19, 18, + 16, 4, 14, -22, -2, -11, -22, 1, -1, 11, 1, 2, 11, -10, 7, -12 }, + { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9, -24, 23, 1, 20, + 14, -11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 }, + { -1, -1, 1, 7, -3, -4, 8, -16, 15, -1, -7, 9, -22, -11, -11, 10, + 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7, -14, -7, 4 }, + { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5, -22, 17, + 7, -11, 15, -5, 1, 3, -19, 0, -15, -3, 16, 5, 5, -7, -11, 12 }, + { -2, -1, 13, 2, 4, -24, 37, -5, -2, -6, 12, 7, -2, -23, -4, 9, + 2, -3, 3, 2, 3, 3, -14, 11, 0, -4, -2, -2, 3, 10, -10, 4 }, + { 2, 9, 8, -6, -28, 14, 28, -11, 18, -11, 0, 2, -2, 4, -12, 3, + 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 }, + { -7, 14, 5, -10, -3, 7, 4, -5, 7, -8, -7, 4, -12, 14, -16, 25, + 3, 0, 1, -5, 12, -10, 0, -10, 0, 12, 12, 17, 12, 10, -1, 0 }, + { -4, -2, 5, -2, -17, -3, 5, -5, 7, -17, 1, 5, -4, 4, -20, 0, + 11, -15, 13, -8, 10, 1, 1, 5, -12, 9, -8, 0, 6, -1, -11, 4 }, + { -3, 12, 13, -15, -7, -7, 0, 5, 33, 3, 3, -6, -13, -7, -15, 10, + 3, 3, 3, -5, 2, 7, -1, 0, -12, 2, 11, -6, -9, 0, 5, 11 }, + { -8, 5, 10, -7, -14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21, + 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 }, + { -8, 8, -3, -8, 8, -11, 16, -16, 17, 0, 8, 16, -17, 10, -16, 10, + -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 }, + { -6, 0, 6, 1, -8, -8, 8, -7, -5, -10, -11, 8, -19, 6, -7, 13, + 5, -3, 4, -8, 7, -1, -18, 9, 0, -5, 6, 26, 3, 8, 2, 4 }, + { -2, -2, 23, -2, -20, 2, 7, -7, -6, -15, 3, 9, -19, -2, -10, 7, + -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 }, + { -6, 12, 10, -10, -7, 4, 17, 11, -6, 1, 12, 11, -18, 8, -12, 4, + 1, 13, 6, -13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 }, + { 7, 1, 7, -17, -8, 8, -1, -7, 5, -6, 4, -3, -16, 9, -24, 18, + -3, 10, 13, -11, -6, -11, -4, 10, 0, 11, 8, 2, 6, -5, -11, 4 }, + { -4, 1, -5, -10, 0, -3, 9, -2, 4, -1, 1, 5, -41, -10, -7, 4, + -3, 3, 1, 0, -12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 }, + { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0, -17, -3, -1, 11, + 4, 1, 27, -12, 0, -14, 2, -15, -3, -9, 0, -7, -3, 15, -8, 6 }, + { -6, 4, 9, 2, 4, 3, 7, -10, 28, 1, -2, 48, 7, 0, -10, 10, + 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 }, + { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39, -14, -12, 5, -19, 21, + 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 }, + { 4, 2, -29, 12, 5, -3, 16, -6, 15, -13, -4, -1, -13, 22, -16, 17, + 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7, -13 }, + { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4, -13, -12, 16, + 23, -4, -12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 }, + { -6, 4, -15, -9, -1, -19, 12, -30, -17, -4, 1, -13, -13, 4, -3, 26, + 5, -25, 11, -14, -6, -13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 }, + { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2, -11, 4, + 32, 15, 15, -47, -8, 3, -12, 4, -5, 4, -1, 0, -5, 5, 1, -7 }, + { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51, + 4, -5, 4, -14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 }, + { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3, -11, -8, -12, 8, + 11, 5, 19, 3, -24, 19, -14, 11, -5, -18, -8, -12, -5, -4, -1, 4 }, + { 16, 9, 10, 14, -18, -2, -18, -27, 10, -5, 12, 14, 4, 0, -2, -6, + -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7, -16, -3, -6, 6, 9 }, + { 7, 15, -9, 10, -19, 4, -5, -37, -2, -4, 8, 2, 4, -1, 1, 9, + -5, -5, -12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 }, + { 13, 17, 3, 9, -7, -7, -15, -17, -8, -13, -4, -8, 19, 2, 16, 25, + 7, 15, 2, 16, -5, -6, -10, -9, -7, -6, -2, -7, 7, 2, 4, 5 }, + { 24, 7, 9, 8, -13, -2, 0, -4, 1, -13, 3, 6, 7, 10, -4, 15, + 5, 7, -4, 5, -5, 3, 13, -7, 5, 15, -11, -2, 7, 5, 8, 6 }, + { 17, 6, -15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8, + -15, 10, -9, 7, -1, -11, 2, -8, -4, 3, 4, -10, 4, 4, 11, 1 }, + { 21, 12, -3, 6, -8, 8, -11, -8, -5, -5, 3, 7, -1, -5, 12, 15, + -10, -11, 3, 15, 8, 4, 2, -15, 0, 14, 1, -8, -1, 3, 10, -7 }, + { 16, 12, 5, 13, -6, 15, -23, 0, -17, -9, 0, 4, -9, 13, 6, 18, + 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 }, + { 14, 16, -1, 12, -15, -9, -6, -20, 4, 6, 8, 9, 3, 1, -9, -4, + -1, -11, 9, 11, -12, 1, -14, -7, 2, -8, 11, 9, -4, 10, 4, -16 }, + { 13, 10, 3, 7, 0, -8, -33, -6, 4, -4, 19, -2, 14, 6, 5, 7, + 6, -3, -1, -10, -10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 }, + { 11, 10, 25, 18, -1, -6, -21, -21, -11, -16, 6, 5, 14, 4, 8, 7, + 0, -10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 }, + { 15, 9, 5, 22, -17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3, + -2, 6, 1, 17, 8, -14, 7, -3, 12, 9, 1, 0, 1, -5, 17, -18 }, + { 25, 19, -17, 12, -4, -10, 1, -13, -19, -7, -3, 9, 6, -2, 3, 1, + 4, -2, -11, -14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 }, + { 20, 8, -3, -10, -24, 3, -6, -2, 0, -12, 14, 6, 7, 11, 4, 7, + -12, -5, -8, -10, 5, -1, -4, 4, 16, 7, -14, 6, -1, -2, -7, -11 }, + { 16, 18, 17, 1, -15, -6, -5, -3, -1, -19, 8, -2, 2, 8, 12, -19, + -12, 8, 0, -3, -1, -1, 4, -14, 9, -1, -12, -1, -7, 10, -3, 5 }, + { 18, 12, -7, 7, 0, -3, -13, 0, -1, -4, 9, -2, 6, -1, 0, 1, + 15, -21, 1, -8, 25, -19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 }, + { 13, 16, -4, 9, -2, 2, -1, -19, -7, -4, 18, -6, 14, 18, -5, 4, + -6, -3, -19, -14, -1, -12, 10, 6, 7, 17, -12, -13, -10, -4, 5, 4 }, + { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14, -11, -7, 2, -3, -3, + -2, -3, -13, 12, 16, 1, -5, -9, -10, -11, -2, 3, -7, 5, 11, -7 }, + { 7, 17, -16, -2, -14, -28, -7, -8, 15, -10, 7, 15, 8, 17, 13, -1, + 4, -7, -12, -11, 0, 0, 2, 3, -3, 7, -6, 6, 1, -16, 1, -2 }, + { 23, 11, -9, 15, -23, -4, -6, -4, 2, -9, -7, 9, -8, 3, -13, -4, + 8, 18, -6, -2, 1, -5, 6, -14, -5, -2, -6, -5, -3, -2, 4, -5 }, + { 12, 13, 18, 18, -35, 2, 7, -17, 3, -11, 6, 9, -3, -2, 10, -4, + 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 }, + { 19, 11, 1, 20, -14, 4, -9, -13, -2, 11, 0, 17, -1, -1, -1, -1, + -5, -8, 0, 5, -1, -8, 5, -1, 3, 2, -12, 21, -2, -24, 5, 7 }, + { 15, 15, -15, 17, -14, -22, 3, -4, -11, -3, -7, 1, 18, 10, 1, 10, + -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 }, + { 45, 13, 8, 17, -5, 2, -16, 2, 8, -2, 8, -15, 4, 5, -1, 7, + -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 }, + { 1, 18, -8, 18, -12, -10, 3, 4, -22, -12, 20, 8, -3, 9, 2, 10, + -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3, -18 }, + { 9, 10, -5, 9, -35, -21, -18, -16, -1, -12, -6, -7, -15, -19, 12, 4, + 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 }, + { 31, 8, -17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3, + -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 }, + { 18, 4, -8, 7, -8, -15, -1, -16, 12, 18, 3, 19, 2, 4, 8, 8, + 0, -5, -8, -12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 }, + { 27, 15, -17, -10, -23, -22, -1, -14, -4, -7, 20, -2, -7, 6, 15, -5, + 32, 4, 9, -11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 }, + { 22, 4, -7, 2, -15, -11, -17, -10, 2, 0, 15, 11, 7, 12, -8, 6, + -10, -18, -6, -12, 7, 3, 22, 3, -7, 14, -5, -2, -13, -7, -1, -7 }, + { 18, 13, 9, 24, -4, -19, -9, -11, 13, 8, 2, 4, -1, 8, 14, 10, + -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 }, + { 15, 19, -5, 1, -4, -10, -8, -27, 6, 8, 5, 10, 4, 11, 5, -5, + -11, 0, -11, -14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 }, + { 18, 1, -13, 14, -14, 9, -15, -7, 12, 1, 13, -4, -20, 12, 10, 12, + -12, 7, 1, -13, 10, -6, 5, -3, 4, 8, 10, -13, -3, -6, 9, -3 }, + { 19, -14, 5, -8, -6, 2, -5, 5, -3, -1, -28, 11, 18, -6, -4, -2, + 11, 14, -43, -42, 9, 2, 20, -23, 6, 32, 0, 5, 0, 6, 9, 5 }, + { 8, 11, -14, -1, 7, 12, -7, 2, -16, 2, 10, -3, -1, -7, -7, -1, + 1, -10, -60, -23, -18, 42, -13, 9, 18, -11, 0, 1, 0, 2, -5, 1 }, + { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2, + -2, 3, -34, -15, 37, 47, 10, 20, 9, 1, 3, -21, -25, -33, -14, 8 }, + { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5, -13, 9, 3, + -17, -19, -2, -79, -12, -7, -8, -6, -2, -2, -1, -1, -7, -13, 6, -1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, + 0, 3, 4, -87, 6, -11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 }, + { -5, 6, 2, -24, 5, -9, -7, 0, 7, 3, -3, 16, -14, -16, 0, 18, + 15, -9, -14, -28, -17, 53, 14, -6, -28, -1, -3, -10, -7, -14, 19, -15 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, + -13, 0, -53, 3, -22, 63, 19, 16, 1, -11, 0, -3, 0, -3, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -1, -6, -43, -43, -2, 65, -13, -4, 9, 1, 1, 2, 1, 0, 0, 1 }, + { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1, + -23, 1, -61, -55, 3, -28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 }, + { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4, + -48, -19, -52, -46, 11, -12, 5, -14, 0, -10, 0, 0, -1, -2, -1, 0 }, + { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0, + 3, -7, -61, -51, -4, -21, -16, -21, -11, 14, -7, 8, 3, -5, 1, 2 }, + { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3, + 56, -11, -6, -67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 }, + { 14, 9, -2, 14, -10, -10, 9, -5, 1, -8, -23, 30, 8, -7, 23, 8, + 2, 10, -1, -27, -17, 57, 22, 4, -5, 2, -12, -6, 2, -7, -4, -9 }, + { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16, + -15, 29, -55, -29, -24, 29, 3, 10, 6, 13, 10, -5, 21, 11, -14, 5 }, + { 4, 2, 26, -6, 10, 11, -23, -10, -27, -20, 3, -24, -11, -10, -13, 25, + -10, 5, -9, -36, -7, 43, 3, -13, 6, 13, -2, 0, 1, 3, -3, -4 }, + { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1, + -12, 12, -26, -64, -15, 29, 37, -7, -3, -12, -5, 14, 8, -8, -10, -2 }, + { 19, -4, -11, -16, 8, 14, 5, 19, 3, 22, -11, -21, -1, -6, -11, 11, + 10, -24, -23, -40, -8, 20, 17, 5, 13, -6, 3, 14, -20, -8, 3, 28 }, + { 2, -12, 10, -14, -18, 26, -22, 4, -2, 5, -21, 8, 3, 1, 19, 0, + -12, 24, -14, -40, 15, 29, -15, 6, 15, 1, -19, 2, 4, 7, -12, -3 }, + { 0, 17, 13, 7, -5, -11, 2, -19, 3, 38, -21, -3, -6, -4, 7, 1, + 1, -5, -40, -10, -2, 35, 8, 8, -10, -8, -9, 33, 4, 4, 0, -2 }, + { -2, -12, 7, 29, -24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2, + -37, 15, -22, -40, -11, 33, 10, -1, 8, 10, 6, 8, 9, 0, -12, 2 }, + { 15, -8, -9, -2, 7, -17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11, + -15, 14, -13, -48, 5, 18, 0, -9, -36, -11, 2, 4, 5, 5, -15, -12 }, + { -12, 0, 3, 4, 7, -5, 5, -14, -24, -18, -6, -15, -8, -20, 1, -7, + -33, -28, -40, -38, -18, -10, -5, 17, -12, 4, 3, -5, 5, -13, 4, -7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, + 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, + -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, + 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, + { -8, 2, 1, 22, -31, -6, -25, -3, -3, 1, -15, -11, -2, -3, 4, -13, + -9, 15, -18, 37, -7, -37, 12, -13, -11, -25, -10, -11, -22, 7, 16, 7 }, + { 14, 10, 4, -10, -1, -5, -7, -3, 16, 13, -5, -15, 5, 11, -1, 8, + -27, 7, -12, 49, 17, -22, 9, -2, -9, -1, 2, -15, -1, 41, -18, -17 }, + { -4, -9, -15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17, -19, -7, + 36, -9, -38, 17, 1, -48, 11, -18, -13, -2, -8, 4, -10, -5, 21, 11 }, + { 15, -13, 4, 2, 1, -5, -2, 1, -10, 7, -1, 3, -6, 0, 11, -11, + 8, 20, -17, 51, -17, -41, 2, 15, 4, 8, -2, 16, -32, -1, 17, 6 }, + { -8, 8, -18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8, + 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7, -11, 2 }, + { -8, -7, 9, -10, -13, 6, -11, -14, 13, 25, -26, 5, 2, -5, -5, 5, + -8, 4, 0, 33, 12, -38, -4, 6, 13, 6, 25, 34, -1, 25, -19, -5 }, + { 18, 3, -17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8, -35, 15, + 24, 43, -5, 51, 5, -12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 10, 24, 76, -2, -22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 }, + { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0, + 24, 13, 32, 70, 26, 5, -21, -9, -6, -15, 2, -2, 2, 4, 1, 1 }, + { 5, -4, -11, 4, -4, 22, 10, -2, 13, -11, -4, -21, -17, 0, -7, 4, + 10, -34, 11, 52, 2, -46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 }, + { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1, + -8, 9, -1, 64, -13, -61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 }, + { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1, + 10, -2, -31, 79, -10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 }, + { 3, 12, 10, 26, -19, 10, -9, 6, -4, -15, 10, 3, -16, 6, 11, -19, + 3, 10, 18, 44, 5, -30, 5, -9, 21, 4, 20, 10, 14, -25, 8, -17 }, + { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2, + 8, -8, 13, 69, 26, -19, -25, -17, 16, 6, -12, 22, 2, -6, 9, 5 }, + { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, + -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, + { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, + -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, + { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, + -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, + { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, + 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, + { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, + 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, + { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, + -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, + 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, + { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, + -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, + { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, + -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, + { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, + -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, + { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, + 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, + { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, + 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, + { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, + -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + -1, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, + 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, + { 16, -18, 7, -4, 31, -15, -9, -13, 20, -12, -6, 0, 12, -6, -2, 4, + 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 }, + { 38, -5, -13, -4, 8, -15, 11, 1, 2, -4, -1, 9, 13, 4, -12, -7, + 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1, -11, -2 }, + { 47, -22, 9, -26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4, + 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 }, + { 14, -16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7, -19, -14, -17, + -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 }, + { 29, -11, 5, -3, 4, 11, 4, -10, 1, -22, -3, -10, 5, 4, 2, 8, + -2, -7, -12, -12, -8, -3, -18, -2, -9, -5, -1, -3, 2, -14, -14, 7 }, + { 28, -12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4, + 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 }, + { 31, -18, -22, 8, 15, -5, -10, -15, 1, 10, 6, 7, 6, -8, 2, -1, + 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7, -10, -2, 4, -3, -4 }, + { 53, -30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1, + 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 }, + { 27, -18, -3, -2, 4, -8, 3, -2, -11, 2, 10, -8, -8, -4, 0, -2, + 8, 0, 9, 0, -16, 11, 1, -6, 13, -3, -10, -13, -15, 25, 1, 0 }, + { 35, -5, -1, -8, 23, 11, -14, -3, 2, -2, 8, -6, 17, -2, 7, 0, + -2, 10, -17, 13, -2, -2, 11, 11, -14, 2, -2, -3, -8, -1, -12, -5 }, + { 29, -9, 7, 3, 2, -10, 0, 3, 9, 0, -3, 5, 1, -10, 10, -5, + 3, 6, -20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 }, + { 15, -16, 18, -19, 16, -15, 17, -18, 13, -16, 17, -14, 15, -9, 13, -17, + 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 }, + { 21, -10, 7, -2, 12, -7, 13, -17, 11, -2, 20, 3, 5, -11, -6, -6, + -15, 0, -9, 5, -11, 7, -1, 7, 8, -10, -9, 3, -5, 9, -8, -2 }, + { 23, -22, 15, -5, 16, -4, -3, -12, 9, 3, -1, -2, -8, 2, -2, -16, + 3, 4, -2, -6, -7, 12, -8, 2, -14, 2, -7, 11, -2, 6, -4, -1 }, + { 34, -17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1, -15, + 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 }, + { 18, -18, 2, -2, 10, 1, 18, -23, -3, -10, 0, 4, 20, -19, -3, -4, + 2, 8, 6, 1, -3, 1, 1, 3, 5, -1, -11, 3, -7, 5, -1, 1 }, + { 15, -14, 2, 3, 10, -8, 12, -13, 13, -15, 6, -8, -4, -10, 14, -9, + 24, 2, -7, -18, 13, -11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 }, + { 20, -12, 13, 5, -1, -10, 15, -6, 8, -1, -3, -10, 17, 0, -6, -19, + 2, -1, 8, -3, -16, 0, -3, 2, -2, 0, 8, -9, 0, 1, -10, -9 }, + { 32, 0, -9, -5, -1, 5, 13, -11, 8, 3, 11, -11, 0, -8, -2, -14, + 7, 10, 6, -5, 1, 10, 2, 12, -10, 4, 4, 6, 4, 0, -7, -10 }, + { 16, -14, 10, -7, 11, -11, 11, -11, 18, -13, 8, -15, 16, -11, 13, -9, + 8, -7, 12, -11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 }, + { 24, -27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9, -11, -13, -5, + 10, 0, -13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3, -17, -2 }, + { 23, -19, 15, 1, -10, -18, -12, -6, 8, -3, 12, 0, -12, -10, -4, -4, + 8, -10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 }, + { 25, -12, 4, 2, 24, -3, 3, -6, 14, 11, 0, -21, -3, -3, 1, -8, + 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 }, + { 24, -8, -6, 7, 16, -12, 13, -1, 11, -21, 2, -6, 3, -12, 0, 9, + 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 }, + { 25, -21, 13, 14, 13, -18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12, + 7, 3, 5, -5, 2, -2, 3, -10, 2, -9, -15, 6, 1, 7, -5, 1 }, + { 23, -16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4, + -6, 2, 9, -1, 14, 12, -6, -1, -17, -2, -4, -9, -7, -6, -8, 3 }, + { 50, -8, 5, 2, -11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0, + 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 }, + { 28, -17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19, -27, 5, -12, + 7, -14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 }, + { 22, -19, -6, -6, 3, -22, 3, 5, 20, -8, -14, -5, 1, 1, 20, 2, + 16, 6, 3, 14, 4, 3, 5, 1, 5, -7, -10, -6, 3, -6, 1, -14 }, + { 29, -14, -8, 13, 8, -10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11, + -7, 1, 2, -9, -11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1, -11 }, + { 18, -9, 4, 1, 7, -29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8, + -13, 5, 4, -13, -4, 2, -5, -7, -6, 14, -10, -34, -3, 1, -3, -13 }, + { 38, -9, 24, 8, 11, 4, -6, -11, -2, -12, 1, 1, -11, -8, -5, -2, + -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 }, + { -20, 11, -4, 24, -11, 1, 15, 4, 0, -28, -10, -1, 10, 10, -6, 5, + -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 }, + { -9, 10, -23, 27, -4, -17, 20, -6, 14, -17, 5, -1, 5, -9, -7, 5, + -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 }, + { -10, 19, 4, 9, 1, -16, 17, -2, 9, -29, -16, -11, -4, 7, -5, 4, + -1, -3, 3, 2, 3, -4, 5, -12, -2, 6, 5, -4, 4, 1, 4, 10 }, + { -20, 10, -24, 14, -5, 11, 9, 0, 16, -20, 10, -5, -6, -6, -1, 2, + -4, 5, -16, 8, -2, 5, 5, -11, 9, -11, 4, -11, -1, -1, 4, 3 }, + { -9, 11, 3, 19, 24, 4, 5, -14, 30, -17, -4, -2, -17, 7, 2, 3, + 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3, -12, -2, 3, -3, 10 }, + { -19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12, + -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4, -20, 0, 10, -9, -3 }, + { -21, 9, 20, 12, 0, -3, 5, -9, 15, -13, 5, -5, -6, 24, 2, 9, + -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 }, + { -18, 16, 13, 15, 2, -10, 14, -11, 4, -11, 5, 12, 12, 20, 8, 30, + 2, 11, -9, 7, 0, -3, -16, -5, -6, 5, -4, -21, 0, 5, 6, 1 }, + { -26, 8, -13, 9, 6, -10, 2, -11, 7, -4, 6, -19, -11, -6, -12, 16, + 0, 5, -7, 8, 5, 6, 17, -9, 10, -10, 5, -3, -11, 2, 4, 10 }, + { -11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14, -27, 5, -7, -4, -5, + -10, 11, 1, 15, 1, 1, -6, -5, 10, -22, -7, -7, -15, 13, -4, 5 }, + { -17, 14, -7, 13, 3, 0, 13, -6, 9, -14, -22, -1, 1, 19, 14, -3, + 4, -13, -13, 2, -4, 8, -2, -2, 13, -12, 13, -12, -7, -5, -3, 6 }, + { -17, 17, -1, 33, 6, 3, 9, -16, 3, -14, -8, 6, -17, 8, 3, 13, + 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13, -10, 4, -17, 0, -6 }, + { -20, 7, 7, 21, 1, -3, 7, -3, -2, -12, 9, -7, 2, -3, 14, 1, + -1, -7, 12, -10, 5, -20, 11, -2, 0, -24, -17, 6, 6, -4, 3, -1 }, + { -8, 10, 6, 7, -1, -6, 28, -6, 10, -33, 1, -20, 0, -12, 10, 1, + -6, 8, -3, -1, -10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 }, + { -17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3, + -2, 12, -15, 3, 4, 1, 2, -9, 0, -16, -21, 2, -4, 16, -7, 4 }, + { -15, 20, 8, 17, 5, -14, 15, -11, 21, -11, 13, -13, 2, -15, -13, 1, + -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 }, + { -21, 8, 2, 16, -1, 2, 15, -16, 13, -12, -12, -7, -8, 2, -7, 11, + -8, 5, 2, -7, 16, -4, 1, -7, 3, -15, 6, -5, -8, 2, -8, 5 }, + { -15, 17, -6, 3, -3, 3, 9, -7, 14, -23, 11, 1, -1, 4, 7, 6, + -1, -14, 7, 6, -8, 5, 1, -15, 10, -9, 2, -3, -1, 4, -10, -4 }, + { -10, 18, 3, 11, 1, 4, 14, -14, 7, -4, 15, -10, 10, -11, 10, -4, + 5, -14, 10, 4, 15, -12, 15, -13, 20, -15, 14, -15, 8, -11, 4, -6 }, + { -7, 23, 2, 20, 7, 8, 19, -5, 9, -16, -8, -17, -5, 1, 5, -6, + -8, 1, -6, -4, 10, 6, 6, 2, -11, -4, 0, 2, 4, 7, 9, -4 }, + { -15, 20, -5, 22, 11, -8, 9, -5, 10, -13, -8, 8, 2, -2, -3, 7, + 6, 10, 1, 2, -5, -9, 1, 10, 16, -22, -7, 0, 7, 7, 6, 1 }, + { -26, 19, -5, 3, 5, 25, 18, -5, 9, -14, -8, -6, -2, -6, 2, 3, + -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 }, + { -20, 14, -10, 6, -3, 7, 8, -32, -2, -7, -2, -10, 16, -12, -9, 15, + -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 }, + { -14, 16, 4, 11, -8, 1, 23, -4, 17, -13, -10, 1, 12, 9, 12, -4, + 7, -1, -1, 5, -8, -6, 3, 3, -6, -3, -18, 0, 18, 20, 4, -2 }, + { -33, 19, -10, 30, 15, 2, -3, -1, -4, -14, 7, -7, -1, 7, -8, 9, + -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 }, + { -6, 20, 0, 5, 17, -10, 18, -17, 9, -16, 4, -13, -6, 2, -14, 14, + -28, 9, -12, 25, -4, 7, 7, -8, 6, -6, -2, -10, 2, -11, -1, 2 }, + { -12, 14, 12, 52, -3, 5, -5, 4, 8, -13, 2, -5, -4, 2, -2, -1, + -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 }, + { -13, 6, 9, 24, 0, 8, 14, -15, 18, -9, -11, -8, 3, 15, -2, -4, + -9, 4, -3, 12, 14, -13, 11, -4, 2, -4, 0, -6, -6, -6, -14, -1 }, + { -10, 28, 3, 12, 9, 3, 11, -28, 6, -11, -7, 4, 0, 7, 8, -9, + 0, -6, 0, -16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3, -10, 6 }, + { -11, 14, -2, 19, -1, -1, 7, 9, -2, -27, 10, -14, 15, -4, 12, -4, + 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3, -11, 5, -9, 3, -8 }, + { -18, 7, 13, 16, -4, 3, 9, -10, 10, -10, -3, -22, -4, -12, 3, -16, + 0, -3, -16, 8, -11, 1, 10, -7, 15, 3, 0, -1, -13, 8, 1, 6 }, + { -20, 10, -10, 10, 8, -1, 6, 0, 16, -12, 9, -10, -1, -5, -4, -13, + 13, 16, -8, 12, -2, 14, 18, 13, 0, -16, 2, -5, -5, -5, -4, 3 }, + { -14, 5, -7, -17, 5, -13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4, + -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 }, + { -19, 3, -24, -28, -9, -7, 19, 3, 2, 19, 7, 5, -13, 8, -15, -17, + 3, -11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 }, + { -17, 18, -30, -20, -2, -3, 1, 15, -1, -11, 6, -4, 11, 11, -4, -5, + -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 }, + { -6, 1, -30, -25, -1, -8, -2, -9, -17, 16, 3, -1, -2, -9, -6, -7, + -3, 12, 6, -4, -10, 0, 10, -8, -6, -5, -3, -11, -4, 0, -1, -3 }, + { -1, -1, -34, -28, 1, -10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7, + -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 }, + { -11, 14, 1, -31, -7, -24, 9, 7, 6, 5, -13, 1, -1, 3, 4, -1, + -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 }, + { -25, 8, -11, -18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4, + -4, 5, 6, 8, -7, 6, 1, -11, -15, -13, 9, -4, -14, 10, 12, 7 }, + { -20, 11, -15, -25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7, + 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7, -17, -6, -11, 6 }, + { -11, 18, -5, -20, -15, -3, 9, 11, -20, 12, 5, 5, 11, -3, 7, 1, + 10, -6, -3, -3, 3, 3, 14, -7, 10, -17, 9, -11, -2, -6, 7, -12 }, + { -20, 8, -14, -17, -9, -13, -3, 0, -27, -14, -3, -14, 4, 3, 6, -6, + 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8, -11 }, + { -9, 14, 2, -37, -7, 13, 6, -11, -6, 9, 18, -11, -6, 2, 12, 4, + -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 }, + { -29, 8, -1, -13, -2, 8, 23, 2, -10, 7, 13, -6, -5, 11, 13, 0, + -10, -13, 11, -12, -10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 }, + { -18, 6, -10, -55, -4, -11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6, + 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 }, + { -14, 5, 3, -21, -8, -16, -4, -2, -11, 27, 15, -20, 3, 0, 1, 1, + 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2, -11, -4, -3, 7 }, + { -17, -1, -9, -17, -8, -18, 12, -13, -9, 13, -3, 3, 3, -3, 1, -2, + 0, 16, -9, 6, 12, 9, 5, 11, 2, -15, 1, -4, -16, 7, -4, -12 }, + { -18, 8, -6, -11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15, + 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 }, + { -10, 7, -18, -29, 3, 12, 12, 9, 11, 4, -1, -15, 1, -1, 8, -2, + -2, 10, -15, -1, 0, 6, 12, -6, -1, 10, -6, -3, -11, -4, 9, -6 }, + { -14, 14, -9, -21, -12, -2, -1, -7, -5, -10, 5, -8, 0, 6, 9, -11, + 11, -3, -5, 3, 8, 15, -2, -4, -22, 4, -6, 12, 2, 13, 6, -7 }, + { -12, 11, -5, -29, -25, 4, 12, -13, -11, -7, 4, 2, 2, -5, 5, 8, + 7, -5, -5, 6, 3, -10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 }, + { -15, 11, -5, -16, 0, -13, 26, -23, -6, -3, 5, -2, -2, 21, -6, -3, + -5, -1, 6, -1, 0, -13, 2, -3, -9, -1, -4, -3, 5, -4, 12, -16 }, + { -9, 9, -1, -17, -3, -6, 12, 6, -18, -2, 11, -14, -6, 3, 14, -12, + -11, -5, 14, 2, 5, -8, -4, -11, 2, -5, 16, 6, -7, -4, 8, 13 }, + { -13, 5, 3, -28, -14, 0, 6, 23, 5, 4, -1, -17, 1, -3, 0, 0, + 5, 4, 0, -18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 }, + { -15, 4, -13, -16, -3, -12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14, + 9, 16, 4, 1, -12, -3, 4, -7, -15, -7, -10, -14, -6, -8, -1, -6 }, + { -7, 10, -5, -10, -3, -13, 16, -1, -12, 7, -3, -12, 2, 13, 13, 2, + 17, 15, -13, 1, -5, -2, 3, -1, 1, -3, 6, -3, -12, -16, 7, -7 }, + { -11, -5, -12, -30, -6, -22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6, + -2, 0, -22, -2, -9, 2, -13, 8, 6, -8, 4, -7, -1, -6, 4, 6 }, + { -14, 5, 1, -27, -4, 2, 1, 14, -11, -7, -8, -4, 1, 8, 0, -6, + -13, 11, -12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 }, + { -10, 10, -25, -13, -20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2, + 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 }, + { -9, 15, -18, -17, 4, -11, 6, 7, -12, 8, -1, -11, 2, 3, 7, 16, + -3, -9, 7, -12, 23, 0, 6, 7, -14, -9, 8, 1, -2, 6, -2, -1 }, + { -6, 9, -16, -26, -14, -11, 9, -6, 5, -2, 13, 17, 21, 7, 18, -19, + 6, -23, -2, -15, -2, 2, -10, -8, 2, 1, -2, 4, -3, -4, -5, -4 }, + { 0, 6, -5, -28, -17, -32, 2, -10, 11, 3, -5, 9, 10, 3, 11, 11, + -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 }, + { 0, -8, -18, -34, -9, -7, -4, -11, 10, 15, 11, -1, -8, 15, 6, -13, + 9, 2, -4, -12, 0, -1, 19, 12, 6, 5, 0, -3, -10, -12, 3, -5 }, + { -10, 6, -9, -17, -12, -11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2, + -6, 3, -12, -1, 0, 1, -5, -22, -2, -12, 0, 6, 17, 5, 5, 6 }, + { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2, -29, 11, + 5, -13, -73, 24, 12, 4, -14, -10, 5, 1, 0, -11, -7, -7, 7, 3 }, + { 10, -3, -1, -3, 4, -11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7, + 21, 17, -54, 47, -14, -10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 }, + { -12, 4, -16, -12, 5, -9, -4, 19, -7, -22, -22, -17, 3, 0, -6, 8, + 23, -4, -55, -28, 2, -26, 2, 1, 4, 0, -13, 6, 0, 10, -7, -11 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, + 35, -1, -67, -35, -24, -24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, + 41, -4, -73, -15, 18, 4, 17, 8, -1, -16, -1, -2, 1, 0, 0, 0 }, + { -4, -4, 4, 6, -1, 2, -16, -10, -15, -10, 21, -2, -6, -2, 14, -7, + 10, -5, -55, 34, -12, 11, -13, -2, 2, 28, -26, 0, 7, 4, 21, -7 }, + { 2, 1, 15, -22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6, -15, -7, + 23, 10, -60, 8, -4, 29, -22, 2, -13, 9, -10, 12, -1, -3, 4, 7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5, + -21, -11, -60, -27, -17, -39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 }, + { 2, -5, 9, -17, -1, 2, -3, -6, 8, 12, 7, -6, -33, -11, -14, -40, + 10, 36, -46, 0, -19, 5, 0, -10, 3, 12, -6, -8, 6, -12, -7, 1 }, + { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0, + 4, -2, -87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 }, + { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, + 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, + { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, + -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, + { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, + -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, + { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, + 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, + { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, + -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, + 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, + { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, + 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, + { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, + -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, + { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, + 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, + -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, + -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, + 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, + { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, + -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, + { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, + -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, + { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, + 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, + { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, + -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, + 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, + { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, + 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, + { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, + -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, + { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, + 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, + -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, + -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5, + 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 }, + { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7, + -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4, -12, -11 }, + { 15, 24, -14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5, + 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 }, + { 9, 36, -9, -8, 7, 7, 4, 3, -1, -16, -2, 7, -5, -6, 6, 12, + -11, -12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 }, + { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2, -10, -5, 2, + -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 }, + { 16, 27, -1, 0, -14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1, + -1, -19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6, -14, 14, -13, -15 }, + { 12, 23, -14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7, + -3, 0, 2, 8, -13, 7, 13, -6, -4, 6, -13, -16, 14, 11, -7, 5 }, + { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3, -12, 20, 8, 9, + 8, 23, 8, -13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 }, + { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4, + -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 }, + { 24, 21, 1, -11, -10, 17, -14, 14, 6, -1, -6, -1, 0, -13, -1, -12, + -2, -5, 6, -4, -12, 14, 5, -2, -8, -8, 15, -7, -30, -12, 4, 0 }, + { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10, -28, 10, -17, + -8, 1, 2, -7, -1, -6, -15, -1, 4, 5, -7, 9, 0, -5, -4, 4 }, + { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12, -11, 7, 11, 13, 2, + 0, 5, 9, -10, 16, 3, -3, 5, -9, -23, 2, -2, -1, 5, 2, 11 }, + { 35, 24, -20, 2, 4, -1, 5, 14, -10, -9, 8, -7, 0, 5, -7, -7, + 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 }, + { 9, 35, -1, 2, -1, -19, -3, 12, -1, 8, 8, -13, -1, -2, 2, 5, + -8, -1, 13, -2, 11, 1, 0, -10, 0, -3, -7, 2, 1, -12, 3, 12 }, + { 20, 27, -12, -12, 7, 4, -1, -13, -1, -9, 2, 13, -11, 5, 7, -9, + 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 }, + { 8, 37, -20, -5, 0, -21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2, + 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 }, + { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3, -17, 10, 5, + 5, -6, -6, 6, -10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 }, + { 14, 29, -20, -4, -3, 1, -5, -1, 2, 12, -10, -3, 4, -18, 4, 14, + -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2, -14, -3, 4, -4, -7 }, + { 23, 23, -23, -11, 27, 4, 4, -1, 7, 0, -5, 9, 2, -11, 3, 7, + -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 }, + { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0, -12, 9, -1, 0, + -17, -9, 30, -5, -15, -16, -13, 0, 10, -11, -7, -3, -1, 0, -11, -2 }, + { 12, 32, -4, -5, 10, 19, -10, 4, -12, 5, -6, 9, -12, -6, -6, -8, + 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 }, + { 46, 42, -3, -14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1, + 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 }, + { 9, 33, -13, 4, -11, 3, -8, 22, 12, -2, 4, 0, -16, 5, 4, -1, + 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 }, + { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1, + 8, 7, -6, -13, -10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1, -16 }, + { 9, 28, -11, -10, 9, -10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8, + -7, 2, -15, -23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 }, + { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16, + 0, 0, -7, -2, -13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 }, + { 11, 37, 7, -23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8, + -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 }, + { 21, 33, 7, 20, 21, -10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4, + 10, 2, -2, -2, 0, -10, -6, -2, 0, -5, 3, -11, 3, -9, -3, 1 }, + { 6, 30, -15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6, + 8, 2, -2, 4, -2, 5, 11, -21, 3, -10, 16, -11, 24, 10, 14, -6 }, + { 15, 36, -3, -9, -20, 12, 0, -7, -18, -4, -8, -9, 9, -7, -3, -1, + 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 }, + { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3, + 3, -19, 1, 5, 4, -2, -6, -5, -10, -11, -8, -2, 2, -5, -8, -7 }, + { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10, -11, -4, -13, -12, -6, -4, + 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 }, + { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6, -13, -14, 8, -1, 1, 2, + -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 }, + { 0, 6, 0, 0, 4, 13, -7, -16, -6, 15, -14, -21, -9, -10, -10, -6, + -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6, -10, -7, -18, 1, 4 }, + { -1, 3, 10, 1, -1, 15, 4, -7, -16, 3, 0, -22, 10, 2, -3, -2, + 13, 5, -8, 16, -5, 4, 0, -11, -10, -22, 0, -4, -17, 5, 2, 1 }, + { 12, 8, -4, -9, 14, 40, -21, 0, 1, -15, -10, -12, 12, 6, -10, 2, + 8, 6, -12, -10, -11, 1, 0, -11, 2, 1, 13, 0, 6, 3, 8, 4 }, + { -10, 3, 5, -4, -3, 3, 0, -9, 2, 8, -22, -23, 17, 8, -17, -3, + 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1, -10, 0, -2 }, + { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2, -16, -15, 12, 21, -7, -4, + 7, -7, -11, -15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 }, + { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13, -14, -20, -4, 11, 8, -4, + -1, 2, 0, -7, 5, -17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 }, + { -2, 6, 2, 8, -2, 5, -4, -2, -10, 3, -45, -30, -3, -3, -12, -4, + -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 }, + { -3, 14, -16, -10, 10, 0, -2, -40, -9, 12, 2, -19, 15, -4, 4, 3, + 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 }, + { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21, -10, -26, 7, 2, -9, -7, + -3, -16, 8, 5, 5, -6, 10, 4, -14, -6, 5, 3, -2, -2, -4, 1 }, + { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13, -16, -18, 20, 6, -5, 0, + -3, 2, 8, 4, -19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7, -11 }, + { 2, 5, 16, -4, 19, 15, 4, 0, -11, 7, -10, -10, -16, 18, -11, -12, + -9, -4, 7, -4, -4, -17, 1, 1, -8, -3, -3, 5, -2, -6, -11, -5 }, + { 2, 12, 0, -9, -10, 14, 6, 2, -3, 2, -12, -28, 12, 1, -1, 2, + 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3, -12, 4, -17, -5 }, + { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6, -24, 23, -9, -15, 13, + -7, -9, -15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9, -10 }, + { 1, 5, 11, 3, 6, 12, -3, 8, -21, 5, -7, -20, 12, -2, -9, -3, + 17, -7, -8, -9, -14, 3, -13, 18, -8, 9, 2, -8, 4, -8, -5, -2 }, + { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1, -39, -6, 13, -13, 0, + -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0, -13 }, + { 2, 8, 5, -12, -13, 22, 8, -16, 11, 5, -2, -32, -2, -4, 11, 5, + 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 }, + { 13, 9, 5, -4, 9, 18, -11, 2, -1, 15, -10, -19, -2, 14, 0, -10, + 1, 1, -18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9, -13, -3, -2 }, + { -13, 11, 11, -9, -10, 13, -3, -18, 2, 10, 5, -21, 6, 15, -11, -21, + 3, 14, 0, -12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 }, + { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6, -26, 2, 12, -3, -5, + 12, -2, 1, 8, -7, -17, -19, 5, 10, 7, -3, 2, -3, 0, 5, 0 }, + { 5, 0, 3, -3, -9, 5, -15, -5, -5, 17, -5, -31, 0, 13, 13, 5, + -1, -6, -14, 7, -8, 9, -14, -2, -16, -4, -4, -6, 6, -6, -10, 6 }, + { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8, -32, -1, -4, 0, 3, + -10, 7, 10, -10, 4, -1, 6, 2, -16, -9, 4, 3, 13, -23, -3, -4 }, + { 4, 11, -4, -9, 4, 11, -12, -12, -12, 6, 1, -28, -3, 14, 18, -2, + -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2, -13 }, + { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36, -10, -22, 3, 23, -3, -10, + -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 }, + { -1, 1, 13, 1, -6, -1, -6, -9, -18, 17, -5, -37, -1, -1, -6, -4, + 1, -6, -15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 }, + { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7, -16, -5, 23, -14, -13, + 8, -15, 11, 10, -11, -13, -33, -5, -2, 1, 6, 8, 0, -13, -9, 5 }, + { 11, 7, -2, -8, 9, 11, 25, -14, 7, 3, -1, -33, 14, 8, -6, -19, + 3, 3, 2, -1, -3, -1, -2, -10, -3, 1, 2, 1, 4, 2, -3, 4 }, + { -2, 8, 4, -2, 9, 13, -4, -2, -15, -3, 19, -37, 9, 25, -9, 2, + -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 }, + { 10, 13, -1, -15, 4, 6, -18, -4, 25, 1, -23, -17, 15, 13, -8, -8, + 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 }, + { 1, 3, 9, -5, 27, 15, -9, -31, -1, 23, -2, -9, 1, 8, -1, -7, + -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 }, + { -8, 7, 3, -6, 8, 3, -11, -2, 36, 14, 1, -30, 6, 10, -12, -6, + -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 }, + { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6, -25, 11, -6, -9, -11, + -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 }, + { -22, -21, -9, -19, -5, -7, -12, -15, -8, 9, -19, 14, -7, -4, 5, -8, + -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 }, + { -32, -13, 3, -24, 3, -8, 4, 1, -10, 14, -15, 0, 4, 6, -1, 6, + 7, -1, 6, 4, -3, -17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 }, + { -32, -11, 7, -8, -12, 13, -5, -22, -4, 12, -16, 2, 0, 4, 0, 1, + 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 }, + { -44, -33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1, + 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 }, + { -30, -18, -24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7, + 5, 7, -11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 }, + { -22, -20, -13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1, + 2, -3, 6, -19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 }, + { -27, -8, -1, 3, -1, -11, 24, 4, -1, 1, -8, 8, 5, -11, 15, -3, + -15, -1, -1, -13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 }, + { -33, -16, -1, -8, 10, -23, 6, 13, -1, -3, -9, 0, 5, -7, -5, -12, + -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 }, + { -22, -17, 11, -3, 3, 1, -1, -5, 17, 2, -15, -2, 10, -9, 6, 14, + -16, -12, 20, -1, -7, 6, -3, -12, 1, 10, -10, -1, 7, -3, -1, 10 }, + { -28, -13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10, -10, -3, 7, 2, + 4, 19, -1, -1, 10, 5, -8, 1, 11, -15, -4, -3, -5, 4, -13, 3 }, + { -22, -13, 42, -20, 5, -13, 7, -11, 1, 1, -1, 1, 6, 3, 6, -11, + 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 }, + { -26, -15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3, -10, 7, -8, -12, + -5, 12, -9, 3, -2, -3, 18, 1, -12, -15, -4, 5, -3, 0, 12, 7 }, + { -26, -16, 5, 6, 14, -3, 15, 6, 1, -7, -13, 16, -15, 5, 11, -2, + 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 }, + { -31, -17, -8, -30, 4, 14, 6, -6, 6, -11, 0, 3, -4, 0, 0, -4, + 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 }, + { -61, -10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2, + -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 }, + { -28, -13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5, + -3, -2, -2, -12, -14, -9, -11, -15, -12, -5, -4, -12, 3, -3, 0, -5 }, + { -41, 0, 12, -24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9, + 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 }, + { -26, -19, -2, -15, 4, -14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5, + -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2, -10, 0 }, + { -29, -18, 9, -4, 1, -5, -14, -12, 5, -10, -5, 4, -5, 0, -1, -1, + 4, -5, 7, -16, -11, 2, 7, -15, 2, -4, 6, -4, -6, 7, -3, 7 }, + { -27, -16, 9, -14, 3, -8, 9, 0, 7, -4, -3, -7, 0, -10, -1, 2, + 1, -2, 15, -10, 14, 7, 6, 17, 3, -4, 3, -10, 8, -8, 3, 11 }, + { -21, -20, -8, -8, 4, 5, -3, -2, 0, -5, 14, -10, 11, -4, 13, 0, + 5, -11, 19, -18, 18, 3, -5, -3, -4, -8, 11, -10, 10, 3, 4, -9 }, + { -35, -15, 13, -12, 4, 0, -2, -4, -12, -3, -8, -24, -7, 1, 7, 8, + -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 }, + { -19, -14, 13, -10, 9, -1, 1, 3, -12, 5, -16, 7, 13, 9, 4, -4, + 6, -5, 4, 9, -3, 17, -4, 12, -11, -6, -5, -6, 13, 2, 7, -9 }, + { -34, -8, -4, 1, 2, -1, 3, 6, -20, -11, 8, -1, 4, 2, -9, 4, + -4, -5, 16, 10, -4, 14, -13, 1, -6, 0, 2, -10, 0, -3, -3, 7 }, + { -36, -10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15, -11, + 0, 2, 3, -1, 4, 0, 8, -1, 0, 18, -11, -5, 15, -5, 13, -12 }, + { -22, -13, 14, -20, 15, 25, 16, 10, 8, -2, -10, -5, -1, -8, 11, 8, + -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 }, + { -31, -22, 7, 6, -2, 5, -20, 14, -6, 7, 0, 14, 3, -7, 3, -6, + -2, 1, -3, -5, 1, -10, 1, -24, 6, -2, 3, -7, 1, -7, 8, 7 }, + { -25, -20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8, + 3, 5, 6, 5, -10, 10, -4, -15, -15, -2, -9, 2, 18, 1, 8, 12 }, + { -24, -19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6, + -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8, -11, 8, 4, 2 }, + { -26, -20, -12, -12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2, + 9, 22, 13, 4, -4, -1, -2, -14, 5, 15, -8, -5, -7, -11, -14, -6 }, + { -21, -18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3, + 1, 3, -5, -2, 2, 4, 0, -1, 10, 2, -19, -8, 8, 30, -7, 8 }, + { -25, -6, 26, 4, -8, 4, -2, 21, 5, -4, -16, 5, 13, 4, -10, -1, + -6, -2, 2, -10, -13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 }, + { 0, -1, -2, 19, -12, -48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2, + -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 }, + { -11, -8, -28, 18, 16, -24, -8, 19, 4, 8, -12, 9, -4, -2, 4, -7, + 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1, -16 }, + { -9, -5, -26, 7, -3, -37, -16, -2, 2, -7, 4, -13, 0, -4, -6, -5, + -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 }, + { 2, 9, -18, 7, 29, -24, -1, 7, 14, 10, 3, -3, -2, -5, 6, -10, + -6, -3, -8, 0, 5, 1, 4, 3, -12, 2, 6, 1, 3, 4, 1, -3 }, + { -20, 2, 8, 20, -9, -24, -4, 18, 3, 11, -1, -11, 6, 9, -1, -3, + 1, -1, -15, 3, 15, 9, 3, 2, -13, 2, -8, 8, 1, -1, 1, -8 }, + { -12, 5, -11, 6, 19, -26, -17, -6, 4, 14, 6, -8, 9, 5, -6, -5, + 2, -1, 20, 1, -11, -10, -18, 20, -7, 0, -3, 4, 2, 0, 10, 4 }, + { -15, 1, -2, 13, -8, -21, -22, 4, 4, 3, 3, -7, -31, 4, -10, -14, + 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 }, + { -13, -10, -9, 12, 19, -16, -3, -2, 9, 2, 11, -29, -1, 9, 4, -3, + 1, -10, -10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 }, + { -17, -1, -5, 19, 12, -9, -21, -5, 2, 12, -7, -7, -3, 8, 7, -2, + 6, -9, -9, 1, -4, 1, 1, 3, -14, 2, -8, 0, 10, 1, -12, -6 }, + { -13, -5, 8, 15, 0, -20, -2, 20, 8, -8, 8, -19, 12, 10, 2, -11, + 0, 12, 1, -11, 0, -11, -15, 5, -11, 2, 4, -4, -11, 5, -4, -5 }, + { 3, -11, -7, 8, 0, -17, -26, 15, 19, -7, 10, -9, -5, -5, 14, -25, + 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 }, + { -12, 5, 5, 9, 14, -18, -19, 4, 2, 16, 14, -21, -15, -9, -1, 16, + 12, -11, -10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 }, + { -10, -5, -1, 8, 7, -23, -10, 14, 6, 11, 10, -16, -3, 16, 6, 0, + 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2, -10, 3, 0 }, + { -2, -14, 2, 16, 15, -17, -17, 6, 19, 4, -10, -15, -1, 15, 11, -14, + -8, 5, 8, 8, -2, -8, -11, 10, 10, -8, -14, 2, 13, 4, -2, -12 }, + { -10, 3, 6, 4, 19, -23, -19, 1, 4, -9, -30, 3, -6, 18, 0, 2, + 0, -11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 }, + { 9, 5, -2, 21, 20, -33, -13, 7, -10, 8, 8, -15, -6, -4, 1, 5, + 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 }, + { -9, -3, 3, 15, -3, -30, -7, -7, -25, 6, 2, -6, 1, 19, 1, -12, + 1, -8, -13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 }, + { -6, -12, -17, 25, 22, -13, -10, 9, 2, 11, -7, -16, 4, 6, 1, 0, + 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 }, + { -1, 0, -10, 8, 8, -27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0, + 6, 10, 6, 4, 2, -7, 9, -18, 3, 3, 3, -10, 17, 10, 9, -6 }, + { -3, -12, -6, 11, 20, -32, 5, 21, 3, -4, -9, 2, -10, 1, 7, -4, + 5, 0, 0, -1, -8, -9, -7, 4, -10, 5, 0, 2, -5, 4, 9, 1 }, + { -5, -1, -5, 1, 2, -19, -13, 1, 6, 12, 2, -16, -17, 11, 10, 13, + 16, -12, -11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5, -11, 3, -14 }, + { -19, 5, 10, 11, 2, -23, -9, 16, -2, 7, 0, -11, -7, 10, 6, -7, + 26, -15, -4, 8, 6, -4, 7, -9, -15, 1, 8, -4, 4, 2, -12, 16 }, + { -11, 1, 11, -4, 1, -31, -13, -1, 8, 5, 4, -2, 0, 13, 7, -17, + 7, -10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 }, + { -3, 1, 10, -1, 0, -15, -22, 4, 40, -11, -4, -3, -14, 9, 11, -1, + 9, -1, -6, 6, 3, -6, 0, 0, -12, 7, -2, 0, 9, 3, 1, 3 }, + { -1, -1, -1, 14, 8, -24, -14, -8, 5, 8, 5, -12, -17, 8, 2, 7, + 10, -8, 0, 4, -6, -6, -10, 8, 4, -12, 3, -9, -12, 5, 4, -3 }, + { -5, 1, -11, 8, 9, -24, 0, 2, 2, 14, -12, -13, 1, 6, 7, 0, + 7, -6, 9, 26, 11, -14, 8, 10, 1, 9, 0, 11, -2, 6, 2, -10 }, + { -13, 1, 4, 34, 19, -17, -15, 0, 3, -2, -7, -1, 0, -3, -3, -1, + 1, -1, -10, 8, 5, 0, -8, 4, -17, 9, -2, 0, 0, 6, 2, -3 }, + { -6, -4, 1, 2, 2, -14, -29, 0, 9, 34, -3, -5, -14, 6, -10, -9, + -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 }, + { -4, 6, 3, 14, 14, -8, -29, 31, 11, 14, -4, -5, -6, 10, 6, -9, + -1, -11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 }, + { -4, -4, -2, 14, 6, -32, -6, -14, 14, -5, -11, 10, -18, -4, 6, -8, + 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2, -10, -6, -17, 3, 17 }, + { -16, 9, 21, 19, 4, -20, -17, 14, 9, 15, -6, -17, -1, 1, 6, -3, + 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 }, + { -7, -5, 3, 19, 1, -20, -9, 14, 21, -7, -18, -9, 26, -7, -17, -7, + 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 }, + { -20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8, -17, 0, 5, + -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 }, + { -35, 17, 6, 1, -9, -1, -16, 3, -20, -13, 8, 7, -4, -7, -4, -20, + 7, 12, -5, 5, -5, -11, 12, -1, 15, -9, -6, 16, -4, -9, -13, 4 }, + { -21, 36, -19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2, + -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 }, + { -12, 33, -4, 1, -12, -9, 0, -13, -1, 2, -8, 4, -10, 6, -16, -7, + -1, -4, -10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 }, + { -14, 32, 5, -7, -15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7, + 4, -10, -10, 10, -1, 2, 0, -2, -11, 5, -3, -4, 2, 2, 7, 4 }, + { -14, 34, 1, 20, -1, -12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7, + -9, -20, -7, -4, -13, 12, 1, 12, 5, -6, 2, -4, 0, -15, 1, 3 }, + { -21, 23, 7, -8, 3, -13, -3, 0, -6, -2, -7, 6, -12, 9, -6, -2, + -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6, -15, 3, -5 }, + { -27, 32, -1, -4, -2, 4, -10, 12, -3, 8, 13, 7, 0, -15, 4, -2, + 3, 5, 7, -4, 9, -12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 }, + { -17, 29, 15, 0, -1, -4, -10, 13, 12, -1, -8, -10, -10, 4, 7, -2, + 6, -5, -13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 }, + { -38, 27, 16, -15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6, + -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 }, + { -33, 40, -4, 2, 1, 0, 0, -10, -14, 0, -7, 4, -1, 3, -2, 5, + 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 }, + { -20, 25, 12, -4, 16, -4, 2, 2, -14, -2, -3, 29, -1, 1, 3, 1, + 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 }, + { -10, 30, 17, 3, -5, -2, 0, -5, -22, 4, 5, 5, -3, -18, -6, 10, + -5, -7, 2, 8, 7, -7, -11, -2, 0, -3, 3, 2, 11, -4, 4, -4 }, + { -11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4, + -3, 10, 13, 14, 5, -5, 1, 1, -10, 2, 15, 4, 9, -1, -5, -3 }, + { -17, 32, 18, -18, -3, -5, 6, 10, 1, -15, -5, 9, 8, -12, -10, -6, + 11, 9, -5, -8, -7, 10, 5, -10, -14, -4, -3, 1, 9, -11, 2, 1 }, + { -13, 28, -11, -1, 2, -16, -2, 7, -24, 0, 3, 6, 3, -1, -8, -7, + -12, 2, 2, -20, 10, 4, 0, -13, -2, -2, 1, 8, -14, 0, 4, 1 }, + { -14, 23, 12, 8, 8, -26, 2, -4, -14, 13, -14, 15, 3, -9, -1, -13, + -10, -2, -10, 6, -16, 12, 8, 0, 9, -10, -7, -4, -4, 7, -8, 8 }, + { -20, 45, 10, -14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5, + -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 }, + { -20, 26, -4, 1, 7, 4, -8, 1, -5, -13, 2, 13, -7, -3, 6, -6, + 22, 0, 5, 11, -4, -11, 8, -9, 2, -2, -4, -2, 2, -13, -4, -8 }, + { -28, 18, 17, 3, -8, -23, -16, -6, 5, -10, 14, 10, 5, -1, -8, 4, + -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 }, + { -12, 32, -6, -16, 18, 12, -16, 0, 7, 13, -4, 5, -8, -1, -3, 4, + 6, -2, -1, -13, 4, -1, 3, 12, -3, -10, 1, 6, 8, -11, -2, 4 }, + { -18, 26, 2, 5, 0, -9, -17, 14, 5, 1, 7, -3, -8, -3, 11, 7, + -5, -12, -8, 7, 0, -7, 2, -12, -9, 13, -11, 9, 6, -11, -5, 11 }, + { -24, 22, -15, -9, 8, 1, -7, -12, -9, 3, 11, 15, 14, -11, 12, -15, + -5, 7, -2, 0, -8, 3, 3, -1, 2, 11, -11, 14, -6, 13, 1, -6 }, + { -20, 28, 18, -4, -6, -5, 12, 14, 2, 10, -13, -6, -8, -6, -13, -1, + -26, 22, -3, -14, 6, 0, 10, -15, -13, -9, 6, -7, 1, -5, -4, -1 }, + { -19, 26, -8, -3, -14, -6, -9, -4, -8, 15, -8, 3, -12, -4, -2, -7, + -5, 3, 13, -3, -4, -25, 4, -1, 5, -12, -1, -13, 5, 2, 0, 6 }, + { -18, 43, 14, -8, 1, -23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3, + -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 }, + { -11, 30, 10, -14, 3, 1, 10, -11, 1, -7, -4, 14, 2, 1, -9, 1, + -11, -2, -7, 5, -11, 1, 3, 14, 1, -16, -8, 3, -5, 7, -4, 4 }, + { -18, 24, 6, 3, 8, 7, -22, -7, -7, 3, -8, 4, 23, 9, 3, -1, + 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 }, + { -15, 38, -7, -1, -11, 2, -17, -24, 24, 8, 7, -4, -5, 2, 2, -7, + 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 }, + { -14, 22, 1, -5, 9, -12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3, + -33, -16, -9, -1, 12, -11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 }, + { -14, 20, 6, 4, -10, -4, -4, -4, 1, -7, 2, 6, 8, -12, 4, 1, + -1, 12, 10, 3, -14, -10, -3, 18, -2, 33, -5, -17, 17, -5, 9, 7 }, + { -12, 23, 13, 0, -11, -8, -11, 12, -5, -9, -16, 11, 6, 4, 12, -5, + 5, -13, 7, -12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11, -12, -3 }, + { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6, -20, -10, 4, 26, + -6, 13, 4, 3, 2, -11, 5, -7, -10, 4, 9, 1, 10, -4, 11, 4 }, + { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3, + -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 }, + { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5, + 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 }, + { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7, -10, -8, -18, + 3, -2, 2, 7, -15, -11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 }, + { 10, -6, 8, 11, 12, 20, 22, -11, -3, 15, -3, 15, -2, -2, 0, 2, + 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 }, + { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2, + 4, -9, -3, -14, -12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 }, + { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3, + -10, -2, -7, 11, -11, -10, 17, -1, 3, -15, 2, 9, -15, -10, 16, 10 }, + { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6, -13, -1, 6, 5, + -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 }, + { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2, + -15, -11, -10, -4, -13, -6, -17, -13, -6, -14, 1, -10, 6, 4, -1, -1 }, + { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3, + -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 }, + { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8, -12, + 9, -10, -7, 1, -1, 19, 0, 2, -8, -11, -10, 9, 6, 11, 0, 3 }, + { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4, + 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 }, + { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3, -10, 7, 6, + -8, -7, 2, -13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 }, + { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5, -14, 8, 0, 9, + 8, -10, 5, -15, -6, -9, 9, -1, 18, -16, 9, -21, -3, -13, -2, 8 }, + { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7, + 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5, -10, 8, 4, -5 }, + { 9, 2, 16, 14, -5, 14, 1, 0, -21, 17, -1, 9, 12, -3, -3, 4, + -4, 14, 10, 3, 0, -10, 7, 4, 4, -11, 2, 4, -1, -3, 9, -1 }, + { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8, -18, -11, -3, + -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 }, + { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4, -16, -2, 14, -2, + 1, 8, 12, 14, 3, -3, 8, 8, 12, -15, 3, -3, 3, -2, 14, 10 }, + { 22, -3, -11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2, + -2, 0, -5, -27, -10, 3, -1, 5, 8, -24, -3, -11, -3, 2, 11, -1 }, + { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14, -10, 1, -12, -10, + -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 }, + { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9, -15, 15, 6, -8, + -10, -13, 5, -8, -20, -13, -6, -11, -1, -3, -6, -4, -1, 0, 13, 15 }, + { -2, -1, 9, 12, 2, 2, 13, 3, -23, 33, 15, 2, -4, -1, 3, 8, + 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 }, + { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1, -12, 3, + -13, -18, 2, -11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 }, + { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5, + 5, -3, -2, -14, 0, -12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 }, + { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15, + 2, 1, 2, -10, -10, 0, 2, -1, 0, 1, -12, -1, 21, 16, 9, -7 }, + { 11, -4, -5, 24, -7, 11, 20, 11, -15, 18, 5, -13, -15, 0, -5, 9, + 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 }, + { 20, 0, -12, -6, 9, 31, 9, 12, 8, 27, 15, 7, -16, 5, -3, -7, + -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 }, + { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4, + 4, -6, 0, -4, -4, -3, 3, 6, 3, -13, -8, 5, -3, -7, 8, 5 }, + { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1, + 2, 0, -15, -9, -16, -2, 8, -17, -5, -22, -19, -5, -1, -10, 1, -2 }, + { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9, + 9, -11, -17, 0, -6, 16, 0, 1, 9, -24, 3, 3, -9, -3, 3, -2 }, + { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6, + 5, -2, 6, -2, -4, -3, 0, -3, 13, -50, 1, -2, 2, 4, 4, 3 }, + { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1, -15, -1, -15, + -11, -4, -17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 }, + { 1, -2, 2, -1, -10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0, + 1, 1, 6, 0, 11, 13, 3, 4, 0, -12, 11, -5, 19, 20, 2, 5 }, + { 5, 3, -13, -2, 1, -12, 11, -7, -12, 7, 10, 0, 7, 0, -2, 4, + -6, -9, -11, -12, -23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 }, + { 6, -3, 2, 5, 2, 2, -2, -5, -8, -11, -4, 3, -8, -4, 5, -3, + -16, -4, 3, -12, -4, 3, 32, 7, 2, 8, 32, -18, -1, 12, 1, 7 }, + { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4, -12, -1, 3, 0, 1, -18, + 8, 8, -14, -10, -11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 }, + { 3, 5, -14, 7, 14, 8, 20, -13, -16, -10, -2, 17, -7, 4, -8, -9, + 14, -5, 3, -4, -12, 7, 14, -10, -19, -20, 35, 8, 13, 14, -2, 9 }, + { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2, + 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 }, + { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6, + -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 }, + { -11, 1, -3, -3, -11, 3, -9, -25, -1, -16, 4, -8, 15, 1, -2, 7, + 8, 23, 2, 18, -13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 }, + { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1, -13, 2, 2, 10, 6, 7, + 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 }, + { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5, + -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 }, + { 2, 4, 3, -7, 5, 8, -11, 7, -5, 9, -10, 6, 8, -10, -3, 10, + 1, -29, -4, -26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 }, + { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0, + 5, -1, -2, -2, -1, -4, -10, 8, 0, -6, 10, -4, 46, 12, 2, 28 }, + { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3, + 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35, -11, 13, 53, -3, -1 }, + { -5, -2, 0, -13, -16, 5, -12, -11, 1, -30, 3, -18, -24, -8, -5, -19, + 1, -3, -8, 7, -7, -8, 15, -19, 4, 10, 30, 24, 6, 1, -9, 10 }, + { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2, + 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18, -12, 18, 16, 4, 16 }, + { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6, + 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 }, + { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2, + -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 }, + { 4, -3, -7, -5, -11, -5, -12, -10, -10, -12, -15, -12, -14, -14, 1, 1, + 10, -10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 }, + { 7, -3, -2, 4, 6, -8, 2, -3, -12, -5, -9, -8, -10, 15, -2, -4, + 8, 9, 7, -13, -18, 34, -5, 7, 12, 22, 16, -11, 13, 25, -15, -11 }, + { -3, -2, 0, -4, 1, 0, -3, -13, -7, 13, 12, -7, -10, 13, 19, 6, + 16, 15, -12, -15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 }, + { 3, -5, 0, -4, 0, 4, -11, 4, -7, -3, -1, -8, 3, -2, 2, 1, + 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 }, + { -1, -4, -9, 5, -8, -18, -4, -9, -20, -18, 7, -14, -16, 3, 8, -3, + 29, 11, -13, -13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 }, + { -3, 8, -10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8, -14, 15, -5, + 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13, -11, 1 }, + { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8, -10, + 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 }, + { -4, -7, -31, -2, -7, -1, 5, -5, -5, -12, 4, -7, -6, 3, 15, -2, + 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 }, + { -7, 0, -3, -6, 1, 3, -13, -6, -4, -4, -5, -9, -1, -10, -4, -8, + 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 }, + { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4, + 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20, -27, 14, 1, 2, -3 }, + { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8, + -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 }, + { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2, -10, 0, 7, 21, -1, + 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14, -20, 15, 14, 4, 15 }, + { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9, -10, -2, + -5, 0, -3, -21, 9, 14, -11, 13, 29, 2, 25, 4, 22, -1, 2, -3 }, + { 2, 12, -11, 2, 16, 9, -4, 7, 1, -10, -15, 11, -4, 3, -2, 4, + 4, -5, -10, 1, 4, 19, -15, 6, -4, -2, 30, -7, 11, 21, -12, 5 }, + { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0, + 8, -7, -3, -2, 2, 14, 2, -3, -26, -1, 26, 22, 32, 1, -2, 6 }, + { 1, -38, -1, -20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10, + 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1, -14, -1, -9, -5, -4 }, + { -5, -26, -7, -19, -10, -5, -11, 5, -11, -25, -8, -14, -9, -16, -8, -6, + -17, -14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 }, + { 17, -49, -3, -23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4, + -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 }, + { 4, -34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2, -16, 7, -3, + 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 }, + { 5, -29, 13, -2, -14, 3, 1, 18, -15, 4, -8, 8, -10, 8, 2, 1, + -8, 15, 3, -10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 }, + { 13, -20, 3, -18, -17, 4, -14, 13, 28, 11, -8, -6, 16, 6, 0, 10, + 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 }, + { 3, -27, -5, -11, -21, -11, -12, 0, -5, 7, -22, 1, 3, 5, 0, -5, + 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 }, + { 31, -45, 0, -1, -12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3, + -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 }, + { 9, -45, 6, 5, -1, -17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8, + -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 }, + { 3, -26, -2, -12, -12, 2, -10, 16, -3, 12, 4, 5, 11, 8, -16, -17, + -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 }, + { 8, -26, 32, -7, -5, 22, 2, 14, -10, -8, -7, 3, 3, 7, 0, -5, + 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 }, + { 4, -31, 2, -14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5, -10, + -2, -10, -2, -10, -3, 7, 1, 5, -8, 8, -14, -3, -15, 7, -10, -6 }, + { 16, -27, 13, -4, -23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23, -18, + 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 }, + { -1, -35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6, -10, 9, 6, + -3, -5, -6, -3, 9, 16, -16, -9, -20, 12, 3, 5, -3, 1, -9, 4 }, + { 2, -24, 1, -12, -16, 5, -4, 3, -4, -1, -11, -11, -8, -14, 14, 10, + -8, 20, 8, -3, -11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 }, + { 9, -21, 2, -19, -7, -5, -8, 25, 3, 17, 5, -3, 9, -12, 8, 2, + -4, 3, 3, 1, 11, -9, -4, -3, 4, 3, -22, 6, 4, 6, 11, -5 }, + { 16, -23, 13, -17, -21, -12, 5, 9, -20, 7, 6, -6, 0, 2, -9, 6, + -6, -13, -7, -1, 5, -3, 5, -7, -10, 1, 0, 8, -9, 11, 0, -8 }, + { 10, -26, -9, -7, -19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1, + 6, -7, 1, -8, -11, 10, -14, 0, -16, 6, -3, 5, -1, 14, 12, 1 }, + { 8, -27, 12, -14, -1, -1, -19, 10, -11, 21, -14, 9, -8, -3, 8, -1, + 12, -13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 }, + { 18, -20, -14, -14, -16, -3, -24, 6, -17, 2, -3, -11, 2, -3, 12, 10, + 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 }, + { 0, -30, 9, -16, -18, 15, 12, -3, 4, -4, -5, -11, -4, -12, -10, 0, + 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 }, + { 25, -24, -1, -6, -9, 6, -13, -2, 3, 15, -3, 11, 4, -8, -11, 2, + 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1, -11, -15, -5, 0, 11 }, + { 0, -34, -7, -11, -7, 9, -3, 19, 4, -8, 3, -11, 11, -3, -9, 12, + 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 }, + { 6, -34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3, -26, -12, 8, -6, + -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 }, + { 3, -30, 5, 6, -10, 3, -7, 6, 3, 3, -26, -19, -3, 1, 7, 5, + -4, -5, 6, 10, 13, -10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 }, + { 4, -24, 9, -19, 2, -4, -5, 8, -3, 2, 0, -15, -1, 9, -4, 22, + 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 }, + { 8, -27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7, + 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 }, + { 17, -22, -15, -11, -8, 16, -14, 18, 2, -1, 14, -7, 14, -6, -6, -7, + -8, 17, 6, 4, 4, -7, -5, -9, -14, -6, -1, 9, -3, 1, 6, -5 }, + { 25, -30, 2, -12, -13, 18, -18, 16, 8, -3, 10, -8, -3, -1, -6, 3, + -5, -7, 4, 6, 7, 1, 1, -11, -5, 6, 2, -4, 9, -1, -5, -2 }, + { 7, -23, 7, -15, -1, -3, -1, 0, -10, 12, 2, 5, -4, 0, 4, 6, + -1, 5, -9, -1, -1, -7, 1, 17, 9, -17, -16, 8, 4, -14, 11, 14 }, + { 0, -31, 7, -13, 3, -11, -7, 6, 1, -11, 8, -7, 15, -3, 16, -11, + -1, -15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 }, + { 13, -24, -2, -20, -10, 7, -3, -1, 15, 2, 6, -5, -7, -10, -20, 1, + -4, 14, 8, -2, 3, -13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 }, + { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0, + -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7, -31, -50 }, + { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0, -20, -6, -3, 9, + -20, -22, -1, -1, 15, 9, -12, 10, -13, -20, 12, 3, 5, 6, -7, -26 }, + { 0, 4, -2, -14, -12, 6, -13, 11, -10, 3, 22, 6, 16, -2, -5, 1, + -3, -11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5, -27 }, + { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4, -15, 14, 1, 3, -10, 5, + 0, -2, 7, 3, -13, 6, 9, -6, 5, -14, -17, -1, 11, 14, -2, -26 }, + { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11, + 9, 19, -2, 14, -8, 7, -1, 3, -3, -3, -10, -2, 12, -2, -12, -29 }, + { -12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1, + 2, -2, -14, 0, -1, -5, 3, 8, -28, -26, 6, -6, 3, 8, -10, -27 }, + { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6, + -1, -4, -1, -5, 8, -1, 5, -5, -15, 11, -8, -5, 14, -6, -14, -29 }, + { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2, -10, 3, 4, + 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28, -11, -31 }, + { 1, -4, -10, -9, -4, -3, -15, -6, 1, 5, -3, -6, 5, -6, -22, 27, + -13, 5, 3, -7, -4, 20, -7, -12, -1, -24, -4, -13, -8, -11, -15, -21 }, + { -6, -4, 19, -6, 2, 11, -6, 1, -3, -10, 9, -9, 12, -10, 2, 1, + -9, 1, 15, 7, -5, 5, -29, -35, 4, -30, 9, 9, 19, 17, 2, -17 }, + { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2, + -4, -1, 12, 0, 2, -8, -6, -4, 16, -1, -14, -2, 25, -6, -15, -36 }, + { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1, + -3, -13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1, -28 }, + { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2, + 16, -11, 11, 0, 1, 6, 1, 18, -10, -16, -1, -4, 5, -14, -15, -20 }, + { 1, -12, 5, 4, -7, 8, -1, -17, -2, -9, -14, -11, 6, -9, 5, -4, + 3, -2, 7, 18, -5, 5, 6, -1, -11, -2, -10, -3, 8, -3, -2, -32 }, + { -12, 5, 20, -5, -6, -11, -6, -6, -13, 4, -6, 19, -8, 2, 3, -9, + -4, -4, -1, 9, -1, 21, -1, 7, 15, -10, -1, -3, 9, -3, 2, -24 }, + { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8, + 0, -2, -6, 9, -4, 3, 2, -13, 1, -7, 23, -13, 4, -3, -15, -33 }, + { -7, 2, -15, 11, -10, 14, 0, -11, 3, -1, 12, -4, -4, 9, 11, -13, + -13, -3, -14, 1, 3, 6, -5, 8, 0, 5, 5, -10, 4, 5, -6, -30 }, + { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5, + -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3, -19, 37, 12, 10, -40 }, + { -7, 2, -7, -12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5, + 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2, -24 }, + { -7, 6, 1, 3, 1, 0, 6, 0, 4, -12, -2, -2, 1, -9, 10, -2, + 11, -1, 21, -12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3, -29 }, + { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2, + 3, -5, 2, -1, 6, -4, 0, -3, 8, -11, 19, -8, 22, -34, 13, -35 }, + { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2, -12, -11, 18, + 9, -5, 1, -6, -9, 12, 1, -3, -3, -9, -14, 9, 9, 8, -6, -26 }, + { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4, + 1, 1, 18, 1, 7, -10, 3, -2, 12, -1, -15, 9, 12, -14, 13, -38 }, + { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1, + -7, -1, -4, 13, 7, 0, 1, 2, -1, -16, 0, -2, 1, 8, -8, -28 }, + { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28, -18, + -6, 2, 15, -10, -15, -10, -2, 0, -2, -2, 4, -3, 7, 11, 5, -30 }, + { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3, + -10, 4, 10, 5, 21, -4, 14, -18, 1, 3, -10, -2, 6, 14, -8, -26 }, + { -14, -1, 2, 3, -3, 7, 1, -22, -1, -1, 0, 1, 12, -14, 3, -5, + 0, 10, -3, 1, -5, 12, -3, 10, -8, -22, -11, -13, -7, -10, -13, -25 }, + { -2, -5, -4, -4, -9, -18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8, + 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0, -17, -23 }, + { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6, + 8, 10, -1, 1, -5, 5, -14, -2, -11, 8, 6, 25, 7, -1, 0, -43 }, + { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2, -10, + -16, -9, 7, -12, 9, -8, 2, 5, -5, -10, -2, -11, -5, -1, -9, -30 }, + { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3, -17, 13, 9, + 0, 7, -6, -5, 9, 1, 5, 4, -10, -18, 0, 14, 11, -4, -16, -28 }, + { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1, + -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6, -70 }, + { 7, 3, -11, -1, 12, -4, -14, 4, 4, -4, 4, -2, 2, -12, -4, 15, + -17, -4, -3, 6, 8, -5, 22, -22, 5, -11, 15, -4, 4, -1, -21, -1 }, + { 10, -2, -13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10, + 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8, -29, 13 }, + { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0, + 9, -2, 1, -2, 26, -19, 21, -10, 4, 1, -8, 5, 22, -10, -13, 15 }, + { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1, + -8, -5, -13, 13, -2, -3, -1, -9, -28, 4, 2, -11, 18, -20, -24, 9 }, + { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5, + 2, -13, -12, 2, 0, 5, 18, 15, -13, -7, 13, -20, 16, -10, -19, 6 }, + { 5, -8, -1, 5, 10, 2, -1, -10, -11, 23, 8, -5, -8, 4, -5, -4, + -5, -5, -11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17, -12, -22, 3 }, + { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7, + -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5, -24, 13, -20, -27, 14 }, + { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1, + -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24, -43, -13, 2 }, + { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1, + -7, 1, -1, 10, 0, 5, -1, -24, 25, -15, 7, 2, 22, -10, -21, 0 }, + { -5, 2, 6, -2, 13, 3, 5, -12, -11, 16, 6, 10, -5, 0, -3, 6, + 5, -5, -5, 10, 12, 10, 11, -7, 8, -14, 2, -15, 13, -14, -8, -3 }, + { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5, + -12, 3, -3, -6, 2, -1, -5, 14, 11, -20, -21, -25, 24, -1, -10, 6 }, + { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1, + -17, -18, -4, -13, 9, -1, 9, -7, -4, -8, 2, -3, 12, -31, -18, 5 }, + { -7, -11, 6, -8, 4, -3, -12, 0, -1, -6, -3, 0, 5, 9, 7, 2, + 1, -8, -6, 8, 2, -5, 7, -1, 16, -10, 16, -12, 18, -1, -25, -12 }, + { 3, -12, 1, 2, -2, -18, -8, -15, -10, -9, 2, -7, 11, -11, 2, -1, + -1, -1, -9, -6, 3, -14, -2, -1, 2, -13, -7, -9, 19, -5, -17, 2 }, + { 7, 1, -8, 7, 17, -13, -10, 5, 7, 1, -6, 4, 9, -4, 0, 3, + 8, 1, -14, -9, 4, 7, -9, 0, 6, -5, -12, -2, 25, -2, -19, 1 }, + { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5, -17, -4, 4, -1, + 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2, -18, -2 }, + { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2, + -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0, -13, 4 }, + { 0, -13, -11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2, + 9, -2, -11, 15, 1, -21, 1, -1, 0, 4, -14, -4, 24, -16, -13, 1 }, + { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9, -12, 0, + -1, -14, -9, -14, 0, -2, 19, 4, 6, 4, 4, -11, 8, -17, -19, -5 }, + { -3, 1, 2, 12, -4, -18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12, + -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1, -25, 22, 2, -23, -5 }, + { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2, + 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3, -25, 4 }, + { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3, -12, 12, 15, -9, -4, 2, + 9, -4, -12, 3, 14, 1, 7, -15, 15, 0, -6, -12, 0, -3, -20, 6 }, + { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1, -18, -4, -6, + -15, -5, 11, 5, -10, -1, 2, 7, 12, -19, -7, 8, 21, -4, -15, 4 }, + { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2, -14, -11, 6, + 2, 17, 8, -13, 26, -2, 5, -15, -4, -14, 12, -9, 13, -21, -23, -4 }, + { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1, + -17, -22, -3, 4, 3, -2, 1, -9, 1, -6, 11, -13, 14, 0, -15, 6 }, + { -16, -4, 17, -2, -20, -11, 11, 10, 5, -8, 16, 2, -17, -14, 11, 11, + -6, -11, -7, 12, 12, -10, -6, 5, 8, -4, -2, -5, 28, 3, -13, 4 }, + { 0, -3, 3, -7, 6, 8, -12, 20, -19, 18, -11, 10, -5, 0, -9, 11, + 3, 0, -2, 9, -7, -5, 18, 3, -2, -16, 1, 6, 12, -7, -16, 1 }, + { 4, 1, 5, -5, 15, 2, -8, 3, 5, -11, 15, -3, 8, -8, -1, 7, + 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6, -18, 4, 0, -18, 11 }, + { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4, + -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4, -37, 19, 1, -15, -4 }, + { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4, + -10, 2, -6, 4, 4, 1, 27, -7, 17, -34, 5, -9, 15, -16, -7, -5 }, + { -2, 7, 7, -2, 9, -2, -15, 11, 11, 7, 5, 1, 15, 1, -9, 31, + 2, -15, 2, 4, 3, 4, -1, -8, 2, -7, 6, -17, 11, -14, -11, 2 }, + { 1, 1, -11, 9, 9, -6, -14, -11, -10, 8, -3, 11, 16, -9, -8, -13, + -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6, -17, 4 }, + { 14, 5, 4, -6, -12, 10, -7, 8, 21, -8, -30, 15, -2, 1, 11, -9, + -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 }, + { -1, 2, 20, -17, -15, 3, 3, 7, 11, -17, -13, -6, -3, 18, 17, -15, + -4, -4, -5, 22, 14, -14, -2, -10, -7, 11, 8, -7, -3, 0, -7, 11 }, + { 7, -11, -7, -8, -14, 22, 5, 2, 6, 13, -12, -2, 10, 3, 0, -21, + -4, 20, 3, 10, 21, -10, -12, 8, 11, 2, -5, 2, 1, 3, -1, 15 }, + { -1, -2, -1, -2, -13, 8, -4, 0, 7, -2, -17, 8, 18, 5, 3, 8, + -8, -2, 3, -4, 14, -18, -13, 14, 15, -13, -1, -2, 4, 11, 1, 12 }, + { 13, -6, -4, -16, -17, 16, 21, -2, 5, -11, -9, 19, 21, -17, -3, -17, + 3, 12, 8, -12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 }, + { 11, 5, 12, -20, -6, 10, 4, 12, 8, -5, -10, 15, 13, 14, 10, -15, + -13, 1, 6, 14, 15, -17, -13, 4, -5, 10, 7, -6, -8, -3, -4, 12 }, + { 25, -1, 7, -5, -7, 11, 1, 17, 13, -15, -14, -4, 5, 3, 8, -3, + -2, 2, 0, 6, 16, -12, -6, -4, 4, -3, 7, -10, -3, -7, -13, 7 }, + { -8, 10, -3, -13, 5, 2, 4, 9, 9, -17, -13, 2, 11, 1, 6, -4, + 8, -10, 4, 1, 19, -15, -4, 12, 31, 7, -5, -17, -4, 9, -2, 7 }, + { 14, -6, -6, -6, -14, 13, 17, -5, 4, -14, -9, 7, 7, -9, 3, -16, + -15, 11, 11, 6, 4, -11, -19, 3, 5, 8, 13, -14, -14, 3, -4, 12 }, + { -2, -4, 10, -4, -7, -1, 27, 5, 2, -16, -18, 4, 12, -2, -3, -2, + -1, 1, -8, -12, 3, -4, 8, 15, 2, 4, 9, -13, -14, 9, -7, 5 }, + { 4, 2, -10, -5, -7, 2, 1, 4, -1, -6, -15, 6, 1, 10, 5, -10, + -9, -1, 13, -3, 5, -21, -11, 8, 8, 5, 27, -21, -18, -5, -1, 15 }, + { 11, 1, -16, -8, -11, 0, 5, -8, -12, -13, -17, 22, 4, -6, -1, -18, + -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9, -17, -5, 4, 4, 10 }, + { 8, -6, -19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1, + 2, 4, 7, 9, 16, -16, -14, 9, -4, 3, 1, 0, -2, 10, -1, -1 }, + { 12, -8, 12, -9, 0, 25, 7, 9, 2, -31, -9, -4, 15, 4, -5, 1, + -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4, -10, -9, 6, 4, 5 }, + { 14, 6, -17, -2, 17, 12, -9, 2, 0, -25, -14, 5, 20, 14, 8, -20, + 5, 2, -2, -3, 9, -13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 }, + { 8, 4, -15, -3, 10, 18, -4, 13, 8, -22, -10, 9, 19, -15, 7, -5, + -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 }, + { 4, 1, 4, -5, -10, 18, 7, 2, -4, -9, -11, 0, 32, -7, 4, -16, + -1, 0, 6, 3, 6, -3, -14, 16, 9, -2, 7, -1, 0, -5, 5, -3 }, + { -3, 2, 3, -8, -6, 4, 6, 2, 4, -12, -15, 2, 8, 8, 9, -3, + -18, 6, 34, 11, 12, -15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 }, + { 18, -6, -12, -8, -1, 15, 20, -4, -1, -11, -5, 6, 6, -11, -15, -7, + 3, 7, 10, 2, 8, -10, -5, 8, 15, -5, 5, -17, -13, 13, 11, 7 }, + { 8, -4, -6, -1, -14, -3, 6, -2, 1, -5, -1, 10, 10, -15, 5, 0, + -10, -4, -3, 7, -4, -19, -15, 27, 11, 18, 3, -19, -2, 6, 0, 12 }, + { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7, -11, 21, 29, 1, -2, 1, + -4, -11, -1, 13, 11, -20, -1, 4, 4, 4, -5, 6, -13, -2, 11, 9 }, + { 2, -7, -7, -3, -10, -1, 20, 12, 1, -19, -19, -1, 5, 4, -7, -25, + 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 }, + { 12, -8, 3, -12, -10, 10, 13, 0, 23, -14, -18, 10, 0, 15, 3, -12, + -3, -5, 5, -4, 2, -14, -10, 8, 2, 9, -1, -11, -3, 5, 13, 2 }, + { 9, -6, 7, -7, -30, 17, 6, 13, 1, -14, 0, -1, 6, -9, 8, 3, + -4, 0, -1, -7, -5, -13, -19, -3, -4, 4, -6, -2, -13, 1, -2, 3 }, + { 10, 1, 3, -18, -26, 17, 4, -16, 4, -3, -13, -4, -6, -11, -4, -21, + 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 }, + { -3, -1, 0, -2, -2, 0, -1, 3, 4, -14, -8, -9, 13, 2, 50, -23, + -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 }, + { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5, + 5, 4, 4, -2, 10, -8, -40, -1, 21, 8, 3, -4, -1, 13, 4, 7 }, + { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12, -13, + -9, 0, 1, -12, 9, -43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 }, + { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7, -23, -5, 23, -17, -6, -15, + -8, 7, 10, -1, 7, -16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 }, + { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1, -45, + -6, -4, 4, 2, 1, -14, -10, 1, 1, 6, 2, -8, -1, -3, 3, 3 }, + { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6, + 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 }, + { -4, 1, -2, -1, -11, 11, 8, -3, -2, -10, 0, 4, 9, 9, -17, -17, + -34, -4, -5, -7, -3, -12, -3, 11, 18, 3, -2, -5, -18, -5, -3, 6 }, + { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3, -10, 12, -18, -5, + -10, 12, -9, 4, -6, 2, 0, 16, -17, 15, 14, -12, -10, -2, -9, -1 }, + { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4, -20, 1, + -25, 1, -8, 13, -10, 8, -19, -1, -8, 10, 6, -9, -1, 0, 12, 4 }, + { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4, + -25, 13, -23, 10, 14, 15, -11, 3, -18, 4, 16, -4, 1, -10, -10, 3 }, + { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1, -12, 14, -7, 11, -15, 6, + -6, 24, -4, 13, -1, 15, -13, 8, 3, 7, -5, 2, 2, 0, 3, -7 }, + { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2, -12, 4, 0, -2, -3, 5, + -6, 0, -8, 9, -10, 4, -28, 12, -20, 11, -13, 7, -18, 1, -11, 1 }, + { 1, -4, -15, 5, 0, -13, -5, 13, -11, 4, -4, -5, 5, -14, -16, 0, + -14, 5, -20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 }, + { 13, -11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5, + -22, 5, -10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 }, + { 18, -4, -13, 0, 1, -15, -1, -3, 2, 10, -1, 6, 1, -4, -20, -5, + -8, 6, -8, 17, -5, 5, -10, 8, -22, 6, -5, -2, 8, -17, 8, 2 }, + { 1, -2, -9, 6, -31, -8, -8, 8, 0, 5, -9, -4, 2, 3, -12, 11, + -18, 10, -5, 3, -11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 }, + { -9, -6, 21, -8, -15, 4, -11, 12, -11, 17, -1, 2, -6, 0, -15, 13, + -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5, -10, -3, 0, 1 }, + { 4, -6, 5, -10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0, + -4, 3, -4, 1, -12, 6, -49, 16, -10, 13, 0, -2, 8, 6, 1, 8 }, + { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13, -14, 6, + -15, -6, -14, 16, 15, 1, -18, -4, -20, 20, -7, -1, -9, -2, -10, 10 }, + { -12, 4, 0, 10, 0, 3, 8, 4, -27, -1, -2, 19, -4, 2, -13, 3, + 1, 9, -12, 1, -22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 }, + { 4, -5, 11, -6, 17, -17, 5, -4, -2, -6, 1, -5, 2, 4, -14, 6, + -20, 19, -20, 12, -21, 5, -14, 13, -2, 11, 4, -3, 0, -10, -4, -2 }, + { -2, -1, -3, 8, -9, -7, -22, -3, -24, 13, -2, 10, -15, 5, -9, 4, + -7, 0, -5, 15, -8, 11, -13, 6, -4, 19, -8, 12, -4, 6, 9, 7 }, + { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5, -12, 6, + -16, 14, -23, 10, -14, 17, -15, 16, -2, 9, -25, 9, -10, 16, 4, 9 }, + { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3, -11, 25, -10, -28, 27, + -9, 7, -13, 9, -2, 4, -12, -8, -14, 6, 7, -10, 3, 3, -3, 5 }, + { -8, -3, 1, -10, 8, -3, -9, -4, 13, 7, 2, 4, -10, 4, 3, 7, + -18, 2, -22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 }, + { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0, + -2, -3, 1, 2, -1, 2, -8, -1, -24, 68, -3, 8, 3, 3, -1, -1 }, + { -15, -2, -9, -7, -1, 8, -14, 8, 3, 6, 0, -1, -8, 8, -23, 2, + -14, 17, -15, 8, -4, 7, -18, 0, -8, -3, -1, -4, -10, 4, -1, 4 }, + { 8, 0, 2, -7, 0, 5, 1, 3, -11, 4, -8, 14, 3, 20, 1, 26, + -11, 13, -13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 }, + { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3, + -15, 7, -9, 22, -19, 8, -9, 4, -23, 13, -14, 6, -6, -14, -4, 7 }, + { 14, -5, -8, -10, 25, 3, -23, -7, -28, 0, -1, -9, 4, 1, -13, 20, + -8, 10, -16, 8, 12, -13, -21, 5, -13, 11, -2, 1, 12, -7, 2, -10 }, + { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2, -18, 7, + -15, 6, -3, 2, 8, 12, -30, 7, -4, 20, 2, 6, 13, -6, -4, 0 }, + { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16, -17, 14, -13, 15, -18, 14, + -15, 17, -12, 14, -13, 7, -16, 13, -9, 5, -11, 10, -9, 6, -12, 13 }, + { -10, -4, 5, 3, 1, 6, 8, -14, -5, 15, 7, 4, 8, 7, -22, 8, + -7, -8, -15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 }, + { 8, -3, 2, 3, 3, 1, -2, -1, -11, 8, -4, 0, -6, -5, -1, 13, + -37, 9, 1, -6, -10, -2, -10, 11, 8, 13, -3, -2, -6, 8, -4, 13 }, + { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9, -20, 12, -19, 15, -18, 17, + -15, 7, -1, 20, -11, 6, -6, 3, 1, 9, 2, -14, -2, -2, 2, 1 }, + { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9, + -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 }, + { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8, + -7, 4, 10, 11, -41, 27, -20, 3, -3, 8, 1, 11, -5, -8, 0, 4 }, + { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7, + -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2, -21, -12, -3, -1, 2 }, + { -4, 4, -2, -2, 6, -8, 2, 1, -10, 14, 8, 6, 5, 1, -2, 4, + -13, 4, 2, 5, 10, -2, -21, 32, -3, 18, 9, -6, -9, -9, 10, 2 }, + { 9, -16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19, + -24, -6, -6, -5, -8, -7, 8, -7, -1, -12, 5, -3, 0, 4, 2, -3 }, + { 10, 3, -16, -4, -1, 13, 4, 4, 1, -3, 1, -6, -14, 18, 3, 8, + -8, -28, -16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 }, + { -5, -13, -22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1, + -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 }, + { 5, -10, -18, 2, 20, 4, 13, -10, 8, -15, -11, -3, -1, 16, 10, 9, + -8, 6, 7, -5, 6, 11, 5, 17, -4, 7, -11, 5, -3, -6, 2, 1 }, + { 3, -5, -19, 1, 1, -3, -2, -25, -11, -17, 0, -13, -4, 10, 10, 2, + -5, 4, 0, 3, -3, -5, -10, -2, 13, -22, 0, 3, -11, -5, 7, -1 }, + { 12, -14, -29, 6, -1, 10, 7, -17, -12, 14, 3, 9, -9, 9, 7, 6, + -3, -13, 0, 5, 3, -1, -6, -1, 0, 2, 4, -12, -5, -1, 2, 11 }, + { 12, -15, -7, -2, -12, 17, 20, -16, -2, -12, -6, 15, -6, 12, 11, 9, + 7, -6, 7, -4, -19, 6, 2, 2, 3, -11, -10, -4, -5, -3, 3, 2 }, + { 11, -22, -6, 0, 8, 18, 3, -11, -4, -7, -15, -17, -12, 6, 16, 4, + -9, 4, -5, 3, 6, -16, 10, -7, -7, -3, 5, 0, 1, -15, -4, 5 }, + { 12, -22, -16, 5, -6, 8, 12, -4, -9, -17, -11, 3, 5, 8, -17, 0, + 11, -4, -13, -6, 2, -1, -1, 3, 3, -11, -12, -1, 1, 1, 12, -2 }, + { 8, -10, -33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6, -12, + -16, -8, 11, 8, -14, 7, 12, 11, 4, -14, -3, 6, -7, -5, -3, 3 }, + { 0, -8, -7, 2, -4, 24, 2, -9, -11, -3, -7, 11, -12, 17, 1, -1, + 3, -5, -7, 12, 4, 11, 0, 3, 2, -18, -3, 4, 7, -6, 3, 15 }, + { 10, -15, -16, -2, -4, -9, 7, -15, -6, 2, -16, 13, -8, 7, 19, -21, + -4, -12, -9, -3, -3, 6, 11, -3, -1, -19, 3, -7, -9, -4, 3, -6 }, + { -5, -10, -21, 0, -3, -7, 18, -21, 15, -5, -12, -4, -13, 2, 6, -9, + -9, -11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 }, + { 15, -1, -27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9, + -11, -17, -2, 7, -9, 11, 10, 0, -8, 6, -16, -3, 2, -7, 3, 11 }, + { 4, -9, -39, 19, 6, -13, 13, -5, -5, -15, -2, 9, 0, 4, 14, 6, + -10, -4, -5, 2, -4, -2, 5, -11, 3, 3, -2, -2, -7, 9, 7, -10 }, + { 5, -11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1, + 18, -30, 4, 10, -4, -6, 2, -11, 9, -10, -8, 5, 0, 0, -7, 6 }, + { -1, -16, -10, 11, 0, 13, 12, -4, -4, -5, -21, 12, 4, 13, 14, -7, + 6, -16, -13, 8, 2, 9, 15, -12, 1, -9, -22, 10, -9, 9, 9, -7 }, + { 4, -12, -27, 1, -2, 11, 15, 3, 14, -14, -9, 0, -9, 16, 22, 10, + 16, -10, 5, -5, -9, 1, 1, 6, 6, -4, 2, -17, -5, -6, -15, -1 }, + { 7, -12, -17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17, + -7, -13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 }, + { 7, -15, -15, -4, 10, 12, 3, -13, 6, 14, 9, -8, -15, 14, 23, -5, + -10, -5, 1, 15, -10, -7, 1, 9, 4, -13, -10, 10, 7, -3, 2, 3 }, + { 4, -10, -14, 0, 3, 4, 0, -9, -3, -4, -11, 2, -17, 8, 2, 15, + 6, -12, -12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 }, + { -2, -18, -26, 10, -4, 10, 13, 4, -4, -16, -7, -17, -3, 5, -4, 2, + -15, -10, -1, -8, -7, -3, 2, 2, 8, -10, -7, 2, 2, -4, 4, -1 }, + { 4, -19, -5, -1, -1, -6, 2, -8, 10, -16, -28, -6, 8, -1, 11, 28, + 2, -10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 }, + { -3, -6, -10, -5, 13, 18, 10, -15, -5, -3, -13, 5, 1, 2, 18, -5, + -10, -10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9, -17, 7, 7 }, + { 20, -12, -2, -4, 5, 14, 7, -11, -1, -16, -6, -4, -11, 17, 14, 0, + -8, -10, -8, 10, 3, 5, 10, -16, 3, -8, -14, 10, 3, 9, 0, 3 }, + { 12, -10, -36, 0, 7, 15, 2, -16, 2, -1, 0, -1, 5, 4, 5, -3, + 1, -10, 5, -1, -15, -3, -12, 12, 2, 5, -1, 5, 6, -3, -2, 2 }, + { 17, -15, -31, 23, -4, 15, -2, -3, 6, -7, -5, 1, -12, 4, 6, 8, + -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 }, + { 6, -18, -5, 12, 10, 12, 14, -11, 15, 2, -9, -6, -5, -2, -9, 4, + -5, -28, -4, 14, 0, -16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 }, + { -5, -14, -31, 8, 16, 7, 13, -13, 5, 6, -16, 10, -5, 2, -2, 2, + 14, -5, 8, -5, 7, -16, 6, -13, -5, 0, -5, 8, -3, -1, 4, 3 }, + { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28, + -12, -35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 }, + { 2, -9, -22, 12, 3, 3, -7, -4, -19, -22, -14, -4, -1, 21, 9, -3, + -15, -16, -13, 1, -11, 4, -9, 1, -7, -1, -1, 0, -2, 9, -13, -3 }, + { -1, -3, -23, 0, 2, 12, 3, -9, -4, 7, 3, 9, -10, 1, 27, 28, + 0, 9, -15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 }, + { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6, + -10, -12, 19, 1, -7, 9, -8, -9, -16, -11, -2, 12, 14, 4, 4, 34 }, + { 17, 7, -6, 1, 4, -10, -5, 4, -11, 3, -18, 4, 14, -13, -3, 1, + 0, 0, -11, 0, 7, -17, -4, 4, -11, -6, -8, 18, 0, 0, 0, 26 }, + { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3, + 7, 4, -12, -8, 0, -9, 8, -22, -5, 0, -6, 22, -2, 11, -13, 24 }, + { -3, 4, 0, 3, 9, 10, -1, 3, -9, -12, 1, -5, 18, 0, -3, 8, + 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 }, + { -5, 2, -9, -1, -3, 0, 3, -1, -10, -4, 0, -13, 16, 9, -1, -14, + 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2, -14, 0, -9, 30 }, + { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7, -11, 14, 14, + 7, 34, -9, 0, -10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 }, + { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1, -10, 1, + 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7, -12, 0, -2, -10, 55 }, + { 5, 9, -1, 0, 4, 9, -21, -9, 4, 2, 6, -7, 11, -7, 1, -5, + 0, -4, 2, -3, -13, -8, 0, -9, -4, 2, 16, -2, -15, -7, -11, 31 }, + { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1, + 5, 2, 0, 0, 12, 20, -19, 1, 8, -12, -11, 0, 6, -5, 2, 31 }, + { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2, + -3, -12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 }, + { -4, 0, -7, 17, 10, -12, -2, -10, -12, -3, 10, 0, 11, -4, -13, -3, + 5, 6, 10, 7, -8, 0, -7, -13, 1, 0, -2, 7, -12, 4, -3, 24 }, + { -13, 9, 4, -2, 2, -4, -14, -1, -3, -5, -10, 4, 13, -2, 5, 13, + 8, 3, -2, 1, 5, -6, 7, -18, -10, 1, -1, 5, 4, 1, 0, 25 }, + { -5, -1, 18, 12, 8, 8, -16, -1, 1, 1, 1, -4, -5, 3, 3, 4, + 4, -11, -12, -16, -6, 2, 12, -13, 0, 9, 7, 9, -9, 0, -10, 24 }, + { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1, + 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 }, + { 8, 5, 11, 0, -15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0, + 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4, -11, -9, 41 }, + { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3, + -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3, -12, 16, 2, 27 }, + { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12, + -1, 10, -11, -11, -7, -4, -14, 7, -14, 13, 22, 18, -1, 0, 14, 28 }, + { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1, -15, 4, -9, + 22, -10, -9, -4, 1, 8, -4, 9, -15, 2, -6, -4, -16, 12, -10, 23 }, + { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1, + 13, -15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5, -11, -14, 23 }, + { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6, + 15, 3, -3, 18, -15, -2, -6, 3, 3, -20, 17, 11, -4, 2, 3, 29 }, + { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7, + -3, -2, -7, -2, -4, 5, 3, -5, -20, -13, -4, 10, -14, -29, 14, 37 }, + { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5, + -4, 4, -4, 4, 4, 3, 1, -4, -4, -9, -14, 20, -30, 3, -18, 33 }, + { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4, + 3, 2, -3, 0, -1, -1, -10, -7, 2, -4, -18, 2, -37, -1, 12, 40 }, + { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9, + 18, 0, 12, -17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 }, + { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1, -15, 8, 7, -1, -17, -4, + 1, 5, 6, -11, -6, 14, 17, -5, -15, 11, 8, 0, -3, -15, -6, 28 }, + { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2, + 2, -1, -1, -7, 1, 2, -9, 0, -1, -4, -18, 7, -10, 49, -13, 32 }, + { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1, + 2, -5, 2, -7, 17, -2, 10, -5, 0, 2, -15, 3, -9, 7, -9, 30 }, + { -5, -1, 0, 2, 1, -1, 2, 5, -33, 3, -5, 14, 11, 7, 5, -3, + 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 }, + { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3, + 4, 2, 1, -7, -4, 1, -3, -4, -35, -25, 17, 10, -3, -26, -7, 32 }, + { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2, + -5, 2, 2, 4, 3, 5, -5, -16, -31, -12, -11, 2, -19, 20, -2, 21 }, + { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2, + 0, -3, 5, -11, -8, -3, -7, -7, 28, -11, -7, 0, -16, -11, -4, 29 }, + { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5, -12, 2, + -2, -5, -22, -2, -1, 11, 8, -7, -12, 0, -34, 6, -5, 11, -8, 19 }, + { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1, + 2, 8, 4, -5, -8, -2, 5, -18, 7, 12, 7, 19, -18, 2, -6, -13 }, + { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6, + -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10, -13, 0, -9, -19 }, + { 12, -10, 2, -2, -2, -1, -3, 6, -12, -5, -2, 14, -16, 4, 12, 12, + 17, 4, 7, -16, 7, -6, 11, 7, 7, 2, -25, 23, -24, 5, -7, -9 }, + { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0, + 1, 2, -4, 2, -3, -8, 0, -1, 9, 9, -10, -3, -29, 1, -1, -27 }, + { 2, 2, 0, 7, 9, -2, -10, -1, -1, 1, -9, -5, 8, 4, 1, 2, + -10, 1, 13, 12, -3, 15, -9, 2, -7, 1, -10, 23, -20, -18, -9, -15 }, + { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7, + -6, 3, -3, -9, 7, 9, -22, 1, 6, -4, 14, 27, -25, -14, 3, -5 }, + { 1, 3, 8, 4, 7, 6, 12, -17, -15, 1, -8, -10, 7, -14, -8, 6, + -2, -2, -11, -11, -7, 13, -2, -2, 4, 5, -5, 13, -23, -6, -17, -8 }, + { -5, 4, -14, -5, -4, -5, 6, 5, -8, -5, -2, -11, -7, -12, 3, -11, + 2, -6, 4, -10, -5, -7, 14, 5, 23, 11, 7, 12, -16, -6, -4, -16 }, + { 5, 6, 2, 5, -2, -5, -5, -6, -5, -19, -13, -1, -3, -13, 5, 0, + 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17, -12, -27, 3, 0, -1 }, + { 7, -1, 9, -10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4, + 12, 5, 11, 14, -13, -1, 8, 1, 13, 9, 12, 12, -18, -14, -11, -16 }, + { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2, + 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0, -36, -5, -9, -21 }, + { 14, -6, -9, 0, -1, -8, -8, -11, 2, 2, -9, -12, 12, -4, 5, 3, + -5, -9, 11, -1, -3, 12, -21, -3, 12, 5, 3, 11, -18, -15, 1, -2 }, + { -1, 3, -9, -3, 7, -7, -18, 2, 4, 12, -10, 2, 8, -3, -14, 13, + 17, -5, 5, -9, 13, -3, -7, -18, 17, -2, 5, 7, -20, -3, -6, -11 }, + { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3, -14, -6, -5, -8, 14, -6, + 7, -1, 5, 1, 15, -1, -7, -4, 6, -11, 9, -2, -37, 16, -7, -3 }, + { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12, -10, + 10, 13, 2, 7, -6, 2, -10, -10, 21, -5, 5, 5, -12, -23, 3, -14 }, + { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1, + 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5, -20, -40, -4, -18, -14 }, + { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5, + 1, 2, -6, 4, -1, -2, -1, -15, 8, 3, 9, 46, -7, -18, 6, -11 }, + { 5, 5, 16, 21, 3, -11, -4, 11, -12, 2, 4, -12, -1, 11, 8, 1, + -4, 11, -11, -21, 1, 1, -11, 3, 13, 1, 5, 12, -25, 1, -3, -2 }, + { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9, -15, 3, -3, -14, 17, 4, + -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6, -29, -17, 8, 4 }, + { -7, -7, 4, 0, 13, 1, 0, 4, 4, -16, -10, -7, 5, 9, -15, -10, + -10, 8, -4, -1, -11, -1, -10, -15, 3, 3, 14, 10, -19, 2, -18, -12 }, + { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9, + 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11, -24, -44, -9, -15 }, + { -1, -10, 6, 21, 11, 15, -7, 10, -14, -9, -8, -8, 4, 6, 19, 1, + -6, 1, -5, -17, -8, -10, 9, 5, 11, 18, -1, 10, -16, -7, -9, -8 }, + { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4, + -7, 7, 17, -20, 6, 4, 1, -6, -12, 31, 13, 19, -14, -10, -7, -2 }, + { -2, 6, -10, 3, 9, 6, -14, 15, 2, -5, 2, -11, 9, -8, 4, 6, + 20, -15, -3, -3, -1, 32, -21, 6, 1, 9, 11, 17, -19, 6, -1, -3 }, + { 8, 10, -2, 0, -8, -16, 7, 7, 6, 10, 4, -14, 7, -6, 21, -7, + 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15, -20, -7, -11, 2 }, + { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5, -13, -1, 27, -9, + -6, -11, -7, 1, 11, -4, -4, -14, -2, 11, 6, 10, -19, -6, -15, 2 }, + { 0, 7, -1, 2, -7, -15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5, + -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7, -27, -4, -4, -12 }, + { 11, 1, -16, 6, -15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9, + 5, -3, 3, -2, -11, 3, 9, 6, 9, 3, -1, 12, -41, 8, -6, 9 }, + { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2, -13, 7, -1, -2, + -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1, -47, -21, 7, -6 }, + { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18, -13, 7, -13, -4, 8, 4, + 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10, -25, -3, -12, -12 }, + { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3, + 2, -2, -17, -6, -4, 1, 33, -6, -20, -6, 8, 31, -26, -8, -1, -4 }, + { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15, + -10, -3, -15, -5, -3, -4, -6, -30, 17, -8, -2, 2, -20, 0, -8, -2 }, + { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4, + 1, 1, -3, 4, 4, -14, 3, 11, -5, 3, -3, 7, -3, 13, 23, -16 }, + { 2, -6, 1, -3, 5, 0, -6, -11, -7, -4, -1, 2, -7, -1, -1, 7, + 1, -2, 6, 12, -6, 8, -13, 17, 25, -23, -19, -7, -12, 9, 16, -17 }, + { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7, + 0, -5, 3, -19, -3, 5, 3, 9, -1, 9, -13, 13, -17, 4, 21, -26 }, + { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2, + -2, 0, 4, -6, 7, -2, 6, 5, -5, 2, -12, 1, -29, 29, 27, 12 }, + { 9, -10, -22, 6, -1, -1, 9, -14, -12, -2, 1, -1, 10, -11, -16, 0, + 3, 11, 13, -14, -9, -2, -1, 6, 4, -14, 0, -10, -2, 16, 17, -11 }, + { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4, + -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1, -47, -3, 50, -17 }, + { 8, -4, -11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2, + -14, 6, 6, 6, 0, 2, -1, 5, -20, 2, -1, 4, -5, 6, 21, -11 }, + { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7, + 4, 7, -12, -9, -2, 10, -6, 13, 6, 5, 20, 2, -15, 9, 28, -7 }, + { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2, + 6, 16, -14, 9, -14, -2, -8, -27, -3, 18, -1, -7, -3, 8, 23, -23 }, + { 1, 4, -9, -1, -5, 10, -2, 1, -11, 1, -9, 4, 7, 14, -9, -2, + -3, 2, -5, -1, -6, -10, -7, 11, 20, 2, 3, -19, 3, 15, 30, -9 }, + { 7, 2, -14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6, -11, + -14, 1, 10, -1, -7, -8, 1, 10, 3, -6, -15, -12, -17, 4, 30, -6 }, + { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4, + 4, -4, -2, -5, -2, 2, -1, -2, 0, -2, -11, -7, -3, 42, 24, -14 }, + { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4, + -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24, -13, -28, 20, 15, -22 }, + { -3, 7, 6, 3, -2, -5, -10, -2, -2, -1, -6, -6, -2, -14, -16, -6, + -5, 0, 18, 0, 9, 1, 7, -13, -5, -6, -9, 11, -15, 9, 22, -11 }, + { 9, -2, 6, 5, 2, 9, -10, 1, 1, 5, -4, 12, 2, 2, -10, -7, + -4, -6, 7, 9, 6, 15, 6, 6, -10, 10, 5, -13, -5, 6, 24, -12 }, + { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6, + -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22, -17 }, + { -2, -2, 3, 10, 9, 9, 12, -15, -1, -11, -13, 3, -2, 1, -3, -11, + 7, 9, 16, -3, -10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31, -12 }, + { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3, + -13, -6, 15, 20, -9, -3, -12, 1, -2, -16, 8, 8, -1, 16, 22, -5 }, + { 5, -3, -15, -2, 12, -8, 8, -5, 2, -8, 20, -18, 14, -4, 3, 3, + 7, -13, -16, 1, -10, 7, 16, 7, 4, -14, -4, -5, -9, 8, 23, -6 }, + { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6, -10, -2, 6, + 9, -17, -14, 11, 12, -3, -13, -7, 2, 18, 3, -25, -16, 18, 22, -5 }, + { 5, 6, -7, -20, -4, 2, 8, 4, -24, -4, 1, 4, -5, -2, 1, -10, + -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21, -11 }, + { 0, 7, -1, 14, -6, -4, -10, 5, 4, 4, 4, -5, 3, 4, -1, -7, + 8, -19, 0, 6, 2, 3, -18, -3, -6, 2, 8, 14, -26, 22, 27, -13 }, + { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14, + 6, -5, 6, -4, -7, 7, -21, 8, 1, 8, -9, -4, -3, 11, 25, -13 }, + { 4, 4, -1, -6, 4, 9, -8, 1, -3, -10, -2, 0, 15, -9, -16, 11, + 1, 1, 6, 3, -9, -5, 16, 26, 1, -14, 1, -3, -14, 7, 15, -9 }, + { -12, -2, -9, -13, 2, 6, 14, 0, 1, 0, -1, -13, 0, 10, -1, 6, + 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7, -22, -2, 29, -7 }, + { 2, 4, 13, -12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10, + 15, -6, -1, -11, -30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25, -16 }, + { 7, -15, -7, -7, -1, -5, -5, -11, -20, 10, 3, -10, -3, 5, 20, -4, + 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1, -12, -3, 15, 22, -16 }, + { 4, -1, 3, 4, -5, 0, -1, -5, -24, -29, 4, -9, 1, -3, 0, 0, + 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5, -10, 3, 25, -10 }, + { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2, + 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1, -11, 7, 46, -46 }, + { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4, -10, + 13, 1, 3, -6, 4, -4, 7, 2, -19, -25, -3, -16, -12, 16, 20, -1 }, + { 18, 6, 4, -12, 0, -14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2, + 7, 0, 2, 5, -11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 }, + { 5, 0, -6, 5, 6, 3, 3, -10, -5, 1, -1, 4, 3, -11, -8, 5, + 4, -5, 5, -5, -7, -5, 11, 5, 20, -8, -16, 21, -4, 27, 23, -5 } +}; + + +/* FIR filter coefficients, they can be cut on half and maybe use float instead of double*/ + +static const float fir_32bands_perfect[] = +{ ++1.135985195E-010, +-6.022448247E-007, ++9.742954035E-007, ++7.018770981E-011, +-6.628192182E-007, ++1.085227950E-006, +-1.608403011E-008, +-6.982898526E-007, ++1.162929266E-006, +-5.083275667E-008, +-7.020648809E-007, ++1.194632091E-006, +-1.543309907E-007, +-6.767839409E-007, ++1.179182050E-006, +-3.961981463E-007, +-6.262345096E-007, ++1.033426656E-006, +-7.342250683E-007, +-5.564140224E-007, ++9.451737242E-007, +-3.970030775E-007, ++7.003467317E-007, ++1.975324267E-006, +-4.741137047E-007, ++8.419976893E-007, ++1.190443072E-006, ++5.234479659E-007, ++6.402664354E-008, +-1.470520488E-006, ++2.014677420E-007, +-3.246264413E-008, +-1.853591357E-006, ++7.834767501E-008, +-3.809887872E-008, ++7.198007665E-007, ++8.434094667E-008, ++3.086857760E-006, +-6.702406963E-010, ++6.437721822E-008, ++6.084746474E-006, +-1.613285505E-009, ++1.189317118E-006, ++9.561075785E-006, +-2.682709610E-009, ++2.497214155E-006, ++1.309637537E-005, +-3.399493131E-009, ++3.617151151E-006, ++2.263354872E-005, ++1.314406006E-008, ++3.157242645E-006, ++2.847247197E-005, ++7.506701927E-009, ++2.319611212E-006, ++3.415624451E-005, ++2.788728892E-008, ++7.869333785E-006, ++3.946387005E-005, ++1.444918922E-007, ++9.826449968E-006, ++4.425736552E-005, ++3.132386439E-007, ++1.177108606E-005, ++4.839275425E-005, ++1.399798180E-006, ++1.379448349E-005, ++5.176846025E-005, ++2.032118118E-006, ++1.571428584E-005, ++5.429694284E-005, ++2.715013807E-006, ++1.743183020E-005, ++5.595519906E-005, ++3.453840463E-006, ++1.884208177E-005, ++4.916387297E-006, ++4.195037945E-006, ++1.987093310E-005, ++9.299508747E-006, ++4.896494374E-006, ++2.042970118E-005, ++1.356193479E-005, ++5.516381407E-006, +-3.144468428E-005, ++1.751866148E-005, ++6.015239251E-006, +-3.334947178E-005, ++2.093936746E-005, ++6.361419310E-006, +-3.460439257E-005, ++2.362549276E-005, ++8.006985809E-006, +-3.515914432E-005, ++2.537086584E-005, ++8.087732567E-006, +-3.495384954E-005, ++2.618136386E-005, ++7.941360309E-006, +-3.397853652E-005, ++2.554462844E-005, ++7.568834008E-006, +-3.225446198E-005, ++3.018750249E-005, ++6.986399967E-006, +-2.978993689E-005, ++2.570833203E-005, ++6.225028756E-006, +-2.677291741E-005, ++1.985177369E-005, ++5.315936960E-006, +-1.806914770E-005, ++1.191342653E-005, ++4.429412002E-006, +-1.776598037E-005, ++2.525620175E-006, ++3.332600045E-006, +-1.661818715E-005, +-1.521241393E-005, ++8.427224429E-007, +-1.207003334E-005, +-1.617751332E-005, ++4.341498823E-007, +-6.993315310E-006, ++1.992636317E-005, ++9.458596395E-008, +-5.633860383E-007, ++1.774702469E-005, ++2.975164826E-008, +-9.984935332E-007, ++4.624524081E-005, ++5.610509834E-005, +-5.729619297E-004, ++4.244441516E-004, ++6.568001118E-005, +-6.358824321E-004, ++2.206075296E-004, ++7.513730816E-005, +-7.021900383E-004, +-2.719412748E-007, ++8.413690375E-005, +-7.698345580E-004, +-2.382978710E-004, ++8.757545584E-005, +-8.385353722E-004, +-4.935106263E-004, ++9.517164290E-005, +-9.078957955E-004, +-7.658848190E-004, ++1.020687996E-004, +-9.775133803E-004, +-1.055365428E-003, ++1.084438481E-004, +-1.046945457E-003, +-1.361547387E-003, ++1.140582463E-004, +-1.115717343E-003, +-1.684492454E-003, ++1.187910311E-004, +-1.183370827E-003, +-2.023874084E-003, ++1.224978914E-004, +-1.252829796E-003, +-2.379294252E-003, ++1.250260248E-004, +-1.316190348E-003, +-2.750317100E-003, ++1.262027217E-004, +-1.376571832E-003, +-3.136433195E-003, ++1.226499153E-004, +-1.433344092E-003, +-3.537061159E-003, ++1.213575742E-004, +-1.485876855E-003, +-3.951539751E-003, ++1.180980107E-004, +-1.533520175E-003, +-4.379155114E-003, ++1.126275165E-004, +-1.575609902E-003, +-4.819062538E-003, ++1.047207043E-004, +-1.611457788E-003, +-5.270531867E-003, ++9.417100227E-005, +-1.640390139E-003, +-5.732392892E-003, ++8.078388782E-005, +-1.661288203E-003, +-6.203945260E-003, ++6.447290798E-005, +-1.674512983E-003, +-6.683901884E-003, ++4.491530854E-005, +-1.678415807E-003, +-7.170005701E-003, ++2.470704203E-005, +-1.672798418E-003, +-7.664063945E-003, +-1.714242217E-006, +-1.656501088E-003, +-8.162760176E-003, +-3.193307566E-005, +-1.633993932E-003, +-8.665001951E-003, +-6.541742187E-005, +-1.593449386E-003, +-9.170533158E-003, +-1.024175072E-004, ++1.542080659E-003, +-9.676489048E-003, +-1.312203676E-004, ++1.479332102E-003, +-1.018219907E-002, +-1.774113771E-004, ++1.395521569E-003, +-1.068630442E-002, +-2.233728592E-004, ++1.303116791E-003, +-1.118756086E-002, +-2.682086197E-004, ++1.196175464E-003, +-1.168460958E-002, +-3.347633174E-004, ++1.073757303E-003, +-1.217562053E-002, +-3.906481725E-004, ++9.358961834E-004, +-1.265939046E-002, +-4.490280990E-004, ++7.817269652E-004, +-1.313448418E-002, +-5.099929986E-004, ++6.114174030E-004, +-1.359948888E-002, +-1.405300573E-002, ++1.572482102E-002, ++4.935106263E-004, +-1.449365262E-002, ++1.533095632E-002, ++2.382978710E-004, +-1.492007636E-002, ++1.492007636E-002, ++2.719412748E-007, +-1.533095632E-002, ++1.449365262E-002, +-2.206075296E-004, +-1.572482102E-002, ++1.405300573E-002, +-4.244441516E-004, +-1.610082202E-002, ++1.359948888E-002, +-6.114174030E-004, +-1.645756140E-002, ++1.313448418E-002, +-7.817269652E-004, +-1.679391414E-002, ++1.265939046E-002, +-9.358961834E-004, +-1.710879989E-002, ++1.217562053E-002, +-1.073757303E-003, +-1.740120351E-002, ++1.168460958E-002, +-1.196175464E-003, +-1.767017506E-002, ++1.118756086E-002, +-1.303116791E-003, +-1.791484281E-002, ++1.068630442E-002, +-1.395521569E-003, +-1.813439466E-002, ++1.018219907E-002, +-1.479332102E-003, +-1.832821220E-002, ++9.676489048E-003, +-1.542080659E-003, +-1.849545911E-002, ++9.170533158E-003, ++1.593449386E-003, +-1.863567345E-002, ++8.665001951E-003, ++1.633993932E-003, +-1.874836907E-002, ++8.162760176E-003, ++1.656501088E-003, +-1.883326657E-002, ++7.664063945E-003, ++1.672798418E-003, +-1.889026538E-002, ++7.170005701E-003, ++1.678415807E-003, +-1.891860925E-002, ++6.683901884E-003, ++1.674512983E-003, ++1.891860925E-002, ++6.203945260E-003, ++1.661288203E-003, ++1.889026538E-002, ++5.732392892E-003, ++1.640390139E-003, ++1.883326657E-002, ++5.270531867E-003, ++1.611457788E-003, ++1.874836907E-002, ++4.819062538E-003, ++1.575609902E-003, ++1.863567345E-002, ++4.379155114E-003, ++1.533520175E-003, ++1.849545911E-002, ++3.951539751E-003, ++1.485876855E-003, ++1.832821220E-002, ++3.537061159E-003, ++1.433344092E-003, ++1.813439466E-002, ++3.136433195E-003, ++1.376571832E-003, ++1.791484281E-002, ++2.750317100E-003, ++1.316190348E-003, ++1.767017506E-002, ++2.379294252E-003, ++1.252829796E-003, ++1.740120351E-002, ++2.023874084E-003, ++1.183370827E-003, ++1.710879989E-002, ++1.684492454E-003, ++1.115717343E-003, ++1.679391414E-002, ++1.361547387E-003, ++1.046945457E-003, ++1.645756140E-002, ++1.055365428E-003, ++9.775133803E-004, ++1.610082202E-002, ++7.658848190E-004, ++9.078957955E-004, ++8.385353722E-004, +-8.757545584E-005, +-6.084746474E-006, ++7.698345580E-004, +-8.413690375E-005, +-3.086857760E-006, ++7.021900383E-004, +-7.513730816E-005, +-7.198007665E-007, ++6.358824321E-004, +-6.568001118E-005, ++1.853591357E-006, ++5.729619297E-004, +-5.610509834E-005, ++1.470520488E-006, ++5.099929986E-004, +-4.624524081E-005, ++9.984935332E-007, ++4.490280990E-004, +-1.774702469E-005, ++5.633860383E-007, ++3.906481725E-004, +-1.992636317E-005, ++6.993315310E-006, ++3.347633174E-004, ++1.617751332E-005, ++1.207003334E-005, ++2.682086197E-004, ++1.521241393E-005, ++1.661818715E-005, ++2.233728592E-004, +-2.525620175E-006, ++1.776598037E-005, ++1.774113771E-004, +-1.191342653E-005, ++1.806914770E-005, ++1.312203676E-004, +-1.985177369E-005, ++2.677291741E-005, ++1.024175072E-004, +-2.570833203E-005, ++2.978993689E-005, ++6.541742187E-005, +-3.018750249E-005, ++3.225446198E-005, ++3.193307566E-005, +-2.554462844E-005, ++3.397853652E-005, ++1.714242217E-006, +-2.618136386E-005, ++3.495384954E-005, +-2.470704203E-005, +-2.537086584E-005, ++3.515914432E-005, +-4.491530854E-005, +-2.362549276E-005, ++3.460439257E-005, +-6.447290798E-005, +-2.093936746E-005, ++3.334947178E-005, +-8.078388782E-005, +-1.751866148E-005, ++3.144468428E-005, +-9.417100227E-005, +-1.356193479E-005, +-2.042970118E-005, +-1.047207043E-004, +-9.299508747E-006, +-1.987093310E-005, +-1.126275165E-004, +-4.916387297E-006, +-1.884208177E-005, +-1.180980107E-004, +-5.595519906E-005, +-1.743183020E-005, +-1.213575742E-004, +-5.429694284E-005, +-1.571428584E-005, +-1.226499153E-004, +-5.176846025E-005, +-1.379448349E-005, +-1.262027217E-004, +-4.839275425E-005, +-1.177108606E-005, +-1.250260248E-004, +-4.425736552E-005, +-9.826449968E-006, +-1.224978914E-004, +-3.946387005E-005, +-7.869333785E-006, +-1.187910311E-004, +-3.415624451E-005, +-2.319611212E-006, +-1.140582463E-004, +-2.847247197E-005, +-3.157242645E-006, +-1.084438481E-004, +-2.263354872E-005, +-3.617151151E-006, +-1.020687996E-004, +-1.309637537E-005, +-2.497214155E-006, +-9.517164290E-005, +-9.561075785E-006, +-1.189317118E-006, +-6.437721822E-008, +-4.195037945E-006, +-1.194632091E-006, +-8.434094667E-008, +-3.453840463E-006, +-1.162929266E-006, ++3.809887872E-008, +-2.715013807E-006, +-1.085227950E-006, ++3.246264413E-008, +-2.032118118E-006, +-9.742954035E-007, +-6.402664354E-008, +-1.399798180E-006, +-8.419976893E-007, +-2.975164826E-008, +-3.132386439E-007, +-7.003467317E-007, +-9.458596395E-008, +-1.444918922E-007, ++5.564140224E-007, +-4.341498823E-007, +-2.788728892E-008, ++6.262345096E-007, +-8.427224429E-007, +-7.506701927E-009, ++6.767839409E-007, +-3.332600045E-006, +-1.314406006E-008, ++7.020648809E-007, +-4.429412002E-006, ++3.399493131E-009, ++6.982898526E-007, +-5.315936960E-006, ++2.682709610E-009, ++6.628192182E-007, +-6.225028756E-006, ++1.613285505E-009, ++6.022448247E-007, +-6.986399967E-006, ++6.702406963E-010, ++4.741137047E-007, +-7.568834008E-006, +-7.834767501E-008, ++3.970030775E-007, +-7.941360309E-006, +-2.014677420E-007, ++7.342250683E-007, +-8.087732567E-006, +-5.234479659E-007, ++3.961981463E-007, +-8.006985809E-006, +-1.190443072E-006, ++1.543309907E-007, +-6.361419310E-006, +-1.975324267E-006, ++5.083275667E-008, +-6.015239251E-006, +-9.451737242E-007, ++1.608403011E-008, +-5.516381407E-006, +-1.033426656E-006, +-7.018770981E-011, +-4.896494374E-006, +-1.179182050E-006, +-1.135985195E-010 +}; + +static const float fir_32bands_nonperfect[] = +{ +-1.390191784E-007, +-1.693738625E-007, +-2.030677564E-007, +-2.404238444E-007, +-2.818143514E-007, +-3.276689142E-007, +-3.784752209E-007, +-4.347855338E-007, +-4.972276315E-007, +-5.665120852E-007, +-6.434325428E-007, +-7.288739425E-007, +-8.238164355E-007, +-9.293416952E-007, +-1.046637067E-006, +-1.176999604E-006, +-1.321840614E-006, +-1.482681114E-006, +-1.661159786E-006, +-1.859034001E-006, +-2.078171747E-006, +-2.320550948E-006, +-2.588257530E-006, +-2.883470643E-006, +-3.208459020E-006, +-3.565570978E-006, +-3.957220997E-006, +-4.385879038E-006, +-4.854050530E-006, +-5.364252502E-006, +-5.918994248E-006, +-6.520755960E-006, +-7.171964626E-006, +-7.874960829E-006, +-8.631964192E-006, +-9.445050637E-006, +-1.031611009E-005, +-1.124680875E-005, +-1.223855270E-005, +-1.329243969E-005, +-1.440921824E-005, +-1.558924305E-005, +-1.683242772E-005, +-1.813820381E-005, +-1.950545993E-005, +-2.093250441E-005, +-2.241701623E-005, +-2.395598858E-005, +-2.554569073E-005, +-2.718161704E-005, +-2.885844333E-005, +-3.056998685E-005, +-3.230916263E-005, +-3.406793985E-005, +-3.583733633E-005, +-3.760734762E-005, +-3.936696885E-005, +-4.110412556E-005, +-4.280570283E-005, +-4.445751256E-005, +-4.604430433E-005, +-4.754976908E-005, +-4.895655002E-005, +-5.024627535E-005, ++5.139957648E-005, ++5.239612074E-005, ++5.321469871E-005, ++5.383323878E-005, ++5.422891263E-005, ++5.437819709E-005, ++5.425697600E-005, ++5.384063843E-005, ++5.310418419E-005, ++5.202236207E-005, ++5.056979353E-005, ++4.872112549E-005, ++4.645117951E-005, ++4.373511547E-005, ++4.054862075E-005, ++3.686808850E-005, ++3.267079956E-005, ++2.793515523E-005, ++2.264085742E-005, ++1.676913780E-005, ++1.030297699E-005, ++3.227306706E-006, +-4.470633485E-006, +-1.280130618E-005, +-2.177240640E-005, +-3.138873581E-005, +-4.165195787E-005, +-5.256036457E-005, +-6.410864444E-005, +-7.628766616E-005, +-8.908427117E-005, +-1.024810626E-004, +-1.164562127E-004, +-1.309833024E-004, +-1.460311323E-004, +-1.615635992E-004, +-1.775395358E-004, +-1.939126523E-004, +-2.106313768E-004, +-2.276388550E-004, +-2.448728774E-004, +-2.622658503E-004, +-2.797449124E-004, +-2.972317743E-004, +-3.146430245E-004, +-3.318900708E-004, +-3.488793736E-004, +-3.655125911E-004, +-3.816867538E-004, +-3.972945851E-004, +-4.122247046E-004, +-4.263620067E-004, +-4.395879805E-004, +-4.517810594E-004, +-4.628172028E-004, +-4.725702747E-004, +-4.809123348E-004, +-4.877146275E-004, +-4.928477574E-004, +-4.961824161E-004, +-4.975944757E-004, +-4.969481961E-004, +-4.941228544E-004, +-4.889960401E-004, ++4.814492422E-004, ++4.713678791E-004, ++4.586426076E-004, ++4.431701091E-004, ++4.248536134E-004, ++4.036037717E-004, ++3.793396754E-004, ++3.519894381E-004, ++3.214911267E-004, ++2.877934603E-004, ++2.508567995E-004, ++2.106537577E-004, ++1.671699720E-004, ++1.204049113E-004, ++7.037253090E-005, ++1.710198012E-005, +-3.936182839E-005, +-9.895755647E-005, +-1.616069785E-004, +-2.272142592E-004, +-2.956659591E-004, +-3.668301215E-004, +-4.405563814E-004, +-5.166754709E-004, +-5.949990009E-004, +-6.753197522E-004, +-7.574109477E-004, +-8.410271257E-004, +-9.259034996E-004, +-1.011756598E-003, +-1.098284614E-003, +-1.185167348E-003, +-1.272067428E-003, +-1.358630019E-003, +-1.444484224E-003, +-1.529243193E-003, +-1.612505526E-003, +-1.693855622E-003, +-1.772865304E-003, +-1.849094522E-003, +-1.922092517E-003, +-1.991399564E-003, +-2.056547208E-003, +-2.117061289E-003, +-2.172462177E-003, +-2.222266514E-003, +-2.265989315E-003, +-2.303145360E-003, +-2.333251061E-003, +-2.355825622E-003, +-2.370394068E-003, +-2.376487479E-003, +-2.373647178E-003, +-2.361423569E-003, +-2.339380793E-003, +-2.307097195E-003, +-2.264167881E-003, +-2.210205887E-003, +-2.144844970E-003, +-2.067740774E-003, +-1.978572691E-003, +-1.877046190E-003, +-1.762894331E-003, +-1.635878929E-003, ++1.495792647E-003, ++1.342460280E-003, ++1.175740734E-003, ++9.955273708E-004, ++8.017504588E-004, ++5.943773431E-004, ++3.734139318E-004, ++1.389056415E-004, +-1.090620208E-004, +-3.703625989E-004, +-6.448282511E-004, +-9.322494152E-004, +-1.232374110E-003, +-1.544908970E-003, +-1.869517611E-003, +-2.205822384E-003, +-2.553403843E-003, +-2.911801683E-003, +-3.280514618E-003, +-3.659002949E-003, +-4.046686925E-003, +-4.442950245E-003, +-4.847140983E-003, +-5.258570891E-003, +-5.676518660E-003, +-6.100233644E-003, +-6.528933067E-003, +-6.961807609E-003, +-7.398022339E-003, +-7.836719044E-003, +-8.277016692E-003, +-8.718019351E-003, +-9.158811532E-003, +-9.598465636E-003, +-1.003604382E-002, +-1.047059800E-002, +-1.090117730E-002, +-1.132682897E-002, +-1.174659748E-002, +-1.215953380E-002, +-1.256469358E-002, +-1.296114177E-002, +-1.334795821E-002, +-1.372423489E-002, +-1.408908330E-002, +-1.444163360E-002, +-1.478104480E-002, +-1.510649733E-002, +-1.541720331E-002, +-1.571240649E-002, +-1.599138230E-002, +-1.625344716E-002, +-1.649795473E-002, +-1.672429405E-002, +-1.693190821E-002, +-1.712027565E-002, +-1.728892699E-002, +-1.743743755E-002, +-1.756543480E-002, +-1.767260395E-002, +-1.775865816E-002, +-1.782339066E-002, +-1.786663756E-002, +-1.788828894E-002, ++1.788828894E-002, ++1.786663756E-002, ++1.782339066E-002, ++1.775865816E-002, ++1.767260395E-002, ++1.756543480E-002, ++1.743743755E-002, ++1.728892699E-002, ++1.712027565E-002, ++1.693190821E-002, ++1.672429405E-002, ++1.649795473E-002, ++1.625344716E-002, ++1.599138230E-002, ++1.571240649E-002, ++1.541720331E-002, ++1.510649733E-002, ++1.478104480E-002, ++1.444163360E-002, ++1.408908330E-002, ++1.372423489E-002, ++1.334795821E-002, ++1.296114177E-002, ++1.256469358E-002, ++1.215953380E-002, ++1.174659748E-002, ++1.132682897E-002, ++1.090117730E-002, ++1.047059800E-002, ++1.003604382E-002, ++9.598465636E-003, ++9.158811532E-003, ++8.718019351E-003, ++8.277016692E-003, ++7.836719044E-003, ++7.398022339E-003, ++6.961807609E-003, ++6.528933067E-003, ++6.100233644E-003, ++5.676518660E-003, ++5.258570891E-003, ++4.847140983E-003, ++4.442950245E-003, ++4.046686925E-003, ++3.659002949E-003, ++3.280514618E-003, ++2.911801683E-003, ++2.553403843E-003, ++2.205822384E-003, ++1.869517611E-003, ++1.544908970E-003, ++1.232374110E-003, ++9.322494152E-004, ++6.448282511E-004, ++3.703625989E-004, ++1.090620208E-004, +-1.389056415E-004, +-3.734139318E-004, +-5.943773431E-004, +-8.017504588E-004, +-9.955273708E-004, +-1.175740734E-003, +-1.342460280E-003, +-1.495792647E-003, ++1.635878929E-003, ++1.762894331E-003, ++1.877046190E-003, ++1.978572691E-003, ++2.067740774E-003, ++2.144844970E-003, ++2.210205887E-003, ++2.264167881E-003, ++2.307097195E-003, ++2.339380793E-003, ++2.361423569E-003, ++2.373647178E-003, ++2.376487479E-003, ++2.370394068E-003, ++2.355825622E-003, ++2.333251061E-003, ++2.303145360E-003, ++2.265989315E-003, ++2.222266514E-003, ++2.172462177E-003, ++2.117061289E-003, ++2.056547208E-003, ++1.991399564E-003, ++1.922092517E-003, ++1.849094522E-003, ++1.772865304E-003, ++1.693855622E-003, ++1.612505526E-003, ++1.529243193E-003, ++1.444484224E-003, ++1.358630019E-003, ++1.272067428E-003, ++1.185167348E-003, ++1.098284614E-003, ++1.011756598E-003, ++9.259034996E-004, ++8.410271257E-004, ++7.574109477E-004, ++6.753197522E-004, ++5.949990009E-004, ++5.166754709E-004, ++4.405563814E-004, ++3.668301215E-004, ++2.956659591E-004, ++2.272142592E-004, ++1.616069785E-004, ++9.895755647E-005, ++3.936182839E-005, +-1.710198012E-005, +-7.037253090E-005, +-1.204049113E-004, +-1.671699720E-004, +-2.106537577E-004, +-2.508567995E-004, +-2.877934603E-004, +-3.214911267E-004, +-3.519894381E-004, +-3.793396754E-004, +-4.036037717E-004, +-4.248536134E-004, +-4.431701091E-004, +-4.586426076E-004, +-4.713678791E-004, +-4.814492422E-004, ++4.889960401E-004, ++4.941228544E-004, ++4.969481961E-004, ++4.975944757E-004, ++4.961824161E-004, ++4.928477574E-004, ++4.877146275E-004, ++4.809123348E-004, ++4.725702747E-004, ++4.628172028E-004, ++4.517810594E-004, ++4.395879805E-004, ++4.263620067E-004, ++4.122247046E-004, ++3.972945851E-004, ++3.816867538E-004, ++3.655125911E-004, ++3.488793736E-004, ++3.318900708E-004, ++3.146430245E-004, ++2.972317743E-004, ++2.797449124E-004, ++2.622658503E-004, ++2.448728774E-004, ++2.276388550E-004, ++2.106313768E-004, ++1.939126523E-004, ++1.775395358E-004, ++1.615635992E-004, ++1.460311323E-004, ++1.309833024E-004, ++1.164562127E-004, ++1.024810626E-004, ++8.908427117E-005, ++7.628766616E-005, ++6.410864444E-005, ++5.256036457E-005, ++4.165195787E-005, ++3.138873581E-005, ++2.177240640E-005, ++1.280130618E-005, ++4.470633485E-006, +-3.227306706E-006, +-1.030297699E-005, +-1.676913780E-005, +-2.264085742E-005, +-2.793515523E-005, +-3.267079956E-005, +-3.686808850E-005, +-4.054862075E-005, +-4.373511547E-005, +-4.645117951E-005, +-4.872112549E-005, +-5.056979353E-005, +-5.202236207E-005, +-5.310418419E-005, +-5.384063843E-005, +-5.425697600E-005, +-5.437819709E-005, +-5.422891263E-005, +-5.383323878E-005, +-5.321469871E-005, +-5.239612074E-005, +-5.139957648E-005, ++5.024627535E-005, ++4.895655002E-005, ++4.754976908E-005, ++4.604430433E-005, ++4.445751256E-005, ++4.280570283E-005, ++4.110412556E-005, ++3.936696885E-005, ++3.760734762E-005, ++3.583733633E-005, ++3.406793985E-005, ++3.230916263E-005, ++3.056998685E-005, ++2.885844333E-005, ++2.718161704E-005, ++2.554569073E-005, ++2.395598858E-005, ++2.241701623E-005, ++2.093250441E-005, ++1.950545993E-005, ++1.813820381E-005, ++1.683242772E-005, ++1.558924305E-005, ++1.440921824E-005, ++1.329243969E-005, ++1.223855270E-005, ++1.124680875E-005, ++1.031611009E-005, ++9.445050637E-006, ++8.631964192E-006, ++7.874960829E-006, ++7.171964626E-006, ++6.520755960E-006, ++5.918994248E-006, ++5.364252502E-006, ++4.854050530E-006, ++4.385879038E-006, ++3.957220997E-006, ++3.565570978E-006, ++3.208459020E-006, ++2.883470643E-006, ++2.588257530E-006, ++2.320550948E-006, ++2.078171747E-006, ++1.859034001E-006, ++1.661159786E-006, ++1.482681114E-006, ++1.321840614E-006, ++1.176999604E-006, ++1.046637067E-006, ++9.293416952E-007, ++8.238164355E-007, ++7.288739425E-007, ++6.434325428E-007, ++5.665120852E-007, ++4.972276315E-007, ++4.347855338E-007, ++3.784752209E-007, ++3.276689142E-007, ++2.818143514E-007, ++2.404238444E-007, ++2.030677564E-007, ++1.693738625E-007, ++1.390191784E-007 +}; + +//FIXME the coeffs are symmetric +static const float lfe_fir_64[] = +{ +2.6584343868307770E-004, +8.1793652498163280E-005, +9.4393239123746760E-005, +1.0821702744578940E-004, +1.2333714403212070E-004, +1.3974857574794440E-004, +1.5759580128360540E-004, +1.7699223826639360E-004, +1.9817386055365200E-004, +2.2118473134469240E-004, +2.4602311896160240E-004, +2.7261159266345200E-004, +3.0138631700538100E-004, +3.3283955417573450E-004, +3.6589911906048660E-004, +4.0182814700528980E-004, +4.4018754852004350E-004, +4.8127761692740020E-004, +5.2524596685543660E-004, +5.7215924607589840E-004, +6.2221300322562460E-004, +6.7555153509601950E-004, +7.3241489008069040E-004, +7.9285167157649990E-004, +8.5701106581836940E-004, +9.2511920956894760E-004, +9.9747709464281800E-004, +1.0739302961155770E-003, +1.1550235794857140E-003, +1.2406768510118130E-003, +1.3312589144334200E-003, +1.4268938684836030E-003, +1.5278297942131760E-003, +1.6342115122824910E-003, +1.7463274998590350E-003, +1.8643775256350640E-003, +1.9886041991412640E-003, +2.1191518753767010E-003, +2.2563596721738580E-003, +2.4004334118217230E-003, +2.5515670422464610E-003, +2.7100932784378530E-003, +2.8761904686689380E-003, +3.0501529108732940E-003, +3.2322725746780640E-003, +3.4227769356220960E-003, +3.6219672765582800E-003, +3.8300913292914630E-003, +4.0474990382790560E-003, +4.2744171805679800E-003, +4.5111598446965220E-003, +4.7580120153725150E-003, +5.0153112970292570E-003, +5.2832840010523800E-003, +5.5623454973101620E-003, +5.8526843786239620E-003, +6.1547122895717620E-003, +6.4686913974583150E-003, +6.7949919030070300E-003, +7.1338820271193980E-003, +7.4857366271317010E-003, +7.8508658334612850E-003, +8.2296309992671010E-003, +8.6223213002085690E-003, +9.0293306857347480E-003, +9.4509534537792200E-003, +9.8875602707266800E-003, +1.0339494794607160E-002, +1.0807084850966930E-002, +1.1290682479739190E-002, +1.1790650896728040E-002, +1.2307321652770040E-002, +1.2841059826314450E-002, +1.3392185792326930E-002, +1.3961089774966240E-002, +1.4548087492585180E-002, +1.5153550542891020E-002, +1.5777811408042910E-002, +1.6421230509877200E-002, +1.7084129154682160E-002, +1.7766902223229410E-002, +1.8469827249646190E-002, +1.9193304702639580E-002, +1.9937623292207720E-002, +2.0703161135315900E-002, +2.1490212529897690E-002, +2.2299138829112050E-002, +2.3130238056182860E-002, +2.3983856663107870E-002, +2.4860285222530360E-002, +2.5759860873222350E-002, +2.6682861149311060E-002, +2.7629608288407320E-002, +2.8600392863154410E-002, +2.9595496132969860E-002, +3.0615204945206640E-002, +3.1659796833992000E-002, +3.2729536294937140E-002, +3.3824689686298370E-002, +3.4945506602525710E-002, +3.6092240363359450E-002, +3.7265110760927200E-002, +3.8464374840259550E-002, +3.9690230041742320E-002, +4.0942888706922530E-002, +4.2222552001476290E-002, +4.3529424816370010E-002, +4.4863656163215640E-002, +4.6225443482398990E-002, +4.7614917159080510E-002, +4.9032241106033330E-002, +5.0477534532547000E-002, +5.1950931549072270E-002, +5.3452525287866590E-002, +5.4982420057058330E-002, +5.6540694087743760E-002, +5.8127421885728840E-002, +5.9742655605077740E-002, +6.1386436223983760E-002, +6.3058786094188690E-002, +6.4759708940982820E-002, +6.6489234566688540E-002, +6.8247318267822270E-002, +7.0033922791481020E-002, +7.1849010884761810E-002, +7.3692522943019870E-002, +7.5564362108707430E-002, +7.7464438974857330E-002, +7.9392634332180020E-002, +8.1348828971385960E-002, +8.3332858979702000E-002, +8.5344567894935610E-002, +8.7383769452571870E-002, +8.9450262486934660E-002, +9.1543838381767280E-002, +9.3664251267910000E-002, +9.5811240375041960E-002, +9.7984537482261660E-002, +1.0018386691808700E-001, +1.0240890830755230E-001, +1.0465932637453080E-001, +1.0693479329347610E-001, +1.0923493653535840E-001, +1.1155936866998670E-001, +1.1390769481658940E-001, +1.1627949774265290E-001, +1.1867434531450270E-001, +1.2109176814556120E-001, +1.2353130429983140E-001, +1.2599244713783260E-001, +1.2847468256950380E-001, +1.3097748160362240E-001, +1.3350030779838560E-001, +1.3604259490966800E-001, +1.3860376179218290E-001, +1.4118319749832150E-001, +1.4378026127815250E-001, +1.4639437198638920E-001, +1.4902481436729430E-001, +1.5167096257209780E-001, +1.5433208644390100E-001, +1.5700751543045040E-001, +1.5969651937484740E-001, +1.6239835321903230E-001, +1.6511227190494540E-001, +1.6783750057220460E-001, +1.7057323455810550E-001, +1.7331869900226590E-001, +1.7607308924198150E-001, +1.7883554100990300E-001, +1.8160524964332580E-001, +1.8438133597373960E-001, +1.8716295063495640E-001, +1.8994916975498200E-001, +1.9273911416530610E-001, +1.9553191959857940E-001, +1.9832661747932440E-001, +2.0112232863903040E-001, +2.0391805469989780E-001, +2.0671287178993220E-001, +2.0950584113597870E-001, +2.1229594945907590E-001, +2.1508227288722990E-001, +2.1786379814147950E-001, +2.2063951194286350E-001, +2.2340846061706540E-001, +2.2616961598396300E-001, +2.2892196476459500E-001, +2.3166447877883910E-001, +2.3439615964889520E-001, +2.3711597919464110E-001, +2.3982289433479310E-001, +2.4251587688922880E-001, +2.4519388377666480E-001, +2.4785590171813960E-001, +2.5050088763237000E-001, +2.5312781333923340E-001, +2.5573557615280150E-001, +2.5832322239875800E-001, +2.6088967919349670E-001, +2.6343390345573420E-001, +2.6595494151115420E-001, +2.6845166087150580E-001, +2.7092313766479490E-001, +2.7336826920509340E-001, +2.7578607201576240E-001, +2.7817553281784060E-001, +2.8053569793701170E-001, +2.8286558389663700E-001, +2.8516408801078800E-001, +2.8743034601211550E-001, +2.8966337442398070E-001, +2.9186218976974480E-001, +2.9402589797973640E-001, +2.9615348577499390E-001, +2.9824411869049070E-001, +3.0029675364494320E-001, +3.0231067538261420E-001, +3.0428490042686460E-001, +3.0621853470802300E-001, +3.0811080336570740E-001, +3.0996081233024600E-001, +3.1176769733428960E-001, +3.1353080272674560E-001, +3.1524917483329780E-001, +3.1692212820053100E-001, +3.1854888796806340E-001, +3.2012873888015740E-001, +3.2166096568107600E-001, +3.2314485311508180E-001, +3.2457971572875980E-001, +3.2596495747566220E-001, +3.2729989290237420E-001, +3.2858389616012580E-001, +3.2981643080711360E-001, +3.3099696040153500E-001, +3.3212485909461980E-001, +3.3319962024688720E-001, +3.3422079682350160E-001, +3.3518791198730470E-001, +3.3610042929649360E-001, +3.3695802092552180E-001, +3.3776029944419860E-001, +3.3850681781768800E-001, +3.3919724822044380E-001, +3.3983129262924200E-001, +3.4040865302085880E-001, +3.4092903137207030E-001, +3.4139221906661980E-001, +3.4179797768592840E-001, +3.4214612841606140E-001, +3.4243649244308470E-001, +3.4266895055770880E-001, +3.4284341335296630E-001, +3.4295973181724550E-001, +3.4301793575286860E-001, +3.4301793575286860E-001, +3.4295973181724550E-001, +3.4284341335296630E-001, +3.4266895055770880E-001, +3.4243649244308470E-001, +3.4214612841606140E-001, +3.4179797768592840E-001, +3.4139221906661980E-001, +3.4092903137207030E-001, +3.4040865302085880E-001, +3.3983129262924200E-001, +3.3919724822044380E-001, +3.3850681781768800E-001, +3.3776029944419860E-001, +3.3695802092552180E-001, +3.3610042929649360E-001, +3.3518791198730470E-001, +3.3422079682350160E-001, +3.3319962024688720E-001, +3.3212485909461980E-001, +3.3099696040153500E-001, +3.2981643080711360E-001, +3.2858389616012580E-001, +3.2729989290237420E-001, +3.2596495747566220E-001, +3.2457971572875980E-001, +3.2314485311508180E-001, +3.2166096568107600E-001, +3.2012873888015740E-001, +3.1854888796806340E-001, +3.1692212820053100E-001, +3.1524917483329780E-001, +3.1353080272674560E-001, +3.1176769733428960E-001, +3.0996081233024600E-001, +3.0811080336570740E-001, +3.0621853470802300E-001, +3.0428490042686460E-001, +3.0231067538261420E-001, +3.0029675364494320E-001, +2.9824411869049070E-001, +2.9615348577499390E-001, +2.9402589797973640E-001, +2.9186218976974480E-001, +2.8966337442398070E-001, +2.8743034601211550E-001, +2.8516408801078800E-001, +2.8286558389663700E-001, +2.8053569793701170E-001, +2.7817553281784060E-001, +2.7578607201576240E-001, +2.7336826920509340E-001, +2.7092313766479490E-001, +2.6845166087150580E-001, +2.6595494151115420E-001, +2.6343390345573420E-001, +2.6088967919349670E-001, +2.5832322239875800E-001, +2.5573557615280150E-001, +2.5312781333923340E-001, +2.5050088763237000E-001, +2.4785590171813960E-001, +2.4519388377666480E-001, +2.4251587688922880E-001, +2.3982289433479310E-001, +2.3711597919464110E-001, +2.3439615964889520E-001, +2.3166447877883910E-001, +2.2892196476459500E-001, +2.2616961598396300E-001, +2.2340846061706540E-001, +2.2063951194286350E-001, +2.1786379814147950E-001, +2.1508227288722990E-001, +2.1229594945907590E-001, +2.0950584113597870E-001, +2.0671287178993220E-001, +2.0391805469989780E-001, +2.0112232863903040E-001, +1.9832661747932440E-001, +1.9553191959857940E-001, +1.9273911416530610E-001, +1.8994916975498200E-001, +1.8716295063495640E-001, +1.8438133597373960E-001, +1.8160524964332580E-001, +1.7883554100990300E-001, +1.7607308924198150E-001, +1.7331869900226590E-001, +1.7057323455810550E-001, +1.6783750057220460E-001, +1.6511227190494540E-001, +1.6239835321903230E-001, +1.5969651937484740E-001, +1.5700751543045040E-001, +1.5433208644390100E-001, +1.5167096257209780E-001, +1.4902481436729430E-001, +1.4639437198638920E-001, +1.4378026127815250E-001, +1.4118319749832150E-001, +1.3860376179218290E-001, +1.3604259490966800E-001, +1.3350030779838560E-001, +1.3097748160362240E-001, +1.2847468256950380E-001, +1.2599244713783260E-001, +1.2353130429983140E-001, +1.2109176814556120E-001, +1.1867434531450270E-001, +1.1627949774265290E-001, +1.1390769481658940E-001, +1.1155936866998670E-001, +1.0923493653535840E-001, +1.0693479329347610E-001, +1.0465932637453080E-001, +1.0240890830755230E-001, +1.0018386691808700E-001, +9.7984537482261660E-002, +9.5811240375041960E-002, +9.3664251267910000E-002, +9.1543838381767280E-002, +8.9450262486934660E-002, +8.7383769452571870E-002, +8.5344567894935610E-002, +8.3332858979702000E-002, +8.1348828971385960E-002, +7.9392634332180020E-002, +7.7464438974857330E-002, +7.5564362108707430E-002, +7.3692522943019870E-002, +7.1849010884761810E-002, +7.0033922791481020E-002, +6.8247318267822270E-002, +6.6489234566688540E-002, +6.4759708940982820E-002, +6.3058786094188690E-002, +6.1386436223983760E-002, +5.9742655605077740E-002, +5.8127421885728840E-002, +5.6540694087743760E-002, +5.4982420057058330E-002, +5.3452525287866590E-002, +5.1950931549072270E-002, +5.0477534532547000E-002, +4.9032241106033330E-002, +4.7614917159080510E-002, +4.6225443482398990E-002, +4.4863656163215640E-002, +4.3529424816370010E-002, +4.2222552001476290E-002, +4.0942888706922530E-002, +3.9690230041742320E-002, +3.8464374840259550E-002, +3.7265110760927200E-002, +3.6092240363359450E-002, +3.4945506602525710E-002, +3.3824689686298370E-002, +3.2729536294937140E-002, +3.1659796833992000E-002, +3.0615204945206640E-002, +2.9595496132969860E-002, +2.8600392863154410E-002, +2.7629608288407320E-002, +2.6682861149311060E-002, +2.5759860873222350E-002, +2.4860285222530360E-002, +2.3983856663107870E-002, +2.3130238056182860E-002, +2.2299138829112050E-002, +2.1490212529897690E-002, +2.0703161135315900E-002, +1.9937623292207720E-002, +1.9193304702639580E-002, +1.8469827249646190E-002, +1.7766902223229410E-002, +1.7084129154682160E-002, +1.6421230509877200E-002, +1.5777811408042910E-002, +1.5153550542891020E-002, +1.4548087492585180E-002, +1.3961089774966240E-002, +1.3392185792326930E-002, +1.2841059826314450E-002, +1.2307321652770040E-002, +1.1790650896728040E-002, +1.1290682479739190E-002, +1.0807084850966930E-002, +1.0339494794607160E-002, +9.8875602707266800E-003, +9.4509534537792200E-003, +9.0293306857347480E-003, +8.6223213002085690E-003, +8.2296309992671010E-003, +7.8508658334612850E-003, +7.4857366271317010E-003, +7.1338820271193980E-003, +6.7949919030070300E-003, +6.4686913974583150E-003, +6.1547122895717620E-003, +5.8526843786239620E-003, +5.5623454973101620E-003, +5.2832840010523800E-003, +5.0153112970292570E-003, +4.7580120153725150E-003, +4.5111598446965220E-003, +4.2744171805679800E-003, +4.0474990382790560E-003, +3.8300913292914630E-003, +3.6219672765582800E-003, +3.4227769356220960E-003, +3.2322725746780640E-003, +3.0501529108732940E-003, +2.8761904686689380E-003, +2.7100932784378530E-003, +2.5515670422464610E-003, +2.4004334118217230E-003, +2.2563596721738580E-003, +2.1191518753767010E-003, +1.9886041991412640E-003, +1.8643775256350640E-003, +1.7463274998590350E-003, +1.6342115122824910E-003, +1.5278297942131760E-003, +1.4268938684836030E-003, +1.3312589144334200E-003, +1.2406768510118130E-003, +1.1550235794857140E-003, +1.0739302961155770E-003, +9.9747709464281800E-004, +9.2511920956894760E-004, +8.5701106581836940E-004, +7.9285167157649990E-004, +7.3241489008069040E-004, +6.7555153509601950E-004, +6.2221300322562460E-004, +5.7215924607589840E-004, +5.2524596685543660E-004, +4.8127761692740020E-004, +4.4018754852004350E-004, +4.0182814700528980E-004, +3.6589911906048660E-004, +3.3283955417573450E-004, +3.0138631700538100E-004, +2.7261159266345200E-004, +2.4602311896160240E-004, +2.2118473134469240E-004, +1.9817386055365200E-004, +1.7699223826639360E-004, +1.5759580128360540E-004, +1.3974857574794440E-004, +1.2333714403212070E-004, +1.0821702744578940E-004, +9.4393239123746760E-005, +8.1793652498163280E-005, +2.6584343868307770E-004 +}; + +//FIXME the coeffs are symmetric + +static const float lfe_fir_128[] = +{ +0.00053168571, +0.00016358691, +0.00018878609, +0.00021643363, +0.00024667382, +0.00027949660, +0.00031519096, +0.00035398375, +0.00039634691, +0.00044236859, +0.00049204525, +0.00054522208, +0.00060277141, +0.00066567765, +0.00073179678, +0.00080365466, +0.00088037323, +0.00096255314, +0.00105048984, +0.00114431616, +0.00124442333, +0.00135110028, +0.00146482687, +0.00158570008, +0.00171401864, +0.00185023469, +0.00199495023, +0.00214785640, +0.00231004250, +0.00248134881, +0.00266251224, +0.00285378192, +0.00305565330, +0.00326841651, +0.00349264755, +0.00372874714, +0.00397720048, +0.00423829490, +0.00451271003, +0.00480085658, +0.00510312291, +0.00542017492, +0.00575236930, +0.00610029325, +0.00646453211, +0.00684553990, +0.00724391919, +0.00766016589, +0.00809498038, +0.00854881573, +0.00902230106, +0.00951600447, +0.01003060210, +0.01056654565, +0.01112466771, +0.01170534454, +0.01230939943, +0.01293735672, +0.01358995494, +0.01426773332, +0.01497144438, +0.01570170000, +0.01645922661, +0.01724460535, +0.01805862412, +0.01890186779, +0.01977507770, +0.02067894675, +0.02161412500, +0.02258131653, +0.02358125709, +0.02461459488, +0.02568206564, +0.02678431384, +0.02792212367, +0.02909611352, +0.03030703776, +0.03155555204, +0.03284239396, +0.03416819125, +0.03553372994, +0.03693958372, +0.03838652745, +0.03987516090, +0.04140623659, +0.04298033938, +0.04459818453, +0.04626038298, +0.04796761274, +0.04972046614, +0.05151961371, +0.05336561054, +0.05525910854, +0.05720067024, +0.05919086933, +0.06123027951, +0.06331945211, +0.06545893103, +0.06764923781, +0.06989086419, +0.07218432426, +0.07453006506, +0.07692859322, +0.07938029617, +0.08188561350, +0.08444493264, +0.08705867827, +0.08972713351, +0.09245070815, +0.09522963315, +0.09806428105, +0.10095486045, +0.10390164703, +0.10690483451, +0.10996460915, +0.11308115721, +0.11625462025, +0.11948505789, +0.12277261168, +0.12611730397, +0.12951917946, +0.13297818601, +0.13649433851, +0.14006754756, +0.14369773865, +0.14738474786, +0.15112841129, +0.15492856503, +0.15878495574, +0.16269733012, +0.16666537523, +0.17068879306, +0.17476719618, +0.17890018225, +0.18308731914, +0.18732811511, +0.19162209332, +0.19596865773, +0.20036731660, +0.20481738448, +0.20931822062, +0.21386915445, +0.21846942604, +0.22311829031, +0.22781492770, +0.23255851865, +0.23734821379, +0.24218304455, +0.24706205726, +0.25198432803, +0.25694879889, +0.26195442677, +0.26700007915, +0.27208462358, +0.27720692754, +0.28236576915, +0.28755992651, +0.29278811812, +0.29804900289, +0.30334126949, +0.30866351724, +0.31401440501, +0.31939238310, +0.32479602098, +0.33022382855, +0.33567428589, +0.34114575386, +0.34663668275, +0.35214546323, +0.35767036676, +0.36320972443, +0.36876192689, +0.37432509661, +0.37989753485, +0.38547745347, +0.39106300473, +0.39665243030, +0.40224379301, +0.40783521533, +0.41342487931, +0.41901078820, +0.42459106445, +0.43016362190, +0.43572667241, +0.44127810001, +0.44681602716, +0.45233830810, +0.45784294605, +0.46332800388, +0.46879136562, +0.47423094511, +0.47964480519, +0.48503074050, +0.49038675427, +0.49571081996, +0.50100076199, +0.50625455379, +0.51147013903, +0.51664537191, +0.52177828550, +0.52686679363, +0.53190881014, +0.53690224886, +0.54184508324, +0.54673534632, +0.55157101154, +0.55634999275, +0.56107026339, +0.56572991610, +0.57032698393, +0.57485944033, +0.57932555676, +0.58372318745, +0.58805054426, +0.59230577946, +0.59648692608, +0.60059231520, +0.60462015867, +0.60856848955, +0.61243581772, +0.61622029543, +0.61992025375, +0.62353414297, +0.62706029415, +0.63049703836, +0.63384294510, +0.63709646463, +0.64025616646, +0.64332056046, +0.64628833532, +0.64915806055, +0.65192854404, +0.65459835529, +0.65716648102, +0.65963155031, +0.66199249029, +0.66424828768, +0.66639786959, +0.66844022274, +0.67037439346, +0.67219948769, +0.67391467094, +0.67551922798, +0.67701220512, +0.67839306593, +0.67966115475, +0.68081587553, +0.68185669184, +0.68278300762, +0.68359452486, +0.68429082632, +0.68487155437, +0.68533653021, +0.68568539619, +0.68591803312, +0.68603444099, +0.68603444099, +0.68591803312, +0.68568539619, +0.68533653021, +0.68487155437, +0.68429082632, +0.68359452486, +0.68278300762, +0.68185669184, +0.68081587553, +0.67966115475, +0.67839306593, +0.67701220512, +0.67551922798, +0.67391467094, +0.67219948769, +0.67037439346, +0.66844022274, +0.66639786959, +0.66424828768, +0.66199249029, +0.65963155031, +0.65716648102, +0.65459835529, +0.65192854404, +0.64915806055, +0.64628833532, +0.64332056046, +0.64025616646, +0.63709646463, +0.63384294510, +0.63049703836, +0.62706029415, +0.62353414297, +0.61992025375, +0.61622029543, +0.61243581772, +0.60856848955, +0.60462015867, +0.60059231520, +0.59648692608, +0.59230577946, +0.58805054426, +0.58372318745, +0.57932555676, +0.57485944033, +0.57032698393, +0.56572991610, +0.56107026339, +0.55634999275, +0.55157101154, +0.54673534632, +0.54184508324, +0.53690224886, +0.53190881014, +0.52686679363, +0.52177828550, +0.51664537191, +0.51147013903, +0.50625455379, +0.50100076199, +0.49571081996, +0.49038675427, +0.48503074050, +0.47964480519, +0.47423094511, +0.46879136562, +0.46332800388, +0.45784294605, +0.45233830810, +0.44681602716, +0.44127810001, +0.43572667241, +0.43016362190, +0.42459106445, +0.41901078820, +0.41342487931, +0.40783521533, +0.40224379301, +0.39665243030, +0.39106300473, +0.38547745347, +0.37989753485, +0.37432509661, +0.36876192689, +0.36320972443, +0.35767036676, +0.35214546323, +0.34663668275, +0.34114575386, +0.33567428589, +0.33022382855, +0.32479602098, +0.31939238310, +0.31401440501, +0.30866351724, +0.30334126949, +0.29804900289, +0.29278811812, +0.28755992651, +0.28236576915, +0.27720692754, +0.27208462358, +0.26700007915, +0.26195442677, +0.25694879889, +0.25198432803, +0.24706205726, +0.24218304455, +0.23734821379, +0.23255851865, +0.22781492770, +0.22311829031, +0.21846942604, +0.21386915445, +0.20931822062, +0.20481738448, +0.20036731660, +0.19596865773, +0.19162209332, +0.18732811511, +0.18308731914, +0.17890018225, +0.17476719618, +0.17068879306, +0.16666537523, +0.16269733012, +0.15878495574, +0.15492856503, +0.15112841129, +0.14738474786, +0.14369773865, +0.14006754756, +0.13649433851, +0.13297818601, +0.12951917946, +0.12611730397, +0.12277261168, +0.11948505789, +0.11625462025, +0.11308115721, +0.10996460915, +0.10690483451, +0.10390164703, +0.10095486045, +0.09806428105, +0.09522963315, +0.09245070815, +0.08972713351, +0.08705867827, +0.08444493264, +0.08188561350, +0.07938029617, +0.07692859322, +0.07453006506, +0.07218432426, +0.06989086419, +0.06764923781, +0.06545893103, +0.06331945211, +0.06123027951, +0.05919086933, +0.05720067024, +0.05525910854, +0.05336561054, +0.05151961371, +0.04972046614, +0.04796761274, +0.04626038298, +0.04459818453, +0.04298033938, +0.04140623659, +0.03987516090, +0.03838652745, +0.03693958372, +0.03553372994, +0.03416819125, +0.03284239396, +0.03155555204, +0.03030703776, +0.02909611352, +0.02792212367, +0.02678431384, +0.02568206564, +0.02461459488, +0.02358125709, +0.02258131653, +0.02161412500, +0.02067894675, +0.01977507770, +0.01890186779, +0.01805862412, +0.01724460535, +0.01645922661, +0.01570170000, +0.01497144438, +0.01426773332, +0.01358995494, +0.01293735672, +0.01230939943, +0.01170534454, +0.01112466771, +0.01056654565, +0.01003060210, +0.00951600447, +0.00902230106, +0.00854881573, +0.00809498038, +0.00766016589, +0.00724391919, +0.00684553990, +0.00646453211, +0.00610029325, +0.00575236930, +0.00542017492, +0.00510312291, +0.00480085658, +0.00451271003, +0.00423829490, +0.00397720048, +0.00372874714, +0.00349264755, +0.00326841651, +0.00305565330, +0.00285378192, +0.00266251224, +0.00248134881, +0.00231004250, +0.00214785640, +0.00199495023, +0.00185023469, +0.00171401864, +0.00158570008, +0.00146482687, +0.00135110028, +0.00124442333, +0.00114431616, +0.00105048984, +0.00096255314, +0.00088037323, +0.00080365466, +0.00073179678, +0.00066567765, +0.00060277141, +0.00054522208, +0.00049204525, +0.00044236859, +0.00039634691, +0.00035398375, +0.00031519096, +0.00027949660, +0.00024667382, +0.00021643363, +0.00018878609, +0.00016358691, +0.00053168571 +}; + +/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */ +/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */ + +static const float dca_downmix_coeffs[65] = { + 1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746, + 0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456, + 0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193, + 0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988, + 0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838, + 0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111, + 0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428, + 0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684, + 0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020, + 0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969, + 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, +}; + +static const uint8_t dca_default_coeffs[16][5][2] = { + { { 13, 13 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, }, + { { 0, 25 }, { 25, 0 }, { 13, 13 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, }, + { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, +}; + +/* downmix coeffs + + TABLE 9 +______________________________________ +Down-mix coefficients for 8-channel source +audio (5 + 3 format) + lt + cen- rt lt ctr rt +lt ter ctr center + rt srd srd srd +______________________________________ +1 0.71 0.74 1.0 0.71 0.71 0.58 0.58 0.58 +2 left 1.0 0.89 0.71 0.46 0.71 0.50 + rt 0.45 0.71 0.89 1.0 0.50 0.71 +3 lt 1.0 0.89 0.71 0.45 + rt 0.45 0.71 0.89 1.0 + srd 0.71 0.71 0.71 +4 lt 1.0 0.89 0.71 0.45 + rt 0.45 0.71 0.89 1.0 + lt srd 1.0 0.71 + rt srd 0.71 0.71 +4 lt 1.0 0.5 + ctr 0.87 1.0 0.87 + rt 0.5 1.0 + srd 0.71 0.71 0.71 +5 lt 1.0 0.5 + ctr 0.87 1.0 0.87 + rt 0.5 1.0 + lt srd 1.0 0.71 + rt srd 0.71 1.0 +6 lt 1.0 0.5 + lt ctr 0.87 0.71 + rt ctr 0.71 0.87 + rt 0.5 1.0 + lt srd 1.0 0.71 + rt srd 0.71 1.0 +6 lt 1.0 0.5 + ctr 0.86 1.0 0.86 + rt 0.5 1.0 + lt srd 1.0 + ctr srd 1.0 + rt srd 1.0 +7 lt 1.0 + lt ctr 1.0 + ctr 1.0 + rt ctr 1.0 + rt 1.0 + lt srd 1.0 0.71 + rt srd 0.71 1.0 +7 lt 1.0 0.5 + lt ctr 0.87 0.71 + rt ctr 0.71 0.87 + rt 0.5 1.0 + lt srd 1.0 + ctr srd 1.0 + rt srd 1.0 +8 lt 1.0 0.5 + lt ctr 0.87 0.71 + rt ctr 0.71 0.87 + rt 0.5 1.0 + lt 1 srd 0.87 0.35 + lt 2 srd 0.5 0.61 + rt 2 srd 0.61 0.50 + rt 2 srd 0.35 0.87 + + Generation of Lt Rt + +In the case when the playback system has analog or digital surround multi-channel capability, a down matrix from 5, 4, or 3 channel to Lt Rt may be desirable. In the case when the number of decoded audio channels exceeds 5, 4 or 3 respectively a first stage down mix to 5, 4 or 3 chs should be used as described above. + +The down matrixing equations for 5-channel source audio to a two-channel Lt Rt playback system are given by: + +Left left+0.7*center-0.7*(lt surround+rt surround) + +Right=right+0.7*center+0.7*(lt surround+rt surround) + +Embedded mixing to 2-channel + +One concern arising from the proliferation of multi-channel audio systems is that most home systems presently have only two channel playback capability. To accommodate this a fixed 2-channel down matrix processes is commonly used following the multi-channel decoding stage. However, for music only applications the image quality etc. of the down matrixed signal may not match that of an equivalent stereo recording found on CD. + +The concept of embedded mixing is to allow the producer to dynamically specify the matrixing coefficients within the audio frame itself. In this way the stereo down mix at the decoder may be better matched to a 2-channel playback environment. + +CHS*2, 7-bit down mix indexes (MCOEFFS) are transmitted along with the multi-channel audio once in every frame. The indexes are converted to attenuation factors using a 7 bit LUT. The 2-ch down mix equations are as follows, + +Left Ch=sum (MCOEFF[n]*Ch[n]) for n=1, CHS + +Right Ch sum (MCOEFF[n+CHS]*Ch[n]) for n=1, CHS + +where Ch(n) represents the subband samples in the (n)th audio channel. + + +*/ + +#endif /* FFMPEG_DCADATA_H */ diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dcahuff.h b/src/add-ons/media/plugins/avcodec/libavcodec/dcahuff.h new file mode 100644 index 0000000000..bdb05d55d0 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dcahuff.h @@ -0,0 +1,1076 @@ +/* + * DCA compatible decoder - huffman tables + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2007 Konstantin Shishkov + * + * 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 + */ + +#ifndef FFMPEG_DCAHUFF_H +#define FFMPEG_DCAHUFF_H + +#include +#include + +#define TMODE_COUNT 4 +static const uint8_t tmode_vlc_bits[TMODE_COUNT] = { 3, 3, 3, 2 }; +static const uint16_t tmode_codes[TMODE_COUNT][4] = { + { 0x0000, 0x0002, 0x0006, 0x0007 }, + { 0x0002, 0x0006, 0x0007, 0x0000 }, + { 0x0006, 0x0007, 0x0000, 0x0002 }, + { 0x0000, 0x0001, 0x0002, 0x0003 } +}; +static const uint8_t tmode_bits[TMODE_COUNT][4] = { + { 1, 2, 3, 3 }, + { 2, 3, 3, 1 }, + { 3, 3, 1, 2 }, + { 2, 2, 2, 2 } +}; + + +#define BITALLOC_12_COUNT 5 +#define BITALLOC_12_VLC_BITS 9 +static const uint8_t bitalloc_12_vlc_bits[BITALLOC_12_COUNT] = { + 9, 7, 7, 9, 9 +}; +static const uint16_t bitalloc_12_codes[BITALLOC_12_COUNT][12] = { + { + 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, 0x00FF, 0x00FE, + 0x01FB, 0x01FA, 0x01F9, 0x01F8, + }, + { + 0x0001, 0x0000, 0x0002, 0x000F, 0x000C, 0x001D, 0x0039, 0x0038, + 0x0037, 0x0036, 0x0035, 0x0034, + }, + { + 0x0000, 0x0007, 0x0005, 0x0004, 0x0002, 0x000D, 0x000C, 0x0006, + 0x000F, 0x001D, 0x0039, 0x0038, + }, + { + 0x0003, 0x0002, 0x0000, 0x0002, 0x0006, 0x000E, 0x001E, 0x003E, + 0x007E, 0x00FE, 0x01FF, 0x01FE, + }, + { + 0x0001, 0x0000, 0x0002, 0x0006, 0x000E, 0x003F, 0x003D, 0x007C, + 0x0079, 0x0078, 0x00FB, 0x00FA, + } +}; +static const uint8_t bitalloc_12_bits[BITALLOC_12_COUNT][12] = { + { 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 9, 9 }, + { 1, 2, 3, 5, 5, 6, 7, 7, 7, 7, 7, 7 }, + { 2, 3, 3, 3, 3, 4, 4, 4, 5, 6, 7, 7 }, + { 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 }, + { 1, 2, 3, 4, 5, 7, 7, 8, 8, 8, 9, 9 } +}; + + +#define SCALES_COUNT 5 +#define SCALES_VLC_BITS 9 +static const uint16_t scales_codes[SCALES_COUNT][129] = { + { + 0x3AB0, 0x3AB2, 0x3AB4, 0x3AB6, 0x3AB8, 0x3ABA, 0x3ABC, 0x3ABE, + 0x3AC0, 0x3AC2, 0x3AC4, 0x3AC6, 0x3AC8, 0x3ACA, 0x3ACC, 0x3ACE, + 0x3AD0, 0x3AD2, 0x3AD4, 0x3AD6, 0x3AD8, 0x3ADA, 0x3ADC, 0x3ADE, + 0x3AE0, 0x3AE2, 0x3AE4, 0x3AE6, 0x3AE8, 0x3AEA, 0x3AEC, 0x3AEE, + 0x3AF0, 0x3AF2, 0x3AF4, 0x3AF6, 0x3AF8, 0x3AFA, 0x3AFC, 0x3AFE, + 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E, + 0x0558, 0x055E, 0x02AD, 0x0154, 0x0754, 0x03A8, 0x0056, 0x0028, + 0x00E8, 0x004A, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005, + 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x004B, + 0x00E9, 0x0029, 0x0057, 0x03A9, 0x0755, 0x0155, 0x02AE, 0x055F, + 0x0559, 0x054F, 0x054D, 0x054B, 0x0549, 0x0547, 0x0545, 0x0543, + 0x0541, 0x3AFF, 0x3AFD, 0x3AFB, 0x3AF9, 0x3AF7, 0x3AF5, 0x3AF3, + 0x3AF1, 0x3AEF, 0x3AED, 0x3AEB, 0x3AE9, 0x3AE7, 0x3AE5, 0x3AE3, + 0x3AE1, 0x3ADF, 0x3ADD, 0x3ADB, 0x3AD9, 0x3AD7, 0x3AD5, 0x3AD3, + 0x3AD1, 0x3ACF, 0x3ACD, 0x3ACB, 0x3AC9, 0x3AC7, 0x3AC5, 0x3AC3, + 0x3AC1, 0x3ABF, 0x3ABD, 0x3ABB, 0x3AB9, 0x3AB7, 0x3AB5, 0x3AB3, + 0x3AB1, + }, + { + 0x0F60, 0x0F62, 0x0F64, 0x0F66, 0x0F68, 0x0F6A, 0x0F6C, 0x0F6E, + 0x0F70, 0x0F72, 0x0F74, 0x0F76, 0x0F78, 0x0F7A, 0x0F7C, 0x0F7E, + 0x0F80, 0x0F82, 0x0F84, 0x0F86, 0x0F88, 0x0F8A, 0x0F8C, 0x0F8E, + 0x0F90, 0x0F92, 0x0F94, 0x0F96, 0x0F98, 0x0F9A, 0x0F9C, 0x0F9E, + 0x0FA0, 0x0FA2, 0x0FA4, 0x0FA6, 0x0FA8, 0x0FAA, 0x0FAC, 0x0FAE, + 0x0FB0, 0x0FB2, 0x0FB4, 0x0FB6, 0x0FB8, 0x0FBA, 0x0FBC, 0x0FBE, + 0x07A0, 0x07A2, 0x03D2, 0x01EA, 0x00FC, 0x007F, 0x001C, 0x000C, + 0x0004, 0x0034, 0x0010, 0x001B, 0x0009, 0x000B, 0x000E, 0x0001, + 0x0003, 0x0002, 0x000F, 0x000C, 0x000A, 0x0000, 0x0011, 0x0035, + 0x0005, 0x000D, 0x001D, 0x003C, 0x00FD, 0x01EB, 0x03D3, 0x07A3, + 0x07A1, 0x0FBF, 0x0FBD, 0x0FBB, 0x0FB9, 0x0FB7, 0x0FB5, 0x0FB3, + 0x0FB1, 0x0FAF, 0x0FAD, 0x0FAB, 0x0FA9, 0x0FA7, 0x0FA5, 0x0FA3, + 0x0FA1, 0x0F9F, 0x0F9D, 0x0F9B, 0x0F99, 0x0F97, 0x0F95, 0x0F93, + 0x0F91, 0x0F8F, 0x0F8D, 0x0F8B, 0x0F89, 0x0F87, 0x0F85, 0x0F83, + 0x0F81, 0x0F7F, 0x0F7D, 0x0F7B, 0x0F79, 0x0F77, 0x0F75, 0x0F73, + 0x0F71, 0x0F6F, 0x0F6D, 0x0F6B, 0x0F69, 0x0F67, 0x0F65, 0x0F63, + 0x0F61, + }, + { + 0x51D0, 0x51D2, 0x51D4, 0x51D6, 0x51D8, 0x51DA, 0x51DC, 0x51DE, + 0x51E0, 0x51E2, 0x51E4, 0x51E6, 0x51E8, 0x51EA, 0x51EC, 0x51EE, + 0x51F0, 0x51F2, 0x51F4, 0x51F6, 0x51F8, 0x51FA, 0x51FC, 0x51FE, + 0x70C0, 0x70C2, 0x70C4, 0x70C6, 0x70C8, 0x70CA, 0x70CC, 0x70CE, + 0x70EC, 0x10EA, 0x3868, 0x3877, 0x0876, 0x1C35, 0x0434, 0x0A34, + 0x0E1B, 0x021B, 0x051B, 0x070F, 0x010F, 0x0380, 0x0080, 0x0140, + 0x01C1, 0x0041, 0x00A1, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012, + 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000, + 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B, + 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A2, 0x0042, + 0x01C2, 0x0141, 0x0081, 0x0381, 0x028C, 0x010C, 0x051C, 0x021C, + 0x0E1C, 0x0A35, 0x0435, 0x1C3A, 0x0877, 0x0874, 0x3869, 0x10EB, + 0x70ED, 0x70CF, 0x70CD, 0x70CB, 0x70C9, 0x70C7, 0x70C5, 0x70C3, + 0x70C1, 0x51FF, 0x51FD, 0x51FB, 0x51F9, 0x51F7, 0x51F5, 0x51F3, + 0x51F1, 0x51EF, 0x51ED, 0x51EB, 0x51E9, 0x51E7, 0x51E5, 0x51E3, + 0x51E1, 0x51DF, 0x51DD, 0x51DB, 0x51D9, 0x51D7, 0x51D5, 0x51D3, + 0x51D1, + }, + { + 0x6F64, 0x6F66, 0x6F68, 0x6F6A, 0x6F6C, 0x6F6E, 0x6F70, 0x6F72, + 0x6F74, 0x6F76, 0x6F78, 0x6F7A, 0x6F7C, 0x6F7E, 0x6F80, 0x6F82, + 0x6F84, 0x6F86, 0x6F88, 0x6F8A, 0x6F8C, 0x6F8E, 0x6F90, 0x6F92, + 0x6F94, 0x6F96, 0x6F98, 0x6F9A, 0x6F9C, 0x6F9E, 0x6FA0, 0x6FA2, + 0x6FA4, 0x6FA6, 0x6FA8, 0x6FAA, 0x6FAC, 0x6FAE, 0x6FB0, 0x6FB2, + 0x6FB4, 0x6FB6, 0x17B4, 0x37DC, 0x0BDB, 0x1BEF, 0x05EE, 0x0DF8, + 0x02F8, 0x06FD, 0x017D, 0x037F, 0x00BF, 0x0040, 0x00C0, 0x0021, + 0x0061, 0x0011, 0x0031, 0x0009, 0x0019, 0x0006, 0x000E, 0x0004, + 0x0000, 0x0005, 0x000F, 0x0007, 0x001A, 0x000A, 0x0036, 0x0016, + 0x006E, 0x002E, 0x00C1, 0x0041, 0x01BC, 0x00BC, 0x037A, 0x017A, + 0x02F9, 0x0DF9, 0x05EF, 0x05EC, 0x1BD8, 0x37DD, 0x17B5, 0x6FB7, + 0x6FB5, 0x6FB3, 0x6FB1, 0x6FAF, 0x6FAD, 0x6FAB, 0x6FA9, 0x6FA7, + 0x6FA5, 0x6FA3, 0x6FA1, 0x6F9F, 0x6F9D, 0x6F9B, 0x6F99, 0x6F97, + 0x6F95, 0x6F93, 0x6F91, 0x6F8F, 0x6F8D, 0x6F8B, 0x6F89, 0x6F87, + 0x6F85, 0x6F83, 0x6F81, 0x6F7F, 0x6F7D, 0x6F7B, 0x6F79, 0x6F77, + 0x6F75, 0x6F73, 0x6F71, 0x6F6F, 0x6F6D, 0x6F6B, 0x6F69, 0x6F67, + 0x6F65, + }, + { + 0xDF54, 0xDF56, 0xDFC8, 0xDFCA, 0xDFCC, 0xDFCE, 0xDFD0, 0xDFD2, + 0xDFD4, 0xDFD6, 0xDFD8, 0xDFDA, 0xDFDC, 0xDFDE, 0xDFE0, 0xDFE2, + 0x0FE8, 0x2FEA, 0x6FA8, 0x6FF6, 0x07F5, 0x07F7, 0x37D2, 0x37F9, + 0x03F8, 0x0BF8, 0x0BFB, 0x1BEB, 0x01FA, 0x05FA, 0x09FA, 0x0DFA, + 0x0DFF, 0x00FF, 0x02FF, 0x06FB, 0x007C, 0x017C, 0x027C, 0x027F, + 0x003C, 0x00BC, 0x013C, 0x01BC, 0x001C, 0x005C, 0x009C, 0x00DC, + 0x000C, 0x002C, 0x004C, 0x006C, 0x0004, 0x0014, 0x0024, 0x0034, + 0x0000, 0x0008, 0x0010, 0x0018, 0x001E, 0x0002, 0x0006, 0x000A, + 0x000E, 0x000B, 0x0007, 0x0003, 0x001F, 0x0019, 0x0011, 0x0009, + 0x0001, 0x0035, 0x0025, 0x0015, 0x0005, 0x006D, 0x004D, 0x002D, + 0x000D, 0x00DD, 0x009D, 0x005D, 0x001D, 0x01BD, 0x013D, 0x00BD, + 0x003D, 0x037C, 0x027D, 0x017D, 0x007D, 0x06FC, 0x04FC, 0x02FC, + 0x00FC, 0x0DFB, 0x09FB, 0x05FB, 0x01FB, 0x1BF8, 0x1BE8, 0x0BF9, + 0x03F9, 0x37FA, 0x37D3, 0x17F4, 0x07F6, 0x6FF7, 0x6FA9, 0x2FEB, + 0x0FE9, 0xDFE3, 0xDFE1, 0xDFDF, 0xDFDD, 0xDFDB, 0xDFD9, 0xDFD7, + 0xDFD5, 0xDFD3, 0xDFD1, 0xDFCF, 0xDFCD, 0xDFCB, 0xDFC9, 0xDF57, + 0xDF55, + } +}; + +static const uint8_t scales_bits[SCALES_COUNT][129] = { + { + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 12, 11, 11, 10, 9, 8, + 8, 7, 6, 6, 5, 4, 4, 3, + 2, 3, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, + }, + { + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 14, 14, 13, 12, 11, 10, 8, 7, + 6, 6, 5, 5, 4, 4, 4, 3, + 3, 3, 4, 4, 4, 4, 5, 6, + 6, 7, 8, 9, 11, 12, 13, 14, + 14, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, + }, + { + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 14, 14, 14, 13, 13, 12, 12, + 12, 11, 11, 11, 10, 10, 9, 9, + 9, 8, 8, 8, 7, 7, 7, 6, + 6, 6, 5, 5, 5, 4, 4, 3, + 3, 3, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, + 9, 9, 9, 10, 10, 10, 11, 11, + 12, 12, 12, 13, 13, 13, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, + }, + { + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 14, 14, 13, 13, 12, 12, + 11, 11, 10, 10, 9, 8, 8, 7, + 7, 6, 6, 5, 5, 4, 4, 3, + 2, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, + 11, 12, 12, 12, 13, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, + }, + { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 14, 14, 14, 14, + 13, 13, 13, 13, 12, 12, 12, 12, + 12, 11, 11, 11, 10, 10, 10, 10, + 9, 9, 9, 9, 8, 8, 8, 8, + 7, 7, 7, 7, 6, 6, 6, 6, + 5, 5, 5, 5, 5, 4, 4, 4, + 4, 4, 4, 4, 5, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 13, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, + 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, + } +}; + +static const uint16_t bitalloc_3_codes[3] = +{ + 0x0003, 0x0000, 0x0002, +}; +static const uint8_t bitalloc_3_bits[3] = +{ + 2, 1, 2, +}; + +static const uint16_t bitalloc_5_codes_a[5] = +{ + 0x000F, 0x0006, 0x0000, 0x0002, 0x000E, +}; +static const uint16_t bitalloc_5_codes_b[5] = +{ + 0x0007, 0x0001, 0x0002, 0x0000, 0x0006, +}; +static const uint16_t bitalloc_5_codes_c[5] = +{ + 0x0007, 0x0005, 0x0000, 0x0004, 0x0006, +}; +static const uint8_t bitalloc_5_bits_a[5] = +{ + 4, 3, 1, 2, 4, +}; +static const uint8_t bitalloc_5_bits_b[5] = +{ + 3, 2, 2, 2, 3, +}; +static const uint8_t bitalloc_5_bits_c[5] = +{ + 3, 3, 1, 3, 3, +}; + +static const uint16_t bitalloc_7_codes_a[7] = +{ + 0x001E, 0x000E, 0x0005, 0x0000, 0x0006, 0x0004, 0x001F, +}; +static const uint16_t bitalloc_7_codes_b[7] = +{ + 0x0014, 0x000B, 0x0000, 0x0003, 0x0001, 0x0004, 0x0015, +}; +static const uint16_t bitalloc_7_codes_c[7] = +{ + 0x0000, 0x0002, 0x0001, 0x0003, 0x0002, 0x0003, 0x0001, +}; +static const uint8_t bitalloc_7_bits_a[7] = +{ + 5, 4, 3, 1, 3, 3, 5, +}; +static const uint8_t bitalloc_7_bits_b[7] = +{ + 5, 4, 2, 2, 2, 3, 5, +}; +static const uint8_t bitalloc_7_bits_c[7] = +{ + 4, 4, 2, 2, 2, 4, 4, +}; + +static const uint16_t bitalloc_9_codes_a[9] = +{ + 0x0030, 0x0019, 0x0009, 0x0005, 0x0000, 0x0007, 0x000D, 0x0008, + 0x0031, +}; +static const uint16_t bitalloc_9_codes_b[9] = +{ + 0x0018, 0x001A, 0x0002, 0x0007, 0x0002, 0x0000, 0x0003, 0x001B, + 0x0019, +}; +static const uint16_t bitalloc_9_codes_c[9] = +{ + 0x001C, 0x000F, 0x0002, 0x0007, 0x0002, 0x0000, 0x0006, 0x0006, + 0x001D, +}; +static const uint8_t bitalloc_9_bits_a[9] = +{ + 6, 5, 4, 3, 1, 3, 4, 4, 6, +}; +static const uint8_t bitalloc_9_bits_b[9] = +{ + 5, 5, 3, 3, 2, 2, 3, 5, 5, +}; +static const uint8_t bitalloc_9_bits_c[9] = +{ + 6, 5, 3, 3, 2, 2, 3, 4, 6, +}; + +static const uint16_t bitalloc_13_codes_a[13] = +{ + 0x0070, 0x002E, 0x0039, 0x001D, 0x000C, 0x000F, 0x0000, 0x0004, + 0x000D, 0x000A, 0x0016, 0x002F, 0x0071, +}; +static const uint16_t bitalloc_13_codes_b[13] = +{ + 0x0038, 0x0010, 0x001D, 0x0007, 0x000F, 0x0005, 0x0000, 0x0006, + 0x0002, 0x0009, 0x0006, 0x0011, 0x0039, +}; +static const uint16_t bitalloc_13_codes_c[13] = +{ + 0x0004, 0x001A, 0x0003, 0x000E, 0x0000, 0x0003, 0x0005, 0x0004, + 0x0002, 0x000F, 0x000C, 0x001B, 0x0005, +}; +static const uint8_t bitalloc_13_bits_a[13] = +{ + 7, 6, 6, 5, 4, 4, 1, 3, 4, 4, 5, 6, 7, +}; +static const uint8_t bitalloc_13_bits_b[13] = +{ + 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 4, 5, 6, +}; +static const uint8_t bitalloc_13_bits_c[13] = +{ + 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, +}; + +static const uint16_t bitalloc_17_codes_a[17] = +{ + 0x0154, 0x00AB, 0x002B, 0x000B, 0x0003, 0x000A, 0x0001, 0x0006, + 0x0001, 0x0007, 0x0004, 0x000B, 0x0000, 0x0004, 0x0014, 0x0054, + 0x0155, +}; +static const uint16_t bitalloc_17_codes_b[17] = +{ + 0x007C, 0x003F, 0x0019, 0x000D, 0x001C, 0x0008, 0x000F, 0x0005, + 0x0000, 0x0006, 0x0002, 0x0009, 0x001D, 0x000E, 0x001E, 0x0018, + 0x007D, +}; +static const uint16_t bitalloc_17_codes_c[17] = +{ + 0x002C, 0x0017, 0x0005, 0x001C, 0x0003, 0x000A, 0x000F, 0x0003, + 0x0006, 0x0004, 0x0000, 0x000B, 0x0004, 0x001D, 0x000A, 0x0004, + 0x002D, +}; +static const uint16_t bitalloc_17_codes_d[17] = +{ + 0x0100, 0x0102, 0x0082, 0x0042, 0x0022, 0x0012, 0x000A, 0x0006, + 0x0000, 0x0007, 0x000B, 0x0013, 0x0023, 0x0043, 0x0083, 0x0103, + 0x0101, +}; +static const uint16_t bitalloc_17_codes_e[17] = +{ + 0x00E8, 0x00F6, 0x0075, 0x0034, 0x003B, 0x001B, 0x001F, 0x0004, + 0x0000, 0x0005, 0x000C, 0x001C, 0x003C, 0x0035, 0x007A, 0x00F7, + 0x00E9, +}; +static const uint16_t bitalloc_17_codes_f[17] = +{ + 0x0004, 0x0003, 0x001E, 0x0001, 0x0001, 0x000E, 0x0001, 0x0004, + 0x0006, 0x0005, 0x0002, 0x000F, 0x0006, 0x000E, 0x001F, 0x0000, + 0x0005, +}; +static const uint16_t bitalloc_17_codes_g[17] = +{ + 0x0060, 0x007E, 0x0031, 0x0019, 0x000D, 0x0004, 0x0000, 0x0006, + 0x0002, 0x0007, 0x0001, 0x0005, 0x000E, 0x001E, 0x003E, 0x007F, + 0x0061, +}; +static const uint8_t bitalloc_17_bits_a[17] = +{ + 12, 11, 9, 7, 5, 4, 3, 3, 2, 3, 3, 4, 4, 6, 8, 10, + 12, +}; +static const uint8_t bitalloc_17_bits_b[17] = +{ + 8, 7, 6, 5, 5, 4, 4, 3, 2, 3, 3, 4, 5, 5, 6, 6, + 8, +}; +static const uint8_t bitalloc_17_bits_c[17] = +{ + 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 4, 4, 5, 5, 5, + 7, +}; +static const uint8_t bitalloc_17_bits_d[17] = +{ + 9, 9, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, 8, 9, + 9, +}; +static const uint8_t bitalloc_17_bits_e[17] = +{ + 8, 8, 7, 6, 6, 5, 5, 3, 1, 3, 4, 5, 6, 6, 7, 8, + 8, +}; +static const uint8_t bitalloc_17_bits_f[17] = +{ + 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, + 8, +}; +static const uint8_t bitalloc_17_bits_g[17] = +{ + 8, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, + 8, +}; + +static const uint16_t bitalloc_25_codes_a[25] = +{ + 0x2854, 0x142B, 0x050B, 0x0143, 0x00A2, 0x0052, 0x002E, 0x0015, + 0x0004, 0x000E, 0x0000, 0x0003, 0x0006, 0x0004, 0x0001, 0x000F, + 0x0005, 0x0016, 0x002F, 0x0053, 0x00A3, 0x00A0, 0x0284, 0x0A14, + 0x2855, +}; +static const uint16_t bitalloc_25_codes_b[25] = +{ + 0x001C, 0x000F, 0x0005, 0x0000, 0x0030, 0x0036, 0x000E, 0x0019, + 0x0001, 0x0008, 0x000E, 0x0001, 0x0005, 0x0002, 0x000F, 0x0009, + 0x0006, 0x001A, 0x000F, 0x0037, 0x0031, 0x0001, 0x0006, 0x0004, + 0x001D, +}; +static const uint16_t bitalloc_25_codes_c[25] = +{ + 0x004C, 0x0027, 0x006D, 0x0028, 0x0037, 0x000E, 0x0015, 0x0000, + 0x0005, 0x0008, 0x000B, 0x000E, 0x0001, 0x000F, 0x000C, 0x0009, + 0x0006, 0x0001, 0x001A, 0x000F, 0x0008, 0x0029, 0x0012, 0x006C, + 0x004D, +}; +static const uint16_t bitalloc_25_codes_d[25] = +{ + 0x0780, 0x0782, 0x03C2, 0x01E2, 0x00FE, 0x0079, 0x003D, 0x001C, + 0x000C, 0x0004, 0x0000, 0x0006, 0x0002, 0x0007, 0x0001, 0x0005, + 0x000D, 0x001D, 0x003E, 0x007E, 0x00FF, 0x01E3, 0x03C3, 0x0783, + 0x0781, +}; +static const uint16_t bitalloc_25_codes_e[25] = +{ + 0x003C, 0x0092, 0x0018, 0x001F, 0x004E, 0x000D, 0x0025, 0x0004, + 0x0010, 0x0000, 0x000A, 0x0002, 0x0003, 0x0003, 0x000B, 0x0001, + 0x0011, 0x0005, 0x0026, 0x000E, 0x004F, 0x0048, 0x0019, 0x0093, + 0x003D, +}; +static const uint16_t bitalloc_25_codes_f[25] = +{ + 0x0324, 0x0193, 0x00CE, 0x0065, 0x0024, 0x000C, 0x0013, 0x0004, + 0x0007, 0x000A, 0x000D, 0x000F, 0x0001, 0x0000, 0x000E, 0x000B, + 0x0008, 0x0005, 0x0018, 0x000D, 0x0025, 0x0066, 0x00CF, 0x00C8, + 0x0325, +}; +static const uint16_t bitalloc_25_codes_g[25] = +{ + 0x03A8, 0x03AE, 0x01D5, 0x0094, 0x0014, 0x004B, 0x000B, 0x003B, + 0x0013, 0x0003, 0x000F, 0x0005, 0x0001, 0x0006, 0x0000, 0x0008, + 0x001C, 0x0004, 0x0024, 0x0074, 0x0015, 0x0095, 0x01D6, 0x03AF, + 0x03A9, +}; +static const uint8_t bitalloc_25_bits_a[25] = +{ + 14, 13, 11, 9, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 3, 4, + 4, 5, 6, 7, 8, 8, 10, 12, 14, +}; +static const uint8_t bitalloc_25_bits_b[25] = +{ + 9, 8, 7, 6, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 4, 4, + 4, 5, 5, 6, 6, 6, 7, 7, 9, +}; +static const uint8_t bitalloc_25_bits_c[25] = +{ + 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 4, 3, 4, 4, 4, + 4, 4, 5, 5, 5, 6, 6, 7, 8, +}; +static const uint8_t bitalloc_25_bits_d[25] = +{ + 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 3, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 12, +}; +static const uint8_t bitalloc_25_bits_e[25] = +{ + 8, 8, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 7, 8, 8, +}; +static const uint8_t bitalloc_25_bits_f[25] = +{ + 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 4, 4, 3, 3, 4, 4, + 4, 4, 5, 5, 6, 7, 8, 8, 10, +}; +static const uint8_t bitalloc_25_bits_g[25] = +{ + 10, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 3, 3, 4, + 5, 5, 6, 7, 7, 8, 9, 10, 10, +}; + +static const uint16_t bitalloc_33_codes_a[33] = +{ + 0x1580, 0x1582, 0x0AC2, 0x0562, 0x02B2, 0x015E, 0x00AD, 0x0054, + 0x001C, 0x003C, 0x000F, 0x001F, 0x0008, 0x000B, 0x000D, 0x0000, + 0x0002, 0x0001, 0x000E, 0x000C, 0x0009, 0x0006, 0x0014, 0x003D, + 0x001D, 0x0055, 0x00AE, 0x015F, 0x02B3, 0x0563, 0x0AC3, 0x1583, + 0x1581, +}; +static const uint16_t bitalloc_33_codes_b[33] = +{ + 0x030C, 0x0187, 0x006D, 0x0028, 0x0037, 0x0066, 0x0015, 0x0031, + 0x0000, 0x000B, 0x0012, 0x001A, 0x0001, 0x0007, 0x000A, 0x000E, + 0x0001, 0x000F, 0x000B, 0x0008, 0x0004, 0x001B, 0x0013, 0x000C, + 0x0001, 0x0032, 0x001A, 0x0067, 0x0060, 0x0029, 0x00C2, 0x006C, + 0x030D, +}; +static const uint16_t bitalloc_33_codes_c[33] = +{ + 0x00CC, 0x0067, 0x0005, 0x0070, 0x0003, 0x001A, 0x0039, 0x003F, + 0x000A, 0x0012, 0x0018, 0x001D, 0x0001, 0x0003, 0x0007, 0x000A, + 0x000D, 0x000B, 0x0008, 0x0004, 0x0002, 0x001E, 0x0019, 0x0013, + 0x000B, 0x0000, 0x003E, 0x001B, 0x0018, 0x0071, 0x0032, 0x0004, + 0x00CD, +}; +static const uint16_t bitalloc_33_codes_d[33] = +{ + 0x3AF8, 0x3AFA, 0x1D7E, 0x0EBC, 0x075C, 0x03AC, 0x01D4, 0x0094, + 0x0014, 0x004B, 0x000B, 0x003B, 0x0013, 0x0003, 0x000F, 0x0005, + 0x0001, 0x0006, 0x0000, 0x0008, 0x001C, 0x0004, 0x0024, 0x0074, + 0x0015, 0x0095, 0x01D5, 0x03AD, 0x075D, 0x0EBD, 0x1D7F, 0x3AFB, + 0x3AF9, +}; +static const uint16_t bitalloc_33_codes_e[33] = +{ + 0x01C8, 0x01E6, 0x0064, 0x00E2, 0x00E5, 0x0030, 0x0033, 0x0073, + 0x007A, 0x001A, 0x003A, 0x0002, 0x001A, 0x001F, 0x0007, 0x0001, + 0x0002, 0x0002, 0x000C, 0x0000, 0x001B, 0x0003, 0x003B, 0x001B, + 0x007B, 0x0078, 0x0070, 0x0031, 0x00F2, 0x00E3, 0x0065, 0x01E7, + 0x01C9, +}; +static const uint16_t bitalloc_33_codes_f[33] = +{ + 0x0724, 0x0393, 0x01CE, 0x00E5, 0x002C, 0x0008, 0x0017, 0x003E, + 0x0005, 0x0014, 0x001D, 0x0000, 0x0003, 0x0006, 0x0008, 0x000B, + 0x000D, 0x000C, 0x0009, 0x0007, 0x0004, 0x0001, 0x001E, 0x0015, + 0x000A, 0x003F, 0x0038, 0x0009, 0x002D, 0x00E6, 0x01CF, 0x01C8, + 0x0725, +}; +static const uint16_t bitalloc_33_codes_g[33] = +{ + 0x0284, 0x0042, 0x0140, 0x0143, 0x003E, 0x00BE, 0x0011, 0x0051, + 0x0009, 0x0029, 0x0005, 0x0015, 0x0000, 0x0008, 0x000E, 0x0002, + 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0016, 0x0006, 0x002E, + 0x000E, 0x005E, 0x001E, 0x00BF, 0x003F, 0x0020, 0x0141, 0x0043, + 0x0285, +}; +static const uint8_t bitalloc_33_bits_a[33] = +{ + 13, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, + 3, 3, 4, 4, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, + 13, +}; +static const uint8_t bitalloc_33_bits_b[33] = +{ + 10, 9, 8, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, + 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, + 10, +}; +static const uint8_t bitalloc_33_bits_c[33] = +{ + 9, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, + 9, +}; +static const uint8_t bitalloc_33_bits_d[33] = +{ + 14, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 5, 4, 4, 3, + 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, + 14, +}; +static const uint8_t bitalloc_33_bits_e[33] = +{ + 9, 9, 8, 8, 8, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3, + 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, + 9, +}; +static const uint8_t bitalloc_33_bits_f[33] = +{ + 11, 10, 9, 8, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9, 9, + 11, +}; +static const uint8_t bitalloc_33_bits_g[33] = +{ + 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, + 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, + 10, +}; + +static const uint16_t bitalloc_65_codes_a[65] = +{ + 0x9E5C, 0x9E5E, 0x4F2C, 0x2794, 0x13C4, 0x1E44, 0x09E3, 0x0F23, + 0x04F3, 0x0792, 0x027E, 0x03CE, 0x013D, 0x01E5, 0x009C, 0x00CC, + 0x0040, 0x0058, 0x0067, 0x001E, 0x0021, 0x002D, 0x003D, 0x0007, + 0x0011, 0x0014, 0x0017, 0x001A, 0x001C, 0x001F, 0x0001, 0x0004, + 0x0006, 0x0005, 0x0002, 0x0000, 0x001D, 0x001B, 0x0018, 0x0015, + 0x0012, 0x000E, 0x0006, 0x0032, 0x0026, 0x001F, 0x0078, 0x0059, + 0x0041, 0x00CD, 0x009D, 0x01E6, 0x013E, 0x03CF, 0x027F, 0x0793, + 0x0790, 0x04F0, 0x09E4, 0x1E45, 0x13C5, 0x2795, 0x4F2D, 0x9E5F, + 0x9E5D, +}; +static const uint16_t bitalloc_65_codes_b[65] = +{ + 0x0A8C, 0x0547, 0x01B5, 0x0008, 0x00DB, 0x0152, 0x0005, 0x000B, + 0x008E, 0x00AE, 0x00E4, 0x0003, 0x0037, 0x0039, 0x0055, 0x006C, + 0x0073, 0x0003, 0x0015, 0x001D, 0x0028, 0x0030, 0x0037, 0x003E, + 0x0006, 0x000B, 0x000F, 0x0012, 0x0016, 0x0019, 0x001D, 0x0001, + 0x0004, 0x0002, 0x001E, 0x001A, 0x0017, 0x0013, 0x0010, 0x000C, + 0x0007, 0x003F, 0x0038, 0x0031, 0x0029, 0x0022, 0x001A, 0x0014, + 0x0000, 0x006D, 0x0056, 0x0046, 0x0038, 0x0004, 0x00E5, 0x00AF, + 0x008F, 0x006C, 0x000A, 0x0153, 0x0150, 0x0009, 0x02A2, 0x01B4, + 0x0A8D, +}; +static const uint16_t bitalloc_65_codes_c[65] = +{ + 0x045C, 0x022F, 0x03F5, 0x01BC, 0x01FB, 0x0059, 0x00D0, 0x00DF, + 0x000A, 0x002D, 0x002F, 0x0052, 0x0069, 0x0078, 0x007F, 0x000A, + 0x0010, 0x001C, 0x0023, 0x002A, 0x0035, 0x003A, 0x003D, 0x0000, + 0x0003, 0x0006, 0x0009, 0x000C, 0x000F, 0x0012, 0x0016, 0x0018, + 0x001C, 0x0019, 0x0017, 0x0013, 0x0010, 0x000D, 0x000A, 0x0007, + 0x0004, 0x0001, 0x003E, 0x003B, 0x0036, 0x002B, 0x0028, 0x001D, + 0x0011, 0x000B, 0x0004, 0x0079, 0x006E, 0x0053, 0x0044, 0x002E, + 0x000B, 0x00FC, 0x00D1, 0x008A, 0x0058, 0x01BD, 0x0116, 0x03F4, + 0x045D, +}; +static const uint16_t bitalloc_65_codes_d[65] = +{ + 0x70B0, 0x70B2, 0x70B4, 0x2852, 0x385B, 0x142E, 0x1C2E, 0x0A15, + 0x0E14, 0x0214, 0x0704, 0x0104, 0x010B, 0x0383, 0x0083, 0x0143, + 0x01C3, 0x0043, 0x00A2, 0x00E2, 0x0022, 0x0052, 0x0072, 0x0012, + 0x002A, 0x003A, 0x000A, 0x0016, 0x001E, 0x0006, 0x000C, 0x0000, + 0x0004, 0x0001, 0x000D, 0x0007, 0x001F, 0x0017, 0x000B, 0x003B, + 0x002B, 0x0013, 0x0073, 0x0053, 0x0023, 0x00E3, 0x00A3, 0x00A0, + 0x0040, 0x01C0, 0x0084, 0x0384, 0x0284, 0x0105, 0x0705, 0x0215, + 0x0E15, 0x0A16, 0x1C2F, 0x142F, 0x1428, 0x2853, 0x70B5, 0x70B3, + 0x70B1, +}; +static const uint16_t bitalloc_65_codes_e[65] = +{ + 0x032C, 0x0332, 0x0378, 0x037E, 0x008C, 0x014A, 0x0188, 0x0197, + 0x019E, 0x01BD, 0x0044, 0x0047, 0x00AA, 0x00C5, 0x00CD, 0x00DC, + 0x001C, 0x002C, 0x0053, 0x0063, 0x0068, 0x0008, 0x000F, 0x0017, + 0x002B, 0x0035, 0x0005, 0x0009, 0x0016, 0x001C, 0x0006, 0x000F, + 0x0004, 0x0000, 0x0007, 0x001D, 0x0017, 0x000A, 0x0006, 0x0036, + 0x0030, 0x0028, 0x0010, 0x0009, 0x0069, 0x0064, 0x0054, 0x002D, + 0x001D, 0x00DD, 0x00CE, 0x00CA, 0x00AB, 0x00A4, 0x0045, 0x01BE, + 0x019F, 0x0198, 0x0189, 0x014B, 0x008D, 0x037F, 0x0379, 0x0333, + 0x032D, +}; +static const uint16_t bitalloc_65_codes_f[65] = +{ + 0x0FE0, 0x0FE2, 0x0FE8, 0x0FEA, 0x0FEC, 0x0FEE, 0x0FF0, 0x0FF2, + 0x0FF4, 0x2FF2, 0x07F2, 0x07FB, 0x03F6, 0x0BFA, 0x0BFD, 0x01FF, + 0x05FF, 0x02FC, 0x007C, 0x017C, 0x003C, 0x00BC, 0x001C, 0x005C, + 0x000C, 0x002C, 0x0004, 0x0014, 0x0000, 0x0008, 0x000E, 0x0002, + 0x0006, 0x0003, 0x000F, 0x0009, 0x0001, 0x0015, 0x0005, 0x002D, + 0x000D, 0x005D, 0x001D, 0x00BD, 0x003D, 0x017D, 0x007D, 0x02FD, + 0x00FC, 0x05FC, 0x01FA, 0x0BFB, 0x03F7, 0x17F8, 0x07F3, 0x2FF3, + 0x0FF5, 0x0FF3, 0x0FF1, 0x0FEF, 0x0FED, 0x0FEB, 0x0FE9, 0x0FE3, + 0x0FE1, +}; +static const uint16_t bitalloc_65_codes_g[65] = +{ + 0x010C, 0x038A, 0x0608, 0x0786, 0x0084, 0x0087, 0x0302, 0x0305, + 0x0040, 0x00E0, 0x00E3, 0x0183, 0x001E, 0x005E, 0x009E, 0x00DE, + 0x00F1, 0x0011, 0x0039, 0x0061, 0x0079, 0x0009, 0x001D, 0x0031, + 0x003D, 0x0005, 0x000F, 0x0019, 0x001F, 0x0003, 0x0006, 0x000A, + 0x000E, 0x000B, 0x0008, 0x0004, 0x0000, 0x001A, 0x0012, 0x000A, + 0x0002, 0x0036, 0x0026, 0x0016, 0x0006, 0x006E, 0x004E, 0x002E, + 0x000E, 0x00DF, 0x009F, 0x005F, 0x001F, 0x01E0, 0x0180, 0x00E1, + 0x0041, 0x03C2, 0x0303, 0x01C4, 0x0085, 0x0787, 0x0609, 0x038B, + 0x010D, +}; +static const uint8_t bitalloc_65_bits_a[65] = +{ + 16, 16, 15, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, + 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, + 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 13, 13, 14, 15, 16, + 16, +}; +static const uint8_t bitalloc_65_bits_b[65] = +{ + 12, 11, 10, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, + 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, + 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, + 12, +}; +static const uint8_t bitalloc_65_bits_c[65] = +{ + 11, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 10, + 11, +}; +static const uint8_t bitalloc_65_bits_d[65] = +{ + 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 10, 9, 9, + 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 3, + 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, + 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 15, 15, + 15, +}; +static const uint8_t bitalloc_65_bits_e[65] = +{ + 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, + 3, 3, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, + 10, +}; +static const uint8_t bitalloc_65_bits_f[65] = +{ + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 12, 12, 12, 11, + 11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, + 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, +}; +static const uint8_t bitalloc_65_bits_g[65] = +{ + 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, + 11, +}; + +static const uint16_t bitalloc_129_codes_a[129] = +{ + 0x0660, 0x0666, 0x06EC, 0x0722, 0x0760, 0x076E, 0x004C, 0x004E, + 0x00F4, 0x010A, 0x0148, 0x0156, 0x01D4, 0x01F2, 0x0331, 0x0370, + 0x0377, 0x0396, 0x03B1, 0x0024, 0x0064, 0x007B, 0x008A, 0x00A5, + 0x00D4, 0x00EB, 0x00FA, 0x019A, 0x01B9, 0x01C9, 0x01D9, 0x0010, + 0x0030, 0x0033, 0x0043, 0x0053, 0x006B, 0x007A, 0x00CA, 0x00D2, + 0x00DE, 0x00E6, 0x00F6, 0x000E, 0x001F, 0x0023, 0x002B, 0x003B, + 0x003F, 0x0067, 0x0070, 0x0077, 0x0005, 0x000D, 0x0012, 0x001B, + 0x002C, 0x0035, 0x003A, 0x0004, 0x000B, 0x0017, 0x001F, 0x0009, + 0x0008, 0x000A, 0x0000, 0x0018, 0x000C, 0x0005, 0x003C, 0x0036, + 0x002D, 0x001C, 0x0013, 0x000E, 0x0006, 0x007A, 0x0071, 0x0068, + 0x0064, 0x003C, 0x0034, 0x0028, 0x0020, 0x000F, 0x00F7, 0x00E7, + 0x00DF, 0x00D3, 0x00CB, 0x007B, 0x0074, 0x0054, 0x0044, 0x003C, + 0x0031, 0x0011, 0x01DA, 0x01CA, 0x01BA, 0x019B, 0x00FB, 0x00F8, + 0x00D5, 0x00AA, 0x008B, 0x0084, 0x0065, 0x0025, 0x03B6, 0x0397, + 0x0390, 0x0371, 0x0332, 0x01F3, 0x01D5, 0x0157, 0x0149, 0x010B, + 0x00F5, 0x004F, 0x004D, 0x076F, 0x0761, 0x0723, 0x06ED, 0x0667, + 0x0661, +}; +static const uint16_t bitalloc_129_codes_b[129] = +{ + 0x29DC, 0x14EF, 0x0455, 0x0E9C, 0x022B, 0x0489, 0x0740, 0x074F, + 0x0172, 0x0245, 0x0247, 0x030A, 0x03A1, 0x001C, 0x008B, 0x00D6, + 0x010C, 0x0148, 0x014F, 0x0186, 0x01D1, 0x0008, 0x000F, 0x0046, + 0x005D, 0x0078, 0x0087, 0x0096, 0x00A5, 0x00BC, 0x00D8, 0x00DE, + 0x00F6, 0x0005, 0x0014, 0x0024, 0x002F, 0x003A, 0x003D, 0x0049, + 0x0050, 0x0058, 0x005F, 0x0066, 0x006D, 0x0075, 0x007C, 0x0004, + 0x000B, 0x0013, 0x0018, 0x001B, 0x001F, 0x0022, 0x0026, 0x002A, + 0x002D, 0x0031, 0x0034, 0x0038, 0x003B, 0x003F, 0x0003, 0x0006, + 0x000A, 0x0007, 0x0004, 0x0000, 0x003C, 0x0039, 0x0035, 0x0032, + 0x002E, 0x002B, 0x0027, 0x0023, 0x0020, 0x001C, 0x0019, 0x0016, + 0x0010, 0x0005, 0x007D, 0x007A, 0x006E, 0x0067, 0x0060, 0x0059, + 0x0051, 0x004A, 0x0042, 0x003B, 0x0034, 0x0025, 0x0015, 0x0006, + 0x00F7, 0x00DF, 0x00D9, 0x00BD, 0x00A6, 0x0097, 0x0090, 0x0079, + 0x006A, 0x0047, 0x0044, 0x0009, 0x01D2, 0x0187, 0x0184, 0x0149, + 0x010D, 0x00D7, 0x00B8, 0x001D, 0x03A6, 0x030B, 0x029C, 0x0246, + 0x0173, 0x0114, 0x0741, 0x053A, 0x0488, 0x0E9D, 0x0A76, 0x0454, + 0x29DD, +}; +static const uint16_t bitalloc_129_codes_c[129] = +{ + 0x0E5C, 0x072F, 0x001D, 0x0724, 0x000F, 0x010D, 0x0324, 0x0393, + 0x03E9, 0x0080, 0x0087, 0x00FA, 0x0164, 0x0193, 0x01DE, 0x01F5, + 0x0010, 0x002A, 0x0041, 0x0064, 0x0073, 0x008E, 0x00A4, 0x00B3, + 0x00D6, 0x00E5, 0x00F4, 0x00FB, 0x0002, 0x0009, 0x0013, 0x001E, + 0x0026, 0x002C, 0x0033, 0x003F, 0x0041, 0x004C, 0x0053, 0x005E, + 0x0065, 0x0070, 0x0073, 0x0078, 0x007B, 0x007E, 0x0002, 0x0005, + 0x0007, 0x000B, 0x000D, 0x0011, 0x0014, 0x0017, 0x001A, 0x001D, + 0x0021, 0x0024, 0x0027, 0x002A, 0x002D, 0x0030, 0x0033, 0x0036, + 0x003A, 0x0037, 0x0034, 0x0031, 0x002E, 0x002B, 0x0028, 0x0025, + 0x0022, 0x001E, 0x001B, 0x0018, 0x0015, 0x0012, 0x000E, 0x000C, + 0x0008, 0x0006, 0x0003, 0x007F, 0x007C, 0x0079, 0x0076, 0x0071, + 0x006A, 0x005F, 0x0058, 0x004D, 0x0046, 0x0040, 0x0038, 0x002D, + 0x0027, 0x001F, 0x0014, 0x0012, 0x0003, 0x0000, 0x00F5, 0x00EE, + 0x00D7, 0x00C8, 0x00A5, 0x008F, 0x007C, 0x0065, 0x0042, 0x002B, + 0x0011, 0x0002, 0x01DF, 0x01C8, 0x0165, 0x00FB, 0x00E4, 0x0081, + 0x0006, 0x03E8, 0x0325, 0x01CA, 0x010C, 0x0725, 0x0396, 0x001C, + 0x0E5D, +}; +static const uint16_t bitalloc_129_codes_d[129] = +{ + 0xA598, 0xA59A, 0xA59C, 0xA59E, 0xC598, 0xE586, 0x3ACC, 0x52CA, + 0x62CD, 0x0D48, 0x1D67, 0x2978, 0x3167, 0x3966, 0x06A5, 0x0EBC, + 0x14BD, 0x1CB1, 0x0350, 0x0353, 0x075F, 0x0A5F, 0x0C5E, 0x0E5E, + 0x01AE, 0x03AD, 0x052D, 0x062D, 0x072D, 0x00D5, 0x01D4, 0x0294, + 0x0314, 0x0394, 0x0014, 0x0094, 0x0114, 0x0174, 0x01B4, 0x01F4, + 0x000B, 0x004B, 0x008B, 0x00BB, 0x00DB, 0x00FB, 0x001B, 0x003B, + 0x0053, 0x0063, 0x0073, 0x0003, 0x0013, 0x0023, 0x002F, 0x0037, + 0x003F, 0x0007, 0x000F, 0x0015, 0x0019, 0x001D, 0x0001, 0x0005, + 0x0009, 0x0006, 0x0002, 0x001E, 0x001A, 0x0016, 0x0010, 0x0008, + 0x0000, 0x0038, 0x0030, 0x0028, 0x001C, 0x000C, 0x007C, 0x006C, + 0x005C, 0x0044, 0x0024, 0x0004, 0x00E4, 0x00C4, 0x00A4, 0x0074, + 0x0034, 0x01F5, 0x01B5, 0x0175, 0x0115, 0x0095, 0x0015, 0x0395, + 0x0315, 0x0295, 0x01D5, 0x00D6, 0x072E, 0x062E, 0x052E, 0x03AE, + 0x01AF, 0x0E5F, 0x0C5F, 0x0C58, 0x0A58, 0x0758, 0x0351, 0x1CB2, + 0x18B2, 0x0EBD, 0x0EB2, 0x3967, 0x3960, 0x2979, 0x2964, 0x0D49, + 0x72C2, 0x52CB, 0x3ACD, 0xE587, 0xC599, 0xA59F, 0xA59D, 0xA59B, + 0xA599, +}; +static const uint16_t bitalloc_129_codes_e[129] = +{ + 0xA13C, 0xC720, 0xA13F, 0xA13E, 0xA13D, 0xE722, 0x5090, 0x6393, + 0x7392, 0x2849, 0x31CE, 0x39CE, 0x1425, 0x18E5, 0x1CE5, 0x0844, + 0x0A1C, 0x0C7C, 0x036C, 0x0423, 0x050F, 0x063F, 0x01B7, 0x0216, + 0x0285, 0x031D, 0x039D, 0x0109, 0x0140, 0x0180, 0x01C8, 0x01CF, + 0x007A, 0x008A, 0x00A2, 0x00C1, 0x00E5, 0x0014, 0x0037, 0x0043, + 0x004E, 0x0056, 0x0061, 0x006C, 0x007C, 0x000B, 0x001C, 0x001F, + 0x0023, 0x0025, 0x0029, 0x002C, 0x002E, 0x0032, 0x0034, 0x0037, + 0x003A, 0x003C, 0x003F, 0x0001, 0x0003, 0x0006, 0x0008, 0x000A, + 0x000C, 0x000B, 0x0009, 0x0007, 0x0004, 0x0002, 0x0000, 0x003D, + 0x003B, 0x0038, 0x0035, 0x0033, 0x002F, 0x002D, 0x002A, 0x0026, + 0x0024, 0x0020, 0x001D, 0x001A, 0x007D, 0x006D, 0x0062, 0x0057, + 0x004F, 0x0044, 0x003C, 0x0015, 0x00E6, 0x00C6, 0x00A3, 0x008B, + 0x007B, 0x006C, 0x01C9, 0x0181, 0x0141, 0x010A, 0x00DA, 0x031E, + 0x0286, 0x0217, 0x0210, 0x0738, 0x0638, 0x0508, 0x036D, 0x0C7D, + 0x0A1D, 0x0845, 0x1CE6, 0x18E6, 0x1426, 0x39CF, 0x31CF, 0x284E, + 0x7393, 0x7390, 0x5091, 0xE723, 0xC724, 0xC725, 0xC722, 0xC723, + 0xC721, +}; +static const uint16_t bitalloc_129_codes_f[129] = +{ + 0x762C, 0x3B17, 0x1555, 0x0608, 0x0AAB, 0x0FF2, 0x0305, 0x0307, + 0x0763, 0x0046, 0x010C, 0x01BC, 0x02AB, 0x03B6, 0x03FD, 0x0080, + 0x0087, 0x00DF, 0x0156, 0x01D9, 0x01F8, 0x01FF, 0x002A, 0x0041, + 0x0061, 0x0094, 0x00D4, 0x00EA, 0x00F2, 0x00FD, 0x0009, 0x000B, + 0x001A, 0x0026, 0x0031, 0x0040, 0x004B, 0x006B, 0x0073, 0x0077, + 0x007A, 0x007C, 0x0000, 0x0002, 0x0006, 0x0008, 0x000B, 0x000E, + 0x0011, 0x0014, 0x0016, 0x0019, 0x001C, 0x001E, 0x0021, 0x0023, + 0x0026, 0x0028, 0x002B, 0x002D, 0x002F, 0x0031, 0x0033, 0x0036, + 0x0038, 0x0037, 0x0034, 0x0032, 0x0030, 0x002E, 0x002C, 0x0029, + 0x0027, 0x0024, 0x0022, 0x001F, 0x001D, 0x001A, 0x0017, 0x0015, + 0x0012, 0x000F, 0x000C, 0x0009, 0x0007, 0x0003, 0x0001, 0x007D, + 0x007B, 0x0078, 0x0074, 0x0072, 0x0054, 0x0041, 0x0036, 0x0027, + 0x001B, 0x0014, 0x000A, 0x00FE, 0x00F3, 0x00EB, 0x00D5, 0x0095, + 0x006E, 0x0042, 0x002B, 0x0010, 0x01F9, 0x01DA, 0x0157, 0x0154, + 0x00C0, 0x0081, 0x0022, 0x03B7, 0x03B0, 0x01BD, 0x010D, 0x0047, + 0x07F8, 0x0554, 0x0306, 0x0FF3, 0x0EC4, 0x0609, 0x1D8A, 0x1554, + 0x762D, +}; +static const uint16_t bitalloc_129_codes_g[129] = +{ + 0x1E20, 0x1E5E, 0x031C, 0x051A, 0x0718, 0x0916, 0x0B14, 0x0D12, + 0x0F11, 0x0090, 0x018F, 0x028E, 0x038D, 0x048C, 0x058B, 0x068A, + 0x0789, 0x0049, 0x00C8, 0x0148, 0x01C7, 0x0247, 0x02C6, 0x0346, + 0x03C5, 0x0025, 0x0065, 0x00A5, 0x00E4, 0x0124, 0x0164, 0x01A4, + 0x01E3, 0x0013, 0x0033, 0x0053, 0x0073, 0x0093, 0x00B3, 0x00D3, + 0x00F3, 0x000A, 0x001A, 0x002A, 0x003A, 0x004A, 0x005A, 0x006A, + 0x007A, 0x0006, 0x000E, 0x0016, 0x001E, 0x0026, 0x002E, 0x0036, + 0x003E, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, + 0x0000, 0x001D, 0x0019, 0x0015, 0x0011, 0x000D, 0x0009, 0x0005, + 0x003F, 0x0037, 0x002F, 0x0027, 0x001F, 0x0017, 0x000F, 0x0007, + 0x007B, 0x006B, 0x005B, 0x004B, 0x003B, 0x002B, 0x001B, 0x000B, + 0x0008, 0x00F0, 0x00D0, 0x00B0, 0x0090, 0x0070, 0x0050, 0x0030, + 0x01E4, 0x01A5, 0x0165, 0x0125, 0x00E5, 0x00E2, 0x00A2, 0x0062, + 0x03CA, 0x0347, 0x02C7, 0x02C4, 0x0244, 0x0149, 0x00C9, 0x00C6, + 0x0796, 0x068B, 0x0688, 0x048D, 0x048A, 0x028F, 0x028C, 0x0091, + 0x0F2E, 0x0D13, 0x0B15, 0x0917, 0x0719, 0x051B, 0x031D, 0x1E5F, + 0x1E21, +}; +static const uint8_t bitalloc_129_bits_a[129] = +{ + 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, + 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, + 11, +}; +static const uint8_t bitalloc_129_bits_b[129] = +{ + 14, 13, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, + 14, +}; +static const uint8_t bitalloc_129_bits_c[129] = +{ + 13, 12, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, + 13, +}; +static const uint8_t bitalloc_129_bits_d[129] = +{ + 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, + 13, 13, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 10, 10, 10, + 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, + 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, + 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, + 16, +}; +static const uint8_t bitalloc_129_bits_e[129] = +{ + 16, 16, 16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, + 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, + 16, +}; +static const uint8_t bitalloc_129_bits_f[129] = +{ + 15, 14, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 10, 9, + 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, + 15, +}; +static const uint8_t bitalloc_129_bits_g[129] = +{ + 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, + 11, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, + 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, + 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, + 13, +}; + +static const uint8_t bitalloc_sizes[10] = { 3, 5, 7, 9, 13, 17, 25, 33, 65, 129 }; + +static const uint8_t bitalloc_offsets[10] = + { -1, -2, -3, -4, -6, -8, -12, -16, -32, -64 }; + +static const uint8_t bitalloc_maxbits[10][7] = { + { 2 }, + { 4, 3, 3 }, + { 5, 5, 4 }, + { 6, 5, 6 }, + { 7, 6, 5 }, + { 9, 8, 7, 9, 8, 8, 8 }, + { 9, 9, 8, 9, 8, 9, 9 }, + { 9, 9, 9, 9, 9, 9, 9 }, + { 9, 9, 9, 9, 9, 9, 9 }, + { 9, 9, 9, 9, 9, 9, 9 } +}; + +static const uint16_t* const bitalloc_codes[10][8] = { + { bitalloc_3_codes, NULL }, + { bitalloc_5_codes_a, bitalloc_5_codes_b, bitalloc_5_codes_c, NULL }, + { bitalloc_7_codes_a, bitalloc_7_codes_b, bitalloc_7_codes_c, NULL }, + { bitalloc_9_codes_a, bitalloc_9_codes_b, bitalloc_9_codes_c, NULL }, + { bitalloc_13_codes_a, bitalloc_13_codes_b, bitalloc_13_codes_c, NULL }, + { bitalloc_17_codes_a, bitalloc_17_codes_b, bitalloc_17_codes_c, bitalloc_17_codes_d, + bitalloc_17_codes_e, bitalloc_17_codes_f, bitalloc_17_codes_g, NULL }, + { bitalloc_25_codes_a, bitalloc_25_codes_b, bitalloc_25_codes_c, bitalloc_25_codes_d, + bitalloc_25_codes_e, bitalloc_25_codes_f, bitalloc_25_codes_g, NULL }, + { bitalloc_33_codes_a, bitalloc_33_codes_b, bitalloc_33_codes_c, bitalloc_33_codes_d, + bitalloc_33_codes_e, bitalloc_33_codes_f, bitalloc_33_codes_g, NULL }, + { bitalloc_65_codes_a, bitalloc_65_codes_b, bitalloc_65_codes_c, bitalloc_65_codes_d, + bitalloc_65_codes_e, bitalloc_65_codes_f, bitalloc_65_codes_g, NULL }, + { bitalloc_129_codes_a, bitalloc_129_codes_b, bitalloc_129_codes_c, bitalloc_129_codes_d, + bitalloc_129_codes_e, bitalloc_129_codes_f, bitalloc_129_codes_g, NULL } +}; + +static const uint8_t* const bitalloc_bits[10][8] = { + { bitalloc_3_bits, NULL }, + { bitalloc_5_bits_a, bitalloc_5_bits_b, bitalloc_5_bits_c, NULL }, + { bitalloc_7_bits_a, bitalloc_7_bits_b, bitalloc_7_bits_c, NULL }, + { bitalloc_9_bits_a, bitalloc_9_bits_b, bitalloc_9_bits_c, NULL }, + { bitalloc_13_bits_a, bitalloc_13_bits_b, bitalloc_13_bits_c, NULL }, + { bitalloc_17_bits_a, bitalloc_17_bits_b, bitalloc_17_bits_c, bitalloc_17_bits_d, + bitalloc_17_bits_e, bitalloc_17_bits_f, bitalloc_17_bits_g, NULL }, + { bitalloc_25_bits_a, bitalloc_25_bits_b, bitalloc_25_bits_c, bitalloc_25_bits_d, + bitalloc_25_bits_e, bitalloc_25_bits_f, bitalloc_25_bits_g, NULL }, + { bitalloc_33_bits_a, bitalloc_33_bits_b, bitalloc_33_bits_c, bitalloc_33_bits_d, + bitalloc_33_bits_e, bitalloc_33_bits_f, bitalloc_33_bits_g, NULL }, + { bitalloc_65_bits_a, bitalloc_65_bits_b, bitalloc_65_bits_c, bitalloc_65_bits_d, + bitalloc_65_bits_e, bitalloc_65_bits_f, bitalloc_65_bits_g, NULL }, + { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d, + bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL } +}; + +#endif /* FFMPEG_DCAHUFF_H */ diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dct-test.c b/src/add-ons/media/plugins/avcodec/libavcodec/dct-test.c new file mode 100644 index 0000000000..f3f9408d98 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dct-test.c @@ -0,0 +1,582 @@ +/* + * (c) 2001 Fabrice Bellard + * 2007 Marc Hoffman + * + * 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 + */ + +/** + * @file dct-test.c + * DCT test. (c) 2001 Fabrice Bellard. + * Started from sample code by Juan J. Sierralta P. + */ + +#include +#include +#include +#include +#include +#include + +#include "libavutil/common.h" + +#include "simple_idct.h" +#include "faandct.h" +#include "faanidct.h" +#include "i386/idct_xvid.h" + +#undef printf +#undef random + +void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);}; + +/* reference fdct/idct */ +extern void fdct(DCTELEM *block); +extern void idct(DCTELEM *block); +extern void init_fdct(); + +extern void ff_mmx_idct(DCTELEM *data); +extern void ff_mmxext_idct(DCTELEM *data); + +extern void odivx_idct_c (short *block); + +// BFIN +extern void ff_bfin_idct (DCTELEM *block) ; +extern void ff_bfin_fdct (DCTELEM *block) ; + +// ALTIVEC +extern void fdct_altivec (DCTELEM *block); +//extern void idct_altivec (DCTELEM *block);?? no routine + + +struct algo { + const char *name; + enum { FDCT, IDCT } is_idct; + void (* func) (DCTELEM *block); + void (* ref) (DCTELEM *block); + enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM } format; + int mm_support; +}; + +#ifndef FAAN_POSTSCALE +#define FAAN_SCALE SCALE_PERM +#else +#define FAAN_SCALE NO_PERM +#endif + +static int cpu_flags; + +struct algo algos[] = { + {"REF-DBL", 0, fdct, fdct, NO_PERM}, + {"FAAN", 0, ff_faandct, fdct, FAAN_SCALE}, + {"FAANI", 1, ff_faanidct, idct, NO_PERM}, + {"IJG-AAN-INT", 0, fdct_ifast, fdct, SCALE_PERM}, + {"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, fdct, NO_PERM}, + {"REF-DBL", 1, idct, idct, NO_PERM}, + {"INT", 1, j_rev_dct, idct, MMX_PERM}, + {"SIMPLE-C", 1, ff_simple_idct, idct, NO_PERM}, + +#ifdef HAVE_MMX + {"MMX", 0, ff_fdct_mmx, fdct, NO_PERM, MM_MMX}, +#ifdef HAVE_MMX2 + {"MMX2", 0, ff_fdct_mmx2, fdct, NO_PERM, MM_MMXEXT}, +#endif + +#ifdef CONFIG_GPL + {"LIBMPEG2-MMX", 1, ff_mmx_idct, idct, MMX_PERM, MM_MMX}, + {"LIBMPEG2-MMXEXT", 1, ff_mmxext_idct, idct, MMX_PERM, MM_MMXEXT}, +#endif + {"SIMPLE-MMX", 1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM, MM_MMX}, + {"XVID-MMX", 1, ff_idct_xvid_mmx, idct, NO_PERM, MM_MMX}, + {"XVID-MMX2", 1, ff_idct_xvid_mmx2, idct, NO_PERM, MM_MMXEXT}, + {"XVID-SSE2", 1, ff_idct_xvid_sse2, idct, SSE2_PERM, MM_SSE2}, +#endif + +#ifdef HAVE_ALTIVEC + {"altivecfdct", 0, fdct_altivec, fdct, NO_PERM, MM_ALTIVEC}, +#endif + +#ifdef ARCH_BFIN + {"BFINfdct", 0, ff_bfin_fdct, fdct, NO_PERM}, + {"BFINidct", 1, ff_bfin_idct, idct, NO_PERM}, +#endif + + { 0 } +}; + +#define AANSCALE_BITS 12 +static const unsigned short aanscales[64] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 +}; + +uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; + +int64_t gettime(void) +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +} + +#define NB_ITS 20000 +#define NB_ITS_SPEED 50000 + +static short idct_mmx_perm[64]; + +static short idct_simple_mmx_perm[64]={ + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; + +void idct_mmx_init(void) +{ + int i; + + /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ + for (i = 0; i < 64; i++) { + idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); +// idct_simple_mmx_perm[i] = simple_block_permute_op(i); + } +} + +static DCTELEM block[64] __attribute__ ((aligned (16))); +static DCTELEM block1[64] __attribute__ ((aligned (8))); +static DCTELEM block_org[64] __attribute__ ((aligned (8))); + +static inline void mmx_emms(void) +{ +#ifdef HAVE_MMX + if (cpu_flags & MM_MMX) + asm volatile ("emms\n\t"); +#endif +} + +void dct_error(const char *name, int is_idct, + void (*fdct_func)(DCTELEM *block), + void (*fdct_ref)(DCTELEM *block), int form, int test) +{ + int it, i, scale; + int err_inf, v; + int64_t err2, ti, ti1, it1; + int64_t sysErr[64], sysErrMax=0; + int maxout=0; + int blockSumErrMax=0, blockSumErr; + + srandom(0); + + err_inf = 0; + err2 = 0; + for(i=0; i<64; i++) sysErr[i]=0; + for(it=0;it>=3; + } + break; + case 1:{ + int num= (random()%10)+1; + for(i=0;i> AANSCALE_BITS; + } + } + + fdct_ref(block1); + + blockSumErr=0; + for(i=0;i<64;i++) { + v = abs(block[i] - block1[i]); + if (v > err_inf) + err_inf = v; + err2 += v * v; + sysErr[i] += block[i] - block1[i]; + blockSumErr += v; + if( abs(block[i])>maxout) maxout=abs(block[i]); + } + if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr; +#if 0 // print different matrix pairs + if(blockSumErr){ + printf("\n"); + for(i=0; i<64; i++){ + if((i&7)==0) printf("\n"); + printf("%4d ", block_org[i]); + } + for(i=0; i<64; i++){ + if((i&7)==0) printf("\n"); + printf("%4d ", block[i] - block1[i]); + } + } +#endif + } + for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i])); + +#if 1 // dump systematic errors + for(i=0; i<64; i++){ + if(i%8==0) printf("\n"); + printf("%5d ", (int)sysErr[i]); + } + printf("\n"); +#endif + + printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", + is_idct ? "IDCT" : "DCT", + name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax); +#if 1 //Speed test + /* speed test */ + for(i=0;i<64;i++) + block1[i] = 0; + switch(test){ + case 0: + for(i=0;i<64;i++) + block1[i] = (random() % 512) -256; + if (is_idct){ + fdct(block1); + + for(i=0;i<64;i++) + block1[i]>>=3; + } + break; + case 1:{ + case 2: + block1[0] = (random() % 512) -256; + block1[1] = (random() % 512) -256; + block1[2] = (random() % 512) -256; + block1[3] = (random() % 512) -256; + }break; + } + + if (form == MMX_PERM) { + for(i=0;i<64;i++) + block[idct_mmx_perm[i]] = block1[i]; + } else if(form == MMX_SIMPLE_PERM) { + for(i=0;i<64;i++) + block[idct_simple_mmx_perm[i]] = block1[i]; + } else { + for(i=0; i<64; i++) + block[i]= block1[i]; + } + + ti = gettime(); + it1 = 0; + do { + for(it=0;it 255) + v = 255; + dest[i * linesize + j] = (int)rint(v); + } + } +} + +void idct248_error(const char *name, + void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block)) +{ + int it, i, it1, ti, ti1, err_max, v; + + srandom(0); + + /* just one test to see if code is correct (precision is less + important here) */ + err_max = 0; + for(it=0;it err_max) + err_max = v; + } +#if 0 + printf("ref=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest1[i*8+j]); + } + printf("\n"); + } + + printf("out=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest[i*8+j]); + } + printf("\n"); + } +#endif + } + printf("%s %s: err_inf=%d\n", + 1 ? "IDCT248" : "DCT248", + name, err_max); + + ti = gettime(); + it1 = 0; + do { + for(it=0;it]\n" + "test-number 0 -> test with random matrixes\n" + " 1 -> test with random sparse matrixes\n" + " 2 -> do 3. test from mpeg4 std\n" + "-i test IDCT implementations\n" + "-4 test IDCT248 implementations\n"); +} + +int main(int argc, char **argv) +{ + int test_idct = 0, test_248_dct = 0; + int c,i; + int test=1; + cpu_flags = mm_support(); + + init_fdct(); + idct_mmx_init(); + + for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i + * + * 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 + */ + +/** + * @file dirac_parser.c + * Dirac Parser + * @author Marco Gerards + */ + +#include "parser.h" + +#define DIRAC_PARSE_INFO_PREFIX 0x42424344 + +/** + * Finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame or -1 + */ +static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +{ + uint32_t state = pc->state; + int i; + + for (i = 0; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (state == DIRAC_PARSE_INFO_PREFIX) { + pc->frame_start_found ^= 1; + if (!pc->frame_start_found) { + pc->state = -1; + return i - 3; + } + } + } + + pc->state = state; + + return END_NOT_FOUND; +} + +static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + }else{ + next = find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser dirac_parser = { + { CODEC_ID_DIRAC }, + sizeof(ParseContext), + NULL, + dirac_parse, + ff_parse_close, +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.c b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.c new file mode 100644 index 0000000000..c1f2671c9d --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.c @@ -0,0 +1,445 @@ +/* + * VC3/DNxHD data. + * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier . + * + * 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 + */ + +#include "avcodec.h" +#include "dnxhddata.h" + +static const uint8_t dnxhd_1237_luma_weight[] = { + 0, 32, 33, 34, 34, 36, 37, 36, + 36, 37, 38, 38, 38, 39, 41, 44, + 43, 41, 40, 41, 46, 49, 47, 46, + 47, 49, 51, 54, 60, 62, 59, 55, + 54, 56, 58, 61, 65, 66, 64, 63, + 66, 73, 78, 79, 80, 79, 78, 78, + 82, 87, 89, 90, 93, 95, 96, 97, + 97, 100, 104, 102, 98, 98, 99, 99, +}; + +static const uint8_t dnxhd_1237_chroma_weight[] = { + 0, 32, 36, 39, 39, 38, 39, 41, + 45, 51, 57, 58, 53, 48, 47, 51, + 55, 58, 66, 75, 81, 83, 82, 78, + 73, 72, 74, 77, 83, 85, 83, 82, + 89, 99, 96, 90, 94, 97, 99, 105, + 109, 105, 95, 89, 92, 95, 94, 93, + 92, 88, 89, 90, 93, 95, 96, 97, + 97, 100, 104, 102, 98, 98, 99, 99, +}; + +static const uint8_t dnxhd_1238_luma_weight[] = { + 0, 32, 32, 33, 34, 33, 33, 33, + 33, 33, 33, 33, 33, 35, 37, 37, + 36, 36, 35, 36, 38, 38, 36, 35, + 36, 37, 38, 41, 42, 41, 39, 38, + 38, 38, 39, 41, 42, 41, 39, 39, + 40, 41, 43, 44, 44, 44, 44, 44, + 45, 47, 47, 47, 49, 50, 51, 51, + 51, 53, 55, 57, 58, 59, 57, 57, +}; + +static const uint8_t dnxhd_1238_chroma_weight[] = { + 0, 32, 35, 35, 35, 34, 34, 35, + 39, 43, 45, 45, 41, 39, 40, 41, + 42, 44, 48, 55, 59, 63, 65, 59, + 53, 52, 52, 55, 61, 62, 58, 58, + 63, 66, 66, 65, 70, 74, 70, 66, + 65, 68, 75, 77, 74, 74, 77, 76, + 73, 73, 73, 73, 76, 80, 89, 90, + 82, 77, 80, 86, 84, 82, 82, 82, +}; + +static const uint8_t dnxhd_1241_luma_weight[] = { + 0, 32, 33, 34, 34, 35, 36, 37, + 36, 37, 38, 38, 38, 39, 39, 40, + 40, 38, 38, 39, 38, 37, 39, 41, + 41, 42, 43, 45, 45, 46, 47, 46, + 45, 43, 39, 37, 37, 40, 44, 45, + 45, 46, 46, 46, 47, 47, 46, 44, + 42, 43, 45, 47, 48, 49, 50, 49, + 48, 46, 47, 48, 48, 49, 49, 49, +}; + +static const uint8_t dnxhd_1241_chroma_weight[] = { + 0, 32, 36, 38, 37, 37, 40, 41, + 40, 40, 42, 42, 41, 41, 41, 41, + 42, 43, 44, 44, 45, 46, 46, 45, + 44, 45, 45, 45, 45, 46, 47, 46, + 45, 44, 42, 41, 43, 45, 45, 47, + 48, 48, 48, 46, 47, 47, 46, 47, + 46, 45, 45, 47, 48, 49, 50, 49, + 48, 46, 48, 49, 48, 49, 49, 49, +}; + +static const uint8_t dnxhd_1242_luma_weight[] = { + 0, 32, 33, 33, 34, 35, 36, 35, + 33, 33, 35, 36, 37, 37, 38, 37, + 37, 37, 36, 37, 37, 37, 38, 39, + 37, 36, 37, 40, 42, 45, 46, 44, + 41, 42, 44, 45, 47, 49, 50, 48, + 46, 48, 49, 50, 52, 52, 50, 49, + 47, 48, 50, 50, 51, 51, 50, 49, + 49, 51, 52, 51, 49, 47, 47, 47, +}; + +static const uint8_t dnxhd_1242_chroma_weight[] = { + 0, 32, 37, 42, 45, 45, 45, 44, + 38, 37, 40, 42, 44, 49, 51, 47, + 41, 40, 43, 44, 46, 48, 51, 54, + 51, 47, 47, 45, 47, 50, 51, 49, + 46, 47, 49, 47, 50, 55, 55, 51, + 48, 49, 51, 51, 52, 52, 54, 54, + 49, 49, 52, 53, 54, 54, 53, 53, + 55, 59, 63, 62, 60, 60, 60, 60, + }; + +static const uint8_t dnxhd_1243_luma_weight[] = { + 0, 32, 32, 33, 33, 35, 35, 35, + 35, 35, 35, 35, 34, 35, 38, 40, + 39, 37, 37, 37, 36, 35, 36, 38, + 40, 41, 42, 44, 45, 44, 42, 41, + 40, 38, 36, 36, 37, 38, 40, 43, + 44, 45, 45, 45, 45, 45, 45, 41, + 39, 41, 45, 47, 47, 48, 48, 48, + 46, 44, 45, 47, 47, 48, 47, 47, +}; + +static const uint8_t dnxhd_1243_chroma_weight[] = { + 0, 32, 36, 37, 36, 37, 39, 39, + 41, 43, 43, 42, 41, 41, 41, 42, + 43, 43, 43, 44, 44, 44, 46, 47, + 46, 45, 45, 45, 45, 46, 44, 44, + 45, 44, 42, 41, 43, 46, 45, 44, + 45, 45, 45, 46, 46, 46, 45, 44, + 45, 44, 45, 47, 47, 48, 49, 48, + 46, 45, 46, 47, 47, 48, 47, 47, +}; + +static const uint8_t dnxhd_1251_luma_weight[] = { + 0, 32, 32, 34, 34, 34, 34, 35, + 35, 35, 36, 37, 36, 36, 35, 36, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 39, 41, 44, 43, 41, 40, + 40, 40, 40, 39, 40, 41, 40, 39, + 40, 43, 46, 46, 44, 44, 44, 42, + 41, 43, 46, 48, 50, 55, 58, 53, + 48, 50, 55, 58, 61, 62, 62, 62, +}; + +static const uint8_t dnxhd_1251_chroma_weight[] = { + 0, 32, 35, 36, 36, 35, 36, 39, + 41, 43, 45, 44, 41, 39, 40, 42, + 43, 43, 45, 48, 48, 48, 50, 50, + 50, 51, 51, 51, 51, 52, 53, 54, + 51, 49, 51, 52, 52, 56, 57, 55, + 54, 54, 55, 56, 55, 58, 58, 58, + 60, 61, 62, 62, 59, 57, 58, 58, + 61, 59, 59, 59, 61, 62, 62, 62, +}; + +static const uint8_t dnxhd_1252_luma_weight[] = { + 0, 32, 34, 35, 36, 36, 36, 37, + 36, 37, 39, 40, 41, 40, 40, 40, + 41, 41, 42, 41, 41, 43, 44, 44, + 45, 46, 48, 55, 60, 57, 52, 50, + 49, 49, 52, 52, 53, 55, 58, 62, + 65, 73, 82, 82, 80, 78, 73, 68, + 71, 82, 90, 90, 88, 87, 90, 95, + 100, 107, 103, 97, 95, 93, 99, 99, +}; +static const uint8_t dnxhd_1252_chroma_weight[] = { + 0, 32, 35, 36, 37, 37, 38, 40, + 42, 46, 49, 50, 50, 49, 49, 53, + 56, 56, 57, 58, 60, 62, 64, 65, + 63, 64, 64, 65, 66, 65, 67, 71, + 72, 74, 74, 74, 74, 77, 81, 78, + 72, 73, 82, 85, 89, 88, 84, 80, + 90, 100, 90, 90, 88, 87, 90, 95, + 114, 128, 125, 129, 134, 125, 116, 116, +}; + +static const uint8_t dnxhd_1237_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; + +static const uint8_t dnxhd_1237_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; + +static const uint16_t dnxhd_1237_ac_codes[257] = { + 0, 1, 4, 5, 12, 26, 27, 56, 57, 58, 59, 120, 121, 244, 245, 246, 247, 248, 498, 499, 500, 501, 502, 1006, 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1237_ac_bits[257] = { + 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1237_ac_level[257] = { + 1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12, 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24, 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35, 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; + +static const uint8_t dnxhd_1237_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1237_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1237_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 58, 118, 119, 240, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1237_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1237_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, +}; + +static const uint8_t dnxhd_1238_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; + +static const uint8_t dnxhd_1238_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; + +static const uint16_t dnxhd_1238_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1238_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1238_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; /* 0 is EOB */ + +static const uint8_t dnxhd_1238_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1238_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1238_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1238_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1238_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1241_dc_codes[14] = { + 10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127, +}; + +static const uint8_t dnxhd_1241_dc_bits[14] = { + 4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7, +}; +static const uint16_t dnxhd_1241_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1241_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1241_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13, 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1, 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; + +static const uint8_t dnxhd_1241_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1241_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1241_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1241_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1241_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 17, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1251_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; +static const uint8_t dnxhd_1251_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; +static const uint16_t dnxhd_1251_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; +static const uint8_t dnxhd_1251_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; +static const uint8_t dnxhd_1251_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20, 21, 22, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; +static const uint8_t dnxhd_1251_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint8_t dnxhd_1251_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint16_t dnxhd_1251_run_codes[62] = { + 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; +static const uint8_t dnxhd_1251_run_bits[62] = { + 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; +static const uint8_t dnxhd_1251_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1252_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; +static const uint8_t dnxhd_1252_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; +static const uint16_t dnxhd_1252_ac_codes[257] = { + 0, 1, 4, 10, 11, 12, 26, 27, 56, 57, 58, 118, 119, 120, 242, 243, 244, 245, 246, 247, 496, 497, 498, 499, 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; +static const uint8_t dnxhd_1252_ac_bits[257] = { + 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; +static const uint8_t dnxhd_1252_ac_level[257] = { + 1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12, 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7, 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37, 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; +static const uint8_t dnxhd_1252_ac_run_flag[257] = { + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint8_t dnxhd_1252_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint16_t dnxhd_1252_run_codes[62] = { + 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; +static const uint8_t dnxhd_1252_run_bits[62] = { + 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; +static const uint8_t dnxhd_1252_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +const CIDEntry ff_dnxhd_cid_table[] = { + { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, + dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 115, 120, 145, 240, 290 } }, + { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, + dnxhd_1238_luma_weight, dnxhd_1238_chroma_weight, + dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, + dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, + dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, + dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, + { 175, 185, 220, 365, 440 } }, + { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, + dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight, + dnxhd_1241_dc_codes, dnxhd_1241_dc_bits, + dnxhd_1241_ac_codes, dnxhd_1241_ac_bits, dnxhd_1241_ac_level, + dnxhd_1241_ac_run_flag, dnxhd_1241_ac_index_flag, + dnxhd_1241_run_codes, dnxhd_1241_run_bits, dnxhd_1241_run, + { 185, 220 } }, + { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, + dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 120, 145 } }, + { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, + dnxhd_1243_luma_weight, dnxhd_1243_chroma_weight, + dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, + dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, + dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, + dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, + { 185, 220 } }, + { 1251, 1280, 720, 0, 458752, 458752, 4, 8, + dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight, + dnxhd_1251_dc_codes, dnxhd_1251_dc_bits, + dnxhd_1251_ac_codes, dnxhd_1251_ac_bits, dnxhd_1251_ac_level, + dnxhd_1251_ac_run_flag, dnxhd_1251_ac_index_flag, + dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, + { 90, 110, 175, 220 } }, + { 1252, 1280, 720, 0, 303104, 303104, 4, 8, + dnxhd_1252_luma_weight, dnxhd_1252_chroma_weight, + dnxhd_1252_dc_codes, dnxhd_1252_dc_bits, + dnxhd_1252_ac_codes, dnxhd_1252_ac_bits, dnxhd_1252_ac_level, + dnxhd_1252_ac_run_flag, dnxhd_1252_ac_index_flag, + dnxhd_1252_run_codes, dnxhd_1252_run_bits, dnxhd_1252_run, + { 60, 75, 115, 145 } }, + { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, + dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 36, 45, 75, 90 } }, +}; + +int ff_dnxhd_get_cid_table(int cid) +{ + int i; + for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++) + if (ff_dnxhd_cid_table[i].cid == cid) + return i; + return -1; +} + +int ff_dnxhd_find_cid(AVCodecContext *avctx) +{ + int i, j; + int mbs = avctx->bit_rate/1000000; + if (!mbs) + return 0; + for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++) { + const CIDEntry *cid = &ff_dnxhd_cid_table[i]; + if (cid->width == avctx->width && cid->height == avctx->height && + cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) && + cid->bit_depth == 8) { // until 10 bit is supported + for (j = 0; j < sizeof(cid->bit_rates); j++) { + if (cid->bit_rates[j] == mbs) + return cid->cid; + } + } + } + return 0; +} diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.h b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.h new file mode 100644 index 0000000000..1bd028e085 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.h @@ -0,0 +1,51 @@ +/* + * VC3/DNxHD decoder. + * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier . + * + * 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 + */ + +#ifndef FFMPEG_DNXHDDATA_H +#define FFMPEG_DNXHDDATA_H + +#include +#include "avcodec.h" + +typedef struct { + int cid; + unsigned int width, height; + int interlaced; + unsigned int frame_size; + unsigned int coding_unit_size; + int index_bits; + int bit_depth; + const uint8_t *luma_weight, *chroma_weight; + const uint8_t *dc_codes, *dc_bits; + const uint16_t *ac_codes; + const uint8_t *ac_bits, *ac_level; + const uint8_t *ac_run_flag, *ac_index_flag; + const uint16_t *run_codes; + const uint8_t *run_bits, *run; + int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s +} CIDEntry; + +extern const CIDEntry ff_dnxhd_cid_table[]; + +int ff_dnxhd_get_cid_table(int cid); +int ff_dnxhd_find_cid(AVCodecContext *avctx); + +#endif /* FFMPEG_DNXHDDATA_H */ diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddec.c b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddec.c new file mode 100644 index 0000000000..1f4f1c861b --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhddec.c @@ -0,0 +1,346 @@ +/* + * VC3/DNxHD decoder. + * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier . + * + * 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 + */ + +//#define TRACE +//#define DEBUG + +#include "avcodec.h" +#include "bitstream.h" +#include "dnxhddata.h" +#include "dsputil.h" + +typedef struct { + AVCodecContext *avctx; + AVFrame picture; + GetBitContext gb; + int cid; ///< compression id + unsigned int width, height; + unsigned int mb_width, mb_height; + uint32_t mb_scan_index[68]; /* max for 1080p */ + int cur_field; ///< current interlaced field + VLC ac_vlc, dc_vlc, run_vlc; + int last_dc[3]; + DSPContext dsp; + DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); + DECLARE_ALIGNED_8(ScanTable, scantable); + const CIDEntry *cid_table; +} DNXHDContext; + +#define DNXHD_VLC_BITS 9 +#define DNXHD_DC_VLC_BITS 7 + +static av_cold int dnxhd_decode_init(AVCodecContext *avctx) +{ + DNXHDContext *ctx = avctx->priv_data; + + ctx->avctx = avctx; + dsputil_init(&ctx->dsp, avctx); + avctx->coded_frame = &ctx->picture; + ctx->picture.type = FF_I_TYPE; + return 0; +} + +static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) +{ + if (!ctx->cid_table) { + int index; + + if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); + return -1; + } + ctx->cid_table = &ff_dnxhd_cid_table[index]; + init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, + ctx->cid_table->ac_bits, 1, 1, + ctx->cid_table->ac_codes, 2, 2, 0); + init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4, + ctx->cid_table->dc_bits, 1, 1, + ctx->cid_table->dc_codes, 1, 1, 0); + init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, + ctx->cid_table->run_bits, 1, 1, + ctx->cid_table->run_codes, 2, 2, 0); + + ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); + } + return 0; +} + +static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) +{ + static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; + int i; + + if (buf_size < 0x280) + return -1; + + if (memcmp(buf, header_prefix, 5)) { + av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); + return -1; + } + if (buf[5] & 2) { /* interlaced */ + ctx->cur_field = buf[5] & 1; + ctx->picture.interlaced_frame = 1; + ctx->picture.top_field_first = first_field ^ ctx->cur_field; + av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); + } + + ctx->height = AV_RB16(buf + 0x18); + ctx->width = AV_RB16(buf + 0x1a); + + dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height); + + if (buf[0x21] & 0x40) { + av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n"); + return -1; + } + + ctx->cid = AV_RB32(buf + 0x28); + dprintf(ctx->avctx, "compression id %d\n", ctx->cid); + + if (dnxhd_init_vlc(ctx, ctx->cid) < 0) + return -1; + + if (buf_size < ctx->cid_table->coding_unit_size) { + av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n"); + return -1; + } + + ctx->mb_width = ctx->width>>4; + ctx->mb_height = buf[0x16d]; + + if (ctx->mb_height > 68) { + av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big\n"); + return -1; + } + + dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height); + for (i = 0; i < ctx->mb_height; i++) { + ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i<<2)); + dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]); + if (buf_size < ctx->mb_scan_index[i] + 0x280) { + av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n"); + return -1; + } + } + + return 0; +} + +static int dnxhd_decode_dc(DNXHDContext *ctx) +{ + int len; + + len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1); + return len ? get_xbits(&ctx->gb, len) : 0; +} + +static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale) +{ + int i, j, index, index2; + int level, component, sign; + const uint8_t *weigth_matrix; + + if (n&2) { + component = 1 + (n&1); + weigth_matrix = ctx->cid_table->chroma_weight; + } else { + component = 0; + weigth_matrix = ctx->cid_table->luma_weight; + } + + ctx->last_dc[component] += dnxhd_decode_dc(ctx); + block[0] = ctx->last_dc[component]; + //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); + for (i = 1; ; i++) { + index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); + //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); + level = ctx->cid_table->ac_level[index]; + if (!level) { /* EOB */ + //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); + return; + } + sign = get_sbits(&ctx->gb, 1); + + if (ctx->cid_table->ac_index_flag[index]) { + level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; + } + + if (ctx->cid_table->ac_run_flag[index]) { + index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); + i += ctx->cid_table->run[index2]; + } + + if (i > 63) { + av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); + return; + } + + j = ctx->scantable.permutated[i]; + //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); + //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); + level = (2*level+1) * qscale * weigth_matrix[i]; + if (ctx->cid_table->bit_depth == 10) { + if (weigth_matrix[i] != 8) + level += 8; + level >>= 4; + } else { + if (weigth_matrix[i] != 32) + level += 32; + level >>= 6; + } + //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); + block[j] = (level^sign) - sign; + } +} + +static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) +{ + int dct_linesize_luma = ctx->picture.linesize[0]; + int dct_linesize_chroma = ctx->picture.linesize[1]; + uint8_t *dest_y, *dest_u, *dest_v; + int dct_offset; + int qscale, i; + + ctx->dsp.clear_blocks(ctx->blocks[0]); + ctx->dsp.clear_blocks(ctx->blocks[2]); // FIXME change clear blocks to take block amount + + qscale = get_bits(&ctx->gb, 11); + skip_bits1(&ctx->gb); + //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); + + for (i = 0; i < 8; i++) { + dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); + } + + if (ctx->picture.interlaced_frame) { + dct_linesize_luma <<= 1; + dct_linesize_chroma <<= 1; + } + + dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); + dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); + dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); + + if (ctx->cur_field) { + dest_y += ctx->picture.linesize[0]; + dest_u += ctx->picture.linesize[1]; + dest_v += ctx->picture.linesize[2]; + } + + dct_offset = dct_linesize_luma << 3; + ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); + ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); + ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]); + ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]); + + if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { + dct_offset = dct_linesize_chroma << 3; + ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]); + ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]); + ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]); + ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]); + } + + return 0; +} + +static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) +{ + int x, y; + for (y = 0; y < ctx->mb_height; y++) { + ctx->last_dc[0] = + ctx->last_dc[1] = + ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) + init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); + for (x = 0; x < ctx->mb_width; x++) { + //START_TIMER; + dnxhd_decode_macroblock(ctx, x, y); + //STOP_TIMER("decode macroblock"); + } + } + return 0; +} + +static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + DNXHDContext *ctx = avctx->priv_data; + AVFrame *picture = data; + int first_field = 1; + + dprintf(avctx, "frame size %d\n", buf_size); + + decode_coding_unit: + if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) + return -1; + + avctx->pix_fmt = PIX_FMT_YUV422P; + if (avcodec_check_dimensions(avctx, ctx->width, ctx->height)) + return -1; + avcodec_set_dimensions(avctx, ctx->width, ctx->height); + + if (first_field) { + if (ctx->picture.data[0]) + avctx->release_buffer(avctx, &ctx->picture); + if (avctx->get_buffer(avctx, &ctx->picture) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + } + + dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); + + if (first_field && ctx->picture.interlaced_frame) { + buf += ctx->cid_table->coding_unit_size; + buf_size -= ctx->cid_table->coding_unit_size; + first_field = 0; + goto decode_coding_unit; + } + + *picture = ctx->picture; + *data_size = sizeof(AVPicture); + return buf_size; +} + +static av_cold int dnxhd_decode_close(AVCodecContext *avctx) +{ + DNXHDContext *ctx = avctx->priv_data; + + if (ctx->picture.data[0]) + avctx->release_buffer(avctx, &ctx->picture); + free_vlc(&ctx->ac_vlc); + free_vlc(&ctx->dc_vlc); + free_vlc(&ctx->run_vlc); + return 0; +} + +AVCodec dnxhd_decoder = { + "dnxhd", + CODEC_TYPE_VIDEO, + CODEC_ID_DNXHD, + sizeof(DNXHDContext), + dnxhd_decode_init, + NULL, + dnxhd_decode_close, + dnxhd_decode_frame, + CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dnxhdenc.c b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhdenc.c new file mode 100644 index 0000000000..6b1a214f72 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dnxhdenc.c @@ -0,0 +1,861 @@ +/* + * VC3/DNxHD encoder + * Copyright (c) 2007 Baptiste Coudurier + * + * VC-3 encoder funded by the British Broadcasting Corporation + * + * 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 + */ + +//#define DEBUG +#define RC_VARIANCE 1 // use variance or ssd for fast rc + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "dnxhddata.h" + +typedef struct { + uint16_t mb; + int value; +} RCCMPEntry; + +typedef struct { + int ssd; + int bits; +} RCEntry; + +int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); + +typedef struct DNXHDEncContext { + MpegEncContext m; ///< Used for quantization dsp functions + + AVFrame frame; + int cid; + const CIDEntry *cid_table; + uint8_t *msip; ///< Macroblock Scan Indexes Payload + uint32_t *slice_size; + + struct DNXHDEncContext *thread[MAX_THREADS]; + + unsigned dct_y_offset; + unsigned dct_uv_offset; + int interlaced; + int cur_field; + + DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); + + int (*qmatrix_c) [64]; + int (*qmatrix_l) [64]; + uint16_t (*qmatrix_l16)[2][64]; + uint16_t (*qmatrix_c16)[2][64]; + + unsigned frame_bits; + uint8_t *src[3]; + + uint32_t *vlc_codes; + uint8_t *vlc_bits; + uint16_t *run_codes; + uint8_t *run_bits; + + /** Rate control */ + unsigned slice_bits; + unsigned qscale; + unsigned lambda; + + unsigned thread_size; + + uint16_t *mb_bits; + uint8_t *mb_qscale; + + RCCMPEntry *mb_cmp; + RCEntry (*mb_rc)[8160]; +} DNXHDEncContext; + +#define LAMBDA_FRAC_BITS 10 + +static int dnxhd_init_vlc(DNXHDEncContext *ctx) +{ + int i, j, level, run; + int max_level = 1<<(ctx->cid_table->bit_depth+2); + + CHECKED_ALLOCZ(ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes)); + CHECKED_ALLOCZ(ctx->vlc_bits, max_level*4*sizeof(*ctx->vlc_bits)); + CHECKED_ALLOCZ(ctx->run_codes, 63*2); + CHECKED_ALLOCZ(ctx->run_bits, 63); + + ctx->vlc_codes += max_level*2; + ctx->vlc_bits += max_level*2; + for (level = -max_level; level < max_level; level++) { + for (run = 0; run < 2; run++) { + int index = (level<<1)|run; + int sign, offset = 0, alevel = level; + + MASK_ABS(sign, alevel); + if (alevel > 64) { + offset = (alevel-1)>>6; + alevel -= offset<<6; + } + for (j = 0; j < 257; j++) { + if (ctx->cid_table->ac_level[j] == alevel && + (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) && + (!run || (ctx->cid_table->ac_run_flag [j] && run))) { + assert(!ctx->vlc_codes[index]); + if (alevel) { + ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1); + ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1; + } else { + ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j]; + ctx->vlc_bits [index] = ctx->cid_table->ac_bits [j]; + } + break; + } + } + assert(!alevel || j < 257); + if (offset) { + ctx->vlc_codes[index] = (ctx->vlc_codes[index]<cid_table->index_bits)|offset; + ctx->vlc_bits [index]+= ctx->cid_table->index_bits; + } + } + } + for (i = 0; i < 62; i++) { + int run = ctx->cid_table->run[i]; + assert(run < 63); + ctx->run_codes[run] = ctx->cid_table->run_codes[i]; + ctx->run_bits [run] = ctx->cid_table->run_bits[i]; + } + return 0; + fail: + return -1; +} + +static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) +{ + // init first elem to 1 to avoid div by 0 in convert_matrix + uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* + int qscale, i; + + CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); + CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); + CHECKED_ALLOCZ(ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); + CHECKED_ALLOCZ(ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); + + for (i = 1; i < 64; i++) { + int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + weight_matrix[j] = ctx->cid_table->luma_weight[i]; + } + ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix, + ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); + for (i = 1; i < 64; i++) { + int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + weight_matrix[j] = ctx->cid_table->chroma_weight[i]; + } + ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix, + ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); + for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { + for (i = 0; i < 64; i++) { + ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2; + ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2; + ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2; + } + } + return 0; + fail: + return -1; +} + +static int dnxhd_init_rc(DNXHDEncContext *ctx) +{ + CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry)); + if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) + CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry)); + + ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8; + ctx->qscale = 1; + ctx->lambda = 2<priv_data; + int i, index; + + ctx->cid = ff_dnxhd_find_cid(avctx); + if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) { + av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n"); + return -1; + } + av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); + + index = ff_dnxhd_get_cid_table(ctx->cid); + ctx->cid_table = &ff_dnxhd_cid_table[index]; + + ctx->m.avctx = avctx; + ctx->m.mb_intra = 1; + ctx->m.h263_aic = 1; + + dsputil_init(&ctx->m.dsp, avctx); + ff_dct_common_init(&ctx->m); + if (!ctx->m.dct_quantize) + ctx->m.dct_quantize = dct_quantize_c; + + ctx->m.mb_height = (avctx->height + 15) / 16; + ctx->m.mb_width = (avctx->width + 15) / 16; + + if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { + ctx->interlaced = 1; + ctx->m.mb_height /= 2; + } + + ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width; + + if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) + ctx->m.intra_quant_bias = avctx->intra_quant_bias; + if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias + return -1; + + if (dnxhd_init_vlc(ctx) < 0) + return -1; + if (dnxhd_init_rc(ctx) < 0) + return -1; + + CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t)); + CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t)); + CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t)); + + ctx->frame.key_frame = 1; + ctx->frame.pict_type = FF_I_TYPE; + ctx->m.avctx->coded_frame = &ctx->frame; + + if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) { + av_log(avctx, AV_LOG_ERROR, "too many threads\n"); + return -1; + } + + ctx->thread[0] = ctx; + for (i = 1; i < avctx->thread_count; i++) { + ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); + memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); + } + + for (i = 0; i < avctx->thread_count; i++) { + ctx->thread[i]->m.start_mb_y = (ctx->m.mb_height*(i ) + avctx->thread_count/2) / avctx->thread_count; + ctx->thread[i]->m.end_mb_y = (ctx->m.mb_height*(i+1) + avctx->thread_count/2) / avctx->thread_count; + } + + return 0; + fail: //for CHECKED_ALLOCZ + return -1; +} + +static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) +{ + DNXHDEncContext *ctx = avctx->priv_data; + const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; + + memcpy(buf, header_prefix, 5); + buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01; + buf[6] = 0x80; // crc flag off + buf[7] = 0xa0; // reserved + AV_WB16(buf + 0x18, avctx->height); // ALPF + AV_WB16(buf + 0x1a, avctx->width); // SPL + AV_WB16(buf + 0x1d, avctx->height); // NAL + + buf[0x21] = 0x38; // FIXME 8 bit per comp + buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2); + AV_WB32(buf + 0x28, ctx->cid); // CID + buf[0x2c] = ctx->interlaced ? 0 : 0x80; + + buf[0x5f] = 0x01; // UDL + + buf[0x167] = 0x02; // reserved + AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS + buf[0x16d] = ctx->m.mb_height; // Ns + buf[0x16f] = 0x10; // reserved + + ctx->msip = buf + 0x170; + return 0; +} + +static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff) +{ + int nbits; + if (diff < 0) { + nbits = av_log2_16bit(-2*diff); + diff--; + } else { + nbits = av_log2_16bit(2*diff); + } + put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits, + (ctx->cid_table->dc_codes[nbits]<m.last_dc[n]); + ctx->m.last_dc[n] = block[0]; + + for (i = 1; i <= last_index; i++) { + j = ctx->m.intra_scantable.permutated[i]; + slevel = block[j]; + if (slevel) { + int run_level = i - last_non_zero - 1; + int rlevel = (slevel<<1)|!!run_level; + put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]); + if (run_level) + put_bits(&ctx->m.pb, ctx->run_bits[run_level], ctx->run_codes[run_level]); + last_non_zero = i; + } + } + put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB +} + +static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index) +{ + const uint8_t *weight_matrix; + int level; + int i; + + weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight; + + for (i = 1; i <= last_index; i++) { + int j = ctx->m.intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = (1-2*level) * qscale * weight_matrix[i]; + if (weight_matrix[i] != 32) + level += 32; + level >>= 6; + level = -level; + } else { + level = (2*level+1) * qscale * weight_matrix[i]; + if (weight_matrix[i] != 32) + level += 32; + level >>= 6; + } + block[j] = level; + } + } +} + +static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block) +{ + int score = 0; + int i; + for (i = 0; i < 64; i++) + score += (block[i]-qblock[i])*(block[i]-qblock[i]); + return score; +} + +static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index) +{ + int last_non_zero = 0; + int bits = 0; + int i, j, level; + for (i = 1; i <= last_index; i++) { + j = ctx->m.intra_scantable.permutated[i]; + level = block[j]; + if (level) { + int run_level = i - last_non_zero - 1; + bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level]; + last_non_zero = i; + } + } + return bits; +} + +static av_always_inline void dnxhd_get_pixels_4x8(DCTELEM *restrict block, const uint8_t *pixels, int line_size) +{ + int i; + for (i = 0; i < 4; i++) { + block[0] = pixels[0]; + block[1] = pixels[1]; + block[2] = pixels[2]; + block[3] = pixels[3]; + block[4] = pixels[4]; + block[5] = pixels[5]; + block[6] = pixels[6]; + block[7] = pixels[7]; + pixels += line_size; + block += 8; + } + memcpy(block , block- 8, sizeof(*block)*8); + memcpy(block+ 8, block-16, sizeof(*block)*8); + memcpy(block+16, block-24, sizeof(*block)*8); + memcpy(block+24, block-32, sizeof(*block)*8); +} + +static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) +{ + const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4); + const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); + const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); + DSPContext *dsp = &ctx->m.dsp; + + dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize); + dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize); + dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize); + dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize); + + if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { + if (ctx->interlaced) { + dnxhd_get_pixels_4x8(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); + dnxhd_get_pixels_4x8(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); + dnxhd_get_pixels_4x8(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); + dnxhd_get_pixels_4x8(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); + } else + memset(ctx->blocks[4], 0, 4*64*sizeof(DCTELEM)); + } else { + dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); + dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); + dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); + dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); + } +} + +static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) +{ + if (i&2) { + ctx->m.q_intra_matrix16 = ctx->qmatrix_c16; + ctx->m.q_intra_matrix = ctx->qmatrix_c; + return 1 + (i&1); + } else { + ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; + ctx->m.q_intra_matrix = ctx->qmatrix_l; + return 0; + } +} + +static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + int qscale = ctx->thread[0]->qscale; + + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + ctx->m.last_dc[0] = + ctx->m.last_dc[1] = + ctx->m.last_dc[2] = 1024; + + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + int ssd = 0; + int ac_bits = 0; + int dc_bits = 0; + int i; + + dnxhd_get_blocks(ctx, mb_x, mb_y); + + for (i = 0; i < 8; i++) { + DECLARE_ALIGNED_16(DCTELEM, block[64]); + DCTELEM *src_block = ctx->blocks[i]; + int overflow, nbits, diff, last_index; + int n = dnxhd_switch_matrix(ctx, i); + + memcpy(block, src_block, sizeof(block)); + last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); + ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); + + diff = block[0] - ctx->m.last_dc[n]; + if (diff < 0) nbits = av_log2_16bit(-2*diff); + else nbits = av_log2_16bit( 2*diff); + dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; + + ctx->m.last_dc[n] = block[0]; + + if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { + dnxhd_unquantize_c(ctx, block, i, qscale, last_index); + ctx->m.dsp.idct(block); + ssd += dnxhd_ssd_block(block, src_block); + } + } + ctx->mb_rc[qscale][mb].ssd = ssd; + ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0]; + } + } + return 0; +} + +static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + ctx->m.last_dc[0] = + ctx->m.last_dc[1] = + ctx->m.last_dc[2] = 1024; + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + int qscale = ctx->mb_qscale[mb]; + int i; + + put_bits(&ctx->m.pb, 12, qscale<<1); + + dnxhd_get_blocks(ctx, mb_x, mb_y); + + for (i = 0; i < 8; i++) { + DCTELEM *block = ctx->blocks[i]; + int last_index, overflow; + int n = dnxhd_switch_matrix(ctx, i); + last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); + //START_TIMER; + dnxhd_encode_block(ctx, block, last_index, n); + //STOP_TIMER("encode_block"); + } + } + if (put_bits_count(&ctx->m.pb)&31) + put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0); + } + flush_put_bits(&ctx->m.pb); + return 0; +} + +static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf) +{ + int mb_y, mb_x; + int i, offset = 0; + for (i = 0; i < ctx->m.avctx->thread_count; i++) { + int thread_size = 0; + for (mb_y = ctx->thread[i]->m.start_mb_y; mb_y < ctx->thread[i]->m.end_mb_y; mb_y++) { + ctx->slice_size[mb_y] = 0; + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + ctx->slice_size[mb_y] += ctx->mb_bits[mb]; + } + ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31; + ctx->slice_size[mb_y] >>= 3; + thread_size += ctx->slice_size[mb_y]; + } + init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size); + offset += thread_size; + } +} + +static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4); + int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); + int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8; + ctx->mb_cmp[mb].value = varc; + ctx->mb_cmp[mb].mb = mb; + } + } + return 0; +} + +static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) +{ + int lambda, up_step, down_step; + int last_lower = INT_MAX, last_higher = 0; + int x, y, q; + + for (q = 1; q < avctx->qmax; q++) { + ctx->qscale = q; + avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + } + up_step = down_step = 2<lambda; + + for (;;) { + int bits = 0; + int end = 0; + if (lambda == last_higher) { + lambda++; + end = 1; // need to set final qscales/bits + } + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) { + unsigned min = UINT_MAX; + int qscale = 1; + int mb = y*ctx->m.mb_width+x; + for (q = 1; q < avctx->qmax; q++) { + unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<mb_rc[qscale][mb].bits; + ctx->mb_qscale[mb] = qscale; + ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits; + } + bits = (bits+31)&~31; // padding + if (bits > ctx->frame_bits) + break; + } + //dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n", + // lambda, last_higher, last_lower, bits, ctx->frame_bits); + if (end) { + if (bits > ctx->frame_bits) + return -1; + break; + } + if (bits < ctx->frame_bits) { + last_lower = FFMIN(lambda, last_lower); + if (last_higher != 0) + lambda = (lambda+last_higher)>>1; + else + lambda -= down_step; + down_step *= 5; // XXX tune ? + up_step = 1<>1; + else + lambda += up_step; + up_step *= 5; + down_step = 1<m.avctx, "out lambda %d\n", lambda); + ctx->lambda = lambda; + return 0; +} + +static int dnxhd_find_qscale(DNXHDEncContext *ctx) +{ + int bits = 0; + int up_step = 1; + int down_step = 1; + int last_higher = 0; + int last_lower = INT_MAX; + int qscale; + int x, y; + + qscale = ctx->qscale; + for (;;) { + bits = 0; + ctx->qscale = qscale; + // XXX avoid recalculating bits + ctx->m.avctx->execute(ctx->m.avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, ctx->m.avctx->thread_count); + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) + bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits; + bits = (bits+31)&~31; // padding + if (bits > ctx->frame_bits) + break; + } + //dprintf(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", + // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower); + if (bits < ctx->frame_bits) { + if (qscale == 1) + return 1; + if (last_higher == qscale - 1) { + qscale = last_higher; + break; + } + last_lower = FFMIN(qscale, last_lower); + if (last_higher != 0) + qscale = (qscale+last_higher)>>1; + else + qscale -= down_step++; + if (qscale < 1) + qscale = 1; + up_step = 1; + } else { + if (last_lower == qscale + 1) + break; + last_higher = FFMAX(qscale, last_higher); + if (last_lower != INT_MAX) + qscale = (qscale+last_lower)>>1; + else + qscale += up_step++; + down_step = 1; + if (qscale >= ctx->m.avctx->qmax) + return -1; + } + } + //dprintf(ctx->m.avctx, "out qscale %d\n", qscale); + ctx->qscale = qscale; + return 0; +} + +static int dnxhd_rc_cmp(const void *a, const void *b) +{ + return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value; +} + +static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx) +{ + int max_bits = 0; + int ret, x, y; + if ((ret = dnxhd_find_qscale(ctx)) < 0) + return -1; + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) { + int mb = y*ctx->m.mb_width+x; + int delta_bits; + ctx->mb_qscale[mb] = ctx->qscale; + ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits; + max_bits += ctx->mb_rc[ctx->qscale][mb].bits; + if (!RC_VARIANCE) { + delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits; + ctx->mb_cmp[mb].mb = mb; + ctx->mb_cmp[mb].value = delta_bits ? + ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits + : INT_MIN; //avoid increasing qscale + } + } + max_bits += 31; //worst padding + } + if (!ret) { + if (RC_VARIANCE) + avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp); + for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) { + int mb = ctx->mb_cmp[x].mb; + max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits; + ctx->mb_qscale[mb] = ctx->qscale+1; + ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits; + } + } + return 0; +} + +static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) +{ + int i; + + for (i = 0; i < 3; i++) { + ctx->frame.data[i] = frame->data[i]; + ctx->frame.linesize[i] = frame->linesize[i]; + } + + for (i = 0; i < ctx->m.avctx->thread_count; i++) { + ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<interlaced; + ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<interlaced; + ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; + ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; + } + + ctx->frame.interlaced_frame = frame->interlaced_frame; + ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; +} + +static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, const void *data) +{ + DNXHDEncContext *ctx = avctx->priv_data; + int first_field = 1; + int offset, i, ret; + + if (buf_size < ctx->cid_table->frame_size) { + av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n"); + return -1; + } + + dnxhd_load_picture(ctx, data); + + encode_coding_unit: + for (i = 0; i < 3; i++) { + ctx->src[i] = ctx->frame.data[i]; + if (ctx->interlaced && ctx->cur_field) + ctx->src[i] += ctx->frame.linesize[i]; + } + + dnxhd_write_header(avctx, buf); + + if (avctx->mb_decision == FF_MB_DECISION_RD) + ret = dnxhd_encode_rdo(avctx, ctx); + else + ret = dnxhd_encode_fast(avctx, ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n"); + return -1; + } + + dnxhd_setup_threads_slices(ctx, buf); + + offset = 0; + for (i = 0; i < ctx->m.mb_height; i++) { + AV_WB32(ctx->msip + i * 4, offset); + offset += ctx->slice_size[i]; + assert(!(ctx->slice_size[i] & 3)); + } + + avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + + AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF + + if (ctx->interlaced && first_field) { + first_field = 0; + ctx->cur_field ^= 1; + buf += ctx->cid_table->coding_unit_size; + buf_size -= ctx->cid_table->coding_unit_size; + goto encode_coding_unit; + } + + ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA; + + return ctx->cid_table->frame_size; +} + +static int dnxhd_encode_end(AVCodecContext *avctx) +{ + DNXHDEncContext *ctx = avctx->priv_data; + int max_level = 1<<(ctx->cid_table->bit_depth+2); + int i; + + av_free(ctx->vlc_codes-max_level*2); + av_free(ctx->vlc_bits -max_level*2); + av_freep(&ctx->run_codes); + av_freep(&ctx->run_bits); + + av_freep(&ctx->mb_bits); + av_freep(&ctx->mb_qscale); + av_freep(&ctx->mb_rc); + av_freep(&ctx->mb_cmp); + av_freep(&ctx->slice_size); + + av_freep(&ctx->qmatrix_c); + av_freep(&ctx->qmatrix_l); + av_freep(&ctx->qmatrix_c16); + av_freep(&ctx->qmatrix_l16); + + for (i = 1; i < avctx->thread_count; i++) + av_freep(&ctx->thread[i]); + + return 0; +} + +AVCodec dnxhd_encoder = { + "dnxhd", + CODEC_TYPE_VIDEO, + CODEC_ID_DNXHD, + sizeof(DNXHDEncContext), + dnxhd_encode_init, + dnxhd_encode_picture, + dnxhd_encode_end, + .pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dpcm.c b/src/add-ons/media/plugins/avcodec/libavcodec/dpcm.c index b59a9cd6b8..ff684aeb43 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/dpcm.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dpcm.c @@ -2,19 +2,21 @@ * Assorted DPCM codecs * Copyright (c) 2003 The ffmpeg Project. * - * This library is free software; you can redistribute it and/or + * 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -24,6 +26,7 @@ * Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt) * for more information on the specific data formats, visit: * http://www.pcisys.net/~melanson/codecs/simpleaudio.html + * SOL DPCMs implemented by Konstantin Shishkov * * Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files * found in the Wing Commander IV computer game. These AVI files contain @@ -39,18 +42,13 @@ typedef struct DPCMContext { int channels; short roq_square_array[256]; + long sample[2];//for SOL_DPCM + const int *sol_table;//for SOL_DPCM } DPCMContext; -#define SATURATE_S16(x) if (x < -32768) x = -32768; \ - else if (x > 32767) x = 32767; #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; -#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0]) -#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \ - (((uint8_t*)(x))[2] << 16) | \ - (((uint8_t*)(x))[1] << 8) | \ - ((uint8_t*)(x))[0]) -static int interplay_delta_table[] = { +static const int interplay_delta_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -86,13 +84,40 @@ static int interplay_delta_table[] = { }; -static int dpcm_decode_init(AVCodecContext *avctx) +static const int sol_table_old[16] = + { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15, + -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0}; + +static const int sol_table_new[16] = + { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, + 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15}; + +static const int sol_table_16[128] = { + 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, + 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, + 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, + 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, + 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, + 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, + 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, + 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, + 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, + 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, + 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, + 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, + 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 +}; + + + +static av_cold int dpcm_decode_init(AVCodecContext *avctx) { DPCMContext *s = avctx->priv_data; int i; short square; s->channels = avctx->channels; + s->sample[0] = s->sample[1] = 0; switch(avctx->codec->id) { @@ -105,16 +130,37 @@ static int dpcm_decode_init(AVCodecContext *avctx) } break; + + case CODEC_ID_SOL_DPCM: + switch(avctx->codec_tag){ + case 1: + s->sol_table=sol_table_old; + s->sample[0] = s->sample[1] = 0x80; + break; + case 2: + s->sol_table=sol_table_new; + s->sample[0] = s->sample[1] = 0x80; + break; + case 3: + s->sol_table=sol_table_16; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n"); + return -1; + } + break; + default: break; } + avctx->sample_fmt = SAMPLE_FMT_S16; return 0; } static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DPCMContext *s = avctx->priv_data; int in, out = 0; @@ -128,11 +174,15 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; + // almost every DPCM variant expands one byte of data into two + if(*data_size/2 < buf_size) + return -1; + switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: if (s->channels == 1) - predictor[0] = LE_16(&buf[6]); + predictor[0] = AV_RL16(&buf[6]); else { predictor[0] = buf[7] << 8; predictor[1] = buf[6] << 8; @@ -143,7 +193,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, /* decode the samples */ for (in = 8, out = 0; in < buf_size; in++, out++) { predictor[channel_number] += s->roq_square_array[buf[in]]; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out] = predictor[channel_number]; /* toggle channel */ @@ -153,12 +203,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_INTERPLAY_DPCM: in = 6; /* skip over the stream mask and stream length */ - predictor[0] = LE_16(&buf[in]); + predictor[0] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[0]) output_samples[out++] = predictor[0]; if (s->channels == 2) { - predictor[1] = LE_16(&buf[in]); + predictor[1] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[1]) output_samples[out++] = predictor[1]; @@ -166,7 +216,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, while (in < buf_size) { predictor[channel_number] += interplay_delta_table[buf[in++]]; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out++] = predictor[channel_number]; /* toggle channel */ @@ -178,11 +228,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_XAN_DPCM: in = 0; shift[0] = shift[1] = 4; - predictor[0] = LE_16(&buf[in]); + predictor[0] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[0]); if (s->channels == 2) { - predictor[1] = LE_16(&buf[in]); + predictor[1] = AV_RL16(&buf[in]); in += 2; SE_16BIT(predictor[1]); } @@ -201,48 +251,64 @@ static int dpcm_decode_frame(AVCodecContext *avctx, diff >>= shift[channel_number]; predictor[channel_number] += diff; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out++] = predictor[channel_number]; /* toggle channel */ channel_number ^= s->channels - 1; } break; + case CODEC_ID_SOL_DPCM: + in = 0; + if (avctx->codec_tag != 3) { + if(*data_size/4 < buf_size) + return -1; + while (in < buf_size) { + int n1, n2; + n1 = (buf[in] >> 4) & 0xF; + n2 = buf[in++] & 0xF; + s->sample[0] += s->sol_table[n1]; + if (s->sample[0] < 0) s->sample[0] = 0; + if (s->sample[0] > 255) s->sample[0] = 255; + output_samples[out++] = (s->sample[0] - 128) << 8; + s->sample[s->channels - 1] += s->sol_table[n2]; + if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0; + if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255; + output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8; + } + } else { + while (in < buf_size) { + int n; + n = buf[in++]; + if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F]; + else s->sample[channel_number] += s->sol_table[n & 0x7F]; + s->sample[channel_number] = av_clip_int16(s->sample[channel_number]); + output_samples[out++] = s->sample[channel_number]; + /* toggle channel */ + channel_number ^= s->channels - 1; + } + } + break; } *data_size = out * sizeof(short); return buf_size; } -AVCodec roq_dpcm_decoder = { - "roq_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_ROQ_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, +#define DPCM_DECODER(id, name, long_name_) \ +AVCodec name ## _decoder = { \ + #name, \ + CODEC_TYPE_AUDIO, \ + id, \ + sizeof(DPCMContext), \ + dpcm_decode_init, \ + NULL, \ + NULL, \ + dpcm_decode_frame, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ }; -AVCodec interplay_dpcm_decoder = { - "interplay_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_INTERPLAY_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, -}; - -AVCodec xan_dpcm_decoder = { - "xan_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_XAN_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, -}; +DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "Interplay DPCM"); +DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "id RoQ DPCM"); +DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "Sol DPCM"); +DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "Xan DPCM"); diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dsicinav.c b/src/add-ons/media/plugins/avcodec/libavcodec/dsicinav.c new file mode 100644 index 0000000000..039b0adc0d --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dsicinav.c @@ -0,0 +1,365 @@ +/* + * Delphine Software International CIN Audio/Video Decoders + * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) + * + * 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 + */ + +/** + * @file dsicinav.c + * Delphine Software International CIN audio/video decoders + */ + +#include "avcodec.h" +#include "bytestream.h" + + +typedef enum CinVideoBitmapIndex { + CIN_CUR_BMP = 0, /* current */ + CIN_PRE_BMP = 1, /* previous */ + CIN_INT_BMP = 2 /* intermediate */ +} CinVideoBitmapIndex; + +typedef struct CinVideoContext { + AVCodecContext *avctx; + AVFrame frame; + unsigned int bitmap_size; + uint32_t palette[256]; + uint8_t *bitmap_table[3]; +} CinVideoContext; + +typedef struct CinAudioContext { + AVCodecContext *avctx; + int initial_decode_frame; + int delta; +} CinAudioContext; + + +/* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */ +static const int16_t cinaudio_delta16_table[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -30210, -27853, -25680, -23677, -21829, + -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398, + -10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951, + -5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107, + -2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622, + -1495, -1379, -1271, -1172, -1080, -996, -918, -847, + -781, -720, -663, -612, -564, -520, -479, -442, + -407, -376, -346, -319, -294, -271, -250, -230, + -212, -196, -181, -166, -153, -141, -130, -120, + -111, -102, -94, -87, -80, -74, -68, -62, + -58, -53, -49, -45, -41, -38, -35, -32, + -30, -27, -25, -23, -21, -20, -18, -17, + -15, -14, -13, -12, -11, -10, -9, -8, + -7, -6, -5, -4, -3, -2, -1, 0, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 17, 18, 20, 21, 23, 25, 27, 30, + 32, 35, 38, 41, 45, 49, 53, 58, + 62, 68, 74, 80, 87, 94, 102, 111, + 120, 130, 141, 153, 166, 181, 196, 212, + 230, 250, 271, 294, 319, 346, 376, 407, + 442, 479, 520, 564, 612, 663, 720, 781, + 847, 918, 996, 1080, 1172, 1271, 1379, 1495, + 1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865, + 3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487, + 5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508, + 11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126, + 21829, 23677, 25680, 27853, 30210, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + + +static av_cold int cinvideo_decode_init(AVCodecContext *avctx) +{ + CinVideoContext *cin = avctx->priv_data; + unsigned int i; + + cin->avctx = avctx; + avctx->pix_fmt = PIX_FMT_PAL8; + + cin->frame.data[0] = NULL; + + cin->bitmap_size = avctx->width * avctx->height; + for (i = 0; i < 3; ++i) { + cin->bitmap_table[i] = av_mallocz(cin->bitmap_size); + if (!cin->bitmap_table[i]) + av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n"); + } + + return 0; +} + +static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size) +{ + while (size--) + *dst++ += *src++; +} + +static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +{ + int b, huff_code = 0; + unsigned char huff_code_table[15]; + unsigned char *dst_cur = dst; + unsigned char *dst_end = dst + dst_size; + const unsigned char *src_end = src + src_size; + + memcpy(huff_code_table, src, 15); src += 15; src_size -= 15; + + while (src < src_end) { + huff_code = *src++; + if ((huff_code >> 4) == 15) { + b = huff_code << 4; + huff_code = *src++; + *dst_cur++ = b | (huff_code >> 4); + } else + *dst_cur++ = huff_code_table[huff_code >> 4]; + if (dst_cur >= dst_end) + break; + + huff_code &= 15; + if (huff_code == 15) { + *dst_cur++ = *src++; + } else + *dst_cur++ = huff_code_table[huff_code]; + if (dst_cur >= dst_end) + break; + } + + return dst_cur - dst; +} + +static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +{ + uint16_t cmd; + int i, sz, offset, code; + unsigned char *dst_end = dst + dst_size; + const unsigned char *src_end = src + src_size; + + while (src < src_end && dst < dst_end) { + code = *src++; + for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) { + if (code & (1 << i)) { + *dst++ = *src++; + } else { + cmd = AV_RL16(src); src += 2; + offset = cmd >> 4; + sz = (cmd & 0xF) + 2; + /* don't use memcpy/memmove here as the decoding routine (ab)uses */ + /* buffer overlappings to repeat bytes in the destination */ + sz = FFMIN(sz, dst_end - dst); + while (sz--) { + *dst = *(dst - offset - 1); + ++dst; + } + } + } + } +} + +static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +{ + int len, code; + unsigned char *dst_end = dst + dst_size; + const unsigned char *src_end = src + src_size; + + while (src < src_end && dst < dst_end) { + code = *src++; + if (code & 0x80) { + len = code - 0x7F; + memset(dst, *src++, FFMIN(len, dst_end - dst)); + } else { + len = code + 1; + memcpy(dst, src, FFMIN(len, dst_end - dst)); + src += len; + } + dst += len; + } +} + +static int cinvideo_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + CinVideoContext *cin = avctx->priv_data; + int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size; + + cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &cin->frame)) { + av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); + return -1; + } + + palette_type = buf[0]; + palette_colors_count = AV_RL16(buf+1); + bitmap_frame_type = buf[3]; + buf += 4; + + bitmap_frame_size = buf_size - 4; + + /* handle palette */ + if (palette_type == 0) { + for (i = 0; i < palette_colors_count; ++i) { + cin->palette[i] = bytestream_get_le24(&buf); + bitmap_frame_size -= 3; + } + } else { + for (i = 0; i < palette_colors_count; ++i) { + cin->palette[buf[0]] = AV_RL24(buf+1); + buf += 4; + bitmap_frame_size -= 4; + } + } + memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); + cin->frame.palette_has_changed = 1; + + /* note: the decoding routines below assumes that surface.width = surface.pitch */ + switch (bitmap_frame_type) { + case 9: + cin_decode_rle(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 34: + cin_decode_rle(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 35: + cin_decode_huffman(buf, bitmap_frame_size, + cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 36: + bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size, + cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 37: + cin_decode_huffman(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 38: + cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + case 39: + cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + break; + } + + for (y = 0; y < cin->avctx->height; ++y) + memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], + cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, + cin->avctx->width); + + FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = cin->frame; + + return buf_size; +} + +static av_cold int cinvideo_decode_end(AVCodecContext *avctx) +{ + CinVideoContext *cin = avctx->priv_data; + int i; + + if (cin->frame.data[0]) + avctx->release_buffer(avctx, &cin->frame); + + for (i = 0; i < 3; ++i) + av_free(cin->bitmap_table[i]); + + return 0; +} + +static av_cold int cinaudio_decode_init(AVCodecContext *avctx) +{ + CinAudioContext *cin = avctx->priv_data; + + cin->avctx = avctx; + cin->initial_decode_frame = 1; + cin->delta = 0; + avctx->sample_fmt = SAMPLE_FMT_S16; + + return 0; +} + +static int cinaudio_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + CinAudioContext *cin = avctx->priv_data; + const uint8_t *src = buf; + int16_t *samples = (int16_t *)data; + + buf_size = FFMIN(buf_size, *data_size/2); + + if (cin->initial_decode_frame) { + cin->initial_decode_frame = 0; + cin->delta = (int16_t)AV_RL16(src); src += 2; + *samples++ = cin->delta; + buf_size -= 2; + } + while (buf_size > 0) { + cin->delta += cinaudio_delta16_table[*src++]; + cin->delta = av_clip_int16(cin->delta); + *samples++ = cin->delta; + --buf_size; + } + + *data_size = (uint8_t *)samples - (uint8_t *)data; + + return src - buf; +} + + +AVCodec dsicinvideo_decoder = { + "dsicinvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_DSICINVIDEO, + sizeof(CinVideoContext), + cinvideo_decode_init, + NULL, + cinvideo_decode_end, + cinvideo_decode_frame, + CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"), +}; + +AVCodec dsicinaudio_decoder = { + "dsicinaudio", + CODEC_TYPE_AUDIO, + CODEC_ID_DSICINAUDIO, + sizeof(CinAudioContext), + cinaudio_decode_init, + NULL, + NULL, + cinaudio_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.c b/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.c index 114d67b501..241bad0d4f 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.c @@ -3,36 +3,59 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * - * This library is free software; you can redistribute it and/or + * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer + * + * 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + /** * @file dsputil.c * DSP utils */ - + #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" #include "simple_idct.h" #include "faandct.h" +#include "faanidct.h" +#include "h263.h" +#include "snow.h" -uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; -uint32_t squareTbl[512]; +/* snow.c */ +void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count); + +/* vorbis.c */ +void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); + +/* ac3dec.c */ +void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); + +/* flacenc.c */ +void ff_flac_compute_autocorr(const int32_t *data, int len, int lag, double *autoc); + +/* pngdec.c */ +void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + +uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; +uint32_t ff_squareTbl[512] = {0, }; + +// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size +#define pb_7f (~0UL/255 * 0x7f) +#define pb_80 (~0UL/255 * 0x80) const uint8_t ff_zigzag_direct[64] = { 0, 1, 8, 16, 9, 2, 3, 10, @@ -59,96 +82,122 @@ const uint8_t ff_zigzag248_direct[64] = { }; /* not permutated inverse zigzag_direct + 1 for MMX quantizer */ -uint16_t __align8 inv_zigzag_direct16[64]; +DECLARE_ALIGNED_8(uint16_t, inv_zigzag_direct16[64]) = {0, }; const uint8_t ff_alternate_horizontal_scan[64] = { - 0, 1, 2, 3, 8, 9, 16, 17, + 0, 1, 2, 3, 8, 9, 16, 17, 10, 11, 4, 5, 6, 7, 15, 14, - 13, 12, 19, 18, 24, 25, 32, 33, + 13, 12, 19, 18, 24, 25, 32, 33, 26, 27, 20, 21, 22, 23, 28, 29, - 30, 31, 34, 35, 40, 41, 48, 49, + 30, 31, 34, 35, 40, 41, 48, 49, 42, 43, 36, 37, 38, 39, 44, 45, - 46, 47, 50, 51, 56, 57, 58, 59, + 46, 47, 50, 51, 56, 57, 58, 59, 52, 53, 54, 55, 60, 61, 62, 63, }; const uint8_t ff_alternate_vertical_scan[64] = { - 0, 8, 16, 24, 1, 9, 2, 10, + 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, - 41, 33, 26, 18, 3, 11, 4, 12, + 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, - 51, 59, 20, 28, 5, 13, 6, 14, + 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, - 53, 61, 22, 30, 7, 15, 23, 31, + 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63, }; /* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ -const uint32_t inverse[256]={ - 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, - 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, - 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, - 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, - 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, - 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, - 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, - 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, - 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, - 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, - 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, - 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, - 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, - 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, - 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, - 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, - 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, - 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, - 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, - 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, - 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, - 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, - 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, - 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, - 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, - 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, - 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, - 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, - 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, - 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, - 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, +const uint32_t ff_inverse[256]={ + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, }; /* Input permutation for the simple_idct_mmx */ static const uint8_t simple_mmx_permutation[64]={ - 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, - 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, - 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, - 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, - 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, - 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, - 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, - 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, }; +static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7}; + +void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ + int i; + int end; + + st->scantable= src_scantable; + + for(i=0; i<64; i++){ + int j; + j = src_scantable[i]; + st->permutated[i] = permutation[j]; +#ifdef ARCH_POWERPC + st->inverse[j] = i; +#endif + } + + end=-1; + for(i=0; i<64; i++){ + int j; + j = st->permutated[i]; + if(j>end) end=j; + st->raster_end[i]= end; + } +} + static int pix_sum_c(uint8_t * pix, int line_size) { int s, i, j; s = 0; for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { - s += pix[0]; - s += pix[1]; - s += pix[2]; - s += pix[3]; - s += pix[4]; - s += pix[5]; - s += pix[6]; - s += pix[7]; - pix += 8; - } - pix += line_size - 16; + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; } return s; } @@ -156,37 +205,37 @@ static int pix_sum_c(uint8_t * pix, int line_size) static int pix_norm1_c(uint8_t * pix, int line_size) { int s, i, j; - uint32_t *sq = squareTbl + 256; + uint32_t *sq = ff_squareTbl + 256; s = 0; for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { + for (j = 0; j < 16; j += 8) { #if 0 - s += sq[pix[0]]; - s += sq[pix[1]]; - s += sq[pix[2]]; - s += sq[pix[3]]; - s += sq[pix[4]]; - s += sq[pix[5]]; - s += sq[pix[6]]; - s += sq[pix[7]]; + s += sq[pix[0]]; + s += sq[pix[1]]; + s += sq[pix[2]]; + s += sq[pix[3]]; + s += sq[pix[4]]; + s += sq[pix[5]]; + s += sq[pix[6]]; + s += sq[pix[7]]; #else #if LONG_MAX > 2147483647 - register uint64_t x=*(uint64_t*)pix; - s += sq[x&0xff]; - s += sq[(x>>8)&0xff]; - s += sq[(x>>16)&0xff]; - s += sq[(x>>24)&0xff]; + register uint64_t x=*(uint64_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; s += sq[(x>>32)&0xff]; s += sq[(x>>40)&0xff]; s += sq[(x>>48)&0xff]; s += sq[(x>>56)&0xff]; #else - register uint32_t x=*(uint32_t*)pix; - s += sq[x&0xff]; - s += sq[(x>>8)&0xff]; - s += sq[(x>>16)&0xff]; - s += sq[(x>>24)&0xff]; + register uint32_t x=*(uint32_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; x=*(uint32_t*)(pix+4); s += sq[x&0xff]; s += sq[(x>>8)&0xff]; @@ -194,16 +243,16 @@ static int pix_norm1_c(uint8_t * pix, int line_size) s += sq[(x>>24)&0xff]; #endif #endif - pix += 8; - } - pix += line_size - 16; + pix += 8; + } + pix += line_size - 16; } return s; } -static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ +static void bswap_buf(uint32_t *dst, const uint32_t *src, int w){ int i; - + for(i=0; i+8<=w; i+=8){ dst[i+0]= bswap_32(src[i+0]); dst[i+1]= bswap_32(src[i+1]); @@ -219,10 +268,27 @@ static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ } } +static int sse4_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) +{ + int s, i; + uint32_t *sq = ff_squareTbl + 256; + + s = 0; + for (i = 0; i < h; i++) { + s += sq[pix1[0] - pix2[0]]; + s += sq[pix1[1] - pix2[1]]; + s += sq[pix1[2] - pix2[2]]; + s += sq[pix1[3] - pix2[3]]; + pix1 += line_size; + pix2 += line_size; + } + return s; +} + static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { int s, i; - uint32_t *sq = squareTbl + 256; + uint32_t *sq = ff_squareTbl + 256; s = 0; for (i = 0; i < h; i++) { @@ -243,7 +309,7 @@ static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int s, i; - uint32_t *sq = squareTbl + 256; + uint32_t *sq = ff_squareTbl + 256; s = 0; for (i = 0; i < h; i++) { @@ -270,6 +336,202 @@ static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) return s; } + +#ifdef CONFIG_SNOW_ENCODER //dwt is in snow.c +static inline int w_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int w, int h, int type){ + int s, i, j; + const int dec_count= w==8 ? 3 : 4; + int tmp[32*32]; + int level, ori; + static const int scale[2][2][4][4]={ + { + { + // 9/7 8x8 dec=3 + {268, 239, 239, 213}, + { 0, 224, 224, 152}, + { 0, 135, 135, 110}, + },{ + // 9/7 16x16 or 32x32 dec=4 + {344, 310, 310, 280}, + { 0, 320, 320, 228}, + { 0, 175, 175, 136}, + { 0, 129, 129, 102}, + } + },{ + { + // 5/3 8x8 dec=3 + {275, 245, 245, 218}, + { 0, 230, 230, 156}, + { 0, 138, 138, 113}, + },{ + // 5/3 16x16 or 32x32 dec=4 + {352, 317, 317, 286}, + { 0, 328, 328, 233}, + { 0, 180, 180, 140}, + { 0, 132, 132, 105}, + } + } + }; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j+=4) { + tmp[32*i+j+0] = (pix1[j+0] - pix2[j+0])<<4; + tmp[32*i+j+1] = (pix1[j+1] - pix2[j+1])<<4; + tmp[32*i+j+2] = (pix1[j+2] - pix2[j+2])<<4; + tmp[32*i+j+3] = (pix1[j+3] - pix2[j+3])<<4; + } + pix1 += line_size; + pix2 += line_size; + } + + ff_spatial_dwt(tmp, w, h, 32, type, dec_count); + + s=0; + assert(w==h); + for(level=0; level>(dec_count-level); + int sx= (ori&1) ? size : 0; + int stride= 32<<(dec_count-level); + int sy= (ori&2) ? stride>>1 : 0; + + for(i=0; i=0); + return s>>9; +} + +static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 1); +} + +static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 0); +} + +static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 1); +} + +static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 0); +} + +int w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 32, h, 1); +} + +int w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 32, h, 0); +} +#endif + +/* draw the edges of width 'w' of an image of size width, height */ +//FIXME check that this is ok for mpeg4 interlaced +static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w) +{ + uint8_t *ptr, *last_line; + int i; + + last_line = buf + (height - 1) * wrap; + for(i=0;i= h){ + src+= (h-1-src_y)*linesize; + src_y=h-1; + }else if(src_y<=-block_h){ + src+= (1-block_h-src_y)*linesize; + src_y=1-block_h; + } + if(src_x>= w){ + src+= (w-1-src_x); + src_x=w-1; + }else if(src_x<=-block_w){ + src+= (1-block_w-src_x); + src_x=1-block_w; + } + + start_y= FFMAX(0, -src_y); + start_x= FFMAX(0, -src_x); + end_y= FFMIN(block_h, h-src_y); + end_x= FFMIN(block_w, w-src_x); + + // copy existing part + for(y=start_y; y 127) + *pixels = 255; + else + *pixels = (uint8_t)(*block + 128); + block++; + pixels++; + } + pixels += (line_size - 8); + } +} + static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, int line_size) { int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + /* read the pixels */ for(i=0;i<8;i++) { pixels[0] = cm[pixels[0] + block[0]]; @@ -352,6 +669,77 @@ static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, block += 8; } } + +static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels8_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<8;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels[4] += block[4]; + pixels[5] += block[5]; + pixels[6] += block[6]; + pixels[7] += block[7]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels4_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<4;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels += line_size; + block += 4; + } +} + +static int sum_abs_dctelem_c(DCTELEM *block) +{ + int sum=0, i; + for(i=0; i<64; i++) + sum+= FFABS(block[i]); + return sum; +} + #if 0 #define PIXOP2(OPNAME, OP) \ @@ -359,7 +747,7 @@ static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_si {\ int i;\ for(i=0; i>1));\ pixels+=line_size;\ block +=line_size;\ @@ -381,8 +769,8 @@ static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int li {\ int i;\ for(i=0; i>1));\ pixels+=line_size;\ block +=line_size;\ @@ -393,8 +781,8 @@ static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, {\ int i;\ for(i=0; i>1));\ pixels+=line_size;\ block +=line_size;\ @@ -405,8 +793,8 @@ static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int li {\ int i;\ for(i=0; i>1));\ pixels+=line_size;\ block +=line_size;\ @@ -416,8 +804,8 @@ static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int li static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ uint64_t l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0202020202020202ULL;\ @@ -427,8 +815,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l \ pixels+=line_size;\ for(i=0; i>2)\ @@ -436,8 +824,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ pixels+=line_size;\ block +=line_size;\ - a= LD64(pixels );\ - b= LD64(pixels+1);\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0202020202020202ULL;\ @@ -452,8 +840,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ uint64_t l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0101010101010101ULL;\ @@ -463,8 +851,8 @@ static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels \ pixels+=line_size;\ for(i=0; i>2)\ @@ -472,8 +860,8 @@ static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ pixels+=line_size;\ block +=line_size;\ - a= LD64(pixels );\ - b= LD64(pixels+1);\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0101010101010101ULL;\ @@ -500,7 +888,7 @@ CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ int i;\ for(i=0; i>2)\ + ((d&0xFCFCFCFCUL)>>2);\ OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ - c= LD32(&src3[i*src_stride3+4]);\ - d= LD32(&src4[i*src_stride4+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -661,10 +1049,10 @@ static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src int i;\ for(i=0; i>2)\ + ((d&0xFCFCFCFCUL)>>2);\ OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ - c= LD32(&src3[i*src_stride3+4]);\ - d= LD32(&src4[i*src_stride4+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -738,8 +1126,8 @@ static inline void OPNAME ## _pixels2_xy2_c(uint8_t *block, const uint8_t *pixel static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -749,8 +1137,8 @@ static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixel \ pixels+=line_size;\ for(i=0; i>2)\ @@ -758,8 +1146,8 @@ static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixel OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -776,8 +1164,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel int j;\ for(j=0; j<2; j++){\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -787,8 +1175,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel \ pixels+=line_size;\ for(i=0; i>2)\ @@ -796,8 +1184,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -817,8 +1205,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t int j;\ for(j=0; j<2; j++){\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -828,8 +1216,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t \ pixels+=line_size;\ for(i=0; i>2)\ @@ -837,8 +1225,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -874,6 +1262,13 @@ PIXOP2(put, op_put) #define avg2(a,b) ((a+b+1)>>1) #define avg4(a,b,c,d) ((a+b+c+d+2)>>2) +static void put_no_rnd_pixels16_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels16_l2(dst, a, b, stride, stride, stride, h); +} + +static void put_no_rnd_pixels8_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels8_l2(dst, a, b, stride, stride, stride, h); +} static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder) { @@ -898,12 +1293,12 @@ static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y } } -static void gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height) { int y, vx, vy; const int s= 1<>=shift; src_y>>=shift; - + if((unsigned)src_x < width){ if((unsigned)src_y < height){ index= src_x + src_y*stride; @@ -931,23 +1326,23 @@ static void gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + src[index+stride+1]* frac_x )* frac_y + r)>>(shift*2); }else{ - index= src_x + clip(src_y, 0, height)*stride; - dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + index= src_x + av_clip(src_y, 0, height)*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + src[index +1]* frac_x )*s + r)>>(shift*2); } }else{ if((unsigned)src_y < height){ - index= clip(src_x, 0, width) + src_y*stride; - dst[y*stride + x]= ( ( src[index ]*(s-frac_y) + index= av_clip(src_x, 0, width) + src_y*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_y) + src[index+stride ]* frac_y )*s + r)>>(shift*2); }else{ - index= clip(src_x, 0, width) + clip(src_y, 0, height)*stride; + index= av_clip(src_x, 0, width) + av_clip(src_y, 0, height)*stride; dst[y*stride + x]= src[index ]; } } - + vx+= dxx; vy+= dyx; } @@ -969,7 +1364,7 @@ static inline void put_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (683*(2*src[j] + src[j+1] + 1)) >> 11; + dst[j] = (683*(2*src[j] + src[j+1] + 1)) >> 11; } src += stride; dst += stride; @@ -980,29 +1375,29 @@ static inline void put_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (683*(src[j] + 2*src[j+1] + 1)) >> 11; + dst[j] = (683*(src[j] + 2*src[j+1] + 1)) >> 11; } src += stride; dst += stride; } } - + static inline void put_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (683*(2*src[j] + src[j+stride] + 1)) >> 11; + dst[j] = (683*(2*src[j] + src[j+stride] + 1)) >> 11; } src += stride; dst += stride; } } - + static inline void put_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15; + dst[j] = (2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15; } src += stride; dst += stride; @@ -1013,7 +1408,7 @@ static inline void put_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + dst[j] = (2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; } src += stride; dst += stride; @@ -1024,7 +1419,7 @@ static inline void put_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (683*(src[j] + 2*src[j+stride] + 1)) >> 11; + dst[j] = (683*(src[j] + 2*src[j+stride] + 1)) >> 11; } src += stride; dst += stride; @@ -1035,7 +1430,7 @@ static inline void put_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + dst[j] = (2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; } src += stride; dst += stride; @@ -1046,7 +1441,7 @@ static inline void put_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15; + dst[j] = (2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15; } src += stride; dst += stride; @@ -1066,7 +1461,7 @@ static inline void avg_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(2*src[j] + src[j+1] + 1)) >> 11) + 1) >> 1; + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+1] + 1)) >> 11) + 1) >> 1; } src += stride; dst += stride; @@ -1077,29 +1472,29 @@ static inline void avg_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+1] + 1)) >> 11) + 1) >> 1; + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+1] + 1)) >> 11) + 1) >> 1; } src += stride; dst += stride; } } - + static inline void avg_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(2*src[j] + src[j+stride] + 1)) >> 11) + 1) >> 1; + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+stride] + 1)) >> 11) + 1) >> 1; } src += stride; dst += stride; } } - + static inline void avg_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + dst[j] = (dst[j] + ((2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15) + 1) >> 1; } src += stride; dst += stride; @@ -1110,7 +1505,7 @@ static inline void avg_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + dst[j] = (dst[j] + ((2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; } src += stride; dst += stride; @@ -1121,7 +1516,7 @@ static inline void avg_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+stride] + 1)) >> 11) + 1) >> 1; + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+stride] + 1)) >> 11) + 1) >> 1; } src += stride; dst += stride; @@ -1132,7 +1527,7 @@ static inline void avg_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + dst[j] = (dst[j] + ((2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; } src += stride; dst += stride; @@ -1143,7 +1538,7 @@ static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int int i,j; for (i=0; i < height; i++) { for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + dst[j] = (dst[j] + ((2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15) + 1) >> 1; } src += stride; dst += stride; @@ -1181,12 +1576,22 @@ static void OPNAME ## h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*a \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ - for(i=0; i=0 && y>=0);\ \ - for(i=0; i=0 && y>=0);\ \ - for(i=0; i=0 && y>=0); + for(i=0; i> 6; + dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6; + dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6; + dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6; + dst[4] = (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + 32 - 4) >> 6; + dst[5] = (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + 32 - 4) >> 6; + dst[6] = (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + 32 - 4) >> 6; + dst[7] = (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + 32 - 4) >> 6; + dst+= stride; + src+= stride; } } -static inline void copy_block8(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) -{ - int i; - for(i=0; i> log2_denom ) +#define op_scale2(x) dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1)) +#define H264_WEIGHT(W,H) \ +static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \ + int y; \ + offset <<= log2_denom; \ + if(log2_denom) offset += 1<<(log2_denom-1); \ + for(y=0; y>4]; dst[7]= cm[(9*(src[7] + src[8]) - (src[ 6] + src[9]) + 8)>>4]; dst+=dstStride; - src+=srcStride; + src+=srcStride; } } +#ifdef CONFIG_CAVS_DECODER +/* AVS specific */ +void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx); + +void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + put_pixels8_c(dst, src, stride, 8); +} +void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + avg_pixels8_c(dst, src, stride, 8); +} +void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + put_pixels16_c(dst, src, stride, 16); +} +void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { + avg_pixels16_c(dst, src, stride, 16); +} +#endif /* CONFIG_CAVS_DECODER */ + +#if defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) +/* VC-1 specific */ +void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); + +void ff_put_vc1_mspel_mc00_c(uint8_t *dst, uint8_t *src, int stride, int rnd) { + put_pixels8_c(dst, src, stride, 8); +} +#endif /* CONFIG_VC1_DECODER||CONFIG_WMV3_DECODER */ + +void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); + +/* H264 specific */ +void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx); + static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ - uint8_t *cm = cropTbl + MAX_NEG_CROP; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i; for(i=0; i>31); if(p2&256) p2= ~(p2>>31); - + src[x-1*stride] = p1; src[x+0*stride] = p2; - ad1= ABS(d1)>>1; - - d2= clip((p0-p3)/4, -ad1, ad1); - + ad1= FFABS(d1)>>1; + + d2= av_clip((p0-p3)/4, -ad1, ad1); + src[x-2*stride] = p0 - d2; src[x+ stride] = p3 + d2; } + } } static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ + if(ENABLE_ANY_H263) { int y; const int strength= ff_h263_loop_filter_strength[qscale]; - + for(y=0; y<8; y++){ int d1, d2, ad1; int p0= src[y*stride-2]; @@ -2314,22 +2872,164 @@ static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ else if(d< strength) d1= d; else if(d< 2*strength) d1= 2*strength - d; else d1= 0; - + p1 += d1; p2 -= d1; if(p1&256) p1= ~(p1>>31); if(p2&256) p2= ~(p2>>31); - + src[y*stride-1] = p1; src[y*stride+0] = p2; - ad1= ABS(d1)>>1; - - d2= clip((p0-p3)/4, -ad1, ad1); - + ad1= FFABS(d1)>>1; + + d2= av_clip((p0-p3)/4, -ad1, ad1); + src[y*stride-2] = p0 - d2; src[y*stride+1] = p3 + d2; } + } +} + +static void h261_loop_filter_c(uint8_t *src, int stride){ + int x,y,xy,yz; + int temp[64]; + + for(x=0; x<8; x++){ + temp[x ] = 4*src[x ]; + temp[x + 7*8] = 4*src[x + 7*stride]; + } + for(y=1; y<7; y++){ + for(x=0; x<8; x++){ + xy = y * stride + x; + yz = y * 8 + x; + temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride]; + } + } + + for(y=0; y<8; y++){ + src[ y*stride] = (temp[ y*8] + 2)>>2; + src[7+y*stride] = (temp[7+y*8] + 2)>>2; + for(x=1; x<7; x++){ + xy = y * stride + x; + yz = y * 8 + x; + src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4; + } + } +} + +static inline void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + if( tc0[i] < 0 ) { + pix += 4*ystride; + continue; + } + for( d = 0; d < 4; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int p2 = pix[-3*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + const int q2 = pix[2*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + int tc = tc0[i]; + int i_delta; + + if( FFABS( p2 - p0 ) < beta ) { + pix[-2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] ); + tc++; + } + if( FFABS( q2 - q0 ) < beta ) { + pix[ xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] ); + tc++; + } + + i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + pix[-xstride] = av_clip_uint8( p0 + i_delta ); /* p0' */ + pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + const int tc = tc0[i]; + if( tc <= 0 ) { + pix += 2*ystride; + continue; + } + for( d = 0; d < 2; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + int delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + + pix[-xstride] = av_clip_uint8( p0 + delta ); /* p0' */ + pix[0] = av_clip_uint8( q0 - delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_chroma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) +{ + int d; + for( d = 0; d < 8; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( FFABS( p0 - q0 ) < alpha && + FFABS( p1 - p0 ) < beta && + FFABS( q1 - q0 ) < beta ) { + + pix[-xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ + } + pix += ystride; + } +} +static void h264_v_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, stride, 1, alpha, beta); +} +static void h264_h_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, 1, stride, alpha, beta); } static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) @@ -2532,28 +3232,103 @@ static int pix_abs8_xy2_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, return s; } +static int nsse16_c(void *v, uint8_t *s1, uint8_t *s2, int stride, int h){ + MpegEncContext *c = v; + int score1=0; + int score2=0; + int x,y; + + for(y=0; yavctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int nsse8_c(void *v, uint8_t *s1, uint8_t *s2, int stride, int h){ + MpegEncContext *c = v; + int score1=0; + int score2=0; + int x,y; + + for(y=0; yavctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale){ + int i; + unsigned int sum=0; + + for(i=0; i<8*8; i++){ + int b= rem[i] + ((basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT)); + int w= weight[i]; + b>>= RECON_SHIFT; + assert(-512>4; + } + return sum>>2; +} + +static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){ + int i; + + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } +} + /** * permutes an 8x8 block. * @param block the block which will be permuted according to the given permutation vector * @param permutation the permutation vector * @param last the last non zero coefficient in scantable order, used to speed the permutation up - * @param scantable the used scantable, this is only used to speed the permutation up, the block is not + * @param scantable the used scantable, this is only used to speed the permutation up, the block is not * (inverse) permutated to scantable order! */ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last) { int i; DCTELEM temp[64]; - + if(last<=0) return; - //if(permutation[1]==1) return; //FIXME its ok but not clean and might fail for some perms + //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations for(i=0; i<=last; i++){ const int j= scantable[i]; temp[j]= block[j]; block[j]=0; } - + for(i=0; i<=last; i++){ const int j= scantable[i]; const int perm_j= permutation[j]; @@ -2567,9 +3342,9 @@ static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ int i; - + memset(cmp, 0, sizeof(void*)*5); - + for(i=0; i<5; i++){ switch(type&0xFF){ case FF_CMP_SAD: @@ -2584,6 +3359,12 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ case FF_CMP_DCT: cmp[i]= c->dct_sad[i]; break; + case FF_CMP_DCT264: + cmp[i]= c->dct264_sad[i]; + break; + case FF_CMP_DCTMAX: + cmp[i]= c->dct_max[i]; + break; case FF_CMP_PSNR: cmp[i]= c->quant_psnr[i]; break; @@ -2602,6 +3383,17 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ case FF_CMP_ZERO: cmp[i]= zero_cmp; break; + case FF_CMP_NSSE: + cmp[i]= c->nsse[i]; + break; +#ifdef CONFIG_SNOW_ENCODER + case FF_CMP_W53: + cmp[i]= c->w53[i]; + break; + case FF_CMP_W97: + cmp[i]= c->w97[i]; + break; +#endif default: av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n"); } @@ -2617,32 +3409,47 @@ static void clear_blocks_c(DCTELEM *blocks) } static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ - int i; - for(i=0; i+7dsp.diff_pixels(temp, src1, src2, stride); + s->dsp.fdct(temp); + return s->dsp.sum_abs_dctelem(temp); +} + +#ifdef CONFIG_GPL +#define DCT8_1D {\ + const int s07 = SRC(0) + SRC(7);\ + const int s16 = SRC(1) + SRC(6);\ + const int s25 = SRC(2) + SRC(5);\ + const int s34 = SRC(3) + SRC(4);\ + const int a0 = s07 + s34;\ + const int a1 = s16 + s25;\ + const int a2 = s07 - s34;\ + const int a3 = s16 - s25;\ + const int d07 = SRC(0) - SRC(7);\ + const int d16 = SRC(1) - SRC(6);\ + const int d25 = SRC(2) - SRC(5);\ + const int d34 = SRC(3) - SRC(4);\ + const int a4 = d16 + d25 + (d07 + (d07>>1));\ + const int a5 = d07 - d34 - (d25 + (d25>>1));\ + const int a6 = d07 + d34 - (d16 + (d16>>1));\ + const int a7 = d16 - d25 + (d34 + (d34>>1));\ + DST(0, a0 + a1 ) ;\ + DST(1, a4 + (a7>>2)) ;\ + DST(2, a2 + (a3>>1)) ;\ + DST(3, a5 + (a6>>2)) ;\ + DST(4, a0 - a1 ) ;\ + DST(5, a6 - (a5>>2)) ;\ + DST(6, (a2>>1) - a3 ) ;\ + DST(7, (a4>>2) - a7 ) ;\ +} + +static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DCTELEM dct[8][8]; + int i; + int sum=0; + + s->dsp.diff_pixels(dct[0], src1, src2, stride); + +#define SRC(x) dct[i][x] +#define DST(x,v) dct[i][x]= v + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + +#define SRC(x) dct[x][i] +#define DST(x,v) sum += FFABS(v) + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + return sum; +} +#endif + +static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); DCTELEM * const temp= (DCTELEM*)aligned_temp; int sum=0, i; - + assert(h==8); s->dsp.diff_pixels(temp, src1, src2, stride); s->dsp.fdct(temp); for(i=0; i<64; i++) - sum+= ABS(temp[i]); - + sum= FFMAX(sum, FFABS(temp[i])); + return sum; } -void simple_idct(DCTELEM *block); //FIXME - static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ MpegEncContext * const s= (MpegEncContext *)c; - uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64*2/8]; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64*2/8]); DCTELEM * const temp= (DCTELEM*)aligned_temp; DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64; int sum=0, i; assert(h==8); s->mb_intra=0; - + s->dsp.diff_pixels(temp, src1, src2, stride); - + memcpy(bak, temp, 64*sizeof(DCTELEM)); - + s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); s->dct_unquantize_inter(s, temp, 0, s->qscale); - simple_idct(temp); //FIXME - + ff_simple_idct(temp); //FIXME + for(i=0; i<64; i++) sum+= (temp[i]-bak[i])*(temp[i]-bak[i]); - + return sum; } static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ MpegEncContext * const s= (MpegEncContext *)c; const uint8_t *scantable= s->intra_scantable.permutated; - uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8]; - uint64_t __align8 aligned_bak[stride]; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DECLARE_ALIGNED_8 (uint64_t, aligned_bak[stride]); DCTELEM * const temp= (DCTELEM*)aligned_temp; uint8_t * const bak= (uint8_t*)aligned_bak; - int i, last, run, bits, level, distoration, start_i; + int i, last, run, bits, level, distortion, start_i; const int esc_length= s->ac_esc_length; uint8_t * length; uint8_t * last_length; - + assert(h==8); for(i=0; i<8; i++){ @@ -2848,9 +3718,9 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); bits=0; - + if (s->mb_intra) { - start_i = 1; + start_i = 1; length = s->intra_ac_vlc_length; last_length= s->intra_ac_vlc_last_length; bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma @@ -2859,13 +3729,13 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int length = s->inter_ac_vlc_length; last_length= s->inter_ac_vlc_last_length; } - + if(last>=start_i){ run=0; for(i=start_i; i=0){ @@ -2895,18 +3765,18 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int else s->dct_unquantize_inter(s, temp, 0, s->qscale); } - - s->dsp.idct_add(bak, stride, temp); - - distoration= s->dsp.sse[1](NULL, bak, src1, stride, 8); - return distoration + ((bits*s->qscale*s->qscale*109 + 64)>>7); + s->dsp.idct_add(bak, stride, temp); + + distortion= s->dsp.sse[1](NULL, bak, src1, stride, 8); + + return distortion + ((bits*s->qscale*s->qscale*109 + 64)>>7); } static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ MpegEncContext * const s= (MpegEncContext *)c; const uint8_t *scantable= s->intra_scantable.permutated; - uint64_t __align8 aligned_temp[sizeof(DCTELEM)*64/8]; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); DCTELEM * const temp= (DCTELEM*)aligned_temp; int i, last, run, bits, level, start_i; const int esc_length= s->ac_esc_length; @@ -2914,15 +3784,15 @@ static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, in uint8_t * last_length; assert(h==8); - + s->dsp.diff_pixels(temp, src1, src2, stride); s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); bits=0; - + if (s->mb_intra) { - start_i = 1; + start_i = 1; length = s->intra_ac_vlc_length; last_length= s->intra_ac_vlc_last_length; bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma @@ -2931,13 +3801,13 @@ static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, in length = s->inter_ac_vlc_length; last_length= s->inter_ac_vlc_last_length; } - + if(last>=start_i){ run=0; for(i=start_i; i>31; + // is this faster on some gcc/cpu combinations? +// if(tmp > 0x43c0ffff) tmp = 0xFFFF; +// else tmp = 0; + } + return tmp - 0x8000; +} + +void ff_float_to_int16_c(int16_t *dst, const float *src, long len){ + int i; + for(i=0; i> shift; + + return res; +} + +#define W0 2048 +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +static void wmv2_idct_row(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1*/ + a1 = W1*b[1]+W7*b[7]; + a7 = W7*b[1]-W1*b[7]; + a5 = W5*b[5]+W3*b[3]; + a3 = W3*b[5]-W5*b[3]; + a2 = W2*b[2]+W6*b[6]; + a6 = W6*b[2]-W2*b[6]; + a0 = W0*b[0]+W0*b[4]; + a4 = W0*b[0]-W0*b[4]; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7, + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[0] = (a0+a2+a1+a5 + (1<<7))>>8; + b[1] = (a4+a6 +s1 + (1<<7))>>8; + b[2] = (a4-a6 +s2 + (1<<7))>>8; + b[3] = (a0-a2+a7+a3 + (1<<7))>>8; + b[4] = (a0-a2-a7-a3 + (1<<7))>>8; + b[5] = (a4-a6 -s2 + (1<<7))>>8; + b[6] = (a4+a6 -s1 + (1<<7))>>8; + b[7] = (a0+a2-a1-a5 + (1<<7))>>8; +} +static void wmv2_idct_col(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1, with extended precision*/ + a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3; + a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3; + a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3; + a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3; + a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3; + a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3; + a0 = (W0*b[8*0]+W0*b[8*4] )>>3; + a4 = (W0*b[8*0]-W0*b[8*4] )>>3; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8; + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14; + b[8*1] = (a4+a6 +s1 + (1<<13))>>14; + b[8*2] = (a4-a6 +s2 + (1<<13))>>14; + b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14; + + b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14; + b[8*5] = (a4-a6 -s2 + (1<<13))>>14; + b[8*6] = (a4+a6 -s1 + (1<<13))>>14; + b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14; +} +void ff_wmv2_idct_c(short * block){ + int i; + + for(i=0;i<64;i+=8){ + wmv2_idct_row(block+i); + } + for(i=0;i<8;i++){ + wmv2_idct_col(block+i); + } +} /* XXX: those functions should be suppressed ASAP when all IDCTs are converted */ +static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + put_pixels_clamped_c(block, dest, line_size); +} +static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + add_pixels_clamped_c(block, dest, line_size); +} static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) { j_rev_dct (block); @@ -3044,62 +4102,169 @@ static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) add_pixels_clamped_c(block, dest, line_size); } +static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct4 (block); + put_pixels_clamped4_c(block, dest, line_size); +} +static void ff_jref_idct4_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct4 (block); + add_pixels_clamped4_c(block, dest, line_size); +} + +static void ff_jref_idct2_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct2 (block); + put_pixels_clamped2_c(block, dest, line_size); +} +static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct2 (block); + add_pixels_clamped2_c(block, dest, line_size); +} + +static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + dest[0] = cm[(block[0] + 4)>>3]; +} +static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + + dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; +} + +static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } + /* init static data */ void dsputil_static_init(void) { int i; - for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i; for(i=0;i= 4.2.\n" + "Do not report crashes to FFmpeg developers.\n"); +#endif + did_fail=1; + } + return -1; + } + return 0; +} void dsputil_init(DSPContext* c, AVCodecContext *avctx) { int i; + ff_check_alignment(); + #ifdef CONFIG_ENCODERS if(avctx->dct_algo==FF_DCT_FASTINT) { c->fdct = fdct_ifast; - c->fdct248 = fdct_ifast248; - } + c->fdct248 = fdct_ifast248; + } else if(avctx->dct_algo==FF_DCT_FAAN) { c->fdct = ff_faandct; - c->fdct248 = ff_faandct248; - } + c->fdct248 = ff_faandct248; + } else { c->fdct = ff_jpeg_fdct_islow; //slow/accurate/default - c->fdct248 = ff_fdct248_islow; + c->fdct248 = ff_fdct248_islow; } #endif //CONFIG_ENCODERS - if(avctx->idct_algo==FF_IDCT_INT){ - c->idct_put= ff_jref_idct_put; - c->idct_add= ff_jref_idct_add; - c->idct = j_rev_dct; - c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; - }else{ //accurate/default - c->idct_put= simple_idct_put; - c->idct_add= simple_idct_add; - c->idct = simple_idct; + if(avctx->lowres==1){ + if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO || !ENABLE_H264_DECODER){ + c->idct_put= ff_jref_idct4_put; + c->idct_add= ff_jref_idct4_add; + }else{ + c->idct_put= ff_h264_lowres_idct_put_c; + c->idct_add= ff_h264_lowres_idct_add_c; + } + c->idct = j_rev_dct4; c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==2){ + c->idct_put= ff_jref_idct2_put; + c->idct_add= ff_jref_idct2_add; + c->idct = j_rev_dct2; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==3){ + c->idct_put= ff_jref_idct1_put; + c->idct_add= ff_jref_idct1_add; + c->idct = j_rev_dct1; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ + if(avctx->idct_algo==FF_IDCT_INT){ + c->idct_put= ff_jref_idct_put; + c->idct_add= ff_jref_idct_add; + c->idct = j_rev_dct; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; + }else if((ENABLE_VP3_DECODER || ENABLE_VP5_DECODER || ENABLE_VP6_DECODER || ENABLE_THEORA_DECODER ) && + avctx->idct_algo==FF_IDCT_VP3){ + c->idct_put= ff_vp3_idct_put_c; + c->idct_add= ff_vp3_idct_add_c; + c->idct = ff_vp3_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_WMV2){ + c->idct_put= ff_wmv2_idct_put_c; + c->idct_add= ff_wmv2_idct_add_c; + c->idct = ff_wmv2_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_FAAN){ + c->idct_put= ff_faanidct_put; + c->idct_add= ff_faanidct_add; + c->idct = ff_faanidct; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ //accurate/default + c->idct_put= ff_simple_idct_put; + c->idct_add= ff_simple_idct_add; + c->idct = ff_simple_idct; + c->idct_permutation_type= FF_NO_IDCT_PERM; + } + } + + if (ENABLE_H264_DECODER) { + c->h264_idct_add= ff_h264_idct_add_c; + c->h264_idct8_add= ff_h264_idct8_add_c; + c->h264_idct_dc_add= ff_h264_idct_dc_add_c; + c->h264_idct8_dc_add= ff_h264_idct8_dc_add_c; } c->get_pixels = get_pixels_c; c->diff_pixels = diff_pixels_c; c->put_pixels_clamped = put_pixels_clamped_c; + c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; c->add_pixels_clamped = add_pixels_clamped_c; + c->add_pixels8 = add_pixels8_c; + c->add_pixels4 = add_pixels4_c; + c->sum_abs_dctelem = sum_abs_dctelem_c; c->gmc1 = gmc1_c; - c->gmc = gmc_c; + c->gmc = ff_gmc_c; c->clear_blocks = clear_blocks_c; c->pix_sum = pix_sum_c; c->pix_norm1 = pix_norm1_c; @@ -3135,6 +4300,9 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) dspfunc(avg, 3, 2); #undef dspfunc + c->put_no_rnd_pixels_l2[0]= put_no_rnd_pixels16_l2_c; + c->put_no_rnd_pixels_l2[1]= put_no_rnd_pixels8_l2_c; + c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c; c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c; c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c; @@ -3188,6 +4356,7 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) dspfunc(put_h264_qpel, 0, 16); dspfunc(put_h264_qpel, 1, 8); dspfunc(put_h264_qpel, 2, 4); + dspfunc(put_h264_qpel, 3, 2); dspfunc(avg_h264_qpel, 0, 16); dspfunc(avg_h264_qpel, 1, 8); dspfunc(avg_h264_qpel, 2, 4); @@ -3199,6 +4368,43 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_c; c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_c; c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_c; + c->put_no_rnd_h264_chroma_pixels_tab[0]= put_no_rnd_h264_chroma_mc8_c; + + c->weight_h264_pixels_tab[0]= weight_h264_pixels16x16_c; + c->weight_h264_pixels_tab[1]= weight_h264_pixels16x8_c; + c->weight_h264_pixels_tab[2]= weight_h264_pixels8x16_c; + c->weight_h264_pixels_tab[3]= weight_h264_pixels8x8_c; + c->weight_h264_pixels_tab[4]= weight_h264_pixels8x4_c; + c->weight_h264_pixels_tab[5]= weight_h264_pixels4x8_c; + c->weight_h264_pixels_tab[6]= weight_h264_pixels4x4_c; + c->weight_h264_pixels_tab[7]= weight_h264_pixels4x2_c; + c->weight_h264_pixels_tab[8]= weight_h264_pixels2x4_c; + c->weight_h264_pixels_tab[9]= weight_h264_pixels2x2_c; + c->biweight_h264_pixels_tab[0]= biweight_h264_pixels16x16_c; + c->biweight_h264_pixels_tab[1]= biweight_h264_pixels16x8_c; + c->biweight_h264_pixels_tab[2]= biweight_h264_pixels8x16_c; + c->biweight_h264_pixels_tab[3]= biweight_h264_pixels8x8_c; + c->biweight_h264_pixels_tab[4]= biweight_h264_pixels8x4_c; + c->biweight_h264_pixels_tab[5]= biweight_h264_pixels4x8_c; + c->biweight_h264_pixels_tab[6]= biweight_h264_pixels4x4_c; + c->biweight_h264_pixels_tab[7]= biweight_h264_pixels4x2_c; + c->biweight_h264_pixels_tab[8]= biweight_h264_pixels2x4_c; + c->biweight_h264_pixels_tab[9]= biweight_h264_pixels2x2_c; + + c->draw_edges = draw_edges_c; + +#ifdef CONFIG_CAVS_DECODER + ff_cavsdsp_init(c,avctx); +#endif +#if defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) + ff_vc1dsp_init(c,avctx); +#endif +#if defined(CONFIG_WMV2_DECODER) || defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) + ff_intrax8dsp_init(c,avctx); +#endif +#if defined(CONFIG_H264_ENCODER) + ff_h264dspenc_init(c,avctx); +#endif c->put_mspel_pixels_tab[0]= put_mspel8_mc00_c; c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c; @@ -3208,18 +4414,23 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c; c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; - + #define SET_CMP_FUNC(name) \ c->name[0]= name ## 16_c;\ c->name[1]= name ## 8x8_c; - + SET_CMP_FUNC(hadamard8_diff) c->hadamard8_diff[4]= hadamard8_intra16_c; SET_CMP_FUNC(dct_sad) + SET_CMP_FUNC(dct_max) +#ifdef CONFIG_GPL + SET_CMP_FUNC(dct264_sad) +#endif c->sad[0]= pix_abs16_c; c->sad[1]= pix_abs8_c; c->sse[0]= sse16_c; c->sse[1]= sse8_c; + c->sse[2]= sse4_c; SET_CMP_FUNC(quant_psnr) SET_CMP_FUNC(rd) SET_CMP_FUNC(bit) @@ -3227,36 +4438,96 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->vsad[4]= vsad_intra16_c; c->vsse[0]= vsse16_c; c->vsse[4]= vsse_intra16_c; - + c->nsse[0]= nsse16_c; + c->nsse[1]= nsse8_c; +#ifdef CONFIG_SNOW_ENCODER + c->w53[0]= w53_16_c; + c->w53[1]= w53_8_c; + c->w97[0]= w97_16_c; + c->w97[1]= w97_8_c; +#endif + + c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; + c->add_bytes= add_bytes_c; + c->add_bytes_l2= add_bytes_l2_c; c->diff_bytes= diff_bytes_c; c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; c->bswap_buf= bswap_buf; - - c->h263_h_loop_filter= h263_h_loop_filter_c; - c->h263_v_loop_filter= h263_v_loop_filter_c; +#ifdef CONFIG_PNG_DECODER + c->add_png_paeth_prediction= ff_add_png_paeth_prediction; +#endif -#ifdef HAVE_MMX - dsputil_init_mmx(c, avctx); + c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; + c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; + c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_c; + c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_c; + c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_c; + c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_c; + c->h264_loop_filter_strength= NULL; + + if (ENABLE_ANY_H263) { + c->h263_h_loop_filter= h263_h_loop_filter_c; + c->h263_v_loop_filter= h263_v_loop_filter_c; + } + + c->h261_loop_filter= h261_loop_filter_c; + + c->try_8x8basis= try_8x8basis_c; + c->add_8x8basis= add_8x8basis_c; + +#ifdef CONFIG_SNOW_DECODER + c->vertical_compose97i = ff_snow_vertical_compose97i; + c->horizontal_compose97i = ff_snow_horizontal_compose97i; + c->inner_add_yblock = ff_snow_inner_add_yblock; #endif -#ifdef ARCH_ARMV4L - dsputil_init_armv4l(c, avctx); + +#ifdef CONFIG_VORBIS_DECODER + c->vorbis_inverse_coupling = vorbis_inverse_coupling; #endif -#ifdef HAVE_MLIB - dsputil_init_mlib(c, avctx); +#ifdef CONFIG_AC3_DECODER + c->ac3_downmix = ff_ac3_downmix_c; #endif -#ifdef ARCH_ALPHA - dsputil_init_alpha(c, avctx); -#endif -#ifdef ARCH_POWERPC - dsputil_init_ppc(c, avctx); -#endif -#ifdef HAVE_MMI - dsputil_init_mmi(c, avctx); -#endif -#ifdef ARCH_SH4 - dsputil_init_sh4(c,avctx); +#ifdef CONFIG_FLAC_ENCODER + c->flac_compute_autocorr = ff_flac_compute_autocorr; #endif + c->vector_fmul = vector_fmul_c; + c->vector_fmul_reverse = vector_fmul_reverse_c; + c->vector_fmul_add_add = ff_vector_fmul_add_add_c; + c->vector_fmul_window = ff_vector_fmul_window_c; + c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c; + c->float_to_int16 = ff_float_to_int16_c; + c->float_to_int16_interleave = ff_float_to_int16_interleave_c; + c->add_int16 = add_int16_c; + c->sub_int16 = sub_int16_c; + c->scalarproduct_int16 = scalarproduct_int16_c; + + c->shrink[0]= ff_img_copy_plane; + c->shrink[1]= ff_shrink22; + c->shrink[2]= ff_shrink44; + c->shrink[3]= ff_shrink88; + + c->prefetch= just_return; + + memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab)); + memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab)); + + if (ENABLE_MMX) dsputil_init_mmx (c, avctx); + if (ENABLE_ARMV4L) dsputil_init_armv4l(c, avctx); + if (ENABLE_MLIB) dsputil_init_mlib (c, avctx); + if (ENABLE_VIS) dsputil_init_vis (c, avctx); + if (ENABLE_ALPHA) dsputil_init_alpha (c, avctx); + if (ENABLE_POWERPC) dsputil_init_ppc (c, avctx); + if (ENABLE_MMI) dsputil_init_mmi (c, avctx); + if (ENABLE_SH4) dsputil_init_sh4 (c, avctx); + if (ENABLE_BFIN) dsputil_init_bfin (c, avctx); + + for(i=0; i<64; i++){ + if(!c->put_2tap_qpel_pixels_tab[0][i]) + c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; + if(!c->avg_2tap_qpel_pixels_tab[0][i]) + c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; + } switch(c->idct_permutation_type){ case FF_NO_IDCT_PERM: @@ -3275,6 +4546,14 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) for(i=0; i<64; i++) c->idct_permutation[i]= ((i&7)<<3) | (i>>3); break; + case FF_PARTTRANS_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3); + break; + case FF_SSE2_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i&0x38) | idct_sse2_row_perm[i&7]; + break; default: av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n"); } diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.h b/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.h index fbe2c684e1..4b7e8ed4a4 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.h +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dsputil.h @@ -3,19 +3,21 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * - * This library is free software; you can redistribute it and/or + * 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -25,16 +27,17 @@ * absolutely necessary to call emms_c() between dsp & float/double code */ -#ifndef DSPUTIL_H -#define DSPUTIL_H +#ifndef FFMPEG_DSPUTIL_H +#define FFMPEG_DSPUTIL_H -#include "common.h" #include "avcodec.h" //#define DEBUG /* dct code */ typedef short DCTELEM; +typedef int DWTELEM; +typedef short IDWTELEM; void fdct_ifast (DCTELEM *data); void fdct_ifast248 (DCTELEM *data); @@ -42,11 +45,29 @@ void ff_jpeg_fdct_islow (DCTELEM *data); void ff_fdct248_islow (DCTELEM *data); void j_rev_dct (DCTELEM *data); +void j_rev_dct4 (DCTELEM *data); +void j_rev_dct2 (DCTELEM *data); +void j_rev_dct1 (DCTELEM *data); +void ff_wmv2_idct_c(DCTELEM *data); void ff_fdct_mmx(DCTELEM *block); void ff_fdct_mmx2(DCTELEM *block); void ff_fdct_sse2(DCTELEM *block); +void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); +void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); + +void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, + const float *src2, int src3, int blocksize, int step); +void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1, + const float *win, float add_bias, int len); +void ff_float_to_int16_c(int16_t *dst, const float *src, long len); +void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels); + /* encoding scans */ extern const uint8_t ff_alternate_horizontal_scan[64]; extern const uint8_t ff_alternate_vertical_scan[64]; @@ -54,19 +75,35 @@ extern const uint8_t ff_zigzag_direct[64]; extern const uint8_t ff_zigzag248_direct[64]; /* pixel operations */ -#define MAX_NEG_CROP 384 +#define MAX_NEG_CROP 1024 /* temporary */ -extern uint32_t squareTbl[512]; -extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; +extern uint32_t ff_squareTbl[512]; +extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP]; +/* VP3 DSP functions */ +void ff_vp3_idct_c(DCTELEM *block/* align 16*/); +void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); +void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + +/* 1/2^n downscaling functions from imgconvert.c */ +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); /* minimum alignment rules ;) -if u notice errors in the align stuff, need more alignment for some asm code for some cpu -or need to use a function with less aligned data then send a mail to the ffmpeg-dev list, ... +If you notice errors in the align stuff, need more alignment for some ASM code +for some CPU or need to use a function with less aligned data then send a mail +to the ffmpeg-devel mailing list, ... -!warning these alignments might not match reallity, (missing attribute((align)) stuff somewhere possible) -i (michael) didnt check them, these are just the alignents which i think could be reached easily ... +!warning These alignments might not match reality, (missing attribute((align)) +stuff somewhere possible). +I (Michael) did not check them, these are just the alignments which I think +could be reached easily ... !future video codecs might need functions with less strict alignment */ @@ -86,6 +123,8 @@ typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const ui typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset); +typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset); #define DEF_OLD_QPEL(name)\ void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ @@ -113,10 +152,32 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ /* motion estimation */ // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 -// allthough currently h<4 is not used as functions with width <8 are not used and neither implemented +// although currently h<4 is not used as functions with width <8 are neither used nor implemented typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; +// for snow slices +typedef struct slice_buffer_s slice_buffer; + +/** + * Scantable. + */ +typedef struct ScanTable{ + const uint8_t *scantable; + uint8_t permutated[64]; + uint8_t raster_end[64]; +#ifdef ARCH_POWERPC + /** Used by dct_quantize_altivec to find last-non-zero */ + DECLARE_ALIGNED(16, uint8_t, inverse[64]); +#endif +} ScanTable; + +void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); + +void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, + int block_w, int block_h, + int src_x, int src_y, int w, int h); + /** * DSPContext. */ @@ -125,7 +186,11 @@ typedef struct DSPContext { void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); + void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); + int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); /** * translational global motion compensation. */ @@ -134,12 +199,12 @@ typedef struct DSPContext { * global motion compensation. */ void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); void (*clear_blocks)(DCTELEM *blocks/*align 16*/); int (*pix_sum)(uint8_t * pix, int line_size); int (*pix_norm1)(uint8_t * pix, int line_size); // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 - + me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */ me_cmp_func sse[5]; me_cmp_func hadamard8_diff[5]; @@ -149,16 +214,25 @@ typedef struct DSPContext { me_cmp_func rd[5]; me_cmp_func vsad[5]; me_cmp_func vsse[5]; + me_cmp_func nsse[5]; + me_cmp_func w53[5]; + me_cmp_func w97[5]; + me_cmp_func dct_max[5]; + me_cmp_func dct264_sad[5]; me_cmp_func me_pre_cmp[5]; me_cmp_func me_cmp[5]; me_cmp_func me_sub_cmp[5]; me_cmp_func mb_cmp[5]; me_cmp_func ildct_cmp[5]; //only width 16 used + me_cmp_func frame_skip_cmp[5]; //only width 8 used + + int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, + int size); /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * this is an array[4][4] of motion compensation funcions for 4 + * this is an array[4][4] of motion compensation functions for 4 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored @@ -170,7 +244,7 @@ typedef struct DSPContext { /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * This is an array[4][4] of motion compensation functions for 4 + * This is an array[4][4] of motion compensation functions for 4 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b+1)>>1 @@ -182,7 +256,7 @@ typedef struct DSPContext { /** * Halfpel motion compensation with no rounding (a+b)>>1. - * this is an array[2][4] of motion compensation funcions for 2 + * this is an array[2][4] of motion compensation functions for 2 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored @@ -190,11 +264,11 @@ typedef struct DSPContext { * @param line_size number of bytes in a horizontal line of block * @param h height */ - op_pixels_func put_no_rnd_pixels_tab[2][4]; + op_pixels_func put_no_rnd_pixels_tab[4][4]; /** * Halfpel motion compensation with no rounding (a+b)>>1. - * this is an array[2][4] of motion compensation funcions for 2 + * this is an array[2][4] of motion compensation functions for 2 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b)>>1 @@ -202,11 +276,14 @@ typedef struct DSPContext { * @param line_size number of bytes in a horizontal line of block * @param h height */ - op_pixels_func avg_no_rnd_pixels_tab[2][4]; - + op_pixels_func avg_no_rnd_pixels_tab[4][4]; + + void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); + /** * Thirdpel motion compensation with rounding (a+b+1)>>1. - * this is an array[12] of motion compensation funcions for the 9 thirdpel positions
+ * this is an array[12] of motion compensation functions for the 9 thirdpe + * positions
* *pixels_tab[ xthirdpel + 4*ythirdpel ] * @param block destination where the result is stored * @param pixels source @@ -221,51 +298,107 @@ typedef struct DSPContext { qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; qpel_mc_func put_mspel_pixels_tab[8]; - + /** - * h264 Chram MC + * h264 Chroma MC */ h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; + /* This is really one func used in VC-1 decoding */ + h264_chroma_mc_func put_no_rnd_h264_chroma_pixels_tab[3]; h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; - qpel_mc_func put_h264_qpel_pixels_tab[3][16]; - qpel_mc_func avg_h264_qpel_pixels_tab[3][16]; - + qpel_mc_func put_h264_qpel_pixels_tab[4][16]; + qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; + + qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; + qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; + + h264_weight_func weight_h264_pixels_tab[10]; + h264_biweight_func biweight_h264_pixels_tab[10]; + + /* AVS specific */ + qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; + qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; + void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); + void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); + me_cmp_func pix_abs[2][4]; - + /* huffyuv specific */ void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); + void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); /** * subtract huffyuv's variant of median prediction * note, this might read from src1[-1], src2[-1] */ void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); - void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w); - + /* this might write to dst[w] */ + void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); + + void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0); + /* v/h_loop_filter_luma_intra: align 16 */ + void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); + void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta); + // h264_loop_filter_strength: simd only. the C version is inlined in h264.c + void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], + int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field); + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h261_loop_filter)(uint8_t *src, int stride); + + void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); + + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); + void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len); + /* no alignment needed */ + void (*flac_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); + /* assume len is a multiple of 8, and arrays are 16-byte aligned */ + void (*vector_fmul)(float *dst, const float *src, int len); + void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); + /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ + void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step); + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ + void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len); + /* assume len is a multiple of 8, and arrays are 16-byte aligned */ + void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len); + + /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] + * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ + void (*float_to_int16)(int16_t *dst, const float *src, long len); + void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); + /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); void (*fdct248)(DCTELEM *block/* align 16*/); - + /* IDCT really*/ void (*idct)(DCTELEM *block/* align 16*/); - + /** * block -> idct -> clip to unsigned 8 bit -> dest. * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) - * @param line_size size in bytes of a horizotal line of dest + * @param line_size size in bytes of a horizontal line of dest */ void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - + /** * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. - * @param line_size size in bytes of a horizotal line of dest + * @param line_size size in bytes of a horizontal line of dest */ void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - + /** * idct input permutation. * several optimized IDCTs need a permutated input (relative to the normal order of the reference @@ -284,12 +417,74 @@ typedef struct DSPContext { #define FF_LIBMPEG2_IDCT_PERM 2 #define FF_SIMPLE_IDCT_PERM 3 #define FF_TRANSPOSE_IDCT_PERM 4 +#define FF_PARTTRANS_IDCT_PERM 5 +#define FF_SSE2_IDCT_PERM 6 + int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); + void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); +#define BASIS_SHIFT 16 +#define RECON_SHIFT 6 + + void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); +#define EDGE_WIDTH 16 + + /* h264 functions */ + void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); + void (*h264_dct)(DCTELEM block[4][4]); + + /* snow wavelet */ + void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); + void (*horizontal_compose97i)(IDWTELEM *b, int width); + void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); + + void (*prefetch)(void *mem, int stride, int h); + + void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); + + /* vc1 functions */ + void (*vc1_inv_trans_8x8)(DCTELEM *b); + void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_v_overlap)(uint8_t* src, int stride); + void (*vc1_h_overlap)(uint8_t* src, int stride); + /* put 8x8 block with bicubic interpolation and quarterpel precision + * last argument is actually round value instead of height + */ + op_pixels_func put_vc1_mspel_pixels_tab[16]; + + /* intrax8 functions */ + void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); + void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, + int * range, int * sum, int edges); + + /* ape functions */ + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*add_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Add contents of the second vector to the first one. + * @param len length of vectors, should be multiple of 16 + */ + void (*sub_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len); + /** + * Calculate scalar product of two vectors. + * @param len length of vectors, should be multiple of 16 + * @param shift number of bits to discard from product + */ + int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift); } DSPContext; void dsputil_static_init(void); void dsputil_init(DSPContext* p, AVCodecContext *avctx); +int ff_check_alignment(void); + /** * permute block according to permuatation. * @param last last non zero element in scantable order @@ -298,7 +493,7 @@ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scant void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); -#define BYTE_VEC32(c) ((c)*0x01010101UL) +#define BYTE_VEC32(c) ((c)*0x01010101UL) static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) { @@ -310,6 +505,30 @@ static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); } +static inline int get_penalty_factor(int lambda, int lambda2, int type){ + switch(type&0xFF){ + default: + case FF_CMP_SAD: + return lambda>>FF_LAMBDA_SHIFT; + case FF_CMP_DCT: + return (3*lambda)>>(FF_LAMBDA_SHIFT+1); + case FF_CMP_W53: + return (4*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_W97: + return (2*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_SATD: + case FF_CMP_DCT264: + return (2*lambda)>>FF_LAMBDA_SHIFT; + case FF_CMP_RD: + case FF_CMP_PSNR: + case FF_CMP_SSE: + case FF_CMP_NSSE: + return lambda2>>FF_LAMBDA_SHIFT; + case FF_CMP_BIT: + return 1; + } +} + /** * Empty mmx state. * this must be called between any dsp function and float/double code. @@ -321,6 +540,18 @@ static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) one or more MultiMedia extension */ int mm_support(void); +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); + +#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v) + #if defined(HAVE_MMX) #undef emms_c @@ -330,15 +561,19 @@ int mm_support(void); #define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ #define MM_SSE 0x0008 /* SSE functions */ #define MM_SSE2 0x0010 /* PIV SSE2 functions */ +#define MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ +#define MM_SSE3 0x0040 /* Prescott SSE3 functions */ +#define MM_SSSE3 0x0080 /* Conroe SSSE3 functions */ extern int mm_flags; void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); static inline void emms(void) { - __asm __volatile ("emms;":::"memory"); + asm volatile ("emms;":::"memory"); } @@ -348,31 +583,18 @@ static inline void emms(void) emms();\ } -#define __align8 __attribute__ ((aligned (8))) - -void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); #elif defined(ARCH_ARMV4L) -/* This is to use 4 bytes read to the IDCT pointers for some 'zero' - line ptimizations */ -#define __align8 __attribute__ ((aligned (4))) +#define MM_IWMMXT 0x0100 /* XScale IWMMXT */ -void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); +extern int mm_flags; -#elif defined(HAVE_MLIB) - -/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ -#define __align8 __attribute__ ((aligned (8))) - -void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); - -#elif defined(ARCH_ALPHA) - -#define __align8 __attribute__ ((aligned (8))) - -void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); +#ifdef HAVE_NEON +# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +# define STRIDE_ALIGN 16 +#endif #elif defined(ARCH_POWERPC) @@ -380,55 +602,28 @@ void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); extern int mm_flags; -#if defined(HAVE_ALTIVEC) && !defined(CONFIG_DARWIN) -#define pixel altivec_pixel -#include -#undef pixel -#endif - -#define __align8 __attribute__ ((aligned (16))) - -void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); +#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +#define STRIDE_ALIGN 16 #elif defined(HAVE_MMI) -#define __align8 __attribute__ ((aligned (16))) - -void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); - -#elif defined(ARCH_SH4) - -#define __align8 __attribute__ ((aligned (8))) - -void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); +#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) +#define STRIDE_ALIGN 16 #else -#define __align8 +#define mm_flags 0 +#define mm_support() 0 #endif -#ifdef __GNUC__ +#ifndef DECLARE_ALIGNED_8 +# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v) +#endif -struct unaligned_64 { uint64_t l; } __attribute__((packed)); -struct unaligned_32 { uint32_t l; } __attribute__((packed)); -struct unaligned_16 { uint16_t l; } __attribute__((packed)); - -#define LD16(a) (((const struct unaligned_16 *) (a))->l) -#define LD32(a) (((const struct unaligned_32 *) (a))->l) -#define LD64(a) (((const struct unaligned_64 *) (a))->l) - -#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) - -#else /* __GNUC__ */ - -#define LD16(a) (*((uint16_t*)(a))) -#define LD32(a) (*((uint32_t*)(a))) -#define LD64(a) (*((uint64_t*)(a))) - -#define ST32(a, b) *((uint32_t*)(a)) = (b) - -#endif /* !__GNUC__ */ +#ifndef STRIDE_ALIGN +# define STRIDE_ALIGN 8 +#endif /* PSNR */ void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], @@ -441,6 +636,8 @@ void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], FFTSample type */ typedef float FFTSample; +struct MDCTContext; + typedef struct FFTComplex { FFTSample re, im; } FFTComplex; @@ -451,20 +648,31 @@ typedef struct FFTContext { uint16_t *revtab; FFTComplex *exptab; FFTComplex *exptab1; /* only used by SSE code */ + FFTComplex *tmp_buf; + void (*fft_permute)(struct FFTContext *s, FFTComplex *z); void (*fft_calc)(struct FFTContext *s, FFTComplex *z); + void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); + void (*imdct_half)(struct MDCTContext *s, FFTSample *output, const FFTSample *input); } FFTContext; -int fft_init(FFTContext *s, int nbits, int inverse); -void fft_permute(FFTContext *s, FFTComplex *z); -void fft_calc_c(FFTContext *s, FFTComplex *z); -void fft_calc_sse(FFTContext *s, FFTComplex *z); -void fft_calc_altivec(FFTContext *s, FFTComplex *z); +int ff_fft_init(FFTContext *s, int nbits, int inverse); +void ff_fft_permute_c(FFTContext *s, FFTComplex *z); +void ff_fft_permute_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_c(FFTContext *s, FFTComplex *z); +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z); +void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); -static inline void fft_calc(FFTContext *s, FFTComplex *z) +static inline void ff_fft_permute(FFTContext *s, FFTComplex *z) +{ + s->fft_permute(s, z); +} +static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) { s->fft_calc(s, z); } -void fft_end(FFTContext *s); +void ff_fft_end(FFTContext *s); /* MDCT computation */ @@ -477,20 +685,55 @@ typedef struct MDCTContext { FFTContext fft; } MDCTContext; +static inline void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + s->fft.imdct_calc(s, output, input); +} +static inline void ff_imdct_half(MDCTContext *s, FFTSample *output, const FFTSample *input) +{ + s->fft.imdct_half(s, output, input); +} + +/** + * Generate a Kaiser-Bessel Derived Window. + * @param window pointer to half window + * @param alpha determines window shape + * @param n size of half window + */ +void ff_kbd_window_init(float *window, float alpha, int n); + +/** + * Generate a sine window. + * @param window pointer to half window + * @param n size of half window + */ +void ff_sine_window_init(float *window, int n); +extern float ff_sine_128 [ 128]; +extern float ff_sine_256 [ 256]; +extern float ff_sine_512 [ 512]; +extern float ff_sine_1024[1024]; +extern float ff_sine_2048[2048]; +extern float *ff_sine_windows[5]; + int ff_mdct_init(MDCTContext *s, int nbits, int inverse); -void ff_imdct_calc(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp); -void ff_mdct_calc(MDCTContext *s, FFTSample *out, - const FFTSample *input, FFTSample *tmp); +void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, const FFTSample *input); +void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input); void ff_mdct_end(MDCTContext *s); -#define WARPER8_16(name8, name16)\ +#define WRAPPER8_16(name8, name16)\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ return name8(s, dst , src , stride, h)\ +name8(s, dst+8 , src+8 , stride, h);\ } -#define WARPER8_16_SQ(name8, name16)\ +#define WRAPPER8_16_SQ(name8, name16)\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ int score=0;\ score +=name8(s, dst , src , stride, 8);\ @@ -504,19 +747,81 @@ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int st return score;\ } -#ifndef HAVE_LRINTF -/* XXX: add ISOC specific test to avoid specific BSD testing. */ -/* better than nothing implementation. */ -/* btw, rintf() is existing on fbsd too -- alex */ -static inline long int lrintf(float x) -{ -#ifdef CONFIG_WIN32 - /* XXX: incorrect, but make it compile */ - return (int)(x); -#else - return (int)(rint(x)); -#endif -} -#endif -#endif +static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) +{ + int i; + for(i=0; i + * + * 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 + */ + +#include "avcodec.h" + + +static int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + int cmd= args ? *args : 0; + /* cast to avoid warning about discarding qualifiers */ + if(avctx->extradata){ + if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) && cmd=='a') + ||(keyframe && (cmd=='k' || !cmd)) + ||(cmd=='e') + /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ + int size= buf_size + avctx->extradata_size; + *poutbuf_size= size; + *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); + memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + return 1; + } + } + return 0; +} + +AVBitStreamFilter dump_extradata_bsf={ + "dump_extra", + 0, + dump_extradata, +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dv.c b/src/add-ons/media/plugins/avcodec/libavcodec/dv.c index 8e041b5039..aa7ef71a5f 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/dv.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dv.c @@ -1,52 +1,68 @@ /* * DV decoder * Copyright (c) 2002 Fabrice Bellard. + * Copyright (c) 2004 Roman Shaposhnik. * - * DV encoder + * DV encoder * Copyright (c) 2003 Roman Shaposhnik. * + * 50 Mbps (DVCPRO50) support + * Copyright (c) 2006 Daniel Maas + * * Many thanks to Dan Dennedy for providing wealth * of DV technical info. * - * This library is free software; you can redistribute it and/or + * 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file dv.c * DV codec. */ +#define ALT_BITSTREAM_READER #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" +#include "bitstream.h" #include "simple_idct.h" #include "dvdata.h" -typedef struct DVVideoDecodeContext { +//#undef NDEBUG +//#include + +typedef struct DVVideoContext { const DVprofile* sys; AVFrame picture; - + AVCodecContext *avctx; + uint8_t *buf; + uint8_t dv_zigzag[2][64]; - uint8_t dv_idct_shift[2][22][64]; - + uint32_t dv_idct_factor[2][2][22][64]; + void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size); void (*fdct[2])(DCTELEM *block); void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block); - - GetBitContext gb; - DCTELEM block[5*6][64] __align8; -} DVVideoDecodeContext; +} DVVideoContext; + +/* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */ +/* one element is needed for each video segment in a DV frame */ +/* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */ +#define DV_ANCHOR_SIZE (2*12*27) + +static void* dv_anchor[DV_ANCHOR_SIZE]; #define TEX_VLC_BITS 9 @@ -54,126 +70,144 @@ typedef struct DVVideoDecodeContext { #define DV_VLC_MAP_RUN_SIZE 15 #define DV_VLC_MAP_LEV_SIZE 23 #else -#define DV_VLC_MAP_RUN_SIZE 64 -#define DV_VLC_MAP_LEV_SIZE 512 +#define DV_VLC_MAP_RUN_SIZE 64 +#define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check #endif /* XXX: also include quantization */ -static RL_VLC_ELEM *dv_rl_vlc[1]; +static RL_VLC_ELEM dv_rl_vlc[1184]; /* VLC encoding lookup table */ static struct dv_vlc_pair { uint32_t vlc; uint8_t size; -} (*dv_vlc_map)[DV_VLC_MAP_LEV_SIZE] = NULL; +} dv_vlc_map[DV_VLC_MAP_RUN_SIZE][DV_VLC_MAP_LEV_SIZE]; -static void dv_build_unquantize_tables(DVVideoDecodeContext *s, uint8_t* perm) +static void dv_build_unquantize_tables(DVVideoContext *s, uint8_t* perm) { - int i, q, j; + int i, q, a; /* NOTE: max left shift is 6 */ for(q = 0; q < 22; q++) { /* 88DCT */ - for(i = 1; i < 64; i++) { - /* 88 table */ - j = perm[i]; - s->dv_idct_shift[0][q][j] = - dv_quant_shifts[q][dv_88_areas[i]] + 1; - } - - /* 248DCT */ - for(i = 1; i < 64; i++) { - /* 248 table */ - s->dv_idct_shift[1][q][i] = - dv_quant_shifts[q][dv_248_areas[i]] + 1; + i=1; + for(a = 0; a<4; a++) { + for(; i < dv_quant_areas[a]; i++) { + /* 88 table */ + s->dv_idct_factor[0][0][q][i] = dv_iweight_88[i]<<(dv_quant_shifts[q][a] + 1); + s->dv_idct_factor[1][0][q][i] = s->dv_idct_factor[0][0][q][i]<<1; + + /* 248 table */ + s->dv_idct_factor[0][1][q][i] = dv_iweight_248[i]<<(dv_quant_shifts[q][a] + 1); + s->dv_idct_factor[1][1][q][i] = s->dv_idct_factor[0][1][q][i]<<1; + } } } } -static int dvvideo_init(AVCodecContext *avctx) +static av_cold int dvvideo_init(AVCodecContext *avctx) { - DVVideoDecodeContext *s = avctx->priv_data; + DVVideoContext *s = avctx->priv_data; DSPContext dsp; static int done=0; int i, j; if (!done) { - int i; VLC dv_vlc; + uint16_t new_dv_vlc_bits[NB_DV_VLC*2]; + uint8_t new_dv_vlc_len[NB_DV_VLC*2]; + uint8_t new_dv_vlc_run[NB_DV_VLC*2]; + int16_t new_dv_vlc_level[NB_DV_VLC*2]; done = 1; - dv_vlc_map = av_mallocz(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); - if (!dv_vlc_map) - return -ENOMEM; + /* dv_anchor lets each thread know its Id */ + for (i=0; i= DV_VLC_MAP_RUN_SIZE || dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) - continue; - - if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) - continue; - - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] << - (!!dv_vlc_level[i]); - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] + - (!!dv_vlc_level[i]); - } - for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { + for (i = 0; i < NB_DV_VLC - 1; i++) { + if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE) + continue; #ifdef DV_CODEC_TINY_TARGET - for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) { - if (dv_vlc_map[i][j].size == 0) { - dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | - (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); - dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + - dv_vlc_map[0][j].size; - } - } -#else - for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) { - if (dv_vlc_map[i][j].size == 0) { - dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | - (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); - dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + - dv_vlc_map[0][j].size; - } - dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc = - dv_vlc_map[i][j].vlc | 1; - dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size = - dv_vlc_map[i][j].size; - } + if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) + continue; #endif - } + + if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) + continue; + + dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] << + (!!dv_vlc_level[i]); + dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] + + (!!dv_vlc_level[i]); + } + for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { +#ifdef DV_CODEC_TINY_TARGET + for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) { + if (dv_vlc_map[i][j].size == 0) { + dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | + (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); + dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + + dv_vlc_map[0][j].size; + } + } +#else + for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) { + if (dv_vlc_map[i][j].size == 0) { + dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | + (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); + dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + + dv_vlc_map[0][j].size; + } + dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc = + dv_vlc_map[i][j].vlc | 1; + dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size = + dv_vlc_map[i][j].size; + } +#endif + } } /* Generic DSP setup */ @@ -188,184 +222,120 @@ static int dvvideo_init(AVCodecContext *avctx) /* 248DCT setup */ s->fdct[1] = dsp.fdct248; - s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP - memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); + s->idct_put[1] = ff_simple_idct248_put; // FIXME: need to add it to DSP + if(avctx->lowres){ + for (i=0; i<64; i++){ + int j= ff_zigzag248_direct[i]; + s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2]; + } + }else + memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); /* XXX: do it only for constant case */ dv_build_unquantize_tables(s, dsp.idct_permutation); - /* FIXME: I really don't think this should be here */ - if (dv_codec_profile(avctx)) - avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt; avctx->coded_frame = &s->picture; - + s->avctx= avctx; + return 0; } // #define VLC_DEBUG +// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__) typedef struct BlockInfo { - const uint8_t *shift_table; + const uint32_t *factor_table; const uint8_t *scan_table; uint8_t pos; /* position in block */ - uint8_t eob_reached; /* true if EOB has been reached */ uint8_t dct_mode; uint8_t partial_bit_count; uint16_t partial_bit_buffer; int shift_offset; } BlockInfo; -/* block size in bits */ -static const uint16_t block_sizes[6] = { - 112, 112, 112, 112, 80, 80 -}; /* bit budget for AC only in 5 MBs */ static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; /* see dv_88_areas and dv_248_areas for details */ -static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; +static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; -#ifndef ALT_BITSTREAM_READER -#warning only works with ALT_BITSTREAM_READER -#endif +static inline int get_bits_left(GetBitContext *s) +{ + return s->size_in_bits - get_bits_count(s); +} + +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf) * 8 - put_bits_count(s); +} /* decode ac coefs */ -static void dv_decode_ac(DVVideoDecodeContext *s, - BlockInfo *mb, DCTELEM *block, int last_index) +static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) { - int last_re_index; - int shift_offset = mb->shift_offset; + int last_index = gb->size_in_bits; const uint8_t *scan_table = mb->scan_table; - const uint8_t *shift_table = mb->shift_table; + const uint32_t *factor_table = mb->factor_table; int pos = mb->pos; - int level, pos1, sign, run; - int partial_bit_count; -#ifndef ALT_BITSTREAM_READER //FIXME - int re_index=0; - int re1_index=0; -#endif - OPEN_READER(re, &s->gb); - -#ifdef VLC_DEBUG - printf("start\n"); -#endif + int partial_bit_count = mb->partial_bit_count; + int level, run, vlc_len, index; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); /* if we must parse a partial vlc, we do it here */ - partial_bit_count = mb->partial_bit_count; if (partial_bit_count > 0) { - uint8_t buf[4]; - uint32_t v; - int l, l1; - GetBitContext gb1; - - /* build the dummy bit buffer */ - l = 16 - partial_bit_count; - UPDATE_CACHE(re, &s->gb); -#ifdef VLC_DEBUG - printf("show=%04x\n", SHOW_UBITS(re, &s->gb, 16)); -#endif - v = (mb->partial_bit_buffer << l) | SHOW_UBITS(re, &s->gb, l); - buf[0] = v >> 8; - buf[1] = v; -#ifdef VLC_DEBUG - printf("v=%04x cnt=%d %04x\n", - v, partial_bit_count, (mb->partial_bit_buffer << l)); -#endif - /* try to read the codeword */ - init_get_bits(&gb1, buf, 4*8); - { - OPEN_READER(re1, &gb1); - UPDATE_CACHE(re1, &gb1); - GET_RL_VLC(level, run, re1, &gb1, dv_rl_vlc[0], - TEX_VLC_BITS, 2); - l = re1_index; - CLOSE_READER(re1, &gb1); - } -#ifdef VLC_DEBUG - printf("****run=%d level=%d size=%d\n", run, level, l); -#endif - /* compute codeword length */ - l1 = (level != 256 && level != 0); - /* if too long, we cannot parse */ - l -= partial_bit_count; - if ((re_index + l + l1) > last_index) - return; - /* skip read bits */ - last_re_index = 0; /* avoid warning */ - re_index += l; - /* by definition, if we can read the vlc, all partial bits - will be read (otherwise we could have read the vlc before) */ + re_cache = ((unsigned)re_cache >> partial_bit_count) | + (mb->partial_bit_buffer << (sizeof(re_cache)*8 - partial_bit_count)); + re_index -= partial_bit_count; mb->partial_bit_count = 0; - UPDATE_CACHE(re, &s->gb); - goto handle_vlc; } /* get the AC coefficients until last_index is reached */ for(;;) { - UPDATE_CACHE(re, &s->gb); #ifdef VLC_DEBUG - printf("%2d: bits=%04x index=%d\n", - pos, SHOW_UBITS(re, &s->gb, 16), re_index); + printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index); #endif - last_re_index = re_index; - GET_RL_VLC(level, run, re, &s->gb, dv_rl_vlc[0], - TEX_VLC_BITS, 2); - handle_vlc: + /* our own optimized GET_RL_VLC */ + index = NEG_USR32(re_cache, TEX_VLC_BITS); + vlc_len = dv_rl_vlc[index].len; + if (vlc_len < 0) { + index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level; + vlc_len = TEX_VLC_BITS - vlc_len; + } + level = dv_rl_vlc[index].level; + run = dv_rl_vlc[index].run; + + /* gotta check if we're still within gb boundaries */ + if (re_index + vlc_len > last_index) { + /* should be < 16 bits otherwise a codeword could have been parsed */ + mb->partial_bit_count = last_index - re_index; + mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); + re_index = last_index; + break; + } + re_index += vlc_len; + #ifdef VLC_DEBUG printf("run=%d level=%d\n", run, level); #endif - if (level == 256) { - if (re_index > last_index) { - cannot_read: - /* put position before read code */ - re_index = last_re_index; - mb->eob_reached = 0; - break; - } - /* EOB */ - mb->eob_reached = 1; + pos += run; + if (pos >= 64) break; - } else if (level != 0) { - if ((re_index + 1) > last_index) - goto cannot_read; - sign = SHOW_SBITS(re, &s->gb, 1); - level = (level ^ sign) - sign; - LAST_SKIP_BITS(re, &s->gb, 1); - pos += run; - /* error */ - if (pos >= 64) { - goto read_error; - } - pos1 = scan_table[pos]; - level = level << (shift_table[pos1] + shift_offset); - block[pos1] = level; - // printf("run=%d level=%d shift=%d\n", run, level, shift_table[pos1]); - } else { - if (re_index > last_index) - goto cannot_read; - /* level is zero: means run without coding. No - sign is coded */ - pos += run; - /* error */ - if (pos >= 64) { - read_error: -#if defined(VLC_DEBUG) || 1 - av_log(NULL, AV_LOG_ERROR, "error pos=%d\n", pos); -#endif - /* for errors, we consider the eob is reached */ - mb->eob_reached = 1; - break; - } - } + + level = (level*factor_table[pos] + (1 << (dv_iweight_bits-1))) >> dv_iweight_bits; + block[scan_table[pos]] = level; + + UPDATE_CACHE(re, gb); } - CLOSE_READER(re, &s->gb); + CLOSE_READER(re, gb); mb->pos = pos; } -static inline void bit_copy(PutBitContext *pb, GetBitContext *gb, int bits_left) +static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) { - while (bits_left >= 16) { - put_bits(pb, 16, get_bits(gb, 16)); - bits_left -= 16; + int bits_left = get_bits_left(gb); + while (bits_left >= MIN_CACHE_BITS) { + put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); + bits_left -= MIN_CACHE_BITS; } if (bits_left > 0) { put_bits(pb, bits_left, get_bits(gb, bits_left)); @@ -373,60 +343,59 @@ static inline void bit_copy(PutBitContext *pb, GetBitContext *gb, int bits_left) } /* mb_x and mb_y are in units of 8 pixels */ -static inline void dv_decode_video_segment(DVVideoDecodeContext *s, - uint8_t *buf_ptr1, +static inline void dv_decode_video_segment(DVVideoContext *s, + const uint8_t *buf_ptr1, const uint16_t *mb_pos_ptr) { int quant, dc, dct_mode, class1, j; int mb_index, mb_x, mb_y, v, last_index; DCTELEM *block, *block1; - int c_offset, bits_left; + int c_offset; uint8_t *y_ptr; - BlockInfo mb_data[5 * 6], *mb, *mb1; void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); - uint8_t *buf_ptr; + const uint8_t *buf_ptr; PutBitContext pb, vs_pb; - uint8_t mb_bit_buffer[80 + 4]; /* allow some slack */ - int mb_bit_count; - uint8_t vs_bit_buffer[5 * 80 + 4]; /* allow some slack */ - int vs_bit_count; - - memset(s->block, 0, sizeof(s->block)); + GetBitContext gb; + BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1; + DECLARE_ALIGNED_16(DCTELEM, sblock[5*DV_MAX_BPM][64]); + DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */ + DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */ + const int log2_blocksize= 3-s->avctx->lowres; + + assert((((int)mb_bit_buffer)&7)==0); + assert((((int)vs_bit_buffer)&7)==0); + + memset(sblock, 0, sizeof(sblock)); /* pass 1 : read DC and AC coefficients in blocks */ buf_ptr = buf_ptr1; - block1 = &s->block[0][0]; + block1 = &sblock[0][0]; mb1 = mb_data; init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80); - vs_bit_count = 0; - for(mb_index = 0; mb_index < 5; mb_index++) { + for(mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) { /* skip header */ quant = buf_ptr[3] & 0x0f; buf_ptr += 4; init_put_bits(&pb, mb_bit_buffer, 80); - mb_bit_count = 0; mb = mb1; block = block1; - for(j = 0;j < 6; j++) { - /* NOTE: size is not important here */ - init_get_bits(&s->gb, buf_ptr, 14*8); - + for(j = 0;j < s->sys->bpm; j++) { + last_index = s->sys->block_sizes[j]; + init_get_bits(&gb, buf_ptr, last_index); + /* get the dc */ - dc = get_bits(&s->gb, 9); - dc = (dc << (32 - 9)) >> (32 - 9); - dct_mode = get_bits1(&s->gb); + dc = get_sbits(&gb, 9); + dct_mode = get_bits1(&gb); mb->dct_mode = dct_mode; mb->scan_table = s->dv_zigzag[dct_mode]; - class1 = get_bits(&s->gb, 2); - mb->shift_offset = (class1 == 3); - mb->shift_table = s->dv_idct_shift[dct_mode] + class1 = get_bits(&gb, 2); + mb->factor_table = s->dv_idct_factor[class1 == 3][dct_mode] [quant + dv_quant_offset[class1]]; dc = dc << 2; /* convert to unsigned because 128 is not added in the standard IDCT */ dc += 1024; block[0] = dc; - last_index = block_sizes[j]; buf_ptr += last_index >> 3; mb->pos = 0; mb->partial_bit_count = 0; @@ -434,133 +403,120 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s, #ifdef VLC_DEBUG printf("MB block: %d, %d ", mb_index, j); #endif - dv_decode_ac(s, mb, block, last_index); + dv_decode_ac(&gb, mb, block); /* write the remaining bits in a new buffer only if the block is finished */ - bits_left = last_index - get_bits_count(&s->gb); - if (mb->eob_reached) { - mb->partial_bit_count = 0; - mb_bit_count += bits_left; - bit_copy(&pb, &s->gb, bits_left); - } else { - /* should be < 16 bits otherwise a codeword could have - been parsed */ - mb->partial_bit_count = bits_left; - mb->partial_bit_buffer = get_bits(&s->gb, bits_left); - } + if (mb->pos >= 64) + bit_copy(&pb, &gb); + block += 64; mb++; } - - flush_put_bits(&pb); /* pass 2 : we can do it just after */ #ifdef VLC_DEBUG - printf("***pass 2 size=%d MB#=%d\n", mb_bit_count, mb_index); + printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index); #endif block = block1; mb = mb1; - init_get_bits(&s->gb, mb_bit_buffer, 80*8); - for(j = 0;j < 6; j++) { - if (!mb->eob_reached && get_bits_count(&s->gb) < mb_bit_count) { - dv_decode_ac(s, mb, block, mb_bit_count); + init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); + flush_put_bits(&pb); + for(j = 0;j < s->sys->bpm; j++, block += 64, mb++) { + if (mb->pos < 64 && get_bits_left(&gb) > 0) { + dv_decode_ac(&gb, mb, block); /* if still not finished, no need to parse other blocks */ - if (!mb->eob_reached) { - /* we could not parse the current AC coefficient, - so we add the remaining bytes */ - bits_left = mb_bit_count - get_bits_count(&s->gb); - if (bits_left > 0) { - mb->partial_bit_count += bits_left; - mb->partial_bit_buffer = - (mb->partial_bit_buffer << bits_left) | - get_bits(&s->gb, bits_left); - } - goto next_mb; - } + if (mb->pos < 64) + break; } - block += 64; - mb++; } /* all blocks are finished, so the extra bytes can be used at the video segment level */ - bits_left = mb_bit_count - get_bits_count(&s->gb); - vs_bit_count += bits_left; - bit_copy(&vs_pb, &s->gb, bits_left); - next_mb: - mb1 += 6; - block1 += 6 * 64; + if (j >= s->sys->bpm) + bit_copy(&vs_pb, &gb); } /* we need a pass other the whole video segment */ - flush_put_bits(&vs_pb); - #ifdef VLC_DEBUG - printf("***pass 3 size=%d\n", vs_bit_count); + printf("***pass 3 size=%d\n", put_bits_count(&vs_pb)); #endif - block = &s->block[0][0]; + block = &sblock[0][0]; mb = mb_data; - init_get_bits(&s->gb, vs_bit_buffer, 5 * 80*8); + init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); + flush_put_bits(&vs_pb); for(mb_index = 0; mb_index < 5; mb_index++) { - for(j = 0;j < 6; j++) { - if (!mb->eob_reached) { + for(j = 0;j < s->sys->bpm; j++) { + if (mb->pos < 64) { #ifdef VLC_DEBUG printf("start %d:%d\n", mb_index, j); #endif - dv_decode_ac(s, mb, block, vs_bit_count); + dv_decode_ac(&gb, mb, block); } + if (mb->pos >= 64 && mb->pos < 127) + av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos); block += 64; mb++; } } - + /* compute idct and place blocks */ - block = &s->block[0][0]; + block = &sblock[0][0]; mb = mb_data; for(mb_index = 0; mb_index < 5; mb_index++) { v = *mb_pos_ptr++; mb_x = v & 0xff; mb_y = v >> 8; - y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); - if (s->sys->pix_fmt == PIX_FMT_YUV411P) - c_offset = (mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8); - else - c_offset = ((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8); + y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<>(s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] + + (mb_x>>((s->sys->pix_fmt == PIX_FMT_YUV411P)?2:1)))<idct_put[mb->dct_mode]; - if (j < 4) { - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { - /* NOTE: at end of line, the macroblock is handled as 420 */ - idct_put(y_ptr + (j * 8), s->picture.linesize[0], block); - } else { - idct_put(y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]), + idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3]; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ + if (j == 0 || j == 2) { + /* Y0 Y1 */ + idct_put(y_ptr + ((j >> 1)<picture.linesize[0], block); + } else if(j > 3) { + /* Cr Cb */ + idct_put(s->picture.data[6 - j] + c_offset, + s->picture.linesize[6 - j], block); } - } else { - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { - uint64_t aligned_pixels[64/8]; - uint8_t *pixels= (uint8_t*)aligned_pixels; - uint8_t *c_ptr, *c_ptr1, *ptr; - int y, linesize; - /* NOTE: at end of line, the macroblock is handled as 420 */ - idct_put(pixels, 8, block); - linesize = s->picture.linesize[6 - j]; - c_ptr = s->picture.data[6 - j] + c_offset; - ptr = pixels; - for(y = 0;y < 8; y++) { - /* convert to 411P */ - c_ptr1 = c_ptr + 8*linesize; - c_ptr[0]= ptr[0]; c_ptr1[0]= ptr[4]; - c_ptr[1]= ptr[1]; c_ptr1[1]= ptr[5]; - c_ptr[2]= ptr[2]; c_ptr1[2]= ptr[6]; - c_ptr[3]= ptr[3]; c_ptr1[3]= ptr[7]; - c_ptr += linesize; - ptr += 8; + /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */ + } else { /* 4:1:1 or 4:2:0 */ + if (j < 4) { + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { + /* NOTE: at end of line, the macroblock is handled as 420 */ + idct_put(y_ptr + (j<picture.linesize[0], block); + } else { + idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<picture.linesize[0], block); } } else { - /* don't ask me why they inverted Cb and Cr ! */ - idct_put(s->picture.data[6 - j] + c_offset, - s->picture.linesize[6 - j], block); + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { + uint64_t aligned_pixels[64/8]; + uint8_t *pixels= (uint8_t*)aligned_pixels; + uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; + int x, y, linesize; + /* NOTE: at end of line, the macroblock is handled as 420 */ + idct_put(pixels, 8, block); + linesize = s->picture.linesize[6 - j]; + c_ptr = s->picture.data[6 - j] + c_offset; + ptr = pixels; + for(y = 0;y < (1<picture.data[6 - j] + c_offset, + s->picture.linesize[6 - j], block); + } } } block += 64; @@ -571,183 +527,206 @@ static inline void dv_decode_video_segment(DVVideoDecodeContext *s, #ifdef DV_CODEC_TINY_TARGET /* Converts run and level (where level != 0) pair into vlc, returning bit size */ -static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc) +static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) { - int sign = l >> 8; - int level = (l ^ sign) - sign; int size; - - sign = (sign & 1); - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { *vlc = dv_vlc_map[run][level].vlc | sign; - size = dv_vlc_map[run][level].size; + size = dv_vlc_map[run][level].size; } - else { + else { if (level < DV_VLC_MAP_LEV_SIZE) { - *vlc = dv_vlc_map[0][level].vlc | sign; - size = dv_vlc_map[0][level].size; - } else { + *vlc = dv_vlc_map[0][level].vlc | sign; + size = dv_vlc_map[0][level].size; + } else { *vlc = 0xfe00 | (level << 1) | sign; - size = 16; - } - if (run) { - *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : - (0x1f80 | (run - 1))) << size; - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } + size = 16; + } + if (run) { + *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : + (0x1f80 | (run - 1))) << size; + size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; + } } - + return size; } -static always_inline int dv_rl2vlc_size(int run, int l) +static av_always_inline int dv_rl2vlc_size(int run, int level) { - int level = (l ^ (l >> 8)) - (l >> 8); int size; - + if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { - size = dv_vlc_map[run][level].size; + size = dv_vlc_map[run][level].size; } - else { - size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; - if (run) { - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } + else { + size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; + if (run) { + size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; + } } return size; } #else -static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc) +static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) { - *vlc = dv_vlc_map[run][((uint16_t)l)&0x1ff].vlc; - return dv_vlc_map[run][((uint16_t)l)&0x1ff].size; + *vlc = dv_vlc_map[run][l].vlc | sign; + return dv_vlc_map[run][l].size; } -static always_inline int dv_rl2vlc_size(int run, int l) +static av_always_inline int dv_rl2vlc_size(int run, int l) { - return dv_vlc_map[run][((uint16_t)l)&0x1ff].size; + return dv_vlc_map[run][l].size; } #endif typedef struct EncBlockInfo { int area_q[4]; int bit_size[4]; - int prev_run[4]; + int prev[5]; int cur_ac; int cno; int dct_mode; - DCTELEM *mb; + DCTELEM mb[64]; + uint8_t next[64]; + uint8_t sign[64]; uint8_t partial_bit_count; uint32_t partial_bit_buffer; /* we can't use uint16_t here */ } EncBlockInfo; -static always_inline int dv_bits_left(PutBitContext* s) +static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, + PutBitContext* pb_end) { - return (s->buf_end - s->buf) * 8 - - ((s->buf_ptr - s->buf) * 8 + 32 - (int64_t)s->bit_left); -} - -static always_inline void dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, - int pb_size) -{ - int run; + int prev; int bits_left; PutBitContext* pb = pb_pool; int size = bi->partial_bit_count; uint32_t vlc = bi->partial_bit_buffer; - + bi->partial_bit_count = bi->partial_bit_buffer = 0; -vlc_loop: + for(;;){ /* Find suitable storage space */ - for (; size > (bits_left = dv_bits_left(pb)); pb++) { + for (; size > (bits_left = put_bits_left(pb)); pb++) { if (bits_left) { size -= bits_left; - put_bits(pb, bits_left, vlc >> size); - vlc = vlc & ((1<partial_bit_count = size; - bi->partial_bit_buffer = vlc; - return; - } - --pb_size; + put_bits(pb, bits_left, vlc >> size); + vlc = vlc & ((1<= pb_end) { + bi->partial_bit_count = size; + bi->partial_bit_buffer = vlc; + return pb; + } } - + /* Store VLC */ put_bits(pb, size, vlc); - + + if(bi->cur_ac>=64) + break; + /* Construct the next VLC */ - run = 0; - for (; bi->cur_ac < 64; bi->cur_ac++, run++) { - if (bi->mb[bi->cur_ac]) { - size = dv_rl2vlc(run, bi->mb[bi->cur_ac], &vlc); - bi->cur_ac++; - goto vlc_loop; - } - } - - if (bi->cur_ac == 64) { + prev= bi->cur_ac; + bi->cur_ac = bi->next[prev]; + if(bi->cur_ac < 64){ + size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); + } else { size = 4; vlc = 6; /* End Of Block stamp */ - bi->cur_ac++; - goto vlc_loop; } + } + return pb; } -static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, - const uint8_t* zigzag_scan, int bias) +static av_always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, + const uint8_t* zigzag_scan, const int *weight, int bias) { int i, area; - int run; - int classes[] = {12, 24, 36, 0xffff}; + /* We offer two different methods for class number assignment: the + method suggested in SMPTE 314M Table 22, and an improved + method. The SMPTE method is very conservative; it assigns class + 3 (i.e. severe quantization) to any block where the largest AC + component is greater than 36. ffmpeg's DV encoder tracks AC bit + consumption precisely, so there is no need to bias most blocks + towards strongly lossy compression. Instead, we assign class 2 + to most blocks, and use class 3 only when strictly necessary + (for blocks whose largest AC component exceeds 255). */ + +#if 0 /* SMPTE spec method */ + static const int classes[] = {12, 24, 36, 0xffff}; +#else /* improved ffmpeg method */ + static const int classes[] = {-1, -1, 255, 0xffff}; +#endif + int max=classes[0]; + int prev=0; + + bi->mb[0] = blk[0]; - run = 0; - bi->mb[0] = blk[0]; - bi->cno = 0; for (area = 0; area < 4; area++) { - bi->prev_run[area] = run; - bi->bit_size[area] = 0; + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) for (i=mb_area_start[area]; imb[i] = (blk[zigzag_scan[i]] / 16); - while ((bi->mb[i] ^ (bi->mb[i] >> 8)) > classes[bi->cno]) - bi->cno++; - - if (bi->mb[i]) { - bi->bit_size[area] += dv_rl2vlc_size(run, bi->mb[i]); - run = 0; - } else - ++run; + int level = blk[zigzag_scan[i]]; + + if (level+15 > 30U) { + bi->sign[i] = (level>>31)&1; + /* weigh it and and shift down into range, adding for rounding */ + /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT + AND the 2x doubling of the weights */ + level = (FFABS(level) * weight[i] + (1<<(dv_weight_bits+3))) >> (dv_weight_bits+4); + bi->mb[i] = level; + if(level>max) max= level; + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level); + bi->next[prev]= i; + prev= i; + } } } - bi->bit_size[3] += 4; /* EOB marker */ + bi->next[prev]= i; + for(bi->cno = 0; max > classes[bi->cno]; bi->cno++); + bi->cno += bias; - - if (bi->cno >= 3) { /* FIXME: we have to recreate bit_size[], prev_run[] */ + + if (bi->cno >= 3) { bi->cno = 3; - for (i=1; i<64; i++) - bi->mb[i] /= 2; + prev=0; + i= bi->next[prev]; + for (area = 0; area < 4; area++) { + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) + for (; inext[i]) { + bi->mb[i] >>=1; + + if (bi->mb[i]) { + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]); + bi->next[prev]= i; + prev= i; + } + } + } + bi->next[prev]= i; } } +//FIXME replace this by dsputil #define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7)) -static always_inline int dv_guess_dct_mode(DCTELEM *blk) { +static av_always_inline int dv_guess_dct_mode(DCTELEM *blk) { DCTELEM *s; int score88 = 0; int score248 = 0; int i; - + /* Compute 8-8 score (small values give a better chance for 8-8 DCT) */ s = blk; for(i=0; i<7; i++) { - score88 += SC(0, 8) + SC(1, 9) + SC(2, 10) + SC(3, 11) + - SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15); + score88 += SC(0, 8) + SC(1, 9) + SC(2, 10) + SC(3, 11) + + SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15); s += 8; } /* Compute 2-4-8 score (small values give a better chance for 2-4-8 DCT) */ s = blk; for(i=0; i<6; i++) { score248 += SC(0, 16) + SC(1,17) + SC(2, 18) + SC(3, 19) + - SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23); + SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23); s += 8; } @@ -757,131 +736,187 @@ static always_inline int dv_guess_dct_mode(DCTELEM *blk) { static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) { int size[5]; - int i, j, k, a, run; + int i, j, k, a, prev, a2; EncBlockInfo* b; - + + size[0] = size[1] = size[2] = size[3] = size[4] = 1<<24; do { b = blks; for (i=0; i<5; i++) { if (!qnos[i]) - continue; - - qnos[i]--; - size[i] = 0; + continue; + + qnos[i]--; + size[i] = 0; for (j=0; j<6; j++, b++) { - for (a=0; a<4; a++) { - if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) { - b->bit_size[a] = (a==3)?4:0; - b->area_q[a]++; - run = b->prev_run[a]; - for (k=mb_area_start[a]; kmb[k] /= 2; - if (b->mb[k]) { - b->bit_size[a] += dv_rl2vlc_size(run, b->mb[k]); - run = 0; - } else - ++run; - } - } - size[i] += b->bit_size[a]; - } - } + for (a=0; a<4; a++) { + if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) { + b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) + b->area_q[a]++; + prev= b->prev[a]; + assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]); + for (k= b->next[prev] ; knext[k]) { + b->mb[k] >>= 1; + if (b->mb[k]) { + b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); + prev= k; + } else { + if(b->next[k] >= mb_area_start[a+1] && b->next[k]<64){ + for(a2=a+1; b->next[k] >= mb_area_start[a2+1]; a2++) + b->prev[a2] = prev; + assert(a2<4); + assert(b->mb[b->next[k]]); + b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]]) + -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]); + assert(b->prev[a2]==k && (a2+1 >= 4 || b->prev[a2+1]!=k)); + b->prev[a2] = prev; + } + b->next[prev] = b->next[k]; + } + } + b->prev[a+1]= prev; + } + size[i] += b->bit_size[a]; + } + } + if(vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4]) + return; } - } while ((vs_total_ac_bits < size[0] + size[1] + size[2] + size[3] + size[4]) && - (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4])); + } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]); + + + for(a=2; a==2 || vs_total_ac_bits < size[0]; a+=a){ + b = blks; + size[0] = 5*6*4; //EOB + for (j=0; j<6*5; j++, b++) { + prev= b->prev[0]; + for (k= b->next[prev]; k<64; k= b->next[k]) { + if(b->mb[k] < a && b->mb[k] > -a){ + b->next[prev] = b->next[k]; + }else{ + size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); + prev= k; + } + } + } + } } -/* - * This is a very rough initial implementaion. The performance is - * horrible and the weighting is missing. But it's missing from the - * decoding step also -- so at least we're on the same page with decoder ;-) - */ -static inline void dv_encode_video_segment(DVVideoDecodeContext *s, - uint8_t *dif, +static inline void dv_encode_video_segment(DVVideoContext *s, + uint8_t *dif, const uint16_t *mb_pos_ptr) { int mb_index, i, j, v; - int mb_x, mb_y, c_offset, linesize; + int mb_x, mb_y, c_offset, linesize; uint8_t* y_ptr; uint8_t* data; uint8_t* ptr; int do_edge_wrap; - DCTELEM block[64] __align8; + DECLARE_ALIGNED_16(DCTELEM, block[64]); EncBlockInfo enc_blks[5*6]; PutBitContext pbs[5*6]; - PutBitContext* pb; + PutBitContext* pb; EncBlockInfo* enc_blk; int vs_bit_size = 0; int qnos[5]; - + + assert((((int)block) & 15) == 0); + enc_blk = &enc_blks[0]; pb = &pbs[0]; for(mb_index = 0; mb_index < 5; mb_index++) { v = *mb_pos_ptr++; mb_x = v & 0xff; mb_y = v >> 8; - y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); - c_offset = (s->sys->pix_fmt == PIX_FMT_YUV411P) ? - ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)) : - (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8)); - do_edge_wrap = 0; - qnos[mb_index] = 15; /* No quantization */ + y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<3); + c_offset = (((mb_y>>(s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] + + (mb_x>>((s->sys->pix_fmt == PIX_FMT_YUV411P)?2:1)))<<3); + do_edge_wrap = 0; + qnos[mb_index] = 15; /* No quantization */ ptr = dif + mb_index*80 + 4; for(j = 0;j < 6; j++) { - if (j < 4) { /* Four Y blocks */ - /* NOTE: at end of line, the macroblock is handled as 420 */ - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { - data = y_ptr + (j * 8); + int dummy = 0; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ + if (j == 0 || j == 2) { + /* Y0 Y1 */ + data = y_ptr + ((j>>1) * 8); + linesize = s->picture.linesize[0]; + } else if (j > 3) { + /* Cr Cb */ + data = s->picture.data[6 - j] + c_offset; + linesize = s->picture.linesize[6 - j]; } else { - data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]); + /* j=1 and j=3 are "dummy" blocks, used for AC data only */ + data = 0; + linesize = 0; + dummy = 1; } - linesize = s->picture.linesize[0]; - } else { /* Cr and Cb blocks */ - /* don't ask Fabrice why they inverted Cb and Cr ! */ - data = s->picture.data[6 - j] + c_offset; - linesize = s->picture.linesize[6 - j]; - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) - do_edge_wrap = 1; - } - - /* Everything is set up -- now just copy data -> DCT block */ - if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */ - uint8_t* d; - DCTELEM *b = block; - for (i=0;i<8;i++) { - d = data + 8 * linesize; - b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3]; + } else { /* 4:1:1 or 4:2:0 */ + if (j < 4) { /* Four Y blocks */ + /* NOTE: at end of line, the macroblock is handled as 420 */ + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { + data = y_ptr + (j * 8); + } else { + data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]); + } + linesize = s->picture.linesize[0]; + } else { /* Cr and Cb blocks */ + /* don't ask Fabrice why they inverted Cb and Cr ! */ + data = s->picture.data[6 - j] + c_offset; + linesize = s->picture.linesize[6 - j]; + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) + do_edge_wrap = 1; + } + } + + /* Everything is set up -- now just copy data -> DCT block */ + if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */ + uint8_t* d; + DCTELEM *b = block; + for (i=0;i<8;i++) { + d = data + 8 * linesize; + b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3]; b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; - data += linesize; - b += 8; - } - } else { /* Simple copy: 8x8 -> 8x8 */ - s->get_pixels(block, data, linesize); - } - - enc_blk->dct_mode = dv_guess_dct_mode(block); - enc_blk->mb = &s->block[mb_index*6+j][0]; - enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; - enc_blk->partial_bit_count = 0; - enc_blk->partial_bit_buffer = 0; - enc_blk->cur_ac = 1; - - s->fdct[enc_blk->dct_mode](block); - - dv_set_class_number(block, enc_blk, - enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, - j/4*(j%2)); - - init_put_bits(pb, ptr, block_sizes[j]/8); - put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024) >> 2)); - put_bits(pb, 1, enc_blk->dct_mode); - put_bits(pb, 2, enc_blk->cno); - - vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] + - enc_blk->bit_size[2] + enc_blk->bit_size[3]; - ++enc_blk; - ++pb; - ptr += block_sizes[j]/8; + data += linesize; + b += 8; + } + } else { /* Simple copy: 8x8 -> 8x8 */ + if (!dummy) + s->get_pixels(block, data, linesize); + } + + if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) + enc_blk->dct_mode = dv_guess_dct_mode(block); + else + enc_blk->dct_mode = 0; + enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; + enc_blk->partial_bit_count = 0; + enc_blk->partial_bit_buffer = 0; + enc_blk->cur_ac = 0; + + if (dummy) { + /* We rely on the fact that encoding all zeros leads to an immediate EOB, + which is precisely what the spec calls for in the "dummy" blocks. */ + memset(block, 0, sizeof(block)); + } else { + s->fdct[enc_blk->dct_mode](block); + } + + dv_set_class_number(block, enc_blk, + enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, + enc_blk->dct_mode ? dv_weight_248 : dv_weight_88, + j/4); + + init_put_bits(pb, ptr, s->sys->block_sizes[j]/8); + put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2)); + put_bits(pb, 1, enc_blk->dct_mode); + put_bits(pb, 2, enc_blk->cno); + + vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] + + enc_blk->bit_size[2] + enc_blk->bit_size[3]; + ++enc_blk; + ++pb; + ptr += s->sys->block_sizes[j]/8; } } @@ -894,51 +929,92 @@ static inline void dv_encode_video_segment(DVVideoDecodeContext *s, /* First pass over individual cells only */ for (j=0; j<5*6; j++) - dv_encode_ac(&enc_blks[j], &pbs[j], 1); + dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); /* Second pass over each MB space */ - for (j=0; j<5*6; j++) { - if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count) - dv_encode_ac(&enc_blks[j], &pbs[(j/6)*6], 6); + for (j=0; j<5*6; j+=6) { + pb= &pbs[j]; + for (i=0; i<6; i++) { + if (enc_blks[i+j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]); + } } /* Third and final pass over the whole vides segment space */ + pb= &pbs[0]; for (j=0; j<5*6; j++) { - if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count) - dv_encode_ac(&enc_blks[j], &pbs[0], 6*5); + if (enc_blks[j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]); + if (enc_blks[j].partial_bit_count) + av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n"); } for (j=0; j<5*6; j++) flush_put_bits(&pbs[j]); } -/* NOTE: exactly one frame must be given (120000 bytes for NTSC, - 144000 bytes for PAL) */ -static int dvvideo_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) +static int dv_decode_mt(AVCodecContext *avctx, void* sl) { - DVVideoDecodeContext *s = avctx->priv_data; - int ds, vs; - const uint16_t *mb_pos_ptr; - - *data_size=0; - /* special case for last picture */ - if(buf_size==0) - return 0; - + DVVideoContext *s = avctx->priv_data; + int slice = (size_t)sl; + + /* which DIF channel is this? */ + int chan = slice / (s->sys->difseg_size * 27); + + /* slice within the DIF channel */ + int chan_slice = slice % (s->sys->difseg_size * 27); + + /* byte offset of this channel's data */ + int chan_offset = chan * s->sys->difseg_size * 150 * 80; + + dv_decode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], + &s->sys->video_place[slice*5]); + return 0; +} + +#ifdef CONFIG_DVVIDEO_ENCODER +static int dv_encode_mt(AVCodecContext *avctx, void* sl) +{ + DVVideoContext *s = avctx->priv_data; + int slice = (size_t)sl; + + /* which DIF channel is this? */ + int chan = slice / (s->sys->difseg_size * 27); + + /* slice within the DIF channel */ + int chan_slice = slice % (s->sys->difseg_size * 27); + + /* byte offset of this channel's data */ + int chan_offset = chan * s->sys->difseg_size * 150 * 80; + + dv_encode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], + &s->sys->video_place[slice*5]); + return 0; +} +#endif + +#ifdef CONFIG_DECODERS +/* NOTE: exactly one frame must be given (120000 bytes for NTSC, + 144000 bytes for PAL - or twice those for 50Mbps) */ +static int dvvideo_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + DVVideoContext *s = avctx->priv_data; + s->sys = dv_frame_profile(buf); if (!s->sys || buf_size < s->sys->frame_size) return -1; /* NOTE: we only accept several full frames */ - if(s->picture.data[0]) avctx->release_buffer(avctx, &s->picture); - + s->picture.reference = 0; + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; avctx->pix_fmt = s->sys->pix_fmt; - avctx->width = s->sys->width; - avctx->height = s->sys->height; + avctx->time_base = (AVRational){s->sys->frame_rate_base, s->sys->frame_rate}; + avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); if(avctx->get_buffer(avctx, &s->picture) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -946,84 +1022,208 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, s->picture.interlaced_frame = 1; s->picture.top_field_first = 0; - /* for each DIF segment */ - mb_pos_ptr = s->sys->video_place; - for (ds = 0; ds < s->sys->difseg_size; ds++) { - buf += 6 * 80; /* skip DIF segment header */ - - for(vs = 0; vs < 27; vs++) { - if ((vs % 3) == 0) - buf += 80; /* skip audio block */ - -#ifdef VLC_DEBUG - printf("********************* %d, %d **********************\n", ds, vs); -#endif - dv_decode_video_segment(s, buf, mb_pos_ptr); - buf += 5 * 80; - mb_pos_ptr += 5; - } - } + s->buf = buf; + avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL, + s->sys->n_difchan * s->sys->difseg_size * 27); emms_c(); /* return image */ *data_size = sizeof(AVFrame); *(AVFrame*)data= s->picture; - + return s->sys->frame_size; } +#endif -static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, + +static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, uint8_t* buf) +{ + /* + * Here's what SMPTE314M says about these two: + * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical + * as track application IDs (APTn = 001, AP1n = + * 001, AP2n = 001, AP3n = 001), if the source signal + * comes from a digital VCR. If the signal source is + * unknown, all bits for these data shall be set to 1. + * (page 12) STYPE: STYPE defines a signal type of video signal + * 00000b = 4:1:1 compression + * 00100b = 4:2:2 compression + * XXXXXX = Reserved + * Now, I've got two problems with these statements: + * 1. it looks like APT == 111b should be a safe bet, but it isn't. + * It seems that for PAL as defined in IEC 61834 we have to set + * APT to 000 and for SMPTE314M to 001. + * 2. It is not at all clear what STYPE is used for 4:2:0 PAL + * compression scheme (if any). + */ + int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1); + int stype = (c->sys->pix_fmt == PIX_FMT_YUV422P ? 4 : 0); + + uint8_t aspect = 0; + if((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) == 17) /* 16:9 */ + aspect = 0x02; + + buf[0] = (uint8_t)pack_id; + switch (pack_id) { + case dv_header525: /* I can't imagine why these two weren't defined as real */ + case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */ + buf[1] = 0xf8 | /* reserved -- always 1 */ + (apt & 0x07); /* APT: Track application ID */ + buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */ + (0x0f << 3) | /* reserved -- always 1 */ + (apt & 0x07); /* AP1: Audio application ID */ + buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */ + (0x0f << 3) | /* reserved -- always 1 */ + (apt & 0x07); /* AP2: Video application ID */ + buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */ + (0x0f << 3) | /* reserved -- always 1 */ + (apt & 0x07); /* AP3: Subcode application ID */ + break; + case dv_video_source: + buf[1] = 0xff; /* reserved -- always 1 */ + buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */ + (1 << 6) | /* following CLF is valid - 0, invalid - 1 */ + (3 << 4) | /* CLF: color frames id (see ITU-R BT.470-4) */ + 0xf; /* reserved -- always 1 */ + buf[3] = (3 << 6) | /* reserved -- always 1 */ + (c->sys->dsf << 5) | /* system: 60fields/50fields */ + stype; /* signal type video compression */ + buf[4] = 0xff; /* VISC: 0xff -- no information */ + break; + case dv_video_control: + buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */ + 0x3f; /* reserved -- always 1 */ + buf[2] = 0xc8 | /* reserved -- always b11001xxx */ + aspect; + buf[3] = (1 << 7) | /* Frame/field flag 1 -- frame, 0 -- field */ + (1 << 6) | /* First/second field flag 0 -- field 2, 1 -- field 1 */ + (1 << 5) | /* Frame change flag 0 -- same picture as before, 1 -- different */ + (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */ + 0xc; /* reserved -- always b1100 */ + buf[4] = 0xff; /* reserved -- always 1 */ + break; + default: + buf[1] = buf[2] = buf[3] = buf[4] = 0xff; + } + return 5; +} + +#ifdef CONFIG_DVVIDEO_ENCODER +static void dv_format_frame(DVVideoContext* c, uint8_t* buf) +{ + int chan, i, j, k; + + for (chan = 0; chan < c->sys->n_difchan; chan++) { + for (i = 0; i < c->sys->difseg_size; i++) { + memset(buf, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */ + + /* DV header: 1DIF */ + buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf); + buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf); + buf += 72; /* unused bytes */ + + /* DV subcode: 2DIFs */ + for (j = 0; j < 2; j++) { + buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf); + for (k = 0; k < 6; k++) + buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5; + buf += 29; /* unused bytes */ + } + + /* DV VAUX: 3DIFS */ + for (j = 0; j < 3; j++) { + buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf); + buf += dv_write_pack(dv_video_source, c, buf); + buf += dv_write_pack(dv_video_control, c, buf); + buf += 7*5; + buf += dv_write_pack(dv_video_source, c, buf); + buf += dv_write_pack(dv_video_control, c, buf); + buf += 4*5 + 2; /* unused bytes */ + } + + /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */ + for (j = 0; j < 135; j++) { + if (j%15 == 0) { + memset(buf, 0xff, 80); + buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf); + buf += 77; /* audio control & shuffled PCM audio */ + } + buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf); + buf += 77; /* 1 video macro block: 1 bytes control + 4 * 14 bytes Y 8x8 data + 10 bytes Cr 8x8 data + 10 bytes Cb 8x8 data */ + } + } + } +} + + +static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, void *data) { - DVVideoDecodeContext *s = c->priv_data; - const uint16_t *mb_pos_ptr; - int ds, vs; + DVVideoContext *s = c->priv_data; s->sys = dv_codec_profile(c); if (!s->sys) - return -1; - + return -1; + if(buf_size < s->sys->frame_size) + return -1; + c->pix_fmt = s->sys->pix_fmt; s->picture = *((AVFrame *)data); + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; - /* for each DIF segment */ - mb_pos_ptr = s->sys->video_place; - for (ds = 0; ds < s->sys->difseg_size; ds++) { - buf += 6 * 80; /* skip DIF segment header */ - - for(vs = 0; vs < 27; vs++) { - if ((vs % 3) == 0) - buf += 80; /* skip audio block */ - -#ifdef VLC_DEBUG - printf("********************* %d, %d **********************\n", ds, vs); -#endif - dv_encode_video_segment(s, buf, mb_pos_ptr); - buf += 5 * 80; - mb_pos_ptr += 5; - } - } + s->buf = buf; + c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL, + s->sys->n_difchan * s->sys->difseg_size * 27); emms_c(); + + dv_format_frame(s, buf); + return s->sys->frame_size; } +#endif -static int dvvideo_end(AVCodecContext *avctx) +static int dvvideo_close(AVCodecContext *c) { - avcodec_default_free_buffers(avctx); + DVVideoContext *s = c->priv_data; + + if(s->picture.data[0]) + c->release_buffer(c, &s->picture); + return 0; } + +#ifdef CONFIG_DVVIDEO_ENCODER +AVCodec dvvideo_encoder = { + "dvvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_DVVIDEO, + sizeof(DVVideoContext), + dvvideo_init, + dvvideo_encode_frame, + .pix_fmts = (enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), +}; +#endif // CONFIG_DVVIDEO_ENCODER + +#ifdef CONFIG_DVVIDEO_DECODER AVCodec dvvideo_decoder = { "dvvideo", CODEC_TYPE_VIDEO, CODEC_ID_DVVIDEO, - sizeof(DVVideoDecodeContext), + sizeof(DVVideoContext), dvvideo_init, - dvvideo_encode_frame, - dvvideo_end, + NULL, + dvvideo_close, dvvideo_decode_frame, CODEC_CAP_DR1, - NULL + NULL, + .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), }; +#endif diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub.c new file mode 100644 index 0000000000..d7cb2c4d95 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub.c @@ -0,0 +1,412 @@ +/* + * DVB subtitle encoding for ffmpeg + * Copyright (c) 2005 Fabrice Bellard. + * + * 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 + */ +#include "avcodec.h" +#include "bytestream.h" +#include "colorspace.h" + +typedef struct DVBSubtitleContext { + int hide_state; + int object_version; +} DVBSubtitleContext; + +#define PUTBITS2(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 2;\ + if (bitcnt < 0) {\ + bitcnt = 6;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +static void dvb_encode_rle2(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + *q++ = 0x10; + bitbuf = 0; + bitcnt = 6; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(1); + } else if (len >= 3 && len <= 10) { + v = len - 3; + PUTBITS2(0); + PUTBITS2((v >> 2) | 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 12 && len <= 27) { + v = len - 12; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(2); + PUTBITS2(v >> 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 29) { + /* length = 29 ... 284 */ + if (len > 284) + len = 284; + v = len - 29; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(3); + PUTBITS2((v >> 6)); + PUTBITS2((v >> 4) & 3); + PUTBITS2((v >> 2) & 3); + PUTBITS2(v & 3); + PUTBITS2(color); + } else { + PUTBITS2(color); + if (color == 0) { + PUTBITS2(1); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(0); + if (bitcnt != 6) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + } + *pq = q; +} + +#define PUTBITS4(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 4;\ + if (bitcnt < 0) {\ + bitcnt = 4;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +/* some DVB decoders only implement 4 bits/pixel */ +static void dvb_encode_rle4(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + *q++ = 0x11; + bitbuf = 0; + bitcnt = 4; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS4(0); + PUTBITS4(0xd); + } else if (color == 0 && (len >= 3 && len <= 9)) { + PUTBITS4(0); + PUTBITS4(len - 2); + } else if (len >= 4 && len <= 7) { + PUTBITS4(0); + PUTBITS4(8 + len - 4); + PUTBITS4(color); + } else if (len >= 9 && len <= 24) { + PUTBITS4(0); + PUTBITS4(0xe); + PUTBITS4(len - 9); + PUTBITS4(color); + } else if (len >= 25) { + if (len > 280) + len = 280; + v = len - 25; + PUTBITS4(0); + PUTBITS4(0xf); + PUTBITS4(v >> 4); + PUTBITS4(v & 0xf); + PUTBITS4(color); + } else { + PUTBITS4(color); + if (color == 0) { + PUTBITS4(0xc); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS4(0); + PUTBITS4(0); + if (bitcnt != 4) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + } + *pq = q; +} + +static int encode_dvb_subtitles(DVBSubtitleContext *s, + uint8_t *outbuf, AVSubtitle *h) +{ + uint8_t *q, *pseg_len; + int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; + + + q = outbuf; + + page_id = 1; + + if (h->num_rects == 0 || h->rects == NULL) + return -1; + + *q++ = 0x00; /* subtitle_stream_id */ + + /* page composition segment */ + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x10; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = 30; /* page_timeout (seconds) */ + if (s->hide_state) + page_state = 0; /* normal case */ + else + page_state = 2; /* mode change */ + /* page_version = 0 + page_state */ + *q++ = s->object_version | (page_state << 2) | 3; + + for (region_id = 0; region_id < h->num_rects; region_id++) { + *q++ = region_id; + *q++ = 0xff; /* reserved */ + bytestream_put_be16(&q, h->rects[region_id].x); /* left pos */ + bytestream_put_be16(&q, h->rects[region_id].y); /* top pos */ + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + + if (!s->hide_state) { + for (clut_id = 0; clut_id < h->num_rects; clut_id++) { + + /* CLUT segment */ + + if (h->rects[clut_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[clut_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync byte */ + *q++ = 0x12; /* CLUT definition segment */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = clut_id; + *q++ = (0 << 4) | 0xf; /* version = 0 */ + + for(i = 0; i < h->rects[clut_id].nb_colors; i++) { + *q++ = i; /* clut_entry_id */ + *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ + { + int a, r, g, b; + a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff; + r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff; + g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff; + b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff; + + *q++ = RGB_TO_Y_CCIR(r, g, b); + *q++ = RGB_TO_V_CCIR(r, g, b, 0); + *q++ = RGB_TO_U_CCIR(r, g, b, 0); + *q++ = 255 - a; + } + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + } + } + + for (region_id = 0; region_id < h->num_rects; region_id++) { + + /* region composition segment */ + + if (h->rects[region_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[region_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x11; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = region_id; + *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ + bytestream_put_be16(&q, h->rects[region_id].w); /* region width */ + bytestream_put_be16(&q, h->rects[region_id].h); /* region height */ + *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; + *q++ = region_id; /* clut_id == region_id */ + *q++ = 0; /* 8 bit fill colors */ + *q++ = 0x03; /* 4 bit and 2 bit fill colors */ + + if (!s->hide_state) { + bytestream_put_be16(&q, region_id); /* object_id == region_id */ + *q++ = (0 << 6) | (0 << 4); + *q++ = 0; + *q++ = 0xf0; + *q++ = 0; + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + } + + if (!s->hide_state) { + + for (object_id = 0; object_id < h->num_rects; object_id++) { + /* Object Data segment */ + + if (h->rects[object_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[object_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync byte */ + *q++ = 0x13; + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + bytestream_put_be16(&q, object_id); + *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, + onject_coding_method, + non_modifying_color_flag */ + { + uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; + void (*dvb_encode_rle)(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h); + ptop_field_len = q; + q += 2; + pbottom_field_len = q; + q += 2; + + if (bpp_index == 0) + dvb_encode_rle = dvb_encode_rle2; + else + dvb_encode_rle = dvb_encode_rle4; + + top_ptr = q; + dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2, + h->rects[object_id].w, h->rects[object_id].h >> 1); + bottom_ptr = q; + dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, + h->rects[object_id].w * 2, h->rects[object_id].w, + h->rects[object_id].h >> 1); + + bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr); + bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); + } + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + } + } + + /* end of display set segment */ + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x80; /* segment_type */ + bytestream_put_be16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + bytestream_put_be16(&pseg_len, q - pseg_len - 2); + + *q++ = 0xff; /* end of PES data */ + + s->object_version = (s->object_version + 1) & 0xf; + s->hide_state = !s->hide_state; + return q - outbuf; +} + +static int dvbsub_encode(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + DVBSubtitleContext *s = avctx->priv_data; + AVSubtitle *sub = data; + int ret; + + ret = encode_dvb_subtitles(s, buf, sub); + return ret; +} + +AVCodec dvbsub_encoder = { + "dvbsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVB_SUBTITLE, + sizeof(DVBSubtitleContext), + NULL, + dvbsub_encode, + .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub_parser.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub_parser.c new file mode 100644 index 0000000000..0a83de39ef --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsub_parser.c @@ -0,0 +1,196 @@ +/* + * DVB subtitle parser for FFmpeg + * Copyright (c) 2005 Ian Caulfield. + * + * 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 + */ +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" + +//#define DEBUG +//#define DEBUG_PACKET_CONTENTS + +/* Parser (mostly) copied from dvdsub.c */ + +#define PARSE_BUF_SIZE (65536) + + +/* parser definition */ +typedef struct DVBSubParseContext { + uint8_t *packet_buf; + int packet_start; + int packet_index; + int in_packet; +} DVBSubParseContext; + +static av_cold int dvbsub_parse_init(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + pc->packet_buf = av_malloc(PARSE_BUF_SIZE); + + return 0; +} + +static int dvbsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVBSubParseContext *pc = s->priv_data; + uint8_t *p, *p_end; + int len, buf_pos = 0; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n", + s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); +#endif + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + for (i=0; i < buf_size; i++) + { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + *poutbuf = NULL; + *poutbuf_size = 0; + + s->fetch_timestamp = 1; + + if (s->last_pts != s->pts && s->pts != AV_NOPTS_VALUE) /* Start of a new packet */ + { + if (pc->packet_index != pc->packet_start) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n", + pc->packet_index - pc->packet_start); +#endif + } + + pc->packet_start = 0; + pc->packet_index = 0; + + if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Bad packet header\n"); +#endif + return -1; + } + + buf_pos = 2; + + pc->in_packet = 1; + } else { + if (pc->packet_start != 0) + { + if (pc->packet_index != pc->packet_start) + { + memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, + pc->packet_index - pc->packet_start); + + pc->packet_index -= pc->packet_start; + pc->packet_start = 0; + } else { + pc->packet_start = 0; + pc->packet_index = 0; + } + } + } + + if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) + return -1; + +/* if not currently in a packet, discard data */ + if (pc->in_packet == 0) + return buf_size; + + memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); + pc->packet_index += buf_size - buf_pos; + + p = pc->packet_buf; + p_end = pc->packet_buf + pc->packet_index; + + while (p < p_end) + { + if (*p == 0x0f) + { + if (p + 6 <= p_end) + { + len = AV_RB16(p + 4); + + if (p + len + 6 <= p_end) + { + *poutbuf_size += len + 6; + + p += len + 6; + } else + break; + } else + break; + } else if (*p == 0xff) { + if (p + 1 < p_end) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); +#endif + } + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } else { + av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); + + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } + } + + if (*poutbuf_size > 0) + { + *poutbuf = pc->packet_buf; + pc->packet_start = *poutbuf_size; + } + + if (s->pts == AV_NOPTS_VALUE) + s->pts = s->last_pts; + + return buf_size; +} + +static av_cold void dvbsub_parse_close(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + av_freep(&pc->packet_buf); +} + +AVCodecParser dvbsub_parser = { + { CODEC_ID_DVB_SUBTITLE }, + sizeof(DVBSubParseContext), + dvbsub_parse_init, + dvbsub_parse, + dvbsub_parse_close, +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvbsubdec.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsubdec.c new file mode 100644 index 0000000000..3f47c1b4d6 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvbsubdec.c @@ -0,0 +1,1434 @@ +/* + * DVB subtitle decoding for ffmpeg + * Copyright (c) 2005 Ian Caulfield. + * + * 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 + */ +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" +#include "colorspace.h" + +//#define DEBUG +//#define DEBUG_PACKET_CONTENTS +//#define DEBUG_SAVE_IMAGES + +#define DVBSUB_PAGE_SEGMENT 0x10 +#define DVBSUB_REGION_SEGMENT 0x11 +#define DVBSUB_CLUT_SEGMENT 0x12 +#define DVBSUB_OBJECT_SEGMENT 0x13 +#define DVBSUB_DISPLAY_SEGMENT 0x80 + +#define cm (ff_cropTbl + MAX_NEG_CROP) + +#ifdef DEBUG_SAVE_IMAGES +#undef fprintf +#if 0 +static void png_save(const char *filename, uint8_t *bitmap, int w, int h, + uint32_t *rgba_palette) +{ + int x, y, v; + FILE *f; + char fname[40], fname2[40]; + char command[1024]; + + snprintf(fname, 40, "%s.ppm", filename); + + f = fopen(fname, "w"); + if (!f) { + perror(fname); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); + + + snprintf(fname2, 40, "%s-a.pgm", filename); + + f = fopen(fname2, "w"); + if (!f) { + perror(fname2); + exit(1); + } + fprintf(f, "P5\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 24) & 0xff, f); + } + } + fclose(f); + + snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + system(command); + + snprintf(command, 1024, "rm %s %s", fname, fname2); + system(command); +} +#endif + +static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) +{ + int x, y, v; + FILE *f; + char fname[40], fname2[40]; + char command[1024]; + + snprintf(fname, sizeof(fname), "%s.ppm", filename); + + f = fopen(fname, "w"); + if (!f) { + perror(fname); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); + + + snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename); + + f = fopen(fname2, "w"); + if (!f) { + perror(fname2); + exit(1); + } + fprintf(f, "P5\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 24) & 0xff, f); + } + } + fclose(f); + + snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + system(command); + + snprintf(command, sizeof(command), "rm %s %s", fname, fname2); + system(command); +} +#endif + +#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +typedef struct DVBSubCLUT { + int id; + + uint32_t clut4[4]; + uint32_t clut16[16]; + uint32_t clut256[256]; + + struct DVBSubCLUT *next; +} DVBSubCLUT; + +static DVBSubCLUT default_clut; + +typedef struct DVBSubObjectDisplay { + int object_id; + int region_id; + + int x_pos; + int y_pos; + + int fgcolor; + int bgcolor; + + struct DVBSubObjectDisplay *region_list_next; + struct DVBSubObjectDisplay *object_list_next; +} DVBSubObjectDisplay; + +typedef struct DVBSubObject { + int id; + + int type; + + DVBSubObjectDisplay *display_list; + + struct DVBSubObject *next; +} DVBSubObject; + +typedef struct DVBSubRegionDisplay { + int region_id; + + int x_pos; + int y_pos; + + struct DVBSubRegionDisplay *next; +} DVBSubRegionDisplay; + +typedef struct DVBSubRegion { + int id; + + int width; + int height; + int depth; + + int clut; + int bgcolor; + + uint8_t *pbuf; + int buf_size; + + DVBSubObjectDisplay *display_list; + + struct DVBSubRegion *next; +} DVBSubRegion; + +typedef struct DVBSubContext { + int composition_id; + int ancillary_id; + + int time_out; + DVBSubRegion *region_list; + DVBSubCLUT *clut_list; + DVBSubObject *object_list; + + int display_list_size; + DVBSubRegionDisplay *display_list; +} DVBSubContext; + + +static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) +{ + DVBSubObject *ptr = ctx->object_list; + + while (ptr && ptr->id != object_id) { + ptr = ptr->next; + } + + return ptr; +} + +static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id) +{ + DVBSubCLUT *ptr = ctx->clut_list; + + while (ptr && ptr->id != clut_id) { + ptr = ptr->next; + } + + return ptr; +} + +static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id) +{ + DVBSubRegion *ptr = ctx->region_list; + + while (ptr && ptr->id != region_id) { + ptr = ptr->next; + } + + return ptr; +} + +static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) +{ + DVBSubObject *object, *obj2, **obj2_ptr; + DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr; + + while (region->display_list) { + display = region->display_list; + + object = get_object(ctx, display->object_id); + + if (object) { + obj_disp_ptr = &object->display_list; + obj_disp = *obj_disp_ptr; + + while (obj_disp && obj_disp != display) { + obj_disp_ptr = &obj_disp->object_list_next; + obj_disp = *obj_disp_ptr; + } + + if (obj_disp) { + *obj_disp_ptr = obj_disp->object_list_next; + + if (!object->display_list) { + obj2_ptr = &ctx->object_list; + obj2 = *obj2_ptr; + + while (obj2 != object) { + assert(obj2); + obj2_ptr = &obj2->next; + obj2 = *obj2_ptr; + } + + *obj2_ptr = obj2->next; + + av_free(obj2); + } + } + } + + region->display_list = display->region_list_next; + + av_free(display); + } + +} + +static void delete_state(DVBSubContext *ctx) +{ + DVBSubRegion *region; + DVBSubCLUT *clut; + + while (ctx->region_list) { + region = ctx->region_list; + + ctx->region_list = region->next; + + delete_region_display_list(ctx, region); + if (region->pbuf) + av_free(region->pbuf); + + av_free(region); + } + + while (ctx->clut_list) { + clut = ctx->clut_list; + + ctx->clut_list = clut->next; + + av_free(clut); + } + + /* Should already be null */ + if (ctx->object_list) + av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); +} + +static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) +{ + int i, r, g, b, a = 0; + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + memset(avctx->priv_data, 0, sizeof(DVBSubContext)); + + ctx->composition_id = avctx->sub_id & 0xffff; + ctx->ancillary_id = avctx->sub_id >> 16; + + default_clut.id = -1; + default_clut.next = NULL; + + default_clut.clut4[0] = RGBA( 0, 0, 0, 0); + default_clut.clut4[1] = RGBA(255, 255, 255, 255); + default_clut.clut4[2] = RGBA( 0, 0, 0, 255); + default_clut.clut4[3] = RGBA(127, 127, 127, 255); + + default_clut.clut16[0] = RGBA( 0, 0, 0, 0); + for (i = 1; i < 16; i++) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + } else { + r = (i & 1) ? 127 : 0; + g = (i & 2) ? 127 : 0; + b = (i & 4) ? 127 : 0; + } + default_clut.clut16[i] = RGBA(r, g, b, 255); + } + + default_clut.clut256[0] = RGBA( 0, 0, 0, 0); + for (i = 1; i < 256; i++) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + a = 63; + } else { + switch (i & 0x88) { + case 0x00: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 255; + break; + case 0x08: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 127; + break; + case 0x80: + r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + case 0x88: + r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + } + } + default_clut.clut256[i] = RGBA(r, g, b, a); + } + + return 0; +} + +static av_cold int dvbsub_close_decoder(AVCodecContext *avctx) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + DVBSubRegionDisplay *display; + + delete_state(ctx); + + while (ctx->display_list) { + display = ctx->display_list; + ctx->display_list = display->next; + + av_free(display); + } + + return 0; +} + +static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, + const uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + GetBitContext gb; + + int bits; + int run_length; + int pixels_read = 0; + + init_get_bits(&gb, *srcbuf, buf_size << 8); + + while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { + bits = get_bits(&gb, 2); + + if (bits) { + if (non_mod != 1 || bits != 1) { + if (map_table) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = get_bits1(&gb); + if (bits == 1) { + run_length = get_bits(&gb, 3) + 3; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else { + bits = get_bits1(&gb); + if (bits == 0) { + bits = get_bits(&gb, 2); + if (bits == 2) { + run_length = get_bits(&gb, 4) + 12; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 3) { + run_length = get_bits(&gb, 8) + 29; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 1) { + pixels_read += 2; + if (map_table) + bits = map_table[0]; + else + bits = 0; + if (pixels_read <= dbuf_len) { + *destbuf++ = bits; + *destbuf++ = bits; + } + } else { + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + return pixels_read; + } + } else { + if (map_table) + bits = map_table[0]; + else + bits = 0; + *destbuf++ = bits; + pixels_read++; + } + } + } + } + + if (get_bits(&gb, 6)) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + + return pixels_read; +} + +static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, + const uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + GetBitContext gb; + + int bits; + int run_length; + int pixels_read = 0; + + init_get_bits(&gb, *srcbuf, buf_size << 8); + + while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { + bits = get_bits(&gb, 4); + + if (bits) { + if (non_mod != 1 || bits != 1) { + if (map_table) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = get_bits1(&gb); + if (bits == 0) { + run_length = get_bits(&gb, 3); + + if (run_length == 0) { + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + return pixels_read; + } + + run_length += 2; + + if (map_table) + bits = map_table[0]; + else + bits = 0; + + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } else { + bits = get_bits1(&gb); + if (bits == 0) { + run_length = get_bits(&gb, 2) + 4; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else { + bits = get_bits(&gb, 2); + if (bits == 2) { + run_length = get_bits(&gb, 4) + 9; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 3) { + run_length = get_bits(&gb, 8) + 25; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 1) { + pixels_read += 2; + if (map_table) + bits = map_table[0]; + else + bits = 0; + if (pixels_read <= dbuf_len) { + *destbuf++ = bits; + *destbuf++ = bits; + } + } else { + if (map_table) + bits = map_table[0]; + else + bits = 0; + *destbuf++ = bits; + pixels_read ++; + } + } + } + } + } + + if (get_bits(&gb, 8)) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + + return pixels_read; +} + +static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, + const uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + const uint8_t *sbuf_end = (*srcbuf) + buf_size; + int bits; + int run_length; + int pixels_read = 0; + + while (*srcbuf < sbuf_end && pixels_read < dbuf_len) { + bits = *(*srcbuf)++; + + if (bits) { + if (non_mod != 1 || bits != 1) { + if (map_table) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = *(*srcbuf)++; + run_length = bits & 0x7f; + if ((bits & 0x80) == 0) { + if (run_length == 0) { + return pixels_read; + } + + if (map_table) + bits = map_table[0]; + else + bits = 0; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } else { + bits = *(*srcbuf)++; + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + if (map_table) + bits = map_table[bits]; + else while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } + } + + if (*(*srcbuf)++) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + return pixels_read; +} + + + +static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, + const uint8_t *buf, int buf_size, int top_bottom, int non_mod) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + DVBSubRegion *region = get_region(ctx, display->region_id); + const uint8_t *buf_end = buf + buf_size; + uint8_t *pbuf; + int x_pos, y_pos; + int i; + + uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf}; + uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff}; + uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + uint8_t *map_table; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size, + top_bottom ? "bottom" : "top"); +#endif + +#ifdef DEBUG_PACKET_CONTENTS + for (i = 0; i < buf_size; i++) { + if (i % 16 == 0) + av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i); + + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + if (region == 0) + return; + + pbuf = region->pbuf; + + x_pos = display->x_pos; + y_pos = display->y_pos; + + if ((y_pos & 1) != top_bottom) + y_pos++; + + while (buf < buf_end) { + if (x_pos > region->width || y_pos > region->height) { + av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n"); + return; + } + + switch (*buf++) { + case 0x10: + if (region->depth == 8) + map_table = map2to8; + else if (region->depth == 4) + map_table = map2to4; + else + map_table = NULL; + + x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, map_table); + break; + case 0x11: + if (region->depth < 4) { + av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth); + return; + } + + if (region->depth == 8) + map_table = map4to8; + else + map_table = NULL; + + x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, map_table); + break; + case 0x12: + if (region->depth < 8) { + av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth); + return; + } + + x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, NULL); + break; + + case 0x20: + map2to4[0] = (*buf) >> 4; + map2to4[1] = (*buf++) & 0xf; + map2to4[2] = (*buf) >> 4; + map2to4[3] = (*buf++) & 0xf; + break; + case 0x21: + for (i = 0; i < 4; i++) + map2to8[i] = *buf++; + break; + case 0x22: + for (i = 0; i < 16; i++) + map4to8[i] = *buf++; + break; + + case 0xf0: + x_pos = display->x_pos; + y_pos += 2; + break; + default: + av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1)); + } + } + +} + +static void dvbsub_parse_object_segment(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + const uint8_t *buf_end = buf + buf_size; + const uint8_t *block; + int object_id; + DVBSubObject *object; + DVBSubObjectDisplay *display; + int top_field_len, bottom_field_len; + + int coding_method, non_modifying_color; + + object_id = AV_RB16(buf); + buf += 2; + + object = get_object(ctx, object_id); + + if (!object) + return; + + coding_method = ((*buf) >> 2) & 3; + non_modifying_color = ((*buf++) >> 1) & 1; + + if (coding_method == 0) { + top_field_len = AV_RB16(buf); + buf += 2; + bottom_field_len = AV_RB16(buf); + buf += 2; + + if (buf + top_field_len + bottom_field_len > buf_end) { + av_log(avctx, AV_LOG_ERROR, "Field data size too large\n"); + return; + } + + for (display = object->display_list; display; display = display->object_list_next) { + block = buf; + + dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, + non_modifying_color); + + if (bottom_field_len > 0) + block = buf + top_field_len; + else + bottom_field_len = top_field_len; + + dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1, + non_modifying_color); + } + +/* } else if (coding_method == 1) {*/ + + } else { + av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method); + } + +} + +static void dvbsub_parse_clut_segment(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + const uint8_t *buf_end = buf + buf_size; + int clut_id; + DVBSubCLUT *clut; + int entry_id, depth , full_range; + int y, cr, cb, alpha; + int r, g, b, r_add, g_add, b_add; + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n"); + + for (i=0; i < buf_size; i++) { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + clut_id = *buf++; + buf += 1; + + clut = get_clut(ctx, clut_id); + + if (!clut) { + clut = av_malloc(sizeof(DVBSubCLUT)); + + memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); + + clut->id = clut_id; + + clut->next = ctx->clut_list; + ctx->clut_list = clut; + } + + while (buf + 4 < buf_end) { + entry_id = *buf++; + + depth = (*buf) & 0xe0; + + if (depth == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + return; + } + + full_range = (*buf++) & 1; + + if (full_range) { + y = *buf++; + cr = *buf++; + cb = *buf++; + alpha = *buf++; + } else { + y = buf[0] & 0xfc; + cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; + cb = (buf[1] << 2) & 0xf0; + alpha = (buf[1] << 6) & 0xc0; + + buf += 2; + } + + if (y == 0) + alpha = 0xff; + + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); +#endif + + if (depth & 0x80) + clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); + if (depth & 0x40) + clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); + if (depth & 0x20) + clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); + } +} + + +static void dvbsub_parse_region_segment(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + const uint8_t *buf_end = buf + buf_size; + int region_id, object_id; + DVBSubRegion *region; + DVBSubObject *object; + DVBSubObjectDisplay *display; + int fill; + + if (buf_size < 10) + return; + + region_id = *buf++; + + region = get_region(ctx, region_id); + + if (!region) { + region = av_mallocz(sizeof(DVBSubRegion)); + + region->id = region_id; + + region->next = ctx->region_list; + ctx->region_list = region; + } + + fill = ((*buf++) >> 3) & 1; + + region->width = AV_RB16(buf); + buf += 2; + region->height = AV_RB16(buf); + buf += 2; + + if (region->width * region->height != region->buf_size) { + if (region->pbuf) + av_free(region->pbuf); + + region->buf_size = region->width * region->height; + + region->pbuf = av_malloc(region->buf_size); + + fill = 1; + } + + region->depth = 1 << (((*buf++) >> 2) & 7); + if(region->depth<2 || region->depth>8){ + av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); + region->depth= 4; + } + region->clut = *buf++; + + if (region->depth == 8) + region->bgcolor = *buf++; + else { + buf += 1; + + if (region->depth == 4) + region->bgcolor = (((*buf++) >> 4) & 15); + else + region->bgcolor = (((*buf++) >> 2) & 3); + } + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height); +#endif + + if (fill) { + memset(region->pbuf, region->bgcolor, region->buf_size); +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolor); +#endif + } + + delete_region_display_list(ctx, region); + + while (buf + 5 < buf_end) { + object_id = AV_RB16(buf); + buf += 2; + + object = get_object(ctx, object_id); + + if (!object) { + object = av_mallocz(sizeof(DVBSubObject)); + + object->id = object_id; + object->next = ctx->object_list; + ctx->object_list = object; + } + + object->type = (*buf) >> 6; + + display = av_mallocz(sizeof(DVBSubObjectDisplay)); + + display->object_id = object_id; + display->region_id = region_id; + + display->x_pos = AV_RB16(buf) & 0xfff; + buf += 2; + display->y_pos = AV_RB16(buf) & 0xfff; + buf += 2; + + if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { + display->fgcolor = *buf++; + display->bgcolor = *buf++; + } + + display->region_list_next = region->display_list; + region->display_list = display; + + display->object_list_next = object->display_list; + object->display_list = display; + } +} + +static void dvbsub_parse_page_segment(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + DVBSubRegionDisplay *display; + DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; + + const uint8_t *buf_end = buf + buf_size; + int region_id; + int page_state; + + if (buf_size < 1) + return; + + ctx->time_out = *buf++; + page_state = ((*buf++) >> 2) & 3; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state); +#endif + + if (page_state == 2) { + delete_state(ctx); + } + + tmp_display_list = ctx->display_list; + ctx->display_list = NULL; + ctx->display_list_size = 0; + + while (buf + 5 < buf_end) { + region_id = *buf++; + buf += 1; + + display = tmp_display_list; + tmp_ptr = &tmp_display_list; + + while (display && display->region_id != region_id) { + tmp_ptr = &display->next; + display = display->next; + } + + if (!display) + display = av_mallocz(sizeof(DVBSubRegionDisplay)); + + display->region_id = region_id; + + display->x_pos = AV_RB16(buf); + buf += 2; + display->y_pos = AV_RB16(buf); + buf += 2; + + *tmp_ptr = display->next; + + display->next = ctx->display_list; + ctx->display_list = display; + ctx->display_list_size++; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos); +#endif + } + + while (tmp_display_list) { + display = tmp_display_list; + + tmp_display_list = display->next; + + av_free(display); + } + +} + + +#ifdef DEBUG_SAVE_IMAGES +static void save_display_set(DVBSubContext *ctx) +{ + DVBSubRegion *region; + DVBSubRegionDisplay *display; + DVBSubCLUT *clut; + uint32_t *clut_table; + int x_pos, y_pos, width, height; + int x, y, y_off, x_off; + uint32_t *pbuf; + char filename[32]; + static int fileno_index = 0; + + x_pos = -1; + y_pos = -1; + width = 0; + height = 0; + + for (display = ctx->display_list; display; display = display->next) { + region = get_region(ctx, display->region_id); + + if (x_pos == -1) { + x_pos = display->x_pos; + y_pos = display->y_pos; + width = region->width; + height = region->height; + } else { + if (display->x_pos < x_pos) { + width += (x_pos - display->x_pos); + x_pos = display->x_pos; + } + + if (display->y_pos < y_pos) { + height += (y_pos - display->y_pos); + y_pos = display->y_pos; + } + + if (display->x_pos + region->width > x_pos + width) { + width = display->x_pos + region->width - x_pos; + } + + if (display->y_pos + region->height > y_pos + height) { + height = display->y_pos + region->height - y_pos; + } + } + } + + if (x_pos >= 0) { + + pbuf = av_malloc(width * height * 4); + + for (display = ctx->display_list; display; display = display->next) { + region = get_region(ctx, display->region_id); + + x_off = display->x_pos - x_pos; + y_off = display->y_pos - y_pos; + + clut = get_clut(ctx, region->clut); + + if (clut == 0) + clut = &default_clut; + + switch (region->depth) { + case 2: + clut_table = clut->clut4; + break; + case 8: + clut_table = clut->clut256; + break; + case 4: + default: + clut_table = clut->clut16; + break; + } + + for (y = 0; y < region->height; y++) { + for (x = 0; x < region->width; x++) { + pbuf[((y + y_off) * width) + x_off + x] = + clut_table[region->pbuf[y * region->width + x]]; + } + } + + } + + snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index); + + png_save2(filename, pbuf, width, height); + + av_free(pbuf); + } + + fileno_index++; +} +#endif + +static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, + int buf_size, AVSubtitle *sub) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + DVBSubRegion *region; + DVBSubRegionDisplay *display; + AVSubtitleRect *rect; + DVBSubCLUT *clut; + uint32_t *clut_table; + int i; + + sub->rects = NULL; + sub->start_display_time = 0; + sub->end_display_time = ctx->time_out * 1000; + sub->format = 0; + + sub->num_rects = ctx->display_list_size; + + if (sub->num_rects > 0) + sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); + + i = 0; + + for (display = ctx->display_list; display; display = display->next) { + region = get_region(ctx, display->region_id); + rect = &sub->rects[i]; + + if (!region) + continue; + + rect->x = display->x_pos; + rect->y = display->y_pos; + rect->w = region->width; + rect->h = region->height; + rect->nb_colors = 16; + rect->linesize = region->width; + + clut = get_clut(ctx, region->clut); + + if (!clut) + clut = &default_clut; + + switch (region->depth) { + case 2: + clut_table = clut->clut4; + break; + case 8: + clut_table = clut->clut256; + break; + case 4: + default: + clut_table = clut->clut16; + break; + } + + rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t)); + memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t)); + + rect->bitmap = av_malloc(region->buf_size); + memcpy(rect->bitmap, region->pbuf, region->buf_size); + + i++; + } + + sub->num_rects = i; + +#ifdef DEBUG_SAVE_IMAGES + save_display_set(ctx); +#endif + + return 1; +} + +static int dvbsub_decode(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + AVSubtitle *sub = (AVSubtitle*) data; + const uint8_t *p, *p_end; + int segment_type; + int page_id; + int segment_length; + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n"); + + for (i=0; i < buf_size; i++) { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + if (buf_size <= 2) + return -1; + + p = buf; + p_end = buf + buf_size; + + while (p < p_end && *p == 0x0f) { + p += 1; + segment_type = *p++; + page_id = AV_RB16(p); + p += 2; + segment_length = AV_RB16(p); + p += 2; + + if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) { + switch (segment_type) { + case DVBSUB_PAGE_SEGMENT: + dvbsub_parse_page_segment(avctx, p, segment_length); + break; + case DVBSUB_REGION_SEGMENT: + dvbsub_parse_region_segment(avctx, p, segment_length); + break; + case DVBSUB_CLUT_SEGMENT: + dvbsub_parse_clut_segment(avctx, p, segment_length); + break; + case DVBSUB_OBJECT_SEGMENT: + dvbsub_parse_object_segment(avctx, p, segment_length); + break; + case DVBSUB_DISPLAY_SEGMENT: + *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub); + break; + default: +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n", + segment_type, page_id, segment_length); +#endif + break; + } + } + + p += segment_length; + } + + if (p != p_end) { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); +#endif + return -1; + } + + return buf_size; +} + + +AVCodec dvbsub_decoder = { + "dvbsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVB_SUBTITLE, + sizeof(DVBSubContext), + dvbsub_init_decoder, + NULL, + dvbsub_close_decoder, + dvbsub_decode, + .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvdata.h b/src/add-ons/media/plugins/avcodec/libavcodec/dvdata.h index e6e0986ba5..d699a6649e 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/dvdata.h +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvdata.h @@ -2,19 +2,21 @@ * Constants for DV codec * Copyright (c) 2002 Fabrice Bellard. * - * This library is free software; you can redistribute it and/or + * 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -22,8 +24,14 @@ * Constants for DV codec. */ -/* - * DVprofile is used to express the differences between various +#ifndef FFMPEG_DVDATA_H +#define FFMPEG_DVDATA_H + +#include "rational.h" +#include "avcodec.h" + +/* + * DVprofile is used to express the differences between various * DV flavors. For now it's primarily used for differentiating * 525/60 and 625/50, but the plans are to use it for various * DV specs as well (e.g. SMPTE314M vs. IEC 61834). @@ -31,8 +39,9 @@ typedef struct DVprofile { int dsf; /* value of the dsf in the DV header */ int frame_size; /* total size of one frame in bytes */ - int difseg_size; /* number of DIF segments */ - int frame_rate; + int difseg_size; /* number of DIF segments per DIF channel */ + int n_difchan; /* number of DIF channels per frame */ + int frame_rate; int frame_rate_base; int ltc_divisor; /* FPS from the LTS standpoint */ int height; /* picture height in pixels */ @@ -40,21 +49,22 @@ typedef struct DVprofile { AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ const uint16_t *video_place; /* positions of all DV macro blocks */ enum PixelFormat pix_fmt; /* picture pixel format */ - + int bpm; /* blocks per macroblock */ + const uint8_t *block_sizes; /* AC block sizes, in bits */ int audio_stride; /* size of audio_shuffle table */ int audio_min_samples[3];/* min ammount of audio samples */ /* for 48Khz, 44.1Khz and 32Khz */ int audio_samples_dist[5];/* how many samples are supposed to be */ /* in each frame in a 5 frames window */ - const uint16_t (*audio_shuffle)[9]; /* PCM shuffling table */ + const uint8_t (*audio_shuffle)[9]; /* PCM shuffling table */ } DVprofile; #define NB_DV_VLC 409 -/* +/* * There's a catch about the following three tables: the mapping they establish * between (run, level) and vlc is not 1-1. So you have to watch out for that - * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. + * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. */ static const uint16_t dv_vlc_bits[409] = { 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016, @@ -218,7 +228,7 @@ static const uint8_t dv_vlc_run[409] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, +127, }; static const uint8_t dv_vlc_level[409] = { @@ -277,56 +287,35 @@ static const uint8_t dv_vlc_level[409] = { }; /* unquant tables (not used directly) */ -static const uint8_t dv_88_areas[64] = { - 0,0,0,1,1,1,2,2, - 0,0,1,1,1,2,2,2, - 0,1,1,1,2,2,2,3, - 1,1,1,2,2,2,3,3, - 1,1,2,2,2,3,3,3, - 1,2,2,2,3,3,3,3, - 2,2,2,3,3,3,3,3, - 2,2,3,3,3,3,3,3, -}; - -static const uint8_t dv_248_areas[64] = { - 0,0,1,1,1,2,2,3, - 0,0,1,1,2,2,2,3, - 0,1,1,2,2,2,3,3, - 0,1,1,2,2,2,3,3, - 1,1,2,2,2,3,3,3, - 1,1,2,2,2,3,3,3, - 1,2,2,2,3,3,3,3, - 1,2,2,3,3,3,3,3, -}; - static const uint8_t dv_quant_shifts[22][4] = { - { 3,3,4,4 }, - { 3,3,4,4 }, - { 2,3,3,4 }, + { 3,3,4,4 }, + { 3,3,4,4 }, { 2,3,3,4 }, - { 2,2,3,3 }, - { 2,2,3,3 }, - { 1,2,2,3 }, - { 1,2,2,3 }, - { 1,1,2,2 }, - { 1,1,2,2 }, - { 0,1,1,2 }, - { 0,1,1,2 }, - { 0,0,1,1 }, + { 2,3,3,4 }, + { 2,2,3,3 }, + { 2,2,3,3 }, + { 1,2,2,3 }, + { 1,2,2,3 }, + { 1,1,2,2 }, + { 1,1,2,2 }, + { 0,1,1,2 }, + { 0,1,1,2 }, { 0,0,1,1 }, - { 0,0,0,1 }, - { 0,0,0,0 }, - { 0,0,0,0 }, - { 0,0,0,0 }, - { 0,0,0,0 }, - { 0,0,0,0 }, - { 0,0,0,0 }, + { 0,0,1,1 }, + { 0,0,0,1 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, { 0,0,0,0 }, }; static const uint8_t dv_quant_offset[4] = { 6, 3, 0, 1 }; +static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 }; -/* NOTE: I prefer hardcoding the positionning of dv blocks, it is +/* NOTE: I prefer hardcoding the positioning of dv blocks, it is simpler :-) */ static const uint16_t dv_place_420[1620] = { @@ -657,329 +646,329 @@ static const uint16_t dv_place_420[1620] = { }; static const uint16_t dv_place_411P[1620] = { - 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, - 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, - 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, - 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, - 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, - 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, - 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, - 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, - 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, - 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, - 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, - 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, - 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, - 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, - 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, - 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, - 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, - 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, - 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, - 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, - 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, - 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, - 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, - 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, - 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, - 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, - 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, - 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, - 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, - 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, - 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, - 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, - 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, - 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, - 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, - 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, - 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, - 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, - 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, - 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, - 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, - 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, - 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, - 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, - 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, - 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, - 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, - 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, - 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, - 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, - 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, - 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, - 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, - 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, - 0x1824, 0x3310, 0x3f34, 0x0c00, 0x2448, - 0x1924, 0x3410, 0x4034, 0x0d00, 0x2548, - 0x1a24, 0x3510, 0x4134, 0x0e00, 0x2648, - 0x1b24, 0x3514, 0x4138, 0x0f00, 0x2748, - 0x1c24, 0x3414, 0x4038, 0x1000, 0x2848, - 0x1d24, 0x3314, 0x3f38, 0x1100, 0x2948, - 0x1d28, 0x3214, 0x3e38, 0x1104, 0x294c, - 0x1c28, 0x3114, 0x3d38, 0x1004, 0x284c, - 0x1b28, 0x3014, 0x3c38, 0x0f04, 0x274c, - 0x1a28, 0x3018, 0x3c3c, 0x0e04, 0x264c, - 0x1928, 0x3118, 0x3d3c, 0x0d04, 0x254c, - 0x1828, 0x3218, 0x3e3c, 0x0c04, 0x244c, - 0x182c, 0x3318, 0x3f3c, 0x0c08, 0x2450, - 0x192c, 0x3418, 0x403c, 0x0d08, 0x2550, - 0x1a2c, 0x3518, 0x413c, 0x0e08, 0x2650, - 0x1b2c, 0x351c, 0x4140, 0x0f08, 0x2750, - 0x1c2c, 0x341c, 0x4040, 0x1008, 0x2850, - 0x1d2c, 0x331c, 0x3f40, 0x1108, 0x2950, - 0x1d30, 0x321c, 0x3e40, 0x110c, 0x2954, - 0x1c30, 0x311c, 0x3d40, 0x100c, 0x2854, - 0x1b30, 0x301c, 0x3c40, 0x0f0c, 0x2754, - 0x1a30, 0x3020, 0x3c44, 0x0e0c, 0x2654, - 0x1930, 0x3120, 0x3d44, 0x0d0c, 0x2554, - 0x1830, 0x3220, 0x3e44, 0x0c0c, 0x2454, - 0x1834, 0x3320, 0x3f44, 0x0c10, 0x2458, - 0x1934, 0x3420, 0x4044, 0x0d10, 0x2658, - 0x1a34, 0x3520, 0x4144, 0x0e10, 0x2858, - 0x1e24, 0x3910, 0x4534, 0x1200, 0x2a48, - 0x1f24, 0x3a10, 0x4634, 0x1300, 0x2b48, - 0x2024, 0x3b10, 0x4734, 0x1400, 0x2c48, - 0x2124, 0x3b14, 0x4738, 0x1500, 0x2d48, - 0x2224, 0x3a14, 0x4638, 0x1600, 0x2e48, - 0x2324, 0x3914, 0x4538, 0x1700, 0x2f48, - 0x2328, 0x3814, 0x4438, 0x1704, 0x2f4c, - 0x2228, 0x3714, 0x4338, 0x1604, 0x2e4c, - 0x2128, 0x3614, 0x4238, 0x1504, 0x2d4c, - 0x2028, 0x3618, 0x423c, 0x1404, 0x2c4c, - 0x1f28, 0x3718, 0x433c, 0x1304, 0x2b4c, - 0x1e28, 0x3818, 0x443c, 0x1204, 0x2a4c, - 0x1e2c, 0x3918, 0x453c, 0x1208, 0x2a50, - 0x1f2c, 0x3a18, 0x463c, 0x1308, 0x2b50, - 0x202c, 0x3b18, 0x473c, 0x1408, 0x2c50, - 0x212c, 0x3b1c, 0x4740, 0x1508, 0x2d50, - 0x222c, 0x3a1c, 0x4640, 0x1608, 0x2e50, - 0x232c, 0x391c, 0x4540, 0x1708, 0x2f50, - 0x2330, 0x381c, 0x4440, 0x170c, 0x2f54, - 0x2230, 0x371c, 0x4340, 0x160c, 0x2e54, - 0x2130, 0x361c, 0x4240, 0x150c, 0x2d54, - 0x2030, 0x3620, 0x4244, 0x140c, 0x2c54, - 0x1f30, 0x3720, 0x4344, 0x130c, 0x2b54, - 0x1e30, 0x3820, 0x4444, 0x120c, 0x2a54, - 0x1e34, 0x3920, 0x4544, 0x1210, 0x2a58, - 0x1f34, 0x3a20, 0x4644, 0x1310, 0x2c58, - 0x2034, 0x3b20, 0x4744, 0x1410, 0x2e58, - 0x2424, 0x3f10, 0x0334, 0x1800, 0x3048, - 0x2524, 0x4010, 0x0434, 0x1900, 0x3148, - 0x2624, 0x4110, 0x0534, 0x1a00, 0x3248, - 0x2724, 0x4114, 0x0538, 0x1b00, 0x3348, - 0x2824, 0x4014, 0x0438, 0x1c00, 0x3448, - 0x2924, 0x3f14, 0x0338, 0x1d00, 0x3548, - 0x2928, 0x3e14, 0x0238, 0x1d04, 0x354c, - 0x2828, 0x3d14, 0x0138, 0x1c04, 0x344c, - 0x2728, 0x3c14, 0x0038, 0x1b04, 0x334c, - 0x2628, 0x3c18, 0x003c, 0x1a04, 0x324c, - 0x2528, 0x3d18, 0x013c, 0x1904, 0x314c, - 0x2428, 0x3e18, 0x023c, 0x1804, 0x304c, - 0x242c, 0x3f18, 0x033c, 0x1808, 0x3050, - 0x252c, 0x4018, 0x043c, 0x1908, 0x3150, - 0x262c, 0x4118, 0x053c, 0x1a08, 0x3250, - 0x272c, 0x411c, 0x0540, 0x1b08, 0x3350, - 0x282c, 0x401c, 0x0440, 0x1c08, 0x3450, - 0x292c, 0x3f1c, 0x0340, 0x1d08, 0x3550, - 0x2930, 0x3e1c, 0x0240, 0x1d0c, 0x3554, - 0x2830, 0x3d1c, 0x0140, 0x1c0c, 0x3454, - 0x2730, 0x3c1c, 0x0040, 0x1b0c, 0x3354, - 0x2630, 0x3c20, 0x0044, 0x1a0c, 0x3254, - 0x2530, 0x3d20, 0x0144, 0x190c, 0x3154, - 0x2430, 0x3e20, 0x0244, 0x180c, 0x3054, - 0x2434, 0x3f20, 0x0344, 0x1810, 0x3058, - 0x2534, 0x4020, 0x0444, 0x1910, 0x3258, - 0x2634, 0x4120, 0x0544, 0x1a10, 0x3458, - 0x2a24, 0x4510, 0x0934, 0x1e00, 0x3648, - 0x2b24, 0x4610, 0x0a34, 0x1f00, 0x3748, - 0x2c24, 0x4710, 0x0b34, 0x2000, 0x3848, - 0x2d24, 0x4714, 0x0b38, 0x2100, 0x3948, - 0x2e24, 0x4614, 0x0a38, 0x2200, 0x3a48, - 0x2f24, 0x4514, 0x0938, 0x2300, 0x3b48, - 0x2f28, 0x4414, 0x0838, 0x2304, 0x3b4c, - 0x2e28, 0x4314, 0x0738, 0x2204, 0x3a4c, - 0x2d28, 0x4214, 0x0638, 0x2104, 0x394c, - 0x2c28, 0x4218, 0x063c, 0x2004, 0x384c, - 0x2b28, 0x4318, 0x073c, 0x1f04, 0x374c, - 0x2a28, 0x4418, 0x083c, 0x1e04, 0x364c, - 0x2a2c, 0x4518, 0x093c, 0x1e08, 0x3650, - 0x2b2c, 0x4618, 0x0a3c, 0x1f08, 0x3750, - 0x2c2c, 0x4718, 0x0b3c, 0x2008, 0x3850, - 0x2d2c, 0x471c, 0x0b40, 0x2108, 0x3950, - 0x2e2c, 0x461c, 0x0a40, 0x2208, 0x3a50, - 0x2f2c, 0x451c, 0x0940, 0x2308, 0x3b50, - 0x2f30, 0x441c, 0x0840, 0x230c, 0x3b54, - 0x2e30, 0x431c, 0x0740, 0x220c, 0x3a54, - 0x2d30, 0x421c, 0x0640, 0x210c, 0x3954, - 0x2c30, 0x4220, 0x0644, 0x200c, 0x3854, - 0x2b30, 0x4320, 0x0744, 0x1f0c, 0x3754, - 0x2a30, 0x4420, 0x0844, 0x1e0c, 0x3654, - 0x2a34, 0x4520, 0x0944, 0x1e10, 0x3658, - 0x2b34, 0x4620, 0x0a44, 0x1f10, 0x3858, - 0x2c34, 0x4720, 0x0b44, 0x2010, 0x3a58, - 0x3024, 0x0310, 0x0f34, 0x2400, 0x3c48, - 0x3124, 0x0410, 0x1034, 0x2500, 0x3d48, - 0x3224, 0x0510, 0x1134, 0x2600, 0x3e48, - 0x3324, 0x0514, 0x1138, 0x2700, 0x3f48, - 0x3424, 0x0414, 0x1038, 0x2800, 0x4048, - 0x3524, 0x0314, 0x0f38, 0x2900, 0x4148, - 0x3528, 0x0214, 0x0e38, 0x2904, 0x414c, - 0x3428, 0x0114, 0x0d38, 0x2804, 0x404c, - 0x3328, 0x0014, 0x0c38, 0x2704, 0x3f4c, - 0x3228, 0x0018, 0x0c3c, 0x2604, 0x3e4c, - 0x3128, 0x0118, 0x0d3c, 0x2504, 0x3d4c, - 0x3028, 0x0218, 0x0e3c, 0x2404, 0x3c4c, - 0x302c, 0x0318, 0x0f3c, 0x2408, 0x3c50, - 0x312c, 0x0418, 0x103c, 0x2508, 0x3d50, - 0x322c, 0x0518, 0x113c, 0x2608, 0x3e50, - 0x332c, 0x051c, 0x1140, 0x2708, 0x3f50, - 0x342c, 0x041c, 0x1040, 0x2808, 0x4050, - 0x352c, 0x031c, 0x0f40, 0x2908, 0x4150, - 0x3530, 0x021c, 0x0e40, 0x290c, 0x4154, - 0x3430, 0x011c, 0x0d40, 0x280c, 0x4054, - 0x3330, 0x001c, 0x0c40, 0x270c, 0x3f54, - 0x3230, 0x0020, 0x0c44, 0x260c, 0x3e54, - 0x3130, 0x0120, 0x0d44, 0x250c, 0x3d54, - 0x3030, 0x0220, 0x0e44, 0x240c, 0x3c54, - 0x3034, 0x0320, 0x0f44, 0x2410, 0x3c58, - 0x3134, 0x0420, 0x1044, 0x2510, 0x3e58, - 0x3234, 0x0520, 0x1144, 0x2610, 0x4058, - 0x3624, 0x0910, 0x1534, 0x2a00, 0x4248, - 0x3724, 0x0a10, 0x1634, 0x2b00, 0x4348, - 0x3824, 0x0b10, 0x1734, 0x2c00, 0x4448, - 0x3924, 0x0b14, 0x1738, 0x2d00, 0x4548, - 0x3a24, 0x0a14, 0x1638, 0x2e00, 0x4648, - 0x3b24, 0x0914, 0x1538, 0x2f00, 0x4748, - 0x3b28, 0x0814, 0x1438, 0x2f04, 0x474c, - 0x3a28, 0x0714, 0x1338, 0x2e04, 0x464c, - 0x3928, 0x0614, 0x1238, 0x2d04, 0x454c, - 0x3828, 0x0618, 0x123c, 0x2c04, 0x444c, - 0x3728, 0x0718, 0x133c, 0x2b04, 0x434c, - 0x3628, 0x0818, 0x143c, 0x2a04, 0x424c, - 0x362c, 0x0918, 0x153c, 0x2a08, 0x4250, - 0x372c, 0x0a18, 0x163c, 0x2b08, 0x4350, - 0x382c, 0x0b18, 0x173c, 0x2c08, 0x4450, - 0x392c, 0x0b1c, 0x1740, 0x2d08, 0x4550, - 0x3a2c, 0x0a1c, 0x1640, 0x2e08, 0x4650, - 0x3b2c, 0x091c, 0x1540, 0x2f08, 0x4750, - 0x3b30, 0x081c, 0x1440, 0x2f0c, 0x4754, - 0x3a30, 0x071c, 0x1340, 0x2e0c, 0x4654, - 0x3930, 0x061c, 0x1240, 0x2d0c, 0x4554, - 0x3830, 0x0620, 0x1244, 0x2c0c, 0x4454, - 0x3730, 0x0720, 0x1344, 0x2b0c, 0x4354, - 0x3630, 0x0820, 0x1444, 0x2a0c, 0x4254, - 0x3634, 0x0920, 0x1544, 0x2a10, 0x4258, - 0x3734, 0x0a20, 0x1644, 0x2b10, 0x4458, - 0x3834, 0x0b20, 0x1744, 0x2c10, 0x4658, - 0x3c24, 0x0f10, 0x1b34, 0x3000, 0x0048, - 0x3d24, 0x1010, 0x1c34, 0x3100, 0x0148, - 0x3e24, 0x1110, 0x1d34, 0x3200, 0x0248, - 0x3f24, 0x1114, 0x1d38, 0x3300, 0x0348, - 0x4024, 0x1014, 0x1c38, 0x3400, 0x0448, - 0x4124, 0x0f14, 0x1b38, 0x3500, 0x0548, - 0x4128, 0x0e14, 0x1a38, 0x3504, 0x054c, - 0x4028, 0x0d14, 0x1938, 0x3404, 0x044c, - 0x3f28, 0x0c14, 0x1838, 0x3304, 0x034c, - 0x3e28, 0x0c18, 0x183c, 0x3204, 0x024c, - 0x3d28, 0x0d18, 0x193c, 0x3104, 0x014c, - 0x3c28, 0x0e18, 0x1a3c, 0x3004, 0x004c, - 0x3c2c, 0x0f18, 0x1b3c, 0x3008, 0x0050, - 0x3d2c, 0x1018, 0x1c3c, 0x3108, 0x0150, - 0x3e2c, 0x1118, 0x1d3c, 0x3208, 0x0250, - 0x3f2c, 0x111c, 0x1d40, 0x3308, 0x0350, - 0x402c, 0x101c, 0x1c40, 0x3408, 0x0450, - 0x412c, 0x0f1c, 0x1b40, 0x3508, 0x0550, - 0x4130, 0x0e1c, 0x1a40, 0x350c, 0x0554, - 0x4030, 0x0d1c, 0x1940, 0x340c, 0x0454, - 0x3f30, 0x0c1c, 0x1840, 0x330c, 0x0354, - 0x3e30, 0x0c20, 0x1844, 0x320c, 0x0254, - 0x3d30, 0x0d20, 0x1944, 0x310c, 0x0154, - 0x3c30, 0x0e20, 0x1a44, 0x300c, 0x0054, - 0x3c34, 0x0f20, 0x1b44, 0x3010, 0x0058, - 0x3d34, 0x1020, 0x1c44, 0x3110, 0x0258, - 0x3e34, 0x1120, 0x1d44, 0x3210, 0x0458, - 0x4224, 0x1510, 0x2134, 0x3600, 0x0648, - 0x4324, 0x1610, 0x2234, 0x3700, 0x0748, - 0x4424, 0x1710, 0x2334, 0x3800, 0x0848, - 0x4524, 0x1714, 0x2338, 0x3900, 0x0948, - 0x4624, 0x1614, 0x2238, 0x3a00, 0x0a48, - 0x4724, 0x1514, 0x2138, 0x3b00, 0x0b48, - 0x4728, 0x1414, 0x2038, 0x3b04, 0x0b4c, - 0x4628, 0x1314, 0x1f38, 0x3a04, 0x0a4c, - 0x4528, 0x1214, 0x1e38, 0x3904, 0x094c, - 0x4428, 0x1218, 0x1e3c, 0x3804, 0x084c, - 0x4328, 0x1318, 0x1f3c, 0x3704, 0x074c, - 0x4228, 0x1418, 0x203c, 0x3604, 0x064c, - 0x422c, 0x1518, 0x213c, 0x3608, 0x0650, - 0x432c, 0x1618, 0x223c, 0x3708, 0x0750, - 0x442c, 0x1718, 0x233c, 0x3808, 0x0850, - 0x452c, 0x171c, 0x2340, 0x3908, 0x0950, - 0x462c, 0x161c, 0x2240, 0x3a08, 0x0a50, - 0x472c, 0x151c, 0x2140, 0x3b08, 0x0b50, - 0x4730, 0x141c, 0x2040, 0x3b0c, 0x0b54, - 0x4630, 0x131c, 0x1f40, 0x3a0c, 0x0a54, - 0x4530, 0x121c, 0x1e40, 0x390c, 0x0954, - 0x4430, 0x1220, 0x1e44, 0x380c, 0x0854, - 0x4330, 0x1320, 0x1f44, 0x370c, 0x0754, - 0x4230, 0x1420, 0x2044, 0x360c, 0x0654, - 0x4234, 0x1520, 0x2144, 0x3610, 0x0658, - 0x4334, 0x1620, 0x2244, 0x3710, 0x0858, - 0x4434, 0x1720, 0x2344, 0x3810, 0x0a58, - 0x0024, 0x1b10, 0x2734, 0x3c00, 0x0c48, - 0x0124, 0x1c10, 0x2834, 0x3d00, 0x0d48, - 0x0224, 0x1d10, 0x2934, 0x3e00, 0x0e48, - 0x0324, 0x1d14, 0x2938, 0x3f00, 0x0f48, - 0x0424, 0x1c14, 0x2838, 0x4000, 0x1048, - 0x0524, 0x1b14, 0x2738, 0x4100, 0x1148, - 0x0528, 0x1a14, 0x2638, 0x4104, 0x114c, - 0x0428, 0x1914, 0x2538, 0x4004, 0x104c, - 0x0328, 0x1814, 0x2438, 0x3f04, 0x0f4c, - 0x0228, 0x1818, 0x243c, 0x3e04, 0x0e4c, - 0x0128, 0x1918, 0x253c, 0x3d04, 0x0d4c, - 0x0028, 0x1a18, 0x263c, 0x3c04, 0x0c4c, - 0x002c, 0x1b18, 0x273c, 0x3c08, 0x0c50, - 0x012c, 0x1c18, 0x283c, 0x3d08, 0x0d50, - 0x022c, 0x1d18, 0x293c, 0x3e08, 0x0e50, - 0x032c, 0x1d1c, 0x2940, 0x3f08, 0x0f50, - 0x042c, 0x1c1c, 0x2840, 0x4008, 0x1050, - 0x052c, 0x1b1c, 0x2740, 0x4108, 0x1150, - 0x0530, 0x1a1c, 0x2640, 0x410c, 0x1154, - 0x0430, 0x191c, 0x2540, 0x400c, 0x1054, - 0x0330, 0x181c, 0x2440, 0x3f0c, 0x0f54, - 0x0230, 0x1820, 0x2444, 0x3e0c, 0x0e54, - 0x0130, 0x1920, 0x2544, 0x3d0c, 0x0d54, - 0x0030, 0x1a20, 0x2644, 0x3c0c, 0x0c54, - 0x0034, 0x1b20, 0x2744, 0x3c10, 0x0c58, - 0x0134, 0x1c20, 0x2844, 0x3d10, 0x0e58, - 0x0234, 0x1d20, 0x2944, 0x3e10, 0x1058, - 0x0624, 0x2110, 0x2d34, 0x4200, 0x1248, - 0x0724, 0x2210, 0x2e34, 0x4300, 0x1348, - 0x0824, 0x2310, 0x2f34, 0x4400, 0x1448, - 0x0924, 0x2314, 0x2f38, 0x4500, 0x1548, - 0x0a24, 0x2214, 0x2e38, 0x4600, 0x1648, - 0x0b24, 0x2114, 0x2d38, 0x4700, 0x1748, - 0x0b28, 0x2014, 0x2c38, 0x4704, 0x174c, - 0x0a28, 0x1f14, 0x2b38, 0x4604, 0x164c, - 0x0928, 0x1e14, 0x2a38, 0x4504, 0x154c, - 0x0828, 0x1e18, 0x2a3c, 0x4404, 0x144c, - 0x0728, 0x1f18, 0x2b3c, 0x4304, 0x134c, - 0x0628, 0x2018, 0x2c3c, 0x4204, 0x124c, - 0x062c, 0x2118, 0x2d3c, 0x4208, 0x1250, - 0x072c, 0x2218, 0x2e3c, 0x4308, 0x1350, - 0x082c, 0x2318, 0x2f3c, 0x4408, 0x1450, - 0x092c, 0x231c, 0x2f40, 0x4508, 0x1550, - 0x0a2c, 0x221c, 0x2e40, 0x4608, 0x1650, - 0x0b2c, 0x211c, 0x2d40, 0x4708, 0x1750, - 0x0b30, 0x201c, 0x2c40, 0x470c, 0x1754, - 0x0a30, 0x1f1c, 0x2b40, 0x460c, 0x1654, - 0x0930, 0x1e1c, 0x2a40, 0x450c, 0x1554, - 0x0830, 0x1e20, 0x2a44, 0x440c, 0x1454, - 0x0730, 0x1f20, 0x2b44, 0x430c, 0x1354, - 0x0630, 0x2020, 0x2c44, 0x420c, 0x1254, - 0x0634, 0x2120, 0x2d44, 0x4210, 0x1258, - 0x0734, 0x2220, 0x2e44, 0x4310, 0x1458, + 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, + 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, + 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, + 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, + 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, + 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, + 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, + 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, + 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, + 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, + 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, + 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, + 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, + 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, + 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, + 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, + 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, + 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, + 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, + 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, + 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, + 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, + 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, + 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, + 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, + 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, + 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, + 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, + 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, + 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, + 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, + 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, + 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, + 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, + 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, + 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, + 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, + 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, + 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, + 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, + 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, + 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, + 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, + 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, + 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, + 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, + 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, + 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, + 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, + 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, + 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, + 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, + 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, + 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, + 0x1824, 0x3310, 0x3f34, 0x0c00, 0x2448, + 0x1924, 0x3410, 0x4034, 0x0d00, 0x2548, + 0x1a24, 0x3510, 0x4134, 0x0e00, 0x2648, + 0x1b24, 0x3514, 0x4138, 0x0f00, 0x2748, + 0x1c24, 0x3414, 0x4038, 0x1000, 0x2848, + 0x1d24, 0x3314, 0x3f38, 0x1100, 0x2948, + 0x1d28, 0x3214, 0x3e38, 0x1104, 0x294c, + 0x1c28, 0x3114, 0x3d38, 0x1004, 0x284c, + 0x1b28, 0x3014, 0x3c38, 0x0f04, 0x274c, + 0x1a28, 0x3018, 0x3c3c, 0x0e04, 0x264c, + 0x1928, 0x3118, 0x3d3c, 0x0d04, 0x254c, + 0x1828, 0x3218, 0x3e3c, 0x0c04, 0x244c, + 0x182c, 0x3318, 0x3f3c, 0x0c08, 0x2450, + 0x192c, 0x3418, 0x403c, 0x0d08, 0x2550, + 0x1a2c, 0x3518, 0x413c, 0x0e08, 0x2650, + 0x1b2c, 0x351c, 0x4140, 0x0f08, 0x2750, + 0x1c2c, 0x341c, 0x4040, 0x1008, 0x2850, + 0x1d2c, 0x331c, 0x3f40, 0x1108, 0x2950, + 0x1d30, 0x321c, 0x3e40, 0x110c, 0x2954, + 0x1c30, 0x311c, 0x3d40, 0x100c, 0x2854, + 0x1b30, 0x301c, 0x3c40, 0x0f0c, 0x2754, + 0x1a30, 0x3020, 0x3c44, 0x0e0c, 0x2654, + 0x1930, 0x3120, 0x3d44, 0x0d0c, 0x2554, + 0x1830, 0x3220, 0x3e44, 0x0c0c, 0x2454, + 0x1834, 0x3320, 0x3f44, 0x0c10, 0x2458, + 0x1934, 0x3420, 0x4044, 0x0d10, 0x2658, + 0x1a34, 0x3520, 0x4144, 0x0e10, 0x2858, + 0x1e24, 0x3910, 0x4534, 0x1200, 0x2a48, + 0x1f24, 0x3a10, 0x4634, 0x1300, 0x2b48, + 0x2024, 0x3b10, 0x4734, 0x1400, 0x2c48, + 0x2124, 0x3b14, 0x4738, 0x1500, 0x2d48, + 0x2224, 0x3a14, 0x4638, 0x1600, 0x2e48, + 0x2324, 0x3914, 0x4538, 0x1700, 0x2f48, + 0x2328, 0x3814, 0x4438, 0x1704, 0x2f4c, + 0x2228, 0x3714, 0x4338, 0x1604, 0x2e4c, + 0x2128, 0x3614, 0x4238, 0x1504, 0x2d4c, + 0x2028, 0x3618, 0x423c, 0x1404, 0x2c4c, + 0x1f28, 0x3718, 0x433c, 0x1304, 0x2b4c, + 0x1e28, 0x3818, 0x443c, 0x1204, 0x2a4c, + 0x1e2c, 0x3918, 0x453c, 0x1208, 0x2a50, + 0x1f2c, 0x3a18, 0x463c, 0x1308, 0x2b50, + 0x202c, 0x3b18, 0x473c, 0x1408, 0x2c50, + 0x212c, 0x3b1c, 0x4740, 0x1508, 0x2d50, + 0x222c, 0x3a1c, 0x4640, 0x1608, 0x2e50, + 0x232c, 0x391c, 0x4540, 0x1708, 0x2f50, + 0x2330, 0x381c, 0x4440, 0x170c, 0x2f54, + 0x2230, 0x371c, 0x4340, 0x160c, 0x2e54, + 0x2130, 0x361c, 0x4240, 0x150c, 0x2d54, + 0x2030, 0x3620, 0x4244, 0x140c, 0x2c54, + 0x1f30, 0x3720, 0x4344, 0x130c, 0x2b54, + 0x1e30, 0x3820, 0x4444, 0x120c, 0x2a54, + 0x1e34, 0x3920, 0x4544, 0x1210, 0x2a58, + 0x1f34, 0x3a20, 0x4644, 0x1310, 0x2c58, + 0x2034, 0x3b20, 0x4744, 0x1410, 0x2e58, + 0x2424, 0x3f10, 0x0334, 0x1800, 0x3048, + 0x2524, 0x4010, 0x0434, 0x1900, 0x3148, + 0x2624, 0x4110, 0x0534, 0x1a00, 0x3248, + 0x2724, 0x4114, 0x0538, 0x1b00, 0x3348, + 0x2824, 0x4014, 0x0438, 0x1c00, 0x3448, + 0x2924, 0x3f14, 0x0338, 0x1d00, 0x3548, + 0x2928, 0x3e14, 0x0238, 0x1d04, 0x354c, + 0x2828, 0x3d14, 0x0138, 0x1c04, 0x344c, + 0x2728, 0x3c14, 0x0038, 0x1b04, 0x334c, + 0x2628, 0x3c18, 0x003c, 0x1a04, 0x324c, + 0x2528, 0x3d18, 0x013c, 0x1904, 0x314c, + 0x2428, 0x3e18, 0x023c, 0x1804, 0x304c, + 0x242c, 0x3f18, 0x033c, 0x1808, 0x3050, + 0x252c, 0x4018, 0x043c, 0x1908, 0x3150, + 0x262c, 0x4118, 0x053c, 0x1a08, 0x3250, + 0x272c, 0x411c, 0x0540, 0x1b08, 0x3350, + 0x282c, 0x401c, 0x0440, 0x1c08, 0x3450, + 0x292c, 0x3f1c, 0x0340, 0x1d08, 0x3550, + 0x2930, 0x3e1c, 0x0240, 0x1d0c, 0x3554, + 0x2830, 0x3d1c, 0x0140, 0x1c0c, 0x3454, + 0x2730, 0x3c1c, 0x0040, 0x1b0c, 0x3354, + 0x2630, 0x3c20, 0x0044, 0x1a0c, 0x3254, + 0x2530, 0x3d20, 0x0144, 0x190c, 0x3154, + 0x2430, 0x3e20, 0x0244, 0x180c, 0x3054, + 0x2434, 0x3f20, 0x0344, 0x1810, 0x3058, + 0x2534, 0x4020, 0x0444, 0x1910, 0x3258, + 0x2634, 0x4120, 0x0544, 0x1a10, 0x3458, + 0x2a24, 0x4510, 0x0934, 0x1e00, 0x3648, + 0x2b24, 0x4610, 0x0a34, 0x1f00, 0x3748, + 0x2c24, 0x4710, 0x0b34, 0x2000, 0x3848, + 0x2d24, 0x4714, 0x0b38, 0x2100, 0x3948, + 0x2e24, 0x4614, 0x0a38, 0x2200, 0x3a48, + 0x2f24, 0x4514, 0x0938, 0x2300, 0x3b48, + 0x2f28, 0x4414, 0x0838, 0x2304, 0x3b4c, + 0x2e28, 0x4314, 0x0738, 0x2204, 0x3a4c, + 0x2d28, 0x4214, 0x0638, 0x2104, 0x394c, + 0x2c28, 0x4218, 0x063c, 0x2004, 0x384c, + 0x2b28, 0x4318, 0x073c, 0x1f04, 0x374c, + 0x2a28, 0x4418, 0x083c, 0x1e04, 0x364c, + 0x2a2c, 0x4518, 0x093c, 0x1e08, 0x3650, + 0x2b2c, 0x4618, 0x0a3c, 0x1f08, 0x3750, + 0x2c2c, 0x4718, 0x0b3c, 0x2008, 0x3850, + 0x2d2c, 0x471c, 0x0b40, 0x2108, 0x3950, + 0x2e2c, 0x461c, 0x0a40, 0x2208, 0x3a50, + 0x2f2c, 0x451c, 0x0940, 0x2308, 0x3b50, + 0x2f30, 0x441c, 0x0840, 0x230c, 0x3b54, + 0x2e30, 0x431c, 0x0740, 0x220c, 0x3a54, + 0x2d30, 0x421c, 0x0640, 0x210c, 0x3954, + 0x2c30, 0x4220, 0x0644, 0x200c, 0x3854, + 0x2b30, 0x4320, 0x0744, 0x1f0c, 0x3754, + 0x2a30, 0x4420, 0x0844, 0x1e0c, 0x3654, + 0x2a34, 0x4520, 0x0944, 0x1e10, 0x3658, + 0x2b34, 0x4620, 0x0a44, 0x1f10, 0x3858, + 0x2c34, 0x4720, 0x0b44, 0x2010, 0x3a58, + 0x3024, 0x0310, 0x0f34, 0x2400, 0x3c48, + 0x3124, 0x0410, 0x1034, 0x2500, 0x3d48, + 0x3224, 0x0510, 0x1134, 0x2600, 0x3e48, + 0x3324, 0x0514, 0x1138, 0x2700, 0x3f48, + 0x3424, 0x0414, 0x1038, 0x2800, 0x4048, + 0x3524, 0x0314, 0x0f38, 0x2900, 0x4148, + 0x3528, 0x0214, 0x0e38, 0x2904, 0x414c, + 0x3428, 0x0114, 0x0d38, 0x2804, 0x404c, + 0x3328, 0x0014, 0x0c38, 0x2704, 0x3f4c, + 0x3228, 0x0018, 0x0c3c, 0x2604, 0x3e4c, + 0x3128, 0x0118, 0x0d3c, 0x2504, 0x3d4c, + 0x3028, 0x0218, 0x0e3c, 0x2404, 0x3c4c, + 0x302c, 0x0318, 0x0f3c, 0x2408, 0x3c50, + 0x312c, 0x0418, 0x103c, 0x2508, 0x3d50, + 0x322c, 0x0518, 0x113c, 0x2608, 0x3e50, + 0x332c, 0x051c, 0x1140, 0x2708, 0x3f50, + 0x342c, 0x041c, 0x1040, 0x2808, 0x4050, + 0x352c, 0x031c, 0x0f40, 0x2908, 0x4150, + 0x3530, 0x021c, 0x0e40, 0x290c, 0x4154, + 0x3430, 0x011c, 0x0d40, 0x280c, 0x4054, + 0x3330, 0x001c, 0x0c40, 0x270c, 0x3f54, + 0x3230, 0x0020, 0x0c44, 0x260c, 0x3e54, + 0x3130, 0x0120, 0x0d44, 0x250c, 0x3d54, + 0x3030, 0x0220, 0x0e44, 0x240c, 0x3c54, + 0x3034, 0x0320, 0x0f44, 0x2410, 0x3c58, + 0x3134, 0x0420, 0x1044, 0x2510, 0x3e58, + 0x3234, 0x0520, 0x1144, 0x2610, 0x4058, + 0x3624, 0x0910, 0x1534, 0x2a00, 0x4248, + 0x3724, 0x0a10, 0x1634, 0x2b00, 0x4348, + 0x3824, 0x0b10, 0x1734, 0x2c00, 0x4448, + 0x3924, 0x0b14, 0x1738, 0x2d00, 0x4548, + 0x3a24, 0x0a14, 0x1638, 0x2e00, 0x4648, + 0x3b24, 0x0914, 0x1538, 0x2f00, 0x4748, + 0x3b28, 0x0814, 0x1438, 0x2f04, 0x474c, + 0x3a28, 0x0714, 0x1338, 0x2e04, 0x464c, + 0x3928, 0x0614, 0x1238, 0x2d04, 0x454c, + 0x3828, 0x0618, 0x123c, 0x2c04, 0x444c, + 0x3728, 0x0718, 0x133c, 0x2b04, 0x434c, + 0x3628, 0x0818, 0x143c, 0x2a04, 0x424c, + 0x362c, 0x0918, 0x153c, 0x2a08, 0x4250, + 0x372c, 0x0a18, 0x163c, 0x2b08, 0x4350, + 0x382c, 0x0b18, 0x173c, 0x2c08, 0x4450, + 0x392c, 0x0b1c, 0x1740, 0x2d08, 0x4550, + 0x3a2c, 0x0a1c, 0x1640, 0x2e08, 0x4650, + 0x3b2c, 0x091c, 0x1540, 0x2f08, 0x4750, + 0x3b30, 0x081c, 0x1440, 0x2f0c, 0x4754, + 0x3a30, 0x071c, 0x1340, 0x2e0c, 0x4654, + 0x3930, 0x061c, 0x1240, 0x2d0c, 0x4554, + 0x3830, 0x0620, 0x1244, 0x2c0c, 0x4454, + 0x3730, 0x0720, 0x1344, 0x2b0c, 0x4354, + 0x3630, 0x0820, 0x1444, 0x2a0c, 0x4254, + 0x3634, 0x0920, 0x1544, 0x2a10, 0x4258, + 0x3734, 0x0a20, 0x1644, 0x2b10, 0x4458, + 0x3834, 0x0b20, 0x1744, 0x2c10, 0x4658, + 0x3c24, 0x0f10, 0x1b34, 0x3000, 0x0048, + 0x3d24, 0x1010, 0x1c34, 0x3100, 0x0148, + 0x3e24, 0x1110, 0x1d34, 0x3200, 0x0248, + 0x3f24, 0x1114, 0x1d38, 0x3300, 0x0348, + 0x4024, 0x1014, 0x1c38, 0x3400, 0x0448, + 0x4124, 0x0f14, 0x1b38, 0x3500, 0x0548, + 0x4128, 0x0e14, 0x1a38, 0x3504, 0x054c, + 0x4028, 0x0d14, 0x1938, 0x3404, 0x044c, + 0x3f28, 0x0c14, 0x1838, 0x3304, 0x034c, + 0x3e28, 0x0c18, 0x183c, 0x3204, 0x024c, + 0x3d28, 0x0d18, 0x193c, 0x3104, 0x014c, + 0x3c28, 0x0e18, 0x1a3c, 0x3004, 0x004c, + 0x3c2c, 0x0f18, 0x1b3c, 0x3008, 0x0050, + 0x3d2c, 0x1018, 0x1c3c, 0x3108, 0x0150, + 0x3e2c, 0x1118, 0x1d3c, 0x3208, 0x0250, + 0x3f2c, 0x111c, 0x1d40, 0x3308, 0x0350, + 0x402c, 0x101c, 0x1c40, 0x3408, 0x0450, + 0x412c, 0x0f1c, 0x1b40, 0x3508, 0x0550, + 0x4130, 0x0e1c, 0x1a40, 0x350c, 0x0554, + 0x4030, 0x0d1c, 0x1940, 0x340c, 0x0454, + 0x3f30, 0x0c1c, 0x1840, 0x330c, 0x0354, + 0x3e30, 0x0c20, 0x1844, 0x320c, 0x0254, + 0x3d30, 0x0d20, 0x1944, 0x310c, 0x0154, + 0x3c30, 0x0e20, 0x1a44, 0x300c, 0x0054, + 0x3c34, 0x0f20, 0x1b44, 0x3010, 0x0058, + 0x3d34, 0x1020, 0x1c44, 0x3110, 0x0258, + 0x3e34, 0x1120, 0x1d44, 0x3210, 0x0458, + 0x4224, 0x1510, 0x2134, 0x3600, 0x0648, + 0x4324, 0x1610, 0x2234, 0x3700, 0x0748, + 0x4424, 0x1710, 0x2334, 0x3800, 0x0848, + 0x4524, 0x1714, 0x2338, 0x3900, 0x0948, + 0x4624, 0x1614, 0x2238, 0x3a00, 0x0a48, + 0x4724, 0x1514, 0x2138, 0x3b00, 0x0b48, + 0x4728, 0x1414, 0x2038, 0x3b04, 0x0b4c, + 0x4628, 0x1314, 0x1f38, 0x3a04, 0x0a4c, + 0x4528, 0x1214, 0x1e38, 0x3904, 0x094c, + 0x4428, 0x1218, 0x1e3c, 0x3804, 0x084c, + 0x4328, 0x1318, 0x1f3c, 0x3704, 0x074c, + 0x4228, 0x1418, 0x203c, 0x3604, 0x064c, + 0x422c, 0x1518, 0x213c, 0x3608, 0x0650, + 0x432c, 0x1618, 0x223c, 0x3708, 0x0750, + 0x442c, 0x1718, 0x233c, 0x3808, 0x0850, + 0x452c, 0x171c, 0x2340, 0x3908, 0x0950, + 0x462c, 0x161c, 0x2240, 0x3a08, 0x0a50, + 0x472c, 0x151c, 0x2140, 0x3b08, 0x0b50, + 0x4730, 0x141c, 0x2040, 0x3b0c, 0x0b54, + 0x4630, 0x131c, 0x1f40, 0x3a0c, 0x0a54, + 0x4530, 0x121c, 0x1e40, 0x390c, 0x0954, + 0x4430, 0x1220, 0x1e44, 0x380c, 0x0854, + 0x4330, 0x1320, 0x1f44, 0x370c, 0x0754, + 0x4230, 0x1420, 0x2044, 0x360c, 0x0654, + 0x4234, 0x1520, 0x2144, 0x3610, 0x0658, + 0x4334, 0x1620, 0x2244, 0x3710, 0x0858, + 0x4434, 0x1720, 0x2344, 0x3810, 0x0a58, + 0x0024, 0x1b10, 0x2734, 0x3c00, 0x0c48, + 0x0124, 0x1c10, 0x2834, 0x3d00, 0x0d48, + 0x0224, 0x1d10, 0x2934, 0x3e00, 0x0e48, + 0x0324, 0x1d14, 0x2938, 0x3f00, 0x0f48, + 0x0424, 0x1c14, 0x2838, 0x4000, 0x1048, + 0x0524, 0x1b14, 0x2738, 0x4100, 0x1148, + 0x0528, 0x1a14, 0x2638, 0x4104, 0x114c, + 0x0428, 0x1914, 0x2538, 0x4004, 0x104c, + 0x0328, 0x1814, 0x2438, 0x3f04, 0x0f4c, + 0x0228, 0x1818, 0x243c, 0x3e04, 0x0e4c, + 0x0128, 0x1918, 0x253c, 0x3d04, 0x0d4c, + 0x0028, 0x1a18, 0x263c, 0x3c04, 0x0c4c, + 0x002c, 0x1b18, 0x273c, 0x3c08, 0x0c50, + 0x012c, 0x1c18, 0x283c, 0x3d08, 0x0d50, + 0x022c, 0x1d18, 0x293c, 0x3e08, 0x0e50, + 0x032c, 0x1d1c, 0x2940, 0x3f08, 0x0f50, + 0x042c, 0x1c1c, 0x2840, 0x4008, 0x1050, + 0x052c, 0x1b1c, 0x2740, 0x4108, 0x1150, + 0x0530, 0x1a1c, 0x2640, 0x410c, 0x1154, + 0x0430, 0x191c, 0x2540, 0x400c, 0x1054, + 0x0330, 0x181c, 0x2440, 0x3f0c, 0x0f54, + 0x0230, 0x1820, 0x2444, 0x3e0c, 0x0e54, + 0x0130, 0x1920, 0x2544, 0x3d0c, 0x0d54, + 0x0030, 0x1a20, 0x2644, 0x3c0c, 0x0c54, + 0x0034, 0x1b20, 0x2744, 0x3c10, 0x0c58, + 0x0134, 0x1c20, 0x2844, 0x3d10, 0x0e58, + 0x0234, 0x1d20, 0x2944, 0x3e10, 0x1058, + 0x0624, 0x2110, 0x2d34, 0x4200, 0x1248, + 0x0724, 0x2210, 0x2e34, 0x4300, 0x1348, + 0x0824, 0x2310, 0x2f34, 0x4400, 0x1448, + 0x0924, 0x2314, 0x2f38, 0x4500, 0x1548, + 0x0a24, 0x2214, 0x2e38, 0x4600, 0x1648, + 0x0b24, 0x2114, 0x2d38, 0x4700, 0x1748, + 0x0b28, 0x2014, 0x2c38, 0x4704, 0x174c, + 0x0a28, 0x1f14, 0x2b38, 0x4604, 0x164c, + 0x0928, 0x1e14, 0x2a38, 0x4504, 0x154c, + 0x0828, 0x1e18, 0x2a3c, 0x4404, 0x144c, + 0x0728, 0x1f18, 0x2b3c, 0x4304, 0x134c, + 0x0628, 0x2018, 0x2c3c, 0x4204, 0x124c, + 0x062c, 0x2118, 0x2d3c, 0x4208, 0x1250, + 0x072c, 0x2218, 0x2e3c, 0x4308, 0x1350, + 0x082c, 0x2318, 0x2f3c, 0x4408, 0x1450, + 0x092c, 0x231c, 0x2f40, 0x4508, 0x1550, + 0x0a2c, 0x221c, 0x2e40, 0x4608, 0x1650, + 0x0b2c, 0x211c, 0x2d40, 0x4708, 0x1750, + 0x0b30, 0x201c, 0x2c40, 0x470c, 0x1754, + 0x0a30, 0x1f1c, 0x2b40, 0x460c, 0x1654, + 0x0930, 0x1e1c, 0x2a40, 0x450c, 0x1554, + 0x0830, 0x1e20, 0x2a44, 0x440c, 0x1454, + 0x0730, 0x1f20, 0x2b44, 0x430c, 0x1354, + 0x0630, 0x2020, 0x2c44, 0x420c, 0x1254, + 0x0634, 0x2120, 0x2d44, 0x4210, 0x1258, + 0x0734, 0x2220, 0x2e44, 0x4310, 0x1458, 0x0834, 0x2320, 0x2f44, 0x4410, 0x1658, }; @@ -1256,13 +1245,1256 @@ static const uint16_t dv_place_411[1350] = { 0x0834, 0x2320, 0x2f44, 0x3810, 0x1658, }; -static const uint16_t dv_audio_shuffle525[10][9] = { +/* 2 channels per frame, 10 DIF sequences per channel, + 27 video segments per DIF sequence, 5 macroblocks per video segment */ +static const uint16_t dv_place_422_525[2*10*27*5] = { + 0x0c24, 0x2412, 0x3036, 0x0000, 0x1848, + 0x0d24, 0x2512, 0x3136, 0x0100, 0x1948, + 0x0e24, 0x2612, 0x3236, 0x0200, 0x1a48, + 0x0e26, 0x2614, 0x3238, 0x0202, 0x1a4a, + 0x0d26, 0x2514, 0x3138, 0x0102, 0x194a, + 0x0c26, 0x2414, 0x3038, 0x0002, 0x184a, + 0x0c28, 0x2416, 0x303a, 0x0004, 0x184c, + 0x0d28, 0x2516, 0x313a, 0x0104, 0x194c, + 0x0e28, 0x2616, 0x323a, 0x0204, 0x1a4c, + 0x0e2a, 0x2618, 0x323c, 0x0206, 0x1a4e, + 0x0d2a, 0x2518, 0x313c, 0x0106, 0x194e, + 0x0c2a, 0x2418, 0x303c, 0x0006, 0x184e, + 0x0c2c, 0x241a, 0x303e, 0x0008, 0x1850, + 0x0d2c, 0x251a, 0x313e, 0x0108, 0x1950, + 0x0e2c, 0x261a, 0x323e, 0x0208, 0x1a50, + 0x0e2e, 0x261c, 0x3240, 0x020a, 0x1a52, + 0x0d2e, 0x251c, 0x3140, 0x010a, 0x1952, + 0x0c2e, 0x241c, 0x3040, 0x000a, 0x1852, + 0x0c30, 0x241e, 0x3042, 0x000c, 0x1854, + 0x0d30, 0x251e, 0x3142, 0x010c, 0x1954, + 0x0e30, 0x261e, 0x3242, 0x020c, 0x1a54, + 0x0e32, 0x2620, 0x3244, 0x020e, 0x1a56, + 0x0d32, 0x2520, 0x3144, 0x010e, 0x1956, + 0x0c32, 0x2420, 0x3044, 0x000e, 0x1856, + 0x0c34, 0x2422, 0x3046, 0x0010, 0x1858, + 0x0d34, 0x2522, 0x3146, 0x0110, 0x1958, + 0x0e34, 0x2622, 0x3246, 0x0210, 0x1a58, + 0x1224, 0x2a12, 0x3636, 0x0600, 0x1e48, + 0x1324, 0x2b12, 0x3736, 0x0700, 0x1f48, + 0x1424, 0x2c12, 0x3836, 0x0800, 0x2048, + 0x1426, 0x2c14, 0x3838, 0x0802, 0x204a, + 0x1326, 0x2b14, 0x3738, 0x0702, 0x1f4a, + 0x1226, 0x2a14, 0x3638, 0x0602, 0x1e4a, + 0x1228, 0x2a16, 0x363a, 0x0604, 0x1e4c, + 0x1328, 0x2b16, 0x373a, 0x0704, 0x1f4c, + 0x1428, 0x2c16, 0x383a, 0x0804, 0x204c, + 0x142a, 0x2c18, 0x383c, 0x0806, 0x204e, + 0x132a, 0x2b18, 0x373c, 0x0706, 0x1f4e, + 0x122a, 0x2a18, 0x363c, 0x0606, 0x1e4e, + 0x122c, 0x2a1a, 0x363e, 0x0608, 0x1e50, + 0x132c, 0x2b1a, 0x373e, 0x0708, 0x1f50, + 0x142c, 0x2c1a, 0x383e, 0x0808, 0x2050, + 0x142e, 0x2c1c, 0x3840, 0x080a, 0x2052, + 0x132e, 0x2b1c, 0x3740, 0x070a, 0x1f52, + 0x122e, 0x2a1c, 0x3640, 0x060a, 0x1e52, + 0x1230, 0x2a1e, 0x3642, 0x060c, 0x1e54, + 0x1330, 0x2b1e, 0x3742, 0x070c, 0x1f54, + 0x1430, 0x2c1e, 0x3842, 0x080c, 0x2054, + 0x1432, 0x2c20, 0x3844, 0x080e, 0x2056, + 0x1332, 0x2b20, 0x3744, 0x070e, 0x1f56, + 0x1232, 0x2a20, 0x3644, 0x060e, 0x1e56, + 0x1234, 0x2a22, 0x3646, 0x0610, 0x1e58, + 0x1334, 0x2b22, 0x3746, 0x0710, 0x1f58, + 0x1434, 0x2c22, 0x3846, 0x0810, 0x2058, + 0x1824, 0x3012, 0x0036, 0x0c00, 0x2448, + 0x1924, 0x3112, 0x0136, 0x0d00, 0x2548, + 0x1a24, 0x3212, 0x0236, 0x0e00, 0x2648, + 0x1a26, 0x3214, 0x0238, 0x0e02, 0x264a, + 0x1926, 0x3114, 0x0138, 0x0d02, 0x254a, + 0x1826, 0x3014, 0x0038, 0x0c02, 0x244a, + 0x1828, 0x3016, 0x003a, 0x0c04, 0x244c, + 0x1928, 0x3116, 0x013a, 0x0d04, 0x254c, + 0x1a28, 0x3216, 0x023a, 0x0e04, 0x264c, + 0x1a2a, 0x3218, 0x023c, 0x0e06, 0x264e, + 0x192a, 0x3118, 0x013c, 0x0d06, 0x254e, + 0x182a, 0x3018, 0x003c, 0x0c06, 0x244e, + 0x182c, 0x301a, 0x003e, 0x0c08, 0x2450, + 0x192c, 0x311a, 0x013e, 0x0d08, 0x2550, + 0x1a2c, 0x321a, 0x023e, 0x0e08, 0x2650, + 0x1a2e, 0x321c, 0x0240, 0x0e0a, 0x2652, + 0x192e, 0x311c, 0x0140, 0x0d0a, 0x2552, + 0x182e, 0x301c, 0x0040, 0x0c0a, 0x2452, + 0x1830, 0x301e, 0x0042, 0x0c0c, 0x2454, + 0x1930, 0x311e, 0x0142, 0x0d0c, 0x2554, + 0x1a30, 0x321e, 0x0242, 0x0e0c, 0x2654, + 0x1a32, 0x3220, 0x0244, 0x0e0e, 0x2656, + 0x1932, 0x3120, 0x0144, 0x0d0e, 0x2556, + 0x1832, 0x3020, 0x0044, 0x0c0e, 0x2456, + 0x1834, 0x3022, 0x0046, 0x0c10, 0x2458, + 0x1934, 0x3122, 0x0146, 0x0d10, 0x2558, + 0x1a34, 0x3222, 0x0246, 0x0e10, 0x2658, + 0x1e24, 0x3612, 0x0636, 0x1200, 0x2a48, + 0x1f24, 0x3712, 0x0736, 0x1300, 0x2b48, + 0x2024, 0x3812, 0x0836, 0x1400, 0x2c48, + 0x2026, 0x3814, 0x0838, 0x1402, 0x2c4a, + 0x1f26, 0x3714, 0x0738, 0x1302, 0x2b4a, + 0x1e26, 0x3614, 0x0638, 0x1202, 0x2a4a, + 0x1e28, 0x3616, 0x063a, 0x1204, 0x2a4c, + 0x1f28, 0x3716, 0x073a, 0x1304, 0x2b4c, + 0x2028, 0x3816, 0x083a, 0x1404, 0x2c4c, + 0x202a, 0x3818, 0x083c, 0x1406, 0x2c4e, + 0x1f2a, 0x3718, 0x073c, 0x1306, 0x2b4e, + 0x1e2a, 0x3618, 0x063c, 0x1206, 0x2a4e, + 0x1e2c, 0x361a, 0x063e, 0x1208, 0x2a50, + 0x1f2c, 0x371a, 0x073e, 0x1308, 0x2b50, + 0x202c, 0x381a, 0x083e, 0x1408, 0x2c50, + 0x202e, 0x381c, 0x0840, 0x140a, 0x2c52, + 0x1f2e, 0x371c, 0x0740, 0x130a, 0x2b52, + 0x1e2e, 0x361c, 0x0640, 0x120a, 0x2a52, + 0x1e30, 0x361e, 0x0642, 0x120c, 0x2a54, + 0x1f30, 0x371e, 0x0742, 0x130c, 0x2b54, + 0x2030, 0x381e, 0x0842, 0x140c, 0x2c54, + 0x2032, 0x3820, 0x0844, 0x140e, 0x2c56, + 0x1f32, 0x3720, 0x0744, 0x130e, 0x2b56, + 0x1e32, 0x3620, 0x0644, 0x120e, 0x2a56, + 0x1e34, 0x3622, 0x0646, 0x1210, 0x2a58, + 0x1f34, 0x3722, 0x0746, 0x1310, 0x2b58, + 0x2034, 0x3822, 0x0846, 0x1410, 0x2c58, + 0x2424, 0x0012, 0x0c36, 0x1800, 0x3048, + 0x2524, 0x0112, 0x0d36, 0x1900, 0x3148, + 0x2624, 0x0212, 0x0e36, 0x1a00, 0x3248, + 0x2626, 0x0214, 0x0e38, 0x1a02, 0x324a, + 0x2526, 0x0114, 0x0d38, 0x1902, 0x314a, + 0x2426, 0x0014, 0x0c38, 0x1802, 0x304a, + 0x2428, 0x0016, 0x0c3a, 0x1804, 0x304c, + 0x2528, 0x0116, 0x0d3a, 0x1904, 0x314c, + 0x2628, 0x0216, 0x0e3a, 0x1a04, 0x324c, + 0x262a, 0x0218, 0x0e3c, 0x1a06, 0x324e, + 0x252a, 0x0118, 0x0d3c, 0x1906, 0x314e, + 0x242a, 0x0018, 0x0c3c, 0x1806, 0x304e, + 0x242c, 0x001a, 0x0c3e, 0x1808, 0x3050, + 0x252c, 0x011a, 0x0d3e, 0x1908, 0x3150, + 0x262c, 0x021a, 0x0e3e, 0x1a08, 0x3250, + 0x262e, 0x021c, 0x0e40, 0x1a0a, 0x3252, + 0x252e, 0x011c, 0x0d40, 0x190a, 0x3152, + 0x242e, 0x001c, 0x0c40, 0x180a, 0x3052, + 0x2430, 0x001e, 0x0c42, 0x180c, 0x3054, + 0x2530, 0x011e, 0x0d42, 0x190c, 0x3154, + 0x2630, 0x021e, 0x0e42, 0x1a0c, 0x3254, + 0x2632, 0x0220, 0x0e44, 0x1a0e, 0x3256, + 0x2532, 0x0120, 0x0d44, 0x190e, 0x3156, + 0x2432, 0x0020, 0x0c44, 0x180e, 0x3056, + 0x2434, 0x0022, 0x0c46, 0x1810, 0x3058, + 0x2534, 0x0122, 0x0d46, 0x1910, 0x3158, + 0x2634, 0x0222, 0x0e46, 0x1a10, 0x3258, + 0x2a24, 0x0612, 0x1236, 0x1e00, 0x3648, + 0x2b24, 0x0712, 0x1336, 0x1f00, 0x3748, + 0x2c24, 0x0812, 0x1436, 0x2000, 0x3848, + 0x2c26, 0x0814, 0x1438, 0x2002, 0x384a, + 0x2b26, 0x0714, 0x1338, 0x1f02, 0x374a, + 0x2a26, 0x0614, 0x1238, 0x1e02, 0x364a, + 0x2a28, 0x0616, 0x123a, 0x1e04, 0x364c, + 0x2b28, 0x0716, 0x133a, 0x1f04, 0x374c, + 0x2c28, 0x0816, 0x143a, 0x2004, 0x384c, + 0x2c2a, 0x0818, 0x143c, 0x2006, 0x384e, + 0x2b2a, 0x0718, 0x133c, 0x1f06, 0x374e, + 0x2a2a, 0x0618, 0x123c, 0x1e06, 0x364e, + 0x2a2c, 0x061a, 0x123e, 0x1e08, 0x3650, + 0x2b2c, 0x071a, 0x133e, 0x1f08, 0x3750, + 0x2c2c, 0x081a, 0x143e, 0x2008, 0x3850, + 0x2c2e, 0x081c, 0x1440, 0x200a, 0x3852, + 0x2b2e, 0x071c, 0x1340, 0x1f0a, 0x3752, + 0x2a2e, 0x061c, 0x1240, 0x1e0a, 0x3652, + 0x2a30, 0x061e, 0x1242, 0x1e0c, 0x3654, + 0x2b30, 0x071e, 0x1342, 0x1f0c, 0x3754, + 0x2c30, 0x081e, 0x1442, 0x200c, 0x3854, + 0x2c32, 0x0820, 0x1444, 0x200e, 0x3856, + 0x2b32, 0x0720, 0x1344, 0x1f0e, 0x3756, + 0x2a32, 0x0620, 0x1244, 0x1e0e, 0x3656, + 0x2a34, 0x0622, 0x1246, 0x1e10, 0x3658, + 0x2b34, 0x0722, 0x1346, 0x1f10, 0x3758, + 0x2c34, 0x0822, 0x1446, 0x2010, 0x3858, + 0x3024, 0x0c12, 0x1836, 0x2400, 0x0048, + 0x3124, 0x0d12, 0x1936, 0x2500, 0x0148, + 0x3224, 0x0e12, 0x1a36, 0x2600, 0x0248, + 0x3226, 0x0e14, 0x1a38, 0x2602, 0x024a, + 0x3126, 0x0d14, 0x1938, 0x2502, 0x014a, + 0x3026, 0x0c14, 0x1838, 0x2402, 0x004a, + 0x3028, 0x0c16, 0x183a, 0x2404, 0x004c, + 0x3128, 0x0d16, 0x193a, 0x2504, 0x014c, + 0x3228, 0x0e16, 0x1a3a, 0x2604, 0x024c, + 0x322a, 0x0e18, 0x1a3c, 0x2606, 0x024e, + 0x312a, 0x0d18, 0x193c, 0x2506, 0x014e, + 0x302a, 0x0c18, 0x183c, 0x2406, 0x004e, + 0x302c, 0x0c1a, 0x183e, 0x2408, 0x0050, + 0x312c, 0x0d1a, 0x193e, 0x2508, 0x0150, + 0x322c, 0x0e1a, 0x1a3e, 0x2608, 0x0250, + 0x322e, 0x0e1c, 0x1a40, 0x260a, 0x0252, + 0x312e, 0x0d1c, 0x1940, 0x250a, 0x0152, + 0x302e, 0x0c1c, 0x1840, 0x240a, 0x0052, + 0x3030, 0x0c1e, 0x1842, 0x240c, 0x0054, + 0x3130, 0x0d1e, 0x1942, 0x250c, 0x0154, + 0x3230, 0x0e1e, 0x1a42, 0x260c, 0x0254, + 0x3232, 0x0e20, 0x1a44, 0x260e, 0x0256, + 0x3132, 0x0d20, 0x1944, 0x250e, 0x0156, + 0x3032, 0x0c20, 0x1844, 0x240e, 0x0056, + 0x3034, 0x0c22, 0x1846, 0x2410, 0x0058, + 0x3134, 0x0d22, 0x1946, 0x2510, 0x0158, + 0x3234, 0x0e22, 0x1a46, 0x2610, 0x0258, + 0x3624, 0x1212, 0x1e36, 0x2a00, 0x0648, + 0x3724, 0x1312, 0x1f36, 0x2b00, 0x0748, + 0x3824, 0x1412, 0x2036, 0x2c00, 0x0848, + 0x3826, 0x1414, 0x2038, 0x2c02, 0x084a, + 0x3726, 0x1314, 0x1f38, 0x2b02, 0x074a, + 0x3626, 0x1214, 0x1e38, 0x2a02, 0x064a, + 0x3628, 0x1216, 0x1e3a, 0x2a04, 0x064c, + 0x3728, 0x1316, 0x1f3a, 0x2b04, 0x074c, + 0x3828, 0x1416, 0x203a, 0x2c04, 0x084c, + 0x382a, 0x1418, 0x203c, 0x2c06, 0x084e, + 0x372a, 0x1318, 0x1f3c, 0x2b06, 0x074e, + 0x362a, 0x1218, 0x1e3c, 0x2a06, 0x064e, + 0x362c, 0x121a, 0x1e3e, 0x2a08, 0x0650, + 0x372c, 0x131a, 0x1f3e, 0x2b08, 0x0750, + 0x382c, 0x141a, 0x203e, 0x2c08, 0x0850, + 0x382e, 0x141c, 0x2040, 0x2c0a, 0x0852, + 0x372e, 0x131c, 0x1f40, 0x2b0a, 0x0752, + 0x362e, 0x121c, 0x1e40, 0x2a0a, 0x0652, + 0x3630, 0x121e, 0x1e42, 0x2a0c, 0x0654, + 0x3730, 0x131e, 0x1f42, 0x2b0c, 0x0754, + 0x3830, 0x141e, 0x2042, 0x2c0c, 0x0854, + 0x3832, 0x1420, 0x2044, 0x2c0e, 0x0856, + 0x3732, 0x1320, 0x1f44, 0x2b0e, 0x0756, + 0x3632, 0x1220, 0x1e44, 0x2a0e, 0x0656, + 0x3634, 0x1222, 0x1e46, 0x2a10, 0x0658, + 0x3734, 0x1322, 0x1f46, 0x2b10, 0x0758, + 0x3834, 0x1422, 0x2046, 0x2c10, 0x0858, + 0x0024, 0x1812, 0x2436, 0x3000, 0x0c48, + 0x0124, 0x1912, 0x2536, 0x3100, 0x0d48, + 0x0224, 0x1a12, 0x2636, 0x3200, 0x0e48, + 0x0226, 0x1a14, 0x2638, 0x3202, 0x0e4a, + 0x0126, 0x1914, 0x2538, 0x3102, 0x0d4a, + 0x0026, 0x1814, 0x2438, 0x3002, 0x0c4a, + 0x0028, 0x1816, 0x243a, 0x3004, 0x0c4c, + 0x0128, 0x1916, 0x253a, 0x3104, 0x0d4c, + 0x0228, 0x1a16, 0x263a, 0x3204, 0x0e4c, + 0x022a, 0x1a18, 0x263c, 0x3206, 0x0e4e, + 0x012a, 0x1918, 0x253c, 0x3106, 0x0d4e, + 0x002a, 0x1818, 0x243c, 0x3006, 0x0c4e, + 0x002c, 0x181a, 0x243e, 0x3008, 0x0c50, + 0x012c, 0x191a, 0x253e, 0x3108, 0x0d50, + 0x022c, 0x1a1a, 0x263e, 0x3208, 0x0e50, + 0x022e, 0x1a1c, 0x2640, 0x320a, 0x0e52, + 0x012e, 0x191c, 0x2540, 0x310a, 0x0d52, + 0x002e, 0x181c, 0x2440, 0x300a, 0x0c52, + 0x0030, 0x181e, 0x2442, 0x300c, 0x0c54, + 0x0130, 0x191e, 0x2542, 0x310c, 0x0d54, + 0x0230, 0x1a1e, 0x2642, 0x320c, 0x0e54, + 0x0232, 0x1a20, 0x2644, 0x320e, 0x0e56, + 0x0132, 0x1920, 0x2544, 0x310e, 0x0d56, + 0x0032, 0x1820, 0x2444, 0x300e, 0x0c56, + 0x0034, 0x1822, 0x2446, 0x3010, 0x0c58, + 0x0134, 0x1922, 0x2546, 0x3110, 0x0d58, + 0x0234, 0x1a22, 0x2646, 0x3210, 0x0e58, + 0x0624, 0x1e12, 0x2a36, 0x3600, 0x1248, + 0x0724, 0x1f12, 0x2b36, 0x3700, 0x1348, + 0x0824, 0x2012, 0x2c36, 0x3800, 0x1448, + 0x0826, 0x2014, 0x2c38, 0x3802, 0x144a, + 0x0726, 0x1f14, 0x2b38, 0x3702, 0x134a, + 0x0626, 0x1e14, 0x2a38, 0x3602, 0x124a, + 0x0628, 0x1e16, 0x2a3a, 0x3604, 0x124c, + 0x0728, 0x1f16, 0x2b3a, 0x3704, 0x134c, + 0x0828, 0x2016, 0x2c3a, 0x3804, 0x144c, + 0x082a, 0x2018, 0x2c3c, 0x3806, 0x144e, + 0x072a, 0x1f18, 0x2b3c, 0x3706, 0x134e, + 0x062a, 0x1e18, 0x2a3c, 0x3606, 0x124e, + 0x062c, 0x1e1a, 0x2a3e, 0x3608, 0x1250, + 0x072c, 0x1f1a, 0x2b3e, 0x3708, 0x1350, + 0x082c, 0x201a, 0x2c3e, 0x3808, 0x1450, + 0x082e, 0x201c, 0x2c40, 0x380a, 0x1452, + 0x072e, 0x1f1c, 0x2b40, 0x370a, 0x1352, + 0x062e, 0x1e1c, 0x2a40, 0x360a, 0x1252, + 0x0630, 0x1e1e, 0x2a42, 0x360c, 0x1254, + 0x0730, 0x1f1e, 0x2b42, 0x370c, 0x1354, + 0x0830, 0x201e, 0x2c42, 0x380c, 0x1454, + 0x0832, 0x2020, 0x2c44, 0x380e, 0x1456, + 0x0732, 0x1f20, 0x2b44, 0x370e, 0x1356, + 0x0632, 0x1e20, 0x2a44, 0x360e, 0x1256, + 0x0634, 0x1e22, 0x2a46, 0x3610, 0x1258, + 0x0734, 0x1f22, 0x2b46, 0x3710, 0x1358, + 0x0834, 0x2022, 0x2c46, 0x3810, 0x1458, + 0x0f24, 0x2712, 0x3336, 0x0300, 0x1b48, + 0x1024, 0x2812, 0x3436, 0x0400, 0x1c48, + 0x1124, 0x2912, 0x3536, 0x0500, 0x1d48, + 0x1126, 0x2914, 0x3538, 0x0502, 0x1d4a, + 0x1026, 0x2814, 0x3438, 0x0402, 0x1c4a, + 0x0f26, 0x2714, 0x3338, 0x0302, 0x1b4a, + 0x0f28, 0x2716, 0x333a, 0x0304, 0x1b4c, + 0x1028, 0x2816, 0x343a, 0x0404, 0x1c4c, + 0x1128, 0x2916, 0x353a, 0x0504, 0x1d4c, + 0x112a, 0x2918, 0x353c, 0x0506, 0x1d4e, + 0x102a, 0x2818, 0x343c, 0x0406, 0x1c4e, + 0x0f2a, 0x2718, 0x333c, 0x0306, 0x1b4e, + 0x0f2c, 0x271a, 0x333e, 0x0308, 0x1b50, + 0x102c, 0x281a, 0x343e, 0x0408, 0x1c50, + 0x112c, 0x291a, 0x353e, 0x0508, 0x1d50, + 0x112e, 0x291c, 0x3540, 0x050a, 0x1d52, + 0x102e, 0x281c, 0x3440, 0x040a, 0x1c52, + 0x0f2e, 0x271c, 0x3340, 0x030a, 0x1b52, + 0x0f30, 0x271e, 0x3342, 0x030c, 0x1b54, + 0x1030, 0x281e, 0x3442, 0x040c, 0x1c54, + 0x1130, 0x291e, 0x3542, 0x050c, 0x1d54, + 0x1132, 0x2920, 0x3544, 0x050e, 0x1d56, + 0x1032, 0x2820, 0x3444, 0x040e, 0x1c56, + 0x0f32, 0x2720, 0x3344, 0x030e, 0x1b56, + 0x0f34, 0x2722, 0x3346, 0x0310, 0x1b58, + 0x1034, 0x2822, 0x3446, 0x0410, 0x1c58, + 0x1134, 0x2922, 0x3546, 0x0510, 0x1d58, + 0x1524, 0x2d12, 0x3936, 0x0900, 0x2148, + 0x1624, 0x2e12, 0x3a36, 0x0a00, 0x2248, + 0x1724, 0x2f12, 0x3b36, 0x0b00, 0x2348, + 0x1726, 0x2f14, 0x3b38, 0x0b02, 0x234a, + 0x1626, 0x2e14, 0x3a38, 0x0a02, 0x224a, + 0x1526, 0x2d14, 0x3938, 0x0902, 0x214a, + 0x1528, 0x2d16, 0x393a, 0x0904, 0x214c, + 0x1628, 0x2e16, 0x3a3a, 0x0a04, 0x224c, + 0x1728, 0x2f16, 0x3b3a, 0x0b04, 0x234c, + 0x172a, 0x2f18, 0x3b3c, 0x0b06, 0x234e, + 0x162a, 0x2e18, 0x3a3c, 0x0a06, 0x224e, + 0x152a, 0x2d18, 0x393c, 0x0906, 0x214e, + 0x152c, 0x2d1a, 0x393e, 0x0908, 0x2150, + 0x162c, 0x2e1a, 0x3a3e, 0x0a08, 0x2250, + 0x172c, 0x2f1a, 0x3b3e, 0x0b08, 0x2350, + 0x172e, 0x2f1c, 0x3b40, 0x0b0a, 0x2352, + 0x162e, 0x2e1c, 0x3a40, 0x0a0a, 0x2252, + 0x152e, 0x2d1c, 0x3940, 0x090a, 0x2152, + 0x1530, 0x2d1e, 0x3942, 0x090c, 0x2154, + 0x1630, 0x2e1e, 0x3a42, 0x0a0c, 0x2254, + 0x1730, 0x2f1e, 0x3b42, 0x0b0c, 0x2354, + 0x1732, 0x2f20, 0x3b44, 0x0b0e, 0x2356, + 0x1632, 0x2e20, 0x3a44, 0x0a0e, 0x2256, + 0x1532, 0x2d20, 0x3944, 0x090e, 0x2156, + 0x1534, 0x2d22, 0x3946, 0x0910, 0x2158, + 0x1634, 0x2e22, 0x3a46, 0x0a10, 0x2258, + 0x1734, 0x2f22, 0x3b46, 0x0b10, 0x2358, + 0x1b24, 0x3312, 0x0336, 0x0f00, 0x2748, + 0x1c24, 0x3412, 0x0436, 0x1000, 0x2848, + 0x1d24, 0x3512, 0x0536, 0x1100, 0x2948, + 0x1d26, 0x3514, 0x0538, 0x1102, 0x294a, + 0x1c26, 0x3414, 0x0438, 0x1002, 0x284a, + 0x1b26, 0x3314, 0x0338, 0x0f02, 0x274a, + 0x1b28, 0x3316, 0x033a, 0x0f04, 0x274c, + 0x1c28, 0x3416, 0x043a, 0x1004, 0x284c, + 0x1d28, 0x3516, 0x053a, 0x1104, 0x294c, + 0x1d2a, 0x3518, 0x053c, 0x1106, 0x294e, + 0x1c2a, 0x3418, 0x043c, 0x1006, 0x284e, + 0x1b2a, 0x3318, 0x033c, 0x0f06, 0x274e, + 0x1b2c, 0x331a, 0x033e, 0x0f08, 0x2750, + 0x1c2c, 0x341a, 0x043e, 0x1008, 0x2850, + 0x1d2c, 0x351a, 0x053e, 0x1108, 0x2950, + 0x1d2e, 0x351c, 0x0540, 0x110a, 0x2952, + 0x1c2e, 0x341c, 0x0440, 0x100a, 0x2852, + 0x1b2e, 0x331c, 0x0340, 0x0f0a, 0x2752, + 0x1b30, 0x331e, 0x0342, 0x0f0c, 0x2754, + 0x1c30, 0x341e, 0x0442, 0x100c, 0x2854, + 0x1d30, 0x351e, 0x0542, 0x110c, 0x2954, + 0x1d32, 0x3520, 0x0544, 0x110e, 0x2956, + 0x1c32, 0x3420, 0x0444, 0x100e, 0x2856, + 0x1b32, 0x3320, 0x0344, 0x0f0e, 0x2756, + 0x1b34, 0x3322, 0x0346, 0x0f10, 0x2758, + 0x1c34, 0x3422, 0x0446, 0x1010, 0x2858, + 0x1d34, 0x3522, 0x0546, 0x1110, 0x2958, + 0x2124, 0x3912, 0x0936, 0x1500, 0x2d48, + 0x2224, 0x3a12, 0x0a36, 0x1600, 0x2e48, + 0x2324, 0x3b12, 0x0b36, 0x1700, 0x2f48, + 0x2326, 0x3b14, 0x0b38, 0x1702, 0x2f4a, + 0x2226, 0x3a14, 0x0a38, 0x1602, 0x2e4a, + 0x2126, 0x3914, 0x0938, 0x1502, 0x2d4a, + 0x2128, 0x3916, 0x093a, 0x1504, 0x2d4c, + 0x2228, 0x3a16, 0x0a3a, 0x1604, 0x2e4c, + 0x2328, 0x3b16, 0x0b3a, 0x1704, 0x2f4c, + 0x232a, 0x3b18, 0x0b3c, 0x1706, 0x2f4e, + 0x222a, 0x3a18, 0x0a3c, 0x1606, 0x2e4e, + 0x212a, 0x3918, 0x093c, 0x1506, 0x2d4e, + 0x212c, 0x391a, 0x093e, 0x1508, 0x2d50, + 0x222c, 0x3a1a, 0x0a3e, 0x1608, 0x2e50, + 0x232c, 0x3b1a, 0x0b3e, 0x1708, 0x2f50, + 0x232e, 0x3b1c, 0x0b40, 0x170a, 0x2f52, + 0x222e, 0x3a1c, 0x0a40, 0x160a, 0x2e52, + 0x212e, 0x391c, 0x0940, 0x150a, 0x2d52, + 0x2130, 0x391e, 0x0942, 0x150c, 0x2d54, + 0x2230, 0x3a1e, 0x0a42, 0x160c, 0x2e54, + 0x2330, 0x3b1e, 0x0b42, 0x170c, 0x2f54, + 0x2332, 0x3b20, 0x0b44, 0x170e, 0x2f56, + 0x2232, 0x3a20, 0x0a44, 0x160e, 0x2e56, + 0x2132, 0x3920, 0x0944, 0x150e, 0x2d56, + 0x2134, 0x3922, 0x0946, 0x1510, 0x2d58, + 0x2234, 0x3a22, 0x0a46, 0x1610, 0x2e58, + 0x2334, 0x3b22, 0x0b46, 0x1710, 0x2f58, + 0x2724, 0x0312, 0x0f36, 0x1b00, 0x3348, + 0x2824, 0x0412, 0x1036, 0x1c00, 0x3448, + 0x2924, 0x0512, 0x1136, 0x1d00, 0x3548, + 0x2926, 0x0514, 0x1138, 0x1d02, 0x354a, + 0x2826, 0x0414, 0x1038, 0x1c02, 0x344a, + 0x2726, 0x0314, 0x0f38, 0x1b02, 0x334a, + 0x2728, 0x0316, 0x0f3a, 0x1b04, 0x334c, + 0x2828, 0x0416, 0x103a, 0x1c04, 0x344c, + 0x2928, 0x0516, 0x113a, 0x1d04, 0x354c, + 0x292a, 0x0518, 0x113c, 0x1d06, 0x354e, + 0x282a, 0x0418, 0x103c, 0x1c06, 0x344e, + 0x272a, 0x0318, 0x0f3c, 0x1b06, 0x334e, + 0x272c, 0x031a, 0x0f3e, 0x1b08, 0x3350, + 0x282c, 0x041a, 0x103e, 0x1c08, 0x3450, + 0x292c, 0x051a, 0x113e, 0x1d08, 0x3550, + 0x292e, 0x051c, 0x1140, 0x1d0a, 0x3552, + 0x282e, 0x041c, 0x1040, 0x1c0a, 0x3452, + 0x272e, 0x031c, 0x0f40, 0x1b0a, 0x3352, + 0x2730, 0x031e, 0x0f42, 0x1b0c, 0x3354, + 0x2830, 0x041e, 0x1042, 0x1c0c, 0x3454, + 0x2930, 0x051e, 0x1142, 0x1d0c, 0x3554, + 0x2932, 0x0520, 0x1144, 0x1d0e, 0x3556, + 0x2832, 0x0420, 0x1044, 0x1c0e, 0x3456, + 0x2732, 0x0320, 0x0f44, 0x1b0e, 0x3356, + 0x2734, 0x0322, 0x0f46, 0x1b10, 0x3358, + 0x2834, 0x0422, 0x1046, 0x1c10, 0x3458, + 0x2934, 0x0522, 0x1146, 0x1d10, 0x3558, + 0x2d24, 0x0912, 0x1536, 0x2100, 0x3948, + 0x2e24, 0x0a12, 0x1636, 0x2200, 0x3a48, + 0x2f24, 0x0b12, 0x1736, 0x2300, 0x3b48, + 0x2f26, 0x0b14, 0x1738, 0x2302, 0x3b4a, + 0x2e26, 0x0a14, 0x1638, 0x2202, 0x3a4a, + 0x2d26, 0x0914, 0x1538, 0x2102, 0x394a, + 0x2d28, 0x0916, 0x153a, 0x2104, 0x394c, + 0x2e28, 0x0a16, 0x163a, 0x2204, 0x3a4c, + 0x2f28, 0x0b16, 0x173a, 0x2304, 0x3b4c, + 0x2f2a, 0x0b18, 0x173c, 0x2306, 0x3b4e, + 0x2e2a, 0x0a18, 0x163c, 0x2206, 0x3a4e, + 0x2d2a, 0x0918, 0x153c, 0x2106, 0x394e, + 0x2d2c, 0x091a, 0x153e, 0x2108, 0x3950, + 0x2e2c, 0x0a1a, 0x163e, 0x2208, 0x3a50, + 0x2f2c, 0x0b1a, 0x173e, 0x2308, 0x3b50, + 0x2f2e, 0x0b1c, 0x1740, 0x230a, 0x3b52, + 0x2e2e, 0x0a1c, 0x1640, 0x220a, 0x3a52, + 0x2d2e, 0x091c, 0x1540, 0x210a, 0x3952, + 0x2d30, 0x091e, 0x1542, 0x210c, 0x3954, + 0x2e30, 0x0a1e, 0x1642, 0x220c, 0x3a54, + 0x2f30, 0x0b1e, 0x1742, 0x230c, 0x3b54, + 0x2f32, 0x0b20, 0x1744, 0x230e, 0x3b56, + 0x2e32, 0x0a20, 0x1644, 0x220e, 0x3a56, + 0x2d32, 0x0920, 0x1544, 0x210e, 0x3956, + 0x2d34, 0x0922, 0x1546, 0x2110, 0x3958, + 0x2e34, 0x0a22, 0x1646, 0x2210, 0x3a58, + 0x2f34, 0x0b22, 0x1746, 0x2310, 0x3b58, + 0x3324, 0x0f12, 0x1b36, 0x2700, 0x0348, + 0x3424, 0x1012, 0x1c36, 0x2800, 0x0448, + 0x3524, 0x1112, 0x1d36, 0x2900, 0x0548, + 0x3526, 0x1114, 0x1d38, 0x2902, 0x054a, + 0x3426, 0x1014, 0x1c38, 0x2802, 0x044a, + 0x3326, 0x0f14, 0x1b38, 0x2702, 0x034a, + 0x3328, 0x0f16, 0x1b3a, 0x2704, 0x034c, + 0x3428, 0x1016, 0x1c3a, 0x2804, 0x044c, + 0x3528, 0x1116, 0x1d3a, 0x2904, 0x054c, + 0x352a, 0x1118, 0x1d3c, 0x2906, 0x054e, + 0x342a, 0x1018, 0x1c3c, 0x2806, 0x044e, + 0x332a, 0x0f18, 0x1b3c, 0x2706, 0x034e, + 0x332c, 0x0f1a, 0x1b3e, 0x2708, 0x0350, + 0x342c, 0x101a, 0x1c3e, 0x2808, 0x0450, + 0x352c, 0x111a, 0x1d3e, 0x2908, 0x0550, + 0x352e, 0x111c, 0x1d40, 0x290a, 0x0552, + 0x342e, 0x101c, 0x1c40, 0x280a, 0x0452, + 0x332e, 0x0f1c, 0x1b40, 0x270a, 0x0352, + 0x3330, 0x0f1e, 0x1b42, 0x270c, 0x0354, + 0x3430, 0x101e, 0x1c42, 0x280c, 0x0454, + 0x3530, 0x111e, 0x1d42, 0x290c, 0x0554, + 0x3532, 0x1120, 0x1d44, 0x290e, 0x0556, + 0x3432, 0x1020, 0x1c44, 0x280e, 0x0456, + 0x3332, 0x0f20, 0x1b44, 0x270e, 0x0356, + 0x3334, 0x0f22, 0x1b46, 0x2710, 0x0358, + 0x3434, 0x1022, 0x1c46, 0x2810, 0x0458, + 0x3534, 0x1122, 0x1d46, 0x2910, 0x0558, + 0x3924, 0x1512, 0x2136, 0x2d00, 0x0948, + 0x3a24, 0x1612, 0x2236, 0x2e00, 0x0a48, + 0x3b24, 0x1712, 0x2336, 0x2f00, 0x0b48, + 0x3b26, 0x1714, 0x2338, 0x2f02, 0x0b4a, + 0x3a26, 0x1614, 0x2238, 0x2e02, 0x0a4a, + 0x3926, 0x1514, 0x2138, 0x2d02, 0x094a, + 0x3928, 0x1516, 0x213a, 0x2d04, 0x094c, + 0x3a28, 0x1616, 0x223a, 0x2e04, 0x0a4c, + 0x3b28, 0x1716, 0x233a, 0x2f04, 0x0b4c, + 0x3b2a, 0x1718, 0x233c, 0x2f06, 0x0b4e, + 0x3a2a, 0x1618, 0x223c, 0x2e06, 0x0a4e, + 0x392a, 0x1518, 0x213c, 0x2d06, 0x094e, + 0x392c, 0x151a, 0x213e, 0x2d08, 0x0950, + 0x3a2c, 0x161a, 0x223e, 0x2e08, 0x0a50, + 0x3b2c, 0x171a, 0x233e, 0x2f08, 0x0b50, + 0x3b2e, 0x171c, 0x2340, 0x2f0a, 0x0b52, + 0x3a2e, 0x161c, 0x2240, 0x2e0a, 0x0a52, + 0x392e, 0x151c, 0x2140, 0x2d0a, 0x0952, + 0x3930, 0x151e, 0x2142, 0x2d0c, 0x0954, + 0x3a30, 0x161e, 0x2242, 0x2e0c, 0x0a54, + 0x3b30, 0x171e, 0x2342, 0x2f0c, 0x0b54, + 0x3b32, 0x1720, 0x2344, 0x2f0e, 0x0b56, + 0x3a32, 0x1620, 0x2244, 0x2e0e, 0x0a56, + 0x3932, 0x1520, 0x2144, 0x2d0e, 0x0956, + 0x3934, 0x1522, 0x2146, 0x2d10, 0x0958, + 0x3a34, 0x1622, 0x2246, 0x2e10, 0x0a58, + 0x3b34, 0x1722, 0x2346, 0x2f10, 0x0b58, + 0x0324, 0x1b12, 0x2736, 0x3300, 0x0f48, + 0x0424, 0x1c12, 0x2836, 0x3400, 0x1048, + 0x0524, 0x1d12, 0x2936, 0x3500, 0x1148, + 0x0526, 0x1d14, 0x2938, 0x3502, 0x114a, + 0x0426, 0x1c14, 0x2838, 0x3402, 0x104a, + 0x0326, 0x1b14, 0x2738, 0x3302, 0x0f4a, + 0x0328, 0x1b16, 0x273a, 0x3304, 0x0f4c, + 0x0428, 0x1c16, 0x283a, 0x3404, 0x104c, + 0x0528, 0x1d16, 0x293a, 0x3504, 0x114c, + 0x052a, 0x1d18, 0x293c, 0x3506, 0x114e, + 0x042a, 0x1c18, 0x283c, 0x3406, 0x104e, + 0x032a, 0x1b18, 0x273c, 0x3306, 0x0f4e, + 0x032c, 0x1b1a, 0x273e, 0x3308, 0x0f50, + 0x042c, 0x1c1a, 0x283e, 0x3408, 0x1050, + 0x052c, 0x1d1a, 0x293e, 0x3508, 0x1150, + 0x052e, 0x1d1c, 0x2940, 0x350a, 0x1152, + 0x042e, 0x1c1c, 0x2840, 0x340a, 0x1052, + 0x032e, 0x1b1c, 0x2740, 0x330a, 0x0f52, + 0x0330, 0x1b1e, 0x2742, 0x330c, 0x0f54, + 0x0430, 0x1c1e, 0x2842, 0x340c, 0x1054, + 0x0530, 0x1d1e, 0x2942, 0x350c, 0x1154, + 0x0532, 0x1d20, 0x2944, 0x350e, 0x1156, + 0x0432, 0x1c20, 0x2844, 0x340e, 0x1056, + 0x0332, 0x1b20, 0x2744, 0x330e, 0x0f56, + 0x0334, 0x1b22, 0x2746, 0x3310, 0x0f58, + 0x0434, 0x1c22, 0x2846, 0x3410, 0x1058, + 0x0534, 0x1d22, 0x2946, 0x3510, 0x1158, + 0x0924, 0x2112, 0x2d36, 0x3900, 0x1548, + 0x0a24, 0x2212, 0x2e36, 0x3a00, 0x1648, + 0x0b24, 0x2312, 0x2f36, 0x3b00, 0x1748, + 0x0b26, 0x2314, 0x2f38, 0x3b02, 0x174a, + 0x0a26, 0x2214, 0x2e38, 0x3a02, 0x164a, + 0x0926, 0x2114, 0x2d38, 0x3902, 0x154a, + 0x0928, 0x2116, 0x2d3a, 0x3904, 0x154c, + 0x0a28, 0x2216, 0x2e3a, 0x3a04, 0x164c, + 0x0b28, 0x2316, 0x2f3a, 0x3b04, 0x174c, + 0x0b2a, 0x2318, 0x2f3c, 0x3b06, 0x174e, + 0x0a2a, 0x2218, 0x2e3c, 0x3a06, 0x164e, + 0x092a, 0x2118, 0x2d3c, 0x3906, 0x154e, + 0x092c, 0x211a, 0x2d3e, 0x3908, 0x1550, + 0x0a2c, 0x221a, 0x2e3e, 0x3a08, 0x1650, + 0x0b2c, 0x231a, 0x2f3e, 0x3b08, 0x1750, + 0x0b2e, 0x231c, 0x2f40, 0x3b0a, 0x1752, + 0x0a2e, 0x221c, 0x2e40, 0x3a0a, 0x1652, + 0x092e, 0x211c, 0x2d40, 0x390a, 0x1552, + 0x0930, 0x211e, 0x2d42, 0x390c, 0x1554, + 0x0a30, 0x221e, 0x2e42, 0x3a0c, 0x1654, + 0x0b30, 0x231e, 0x2f42, 0x3b0c, 0x1754, + 0x0b32, 0x2320, 0x2f44, 0x3b0e, 0x1756, + 0x0a32, 0x2220, 0x2e44, 0x3a0e, 0x1656, + 0x0932, 0x2120, 0x2d44, 0x390e, 0x1556, + 0x0934, 0x2122, 0x2d46, 0x3910, 0x1558, + 0x0a34, 0x2222, 0x2e46, 0x3a10, 0x1658, + 0x0b34, 0x2322, 0x2f46, 0x3b10, 0x1758, +}; + +/* 2 channels per frame, 12 DIF sequences per channel, + 27 video segments per DIF sequence, 5 macroblocks per video segment */ +static const uint16_t dv_place_422_625[2*12*27*5] = { + 0x0c24, 0x2412, 0x3036, 0x0000, 0x1848, + 0x0d24, 0x2512, 0x3136, 0x0100, 0x1948, + 0x0e24, 0x2612, 0x3236, 0x0200, 0x1a48, + 0x0e26, 0x2614, 0x3238, 0x0202, 0x1a4a, + 0x0d26, 0x2514, 0x3138, 0x0102, 0x194a, + 0x0c26, 0x2414, 0x3038, 0x0002, 0x184a, + 0x0c28, 0x2416, 0x303a, 0x0004, 0x184c, + 0x0d28, 0x2516, 0x313a, 0x0104, 0x194c, + 0x0e28, 0x2616, 0x323a, 0x0204, 0x1a4c, + 0x0e2a, 0x2618, 0x323c, 0x0206, 0x1a4e, + 0x0d2a, 0x2518, 0x313c, 0x0106, 0x194e, + 0x0c2a, 0x2418, 0x303c, 0x0006, 0x184e, + 0x0c2c, 0x241a, 0x303e, 0x0008, 0x1850, + 0x0d2c, 0x251a, 0x313e, 0x0108, 0x1950, + 0x0e2c, 0x261a, 0x323e, 0x0208, 0x1a50, + 0x0e2e, 0x261c, 0x3240, 0x020a, 0x1a52, + 0x0d2e, 0x251c, 0x3140, 0x010a, 0x1952, + 0x0c2e, 0x241c, 0x3040, 0x000a, 0x1852, + 0x0c30, 0x241e, 0x3042, 0x000c, 0x1854, + 0x0d30, 0x251e, 0x3142, 0x010c, 0x1954, + 0x0e30, 0x261e, 0x3242, 0x020c, 0x1a54, + 0x0e32, 0x2620, 0x3244, 0x020e, 0x1a56, + 0x0d32, 0x2520, 0x3144, 0x010e, 0x1956, + 0x0c32, 0x2420, 0x3044, 0x000e, 0x1856, + 0x0c34, 0x2422, 0x3046, 0x0010, 0x1858, + 0x0d34, 0x2522, 0x3146, 0x0110, 0x1958, + 0x0e34, 0x2622, 0x3246, 0x0210, 0x1a58, + 0x1224, 0x2a12, 0x3636, 0x0600, 0x1e48, + 0x1324, 0x2b12, 0x3736, 0x0700, 0x1f48, + 0x1424, 0x2c12, 0x3836, 0x0800, 0x2048, + 0x1426, 0x2c14, 0x3838, 0x0802, 0x204a, + 0x1326, 0x2b14, 0x3738, 0x0702, 0x1f4a, + 0x1226, 0x2a14, 0x3638, 0x0602, 0x1e4a, + 0x1228, 0x2a16, 0x363a, 0x0604, 0x1e4c, + 0x1328, 0x2b16, 0x373a, 0x0704, 0x1f4c, + 0x1428, 0x2c16, 0x383a, 0x0804, 0x204c, + 0x142a, 0x2c18, 0x383c, 0x0806, 0x204e, + 0x132a, 0x2b18, 0x373c, 0x0706, 0x1f4e, + 0x122a, 0x2a18, 0x363c, 0x0606, 0x1e4e, + 0x122c, 0x2a1a, 0x363e, 0x0608, 0x1e50, + 0x132c, 0x2b1a, 0x373e, 0x0708, 0x1f50, + 0x142c, 0x2c1a, 0x383e, 0x0808, 0x2050, + 0x142e, 0x2c1c, 0x3840, 0x080a, 0x2052, + 0x132e, 0x2b1c, 0x3740, 0x070a, 0x1f52, + 0x122e, 0x2a1c, 0x3640, 0x060a, 0x1e52, + 0x1230, 0x2a1e, 0x3642, 0x060c, 0x1e54, + 0x1330, 0x2b1e, 0x3742, 0x070c, 0x1f54, + 0x1430, 0x2c1e, 0x3842, 0x080c, 0x2054, + 0x1432, 0x2c20, 0x3844, 0x080e, 0x2056, + 0x1332, 0x2b20, 0x3744, 0x070e, 0x1f56, + 0x1232, 0x2a20, 0x3644, 0x060e, 0x1e56, + 0x1234, 0x2a22, 0x3646, 0x0610, 0x1e58, + 0x1334, 0x2b22, 0x3746, 0x0710, 0x1f58, + 0x1434, 0x2c22, 0x3846, 0x0810, 0x2058, + 0x1824, 0x3012, 0x3c36, 0x0c00, 0x2448, + 0x1924, 0x3112, 0x3d36, 0x0d00, 0x2548, + 0x1a24, 0x3212, 0x3e36, 0x0e00, 0x2648, + 0x1a26, 0x3214, 0x3e38, 0x0e02, 0x264a, + 0x1926, 0x3114, 0x3d38, 0x0d02, 0x254a, + 0x1826, 0x3014, 0x3c38, 0x0c02, 0x244a, + 0x1828, 0x3016, 0x3c3a, 0x0c04, 0x244c, + 0x1928, 0x3116, 0x3d3a, 0x0d04, 0x254c, + 0x1a28, 0x3216, 0x3e3a, 0x0e04, 0x264c, + 0x1a2a, 0x3218, 0x3e3c, 0x0e06, 0x264e, + 0x192a, 0x3118, 0x3d3c, 0x0d06, 0x254e, + 0x182a, 0x3018, 0x3c3c, 0x0c06, 0x244e, + 0x182c, 0x301a, 0x3c3e, 0x0c08, 0x2450, + 0x192c, 0x311a, 0x3d3e, 0x0d08, 0x2550, + 0x1a2c, 0x321a, 0x3e3e, 0x0e08, 0x2650, + 0x1a2e, 0x321c, 0x3e40, 0x0e0a, 0x2652, + 0x192e, 0x311c, 0x3d40, 0x0d0a, 0x2552, + 0x182e, 0x301c, 0x3c40, 0x0c0a, 0x2452, + 0x1830, 0x301e, 0x3c42, 0x0c0c, 0x2454, + 0x1930, 0x311e, 0x3d42, 0x0d0c, 0x2554, + 0x1a30, 0x321e, 0x3e42, 0x0e0c, 0x2654, + 0x1a32, 0x3220, 0x3e44, 0x0e0e, 0x2656, + 0x1932, 0x3120, 0x3d44, 0x0d0e, 0x2556, + 0x1832, 0x3020, 0x3c44, 0x0c0e, 0x2456, + 0x1834, 0x3022, 0x3c46, 0x0c10, 0x2458, + 0x1934, 0x3122, 0x3d46, 0x0d10, 0x2558, + 0x1a34, 0x3222, 0x3e46, 0x0e10, 0x2658, + 0x1e24, 0x3612, 0x4236, 0x1200, 0x2a48, + 0x1f24, 0x3712, 0x4336, 0x1300, 0x2b48, + 0x2024, 0x3812, 0x4436, 0x1400, 0x2c48, + 0x2026, 0x3814, 0x4438, 0x1402, 0x2c4a, + 0x1f26, 0x3714, 0x4338, 0x1302, 0x2b4a, + 0x1e26, 0x3614, 0x4238, 0x1202, 0x2a4a, + 0x1e28, 0x3616, 0x423a, 0x1204, 0x2a4c, + 0x1f28, 0x3716, 0x433a, 0x1304, 0x2b4c, + 0x2028, 0x3816, 0x443a, 0x1404, 0x2c4c, + 0x202a, 0x3818, 0x443c, 0x1406, 0x2c4e, + 0x1f2a, 0x3718, 0x433c, 0x1306, 0x2b4e, + 0x1e2a, 0x3618, 0x423c, 0x1206, 0x2a4e, + 0x1e2c, 0x361a, 0x423e, 0x1208, 0x2a50, + 0x1f2c, 0x371a, 0x433e, 0x1308, 0x2b50, + 0x202c, 0x381a, 0x443e, 0x1408, 0x2c50, + 0x202e, 0x381c, 0x4440, 0x140a, 0x2c52, + 0x1f2e, 0x371c, 0x4340, 0x130a, 0x2b52, + 0x1e2e, 0x361c, 0x4240, 0x120a, 0x2a52, + 0x1e30, 0x361e, 0x4242, 0x120c, 0x2a54, + 0x1f30, 0x371e, 0x4342, 0x130c, 0x2b54, + 0x2030, 0x381e, 0x4442, 0x140c, 0x2c54, + 0x2032, 0x3820, 0x4444, 0x140e, 0x2c56, + 0x1f32, 0x3720, 0x4344, 0x130e, 0x2b56, + 0x1e32, 0x3620, 0x4244, 0x120e, 0x2a56, + 0x1e34, 0x3622, 0x4246, 0x1210, 0x2a58, + 0x1f34, 0x3722, 0x4346, 0x1310, 0x2b58, + 0x2034, 0x3822, 0x4446, 0x1410, 0x2c58, + 0x2424, 0x3c12, 0x0036, 0x1800, 0x3048, + 0x2524, 0x3d12, 0x0136, 0x1900, 0x3148, + 0x2624, 0x3e12, 0x0236, 0x1a00, 0x3248, + 0x2626, 0x3e14, 0x0238, 0x1a02, 0x324a, + 0x2526, 0x3d14, 0x0138, 0x1902, 0x314a, + 0x2426, 0x3c14, 0x0038, 0x1802, 0x304a, + 0x2428, 0x3c16, 0x003a, 0x1804, 0x304c, + 0x2528, 0x3d16, 0x013a, 0x1904, 0x314c, + 0x2628, 0x3e16, 0x023a, 0x1a04, 0x324c, + 0x262a, 0x3e18, 0x023c, 0x1a06, 0x324e, + 0x252a, 0x3d18, 0x013c, 0x1906, 0x314e, + 0x242a, 0x3c18, 0x003c, 0x1806, 0x304e, + 0x242c, 0x3c1a, 0x003e, 0x1808, 0x3050, + 0x252c, 0x3d1a, 0x013e, 0x1908, 0x3150, + 0x262c, 0x3e1a, 0x023e, 0x1a08, 0x3250, + 0x262e, 0x3e1c, 0x0240, 0x1a0a, 0x3252, + 0x252e, 0x3d1c, 0x0140, 0x190a, 0x3152, + 0x242e, 0x3c1c, 0x0040, 0x180a, 0x3052, + 0x2430, 0x3c1e, 0x0042, 0x180c, 0x3054, + 0x2530, 0x3d1e, 0x0142, 0x190c, 0x3154, + 0x2630, 0x3e1e, 0x0242, 0x1a0c, 0x3254, + 0x2632, 0x3e20, 0x0244, 0x1a0e, 0x3256, + 0x2532, 0x3d20, 0x0144, 0x190e, 0x3156, + 0x2432, 0x3c20, 0x0044, 0x180e, 0x3056, + 0x2434, 0x3c22, 0x0046, 0x1810, 0x3058, + 0x2534, 0x3d22, 0x0146, 0x1910, 0x3158, + 0x2634, 0x3e22, 0x0246, 0x1a10, 0x3258, + 0x2a24, 0x4212, 0x0636, 0x1e00, 0x3648, + 0x2b24, 0x4312, 0x0736, 0x1f00, 0x3748, + 0x2c24, 0x4412, 0x0836, 0x2000, 0x3848, + 0x2c26, 0x4414, 0x0838, 0x2002, 0x384a, + 0x2b26, 0x4314, 0x0738, 0x1f02, 0x374a, + 0x2a26, 0x4214, 0x0638, 0x1e02, 0x364a, + 0x2a28, 0x4216, 0x063a, 0x1e04, 0x364c, + 0x2b28, 0x4316, 0x073a, 0x1f04, 0x374c, + 0x2c28, 0x4416, 0x083a, 0x2004, 0x384c, + 0x2c2a, 0x4418, 0x083c, 0x2006, 0x384e, + 0x2b2a, 0x4318, 0x073c, 0x1f06, 0x374e, + 0x2a2a, 0x4218, 0x063c, 0x1e06, 0x364e, + 0x2a2c, 0x421a, 0x063e, 0x1e08, 0x3650, + 0x2b2c, 0x431a, 0x073e, 0x1f08, 0x3750, + 0x2c2c, 0x441a, 0x083e, 0x2008, 0x3850, + 0x2c2e, 0x441c, 0x0840, 0x200a, 0x3852, + 0x2b2e, 0x431c, 0x0740, 0x1f0a, 0x3752, + 0x2a2e, 0x421c, 0x0640, 0x1e0a, 0x3652, + 0x2a30, 0x421e, 0x0642, 0x1e0c, 0x3654, + 0x2b30, 0x431e, 0x0742, 0x1f0c, 0x3754, + 0x2c30, 0x441e, 0x0842, 0x200c, 0x3854, + 0x2c32, 0x4420, 0x0844, 0x200e, 0x3856, + 0x2b32, 0x4320, 0x0744, 0x1f0e, 0x3756, + 0x2a32, 0x4220, 0x0644, 0x1e0e, 0x3656, + 0x2a34, 0x4222, 0x0646, 0x1e10, 0x3658, + 0x2b34, 0x4322, 0x0746, 0x1f10, 0x3758, + 0x2c34, 0x4422, 0x0846, 0x2010, 0x3858, + 0x3024, 0x0012, 0x0c36, 0x2400, 0x3c48, + 0x3124, 0x0112, 0x0d36, 0x2500, 0x3d48, + 0x3224, 0x0212, 0x0e36, 0x2600, 0x3e48, + 0x3226, 0x0214, 0x0e38, 0x2602, 0x3e4a, + 0x3126, 0x0114, 0x0d38, 0x2502, 0x3d4a, + 0x3026, 0x0014, 0x0c38, 0x2402, 0x3c4a, + 0x3028, 0x0016, 0x0c3a, 0x2404, 0x3c4c, + 0x3128, 0x0116, 0x0d3a, 0x2504, 0x3d4c, + 0x3228, 0x0216, 0x0e3a, 0x2604, 0x3e4c, + 0x322a, 0x0218, 0x0e3c, 0x2606, 0x3e4e, + 0x312a, 0x0118, 0x0d3c, 0x2506, 0x3d4e, + 0x302a, 0x0018, 0x0c3c, 0x2406, 0x3c4e, + 0x302c, 0x001a, 0x0c3e, 0x2408, 0x3c50, + 0x312c, 0x011a, 0x0d3e, 0x2508, 0x3d50, + 0x322c, 0x021a, 0x0e3e, 0x2608, 0x3e50, + 0x322e, 0x021c, 0x0e40, 0x260a, 0x3e52, + 0x312e, 0x011c, 0x0d40, 0x250a, 0x3d52, + 0x302e, 0x001c, 0x0c40, 0x240a, 0x3c52, + 0x3030, 0x001e, 0x0c42, 0x240c, 0x3c54, + 0x3130, 0x011e, 0x0d42, 0x250c, 0x3d54, + 0x3230, 0x021e, 0x0e42, 0x260c, 0x3e54, + 0x3232, 0x0220, 0x0e44, 0x260e, 0x3e56, + 0x3132, 0x0120, 0x0d44, 0x250e, 0x3d56, + 0x3032, 0x0020, 0x0c44, 0x240e, 0x3c56, + 0x3034, 0x0022, 0x0c46, 0x2410, 0x3c58, + 0x3134, 0x0122, 0x0d46, 0x2510, 0x3d58, + 0x3234, 0x0222, 0x0e46, 0x2610, 0x3e58, + 0x3624, 0x0612, 0x1236, 0x2a00, 0x4248, + 0x3724, 0x0712, 0x1336, 0x2b00, 0x4348, + 0x3824, 0x0812, 0x1436, 0x2c00, 0x4448, + 0x3826, 0x0814, 0x1438, 0x2c02, 0x444a, + 0x3726, 0x0714, 0x1338, 0x2b02, 0x434a, + 0x3626, 0x0614, 0x1238, 0x2a02, 0x424a, + 0x3628, 0x0616, 0x123a, 0x2a04, 0x424c, + 0x3728, 0x0716, 0x133a, 0x2b04, 0x434c, + 0x3828, 0x0816, 0x143a, 0x2c04, 0x444c, + 0x382a, 0x0818, 0x143c, 0x2c06, 0x444e, + 0x372a, 0x0718, 0x133c, 0x2b06, 0x434e, + 0x362a, 0x0618, 0x123c, 0x2a06, 0x424e, + 0x362c, 0x061a, 0x123e, 0x2a08, 0x4250, + 0x372c, 0x071a, 0x133e, 0x2b08, 0x4350, + 0x382c, 0x081a, 0x143e, 0x2c08, 0x4450, + 0x382e, 0x081c, 0x1440, 0x2c0a, 0x4452, + 0x372e, 0x071c, 0x1340, 0x2b0a, 0x4352, + 0x362e, 0x061c, 0x1240, 0x2a0a, 0x4252, + 0x3630, 0x061e, 0x1242, 0x2a0c, 0x4254, + 0x3730, 0x071e, 0x1342, 0x2b0c, 0x4354, + 0x3830, 0x081e, 0x1442, 0x2c0c, 0x4454, + 0x3832, 0x0820, 0x1444, 0x2c0e, 0x4456, + 0x3732, 0x0720, 0x1344, 0x2b0e, 0x4356, + 0x3632, 0x0620, 0x1244, 0x2a0e, 0x4256, + 0x3634, 0x0622, 0x1246, 0x2a10, 0x4258, + 0x3734, 0x0722, 0x1346, 0x2b10, 0x4358, + 0x3834, 0x0822, 0x1446, 0x2c10, 0x4458, + 0x3c24, 0x0c12, 0x1836, 0x3000, 0x0048, + 0x3d24, 0x0d12, 0x1936, 0x3100, 0x0148, + 0x3e24, 0x0e12, 0x1a36, 0x3200, 0x0248, + 0x3e26, 0x0e14, 0x1a38, 0x3202, 0x024a, + 0x3d26, 0x0d14, 0x1938, 0x3102, 0x014a, + 0x3c26, 0x0c14, 0x1838, 0x3002, 0x004a, + 0x3c28, 0x0c16, 0x183a, 0x3004, 0x004c, + 0x3d28, 0x0d16, 0x193a, 0x3104, 0x014c, + 0x3e28, 0x0e16, 0x1a3a, 0x3204, 0x024c, + 0x3e2a, 0x0e18, 0x1a3c, 0x3206, 0x024e, + 0x3d2a, 0x0d18, 0x193c, 0x3106, 0x014e, + 0x3c2a, 0x0c18, 0x183c, 0x3006, 0x004e, + 0x3c2c, 0x0c1a, 0x183e, 0x3008, 0x0050, + 0x3d2c, 0x0d1a, 0x193e, 0x3108, 0x0150, + 0x3e2c, 0x0e1a, 0x1a3e, 0x3208, 0x0250, + 0x3e2e, 0x0e1c, 0x1a40, 0x320a, 0x0252, + 0x3d2e, 0x0d1c, 0x1940, 0x310a, 0x0152, + 0x3c2e, 0x0c1c, 0x1840, 0x300a, 0x0052, + 0x3c30, 0x0c1e, 0x1842, 0x300c, 0x0054, + 0x3d30, 0x0d1e, 0x1942, 0x310c, 0x0154, + 0x3e30, 0x0e1e, 0x1a42, 0x320c, 0x0254, + 0x3e32, 0x0e20, 0x1a44, 0x320e, 0x0256, + 0x3d32, 0x0d20, 0x1944, 0x310e, 0x0156, + 0x3c32, 0x0c20, 0x1844, 0x300e, 0x0056, + 0x3c34, 0x0c22, 0x1846, 0x3010, 0x0058, + 0x3d34, 0x0d22, 0x1946, 0x3110, 0x0158, + 0x3e34, 0x0e22, 0x1a46, 0x3210, 0x0258, + 0x4224, 0x1212, 0x1e36, 0x3600, 0x0648, + 0x4324, 0x1312, 0x1f36, 0x3700, 0x0748, + 0x4424, 0x1412, 0x2036, 0x3800, 0x0848, + 0x4426, 0x1414, 0x2038, 0x3802, 0x084a, + 0x4326, 0x1314, 0x1f38, 0x3702, 0x074a, + 0x4226, 0x1214, 0x1e38, 0x3602, 0x064a, + 0x4228, 0x1216, 0x1e3a, 0x3604, 0x064c, + 0x4328, 0x1316, 0x1f3a, 0x3704, 0x074c, + 0x4428, 0x1416, 0x203a, 0x3804, 0x084c, + 0x442a, 0x1418, 0x203c, 0x3806, 0x084e, + 0x432a, 0x1318, 0x1f3c, 0x3706, 0x074e, + 0x422a, 0x1218, 0x1e3c, 0x3606, 0x064e, + 0x422c, 0x121a, 0x1e3e, 0x3608, 0x0650, + 0x432c, 0x131a, 0x1f3e, 0x3708, 0x0750, + 0x442c, 0x141a, 0x203e, 0x3808, 0x0850, + 0x442e, 0x141c, 0x2040, 0x380a, 0x0852, + 0x432e, 0x131c, 0x1f40, 0x370a, 0x0752, + 0x422e, 0x121c, 0x1e40, 0x360a, 0x0652, + 0x4230, 0x121e, 0x1e42, 0x360c, 0x0654, + 0x4330, 0x131e, 0x1f42, 0x370c, 0x0754, + 0x4430, 0x141e, 0x2042, 0x380c, 0x0854, + 0x4432, 0x1420, 0x2044, 0x380e, 0x0856, + 0x4332, 0x1320, 0x1f44, 0x370e, 0x0756, + 0x4232, 0x1220, 0x1e44, 0x360e, 0x0656, + 0x4234, 0x1222, 0x1e46, 0x3610, 0x0658, + 0x4334, 0x1322, 0x1f46, 0x3710, 0x0758, + 0x4434, 0x1422, 0x2046, 0x3810, 0x0858, + 0x0024, 0x1812, 0x2436, 0x3c00, 0x0c48, + 0x0124, 0x1912, 0x2536, 0x3d00, 0x0d48, + 0x0224, 0x1a12, 0x2636, 0x3e00, 0x0e48, + 0x0226, 0x1a14, 0x2638, 0x3e02, 0x0e4a, + 0x0126, 0x1914, 0x2538, 0x3d02, 0x0d4a, + 0x0026, 0x1814, 0x2438, 0x3c02, 0x0c4a, + 0x0028, 0x1816, 0x243a, 0x3c04, 0x0c4c, + 0x0128, 0x1916, 0x253a, 0x3d04, 0x0d4c, + 0x0228, 0x1a16, 0x263a, 0x3e04, 0x0e4c, + 0x022a, 0x1a18, 0x263c, 0x3e06, 0x0e4e, + 0x012a, 0x1918, 0x253c, 0x3d06, 0x0d4e, + 0x002a, 0x1818, 0x243c, 0x3c06, 0x0c4e, + 0x002c, 0x181a, 0x243e, 0x3c08, 0x0c50, + 0x012c, 0x191a, 0x253e, 0x3d08, 0x0d50, + 0x022c, 0x1a1a, 0x263e, 0x3e08, 0x0e50, + 0x022e, 0x1a1c, 0x2640, 0x3e0a, 0x0e52, + 0x012e, 0x191c, 0x2540, 0x3d0a, 0x0d52, + 0x002e, 0x181c, 0x2440, 0x3c0a, 0x0c52, + 0x0030, 0x181e, 0x2442, 0x3c0c, 0x0c54, + 0x0130, 0x191e, 0x2542, 0x3d0c, 0x0d54, + 0x0230, 0x1a1e, 0x2642, 0x3e0c, 0x0e54, + 0x0232, 0x1a20, 0x2644, 0x3e0e, 0x0e56, + 0x0132, 0x1920, 0x2544, 0x3d0e, 0x0d56, + 0x0032, 0x1820, 0x2444, 0x3c0e, 0x0c56, + 0x0034, 0x1822, 0x2446, 0x3c10, 0x0c58, + 0x0134, 0x1922, 0x2546, 0x3d10, 0x0d58, + 0x0234, 0x1a22, 0x2646, 0x3e10, 0x0e58, + 0x0624, 0x1e12, 0x2a36, 0x4200, 0x1248, + 0x0724, 0x1f12, 0x2b36, 0x4300, 0x1348, + 0x0824, 0x2012, 0x2c36, 0x4400, 0x1448, + 0x0826, 0x2014, 0x2c38, 0x4402, 0x144a, + 0x0726, 0x1f14, 0x2b38, 0x4302, 0x134a, + 0x0626, 0x1e14, 0x2a38, 0x4202, 0x124a, + 0x0628, 0x1e16, 0x2a3a, 0x4204, 0x124c, + 0x0728, 0x1f16, 0x2b3a, 0x4304, 0x134c, + 0x0828, 0x2016, 0x2c3a, 0x4404, 0x144c, + 0x082a, 0x2018, 0x2c3c, 0x4406, 0x144e, + 0x072a, 0x1f18, 0x2b3c, 0x4306, 0x134e, + 0x062a, 0x1e18, 0x2a3c, 0x4206, 0x124e, + 0x062c, 0x1e1a, 0x2a3e, 0x4208, 0x1250, + 0x072c, 0x1f1a, 0x2b3e, 0x4308, 0x1350, + 0x082c, 0x201a, 0x2c3e, 0x4408, 0x1450, + 0x082e, 0x201c, 0x2c40, 0x440a, 0x1452, + 0x072e, 0x1f1c, 0x2b40, 0x430a, 0x1352, + 0x062e, 0x1e1c, 0x2a40, 0x420a, 0x1252, + 0x0630, 0x1e1e, 0x2a42, 0x420c, 0x1254, + 0x0730, 0x1f1e, 0x2b42, 0x430c, 0x1354, + 0x0830, 0x201e, 0x2c42, 0x440c, 0x1454, + 0x0832, 0x2020, 0x2c44, 0x440e, 0x1456, + 0x0732, 0x1f20, 0x2b44, 0x430e, 0x1356, + 0x0632, 0x1e20, 0x2a44, 0x420e, 0x1256, + 0x0634, 0x1e22, 0x2a46, 0x4210, 0x1258, + 0x0734, 0x1f22, 0x2b46, 0x4310, 0x1358, + 0x0834, 0x2022, 0x2c46, 0x4410, 0x1458, + 0x0f24, 0x2712, 0x3336, 0x0300, 0x1b48, + 0x1024, 0x2812, 0x3436, 0x0400, 0x1c48, + 0x1124, 0x2912, 0x3536, 0x0500, 0x1d48, + 0x1126, 0x2914, 0x3538, 0x0502, 0x1d4a, + 0x1026, 0x2814, 0x3438, 0x0402, 0x1c4a, + 0x0f26, 0x2714, 0x3338, 0x0302, 0x1b4a, + 0x0f28, 0x2716, 0x333a, 0x0304, 0x1b4c, + 0x1028, 0x2816, 0x343a, 0x0404, 0x1c4c, + 0x1128, 0x2916, 0x353a, 0x0504, 0x1d4c, + 0x112a, 0x2918, 0x353c, 0x0506, 0x1d4e, + 0x102a, 0x2818, 0x343c, 0x0406, 0x1c4e, + 0x0f2a, 0x2718, 0x333c, 0x0306, 0x1b4e, + 0x0f2c, 0x271a, 0x333e, 0x0308, 0x1b50, + 0x102c, 0x281a, 0x343e, 0x0408, 0x1c50, + 0x112c, 0x291a, 0x353e, 0x0508, 0x1d50, + 0x112e, 0x291c, 0x3540, 0x050a, 0x1d52, + 0x102e, 0x281c, 0x3440, 0x040a, 0x1c52, + 0x0f2e, 0x271c, 0x3340, 0x030a, 0x1b52, + 0x0f30, 0x271e, 0x3342, 0x030c, 0x1b54, + 0x1030, 0x281e, 0x3442, 0x040c, 0x1c54, + 0x1130, 0x291e, 0x3542, 0x050c, 0x1d54, + 0x1132, 0x2920, 0x3544, 0x050e, 0x1d56, + 0x1032, 0x2820, 0x3444, 0x040e, 0x1c56, + 0x0f32, 0x2720, 0x3344, 0x030e, 0x1b56, + 0x0f34, 0x2722, 0x3346, 0x0310, 0x1b58, + 0x1034, 0x2822, 0x3446, 0x0410, 0x1c58, + 0x1134, 0x2922, 0x3546, 0x0510, 0x1d58, + 0x1524, 0x2d12, 0x3936, 0x0900, 0x2148, + 0x1624, 0x2e12, 0x3a36, 0x0a00, 0x2248, + 0x1724, 0x2f12, 0x3b36, 0x0b00, 0x2348, + 0x1726, 0x2f14, 0x3b38, 0x0b02, 0x234a, + 0x1626, 0x2e14, 0x3a38, 0x0a02, 0x224a, + 0x1526, 0x2d14, 0x3938, 0x0902, 0x214a, + 0x1528, 0x2d16, 0x393a, 0x0904, 0x214c, + 0x1628, 0x2e16, 0x3a3a, 0x0a04, 0x224c, + 0x1728, 0x2f16, 0x3b3a, 0x0b04, 0x234c, + 0x172a, 0x2f18, 0x3b3c, 0x0b06, 0x234e, + 0x162a, 0x2e18, 0x3a3c, 0x0a06, 0x224e, + 0x152a, 0x2d18, 0x393c, 0x0906, 0x214e, + 0x152c, 0x2d1a, 0x393e, 0x0908, 0x2150, + 0x162c, 0x2e1a, 0x3a3e, 0x0a08, 0x2250, + 0x172c, 0x2f1a, 0x3b3e, 0x0b08, 0x2350, + 0x172e, 0x2f1c, 0x3b40, 0x0b0a, 0x2352, + 0x162e, 0x2e1c, 0x3a40, 0x0a0a, 0x2252, + 0x152e, 0x2d1c, 0x3940, 0x090a, 0x2152, + 0x1530, 0x2d1e, 0x3942, 0x090c, 0x2154, + 0x1630, 0x2e1e, 0x3a42, 0x0a0c, 0x2254, + 0x1730, 0x2f1e, 0x3b42, 0x0b0c, 0x2354, + 0x1732, 0x2f20, 0x3b44, 0x0b0e, 0x2356, + 0x1632, 0x2e20, 0x3a44, 0x0a0e, 0x2256, + 0x1532, 0x2d20, 0x3944, 0x090e, 0x2156, + 0x1534, 0x2d22, 0x3946, 0x0910, 0x2158, + 0x1634, 0x2e22, 0x3a46, 0x0a10, 0x2258, + 0x1734, 0x2f22, 0x3b46, 0x0b10, 0x2358, + 0x1b24, 0x3312, 0x3f36, 0x0f00, 0x2748, + 0x1c24, 0x3412, 0x4036, 0x1000, 0x2848, + 0x1d24, 0x3512, 0x4136, 0x1100, 0x2948, + 0x1d26, 0x3514, 0x4138, 0x1102, 0x294a, + 0x1c26, 0x3414, 0x4038, 0x1002, 0x284a, + 0x1b26, 0x3314, 0x3f38, 0x0f02, 0x274a, + 0x1b28, 0x3316, 0x3f3a, 0x0f04, 0x274c, + 0x1c28, 0x3416, 0x403a, 0x1004, 0x284c, + 0x1d28, 0x3516, 0x413a, 0x1104, 0x294c, + 0x1d2a, 0x3518, 0x413c, 0x1106, 0x294e, + 0x1c2a, 0x3418, 0x403c, 0x1006, 0x284e, + 0x1b2a, 0x3318, 0x3f3c, 0x0f06, 0x274e, + 0x1b2c, 0x331a, 0x3f3e, 0x0f08, 0x2750, + 0x1c2c, 0x341a, 0x403e, 0x1008, 0x2850, + 0x1d2c, 0x351a, 0x413e, 0x1108, 0x2950, + 0x1d2e, 0x351c, 0x4140, 0x110a, 0x2952, + 0x1c2e, 0x341c, 0x4040, 0x100a, 0x2852, + 0x1b2e, 0x331c, 0x3f40, 0x0f0a, 0x2752, + 0x1b30, 0x331e, 0x3f42, 0x0f0c, 0x2754, + 0x1c30, 0x341e, 0x4042, 0x100c, 0x2854, + 0x1d30, 0x351e, 0x4142, 0x110c, 0x2954, + 0x1d32, 0x3520, 0x4144, 0x110e, 0x2956, + 0x1c32, 0x3420, 0x4044, 0x100e, 0x2856, + 0x1b32, 0x3320, 0x3f44, 0x0f0e, 0x2756, + 0x1b34, 0x3322, 0x3f46, 0x0f10, 0x2758, + 0x1c34, 0x3422, 0x4046, 0x1010, 0x2858, + 0x1d34, 0x3522, 0x4146, 0x1110, 0x2958, + 0x2124, 0x3912, 0x4536, 0x1500, 0x2d48, + 0x2224, 0x3a12, 0x4636, 0x1600, 0x2e48, + 0x2324, 0x3b12, 0x4736, 0x1700, 0x2f48, + 0x2326, 0x3b14, 0x4738, 0x1702, 0x2f4a, + 0x2226, 0x3a14, 0x4638, 0x1602, 0x2e4a, + 0x2126, 0x3914, 0x4538, 0x1502, 0x2d4a, + 0x2128, 0x3916, 0x453a, 0x1504, 0x2d4c, + 0x2228, 0x3a16, 0x463a, 0x1604, 0x2e4c, + 0x2328, 0x3b16, 0x473a, 0x1704, 0x2f4c, + 0x232a, 0x3b18, 0x473c, 0x1706, 0x2f4e, + 0x222a, 0x3a18, 0x463c, 0x1606, 0x2e4e, + 0x212a, 0x3918, 0x453c, 0x1506, 0x2d4e, + 0x212c, 0x391a, 0x453e, 0x1508, 0x2d50, + 0x222c, 0x3a1a, 0x463e, 0x1608, 0x2e50, + 0x232c, 0x3b1a, 0x473e, 0x1708, 0x2f50, + 0x232e, 0x3b1c, 0x4740, 0x170a, 0x2f52, + 0x222e, 0x3a1c, 0x4640, 0x160a, 0x2e52, + 0x212e, 0x391c, 0x4540, 0x150a, 0x2d52, + 0x2130, 0x391e, 0x4542, 0x150c, 0x2d54, + 0x2230, 0x3a1e, 0x4642, 0x160c, 0x2e54, + 0x2330, 0x3b1e, 0x4742, 0x170c, 0x2f54, + 0x2332, 0x3b20, 0x4744, 0x170e, 0x2f56, + 0x2232, 0x3a20, 0x4644, 0x160e, 0x2e56, + 0x2132, 0x3920, 0x4544, 0x150e, 0x2d56, + 0x2134, 0x3922, 0x4546, 0x1510, 0x2d58, + 0x2234, 0x3a22, 0x4646, 0x1610, 0x2e58, + 0x2334, 0x3b22, 0x4746, 0x1710, 0x2f58, + 0x2724, 0x3f12, 0x0336, 0x1b00, 0x3348, + 0x2824, 0x4012, 0x0436, 0x1c00, 0x3448, + 0x2924, 0x4112, 0x0536, 0x1d00, 0x3548, + 0x2926, 0x4114, 0x0538, 0x1d02, 0x354a, + 0x2826, 0x4014, 0x0438, 0x1c02, 0x344a, + 0x2726, 0x3f14, 0x0338, 0x1b02, 0x334a, + 0x2728, 0x3f16, 0x033a, 0x1b04, 0x334c, + 0x2828, 0x4016, 0x043a, 0x1c04, 0x344c, + 0x2928, 0x4116, 0x053a, 0x1d04, 0x354c, + 0x292a, 0x4118, 0x053c, 0x1d06, 0x354e, + 0x282a, 0x4018, 0x043c, 0x1c06, 0x344e, + 0x272a, 0x3f18, 0x033c, 0x1b06, 0x334e, + 0x272c, 0x3f1a, 0x033e, 0x1b08, 0x3350, + 0x282c, 0x401a, 0x043e, 0x1c08, 0x3450, + 0x292c, 0x411a, 0x053e, 0x1d08, 0x3550, + 0x292e, 0x411c, 0x0540, 0x1d0a, 0x3552, + 0x282e, 0x401c, 0x0440, 0x1c0a, 0x3452, + 0x272e, 0x3f1c, 0x0340, 0x1b0a, 0x3352, + 0x2730, 0x3f1e, 0x0342, 0x1b0c, 0x3354, + 0x2830, 0x401e, 0x0442, 0x1c0c, 0x3454, + 0x2930, 0x411e, 0x0542, 0x1d0c, 0x3554, + 0x2932, 0x4120, 0x0544, 0x1d0e, 0x3556, + 0x2832, 0x4020, 0x0444, 0x1c0e, 0x3456, + 0x2732, 0x3f20, 0x0344, 0x1b0e, 0x3356, + 0x2734, 0x3f22, 0x0346, 0x1b10, 0x3358, + 0x2834, 0x4022, 0x0446, 0x1c10, 0x3458, + 0x2934, 0x4122, 0x0546, 0x1d10, 0x3558, + 0x2d24, 0x4512, 0x0936, 0x2100, 0x3948, + 0x2e24, 0x4612, 0x0a36, 0x2200, 0x3a48, + 0x2f24, 0x4712, 0x0b36, 0x2300, 0x3b48, + 0x2f26, 0x4714, 0x0b38, 0x2302, 0x3b4a, + 0x2e26, 0x4614, 0x0a38, 0x2202, 0x3a4a, + 0x2d26, 0x4514, 0x0938, 0x2102, 0x394a, + 0x2d28, 0x4516, 0x093a, 0x2104, 0x394c, + 0x2e28, 0x4616, 0x0a3a, 0x2204, 0x3a4c, + 0x2f28, 0x4716, 0x0b3a, 0x2304, 0x3b4c, + 0x2f2a, 0x4718, 0x0b3c, 0x2306, 0x3b4e, + 0x2e2a, 0x4618, 0x0a3c, 0x2206, 0x3a4e, + 0x2d2a, 0x4518, 0x093c, 0x2106, 0x394e, + 0x2d2c, 0x451a, 0x093e, 0x2108, 0x3950, + 0x2e2c, 0x461a, 0x0a3e, 0x2208, 0x3a50, + 0x2f2c, 0x471a, 0x0b3e, 0x2308, 0x3b50, + 0x2f2e, 0x471c, 0x0b40, 0x230a, 0x3b52, + 0x2e2e, 0x461c, 0x0a40, 0x220a, 0x3a52, + 0x2d2e, 0x451c, 0x0940, 0x210a, 0x3952, + 0x2d30, 0x451e, 0x0942, 0x210c, 0x3954, + 0x2e30, 0x461e, 0x0a42, 0x220c, 0x3a54, + 0x2f30, 0x471e, 0x0b42, 0x230c, 0x3b54, + 0x2f32, 0x4720, 0x0b44, 0x230e, 0x3b56, + 0x2e32, 0x4620, 0x0a44, 0x220e, 0x3a56, + 0x2d32, 0x4520, 0x0944, 0x210e, 0x3956, + 0x2d34, 0x4522, 0x0946, 0x2110, 0x3958, + 0x2e34, 0x4622, 0x0a46, 0x2210, 0x3a58, + 0x2f34, 0x4722, 0x0b46, 0x2310, 0x3b58, + 0x3324, 0x0312, 0x0f36, 0x2700, 0x3f48, + 0x3424, 0x0412, 0x1036, 0x2800, 0x4048, + 0x3524, 0x0512, 0x1136, 0x2900, 0x4148, + 0x3526, 0x0514, 0x1138, 0x2902, 0x414a, + 0x3426, 0x0414, 0x1038, 0x2802, 0x404a, + 0x3326, 0x0314, 0x0f38, 0x2702, 0x3f4a, + 0x3328, 0x0316, 0x0f3a, 0x2704, 0x3f4c, + 0x3428, 0x0416, 0x103a, 0x2804, 0x404c, + 0x3528, 0x0516, 0x113a, 0x2904, 0x414c, + 0x352a, 0x0518, 0x113c, 0x2906, 0x414e, + 0x342a, 0x0418, 0x103c, 0x2806, 0x404e, + 0x332a, 0x0318, 0x0f3c, 0x2706, 0x3f4e, + 0x332c, 0x031a, 0x0f3e, 0x2708, 0x3f50, + 0x342c, 0x041a, 0x103e, 0x2808, 0x4050, + 0x352c, 0x051a, 0x113e, 0x2908, 0x4150, + 0x352e, 0x051c, 0x1140, 0x290a, 0x4152, + 0x342e, 0x041c, 0x1040, 0x280a, 0x4052, + 0x332e, 0x031c, 0x0f40, 0x270a, 0x3f52, + 0x3330, 0x031e, 0x0f42, 0x270c, 0x3f54, + 0x3430, 0x041e, 0x1042, 0x280c, 0x4054, + 0x3530, 0x051e, 0x1142, 0x290c, 0x4154, + 0x3532, 0x0520, 0x1144, 0x290e, 0x4156, + 0x3432, 0x0420, 0x1044, 0x280e, 0x4056, + 0x3332, 0x0320, 0x0f44, 0x270e, 0x3f56, + 0x3334, 0x0322, 0x0f46, 0x2710, 0x3f58, + 0x3434, 0x0422, 0x1046, 0x2810, 0x4058, + 0x3534, 0x0522, 0x1146, 0x2910, 0x4158, + 0x3924, 0x0912, 0x1536, 0x2d00, 0x4548, + 0x3a24, 0x0a12, 0x1636, 0x2e00, 0x4648, + 0x3b24, 0x0b12, 0x1736, 0x2f00, 0x4748, + 0x3b26, 0x0b14, 0x1738, 0x2f02, 0x474a, + 0x3a26, 0x0a14, 0x1638, 0x2e02, 0x464a, + 0x3926, 0x0914, 0x1538, 0x2d02, 0x454a, + 0x3928, 0x0916, 0x153a, 0x2d04, 0x454c, + 0x3a28, 0x0a16, 0x163a, 0x2e04, 0x464c, + 0x3b28, 0x0b16, 0x173a, 0x2f04, 0x474c, + 0x3b2a, 0x0b18, 0x173c, 0x2f06, 0x474e, + 0x3a2a, 0x0a18, 0x163c, 0x2e06, 0x464e, + 0x392a, 0x0918, 0x153c, 0x2d06, 0x454e, + 0x392c, 0x091a, 0x153e, 0x2d08, 0x4550, + 0x3a2c, 0x0a1a, 0x163e, 0x2e08, 0x4650, + 0x3b2c, 0x0b1a, 0x173e, 0x2f08, 0x4750, + 0x3b2e, 0x0b1c, 0x1740, 0x2f0a, 0x4752, + 0x3a2e, 0x0a1c, 0x1640, 0x2e0a, 0x4652, + 0x392e, 0x091c, 0x1540, 0x2d0a, 0x4552, + 0x3930, 0x091e, 0x1542, 0x2d0c, 0x4554, + 0x3a30, 0x0a1e, 0x1642, 0x2e0c, 0x4654, + 0x3b30, 0x0b1e, 0x1742, 0x2f0c, 0x4754, + 0x3b32, 0x0b20, 0x1744, 0x2f0e, 0x4756, + 0x3a32, 0x0a20, 0x1644, 0x2e0e, 0x4656, + 0x3932, 0x0920, 0x1544, 0x2d0e, 0x4556, + 0x3934, 0x0922, 0x1546, 0x2d10, 0x4558, + 0x3a34, 0x0a22, 0x1646, 0x2e10, 0x4658, + 0x3b34, 0x0b22, 0x1746, 0x2f10, 0x4758, + 0x3f24, 0x0f12, 0x1b36, 0x3300, 0x0348, + 0x4024, 0x1012, 0x1c36, 0x3400, 0x0448, + 0x4124, 0x1112, 0x1d36, 0x3500, 0x0548, + 0x4126, 0x1114, 0x1d38, 0x3502, 0x054a, + 0x4026, 0x1014, 0x1c38, 0x3402, 0x044a, + 0x3f26, 0x0f14, 0x1b38, 0x3302, 0x034a, + 0x3f28, 0x0f16, 0x1b3a, 0x3304, 0x034c, + 0x4028, 0x1016, 0x1c3a, 0x3404, 0x044c, + 0x4128, 0x1116, 0x1d3a, 0x3504, 0x054c, + 0x412a, 0x1118, 0x1d3c, 0x3506, 0x054e, + 0x402a, 0x1018, 0x1c3c, 0x3406, 0x044e, + 0x3f2a, 0x0f18, 0x1b3c, 0x3306, 0x034e, + 0x3f2c, 0x0f1a, 0x1b3e, 0x3308, 0x0350, + 0x402c, 0x101a, 0x1c3e, 0x3408, 0x0450, + 0x412c, 0x111a, 0x1d3e, 0x3508, 0x0550, + 0x412e, 0x111c, 0x1d40, 0x350a, 0x0552, + 0x402e, 0x101c, 0x1c40, 0x340a, 0x0452, + 0x3f2e, 0x0f1c, 0x1b40, 0x330a, 0x0352, + 0x3f30, 0x0f1e, 0x1b42, 0x330c, 0x0354, + 0x4030, 0x101e, 0x1c42, 0x340c, 0x0454, + 0x4130, 0x111e, 0x1d42, 0x350c, 0x0554, + 0x4132, 0x1120, 0x1d44, 0x350e, 0x0556, + 0x4032, 0x1020, 0x1c44, 0x340e, 0x0456, + 0x3f32, 0x0f20, 0x1b44, 0x330e, 0x0356, + 0x3f34, 0x0f22, 0x1b46, 0x3310, 0x0358, + 0x4034, 0x1022, 0x1c46, 0x3410, 0x0458, + 0x4134, 0x1122, 0x1d46, 0x3510, 0x0558, + 0x4524, 0x1512, 0x2136, 0x3900, 0x0948, + 0x4624, 0x1612, 0x2236, 0x3a00, 0x0a48, + 0x4724, 0x1712, 0x2336, 0x3b00, 0x0b48, + 0x4726, 0x1714, 0x2338, 0x3b02, 0x0b4a, + 0x4626, 0x1614, 0x2238, 0x3a02, 0x0a4a, + 0x4526, 0x1514, 0x2138, 0x3902, 0x094a, + 0x4528, 0x1516, 0x213a, 0x3904, 0x094c, + 0x4628, 0x1616, 0x223a, 0x3a04, 0x0a4c, + 0x4728, 0x1716, 0x233a, 0x3b04, 0x0b4c, + 0x472a, 0x1718, 0x233c, 0x3b06, 0x0b4e, + 0x462a, 0x1618, 0x223c, 0x3a06, 0x0a4e, + 0x452a, 0x1518, 0x213c, 0x3906, 0x094e, + 0x452c, 0x151a, 0x213e, 0x3908, 0x0950, + 0x462c, 0x161a, 0x223e, 0x3a08, 0x0a50, + 0x472c, 0x171a, 0x233e, 0x3b08, 0x0b50, + 0x472e, 0x171c, 0x2340, 0x3b0a, 0x0b52, + 0x462e, 0x161c, 0x2240, 0x3a0a, 0x0a52, + 0x452e, 0x151c, 0x2140, 0x390a, 0x0952, + 0x4530, 0x151e, 0x2142, 0x390c, 0x0954, + 0x4630, 0x161e, 0x2242, 0x3a0c, 0x0a54, + 0x4730, 0x171e, 0x2342, 0x3b0c, 0x0b54, + 0x4732, 0x1720, 0x2344, 0x3b0e, 0x0b56, + 0x4632, 0x1620, 0x2244, 0x3a0e, 0x0a56, + 0x4532, 0x1520, 0x2144, 0x390e, 0x0956, + 0x4534, 0x1522, 0x2146, 0x3910, 0x0958, + 0x4634, 0x1622, 0x2246, 0x3a10, 0x0a58, + 0x4734, 0x1722, 0x2346, 0x3b10, 0x0b58, + 0x0324, 0x1b12, 0x2736, 0x3f00, 0x0f48, + 0x0424, 0x1c12, 0x2836, 0x4000, 0x1048, + 0x0524, 0x1d12, 0x2936, 0x4100, 0x1148, + 0x0526, 0x1d14, 0x2938, 0x4102, 0x114a, + 0x0426, 0x1c14, 0x2838, 0x4002, 0x104a, + 0x0326, 0x1b14, 0x2738, 0x3f02, 0x0f4a, + 0x0328, 0x1b16, 0x273a, 0x3f04, 0x0f4c, + 0x0428, 0x1c16, 0x283a, 0x4004, 0x104c, + 0x0528, 0x1d16, 0x293a, 0x4104, 0x114c, + 0x052a, 0x1d18, 0x293c, 0x4106, 0x114e, + 0x042a, 0x1c18, 0x283c, 0x4006, 0x104e, + 0x032a, 0x1b18, 0x273c, 0x3f06, 0x0f4e, + 0x032c, 0x1b1a, 0x273e, 0x3f08, 0x0f50, + 0x042c, 0x1c1a, 0x283e, 0x4008, 0x1050, + 0x052c, 0x1d1a, 0x293e, 0x4108, 0x1150, + 0x052e, 0x1d1c, 0x2940, 0x410a, 0x1152, + 0x042e, 0x1c1c, 0x2840, 0x400a, 0x1052, + 0x032e, 0x1b1c, 0x2740, 0x3f0a, 0x0f52, + 0x0330, 0x1b1e, 0x2742, 0x3f0c, 0x0f54, + 0x0430, 0x1c1e, 0x2842, 0x400c, 0x1054, + 0x0530, 0x1d1e, 0x2942, 0x410c, 0x1154, + 0x0532, 0x1d20, 0x2944, 0x410e, 0x1156, + 0x0432, 0x1c20, 0x2844, 0x400e, 0x1056, + 0x0332, 0x1b20, 0x2744, 0x3f0e, 0x0f56, + 0x0334, 0x1b22, 0x2746, 0x3f10, 0x0f58, + 0x0434, 0x1c22, 0x2846, 0x4010, 0x1058, + 0x0534, 0x1d22, 0x2946, 0x4110, 0x1158, + 0x0924, 0x2112, 0x2d36, 0x4500, 0x1548, + 0x0a24, 0x2212, 0x2e36, 0x4600, 0x1648, + 0x0b24, 0x2312, 0x2f36, 0x4700, 0x1748, + 0x0b26, 0x2314, 0x2f38, 0x4702, 0x174a, + 0x0a26, 0x2214, 0x2e38, 0x4602, 0x164a, + 0x0926, 0x2114, 0x2d38, 0x4502, 0x154a, + 0x0928, 0x2116, 0x2d3a, 0x4504, 0x154c, + 0x0a28, 0x2216, 0x2e3a, 0x4604, 0x164c, + 0x0b28, 0x2316, 0x2f3a, 0x4704, 0x174c, + 0x0b2a, 0x2318, 0x2f3c, 0x4706, 0x174e, + 0x0a2a, 0x2218, 0x2e3c, 0x4606, 0x164e, + 0x092a, 0x2118, 0x2d3c, 0x4506, 0x154e, + 0x092c, 0x211a, 0x2d3e, 0x4508, 0x1550, + 0x0a2c, 0x221a, 0x2e3e, 0x4608, 0x1650, + 0x0b2c, 0x231a, 0x2f3e, 0x4708, 0x1750, + 0x0b2e, 0x231c, 0x2f40, 0x470a, 0x1752, + 0x0a2e, 0x221c, 0x2e40, 0x460a, 0x1652, + 0x092e, 0x211c, 0x2d40, 0x450a, 0x1552, + 0x0930, 0x211e, 0x2d42, 0x450c, 0x1554, + 0x0a30, 0x221e, 0x2e42, 0x460c, 0x1654, + 0x0b30, 0x231e, 0x2f42, 0x470c, 0x1754, + 0x0b32, 0x2320, 0x2f44, 0x470e, 0x1756, + 0x0a32, 0x2220, 0x2e44, 0x460e, 0x1656, + 0x0932, 0x2120, 0x2d44, 0x450e, 0x1556, + 0x0934, 0x2122, 0x2d46, 0x4510, 0x1558, + 0x0a34, 0x2222, 0x2e46, 0x4610, 0x1658, + 0x0b34, 0x2322, 0x2f46, 0x4710, 0x1758, +}; + +/* DV25/50 DCT coefficient weights and inverse weights */ +/* created by dvtables.py */ +static const int dv_weight_bits = 18; +static const int dv_weight_88[64] = { + 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536, + 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935, + 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916, + 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433, + 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704, + 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568, + 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627, + 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258, +}; +static const int dv_weight_248[64] = { + 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754, + 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536, + 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568, + 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965, + 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627, + 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965, + 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364, + 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651, +}; +static const int dv_iweight_bits = 14; +static const int dv_iweight_88[64] = { + 32768, 16710, 16710, 17735, 17015, 17735, 18197, 18079, + 18079, 18197, 18725, 18559, 19196, 18559, 18725, 19284, + 19108, 19692, 19692, 19108, 19284, 21400, 19645, 20262, + 20214, 20262, 19645, 21400, 22733, 21845, 20867, 20815, + 20815, 20867, 21845, 22733, 23173, 23173, 21400, 21400, + 21400, 23173, 23173, 24600, 23764, 22017, 22017, 23764, + 24600, 25267, 24457, 22672, 24457, 25267, 25971, 25191, + 25191, 25971, 26715, 27962, 26715, 29642, 29642, 31536, +}; +static const int dv_iweight_248[64] = { + 32768, 17735, 16710, 18079, 18725, 21400, 17735, 19196, + 19108, 21845, 16384, 17735, 18725, 21400, 16710, 18079, + 20262, 23173, 18197, 19692, 18725, 20262, 20815, 23764, + 17735, 19196, 19108, 21845, 20262, 23173, 18197, 19692, + 21400, 24457, 19284, 20867, 21400, 23173, 22017, 25191, + 18725, 20262, 20815, 23764, 21400, 24457, 19284, 20867, + 24457, 27962, 22733, 24600, 25971, 29642, 21400, 23173, + 22017, 25191, 24457, 27962, 22733, 24600, 25971, 29642, +}; + +static const uint8_t dv_audio_shuffle525[10][9] = { { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */ { 6, 36, 66, 26, 56, 86, 16, 46, 76 }, { 12, 42, 72, 2, 32, 62, 22, 52, 82 }, { 18, 48, 78, 8, 38, 68, 28, 58, 88 }, { 24, 54, 84, 14, 44, 74, 4, 34, 64 }, - + { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */ { 7, 37, 67, 27, 57, 87, 17, 47, 77 }, { 13, 43, 73, 3, 33, 63, 23, 53, 83 }, @@ -1270,54 +2502,69 @@ static const uint16_t dv_audio_shuffle525[10][9] = { { 25, 55, 85, 15, 45, 75, 5, 35, 65 }, }; -static const uint16_t dv_audio_shuffle625[12][9] = { +static const uint8_t dv_audio_shuffle625[12][9] = { { 0, 36, 72, 26, 62, 98, 16, 52, 88}, /* 1st channel */ { 6, 42, 78, 32, 68, 104, 22, 58, 94}, { 12, 48, 84, 2, 38, 74, 28, 64, 100}, { 18, 54, 90, 8, 44, 80, 34, 70, 106}, - { 24, 60, 96, 14, 50, 86, 4, 40, 76}, + { 24, 60, 96, 14, 50, 86, 4, 40, 76}, { 30, 66, 102, 20, 56, 92, 10, 46, 82}, - + { 1, 37, 73, 27, 63, 99, 17, 53, 89}, /* 2nd channel */ { 7, 43, 79, 33, 69, 105, 23, 59, 95}, { 13, 49, 85, 3, 39, 75, 29, 65, 101}, { 19, 55, 91, 9, 45, 81, 35, 71, 107}, - { 25, 61, 97, 15, 51, 87, 5, 41, 77}, + { 25, 61, 97, 15, 51, 87, 5, 41, 77}, { 31, 67, 103, 21, 57, 93, 11, 47, 83}, }; -static const __attribute__((unused)) int dv_audio_frequency[3] = { +static const av_unused int dv_audio_frequency[3] = { 48000, 44100, 32000, }; - + +/* macroblock bit budgets */ +static const uint8_t block_sizes_dv2550[8] = { + 112, 112, 112, 112, 80, 80, 0, 0, +}; + +static const uint8_t block_sizes_dv100[8] = { + 80, 80, 80, 80, 80, 80, 64, 64, +}; + static const DVprofile dv_profiles[] = { { .dsf = 0, .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ .difseg_size = 10, + .n_difchan = 1, .frame_rate = 30000, .ltc_divisor = 30, .frame_rate_base = 1001, .height = 480, .width = 720, - .sar = {{72, 79}, {96, 79}}, + .sar = {{10, 11}, {40, 33}}, .video_place = dv_place_411, .pix_fmt = PIX_FMT_YUV411P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, .audio_stride = 90, .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32Khz */ - .audio_samples_dist = { 1602, 1601, 1602, 1601, 1602 }, + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ .audio_shuffle = dv_audio_shuffle525, - }, + }, { .dsf = 1, .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ .difseg_size = 12, + .n_difchan = 1, .frame_rate = 25, .frame_rate_base = 1, .ltc_divisor = 25, .height = 576, .width = 720, - .sar = {{128, 117}, {512, 351}}, + .sar = {{59, 54}, {118, 81}}, .video_place = dv_place_420, .pix_fmt = PIX_FMT_YUV420P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, @@ -1326,41 +2573,160 @@ static const DVprofile dv_profiles[] = { { .dsf = 1, .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ .difseg_size = 12, + .n_difchan = 1, .frame_rate = 25, .frame_rate_base = 1, .ltc_divisor = 25, .height = 576, .width = 720, - .sar = {{128, 117}, {512, 351}}, + .sar = {{59, 54}, {118, 81}}, .video_place = dv_place_411P, .pix_fmt = PIX_FMT_YUV411P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, .audio_stride = 108, .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, .audio_shuffle = dv_audio_shuffle625, - } + }, + { .dsf = 0, + .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ + .difseg_size = 10, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .frame_rate = 30000, + .ltc_divisor = 30, + .frame_rate_base = 1001, + .height = 480, + .width = 720, + .sar = {{10, 11}, {40, 33}}, + .video_place = dv_place_422_525, + .pix_fmt = PIX_FMT_YUV422P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, + }, + { .dsf = 1, + .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ + .difseg_size = 12, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .frame_rate = 25, + .frame_rate_base = 1, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = {{59, 54}, {118, 81}}, + .video_place = dv_place_422_625, + .pix_fmt = PIX_FMT_YUV422P, + .bpm = 6, + .block_sizes = block_sizes_dv2550, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, + } }; -static inline const DVprofile* dv_frame_profile(uint8_t* frame) +enum dv_section_type { + dv_sect_header = 0x1f, + dv_sect_subcode = 0x3f, + dv_sect_vaux = 0x56, + dv_sect_audio = 0x76, + dv_sect_video = 0x96, +}; + +enum dv_pack_type { + dv_header525 = 0x3f, /* see dv_write_pack for important details on */ + dv_header625 = 0xbf, /* these two packs */ + dv_timecode = 0x13, + dv_audio_source = 0x50, + dv_audio_control = 0x51, + dv_audio_recdate = 0x52, + dv_audio_rectime = 0x53, + dv_video_source = 0x60, + dv_video_control = 0x61, + dv_video_recdate = 0x62, + dv_video_rectime = 0x63, + dv_unknown_pack = 0xff, +}; + +/* minimum number of bytes to read from a DV stream in order to determine the profile */ +#define DV_PROFILE_BYTES (6*80) /* 6 DIF blocks */ + +/* largest possible DV frame, in bytes (PAL 50Mbps) */ +#define DV_MAX_FRAME_SIZE 288000 + +/* maximum number of blocks per macroblock in any DV format */ +#define DV_MAX_BPM 8 + +static inline const DVprofile* dv_frame_profile(const uint8_t* frame) { if ((frame[3] & 0x80) == 0) { /* DSF flag */ - return &dv_profiles[0]; + /* it's an NTSC format */ + if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ + return &dv_profiles[3]; /* NTSC 50Mbps */ + } else { /* 4:1:1 sampling */ + return &dv_profiles[0]; /* NTSC 25Mbps */ + } + } else { + /* it's a PAL format */ + if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ + return &dv_profiles[4]; /* PAL 50Mbps */ + } else if ((frame[5] & 0x07) == 0) { /* APT flag */ + return &dv_profiles[1]; /* PAL 25Mbps 4:2:0 */ + } else + return &dv_profiles[2]; /* PAL 25Mbps 4:1:1 */ } - else if ((frame[5] & 0x07) == 0) { /* APT flag */ - return &dv_profiles[1]; - } - else - return &dv_profiles[2]; } static inline const DVprofile* dv_codec_profile(AVCodecContext* codec) { - if (codec->width != 720) { + int i; + + if (codec->width != 720) return NULL; - } - else if (codec->height == 480) { - return &dv_profiles[0]; - } - else - return &dv_profiles[1]; + + for (i=0; iheight == dv_profiles[i].height && codec->pix_fmt == dv_profiles[i].pix_fmt) + return &dv_profiles[i]; + + return NULL; } + +static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num, uint8_t seq_num, + uint8_t dif_num, uint8_t* buf) +{ + buf[0] = (uint8_t)t; /* Section type */ + buf[1] = (seq_num<<4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */ + (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */ + 7; /* reserved -- always 1 */ + buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */ + return 3; +} + + +static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf) +{ + if (syb_num == 0 || syb_num == 6) { + buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ + (0<<4) | /* AP3 (Subcode application ID) */ + 0x0f; /* reserved -- always 1 */ + } + else if (syb_num == 11) { + buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ + 0x7f; /* reserved -- always 1 */ + } + else { + buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ + (0<<4) | /* APT (Track application ID) */ + 0x0f; /* reserved -- always 1 */ + } + buf[1] = 0xf0 | /* reserved -- always 1 */ + (syb_num & 0x0f); /* SSYB number 0 - 11 */ + buf[2] = 0xff; /* reserved -- always 1 */ + return 3; +} + +#endif /* FFMPEG_DVDATA_H */ diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvdsub_parser.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsub_parser.c new file mode 100644 index 0000000000..0893daca65 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsub_parser.c @@ -0,0 +1,83 @@ +/* + * DVD subtitle decoding for ffmpeg + * Copyright (c) 2005 Fabrice Bellard. + * + * 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 + */ +#include "avcodec.h" + +/* parser definition */ +typedef struct DVDSubParseContext { + uint8_t *packet; + int packet_len; + int packet_index; +} DVDSubParseContext; + +static int dvdsub_parse_init(AVCodecParserContext *s) +{ + return 0; +} + +static int dvdsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVDSubParseContext *pc = s->priv_data; + + if (pc->packet_index == 0) { + if (buf_size < 2) + return 0; + pc->packet_len = AV_RB16(buf); + if (pc->packet_len == 0) /* HD-DVD subpicture packet */ + pc->packet_len = AV_RB32(buf+2); + av_freep(&pc->packet); + pc->packet = av_malloc(pc->packet_len); + } + if (pc->packet) { + if (pc->packet_index + buf_size <= pc->packet_len) { + memcpy(pc->packet + pc->packet_index, buf, buf_size); + pc->packet_index += buf_size; + if (pc->packet_index >= pc->packet_len) { + *poutbuf = pc->packet; + *poutbuf_size = pc->packet_len; + pc->packet_index = 0; + return buf_size; + } + } else { + /* erroneous size */ + pc->packet_index = 0; + } + } + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; +} + +static void dvdsub_parse_close(AVCodecParserContext *s) +{ + DVDSubParseContext *pc = s->priv_data; + av_freep(&pc->packet); +} + +AVCodecParser dvdsub_parser = { + { CODEC_ID_DVD_SUBTITLE }, + sizeof(DVDSubParseContext), + dvdsub_parse_init, + dvdsub_parse, + dvdsub_parse_close, +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubdec.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubdec.c new file mode 100644 index 0000000000..f95c329e76 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubdec.c @@ -0,0 +1,512 @@ +/* + * DVD subtitle decoding for ffmpeg + * Copyright (c) 2005 Fabrice Bellard. + * + * 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 + */ +#include "avcodec.h" +#include "bitstream.h" +#include "colorspace.h" +#include "dsputil.h" + +//#define DEBUG + +static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + uint8_t r, g, b; + int i, y, cb, cr; + int r_add, g_add, b_add; + + for (i = num_values; i > 0; i--) { + y = *ycbcr++; + cb = *ycbcr++; + cr = *ycbcr++; + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b; + } +} + +static int decode_run_2bit(GetBitContext *gb, int *color) +{ + unsigned int v, t; + + v = 0; + for (t = 1; v < t && t <= 0x40; t <<= 2) + v = (v << 4) | get_bits(gb, 4); + *color = v & 3; + if (v < 4) { /* Code for fill rest of line */ + return INT_MAX; + } + return v >> 2; +} + +static int decode_run_8bit(GetBitContext *gb, int *color) +{ + int len; + int has_run = get_bits1(gb); + if (get_bits1(gb)) + *color = get_bits(gb, 8); + else + *color = get_bits(gb, 2); + if (has_run) { + if (get_bits1(gb)) { + len = get_bits(gb, 7); + if (len == 0) + len = INT_MAX; + else + len += 9; + } else + len = get_bits(gb, 3) + 2; + } else + len = 1; + return len; +} + +static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, + const uint8_t *buf, int start, int buf_size, int is_8bit) +{ + GetBitContext gb; + int bit_len; + int x, y, len, color; + uint8_t *d; + + bit_len = (buf_size - start) * 8; + init_get_bits(&gb, buf + start, bit_len); + + x = 0; + y = 0; + d = bitmap; + for(;;) { + if (get_bits_count(&gb) > bit_len) + return -1; + if (is_8bit) + len = decode_run_8bit(&gb, &color); + else + len = decode_run_2bit(&gb, &color); + len = FFMIN(len, w - x); + memset(d + x, color, len); + x += len; + if (x >= w) { + y++; + if (y >= h) + break; + d += linesize; + x = 0; + /* byte align */ + align_get_bits(&gb); + } + } + return 0; +} + +static void guess_palette(uint32_t *rgba_palette, + uint8_t *colormap, + uint8_t *alpha, + uint32_t subtitle_color) +{ + uint8_t color_used[16]; + int nb_opaque_colors, i, level, j, r, g, b; + + for(i = 0; i < 4; i++) + rgba_palette[i] = 0; + + memset(color_used, 0, 16); + nb_opaque_colors = 0; + for(i = 0; i < 4; i++) { + if (alpha[i] != 0 && !color_used[colormap[i]]) { + color_used[colormap[i]] = 1; + nb_opaque_colors++; + } + } + + if (nb_opaque_colors == 0) + return; + + j = nb_opaque_colors; + memset(color_used, 0, 16); + for(i = 0; i < 4; i++) { + if (alpha[i] != 0) { + if (!color_used[colormap[i]]) { + level = (0xff * j) / nb_opaque_colors; + r = (((subtitle_color >> 16) & 0xff) * level) >> 8; + g = (((subtitle_color >> 8) & 0xff) * level) >> 8; + b = (((subtitle_color >> 0) & 0xff) * level) >> 8; + rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24); + color_used[colormap[i]] = (i + 1); + j--; + } else { + rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) | + ((alpha[i] * 17) << 24); + } + } + } +} + +#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) + +static int decode_dvd_subtitles(AVSubtitle *sub_header, + const uint8_t *buf, int buf_size) +{ + int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; + int big_offsets, offset_size, is_8bit = 0; + const uint8_t *yuv_palette = 0; + uint8_t colormap[4], alpha[256]; + int date; + int i; + int is_menu = 0; + + if (buf_size < 10) + return -1; + sub_header->rects = NULL; + sub_header->num_rects = 0; + sub_header->start_display_time = 0; + sub_header->end_display_time = 0; + + if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */ + big_offsets = 1; + offset_size = 4; + cmd_pos = 6; + } else { + big_offsets = 0; + offset_size = 2; + cmd_pos = 2; + } + + cmd_pos = READ_OFFSET(buf + cmd_pos); + + while ((cmd_pos + 2 + offset_size) < buf_size) { + date = AV_RB16(buf + cmd_pos); + next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "cmd_pos=0x%04x next=0x%04x date=%d\n", + cmd_pos, next_cmd_pos, date); +#endif + pos = cmd_pos + 2 + offset_size; + offset1 = -1; + offset2 = -1; + x1 = y1 = x2 = y2 = 0; + while (pos < buf_size) { + cmd = buf[pos++]; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "cmd=%02x\n", cmd); +#endif + switch(cmd) { + case 0x00: + /* menu subpicture */ + is_menu = 1; + break; + case 0x01: + /* set start date */ + sub_header->start_display_time = (date << 10) / 90; + break; + case 0x02: + /* set end date */ + sub_header->end_display_time = (date << 10) / 90; + break; + case 0x03: + /* set colormap */ + if ((buf_size - pos) < 2) + goto fail; + colormap[3] = buf[pos] >> 4; + colormap[2] = buf[pos] & 0x0f; + colormap[1] = buf[pos + 1] >> 4; + colormap[0] = buf[pos + 1] & 0x0f; + pos += 2; + break; + case 0x04: + /* set alpha */ + if ((buf_size - pos) < 2) + goto fail; + alpha[3] = buf[pos] >> 4; + alpha[2] = buf[pos] & 0x0f; + alpha[1] = buf[pos + 1] >> 4; + alpha[0] = buf[pos + 1] & 0x0f; + pos += 2; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]); +#endif + break; + case 0x05: + case 0x85: + if ((buf_size - pos) < 6) + goto fail; + x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4); + x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2]; + y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4); + y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5]; + if (cmd & 0x80) + is_8bit = 1; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "x1=%d x2=%d y1=%d y2=%d\n", + x1, x2, y1, y2); +#endif + pos += 6; + break; + case 0x06: + if ((buf_size - pos) < 4) + goto fail; + offset1 = AV_RB16(buf + pos); + offset2 = AV_RB16(buf + pos + 2); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); +#endif + pos += 4; + break; + case 0x86: + if ((buf_size - pos) < 8) + goto fail; + offset1 = AV_RB32(buf + pos); + offset2 = AV_RB32(buf + pos + 4); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); +#endif + pos += 8; + break; + + case 0x83: + /* HD set palette */ + if ((buf_size - pos) < 768) + goto fail; + yuv_palette = buf + pos; + pos += 768; + break; + case 0x84: + /* HD set contrast (alpha) */ + if ((buf_size - pos) < 256) + goto fail; + for (i = 0; i < 256; i++) + alpha[i] = 0xFF - buf[pos+i]; + pos += 256; + break; + + case 0xff: + goto the_end; + default: +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "unrecognised subpicture command 0x%x\n", cmd); +#endif + goto the_end; + } + } + the_end: + if (offset1 >= 0) { + int w, h; + uint8_t *bitmap; + + /* decode the bitmap */ + w = x2 - x1 + 1; + if (w < 0) + w = 0; + h = y2 - y1; + if (h < 0) + h = 0; + if (w > 0 && h > 0) { + if (sub_header->rects != NULL) { + for (i = 0; i < sub_header->num_rects; i++) { + av_free(sub_header->rects[i].bitmap); + av_free(sub_header->rects[i].rgba_palette); + } + av_freep(&sub_header->rects); + sub_header->num_rects = 0; + } + + bitmap = av_malloc(w * h); + sub_header->rects = av_mallocz(sizeof(AVSubtitleRect)); + sub_header->num_rects = 1; + sub_header->rects[0].bitmap = bitmap; + decode_rle(bitmap, w * 2, w, (h + 1) / 2, + buf, offset1, buf_size, is_8bit); + decode_rle(bitmap + w, w * 2, w, h / 2, + buf, offset2, buf_size, is_8bit); + if (is_8bit) { + if (yuv_palette == 0) + goto fail; + sub_header->rects[0].rgba_palette = av_malloc(256 * 4); + sub_header->rects[0].nb_colors = 256; + yuv_a_to_rgba(yuv_palette, alpha, sub_header->rects[0].rgba_palette, 256); + } else { + sub_header->rects[0].rgba_palette = av_malloc(4 * 4); + sub_header->rects[0].nb_colors = 4; + guess_palette(sub_header->rects[0].rgba_palette, + colormap, alpha, 0xffff00); + } + sub_header->rects[0].x = x1; + sub_header->rects[0].y = y1; + sub_header->rects[0].w = w; + sub_header->rects[0].h = h; + sub_header->rects[0].linesize = w; + } + } + if (next_cmd_pos == cmd_pos) + break; + cmd_pos = next_cmd_pos; + } + if (sub_header->num_rects > 0) + return is_menu; + fail: + if (sub_header->rects != NULL) { + for (i = 0; i < sub_header->num_rects; i++) { + av_free(sub_header->rects[i].bitmap); + av_free(sub_header->rects[i].rgba_palette); + } + av_freep(&sub_header->rects); + sub_header->num_rects = 0; + } + return -1; +} + +static int is_transp(const uint8_t *buf, int pitch, int n, + const uint8_t *transp_color) +{ + int i; + for(i = 0; i < n; i++) { + if (!transp_color[*buf]) + return 0; + buf += pitch; + } + return 1; +} + +/* return 0 if empty rectangle, 1 if non empty */ +static int find_smallest_bounding_rectangle(AVSubtitle *s) +{ + uint8_t transp_color[256]; + int y1, y2, x1, x2, y, w, h, i; + uint8_t *bitmap; + + if (s->num_rects == 0 || s->rects == NULL || s->rects[0].w <= 0 || s->rects[0].h <= 0) + return 0; + + memset(transp_color, 0, 256); + for(i = 0; i < s->rects[0].nb_colors; i++) { + if ((s->rects[0].rgba_palette[i] >> 24) == 0) + transp_color[i] = 1; + } + y1 = 0; + while (y1 < s->rects[0].h && is_transp(s->rects[0].bitmap + y1 * s->rects[0].linesize, + 1, s->rects[0].w, transp_color)) + y1++; + if (y1 == s->rects[0].h) { + av_freep(&s->rects[0].bitmap); + s->rects[0].w = s->rects[0].h = 0; + return 0; + } + + y2 = s->rects[0].h - 1; + while (y2 > 0 && is_transp(s->rects[0].bitmap + y2 * s->rects[0].linesize, 1, + s->rects[0].w, transp_color)) + y2--; + x1 = 0; + while (x1 < (s->rects[0].w - 1) && is_transp(s->rects[0].bitmap + x1, s->rects[0].linesize, + s->rects[0].h, transp_color)) + x1++; + x2 = s->rects[0].w - 1; + while (x2 > 0 && is_transp(s->rects[0].bitmap + x2, s->rects[0].linesize, s->rects[0].h, + transp_color)) + x2--; + w = x2 - x1 + 1; + h = y2 - y1 + 1; + bitmap = av_malloc(w * h); + if (!bitmap) + return 1; + for(y = 0; y < h; y++) { + memcpy(bitmap + w * y, s->rects[0].bitmap + x1 + (y1 + y) * s->rects[0].linesize, w); + } + av_freep(&s->rects[0].bitmap); + s->rects[0].bitmap = bitmap; + s->rects[0].linesize = w; + s->rects[0].w = w; + s->rects[0].h = h; + s->rects[0].x += x1; + s->rects[0].y += y1; + return 1; +} + +#ifdef DEBUG +#undef fprintf +#undef perror +#undef exit +static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, + uint32_t *rgba_palette) +{ + int x, y, v; + FILE *f; + + f = fopen(filename, "w"); + if (!f) { + perror(filename); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); +} +#endif + +static int dvdsub_decode(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + AVSubtitle *sub = (void *)data; + int is_menu; + + is_menu = decode_dvd_subtitles(sub, buf, buf_size); + + if (is_menu < 0) { + no_subtitle: + *data_size = 0; + + return buf_size; + } + if (!is_menu && find_smallest_bounding_rectangle(sub) == 0) + goto no_subtitle; + +#if defined(DEBUG) + av_log(NULL, AV_LOG_INFO, "start=%d ms end =%d ms\n", + sub->start_display_time, + sub->end_display_time); + ppm_save("/tmp/a.ppm", sub->rects[0].bitmap, + sub->rects[0].w, sub->rects[0].h, sub->rects[0].rgba_palette); +#endif + + *data_size = 1; + return buf_size; +} + +AVCodec dvdsub_decoder = { + "dvdsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVD_SUBTITLE, + 0, + NULL, + NULL, + NULL, + dvdsub_decode, + .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubenc.c b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubenc.c new file mode 100644 index 0000000000..a5380ceefd --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dvdsubenc.c @@ -0,0 +1,226 @@ +/* + * DVD subtitle encoding for ffmpeg + * Copyright (c) 2005 Wolfram Gloger. + * + * 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 + */ +#include "avcodec.h" +#include "bytestream.h" + +#undef NDEBUG +#include + +// ncnt is the nibble counter +#define PUTNIBBLE(val)\ +do {\ + if (ncnt++ & 1)\ + *q++ = bitbuf | ((val) & 0x0f);\ + else\ + bitbuf = (val) << 4;\ +} while(0) + +static void dvd_encode_rle(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h, + const int cmap[256]) +{ + uint8_t *q; + unsigned int bitbuf = 0; + int ncnt; + int x, y, len, color; + + q = *pq; + + for (y = 0; y < h; ++y) { + ncnt = 0; + for(x = 0; x < w; x += len) { + color = bitmap[x]; + for (len=1; x+len < w; ++len) + if (bitmap[x+len] != color) + break; + color = cmap[color]; + assert(color < 4); + if (len < 0x04) { + PUTNIBBLE((len << 2)|color); + } else if (len < 0x10) { + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } else if (len < 0x40) { + PUTNIBBLE(0); + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } else if (x+len == w) { + PUTNIBBLE(0); + PUTNIBBLE(0); + PUTNIBBLE(0); + PUTNIBBLE(color); + } else { + if (len > 0xff) + len = 0xff; + PUTNIBBLE(0); + PUTNIBBLE(len >> 6); + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } + } + /* end of line */ + if (ncnt & 1) + PUTNIBBLE(0); + bitmap += linesize; + } + + *pq = q; +} + +static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size, + const AVSubtitle *h) +{ + uint8_t *q, *qq; + int object_id; + int offset1[20], offset2[20]; + int i, imax, color, alpha, rects = h->num_rects; + unsigned long hmax; + unsigned long hist[256]; + int cmap[256]; + + if (rects == 0 || h->rects == NULL) + return -1; + if (rects > 20) + rects = 20; + + // analyze bitmaps, compress to 4 colors + for (i=0; i<256; ++i) { + hist[i] = 0; + cmap[i] = 0; + } + for (object_id = 0; object_id < rects; object_id++) + for (i=0; irects[object_id].w*h->rects[object_id].h; ++i) { + color = h->rects[object_id].bitmap[i]; + // only count non-transparent pixels + alpha = h->rects[object_id].rgba_palette[color] >> 24; + hist[color] += alpha; + } + for (color=3;; --color) { + hmax = 0; + imax = 0; + for (i=0; i<256; ++i) + if (hist[i] > hmax) { + imax = i; + hmax = hist[i]; + } + if (hmax == 0) + break; + if (color == 0) + color = 3; + av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n", + imax, hist[imax], color); + cmap[imax] = color; + hist[imax] = 0; + } + + + // encode data block + q = outbuf + 4; + for (object_id = 0; object_id < rects; object_id++) { + offset1[object_id] = q - outbuf; + // worst case memory requirement: 1 nibble per pixel.. + if ((q - outbuf) + h->rects[object_id].w*h->rects[object_id].h/2 + + 17*rects + 21 > outbuf_size) { + av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n"); + return -1; + } + dvd_encode_rle(&q, h->rects[object_id].bitmap, + h->rects[object_id].w*2, + h->rects[object_id].w, h->rects[object_id].h >> 1, + cmap); + offset2[object_id] = q - outbuf; + dvd_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, + h->rects[object_id].w*2, + h->rects[object_id].w, h->rects[object_id].h >> 1, + cmap); + } + + // set data packet size + qq = outbuf + 2; + bytestream_put_be16(&qq, q - outbuf); + + // send start display command + bytestream_put_be16(&q, (h->start_display_time*90) >> 10); + bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2); + *q++ = 0x03; // palette - 4 nibbles + *q++ = 0x03; *q++ = 0x7f; + *q++ = 0x04; // alpha - 4 nibbles + *q++ = 0xf0; *q++ = 0x00; + //*q++ = 0x0f; *q++ = 0xff; + + // XXX not sure if more than one rect can really be encoded.. + // 12 bytes per rect + for (object_id = 0; object_id < rects; object_id++) { + int x2 = h->rects[object_id].x + h->rects[object_id].w - 1; + int y2 = h->rects[object_id].y + h->rects[object_id].h - 1; + + *q++ = 0x05; + // x1 x2 -> 6 nibbles + *q++ = h->rects[object_id].x >> 4; + *q++ = (h->rects[object_id].x << 4) | ((x2 >> 8) & 0xf); + *q++ = x2; + // y1 y2 -> 6 nibbles + *q++ = h->rects[object_id].y >> 4; + *q++ = (h->rects[object_id].y << 4) | ((y2 >> 8) & 0xf); + *q++ = y2; + + *q++ = 0x06; + // offset1, offset2 + bytestream_put_be16(&q, offset1[object_id]); + bytestream_put_be16(&q, offset2[object_id]); + } + *q++ = 0x01; // start command + *q++ = 0xff; // terminating command + + // send stop display command last + bytestream_put_be16(&q, (h->end_display_time*90) >> 10); + bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/); + *q++ = 0x02; // set end + *q++ = 0xff; // terminating command + + qq = outbuf; + bytestream_put_be16(&qq, q - outbuf); + + av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf); + return q - outbuf; +} + +static int dvdsub_encode(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + //DVDSubtitleContext *s = avctx->priv_data; + AVSubtitle *sub = data; + int ret; + + ret = encode_dvd_subtitles(buf, buf_size, sub); + return ret; +} + +AVCodec dvdsub_encoder = { + "dvdsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVD_SUBTITLE, + 0, + NULL, + dvdsub_encode, + .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/dxa.c b/src/add-ons/media/plugins/avcodec/libavcodec/dxa.c new file mode 100644 index 0000000000..3d03445c0c --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/dxa.c @@ -0,0 +1,332 @@ +/* + * Feeble Files/ScummVM DXA decoder + * Copyright (c) 2007 Konstantin Shishkov + * + * 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 + */ + +/** + * @file dxa.c + * DXA Video decoder + */ + +#include +#include + +#include "avcodec.h" + +#include + +/* + * Decoder context + */ +typedef struct DxaDecContext { + AVCodecContext *avctx; + AVFrame pic, prev; + + int dsize; + uint8_t *decomp_buf; + uint32_t pal[256]; +} DxaDecContext; + +static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; +static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; + +static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref) +{ + uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; + int i, j, k; + int type, x, y, d, d2; + int stride = c->pic.linesize[0]; + uint32_t mask; + + code = src + 12; + data = code + ((avctx->width * avctx->height) >> 4); + mv = data + AV_RB32(src + 0); + msk = mv + AV_RB32(src + 4); + + for(j = 0; j < avctx->height; j += 4){ + for(i = 0; i < avctx->width; i += 4){ + tmp = dst + i; + tmp2 = ref + i; + type = *code++; + switch(type){ + case 4: // motion compensation + x = (*mv) >> 4; if(x & 8) x = 8 - x; + y = (*mv++) & 0xF; if(y & 8) y = 8 - y; + tmp2 += x + y*stride; + case 0: // skip + case 5: // skip in method 12 + for(y = 0; y < 4; y++){ + memcpy(tmp, tmp2, 4); + tmp += stride; + tmp2 += stride; + } + break; + case 1: // masked change + case 10: // masked change with only half of pixels changed + case 11: // cases 10-15 are for method 12 only + case 12: + case 13: + case 14: + case 15: + if(type == 1){ + mask = AV_RB16(msk); + msk += 2; + }else{ + type -= 10; + mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] & 0xF) << shift2[type]); + msk++; + } + for(y = 0; y < 4; y++){ + for(x = 0; x < 4; x++){ + tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x]; + mask <<= 1; + } + tmp += stride; + tmp2 += stride; + } + break; + case 2: // fill block + for(y = 0; y < 4; y++){ + memset(tmp, data[0], 4); + tmp += stride; + } + data++; + break; + case 3: // raw block + for(y = 0; y < 4; y++){ + memcpy(tmp, data, 4); + data += 4; + tmp += stride; + } + break; + case 8: // subblocks - method 13 only + mask = *msk++; + for(k = 0; k < 4; k++){ + d = ((k & 1) << 1) + ((k & 2) * stride); + d2 = ((k & 1) << 1) + ((k & 2) * stride); + tmp2 = ref + i + d2; + switch(mask & 0xC0){ + case 0x80: // motion compensation + x = (*mv) >> 4; if(x & 8) x = 8 - x; + y = (*mv++) & 0xF; if(y & 8) y = 8 - y; + tmp2 += x + y*stride; + case 0x00: // skip + tmp[d + 0 ] = tmp2[0]; + tmp[d + 1 ] = tmp2[1]; + tmp[d + 0 + stride] = tmp2[0 + stride]; + tmp[d + 1 + stride] = tmp2[1 + stride]; + break; + case 0x40: // fill + tmp[d + 0 ] = data[0]; + tmp[d + 1 ] = data[0]; + tmp[d + 0 + stride] = data[0]; + tmp[d + 1 + stride] = data[0]; + data++; + break; + case 0xC0: // raw + tmp[d + 0 ] = *data++; + tmp[d + 1 ] = *data++; + tmp[d + 0 + stride] = *data++; + tmp[d + 1 + stride] = *data++; + break; + } + mask <<= 2; + } + break; + case 32: // vector quantization - 2 colors + mask = AV_RB16(msk); + msk += 2; + for(y = 0; y < 4; y++){ + for(x = 0; x < 4; x++){ + tmp[x] = data[mask & 1]; + mask >>= 1; + } + tmp += stride; + tmp2 += stride; + } + data += 2; + break; + case 33: // vector quantization - 3 or 4 colors + case 34: + mask = AV_RB32(msk); + msk += 4; + for(y = 0; y < 4; y++){ + for(x = 0; x < 4; x++){ + tmp[x] = data[mask & 3]; + mask >>= 2; + } + tmp += stride; + tmp2 += stride; + } + data += type - 30; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type); + return -1; + } + } + dst += stride * 4; + ref += stride * 4; + } + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) +{ + DxaDecContext * const c = avctx->priv_data; + uint8_t *outptr, *srcptr, *tmpptr; + unsigned long dsize; + int i, j, compr; + int stride; + int orig_buf_size = buf_size; + int pc = 0; + + /* make the palette available on the way out */ + if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){ + int r, g, b; + + buf += 4; + for(i = 0; i < 256; i++){ + r = *buf++; + g = *buf++; + b = *buf++; + c->pal[i] = (r << 16) | (g << 8) | b; + } + pc = 1; + buf_size -= 768+4; + } + + if(avctx->get_buffer(avctx, &c->pic) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); + c->pic.palette_has_changed = pc; + + outptr = c->pic.data[0]; + srcptr = c->decomp_buf; + tmpptr = c->prev.data[0]; + stride = c->pic.linesize[0]; + + if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L') + compr = -1; + else + compr = buf[4]; + + dsize = c->dsize; + if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){ + av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n"); + return -1; + } + switch(compr){ + case -1: + c->pic.key_frame = 0; + c->pic.pict_type = FF_P_TYPE; + if(c->prev.data[0]) + memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height); + else{ // Should happen only when first frame is 'NULL' + memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height); + c->pic.key_frame = 1; + c->pic.pict_type = FF_I_TYPE; + } + break; + case 2: + case 3: + case 4: + case 5: + c->pic.key_frame = !(compr & 1); + c->pic.pict_type = (compr & 1) ? FF_P_TYPE : FF_I_TYPE; + for(j = 0; j < avctx->height; j++){ + if(compr & 1){ + for(i = 0; i < avctx->width; i++) + outptr[i] = srcptr[i] ^ tmpptr[i]; + tmpptr += stride; + }else + memcpy(outptr, srcptr, avctx->width); + outptr += stride; + srcptr += avctx->width; + } + break; + case 12: // ScummVM coding + case 13: + c->pic.key_frame = 0; + c->pic.pict_type = FF_P_TYPE; + decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]); + return -1; + } + + FFSWAP(AVFrame, c->pic, c->prev); + if(c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = c->prev; + + /* always report that the buffer was completely consumed */ + return orig_buf_size; +} + +static av_cold int decode_init(AVCodecContext *avctx) +{ + DxaDecContext * const c = avctx->priv_data; + + c->avctx = avctx; + avctx->pix_fmt = PIX_FMT_PAL8; + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return -1; + } + + c->dsize = avctx->width * avctx->height * 2; + if((c->decomp_buf = av_malloc(c->dsize)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); + return -1; + } + + return 0; +} + +static av_cold int decode_end(AVCodecContext *avctx) +{ + DxaDecContext * const c = avctx->priv_data; + + av_freep(&c->decomp_buf); + if(c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); + if(c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + return 0; +} + +AVCodec dxa_decoder = { + "dxa", + CODEC_TYPE_VIDEO, + CODEC_ID_DXA, + sizeof(DxaDecContext), + decode_init, + NULL, + decode_end, + decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), +}; +