intrax8 decoder patch by "someone"

Originally committed as revision 10971 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2007-11-09 21:37:48 +00:00
parent a9d5a4485a
commit 9abc7e0fdc
12 changed files with 2345 additions and 13 deletions

View File

@ -188,7 +188,7 @@ OBJS-$(CONFIG_TTA_DECODER) += tta.o
OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o
OBJS-$(CONFIG_ULTI_DECODER) += ulti.o
OBJS-$(CONFIG_VB_DECODER) += vb.o
OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o
OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o intrax8.o intrax8dsp.o
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o
@ -209,8 +209,8 @@ OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o mdct.o fft.o
OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o mdct.o fft.o
OBJS-$(CONFIG_WMV1_DECODER) += h263dec.o h263.o
OBJS-$(CONFIG_WMV1_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o
OBJS-$(CONFIG_WMV2_DECODER) += wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2.o msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o
OBJS-$(CONFIG_WMV2_DECODER) += wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o
OBJS-$(CONFIG_WMV2_ENCODER) += wmv2.o msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o intrax8.o intrax8dsp.o
OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1data.o vc1dsp.o
OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o
OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o

View File

@ -1295,6 +1295,7 @@ typedef struct AVCodecContext {
#define FF_IDCT_SIMPLEARMV5TE 16
#define FF_IDCT_SIMPLEARMV6 17
#define FF_IDCT_SIMPLEVIS 18
#define FF_IDCT_WMV2 19
/**
* slice count

View File

@ -2561,6 +2561,10 @@ void ff_put_vc1_mspel_mc00_c(uint8_t *dst, uint8_t *src, int stride, int rnd) {
}
#endif /* CONFIG_VC1_DECODER||CONFIG_WMV3_DECODER */
#if defined(CONFIG_WMV2_DECODER) || defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER)
void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx);
#endif
#if defined(CONFIG_H264_ENCODER)
/* H264 specific */
void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx);
@ -3758,8 +3762,90 @@ void ff_float_to_int16_c(int16_t *dst, const float *src, int len){
}
}
#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);
@ -3899,6 +3985,11 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
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{ //accurate/default
c->idct_put= simple_idct_put;
c->idct_add= simple_idct_add;
@ -4056,6 +4147,9 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
#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

View File

@ -48,6 +48,7 @@ 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);
@ -326,6 +327,9 @@ typedef struct DSPContext {
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);
/* no alignment needed */
@ -412,6 +416,12 @@ typedef struct DSPContext {
* last argument is actually round value instead of height
*/
op_pixels_func put_vc1_mspel_pixels_tab[16];
/* intrax8 functions */
void (*x8_spacial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize);
void (*x8_setup_spacial_compensation)(uint8_t *src, uint8_t *dst, int linesize,
int * range, int * sum, int edges);
} DSPContext;
void dsputil_static_init(void);

View File

@ -623,9 +623,10 @@ retry:
//the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type
//which is not available before MPV_frame_start()
if (s->msmpeg4_version==5){
if(!ENABLE_WMV2_DECODER || ff_wmv2_decode_secondary_picture_header(s) < 0)
return -1;
if (ENABLE_WMV2_DECODER && s->msmpeg4_version==5){
ret = ff_wmv2_decode_secondary_picture_header(s);
if(ret<0) return ret;
if(ret==1) goto intrax8_decoded;
}
/* decode each macroblock */
@ -682,6 +683,7 @@ retry:
}
}
intrax8_decoded:
ff_er_frame_end(s);
MPV_frame_end(s);

757
libavcodec/intrax8.c Normal file
View File

@ -0,0 +1,757 @@
/*
* 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 intrax8.c
* @brief IntraX8 (J-Frame) sub-decoder, used by wmv2 and vc1
*/
#include "avcodec.h"
#include "bitstream.h"
#include "mpegvideo.h"
#include "msmpeg4data.h"
#include "intrax8huf.h"
#include "intrax8.h"
#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits)
#define DC_VLC_BITS 9
#define AC_VLC_BITS 9
#define OR_VLC_BITS 7
#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS)
#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS)
#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS)
static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select]
static VLC j_dc_vlc[2][8]; //[quant], [select]
static VLC j_orient_vlc[2][4]; //[quant], [select]
static void x8_vlc_init(){
int i;
#define init_ac_vlc(dst,src) \
init_vlc(&dst, \
AC_VLC_BITS,77, \
&src[1],4,2, \
&src[0],4,2, \
1)
//set ac tables
for(i=0;i<8;i++){
init_ac_vlc( j_ac_vlc[0][0][i], ff_x8_ac0_highquant_table[i][0] );
init_ac_vlc( j_ac_vlc[0][1][i], ff_x8_ac1_highquant_table[i][0] );
init_ac_vlc( j_ac_vlc[1][0][i], ff_x8_ac0_lowquant_table [i][0] );
init_ac_vlc( j_ac_vlc[1][1][i], ff_x8_ac1_lowquant_table [i][0] );
}
#undef init_ac_vlc
//set dc tables
#define init_dc_vlc(dst,src) \
init_vlc(&dst, \
DC_VLC_BITS,34, \
&src[1],4,2, \
&src[0],4,2, \
1);
for(i=0;i<8;i++){
init_dc_vlc( j_dc_vlc[0][i], ff_x8_dc_highquant_table[i][0]);
init_dc_vlc( j_dc_vlc[1][i], ff_x8_dc_lowquant_table [i][0]);
}
#undef init_dc_vlc
//set orient tables
#define init_or_vlc(dst,src) \
init_vlc(&dst, \
OR_VLC_BITS,12, \
&src[1],4,2, \
&src[0],4,2, \
1);
for(i=0;i<2;i++){
init_or_vlc( j_orient_vlc[0][i], ff_x8_orient_highquant_table[i][0]);
}
for(i=0;i<4;i++){
init_or_vlc( j_orient_vlc[1][i], ff_x8_orient_lowquant_table [i][0])
}
}
#undef init_or_vlc
static inline void x8_reset_vlc_tables(IntraX8Context * w){
memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc));
memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc));
w->j_orient_vlc=NULL;
}
static inline void x8_select_ac_table(IntraX8Context * const w , int mode){
MpegEncContext * const s= w->s;
int table_index;
assert(mode<4);
if( w->j_ac_vlc[mode] ) return;
table_index = get_bits(&s->gb, 3);
w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
assert(w->j_ac_vlc[mode]);
}
static inline int x8_get_orient_vlc(IntraX8Context * w){
MpegEncContext * const s= w->s;
int table_index;
if(!w->j_orient_vlc ){
table_index = get_bits(&s->gb, 1+(w->quant<13) );
w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
}
assert(w->j_orient_vlc);
assert(w->j_orient_vlc->table);
return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
}
#define extra_bits(eb) (eb)
#define extra_run (0xFF<<8)
#define extra_level (0x00<<8)
#define run_offset(r) ((r)<<16)
#define level_offset(l) ((l)<<24)
static const uint32_t ac_decode_table[]={
/*46*/ extra_bits(3) | extra_run | run_offset(16) | level_offset( 0),
/*47*/ extra_bits(3) | extra_run | run_offset(24) | level_offset( 0),
/*48*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1),
/*49*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1),
/*50*/ extra_bits(5) | extra_run | run_offset(32) | level_offset( 0),
/*51*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1),
/*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
/*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
/*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
/*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
/*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
/*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
/*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
/*59*/ extra_bits(2) | extra_run | run_offset(16) | level_offset( 0),
/*60*/ extra_bits(2) | extra_run | run_offset(20) | level_offset( 0),
/*61*/ extra_bits(2) | extra_run | run_offset(24) | level_offset( 0),
/*62*/ extra_bits(2) | extra_run | run_offset(28) | level_offset( 0),
/*63*/ extra_bits(4) | extra_run | run_offset(32) | level_offset( 0),
/*64*/ extra_bits(4) | extra_run | run_offset(48) | level_offset( 0),
/*65*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1),
/*66*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1),
/*67*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1),
/*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
/*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
/*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
/*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
/*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
};
//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
#undef extra_bits
#undef extra_run
#undef extra_level
#undef run_offset
#undef level_offset
static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
int * const run, int * const level, int * const final){
MpegEncContext * const s= w->s;
int i,e;
// x8_select_ac_table(w,mode);
i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
if(i<46){ //[0-45]
int t,l;
if(i<0){
(*level)=(*final)=//prevent 'may be used unilitialized'
(*run)=64;//this would cause error exit in the ac loop
return;
}
(*final) = t = (i>22);
i-=23*t;
/*
i== 0-15 r=0-15 l=0 ;r=i& %01111
i==16-19 r=0-3 l=1 ;r=i& %00011
i==20-21 r=0-1 l=2 ;r=i& %00001
i==22 r=0 l=3 ;r=i& %00000
l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000
t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits doesn't matter */
l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
t=(0x01030F>>(l<<3));
(*run) = i&t;
(*level) = l;
}else if(i<73){//[46-72]
uint32_t sm;
uint32_t mask;
i-=46;
sm=ac_decode_table[i];
e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
mask=sm&0xff;sm>>=8; //1bit
(*run) =(sm&0xff) + (e&( mask));//6bits
(*level)=(sm>>8) + (e&(~mask));//5bits
(*final)=i>(58-46);
}else if(i<75){//[73-74]
static const uint8_t crazy_mix_runlevel[32]={
0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};
(*final)=!(i&1);
e=get_bits(&s->gb,5);//get the extra bits
(*run) =crazy_mix_runlevel[e]>>4;
(*level)=crazy_mix_runlevel[e]&0x0F;
}else{
(*level)=get_bits( &s->gb, 7-3*(i&1));
(*run) =get_bits( &s->gb, 6);
(*final)=get_bits1(&s->gb);
}
return;
}
//static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 };
static const uint8_t dc_index_offset[] ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
MpegEncContext * const s= w->s;
int i,e,c;
assert(mode<3);
if( !w->j_dc_vlc[mode] ) {
int table_index;
table_index = get_bits(&s->gb, 3);
//4 modes, same table
w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
}
assert(w->j_dc_vlc);
assert(w->j_dc_vlc[mode]->table);
i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
/*(i>=17) {i-=17;final=1;}*/
c= i>16;
(*final)=c;
i-=17*c;
if(i<=0){
(*level)=0;
return -i;
}
c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
c-=c>1;
e=get_bits(&s->gb,c);//get the extra bits
i=dc_index_offset[i]+(e>>1);
e= -(e & 1);//0,0xffffff
(*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
return 0;
}
//end of huffman
static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
MpegEncContext * const s= w->s;
int range;
int sum;
int quant;
s->dsp.x8_setup_spacial_compensation(s->dest[chroma], s->edge_emu_buffer,
s->current_picture.linesize[chroma>0],
&range, &sum, w->edges);
if(chroma){
w->orient=w->chroma_orient;
quant=w->quant_dc_chroma;
}else{
quant=w->quant;
}
w->flat_dc=0;
if(range < quant || range < 3){
w->orient=0;
if(range < 3){//yep you read right, idct error of +-1 may break decoding!
w->flat_dc=1;
sum+=9;
w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
}
}
if(chroma)
return 0;
assert(w->orient < 3);
if(range < 2*w->quant){
if( (w->edges&3) == 0){
if(w->orient==1) w->orient=11;
if(w->orient==2) w->orient=10;
}else{
w->orient=0;
}
w->raw_orient=0;
}else{
static const uint8_t prediction_table[3][12]={
{0,8,4, 10,11, 2,6,9,1,3,5,7},
{4,0,8, 11,10, 3,5,2,6,9,1,7},
{8,0,4, 10,11, 1,7,2,6,9,3,5}
};
w->raw_orient=x8_get_orient_vlc(w);
if(w->raw_orient<0) return -1;
assert(w->raw_orient < 12 );
assert(w->orient<3);
w->orient=prediction_table[w->orient][w->raw_orient];
}
return 0;
}
static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
MpegEncContext * const s= w->s;
w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
/*
y=2n+0 ->//0 2 4
y=2n+1 ->//1 3 5
*/
}
static void x8_get_prediction_chroma(IntraX8Context * const w){
MpegEncContext * const s= w->s;
w->edges = 1*( !(s->mb_x>>1) );
w->edges|= 2*( !(s->mb_y>>1) );
w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
w->raw_orient=0;
if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
w->chroma_orient=4<<((0xCC>>w->edges)&1);
return;
}
w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
}
static void x8_get_prediction(IntraX8Context * const w){
MpegEncContext * const s= w->s;
int a,b,c,i;
w->edges = 1*( !s->mb_x );
w->edges|= 2*( !s->mb_y );
w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
switch(w->edges&3){
case 0:
break;
case 1:
//take the one from the above block[0][y-1]
w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
w->orient = 1;
return;
case 2:
//take the one from the previous block[x-1][0]
w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
w->orient = 2;
return;
case 3:
w->est_run = 16;
w->orient = 0;
return;
}
//no edge cases.
b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1]
a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ]
c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
w->est_run = FFMIN(b,a);
/*this condition have nothing to do with w->edges, even if it looks similar
it would triger if e.g. x=3;y=2;
I guess somebody wrote something wrong and it became standard */
if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
w->est_run>>=2;
a&=3;
b&=3;
c&=3;
i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
if(i!=3) w->orient=i;
else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
/*
lut1[b][a]={
->{0, 1, 0, pad},
{0, 1, X, pad},
{2, 2, 2, pad}}
pad 2 2 2; pad X 1 0; pad 0 1 0 <-
-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
lut2[q>12][c]={
->{0,2,1,pad},
{2,2,2,pad}}
pad 2 2 2; pad 1 2 0 <-
-> 11 10'10 10 '11 01'10 00=>0xEAD8
*/
}
static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
MpegEncContext * const s= w->s;
int t;
#define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]]
#define T(x) ((x) * dc_level + 0x8000) >> 16;
switch(direction){
case 0:
t = T(3811);//h
B(1,0) -= t;
B(0,1) -= t;
t = T(487);//e
B(2,0) -= t;
B(0,2) -= t;
t = T(506);//f
B(3,0) -= t;
B(0,3) -= t;
t = T(135);//c
B(4,0) -= t;
B(0,4) -= t;
B(2,1) += t;
B(1,2) += t;
B(3,1) += t;
B(1,3) += t;
t = T(173);//d
B(5,0) -= t;
B(0,5) -= t;
t = T(61);//b
B(6,0) -= t;
B(0,6) -= t;
B(5,1) += t;
B(1,5) += t;
t = T(42); //a
B(7,0) -= t;
B(0,7) -= t;
B(4,1) += t;
B(1,4) += t;
B(4,4) += t;
t = T(1084);//g
B(1,1) += t;
s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
break;
case 1:
B(0,1) -= T(6269);
B(0,3) -= T( 708);
B(0,5) -= T( 172);
B(0,7) -= T( 73);
s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
break;
case 2:
B(1,0) -= T(6269);
B(3,0) -= T( 708);
B(5,0) -= T( 172);
B(7,0) -= T( 73);
s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
break;
}
#undef B
#undef T
}
static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
int k;
for(k=0;k<8;k++){
memset(dst,pix,8);
dst+=linesize;
}
}
static const int16_t quant_table[64] = {
256, 256, 256, 256, 256, 256, 259, 262,
265, 269, 272, 275, 278, 282, 285, 288,
292, 295, 299, 303, 306, 310, 314, 317,
321, 325, 329, 333, 337, 341, 345, 349,
353, 358, 362, 366, 371, 375, 379, 384,
389, 393, 398, 403, 408, 413, 417, 422,
428, 433, 438, 443, 448, 454, 459, 465,
470, 476, 482, 488, 493, 499, 505, 511
};
static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
MpegEncContext * const s= w->s;
uint8_t * scantable;
int final,run,level;
int ac_mode,dc_mode,est_run,dc_level;
int pos,n;
int zeros_only;
int use_quant_matrix;
int sign;
assert(w->orient<12);
memset(s->block[0],0x00,64*sizeof(DCTELEM));
if(chroma){
dc_mode=2;
}else{
dc_mode=!!w->est_run;//0,1
}
if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
n=0;
zeros_only=0;
if(!final){//decode ac
use_quant_matrix=w->use_quant_matrix;
if(chroma){
ac_mode = 1;
est_run = 64;//not used
}else{
if (w->raw_orient < 3){
use_quant_matrix = 0;
}
if(w->raw_orient > 4){
ac_mode = 0;
est_run = 64;
}else{
if(w->est_run > 1){
ac_mode = 2;
est_run=w->est_run;
}else{
ac_mode = 3;
est_run = 64;
}
}
}
x8_select_ac_table(w,ac_mode);
/*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
-> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
pos=0;
do {
n++;
if( n >= est_run ){
ac_mode=3;
x8_select_ac_table(w,3);
}
x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
pos+=run+1;
if(pos>63){
//this also handles vlc error in x8_get_ac_rlf
return -1;
}
level= (level+1) * w->dquant;
level+= w->qsum;
sign = - get_bits1(&s->gb);
level = (level ^ sign) - sign;
if(use_quant_matrix){
level = (level*quant_table[pos])>>8;
}
s->block[0][ scantable[pos] ]=level;
}while(!final);
s->block_last_index[0]=pos;
}else{//DC only
s->block_last_index[0]=0;
if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
w->divide_quant_dc_chroma;
int32_t dc_quant = !chroma ? w->quant:
w->quant_dc_chroma;
//original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
s->dest[chroma], s->current_picture.linesize[!!chroma]);
goto block_placed;
}
zeros_only = (dc_level == 0);
}
if(!chroma){
s->block[0][0] = dc_level*w->quant;
}else{
s->block[0][0] = dc_level*w->quant_dc_chroma;
}
//there is !zero_only check in the original, but dc_level check is enough
if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
int direction;
/*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
-> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
direction= (0x6A017C>>(w->orient*2))&3;
if (direction != 3){
x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
}
}
if(w->flat_dc){
dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]);
}else{
s->dsp.x8_spacial_compensation[w->orient]( s->edge_emu_buffer,
s->dest[chroma],
s->current_picture.linesize[!!chroma] );
}
if(!zeros_only)
s->dsp.idct_add ( s->dest[chroma],
s->current_picture.linesize[!!chroma],
s->block[0] );
block_placed:
if(!chroma){
x8_update_predictions(w,w->orient,n);
}
if(s->loop_filter){
uint8_t* ptr = s->dest[chroma];
int linesize = s->current_picture.linesize[!!chroma];
if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
s->dsp.x8_h_loop_filter(ptr, linesize, w->quant);
}
if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
s->dsp.x8_v_loop_filter(ptr, linesize, w->quant);
}
}
return 0;
}
static inline void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
//not s->linesize as this would be wrong for field pics
//not that IntraX8 have interlace support ;)
const int linesize = s->current_picture.linesize[0];
const int uvlinesize= s->current_picture.linesize[1];
s->dest[0] = s->current_picture.data[0];
s->dest[1] = s->current_picture.data[1];
s->dest[2] = s->current_picture.data[2];
{
s->dest[0] += s->mb_y * linesize << 3;
s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
}
}
/**
* Initialize IntraX8 frame decoder.
* Requires valid MpegEncContext with valid s->mb_width before calling.
* @param w pointer to IntraX8Context
* @param s pointer to MpegEncContext of the parent codec
*/
void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
w->s=s;
x8_vlc_init();
assert(s->mb_width>0);
w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]);
ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]);
ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]);
}
/**
* Decode single IntraX8 frame.
* The parent codec must fill s->loopfilter and s->gb (bitstream).
* The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function
* The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
* This function does not use MPV_decode_mb().
* lowres decoding is theoretically impossible.
* @param w pointer to IntraX8Context
* @param dquant doubled quantizer, it would be odd in case of vc1 halfpq==1
* @param quant_offset offset away from zero.
*/
//FIXME extern uint8_t wmv3_dc_scale_table[32];
int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
MpegEncContext * const s= w->s;
int mb_xy;
assert(s);
w->use_quant_matrix = get_bits1(&s->gb);
w->dquant = dquant;
w->quant = dquant >> 1;
w->qsum = quant_offset;
w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant;
if(w->quant < 5){
w->quant_dc_chroma = w->quant;
w->divide_quant_dc_chroma = w->divide_quant_dc_luma;
}else{
w->quant_dc_chroma = w->quant+((w->quant+3)>>3);
w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma;
}
x8_reset_vlc_tables(w);
s->resync_mb_x=0;
s->resync_mb_y=0;
for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){
x8_init_block_index(s);
mb_xy=(s->mb_y>>1)*s->mb_stride;
for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){
x8_get_prediction(w);
if(x8_setup_spatial_predictor(w,0)) goto error;
if(x8_decode_intra_mb(w,0)) goto error;
if( s->mb_x & s->mb_y & 1 ){
x8_get_prediction_chroma(w);
/*when setting up chroma, no vlc is read,
so no error condition could be reached*/
x8_setup_spatial_predictor(w,1);
if(x8_decode_intra_mb(w,1)) goto error;
x8_setup_spatial_predictor(w,2);
if(x8_decode_intra_mb(w,2)) goto error;
s->dest[1]+= 8;
s->dest[2]+= 8;
/*emulate MB info in the relevant tables*/
s->mbskip_table [mb_xy]=0;
s->mbintra_table[mb_xy]=1;
s->current_picture.qscale_table[mb_xy]=w->quant;
mb_xy++;
}
s->dest[0]+= 8;
}
if(s->mb_y&1){
ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
}
}
error:
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
(s->mb_x>>1)-1, (s->mb_y>>1)-1,
(AC_END|DC_END|MV_END) );
return 0;
}

51
libavcodec/intrax8.h Normal file
View File

@ -0,0 +1,51 @@
/*
* 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
*/
typedef struct{
VLC * j_ac_vlc[4];//they point to the static j_mb_vlc
VLC * j_orient_vlc;
VLC * j_dc_vlc[3];
int use_quant_matrix;
//set by ff_intrax8_common_init
uint8_t * prediction_table;//2*(mb_w*2)
ScanTable scantable[3];
//set by the caller codec
MpegEncContext * s;
int quant;
int dquant;
int qsum;
//calculated per frame
int quant_dc_chroma;
int divide_quant_dc_luma;
int divide_quant_dc_chroma;
//changed per block
int edges;
int flat_dc;
int predicted_dc;
int raw_orient;
int chroma_orient;
int orient;
int est_run;
//#ifdef DEBUG
int mode_index[10];//debug only
//#endif
} IntraX8Context;
void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s);
int ff_intrax8_decode_picture(IntraX8Context * w, int quant, int halfpq);

485
libavcodec/intrax8dsp.c Normal file
View File

@ -0,0 +1,485 @@
/*
* 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 intrax8dsp.c
*@brief IntraX8 frame sub-decoder image manipulation routines
*
*/
#include "dsputil.h"
/*
area positions, #3 is 1 pixel only, other are 8 pixels
|66666666|
3|44444444|55555555|
- -+--------+--------+
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
1 2|XXXXXXXX|
^-start
*/
#define area1 (0)
#define area2 (8)
#define area3 (8+8)
#define area4 (8+8+1)
#define area5 (8+8+1+8)
#define area6 (8+8+1+16)
/**
Collect statistics and prepare the edge pixels required by the other spacial compensation functions.
* @param src pointer to the beginning of the processed block
* @param dst pointer to emu_edge, edge pixels are stored in way other compensation routines use.
* @param linesize byte offset between 2 vertical pixels in the source image
* @param range pointer to the variable where the range of edge pixels is to be stored (max-min values)
* @param psum pointer to the variable where the sum of edge pixels is to be stored
* @param edges informs this routine that the block is on image border, so it have to interpolate the missing edge pixels.
and some of the edge pixels should be interpolated, flag have following meaning:
1 - mb_x==0 - first block in the row, interpolate area #1,#2,#3;
2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6;
note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas;
4 - mb_x>= (mb_width-1) last block on the row, interpolate area #5;
*/
static void x8_setup_spacial_compensation(uint8_t *src, uint8_t *dst, int linesize,
int * range, int * psum, int edges){
uint8_t * ptr;
int sum;
int i;
int min_pix,max_pix;
uint8_t c;
if((edges&3)==3){
*psum=0x80*(8+1+8+2);
*range=0;
memset(dst,0x80,16+1+16+8);
//this triggers flat_dc for sure.
//flat_dc avoids all (other) prediction modes, but requires dc_level decoding.
return;
}
min_pix=256;
max_pix=-1;
sum=0;
if(!(edges&1)){//(mb_x!=0)//there is previous block on this row
ptr=src-1;//left column, area 2
for(i=7;i>=0;i--){
c=*(ptr-1);//area1, same mb as area2, no need to check
dst[area1+i]=c;
c=*(ptr);
sum+=c;
min_pix=FFMIN(min_pix,c);
max_pix=FFMAX(max_pix,c);
dst[area2+i]=c;
ptr+=linesize;
}
}
if(!(edges&2)){ //(mb_y!=0)//there is row above
ptr=src-linesize;//top line
for(i=0;i<8;i++){
c=*(ptr+i);
sum+=c;
min_pix=FFMIN(min_pix, c);
max_pix=FFMAX(max_pix, c);
}
if(edges&4){//last block on the row?
memset(dst+area5,c,8);//set with last pixel fr
memcpy(dst+area4, ptr, 8);
}else{
memcpy(dst+area4, ptr, 16);//both area4 and 5
}
memcpy(dst+area6, ptr-linesize, 8);//area6 always present in the above block
}
//now calc the stuff we need
if(edges&3){//mb_x==0 || mb_y==0){
if(edges&1){ //(mb_x==0) {//implies mb_y!=0
int avg=(sum+4)>>3;
memset(dst+area1,avg,8+8+1);//areas 1,2 and 3 are averaged
sum+=avg*9;//8+1(egde pixel)
}else{//implies y==0 x!=0
int avg=(sum+4)>>3;
memset(dst+area3,avg, 1+16+8);//areas 3, 4,5,6
sum+=avg*9;
}
}else{
uint8_t c;
c=*(src-1-linesize);//the edge pixel,in the top line and left column
dst[area3]=c;
sum+=c;
//edge pixel is not part of min/max
}
(*range) = max_pix - min_pix;
sum += *(dst+area5) + *(dst+area5+1);
*psum = sum;
}
static const uint16_t zero_prediction_weights[64*2] = {
640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72,
480, 669, 537, 537, 598, 416, 661, 316, 719, 250, 707, 185, 768, 134, 745, 97,
354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241, 716, 179, 706, 132,
257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180,
198, 792, 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231,
161, 855, 206, 788, 266, 710, 340, 623, 411, 548, 455, 455, 548, 366, 576, 288,
122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483, 520, 390,
110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499
};
static void spacial_compensation_0(uint8_t *src , uint8_t *dst, int linesize){
int i,j;
int x,y;
unsigned int p;//power divided by 2
int a;
uint16_t left_sum[2][8];
uint16_t top_sum[2][8];
memset(left_sum,0,2*8*sizeof(uint16_t));
memset( top_sum,0,2*8*sizeof(uint16_t));
for(i=0;i<8;i++){
a=src[area2+7-i]<<4;
for(j=0;j<8;j++){
p=abs(i-j);
left_sum[p&1][j]+= a>>(p>>1);
}
}
for(i=0;i<8;i++){
a=src[area4+i]<<4;
for(j=0;j<8;j++){
p=abs(i-j);
top_sum[p&1][j]+= a>>(p>>1);
}
}
for(;i<10;i++){
a=src[area4+i]<<4;
for(j=5;j<8;j++){
p=abs(i-j);
top_sum[p&1][j]+= a>>(p>>1);
}
}
for(;i<12;i++){
a=src[area4+i]<<4;
for(j=7;j<8;j++){
p=abs(i-j);
top_sum[p&1][j]+= a>>(p>>1);
}
}
for(i=0;i<8;i++){
top_sum [0][i]+=(top_sum [1][i]*181 + 128 )>>8;//181 is sqrt(2)/2
left_sum[0][i]+=(left_sum[1][i]*181 + 128 )>>8;
}
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x] = (
(uint32_t)top_sum [0][x]*zero_prediction_weights[y*16+x*2+0] +
(uint32_t)left_sum[0][y]*zero_prediction_weights[y*16+x*2+1] +
0x8000
)>>16;
}
dst+=linesize;
}
}
static void spacial_compensation_1(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=src[area4 + FFMIN(2*y+x+2, 15) ];
}
dst+=linesize;
}
}
static void spacial_compensation_2(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=src[area4 +1+y+x];
}
dst+=linesize;
}
}
static void spacial_compensation_3(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=src[area4 +((y+1)>>1)+x];
}
dst+=linesize;
}
}
static void spacial_compensation_4(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=( src[area4+x] + src[area6+x] + 1 )>>1;
}
dst+=linesize;
}
}
static void spacial_compensation_5(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
if(2*x-y<0){
dst[x]=src[area2+9+2*x-y];
}else{
dst[x]=src[area4 +x-((y+1)>>1)];
}
}
dst+=linesize;
}
}
static void spacial_compensation_6(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=src[area3+x-y];
}
dst+=linesize;
}
}
static void spacial_compensation_7(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
if(x-2*y>0){
dst[x]=( src[area3-1+x-2*y] + src[area3+x-2*y] + 1)>>1;
}else{
dst[x]=src[area2+8-y +(x>>1)];
}
}
dst+=linesize;
}
}
static void spacial_compensation_8(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=( src[area1+7-y] + src[area2+7-y] + 1 )>>1;
}
dst+=linesize;
}
}
static void spacial_compensation_9(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=src[area2+6-FFMIN(x+y,6)];
}
dst+=linesize;
}
}
static void spacial_compensation_10(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=(src[area2+7-y]*(8-x)+src[area4+x]*x+4)>>3;
}
dst+=linesize;
}
}
static void spacial_compensation_11(uint8_t *src , uint8_t *dst, int linesize){
int x,y;
for(y=0;y<8;y++){
for(x=0;x<8;x++){
dst[x]=(src[area2+7-y]*y+src[area4+x]*(8-y)+4)>>3;
}
dst+=linesize;
}
}
static void x8_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){
int i,t;
int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
int ql=(quant+10)>>3;
for(i=0; i<8; i++,ptr+=b_stride){
p0=ptr[-5*a_stride];
p1=ptr[-4*a_stride];
p2=ptr[-3*a_stride];
p3=ptr[-2*a_stride];
p4=ptr[-1*a_stride];
p5=ptr[ 0 ];
p6=ptr[ 1*a_stride];
p7=ptr[ 2*a_stride];
p8=ptr[ 3*a_stride];
p9=ptr[ 4*a_stride];
t=
(FFABS(p1-p2) <= ql) +
(FFABS(p2-p3) <= ql) +
(FFABS(p3-p4) <= ql) +
(FFABS(p4-p5) <= ql);
if(t>0){//you need at least 1 to be able to reach total score of 6.
t+=
(FFABS(p5-p6) <= ql) +
(FFABS(p6-p7) <= ql) +
(FFABS(p7-p8) <= ql) +
(FFABS(p8-p9) <= ql) +
(FFABS(p0-p1) <= ql);
if(t>=6){
int min,max;
min=max=p1;
min=FFMIN(min,p3); max=FFMAX(max,p3);
min=FFMIN(min,p5); max=FFMAX(max,p5);
min=FFMIN(min,p8); max=FFMAX(max,p8);
if(max-min<2*quant){//early stop
min=FFMIN(min,p2); max=FFMAX(max,p2);
min=FFMIN(min,p4); max=FFMAX(max,p4);
min=FFMIN(min,p6); max=FFMAX(max,p6);
min=FFMIN(min,p7); max=FFMAX(max,p7);
if(max-min<2*quant){
ptr[-2*a_stride]=(4*p2 + 3*p3 + 1*p7 + 4)>>3;
ptr[-1*a_stride]=(3*p2 + 3*p4 + 2*p7 + 4)>>3;
ptr[ 0 ]=(2*p2 + 3*p5 + 3*p7 + 4)>>3;
ptr[ 1*a_stride]=(1*p2 + 3*p6 + 4*p7 + 4)>>3;
continue;
};
}
}
}
{
int x,x0,x1,x2;
int m;
x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3;
if(FFABS(x0) < quant){
x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3;
x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3;
x=FFABS(x0) - FFMIN( FFABS(x1), FFABS(x2) );
m=p4-p5;
if( x > 0 && (m^x0) <0){
int32_t sign;
sign=m>>31;
m=(m^sign)-sign;//abs(m)
m>>=1;
x=(5*x)>>3;
if(x>m) x=m;
x=(x^sign)-sign;
ptr[-1*a_stride] -= x;
ptr[ 0] += x;
}
}
}
}
}
static void x8_h_loop_filter(uint8_t *src, int stride, int qscale){
x8_loop_filter(src, stride, 1, qscale);
}
static void x8_v_loop_filter(uint8_t *src, int stride, int qscale){
x8_loop_filter(src, 1, stride, qscale);
}
void ff_intrax8dsp_init(DSPContext* dsp, AVCodecContext *avctx) {
dsp->x8_h_loop_filter=x8_h_loop_filter;
dsp->x8_v_loop_filter=x8_v_loop_filter;
dsp->x8_setup_spacial_compensation=x8_setup_spacial_compensation;
dsp->x8_spacial_compensation[0]=spacial_compensation_0;
dsp->x8_spacial_compensation[1]=spacial_compensation_1;
dsp->x8_spacial_compensation[2]=spacial_compensation_2;
dsp->x8_spacial_compensation[3]=spacial_compensation_3;
dsp->x8_spacial_compensation[4]=spacial_compensation_4;
dsp->x8_spacial_compensation[5]=spacial_compensation_5;
dsp->x8_spacial_compensation[6]=spacial_compensation_6;
dsp->x8_spacial_compensation[7]=spacial_compensation_7;
dsp->x8_spacial_compensation[8]=spacial_compensation_8;
dsp->x8_spacial_compensation[9]=spacial_compensation_9;
dsp->x8_spacial_compensation[10]=spacial_compensation_10;
dsp->x8_spacial_compensation[11]=spacial_compensation_11;
}
#if 0
static void wmv2_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){
int i,t;
int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
for(i=0; i<8; i++,ptr+=b_stride){
p1=ptr[-4*a_stride];
p2=ptr[-3*a_stride];
p3=ptr[-2*a_stride];
p4=ptr[-1*a_stride];
p5=ptr[ 0 ];
p6=ptr[ 1*a_stride];
p7=ptr[ 2*a_stride];
p8=ptr[ 3*a_stride];
{
int x,x0,x1,x2;
int m;
x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3;
if(abs(x0) < quant){
x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3;
x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3;
x=abs(x0) - FFMIN( abs(x1), abs(x2) );
m=p4-p5;
if( x > 0 && (m^x0) < 0){
int32_t sign;
sign=m>>31;
m=(m^sign)-sign;//abs(m)
m>>=1;
x=(5*x)>>3;
if(x>m) x=m;
x=(x^sign)-sign;
ptr[-1*a_stride] -= x;
ptr[ 0] += x;
}
}
}
}
}
#endif

913
libavcodec/intrax8huf.h Normal file
View File

@ -0,0 +1,913 @@
/*
* 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 <inttypes.h>
const uint16_t ff_x8_orient_lowquant_table[4][12][2]={
{//0
{0x0000, 1}, {0x0004, 3}, {0x0005, 3}, {0x000C, 4},
{0x000D, 4}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6},
{0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6},
},{//1
{0x0000, 5}, {0x0001, 5}, {0x0002, 5}, {0x0001, 2},
{0x0002, 2}, {0x0002, 4}, {0x0003, 5}, {0x0006, 3},
{0x0003, 4}, {0x000E, 4}, {0x001E, 5}, {0x001F, 5},
},{//2
{0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3},
{0x0006, 3}, {0x0038, 6}, {0x0039, 6}, {0x001D, 5},
{0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6},
},{//3
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0001, 2},
{0x0002, 2}, {0x0018, 5}, {0x0019, 5}, {0x000D, 4},
{0x001C, 5}, {0x001D, 5}, {0x001E, 5}, {0x001F, 5},
}
};
const uint16_t ff_x8_orient_highquant_table[2][12][2]={
{//0
{0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3},
{0x0006, 3}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6},
{0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6},
},{//1
{0x0000, 1}, {0x0002, 2}, {0x0006, 3}, {0x001C, 5},
{0x001D, 5}, {0x0078, 7}, {0x003D, 6}, {0x0079, 7},
{0x007C, 7}, {0x007D, 7}, {0x007E, 7}, {0x007F, 7},
}
};
#define MAX_OR_VLC_BITS 7
const uint16_t ff_x8_dc_lowquant_table[8][34][2]={
{//0
{0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5},
{0x0005, 5}, {0x0006, 5}, {0x000E, 6}, {0x000F, 6},
{0x0040, 8}, {0x0041, 8}, {0x0840, 13}, {0x0841, 13},
{0x0842, 13}, {0x0843, 13}, {0x0844, 13}, {0x0845, 13},
{0x0846, 13}, {0x0002, 2}, {0x0003, 2}, {0x0003, 3},
{0x0005, 4}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8},
{0x0085, 9}, {0x0847, 13}, {0x0848, 13}, {0x0849, 13},
{0x084A, 13}, {0x084B, 13}, {0x084C, 13}, {0x084D, 13},
{0x084E, 13}, {0x084F, 13},
},{//1
{0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4},
{0x0006, 4}, {0x0004, 3}, {0x0007, 4}, {0x0005, 3},
{0x000C, 4}, {0x000D, 4}, {0x001C, 5}, {0x003A, 6},
{0x01D8, 9}, {0x01D9, 9}, {0x1DA0, 13}, {0x1DA1, 13},
{0x1DA2, 13}, {0x003C, 6}, {0x003D, 6}, {0x003E, 6},
{0x0077, 7}, {0x01DB, 9}, {0x007E, 7}, {0x00FE, 8},
{0x01FE, 9}, {0x1DA3, 13}, {0x1DA4, 13}, {0x1DA5, 13},
{0x0ED3, 12}, {0x0ED4, 12}, {0x01FF, 9}, {0x0ED5, 12},
{0x0ED6, 12}, {0x0ED7, 12},
},{//2
{0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4},
{0x0006, 4}, {0x0007, 4}, {0x0008, 4}, {0x0009, 4},
{0x0028, 6}, {0x0029, 6}, {0x0054, 7}, {0x0055, 7},
{0x0AC0, 12}, {0x0AC1, 12}, {0x0AC2, 12}, {0x0AC3, 12},
{0x0AC4, 12}, {0x000B, 4}, {0x0006, 3}, {0x000E, 4},
{0x001E, 5}, {0x003E, 6}, {0x003F, 6}, {0x0057, 7},
{0x00AD, 8}, {0x0AC5, 12}, {0x0AC6, 12}, {0x0AC7, 12},
{0x0AC8, 12}, {0x0AC9, 12}, {0x0ACA, 12}, {0x0ACB, 12},
{0x0566, 11}, {0x0567, 11},
},{//3
{0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3},
{0x0005, 3}, {0x0006, 3}, {0x0001, 4}, {0x000E, 4},
{0x003C, 6}, {0x003D, 6}, {0x007C, 7}, {0x00FA, 8},
{0x3EC0, 14}, {0x3EC1, 14}, {0x3EC2, 14}, {0x3EC3, 14},
{0x1F62, 13}, {0x01F7, 9}, {0x007E, 7}, {0x00FE, 8},
{0x00FF, 8}, {0x1F63, 13}, {0x1F64, 13}, {0x1F65, 13},
{0x1F66, 13}, {0x1F67, 13}, {0x1F68, 13}, {0x1F69, 13},
{0x1F6A, 13}, {0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13},
{0x1F6E, 13}, {0x1F6F, 13},
},{//4
{0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7},
{0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7},
{0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7},
{0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7},
{0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7},
{0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7},
{0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7},
{0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7},
{0x001E, 7}, {0x001F, 7},
},{//5
{0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0008, 6},
{0x0009, 6}, {0x000A, 6}, {0x0016, 7}, {0x000C, 6},
{0x0017, 7}, {0x000D, 6}, {0x0038, 8}, {0x001D, 7},
{0x0039, 8}, {0x0780, 13}, {0x0781, 13}, {0x0782, 13},
{0x0783, 13}, {0x0002, 3}, {0x0001, 1}, {0x0003, 3},
{0x001F, 7}, {0x003D, 8}, {0x0079, 9}, {0x0784, 13},
{0x0785, 13}, {0x0786, 13}, {0x0787, 13}, {0x0788, 13},
{0x0789, 13}, {0x078A, 13}, {0x078B, 13}, {0x078C, 13},
{0x078D, 13}, {0x03C7, 12},
},{//6
{0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3},
{0x0001, 4}, {0x000A, 4}, {0x0016, 5}, {0x002E, 6},
{0x005E, 7}, {0x005F, 7}, {0x00C0, 8}, {0x3040, 14},
{0x3041, 14}, {0x0305, 10}, {0x0183, 9}, {0x3042, 14},
{0x3043, 14}, {0x000D, 4}, {0x0007, 3}, {0x0019, 5},
{0x0031, 6}, {0x00C2, 8}, {0x00C3, 8}, {0x3044, 14},
{0x3045, 14}, {0x3046, 14}, {0x3047, 14}, {0x3048, 14},
{0x3049, 14}, {0x304A, 14}, {0x304B, 14}, {0x304C, 14},
{0x304D, 14}, {0x1827, 13},
},{//7
{0x0000, 6}, {0x0001, 6}, {0x0002, 6}, {0x0006, 7},
{0x0007, 7}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6},
{0x000E, 7}, {0x001E, 8}, {0x001F, 8}, {0x0040, 9},
{0x0082, 10}, {0x0830, 14}, {0x0831, 14}, {0x0832, 14},
{0x0833, 14}, {0x0001, 1}, {0x0001, 2}, {0x0003, 4},
{0x0005, 5}, {0x0009, 6}, {0x0011, 7}, {0x0021, 8},
{0x0834, 14}, {0x0835, 14}, {0x0836, 14}, {0x0837, 14},
{0x0838, 14}, {0x0839, 14}, {0x083A, 14}, {0x083B, 14},
{0x041E, 13}, {0x041F, 13},
}
};
const uint16_t ff_x8_dc_highquant_table[8][34][2]={
{//0
{0x0000, 5}, {0x0001, 4}, {0x0002, 4}, {0x0001, 5},
{0x0006, 5}, {0x0004, 4}, {0x0007, 5}, {0x000A, 5},
{0x002C, 7}, {0x002D, 7}, {0x05C0, 12}, {0x05C1, 12},
{0x05C2, 12}, {0x05C3, 12}, {0x05C4, 12}, {0x05C5, 12},
{0x05C6, 12}, {0x0003, 3}, {0x0002, 2}, {0x0006, 3},
{0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x002F, 7},
{0x005D, 8}, {0x05C7, 12}, {0x05C8, 12}, {0x05C9, 12},
{0x05CA, 12}, {0x05CB, 12}, {0x05CC, 12}, {0x05CD, 12},
{0x05CE, 12}, {0x05CF, 12},
},{//1
{0x0000, 3}, {0x0001, 3}, {0x0002, 3}, {0x0006, 4},
{0x0007, 4}, {0x0004, 3}, {0x000A, 4}, {0x000B, 4},
{0x0030, 6}, {0x0062, 7}, {0x0063, 7}, {0x0640, 11},
{0x0641, 11}, {0x0642, 11}, {0x0643, 11}, {0x0644, 11},
{0x0645, 11}, {0x0033, 6}, {0x000D, 4}, {0x001C, 5},
{0x001D, 5}, {0x003C, 6}, {0x001F, 5}, {0x0065, 7},
{0x007A, 7}, {0x0646, 11}, {0x007B, 7}, {0x0647, 11},
{0x0648, 11}, {0x0649, 11}, {0x064A, 11}, {0x064B, 11},
{0x0326, 10}, {0x0327, 10},
},{//2
{0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0004, 7},
{0x0003, 6}, {0x0005, 7}, {0x0010, 8}, {0x0011, 8},
{0x0240, 13}, {0x0241, 13}, {0x0242, 13}, {0x0243, 13},
{0x0244, 13}, {0x0245, 13}, {0x0246, 13}, {0x0247, 13},
{0x0124, 12}, {0x0001, 1}, {0x0001, 2}, {0x0001, 3},
{0x0003, 5}, {0x0005, 6}, {0x0013, 8}, {0x0125, 12},
{0x0126, 12}, {0x0127, 12}, {0x0128, 12}, {0x0129, 12},
{0x012A, 12}, {0x012B, 12}, {0x012C, 12}, {0x012D, 12},
{0x012E, 12}, {0x012F, 12},
},{//3
{0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4},
{0x0006, 4}, {0x0004, 3}, {0x0005, 3}, {0x0006, 3},
{0x000E, 5}, {0x000F, 5}, {0x0070, 7}, {0x0710, 11},
{0x0711, 11}, {0x0712, 11}, {0x0713, 11}, {0x0714, 11},
{0x0715, 11}, {0x001D, 5}, {0x0072, 7}, {0x003C, 6},
{0x003D, 6}, {0x0073, 7}, {0x007C, 7}, {0x007D, 7},
{0x007E, 7}, {0x0716, 11}, {0x0717, 11}, {0x0718, 11},
{0x007F, 7}, {0x0719, 11}, {0x071A, 11}, {0x071B, 11},
{0x038E, 10}, {0x038F, 10},
},{//4
{0x0000, 8}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7},
{0x0002, 9}, {0x0008, 8}, {0x0003, 9}, {0x0240, 14},
{0x0241, 14}, {0x0242, 14}, {0x0243, 14}, {0x0244, 14},
{0x0245, 14}, {0x0246, 14}, {0x0247, 14}, {0x0124, 13},
{0x0125, 13}, {0x0001, 2}, {0x0001, 1}, {0x0001, 3},
{0x0001, 4}, {0x0003, 6}, {0x0005, 7}, {0x0013, 9},
{0x0126, 13}, {0x0127, 13}, {0x0128, 13}, {0x0129, 13},
{0x012A, 13}, {0x012B, 13}, {0x012C, 13}, {0x012D, 13},
{0x012E, 13}, {0x012F, 13},
},{//5
{0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0002, 6},
{0x0003, 6}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6},
{0x0007, 6}, {0x0008, 6}, {0x0009, 6}, {0x000A, 6},
{0x000B, 6}, {0x000C, 6}, {0x000D, 6}, {0x000E, 6},
{0x000F, 6}, {0x0010, 6}, {0x0011, 6}, {0x0012, 6},
{0x0013, 6}, {0x0014, 6}, {0x0015, 6}, {0x0016, 6},
{0x0017, 6}, {0x0018, 6}, {0x0019, 6}, {0x0001, 1},
{0x001A, 6}, {0x001B, 6}, {0x001C, 6}, {0x001D, 6},
{0x001E, 6}, {0x001F, 6},
},{//6
{0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5},
{0x000A, 6}, {0x0006, 5}, {0x000B, 6}, {0x000E, 6},
{0x003C, 8}, {0x003D, 8}, {0x07C0, 13}, {0x07C1, 13},
{0x07C2, 13}, {0x07C3, 13}, {0x07C4, 13}, {0x07C5, 13},
{0x07C6, 13}, {0x0001, 2}, {0x0002, 2}, {0x0006, 3},
{0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x003F, 8},
{0x007D, 9}, {0x07C7, 13}, {0x07C8, 13}, {0x07C9, 13},
{0x07CA, 13}, {0x07CB, 13}, {0x07CC, 13}, {0x07CD, 13},
{0x07CE, 13}, {0x07CF, 13},
},{//7
{0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7},
{0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7},
{0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7},
{0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7},
{0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7},
{0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7},
{0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7},
{0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7},
{0x001E, 7}, {0x001F, 7},
}
};
#define MAX_DC_VLC_BITS 14
const uint16_t ff_x8_ac0_lowquant_table[8][77][2]={
{//0
{0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5},
{0x001E, 6}, {0x003E, 7}, {0x003F, 7}, {0x0040, 7},
{0x0104, 9}, {0x0083, 8}, {0x0084, 8}, {0x0085, 8},
{0x020A, 10}, {0x020B, 10}, {0x0218, 10}, {0x0219, 10},
{0x0009, 4}, {0x0044, 7}, {0x010D, 9}, {0x021C, 10},
{0x0023, 6}, {0x0045, 7}, {0x0050, 7}, {0x000B, 4},
{0x000C, 4}, {0x0015, 5}, {0x001A, 5}, {0x001B, 5},
{0x0029, 6}, {0x0038, 6}, {0x0039, 6}, {0x003A, 6},
{0x0051, 7}, {0x0076, 7}, {0x0077, 7}, {0x0078, 7},
{0x0079, 7}, {0x007A, 7}, {0x007B, 7}, {0x00F8, 8},
{0x010F, 9}, {0x021D, 10}, {0x3E40, 14}, {0x3E41, 14},
{0x3E42, 14}, {0x3E43, 14}, {0x03E5, 10}, {0x3E44, 14},
{0x01F3, 9}, {0x3E45, 14}, {0x3E46, 14}, {0x3E47, 14},
{0x00FA, 8}, {0x3E48, 14}, {0x3E49, 14}, {0x3E4A, 14},
{0x3E4B, 14}, {0x03EC, 10}, {0x3E4C, 14}, {0x007E, 7},
{0x00FE, 8}, {0x00FF, 8}, {0x01F7, 9}, {0x3E4D, 14},
{0x3E4E, 14}, {0x3E4F, 14}, {0x3ED0, 14}, {0x3ED1, 14},
{0x3ED2, 14}, {0x3ED3, 14}, {0x3ED4, 14}, {0x3ED5, 14},
{0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13}, {0x1F6E, 13},
{0x1F6F, 13},
},{//1
{0x0000, 3}, {0x0004, 5}, {0x0014, 7}, {0x000B, 6},
{0x000C, 6}, {0x002A, 8}, {0x002B, 8}, {0x0034, 8},
{0x0D40, 14}, {0x0D41, 14}, {0x001B, 7}, {0x0D42, 14},
{0x0D43, 14}, {0x0D44, 14}, {0x0D45, 14}, {0x0D46, 14},
{0x000E, 6}, {0x003C, 8}, {0x0D47, 14}, {0x003D, 8},
{0x0D48, 14}, {0x0D49, 14}, {0x0D4A, 14}, {0x0001, 2},
{0x0004, 3}, {0x0014, 5}, {0x000B, 4}, {0x000C, 4},
{0x000D, 4}, {0x002A, 6}, {0x001F, 7}, {0x0056, 7},
{0x0057, 7}, {0x0070, 7}, {0x00E2, 8}, {0x0072, 7},
{0x003A, 6}, {0x003B, 6}, {0x003C, 6}, {0x003D, 6},
{0x00E3, 8}, {0x0D4B, 14}, {0x00E6, 8}, {0x00E7, 8},
{0x00F8, 8}, {0x0D4C, 14}, {0x0D4D, 14}, {0x0D4E, 14},
{0x00F9, 8}, {0x0D4F, 14}, {0x0D50, 14}, {0x0D51, 14},
{0x06A9, 13}, {0x06AA, 13}, {0x06AB, 13}, {0x06AC, 13},
{0x06AD, 13}, {0x06AE, 13}, {0x06AF, 13}, {0x003F, 6},
{0x06B0, 13}, {0x06B1, 13}, {0x06B2, 13}, {0x06B3, 13},
{0x06B4, 13}, {0x007D, 7}, {0x06B5, 13}, {0x06B6, 13},
{0x06B7, 13}, {0x06B8, 13}, {0x06B9, 13}, {0x06BA, 13},
{0x06BB, 13}, {0x06BC, 13}, {0x06BD, 13}, {0x06BE, 13},
{0x06BF, 13},
},{//2
{0x0000, 2}, {0x0002, 3}, {0x0003, 3}, {0x0008, 4},
{0x0012, 5}, {0x0013, 5}, {0x0028, 6}, {0x0029, 6},
{0x0054, 7}, {0x0055, 7}, {0x0056, 7}, {0x00AE, 8},
{0x00AF, 8}, {0x00B0, 8}, {0x0162, 9}, {0x02C6, 10},
{0x000C, 4}, {0x002D, 6}, {0x00B2, 8}, {0x0166, 9},
{0x002E, 6}, {0x0167, 9}, {0x00BC, 8}, {0x001A, 5},
{0x0036, 6}, {0x0037, 6}, {0x0038, 6}, {0x005F, 7},
{0x0072, 7}, {0x0073, 7}, {0x0074, 7}, {0x0075, 7},
{0x0076, 7}, {0x0077, 7}, {0x0078, 7}, {0x0079, 7},
{0x007A, 7}, {0x007B, 7}, {0x00BD, 8}, {0xB1C0, 16},
{0xB1C1, 16}, {0x58E1, 15}, {0x0B1D, 12}, {0x58E2, 15},
{0x58E3, 15}, {0x58E4, 15}, {0x00F8, 8}, {0x03E4, 10},
{0x01F3, 9}, {0x0B1E, 12}, {0x58E5, 15}, {0x58E6, 15},
{0x00FA, 8}, {0x58E7, 15}, {0x58F8, 15}, {0x58F9, 15},
{0x58FA, 15}, {0x01F6, 9}, {0x58FB, 15}, {0x007E, 7},
{0x00FE, 8}, {0x00FF, 8}, {0x07CA, 11}, {0x0F96, 12},
{0x58FC, 15}, {0x58FD, 15}, {0x58FE, 15}, {0x58FF, 15},
{0x7CB8, 15}, {0x7CB9, 15}, {0x7CBA, 15}, {0x7CBB, 15},
{0x7CBC, 15}, {0x01F7, 9}, {0x7CBD, 15}, {0x7CBE, 15},
{0x7CBF, 15},
},{//3
{0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5},
{0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7},
{0x0045, 7}, {0x008C, 8}, {0x008D, 8}, {0x011C, 9},
{0x011D, 9}, {0x011E, 9}, {0x023E, 10}, {0x023F, 10},
{0x0005, 3}, {0x0012, 5}, {0x004C, 7}, {0x004D, 7},
{0x000C, 4}, {0x004E, 7}, {0x001A, 5}, {0x0036, 6},
{0x004F, 7}, {0x006E, 7}, {0x006F, 7}, {0x00E0, 8},
{0x00E1, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8},
{0x00E5, 8}, {0x01CC, 9}, {0x00E7, 8}, {0x00E8, 8},
{0x00E9, 8}, {0x01CD, 9}, {0x0750, 11}, {0x03A9, 10},
{0x0751, 11}, {0x7540, 15}, {0x03AB, 10}, {0x7541, 15},
{0x7542, 15}, {0x7543, 15}, {0x01D6, 9}, {0x0755, 11},
{0x0076, 7}, {0x0EA9, 12}, {0x7544, 15}, {0x7545, 15},
{0x001E, 5}, {0x0077, 7}, {0x00F8, 8}, {0x03AE, 10},
{0x075E, 11}, {0x007D, 7}, {0x03E4, 10}, {0x00FC, 8},
{0x00FD, 8}, {0x03E5, 10}, {0x03E6, 10}, {0x0EBE, 12},
{0x7546, 15}, {0x07CE, 11}, {0x7547, 15}, {0x75F8, 15},
{0x75F9, 15}, {0x75FA, 15}, {0x75FB, 15}, {0x75FC, 15},
{0x75FD, 15}, {0x007F, 7}, {0x3AFF, 14}, {0x0F9E, 12},
{0x0F9F, 12},
},{//4
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x002A, 7},
{0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x005D, 8},
{0x005E, 8}, {0x00BE, 9}, {0x00BF, 9}, {0x0060, 8},
{0x0007, 4}, {0x000D, 5}, {0x0019, 6}, {0x0020, 6},
{0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x0014, 5},
{0x002A, 6}, {0x002B, 6}, {0x002C, 6}, {0x002D, 6},
{0x002E, 6}, {0x002F, 6}, {0x0030, 6}, {0x0031, 7},
{0x0062, 7}, {0x0063, 7}, {0x0064, 7}, {0x0065, 7},
{0x0066, 7}, {0x0061, 8}, {0x0670, 11}, {0x0068, 7},
{0x0069, 7}, {0x00CF, 8}, {0x019D, 9}, {0x01A8, 9},
{0x01A9, 9}, {0x0339, 10}, {0x01AA, 9}, {0x0356, 10},
{0x0036, 6}, {0x00D6, 8}, {0x6710, 15}, {0x6711, 15},
{0x000E, 4}, {0x006E, 7}, {0x01AE, 9}, {0x6712, 15},
{0x6713, 15}, {0x003C, 6}, {0x0357, 10}, {0x006F, 7},
{0x00F4, 8}, {0x00F5, 8}, {0x035E, 10}, {0x01EC, 9},
{0x6714, 15}, {0x01ED, 9}, {0x035F, 10}, {0x03DC, 10},
{0x03DD, 10}, {0x6715, 15}, {0x338B, 14}, {0x338C, 14},
{0x338D, 14}, {0x001F, 5}, {0x01EF, 9}, {0x338E, 14},
{0x338F, 14},
},{//5
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5},
{0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8},
{0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x036C, 11},
{0x006E, 8}, {0x01B7, 10}, {0x036D, 11}, {0x3780, 15},
{0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7},
{0x000A, 4}, {0x002C, 6}, {0x0017, 5}, {0x002D, 6},
{0x003F, 7}, {0x00C0, 8}, {0x0061, 7}, {0x00C1, 8},
{0x0062, 7}, {0x00C6, 8}, {0x0064, 7}, {0x00C7, 8},
{0x00CA, 8}, {0x00DF, 9}, {0x0196, 9}, {0x0197, 9},
{0x0198, 9}, {0x0199, 9}, {0x0379, 11}, {0x019A, 9},
{0x01BD, 10}, {0x066C, 11}, {0x3781, 15}, {0x0337, 10},
{0x066D, 11}, {0x0670, 11}, {0x0339, 10}, {0x0671, 11},
{0x0034, 6}, {0x00CF, 8}, {0x3782, 15}, {0x3783, 15},
{0x000E, 4}, {0x001B, 5}, {0x006A, 7}, {0x006B, 7},
{0x019D, 9}, {0x003C, 6}, {0x00F4, 8}, {0x00F5, 8},
{0x03D8, 10}, {0x07B2, 11}, {0x3784, 15}, {0x03DA, 10},
{0x3785, 15}, {0x03DB, 10}, {0x03DC, 10}, {0x3786, 15},
{0x3787, 15}, {0x1BC4, 14}, {0x1BC5, 14}, {0x1BC6, 14},
{0x1BC7, 14}, {0x001F, 5}, {0x03DD, 10}, {0x07B3, 11},
{0x01EF, 9},
},{//6
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6},
{0x0017, 6}, {0x0060, 8}, {0x00C2, 9}, {0x0186, 10},
{0x0187, 10}, {0x00C4, 9}, {0x3140, 15}, {0x3141, 15},
{0x018B, 10}, {0x3142, 15}, {0x018C, 10}, {0x3143, 15},
{0x0007, 4}, {0x000D, 5}, {0x0064, 8}, {0x0065, 8},
{0x0010, 5}, {0x00C7, 9}, {0x0066, 8}, {0x0005, 3},
{0x0006, 3}, {0x0009, 4}, {0x0011, 5}, {0x0038, 6},
{0x0039, 6}, {0x0074, 7}, {0x0075, 7}, {0x0076, 7},
{0x0067, 8}, {0x00EE, 8}, {0x01DE, 9}, {0x00F0, 8},
{0x018D, 10}, {0x3144, 15}, {0x01DF, 9}, {0x003D, 6},
{0x003E, 6}, {0x01E2, 9}, {0x03C6, 10}, {0x00F2, 8},
{0x00F3, 8}, {0x03C7, 10}, {0x3145, 15}, {0x3146, 15},
{0x01F8, 9}, {0x3147, 15}, {0x3148, 15}, {0x3149, 15},
{0x00FD, 8}, {0x314A, 15}, {0x314B, 15}, {0x314C, 15},
{0x314D, 15}, {0x01F9, 9}, {0x314E, 15}, {0x01FC, 9},
{0x314F, 15}, {0x3150, 15}, {0x3151, 15}, {0x3152, 15},
{0x3153, 15}, {0x03FA, 10}, {0x03FB, 10}, {0x3154, 15},
{0x3155, 15}, {0x3156, 15}, {0x3157, 15}, {0x3158, 15},
{0x3159, 15}, {0x00FF, 8}, {0x18AD, 14}, {0x18AE, 14},
{0x18AF, 14},
},{//7
{0x0000, 4}, {0x0080, 11}, {0x0081, 11}, {0x0082, 11},
{0x0083, 11}, {0x0084, 11}, {0x0085, 11}, {0x0086, 11},
{0x0087, 11}, {0x0088, 11}, {0x0089, 11}, {0x008A, 11},
{0x008B, 11}, {0x008C, 11}, {0x008D, 11}, {0x008E, 11},
{0x008F, 11}, {0x0048, 10}, {0x0049, 10}, {0x004A, 10},
{0x004B, 10}, {0x004C, 10}, {0x004D, 10}, {0x0001, 1},
{0x0001, 2}, {0x004E, 10}, {0x0002, 4}, {0x0003, 4},
{0x004F, 10}, {0x0050, 10}, {0x0051, 10}, {0x0052, 10},
{0x0053, 10}, {0x0054, 10}, {0x0055, 10}, {0x0056, 10},
{0x0057, 10}, {0x0058, 10}, {0x0059, 10}, {0x005A, 10},
{0x005B, 10}, {0x005C, 10}, {0x005D, 10}, {0x005E, 10},
{0x005F, 10}, {0x0060, 10}, {0x0061, 10}, {0x0062, 10},
{0x0063, 10}, {0x0064, 10}, {0x0065, 10}, {0x0066, 10},
{0x0067, 10}, {0x0068, 10}, {0x0069, 10}, {0x006A, 10},
{0x006B, 10}, {0x006C, 10}, {0x006D, 10}, {0x006E, 10},
{0x006F, 10}, {0x0070, 10}, {0x0071, 10}, {0x0072, 10},
{0x0073, 10}, {0x0074, 10}, {0x0075, 10}, {0x0076, 10},
{0x0077, 10}, {0x0078, 10}, {0x0079, 10}, {0x007A, 10},
{0x007B, 10}, {0x007C, 10}, {0x007D, 10}, {0x007E, 10},
{0x007F, 10},
}
};
const uint16_t ff_x8_ac0_highquant_table[8][77][2]={
{//0
{0x0000, 3}, {0x0002, 4}, {0x000C, 6}, {0x000D, 6},
{0x001C, 7}, {0x000F, 6}, {0x1D00, 15}, {0x003B, 8},
{0x1D01, 15}, {0x0075, 9}, {0x1D02, 15}, {0x0080, 9},
{0x1D03, 15}, {0x1D04, 15}, {0x1D05, 15}, {0x0E83, 14},
{0x0009, 5}, {0x0011, 6}, {0x0081, 9}, {0x0082, 9},
{0x0021, 7}, {0x0028, 7}, {0x0083, 9}, {0x0002, 2},
{0x0003, 3}, {0x000C, 4}, {0x000D, 4}, {0x000B, 5},
{0x0015, 6}, {0x0052, 8}, {0x0070, 7}, {0x0039, 6},
{0x0071, 7}, {0x0053, 8}, {0x0E84, 14}, {0x0074, 7},
{0x0075, 7}, {0x0076, 7}, {0x01DC, 9}, {0x001E, 5},
{0x003E, 6}, {0x01DD, 9}, {0x00EF, 8}, {0x01F8, 9},
{0x01F9, 9}, {0x0E85, 14}, {0x0E86, 14}, {0x0E87, 14},
{0x00FD, 8}, {0x0E88, 14}, {0x0E89, 14}, {0x0E8A, 14},
{0x0E8B, 14}, {0x0E8C, 14}, {0x0E8D, 14}, {0x0E8E, 14},
{0x0E8F, 14}, {0x0E90, 14}, {0x0E91, 14}, {0x01FC, 9},
{0x0E92, 14}, {0x0E93, 14}, {0x0E94, 14}, {0x0E95, 14},
{0x0E96, 14}, {0x0E97, 14}, {0x01FD, 9}, {0x0E98, 14},
{0x01FE, 9}, {0x0E99, 14}, {0x0E9A, 14}, {0x0E9B, 14},
{0x0E9C, 14}, {0x01FF, 9}, {0x0E9D, 14}, {0x0E9E, 14},
{0x0E9F, 14},
},{//1
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x0015, 6},
{0x002C, 7}, {0x005A, 8}, {0x005B, 8}, {0x005C, 8},
{0x005D, 8}, {0x1780, 14}, {0x0179, 10}, {0x017A, 10},
{0x0006, 4}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7},
{0x0010, 5}, {0x0022, 6}, {0x0012, 5}, {0x000A, 4},
{0x0013, 5}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6},
{0x002F, 6}, {0x0030, 6}, {0x0031, 6}, {0x003F, 7},
{0x005F, 8}, {0x00C8, 8}, {0x0065, 7}, {0x0066, 7},
{0x0067, 7}, {0x0068, 7}, {0x00C9, 8}, {0x0069, 7},
{0x006A, 7}, {0x00D6, 8}, {0x00D7, 8}, {0x00D8, 8},
{0x1781, 14}, {0x017B, 10}, {0x01B2, 9}, {0x1782, 14},
{0x001C, 5}, {0x01B3, 9}, {0x1783, 14}, {0x1784, 14},
{0x001D, 5}, {0x00DA, 8}, {0x1785, 14}, {0x1786, 14},
{0x1787, 14}, {0x0037, 6}, {0x00DB, 8}, {0x0078, 7},
{0x00F2, 8}, {0x01E6, 9}, {0x00F4, 8}, {0x1788, 14},
{0x1789, 14}, {0x00F5, 8}, {0x01E7, 9}, {0x178A, 14},
{0x178B, 14}, {0x178C, 14}, {0x178D, 14}, {0x01EC, 9},
{0x178E, 14}, {0x001F, 5}, {0x00F7, 8}, {0x01ED, 9},
{0x178F, 14},
},{//2
{0x0000, 4}, {0x0002, 5}, {0x0180, 12}, {0x0181, 12},
{0x0182, 12}, {0x0183, 12}, {0x0184, 12}, {0x0185, 12},
{0x0186, 12}, {0x0187, 12}, {0x0188, 12}, {0x0189, 12},
{0x00C5, 11}, {0x00C6, 11}, {0x00C7, 11}, {0x00C8, 11},
{0x00C9, 11}, {0x00CA, 11}, {0x00CB, 11}, {0x00CC, 11},
{0x00CD, 11}, {0x00CE, 11}, {0x00CF, 11}, {0x0001, 1},
{0x0001, 2}, {0x0004, 5}, {0x0005, 5}, {0x0006, 5},
{0x00D0, 11}, {0x00D1, 11}, {0x00D2, 11}, {0x00D3, 11},
{0x00D4, 11}, {0x00D5, 11}, {0x00D6, 11}, {0x00D7, 11},
{0x00D8, 11}, {0x00D9, 11}, {0x00DA, 11}, {0x0007, 5},
{0x00DB, 11}, {0x00DC, 11}, {0x00DD, 11}, {0x00DE, 11},
{0x00DF, 11}, {0x00E0, 11}, {0x00E1, 11}, {0x00E2, 11},
{0x00E3, 11}, {0x00E4, 11}, {0x00E5, 11}, {0x00E6, 11},
{0x00E7, 11}, {0x00E8, 11}, {0x00E9, 11}, {0x00EA, 11},
{0x00EB, 11}, {0x00EC, 11}, {0x00ED, 11}, {0x00EE, 11},
{0x00EF, 11}, {0x00F0, 11}, {0x00F1, 11}, {0x00F2, 11},
{0x00F3, 11}, {0x00F4, 11}, {0x00F5, 11}, {0x00F6, 11},
{0x00F7, 11}, {0x00F8, 11}, {0x00F9, 11}, {0x00FA, 11},
{0x00FB, 11}, {0x00FC, 11}, {0x00FD, 11}, {0x00FE, 11},
{0x00FF, 11},
},{//3
{0x0000, 8}, {0x0001, 8}, {0x0002, 8}, {0x0003, 8},
{0x0004, 8}, {0x0005, 8}, {0x0006, 8}, {0x0007, 8},
{0x0008, 8}, {0x0009, 8}, {0x000A, 8}, {0x000B, 8},
{0x000C, 8}, {0x000D, 8}, {0x000E, 8}, {0x000F, 8},
{0x0010, 8}, {0x0011, 8}, {0x0012, 8}, {0x0013, 8},
{0x0014, 8}, {0x0015, 8}, {0x0016, 8}, {0x0001, 1},
{0x0017, 8}, {0x000C, 7}, {0x000D, 7}, {0x000E, 7},
{0x000F, 7}, {0x0010, 7}, {0x0011, 7}, {0x0012, 7},
{0x0013, 7}, {0x0014, 7}, {0x0015, 7}, {0x0016, 7},
{0x0017, 7}, {0x0018, 7}, {0x0019, 7}, {0x001A, 7},
{0x001B, 7}, {0x001C, 7}, {0x001D, 7}, {0x001E, 7},
{0x001F, 7}, {0x0020, 7}, {0x0021, 7}, {0x0022, 7},
{0x0023, 7}, {0x0024, 7}, {0x0025, 7}, {0x0026, 7},
{0x0027, 7}, {0x0028, 7}, {0x0029, 7}, {0x002A, 7},
{0x002B, 7}, {0x002C, 7}, {0x002D, 7}, {0x002E, 7},
{0x002F, 7}, {0x0030, 7}, {0x0031, 7}, {0x0032, 7},
{0x0033, 7}, {0x0034, 7}, {0x0035, 7}, {0x0036, 7},
{0x0037, 7}, {0x0038, 7}, {0x0039, 7}, {0x003A, 7},
{0x003B, 7}, {0x003C, 7}, {0x003D, 7}, {0x003E, 7},
{0x003F, 7},
},{//4
{0x0000, 9}, {0x0001, 9}, {0x0002, 9}, {0x0003, 9},
{0x0004, 9}, {0x0005, 9}, {0x0006, 9}, {0x0007, 9},
{0x0008, 9}, {0x0009, 9}, {0x000A, 9}, {0x000B, 9},
{0x000C, 9}, {0x000D, 9}, {0x000E, 9}, {0x000F, 9},
{0x0010, 9}, {0x0011, 9}, {0x0012, 9}, {0x0013, 9},
{0x0014, 9}, {0x0015, 9}, {0x000B, 8}, {0x0001, 2},
{0x0001, 1}, {0x000C, 8}, {0x000D, 8}, {0x000E, 8},
{0x000F, 8}, {0x0010, 8}, {0x0011, 8}, {0x0012, 8},
{0x0013, 8}, {0x0014, 8}, {0x0015, 8}, {0x0016, 8},
{0x0017, 8}, {0x0018, 8}, {0x0019, 8}, {0x001A, 8},
{0x001B, 8}, {0x001C, 8}, {0x001D, 8}, {0x001E, 8},
{0x001F, 8}, {0x0020, 8}, {0x0021, 8}, {0x0022, 8},
{0x0023, 8}, {0x0024, 8}, {0x0025, 8}, {0x0026, 8},
{0x0027, 8}, {0x0028, 8}, {0x0029, 8}, {0x002A, 8},
{0x002B, 8}, {0x002C, 8}, {0x002D, 8}, {0x002E, 8},
{0x002F, 8}, {0x0030, 8}, {0x0031, 8}, {0x0032, 8},
{0x0033, 8}, {0x0034, 8}, {0x0035, 8}, {0x0036, 8},
{0x0037, 8}, {0x0038, 8}, {0x0039, 8}, {0x003A, 8},
{0x003B, 8}, {0x003C, 8}, {0x003D, 8}, {0x003E, 8},
{0x003F, 8},
},{//5
{0x0000, 10}, {0x0001, 10}, {0x0002, 10}, {0x0003, 10},
{0x0004, 10}, {0x0005, 10}, {0x0006, 10}, {0x0007, 10},
{0x0008, 10}, {0x0009, 10}, {0x000A, 10}, {0x000B, 10},
{0x000C, 10}, {0x000D, 10}, {0x000E, 10}, {0x000F, 10},
{0x0010, 10}, {0x0011, 10}, {0x0012, 10}, {0x0013, 10},
{0x000A, 9}, {0x000B, 9}, {0x000C, 9}, {0x0001, 1},
{0x0001, 3}, {0x000D, 9}, {0x000E, 9}, {0x0001, 2},
{0x000F, 9}, {0x0010, 9}, {0x0011, 9}, {0x0012, 9},
{0x0013, 9}, {0x0014, 9}, {0x0015, 9}, {0x0016, 9},
{0x0017, 9}, {0x0018, 9}, {0x0019, 9}, {0x001A, 9},
{0x001B, 9}, {0x001C, 9}, {0x001D, 9}, {0x001E, 9},
{0x001F, 9}, {0x0020, 9}, {0x0021, 9}, {0x0022, 9},
{0x0023, 9}, {0x0024, 9}, {0x0025, 9}, {0x0026, 9},
{0x0027, 9}, {0x0028, 9}, {0x0029, 9}, {0x002A, 9},
{0x002B, 9}, {0x002C, 9}, {0x002D, 9}, {0x002E, 9},
{0x002F, 9}, {0x0030, 9}, {0x0031, 9}, {0x0032, 9},
{0x0033, 9}, {0x0034, 9}, {0x0035, 9}, {0x0036, 9},
{0x0037, 9}, {0x0038, 9}, {0x0039, 9}, {0x003A, 9},
{0x003B, 9}, {0x003C, 9}, {0x003D, 9}, {0x003E, 9},
{0x003F, 9},
},{//6
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5},
{0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8},
{0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x00DB, 9},
{0x01B8, 10}, {0x00DD, 9}, {0x01B9, 10}, {0x3780, 15},
{0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x001F, 6},
{0x000A, 4}, {0x0058, 7}, {0x0017, 5}, {0x0018, 5},
{0x0059, 7}, {0x005A, 7}, {0x005B, 7}, {0x00C8, 8},
{0x0065, 7}, {0x0066, 7}, {0x00C9, 8}, {0x00CE, 8},
{0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8},
{0x00D3, 8}, {0x00DF, 9}, {0x00D4, 8}, {0x00D5, 8},
{0x00D6, 8}, {0x01AE, 9}, {0x3781, 15}, {0x01BD, 10},
{0x035E, 10}, {0x035F, 10}, {0x3782, 15}, {0x0360, 10},
{0x0037, 6}, {0x01B1, 9}, {0x3783, 15}, {0x3784, 15},
{0x000E, 4}, {0x003C, 6}, {0x0361, 10}, {0x3785, 15},
{0x1BC3, 14}, {0x003D, 6}, {0x00D9, 8}, {0x1BC4, 14},
{0x0368, 10}, {0x1BC5, 14}, {0x1BC6, 14}, {0x1BC7, 14},
{0x1BC8, 14}, {0x00DB, 8}, {0x0369, 10}, {0x036A, 10},
{0x1BC9, 14}, {0x1BCA, 14}, {0x1BCB, 14}, {0x1BCC, 14},
{0x1BCD, 14}, {0x001F, 5}, {0x036B, 10}, {0x1BCE, 14},
{0x1BCF, 14},
},{//7
{0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5},
{0x0010, 6}, {0x0044, 8}, {0x0023, 7}, {0x0012, 6},
{0x0026, 7}, {0x08A0, 13}, {0x004E, 8}, {0x004F, 8},
{0x08A1, 13}, {0x08A2, 13}, {0x08A3, 13}, {0x0050, 8},
{0x0006, 4}, {0x000B, 5}, {0x0029, 7}, {0x0015, 6},
{0x001C, 6}, {0x003A, 7}, {0x001E, 6}, {0x0004, 3},
{0x0014, 5}, {0x0015, 5}, {0x000B, 4}, {0x001F, 6},
{0x0030, 6}, {0x0031, 6}, {0x0019, 5}, {0x0051, 8},
{0x0034, 6}, {0x0035, 6}, {0x0036, 6}, {0x0037, 6},
{0x0076, 8}, {0x0077, 8}, {0x0070, 7}, {0x001D, 5},
{0x0071, 7}, {0x0072, 7}, {0x08A4, 13}, {0x0073, 7},
{0x00F0, 8}, {0x08A5, 13}, {0x08A6, 13}, {0x08A7, 13},
{0x0079, 7}, {0x007A, 7}, {0x08A8, 13}, {0x08A9, 13},
{0x00F1, 8}, {0x08AA, 13}, {0x08AB, 13}, {0x08AC, 13},
{0x08AD, 13}, {0x00F6, 8}, {0x08AE, 13}, {0x007C, 7},
{0x00F7, 8}, {0x08AF, 13}, {0x08B0, 13}, {0x08B1, 13},
{0x08B2, 13}, {0x00FA, 8}, {0x08B3, 13}, {0x08B4, 13},
{0x08B5, 13}, {0x08B6, 13}, {0x08B7, 13}, {0x00FB, 8},
{0x045C, 12}, {0x003F, 6}, {0x045D, 12}, {0x045E, 12},
{0x045F, 12},
}
};
const uint16_t ff_x8_ac1_lowquant_table[8][77][2]={
{//0
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x004E, 8},
{0x004F, 8}, {0x00A8, 9}, {0x0152, 10}, {0x00AA, 9},
{0x00AB, 9}, {0x00AC, 9}, {0x2A60, 15}, {0x02A7, 11},
{0x0006, 4}, {0x000B, 5}, {0x001C, 6}, {0x003A, 7},
{0x000F, 5}, {0x003B, 7}, {0x0010, 5}, {0x0005, 3},
{0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5},
{0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0070, 7},
{0x0057, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8},
{0x00E5, 8}, {0x00AD, 9}, {0x0398, 10}, {0x003A, 6},
{0x0076, 7}, {0x00E7, 8}, {0x00EE, 8}, {0x00EF, 8},
{0x0732, 11}, {0x039A, 10}, {0x0733, 11}, {0x2A61, 15},
{0x0078, 7}, {0x1531, 14}, {0x1532, 14}, {0x1533, 14},
{0x003D, 6}, {0x039B, 10}, {0x1534, 14}, {0x1535, 14},
{0x1536, 14}, {0x0079, 7}, {0x1537, 14}, {0x00F8, 8},
{0x01F2, 9}, {0x07CC, 11}, {0x03E7, 10}, {0x07CD, 11},
{0x3E80, 14}, {0x00FB, 8}, {0x03E9, 10}, {0x3E81, 14},
{0x3E82, 14}, {0x3E83, 14}, {0x3E84, 14}, {0x3E85, 14},
{0x3E86, 14}, {0x003F, 6}, {0x01F5, 9}, {0x07D1, 11},
{0x3E87, 14},
},{//1
{0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5},
{0x001E, 6}, {0x001F, 6}, {0x0040, 7}, {0x0082, 8},
{0x0083, 8}, {0x0084, 8}, {0x010A, 9}, {0x010B, 9},
{0x0430, 11}, {0x0431, 11}, {0x0432, 11}, {0x0433, 11},
{0x0005, 3}, {0x0011, 5}, {0x0024, 6}, {0x004A, 7},
{0x000C, 4}, {0x0026, 6}, {0x000D, 4}, {0x0087, 8},
{0x010D, 9}, {0x0258, 10}, {0x012D, 9}, {0x0259, 10},
{0x025C, 10}, {0x0974, 12}, {0x025E, 10}, {0x025F, 10},
{0x0270, 10}, {0x0271, 10}, {0x04BB, 11}, {0x0975, 12},
{0x0272, 10}, {0x09CC, 12}, {0x09CD, 12}, {0x4E70, 15},
{0x4E71, 15}, {0x4E72, 15}, {0x4E73, 15}, {0x273A, 14},
{0x273B, 14}, {0x273C, 14}, {0x04E8, 11}, {0x04E9, 11},
{0x009E, 8}, {0x0275, 10}, {0x09D8, 12}, {0x273D, 14},
{0x000E, 4}, {0x003C, 6}, {0x007A, 7}, {0x009F, 8},
{0x0277, 10}, {0x003E, 6}, {0x00F6, 8}, {0x04ED, 11},
{0x03DC, 10}, {0x273E, 14}, {0x07BA, 11}, {0x09D9, 12},
{0x273F, 14}, {0x3DD8, 14}, {0x3DD9, 14}, {0x3DDA, 14},
{0x3DDB, 14}, {0x3DDC, 14}, {0x3DDD, 14}, {0x3DDE, 14},
{0x3DDF, 14}, {0x003F, 6}, {0x07BC, 11}, {0x07BD, 11},
{0x03DF, 10},
},{//2
{0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6},
{0x001E, 7}, {0x003E, 8}, {0x003F, 8}, {0x0040, 8},
{0x0104, 10}, {0x0083, 9}, {0x0105, 10}, {0x0108, 10},
{0x4240, 16}, {0x010A, 10}, {0x010B, 10}, {0x4241, 16},
{0x0003, 3}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8},
{0x0004, 3}, {0x000A, 5}, {0x000A, 4}, {0x002C, 7},
{0x00B4, 9}, {0x00B5, 9}, {0x00B6, 9}, {0x00B7, 9},
{0x00B8, 9}, {0x0172, 10}, {0x0173, 10}, {0x0174, 10},
{0x0175, 10}, {0x0176, 10}, {0x0177, 10}, {0x00BC, 9},
{0x017A, 10}, {0x0213, 11}, {0x4242, 16}, {0x017B, 10},
{0x02F8, 11}, {0x017D, 10}, {0x02F9, 11}, {0x017E, 10},
{0x4243, 16}, {0x02FE, 11}, {0x2122, 15}, {0x2123, 15},
{0x0058, 7}, {0x0164, 9}, {0x2124, 15}, {0x2125, 15},
{0x0006, 3}, {0x000E, 4}, {0x002D, 6}, {0x002E, 6},
{0x00B3, 8}, {0x001E, 5}, {0x005E, 7}, {0x2126, 15},
{0x2127, 15}, {0x2128, 15}, {0x2129, 15}, {0x02FF, 11},
{0x212A, 15}, {0x0594, 11}, {0x0595, 11}, {0x0596, 11},
{0x212B, 15}, {0x212C, 15}, {0x212D, 15}, {0x212E, 15},
{0x212F, 15}, {0x001F, 5}, {0x0597, 11}, {0x00BE, 8},
{0x00BF, 8},
},{//3
{0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x0007, 4},
{0x0010, 5}, {0x0011, 5}, {0x0024, 6}, {0x0025, 6},
{0x0026, 6}, {0x0027, 6}, {0x0050, 7}, {0x0051, 7},
{0x00A4, 8}, {0x00A5, 8}, {0x00A6, 8}, {0x014E, 9},
{0x000B, 4}, {0x002A, 6}, {0x0056, 7}, {0x014F, 9},
{0x0030, 6}, {0x00AE, 8}, {0x0062, 7}, {0x0032, 6},
{0x0033, 6}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6},
{0x0063, 7}, {0x006E, 7}, {0x006F, 7}, {0x0070, 7},
{0x0071, 7}, {0x0072, 7}, {0x0073, 7}, {0x0074, 7},
{0x00AF, 8}, {0x00EA, 8}, {0x01D6, 9}, {0x075C, 11},
{0x03AF, 10}, {0x75D0, 15}, {0x75D1, 15}, {0x75D2, 15},
{0x75D3, 15}, {0x75D4, 15}, {0x0076, 7}, {0x00EE, 8},
{0x00EF, 8}, {0x0EBB, 12}, {0x01E0, 9}, {0x75D5, 15},
{0x0079, 7}, {0x01E1, 9}, {0x75D6, 15}, {0x75D7, 15},
{0x7880, 15}, {0x00F4, 8}, {0x0789, 11}, {0x003E, 6},
{0x007B, 7}, {0x00F5, 8}, {0x00FC, 8}, {0x007F, 7},
{0x01E3, 9}, {0x078A, 11}, {0x078B, 11}, {0x7881, 15},
{0x7882, 15}, {0x7883, 15}, {0x3C42, 14}, {0x3C43, 14},
{0x3C44, 14}, {0x00FD, 8}, {0x3C45, 14}, {0x3C46, 14},
{0x3C47, 14},
},{//4
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6},
{0x0017, 6}, {0x0030, 7}, {0x0031, 7}, {0x0064, 8},
{0x0065, 8}, {0x0066, 8}, {0x00CE, 9}, {0x00CF, 9},
{0x01A0, 10}, {0x01A1, 10}, {0x1A20, 14}, {0x0689, 12},
{0x0004, 3}, {0x000E, 5}, {0x001B, 6}, {0x0035, 7},
{0x000A, 4}, {0x001E, 6}, {0x0016, 5}, {0x0017, 5},
{0x001F, 6}, {0x0030, 6}, {0x0031, 6}, {0x0064, 7},
{0x0065, 7}, {0x0069, 8}, {0x0066, 7}, {0x00CE, 8},
{0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8},
{0x01A6, 9}, {0x01A3, 10}, {0x034E, 10}, {0x006A, 7},
{0x00D6, 8}, {0x01AE, 9}, {0x01AF, 9}, {0x034F, 10},
{0x0345, 11}, {0x01B0, 9}, {0x01B1, 9}, {0x0364, 10},
{0x006D, 7}, {0x00DC, 8}, {0x0D94, 12}, {0x0D95, 12},
{0x000E, 4}, {0x003C, 6}, {0x00DD, 8}, {0x00DE, 8},
{0x01B3, 9}, {0x003D, 6}, {0x00DF, 8}, {0x01F0, 9},
{0x03E2, 10}, {0x03E3, 10}, {0x06CB, 11}, {0x03E4, 10},
{0x07CA, 11}, {0x01F3, 9}, {0x01F4, 9}, {0x07CB, 11},
{0x07D4, 11}, {0x1A21, 14}, {0x1A22, 14}, {0x07D5, 11},
{0x1A23, 14}, {0x003F, 6}, {0x01F6, 9}, {0x01F7, 9},
{0x03EB, 10},
},{//5
{0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5},
{0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7},
{0x0045, 7}, {0x0046, 7}, {0x008E, 8}, {0x008F, 8},
{0x0090, 8}, {0x0122, 9}, {0x0246, 10}, {0x0124, 9},
{0x0005, 3}, {0x0013, 5}, {0x004A, 7}, {0x0093, 8},
{0x0018, 5}, {0x004B, 7}, {0x0032, 6}, {0x001A, 5},
{0x0033, 6}, {0x006C, 7}, {0x006D, 7}, {0x006E, 7},
{0x00DE, 8}, {0x00DF, 8}, {0x0070, 7}, {0x00E2, 8},
{0x00E3, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8},
{0x00E7, 8}, {0x0125, 9}, {0x01D0, 9}, {0x048E, 11},
{0x091E, 12}, {0x091F, 12}, {0x7440, 15}, {0x1D11, 13},
{0x7441, 15}, {0x7442, 15}, {0x00E9, 8}, {0x01D4, 9},
{0x00EB, 8}, {0x03A3, 10}, {0x01D5, 9}, {0x1D12, 13},
{0x001E, 5}, {0x0076, 7}, {0x01DC, 9}, {0x01DD, 9},
{0x7443, 15}, {0x007C, 7}, {0x0745, 11}, {0x00EF, 8},
{0x00FA, 8}, {0x00FB, 8}, {0x01F8, 9}, {0x00FD, 8},
{0x07E4, 11}, {0x0FCA, 12}, {0x1D13, 13}, {0x7E58, 15},
{0x7E59, 15}, {0x7E5A, 15}, {0x7E5B, 15}, {0x7E5C, 15},
{0x7E5D, 15}, {0x007F, 7}, {0x3F2F, 14}, {0x07E6, 11},
{0x07E7, 11},
},{//6
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0009, 5}, {0x0014, 6}, {0x0015, 6}, {0x002C, 7},
{0x005A, 8}, {0x005B, 8}, {0x005C, 8}, {0x00BA, 9},
{0x00BB, 9}, {0x00BC, 9}, {0x02F4, 11}, {0x05EA, 12},
{0x0003, 3}, {0x0010, 5}, {0x0022, 6}, {0x0046, 7},
{0x0009, 4}, {0x0028, 6}, {0x0015, 5}, {0x000B, 4},
{0x0018, 5}, {0x0029, 6}, {0x0032, 6}, {0x0047, 7},
{0x0066, 7}, {0x0067, 7}, {0x0068, 7}, {0x0069, 7},
{0x006A, 7}, {0x005F, 8}, {0x00D6, 8}, {0x00D7, 8},
{0x01B0, 9}, {0x00D9, 8}, {0x017B, 10}, {0x006D, 7},
{0x00DC, 8}, {0x01B1, 9}, {0x06E8, 11}, {0x01BB, 9},
{0x0375, 10}, {0x05EB, 12}, {0x01BC, 9}, {0x6E90, 15},
{0x0038, 6}, {0x0072, 7}, {0x6E91, 15}, {0x6E92, 15},
{0x001D, 5}, {0x0073, 7}, {0x01BD, 9}, {0x06F8, 11},
{0x6E93, 15}, {0x003C, 6}, {0x01BF, 9}, {0x00F4, 8},
{0x01EA, 9}, {0x037D, 10}, {0x03D6, 10}, {0x06F9, 11},
{0x6E94, 15}, {0x00F6, 8}, {0x01EE, 9}, {0x6E95, 15},
{0x6E96, 15}, {0x6E97, 15}, {0x374C, 14}, {0x374D, 14},
{0x374E, 14}, {0x001F, 5}, {0x03D7, 10}, {0x01EF, 9},
{0x374F, 14},
},{//7
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6},
{0x002E, 7}, {0x002F, 7}, {0x0060, 8}, {0x0061, 8},
{0x00C4, 9}, {0x00C5, 9}, {0x00C6, 9}, {0x018E, 10},
{0x31E0, 15}, {0x31E1, 15}, {0x31E2, 15}, {0x31E3, 15},
{0x0004, 3}, {0x000D, 5}, {0x0019, 6}, {0x0038, 7},
{0x000A, 4}, {0x001D, 6}, {0x000B, 4}, {0x0072, 8},
{0x0073, 8}, {0x00F0, 9}, {0x01E2, 10}, {0x00F2, 9},
{0x01E3, 10}, {0x00F3, 9}, {0x01E8, 10}, {0x01E9, 10},
{0x31E4, 15}, {0x01EA, 10}, {0x031F, 11}, {0x03D6, 11},
{0x31E5, 15}, {0x01EC, 10}, {0x31E6, 15}, {0x00F7, 9},
{0x03D7, 11}, {0x31E7, 15}, {0x31E8, 15}, {0x03DA, 11},
{0x03DB, 11}, {0x31E9, 15}, {0x03E0, 11}, {0x31EA, 15},
{0x003F, 7}, {0x01F1, 10}, {0x31EB, 15}, {0x31EC, 15},
{0x0006, 3}, {0x001C, 5}, {0x0074, 7}, {0x0075, 7},
{0x00F9, 9}, {0x001E, 5}, {0x0076, 7}, {0x00FA, 9},
{0x03E1, 11}, {0x31ED, 15}, {0x18F7, 14}, {0x1F60, 14},
{0x1F61, 14}, {0x01DC, 9}, {0x01DD, 9}, {0x1F62, 14},
{0x1F63, 14}, {0x1F64, 14}, {0x1F65, 14}, {0x1F66, 14},
{0x1F67, 14}, {0x001F, 5}, {0x03ED, 11}, {0x00EF, 8},
{0x01F7, 10},
}
};
const uint16_t ff_x8_ac1_highquant_table[8][77][2]={
{//0
{0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5},
{0x0008, 5}, {0x0009, 5}, {0x0014, 6}, {0x002A, 7},
{0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x002F, 7},
{0x0030, 7}, {0x005D, 8}, {0x0062, 8}, {0x00C6, 9},
{0x0007, 4}, {0x0019, 6}, {0x001A, 6}, {0x0036, 7},
{0x0010, 5}, {0x006E, 8}, {0x0022, 6}, {0x0009, 4},
{0x000A, 4}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6},
{0x002F, 6}, {0x0030, 6}, {0x0062, 7}, {0x0063, 7},
{0x0064, 7}, {0x0065, 7}, {0x0066, 7}, {0x0067, 7},
{0x0068, 7}, {0x0069, 7}, {0x006A, 7}, {0x006B, 7},
{0x006C, 7}, {0x00C7, 9}, {0x00DE, 9}, {0x00DF, 9},
{0x06D0, 11}, {0x01B5, 9}, {0x0037, 6}, {0x00DB, 8},
{0x001C, 5}, {0x0074, 7}, {0x01D4, 9}, {0x01D5, 9},
{0x0076, 7}, {0x0369, 10}, {0x3688, 14}, {0x3689, 14},
{0x368A, 14}, {0x0077, 7}, {0x03AC, 10}, {0x0078, 7},
{0x00F2, 8}, {0x01D7, 9}, {0x00F3, 8}, {0x007A, 7},
{0x368B, 14}, {0x007B, 7}, {0x007C, 7}, {0x03AD, 10},
{0x03E8, 10}, {0x368C, 14}, {0x368D, 14}, {0x03E9, 10},
{0x368E, 14}, {0x003F, 6}, {0x01F5, 9}, {0x00FB, 8},
{0x368F, 14},
},{//1
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5},
{0x0018, 6}, {0x0032, 7}, {0x0033, 7}, {0x0034, 7},
{0x006A, 8}, {0x00D6, 9}, {0x00D7, 9}, {0x00D8, 9},
{0x00D9, 9}, {0x3680, 15}, {0x01B5, 10}, {0x0369, 11},
{0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x0037, 7},
{0x000A, 4}, {0x0016, 5}, {0x000C, 4}, {0x001F, 6},
{0x005C, 7}, {0x005D, 7}, {0x00BC, 8}, {0x00BD, 8},
{0x005F, 7}, {0x00D0, 8}, {0x00DB, 9}, {0x00D1, 8},
{0x01A4, 9}, {0x01A5, 9}, {0x01A6, 9}, {0x01A7, 9},
{0x0350, 10}, {0x06A2, 11}, {0x06A3, 11}, {0x01A9, 9},
{0x01AA, 9}, {0x06AC, 11}, {0x3681, 15}, {0x0357, 10},
{0x3682, 15}, {0x3683, 15}, {0x3684, 15}, {0x3685, 15},
{0x0036, 6}, {0x00D6, 8}, {0x3686, 15}, {0x3687, 15},
{0x000E, 4}, {0x006E, 7}, {0x00D7, 8}, {0x06AD, 11},
{0x3688, 15}, {0x001E, 5}, {0x00DE, 8}, {0x06F8, 11},
{0x037D, 10}, {0x3689, 15}, {0x368A, 15}, {0x368B, 15},
{0x368C, 15}, {0x01BF, 9}, {0x368D, 15}, {0x1B47, 14},
{0x37C8, 14}, {0x37C9, 14}, {0x37CA, 14}, {0x37CB, 14},
{0x37CC, 14}, {0x001F, 5}, {0x37CD, 14}, {0x37CE, 14},
{0x37CF, 14},
},{//2
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x0027, 7},
{0x00A8, 9}, {0x00A9, 9}, {0x0055, 8}, {0x2B00, 15},
{0x00AD, 9}, {0x2B01, 15}, {0x2B02, 15}, {0x2B03, 15},
{0x0003, 3}, {0x000B, 5}, {0x0040, 7}, {0x0041, 7},
{0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x000A, 4},
{0x000B, 4}, {0x0018, 5}, {0x0032, 6}, {0x0033, 6},
{0x0034, 6}, {0x0035, 6}, {0x006C, 7}, {0x0057, 8},
{0x006D, 7}, {0x00DC, 8}, {0x0159, 10}, {0x00DD, 8},
{0x01BC, 9}, {0x037A, 10}, {0x037B, 10}, {0x0038, 6},
{0x0072, 7}, {0x01BE, 9}, {0x01BF, 9}, {0x00E6, 8},
{0x039C, 10}, {0x01CF, 9}, {0x2B04, 15}, {0x2B05, 15},
{0x0074, 7}, {0x01D4, 9}, {0x2B06, 15}, {0x2B07, 15},
{0x001E, 5}, {0x00EB, 8}, {0x1584, 14}, {0x1585, 14},
{0x1586, 14}, {0x003B, 6}, {0x01D5, 9}, {0x01F0, 9},
{0x039D, 10}, {0x03E2, 10}, {0x1587, 14}, {0x1588, 14},
{0x1589, 14}, {0x00F9, 8}, {0x158A, 14}, {0x158B, 14},
{0x03E3, 10}, {0x158C, 14}, {0x158D, 14}, {0x01F4, 9},
{0x158E, 14}, {0x003F, 6}, {0x00FB, 8}, {0x01F5, 9},
{0x158F, 14},
},{//3
{0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5},
{0x0010, 6}, {0x0011, 6}, {0x0024, 7}, {0x0025, 7},
{0x0013, 6}, {0x0014, 6}, {0x002A, 7}, {0x002B, 7},
{0x00B0, 9}, {0x00B1, 9}, {0x002D, 7}, {0x0059, 8},
{0x000C, 5}, {0x0017, 6}, {0x00D0, 9}, {0x0035, 7},
{0x001B, 6}, {0x0038, 7}, {0x0039, 7}, {0x0004, 3},
{0x0005, 3}, {0x000F, 5}, {0x0018, 5}, {0x001D, 6},
{0x0032, 6}, {0x0033, 6}, {0x0068, 7}, {0x0069, 7},
{0x0069, 8}, {0x00D4, 8}, {0x00D5, 8}, {0x00D6, 8},
{0x006C, 7}, {0x0037, 6}, {0x006D, 7}, {0x0070, 7},
{0x0039, 6}, {0x00D7, 8}, {0x00D1, 9}, {0x3880, 14},
{0x3881, 14}, {0x3882, 14}, {0x0074, 7}, {0x01C5, 9},
{0x0075, 7}, {0x00E3, 8}, {0x3883, 14}, {0x3884, 14},
{0x00EC, 8}, {0x3885, 14}, {0x1C43, 13}, {0x1C44, 13},
{0x1C45, 13}, {0x00ED, 8}, {0x1C46, 13}, {0x003C, 6},
{0x0077, 7}, {0x01E8, 9}, {0x003E, 6}, {0x007B, 7},
{0x1C47, 13}, {0x007E, 7}, {0x007F, 7}, {0x1C48, 13},
{0x1C49, 13}, {0x1C4A, 13}, {0x1C4B, 13}, {0x1C4C, 13},
{0x1C4D, 13}, {0x00F5, 8}, {0x1C4E, 13}, {0x01E9, 9},
{0x1C4F, 13},
},{//4
{0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5},
{0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x0035, 7},
{0x0036, 7}, {0x006E, 8}, {0x00DE, 9}, {0x00DF, 9},
{0x01C0, 10}, {0x01C1, 10}, {0x01C2, 10}, {0x3860, 15},
{0x0004, 3}, {0x000F, 5}, {0x001D, 6}, {0x0039, 7},
{0x000A, 4}, {0x002C, 6}, {0x002D, 6}, {0x000C, 4},
{0x0017, 5}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6},
{0x006E, 7}, {0x006F, 7}, {0x0070, 7}, {0x0071, 7},
{0x0071, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8},
{0x00E7, 8}, {0x00E8, 8}, {0x03A4, 10}, {0x0075, 7},
{0x00EC, 8}, {0x01D3, 9}, {0x01DA, 9}, {0x03A5, 10},
{0x03B6, 10}, {0x070D, 12}, {0x03B7, 10}, {0x070E, 12},
{0x003C, 6}, {0x00EE, 8}, {0x3861, 15}, {0x3862, 15},
{0x003D, 6}, {0x01DE, 9}, {0x3863, 15}, {0x3864, 15},
{0x3865, 15}, {0x007C, 7}, {0x070F, 12}, {0x03BE, 10},
{0x03BF, 10}, {0x3866, 15}, {0x0FA0, 12}, {0x07D1, 11},
{0x3867, 15}, {0x00FB, 8}, {0x01F5, 9}, {0x7D08, 15},
{0x0FA4, 12}, {0x7D09, 15}, {0x7D0A, 15}, {0x7D0B, 15},
{0x3E86, 14}, {0x003F, 6}, {0x0FA5, 12}, {0x07D3, 11},
{0x3E87, 14},
},{//5
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0009, 5}, {0x0014, 6}, {0x002A, 7}, {0x0056, 8},
{0x02B8, 11}, {0x00AF, 9}, {0x02B9, 11}, {0x015D, 10},
{0x02C0, 11}, {0x2C10, 15}, {0x2C11, 15}, {0x2C12, 15},
{0x0006, 4}, {0x000E, 5}, {0x0017, 6}, {0x002D, 7},
{0x000F, 5}, {0x0040, 7}, {0x0021, 6}, {0x0005, 3},
{0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5},
{0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0041, 7},
{0x0059, 8}, {0x00E0, 8}, {0x00E1, 8}, {0x0071, 7},
{0x00E4, 8}, {0x00B1, 9}, {0x02C2, 11}, {0x001D, 5},
{0x0073, 7}, {0x00E5, 8}, {0x00F0, 8}, {0x0079, 7},
{0x03C4, 10}, {0x01E3, 9}, {0x01E8, 9}, {0x2C13, 15},
{0x007B, 7}, {0x2C14, 15}, {0x2C15, 15}, {0x2C16, 15},
{0x007C, 7}, {0x02C3, 11}, {0x2C17, 15}, {0x160C, 14},
{0x160D, 14}, {0x007D, 7}, {0x160E, 14}, {0x01E9, 9},
{0x03C5, 10}, {0x03D4, 10}, {0x01EB, 9}, {0x160F, 14},
{0x3D50, 14}, {0x00FC, 8}, {0x07AB, 11}, {0x3D51, 14},
{0x3D52, 14}, {0x3D53, 14}, {0x3D54, 14}, {0x01FA, 9},
{0x3D55, 14}, {0x007F, 7}, {0x01FB, 9}, {0x3D56, 14},
{0x3D57, 14},
},{//6
{0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5},
{0x0009, 5}, {0x000A, 5}, {0x000B, 5}, {0x0018, 6},
{0x0032, 7}, {0x000D, 5}, {0x0033, 7}, {0x0E00, 13},
{0x0039, 7}, {0x0E01, 13}, {0x003A, 7}, {0x0E02, 13},
{0x0008, 4}, {0x001E, 6}, {0x003B, 7}, {0x003E, 7},
{0x0012, 5}, {0x003F, 7}, {0x0013, 5}, {0x0028, 6},
{0x0029, 6}, {0x0054, 7}, {0x002B, 6}, {0x0055, 7},
{0x0058, 7}, {0x0E03, 13}, {0x0059, 7}, {0x005A, 7},
{0x0E04, 13}, {0x0E05, 13}, {0x0703, 12}, {0x005B, 7},
{0x005C, 7}, {0x0704, 12}, {0x0705, 12}, {0x005D, 7},
{0x0706, 12}, {0x0707, 12}, {0x0708, 12}, {0x0709, 12},
{0x070A, 12}, {0x070B, 12}, {0x0018, 5}, {0x002F, 6},
{0x000D, 4}, {0x0019, 5}, {0x070C, 12}, {0x0070, 7},
{0x001D, 5}, {0x070D, 12}, {0x070E, 12}, {0x070F, 12},
{0x0710, 12}, {0x0039, 6}, {0x0711, 12}, {0x003C, 6},
{0x0712, 12}, {0x0713, 12}, {0x0714, 12}, {0x0715, 12},
{0x0716, 12}, {0x003D, 6}, {0x0717, 12}, {0x0718, 12},
{0x0719, 12}, {0x071A, 12}, {0x071B, 12}, {0x071C, 12},
{0x071D, 12}, {0x001F, 5}, {0x071E, 12}, {0x0071, 7},
{0x071F, 12},
},{//7
{0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6},
{0x000F, 6}, {0x0040, 8}, {0x0041, 8}, {0x0042, 8},
{0x0218, 11}, {0x2190, 15}, {0x2191, 15}, {0x2192, 15},
{0x2193, 15}, {0x2194, 15}, {0x2195, 15}, {0x2196, 15},
{0x0005, 4}, {0x0011, 6}, {0x0024, 7}, {0x0087, 9},
{0x000C, 5}, {0x004A, 8}, {0x004B, 8}, {0x0002, 2},
{0x0006, 3}, {0x000D, 5}, {0x000E, 5}, {0x000F, 5},
{0x0013, 6}, {0x0038, 6}, {0x00E4, 8}, {0x00E5, 8},
{0x01CC, 9}, {0x00E7, 8}, {0x0074, 7}, {0x00EA, 8},
{0x01CD, 9}, {0x021A, 11}, {0x2197, 15}, {0x001E, 5},
{0x0076, 7}, {0x00EB, 8}, {0x01DC, 9}, {0x00EF, 8},
{0x01DD, 9}, {0x01F0, 9}, {0x2198, 15}, {0x2199, 15},
{0x00F9, 8}, {0x03E2, 10}, {0x219A, 15}, {0x219B, 15},
{0x00FA, 8}, {0x219C, 15}, {0x219D, 15}, {0x219E, 15},
{0x219F, 15}, {0x01F6, 9}, {0x21B0, 15}, {0x00FC, 8},
{0x01F7, 9}, {0x21B1, 15}, {0x21B2, 15}, {0x21B3, 15},
{0x21B4, 15}, {0x01FA, 9}, {0x21B5, 15}, {0x21B6, 15},
{0x21B7, 15}, {0x21B8, 15}, {0x21B9, 15}, {0x03E3, 10},
{0x10DD, 14}, {0x007F, 7}, {0x01FB, 9}, {0x10DE, 14},
{0x10DF, 14},
}
};
#define MAX_AC_VLC_BITS 16

View File

@ -1100,8 +1100,8 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
if (v->multires && v->s.pict_type != B_TYPE) v->respic = get_bits(gb, 2);
if(v->res_x8 && (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)){
if(get_bits1(gb))return -1;
}
v->x8_type = get_bits1(gb);
}else v->x8_type = 0;
//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
// (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
@ -1234,6 +1234,8 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
break;
}
if(!v->x8_type)
{
/* AC Syntax */
v->c_ac_table_index = decode012(gb);
if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
@ -1242,6 +1244,7 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
}
/* DC Syntax */
v->s.dc_table_index = get_bits1(gb);
}
if(v->s.pict_type == BI_TYPE) {
v->s.pict_type = B_TYPE;
@ -3755,6 +3758,9 @@ static void vc1_decode_blocks(VC1Context *v)
{
v->s.esc3_level_length = 0;
if(v->x8_type){
ff_intrax8_decode_picture(&v->x8, 2*v->pq+v->halfpq, v->pq*(!v->pquantizer) );
}else
switch(v->s.pict_type) {
case I_TYPE:
@ -3835,6 +3841,10 @@ static int vc1_decode_init(AVCodecContext *avctx)
avctx->flags |= CODEC_FLAG_EMU_EDGE;
v->s.flags |= CODEC_FLAG_EMU_EDGE;
if(avctx->idct_algo==FF_IDCT_AUTO){
avctx->idct_algo=FF_IDCT_WMV2;
}
if(ff_h263_decode_init(avctx) < 0)
return -1;
if (vc1_init_common(v) < 0) return -1;
@ -3935,6 +3945,7 @@ static int vc1_decode_init(AVCodecContext *avctx)
// return -1;
}
ff_intrax8_common_init(&v->x8,s);
return 0;
}

View File

@ -25,6 +25,7 @@
#include "avcodec.h"
#include "mpegvideo.h"
#include "intrax8.h"
/** Markers used in VC-1 AP frame data */
//@{
@ -156,6 +157,7 @@ enum COTypes {
*/
typedef struct VC1Context{
MpegEncContext s;
IntraX8Context x8;
int bits;
@ -302,6 +304,7 @@ typedef struct VC1Context{
int p_frame_skipped;
int bi_type;
int x8_type;
} VC1Context;
#endif /* FFMPEG_VC1_H */

View File

@ -29,6 +29,7 @@
#include "msmpeg4.h"
#include "msmpeg4data.h"
#include "simple_idct.h"
#include "intrax8.h"
#define SKIP_TYPE_NONE 0
#define SKIP_TYPE_MPEG 1
@ -38,6 +39,7 @@
typedef struct Wmv2Context{
MpegEncContext s;
IntraX8Context x8;
int j_type_bit;
int j_type;
int abt_flag;
@ -472,12 +474,9 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s)
s->picture_number++; //FIXME ?
// if(w->j_type)
// return wmv2_decode_j_picture(w); //FIXME
if(w->j_type){
av_log(s->avctx, AV_LOG_ERROR, "J-type picture is not supported\n");
return -1;
ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 );
return 1;
}
return 0;
@ -830,11 +829,17 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
static int wmv2_decode_init(AVCodecContext *avctx){
Wmv2Context * const w= avctx->priv_data;
if(avctx->idct_algo==FF_IDCT_AUTO){
avctx->idct_algo=FF_IDCT_WMV2;
}
if(ff_h263_decode_init(avctx) < 0)
return -1;
wmv2_common_init(w);
ff_intrax8_common_init(&w->x8,&w->s);
return 0;
}