void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo){
const th_quant_ranges *qranges;
const th_quant_base *base_mats[2*3*64];
int indices[2][3][64];
int nbase_mats;
int nbits;
int ci;
int qi;
int qri;
int qti;
int pli;
int qtj;
int plj;
int bmi;
int i;
/*323 bits for the defaults.*/
/*Unlike the scale tables, we can't assume the maximum value will be in
index 0, so search for it here.*/
i=_qinfo->loop_filter_limits[0];
for(qi=1;qi<64;qi++)i=OC_MAXI(i,_qinfo->loop_filter_limits[qi]);
nbits=oc_ilog(i);
oggpackB_write(_opb,nbits,3);
for(qi=0;qi<64;qi++){
oggpackB_write(_opb,_qinfo->loop_filter_limits[qi],nbits);
}
/*452 bits for the defaults, 580 for VP3.*/
nbits=OC_MAXI(oc_ilog(_qinfo->ac_scale[0]),1);
oggpackB_write(_opb,nbits-1,4);
for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->ac_scale[qi],nbits);
/*260 bits for the defaults, 516 for VP3.*/
nbits=OC_MAXI(oc_ilog(_qinfo->dc_scale[0]),1);
oggpackB_write(_opb,nbits-1,4);
for(qi=0;qi<64;qi++)oggpackB_write(_opb,_qinfo->dc_scale[qi],nbits);
/*Consolidate any duplicate base matrices.*/
nbase_mats=0;
for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
qranges=_qinfo->qi_ranges[qti]+pli;
for(qri=0;qri<=qranges->nranges;qri++){
for(bmi=0;;bmi++){
if(bmi>=nbase_mats){
base_mats[bmi]=qranges->base_matrices+qri;
indices[qti][pli][qri]=nbase_mats++;
break;
}
else if(memcmp(base_mats[bmi][0],qranges->base_matrices[qri],
sizeof(base_mats[bmi][0]))==0){
indices[qti][pli][qri]=bmi;
break;
}
}
}
}
/*Write out the list of unique base matrices.
6153 bits for our default matrices, 1545 bits for VP3 matrices.*/
oggpackB_write(_opb,nbase_mats-1,9);
for(bmi=0;bmi<nbase_mats;bmi++){
for(ci=0;ci<64;ci++)oggpackB_write(_opb,base_mats[bmi][0][ci],8);
}
/*Now store quant ranges and their associated indices into the base matrix
list.
236 bits for our default matrices, 46 bits for VP3 matrices.*/
nbits=oc_ilog(nbase_mats-1);
for(i=0;i<6;i++){
qti=i/3;
pli=i%3;
qranges=_qinfo->qi_ranges[qti]+pli;
if(i>0){
if(qti>0){
if(qranges->nranges==_qinfo->qi_ranges[qti-1][pli].nranges&&
memcmp(qranges->sizes,_qinfo->qi_ranges[qti-1][pli].sizes,
qranges->nranges*sizeof(qranges->sizes[0]))==0&&
memcmp(indices[qti][pli],indices[qti-1][pli],
(qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
oggpackB_write(_opb,1,2);
continue;
}
}
qtj=(i-1)/3;
plj=(i-1)%3;
if(qranges->nranges==_qinfo->qi_ranges[qtj][plj].nranges&&
memcmp(qranges->sizes,_qinfo->qi_ranges[qtj][plj].sizes,
qranges->nranges*sizeof(qranges->sizes[0]))==0&&
memcmp(indices[qti][pli],indices[qtj][plj],
(qranges->nranges+1)*sizeof(indices[qti][pli][0]))==0){
oggpackB_write(_opb,0,1+(qti>0));
continue;
}
oggpackB_write(_opb,1,1);
}
oggpackB_write(_opb,indices[qti][pli][0],nbits);
for(qi=qri=0;qi<63;qri++){
oggpackB_write(_opb,qranges->sizes[qri]-1,oc_ilog(62-qi));
qi+=qranges->sizes[qri];
oggpackB_write(_opb,indices[qti][pli][qri+1],nbits);
}
}
}