/******************************************************************** * * * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007 * * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * * * ******************************************************************** function: last mod: $Id: fragment.c 15469 2008-10-30 12:49:42Z tterribe $ ********************************************************************/ #include "../internal.h" void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst, int _dst_ystride,const ogg_int16_t *_residue){ _state->opt_vtable.frag_recon_intra(_dst,_dst_ystride,_residue); } void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride, const ogg_int16_t *_residue){ int i; for(i=0;i<8;i++){ int j; for(j=0;j<8;j++){ int res; res=*_residue++; _dst[j]=OC_CLAMP255(res+128); } _dst+=_dst_ystride; } } void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst, int _dst_ystride,const unsigned char *_src,int _src_ystride, const ogg_int16_t *_residue){ _state->opt_vtable.frag_recon_inter(_dst,_dst_ystride,_src,_src_ystride, _residue); } void oc_frag_recon_inter_c(unsigned char *_dst,int _dst_ystride, const unsigned char *_src,int _src_ystride,const ogg_int16_t *_residue){ int i; for(i=0;i<8;i++){ int j; for(j=0;j<8;j++){ int res; res=*_residue++; _dst[j]=OC_CLAMP255(res+_src[j]); } _dst+=_dst_ystride; _src+=_src_ystride; } } void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst, int _dst_ystride,const unsigned char *_src1,int _src1_ystride, const unsigned char *_src2,int _src2_ystride,const ogg_int16_t *_residue){ _state->opt_vtable.frag_recon_inter2(_dst,_dst_ystride,_src1,_src1_ystride, _src2,_src2_ystride,_residue); } void oc_frag_recon_inter2_c(unsigned char *_dst,int _dst_ystride, const unsigned char *_src1,int _src1_ystride,const unsigned char *_src2, int _src2_ystride,const ogg_int16_t *_residue){ int i; for(i=0;i<8;i++){ int j; for(j=0;j<8;j++){ int res; res=*_residue++; _dst[j]=OC_CLAMP255(res+((int)_src1[j]+_src2[j]>>1)); } _dst+=_dst_ystride; _src1+=_src1_ystride; _src2+=_src2_ystride; } } /*Computes the predicted DC value for the given fragment. This requires that the fully decoded DC values be available for the left, upper-left, upper, and upper-right fragments (if they exist). _frag: The fragment to predict the DC value for. _fplane: The fragment plane the fragment belongs to. _x: The x-coordinate of the fragment. _y: The y-coordinate of the fragment. _pred_last: The last fully-decoded DC value for each predictor frame (OC_FRAME_GOLD, OC_FRAME_PREV and OC_FRAME_SELF). This should be initialized to 0's for the first fragment in each color plane. Return: The predicted DC value for this fragment.*/ int oc_frag_pred_dc(const oc_fragment *_frag, const oc_fragment_plane *_fplane,int _x,int _y,int _pred_last[3]){ static const int PRED_SCALE[16][4]={ /*0*/ {0,0,0,0}, /*OC_PL*/ {1,0,0,0}, /*OC_PUL*/ {1,0,0,0}, /*OC_PL|OC_PUL*/ {1,0,0,0}, /*OC_PU*/ {1,0,0,0}, /*OC_PL|OC_PU*/ {1,1,0,0}, /*OC_PUL|OC_PU*/ {0,1,0,0}, /*OC_PL|OC_PUL|PC_PU*/ {29,-26,29,0}, /*OC_PUR*/ {1,0,0,0}, /*OC_PL|OC_PUR*/ {75,53,0,0}, /*OC_PUL|OC_PUR*/ {1,1,0,0}, /*OC_PL|OC_PUL|OC_PUR*/ {75,0,53,0}, /*OC_PU|OC_PUR*/ {1,0,0,0}, /*OC_PL|OC_PU|OC_PUR*/ {75,0,53,0}, /*OC_PUL|OC_PU|OC_PUR*/ {3,10,3,0}, /*OC_PL|OC_PUL|OC_PU|OC_PUR*/ {29,-26,29,0} }; static const int PRED_SHIFT[16]={0,0,0,0,0,1,0,5,0,7,1,7,0,7,4,5}; static const int PRED_RMASK[16]={0,0,0,0,0,1,0,31,0,127,1,127,0,127,15,31}; static const int BC_MASK[8]={ /*No boundary condition.*/ OC_PL|OC_PUL|OC_PU|OC_PUR, /*Left column.*/ OC_PU|OC_PUR, /*Top row.*/ OC_PL, /*Top row, left column.*/ 0, /*Right column.*/ OC_PL|OC_PUL|OC_PU, /*Right and left column.*/ OC_PU, /*Top row, right column.*/ OC_PL, /*Top row, right and left column.*/ 0 }; /*Predictor fragments, left, up-left, up, up-right.*/ const oc_fragment *predfr[4]; /*The frame used for prediction for this fragment.*/ int pred_frame; /*The boundary condition flags.*/ int bc; /*DC predictor values: left, up-left, up, up-right, missing values skipped.*/ int p[4]; /*Predictor count.*/ int np; /*Which predictor constants to use.*/ int pflags; /*The predicted DC value.*/ int ret; int i; pred_frame=OC_FRAME_FOR_MODE[_frag->mbmode]; bc=(_x==0)+((_y==0)<<1)+((_x+1==_fplane->nhfrags)<<2); predfr[0]=_frag-1; predfr[1]=_frag-_fplane->nhfrags-1; predfr[2]=predfr[1]+1; predfr[3]=predfr[2]+1; np=0; pflags=0; for(i=0;i<4;i++){ int pflag; pflag=1<coded&& OC_FRAME_FOR_MODE[predfr[i]->mbmode]==pred_frame){ p[np++]=predfr[i]->dc; pflags|=pflag; } } if(pflags==0)return _pred_last[pred_frame]; else{ ret=PRED_SCALE[pflags][0]*p[0]; /*LOOP VECTORIZES.*/ for(i=1;i128)ret=p[2]; else if(abs(ret-p[0])>128)ret=p[0]; else if(abs(ret-p[1])>128)ret=p[1]; } return ret; }