Exemplo n.º 1
0
/*Unpacks a sub-tree from the given buffer.
  _opb:      The buffer to unpack from.
  _binodes:  The nodes to store the sub-tree in.
  _nbinodes: The number of nodes available for the sub-tree.
  Return: 0 on success, or a negative value on error.*/
static int oc_huff_tree_unpack(oc_pack_buf *_opb,
 oc_huff_node *_binodes,int _nbinodes){
  oc_huff_node *binode;
  long          bits;
  int           nused;
  if(_nbinodes<1)return TH_EBADHEADER;
  binode=_binodes;
  nused=0;
  bits=oc_pack_read1(_opb);
  if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
  /*Read an internal node:*/
  if(!bits){
    int ret;
    nused++;
    binode->nbits=1;
    binode->depth=1;
    binode->nodes[0]=_binodes+nused;
    ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
    if(ret>=0){
      nused+=ret;
      binode->nodes[1]=_binodes+nused;
      ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
    }
    if(ret<0)return ret;
    nused+=ret;
  }
  /*Read a leaf node:*/
  else{
    int ntokens;
    int token;
    int i;
    bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
    if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
    /*Find out how many internal tokens we translate this external token into.*/
    ntokens=OC_DCT_TOKEN_MAP_ENTRIES[bits];
    if(_nbinodes<2*ntokens-1)return TH_EBADHEADER;
    /*Fill in a complete binary tree pointing to the internal tokens.*/
    for(i=1;i<ntokens;i<<=1){
      int j;
      binode=_binodes+nused;
      nused+=i;
      for(j=0;j<i;j++){
        binode[j].nbits=1;
        binode[j].depth=1;
        binode[j].nodes[0]=_binodes+nused+2*j;
        binode[j].nodes[1]=_binodes+nused+2*j+1;
      }
    }
    /*And now the leaf nodes with those tokens.*/
    token=OC_DCT_TOKEN_MAP[bits];
    for(i=0;i<ntokens;i++){
      binode=_binodes+nused++;
      binode->nbits=0;
      binode->depth=1;
      binode->token=token+i;
    }
  }
  return nused;
}
Exemplo n.º 2
0
/*Unpacks a Huffman codebook.
  _opb:    The buffer to unpack from.
  _tokens: Stores a list of internal tokens, in the order they were found in
			the codebook, and the lengths of their corresponding codewords.
		   This is enough to completely define the codebook, while minimizing
			stack usage and avoiding temporary allocations (for platforms
			where free() is a no-op).
  Return: The number of internal tokens in the codebook, or a negative value
   on error.*/
int oc_huff_tree_unpack(oc_pack_buf* _opb, unsigned char _tokens[256][2])
{
	ogg_uint32_t code;
	int len;
	int ntokens;
	int nleaves;
	code = 0;
	len = ntokens = nleaves = 0;
	for (;;)
	{
		long bits;
		bits = oc_pack_read1(_opb);
		/*Only process nodes so long as there's more bits in the buffer.*/
		if (oc_pack_bytes_left(_opb) < 0)
			return TH_EBADHEADER;
		/*Read an internal node:*/
		if (!bits)
		{
			len++;
			/*Don't allow codewords longer than 32 bits.*/
			if (len > 32)
				return TH_EBADHEADER;
		}
		/*Read a leaf node:*/
		else
		{
			ogg_uint32_t code_bit;
			int neb;
			int nentries;
			int token;
			/*Don't allow more than 32 spec-tokens per codebook.*/
			if (++nleaves > 32)
				return TH_EBADHEADER;
			bits = oc_pack_read(_opb, OC_NDCT_TOKEN_BITS);
			neb = OC_DCT_TOKEN_MAP_LOG_NENTRIES[bits];
			token = OC_DCT_TOKEN_MAP[bits];
			nentries = 1 << neb;
			while (nentries-- > 0)
			{
				_tokens[ntokens][0] = (unsigned char)token++;
				_tokens[ntokens][1] = (unsigned char)(len + neb);
				ntokens++;
			}
			code_bit = 0x80000000U >> len - 1;
			while (len > 0 && (code & code_bit))
			{
				code ^= code_bit;
				code_bit <<= 1;
				len--;
			}
			if (len <= 0)
				break;
			code |= code_bit;
		}
	}
	return ntokens;
}
Exemplo n.º 3
0
static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){
  long len;
  int  i;
  /*Read the vendor string.*/
  len=oc_unpack_length(_opb);
  if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER;
  _tc->vendor=(char *)_ogg_malloc((size_t)len+1);
  if(_tc->vendor==NULL)return TH_EFAULT;
  oc_unpack_octets(_opb,_tc->vendor,len);
  _tc->vendor[len]='\0';
  /*Read the user comments.*/
  _tc->comments=(int)oc_unpack_length(_opb);
  len=_tc->comments;
  if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){
	_tc->comments=0;
	return TH_EBADHEADER;
  }
  _tc->comment_lengths=(int *)_ogg_malloc(
   _tc->comments*sizeof(_tc->comment_lengths[0]));
  _tc->user_comments=(char **)_ogg_malloc(
   _tc->comments*sizeof(_tc->user_comments[0]));
  for(i=0;i<_tc->comments;i++){
	len=oc_unpack_length(_opb);
	if(len<0||len>oc_pack_bytes_left(_opb)){
	  _tc->comments=i;
	  return TH_EBADHEADER;
	}
	_tc->comment_lengths[i]=len;
	_tc->user_comments[i]=(char *)_ogg_malloc((size_t)len+1);
	if(_tc->user_comments[i]==NULL){
	  _tc->comments=i;
	  return TH_EFAULT;
	}
	oc_unpack_octets(_opb,_tc->user_comments[i],len);
	_tc->user_comments[i][len]='\0';
  }
  return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0;
}
Exemplo n.º 4
0
/*This is used to copy the configuration of an existing setup header for use by
   the encoder.
  The decoder uses a completely different data structure for the Huffman
   codebooks.*/
int oc_huff_codes_unpack(oc_pack_buf *_opb,
 th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){
  int i;
  for(i=0;i<TH_NHUFFMAN_TABLES;i++){
    ogg_uint32_t code;
    int          len;
    int          nleaves;
    code=0;
    len=nleaves=0;
    memset(_codes[i],0,TH_NDCT_TOKENS*sizeof(*_codes[i]));
    for(;;){
      long bits;
      bits=oc_pack_read1(_opb);
      /*Only process nodes so long as there's more bits in the buffer.*/
      if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
      /*Read an internal node:*/
      if(!bits){
        len++;
        /*Don't allow codewords longer than 32 bits.*/
        if(len>32)return TH_EBADHEADER;
      }
      /*Read a leaf node:*/
      else{
        ogg_uint32_t code_bit;
        /*Don't allow more than 32 tokens per codebook.*/
        if(++nleaves>32)return TH_EBADHEADER;
        bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
        /*The current encoder does not support codebooks that do not contain
           all of the tokens.*/
        if(_codes[i][bits].nbits>0)return TH_EINVAL;
        _codes[i][bits].pattern=code>>32-len;
        _codes[i][bits].nbits=len;
        code_bit=0x80000000U>>len-1;
        while(len>0&&(code&code_bit)){
          code^=code_bit;
          code_bit<<=1;
          len--;
        }
        if(len<=0)break;
        code|=code_bit;
      }
    }
    /*The current encoder does not support codebooks that do not contain all of
       the tokens.*/
    if(nleaves<32)return TH_EINVAL;
  }
  return 0;
}
Exemplo n.º 5
0
static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
  long val;
  /*Check the codec bitstream version.*/
  val=oc_pack_read(_opb,8);
  _info->version_major=(unsigned char)val;
  val=oc_pack_read(_opb,8);
  _info->version_minor=(unsigned char)val;
  val=oc_pack_read(_opb,8);
  _info->version_subminor=(unsigned char)val;
  /*verify we can parse this bitstream version.
	 We accept earlier minors and all subminors, by spec*/
  if(_info->version_major>TH_VERSION_MAJOR||
   _info->version_major==TH_VERSION_MAJOR&&
   _info->version_minor>TH_VERSION_MINOR){
	return TH_EVERSION;
  }
  /*Read the encoded frame description.*/
  val=oc_pack_read(_opb,16);
  _info->frame_width=(ogg_uint32_t)val<<4;
  val=oc_pack_read(_opb,16);
  _info->frame_height=(ogg_uint32_t)val<<4;
  val=oc_pack_read(_opb,24);
  _info->pic_width=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,24);
  _info->pic_height=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,8);
  _info->pic_x=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,8);
  _info->pic_y=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,32);
  _info->fps_numerator=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,32);
  _info->fps_denominator=(ogg_uint32_t)val;
  if(_info->frame_width==0||_info->frame_height==0||
   _info->pic_width+_info->pic_x>_info->frame_width||
   _info->pic_height+_info->pic_y>_info->frame_height||
   _info->fps_numerator==0||_info->fps_denominator==0){
	return TH_EBADHEADER;
  }
  /*Note: The sense of pic_y is inverted in what we pass back to the
	 application compared to how it is stored in the bitstream.
	This is because the bitstream uses a right-handed coordinate system, while
	 applications expect a left-handed one.*/
  _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
  val=oc_pack_read(_opb,24);
  _info->aspect_numerator=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,24);
  _info->aspect_denominator=(ogg_uint32_t)val;
  val=oc_pack_read(_opb,8);
  _info->colorspace=(th_colorspace)val;
  val=oc_pack_read(_opb,24);
  _info->target_bitrate=(int)val;
  val=oc_pack_read(_opb,6);
  _info->quality=(int)val;
  val=oc_pack_read(_opb,5);
  _info->keyframe_granule_shift=(int)val;
  val=oc_pack_read(_opb,2);
  _info->pixel_fmt=(th_pixel_fmt)val;
  if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
  val=oc_pack_read(_opb,3);
  if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
  return 0;
}