📄 dct_encode.c
字号:
/********************************************************************
* *
* 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-2003 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
********************************************************************/
#include <stdlib.h>
#include "codec_internal.h"
#include "dsp.h"
static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
static unsigned char TokenizeDctValue (ogg_int16_t DataValue,
ogg_uint32_t * TokenListPtr ){
unsigned char tokens_added = 0;
ogg_uint32_t AbsDataVal = abs( (ogg_int32_t)DataValue );
/* Values are tokenised as category value and a number of additional
bits that define the position within the category. */
if ( DataValue == 0 ) return 0;
if ( AbsDataVal == 1 ){
if ( DataValue == 1 )
TokenListPtr[0] = ONE_TOKEN;
else
TokenListPtr[0] = MINUS_ONE_TOKEN;
tokens_added = 1;
} else if ( AbsDataVal == 2 ) {
if ( DataValue == 2 )
TokenListPtr[0] = TWO_TOKEN;
else
TokenListPtr[0] = MINUS_TWO_TOKEN;
tokens_added = 1;
} else if ( AbsDataVal <= MAX_SINGLE_TOKEN_VALUE ) {
TokenListPtr[0] = LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN);
if ( DataValue > 0 )
TokenListPtr[1] = 0;
else
TokenListPtr[1] = 1;
tokens_added = 2;
} else if ( AbsDataVal <= 8 ) {
/* Bit 1 determines sign, Bit 0 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY3;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT3_MIN);
else
TokenListPtr[1] = (0x02) + (AbsDataVal - DCT_VAL_CAT3_MIN);
tokens_added = 2;
} else if ( AbsDataVal <= 12 ) {
/* Bit 2 determines sign, Bit 0-2 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY4;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT4_MIN);
else
TokenListPtr[1] = (0x04) + (AbsDataVal - DCT_VAL_CAT4_MIN);
tokens_added = 2;
} else if ( AbsDataVal <= 20 ) {
/* Bit 3 determines sign, Bit 0-2 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY5;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT5_MIN);
else
TokenListPtr[1] = (0x08) + (AbsDataVal - DCT_VAL_CAT5_MIN);
tokens_added = 2;
} else if ( AbsDataVal <= 36 ) {
/* Bit 4 determines sign, Bit 0-3 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY6;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT6_MIN);
else
TokenListPtr[1] = (0x010) + (AbsDataVal - DCT_VAL_CAT6_MIN);
tokens_added = 2;
} else if ( AbsDataVal <= 68 ) {
/* Bit 5 determines sign, Bit 0-4 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY7;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT7_MIN);
else
TokenListPtr[1] = (0x20) + (AbsDataVal - DCT_VAL_CAT7_MIN);
tokens_added = 2;
} else if ( AbsDataVal <= 511 ) {
/* Bit 9 determines sign, Bit 0-8 the value */
TokenListPtr[0] = DCT_VAL_CATEGORY8;
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - DCT_VAL_CAT8_MIN);
else
TokenListPtr[1] = (0x200) + (AbsDataVal - DCT_VAL_CAT8_MIN);
tokens_added = 2;
} else {
TokenListPtr[0] = DCT_VAL_CATEGORY8;
if ( DataValue > 0 )
TokenListPtr[1] = (511 - DCT_VAL_CAT8_MIN);
else
TokenListPtr[1] = (0x200) + (511 - DCT_VAL_CAT8_MIN);
tokens_added = 2;
}
/* Return the total number of tokens added */
return tokens_added;
}
static unsigned char TokenizeDctRunValue (unsigned char RunLength,
ogg_int16_t DataValue,
ogg_uint32_t * TokenListPtr ){
unsigned char tokens_added = 0;
ogg_uint32_t AbsDataVal = abs( (ogg_int32_t)DataValue );
/* Values are tokenised as category value and a number of additional
bits that define the category. */
if ( DataValue == 0 ) return 0;
if ( AbsDataVal == 1 ) {
/* Zero runs of 1-5 */
if ( RunLength <= 5 ) {
TokenListPtr[0] = DCT_RUN_CATEGORY1 + (RunLength - 1);
if ( DataValue > 0 )
TokenListPtr[1] = 0;
else
TokenListPtr[1] = 1;
} else if ( RunLength <= 9 ) {
/* Zero runs of 6-9 */
TokenListPtr[0] = DCT_RUN_CATEGORY1B;
if ( DataValue > 0 )
TokenListPtr[1] = (RunLength - 6);
else
TokenListPtr[1] = 0x04 + (RunLength - 6);
} else {
/* Zero runs of 10-17 */
TokenListPtr[0] = DCT_RUN_CATEGORY1C;
if ( DataValue > 0 )
TokenListPtr[1] = (RunLength - 10);
else
TokenListPtr[1] = 0x08 + (RunLength - 10);
}
tokens_added = 2;
} else if ( AbsDataVal <= 3 ) {
if ( RunLength == 1 ) {
TokenListPtr[0] = DCT_RUN_CATEGORY2;
/* Extra bits token bit 1 indicates sign, bit 0 indicates value */
if ( DataValue > 0 )
TokenListPtr[1] = (AbsDataVal - 2);
else
TokenListPtr[1] = (0x02) + (AbsDataVal - 2);
tokens_added = 2;
}else{
TokenListPtr[0] = DCT_RUN_CATEGORY2 + 1;
/* Extra bits token. */
/* bit 2 indicates sign, bit 1 indicates value, bit 0 indicates
run length */
if ( DataValue > 0 )
TokenListPtr[1] = ((AbsDataVal - 2) << 1) + (RunLength - 2);
else
TokenListPtr[1] = (0x04) + ((AbsDataVal - 2) << 1) + (RunLength - 2);
tokens_added = 2;
}
} else {
tokens_added = 2; /* ERROR */
/*IssueWarning( "Bad Input to TokenizeDctRunValue" );*/
}
/* Return the total number of tokens added */
return tokens_added;
}
static unsigned char TokenizeDctBlock (ogg_int16_t * RawData,
ogg_uint32_t * TokenListPtr ) {
ogg_uint32_t i;
unsigned char run_count;
unsigned char token_count = 0; /* Number of tokens crated. */
ogg_uint32_t AbsData;
/* Tokenize the block */
for( i = 0; i < BLOCK_SIZE; i++ ){
run_count = 0;
/* Look for a zero run. */
/* NOTE the use of & instead of && which is faster (and
equivalent) in this instance. */
/* NO, NO IT ISN'T --Monty */
while( (i < BLOCK_SIZE) && (!RawData[i]) ){
run_count++;
i++;
}
/* If we have reached the end of the block then code EOB */
if ( i == BLOCK_SIZE ){
TokenListPtr[token_count] = DCT_EOB_TOKEN;
token_count++;
}else{
/* If we have a short zero run followed by a low data value code
the two as a composite token. */
if ( run_count ){
AbsData = abs(RawData[i]);
if ( ((AbsData == 1) && (run_count <= 17)) ||
((AbsData <= 3) && (run_count <= 3)) ) {
/* Tokenise the run and subsequent value combination value */
token_count += TokenizeDctRunValue( run_count,
RawData[i],
&TokenListPtr[token_count] );
}else{
/* Else if we have a long non-EOB run or a run followed by a
value token > MAX_RUN_VAL then code the run and token
seperately */
if ( run_count <= 8 )
TokenListPtr[token_count] = DCT_SHORT_ZRL_TOKEN;
else
TokenListPtr[token_count] = DCT_ZRL_TOKEN;
token_count++;
TokenListPtr[token_count] = run_count - 1;
token_count++;
/* Now tokenize the value */
token_count += TokenizeDctValue( RawData[i],
&TokenListPtr[token_count] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -