📄 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: last mod: $Id: dct_encode.c 11442 2006-05-27 17:28:08Z giles $ ********************************************************************/#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 + -