📄 fast_dct.c
字号:
/**************************************************************************
* *
* This code is developed by Eugene Kuznetsov. This software is an *
* implementation of a part of one or more MPEG-4 Video tools as *
* specified in ISO/IEC 14496-2 standard. Those intending to use this *
* software module in hardware or software products are advised that its *
* use may infringe existing patents or copyrights, and any such use *
* would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies (including Project Mayo), will have no liability for use of *
* this software or modifications or derivatives thereof. *
* *
* Project Mayo gives users of the Codec a license to this software *
* module or modifications thereof for use in hardware or software *
* products claiming conformance to the MPEG-4 Video Standard as *
* described in the Open DivX license. *
* *
* The complete Open DivX license can be found at *
* http://www.projectmayo.com/opendivx/license.php . *
* *
**************************************************************************/
/**************************************************************************
*
* fast_dct.c, C implementation of fast integer forward DCT algorithm
*
* Copyright (C) 2001 Project Mayo
*
* Eugene Kuznetsov
*
* DivX Advance Research Center <darc@projectmayo.com>
*
**************************************************************************/
#include "dct.h"
const float m_c0 = 0.7071068f; // 2896
const float m_c1 = 0.4903926f; // 2009
const float m_c2 = 0.4619398f; // 1892
const float m_c3 = 0.4157348f; // 1703
const float m_c4 = 0.3535534f; // 1448
const float m_c5 = 0.2777851f; // 1138
const float m_c6 = 0.1913417f; // 784
const float m_c7 = 0.0975452f; // 400
void oneDimensionalFwdDCT_fast_up(int16_t *sInput)
{
int32_t sBuffer[8];
int32_t sBuffer2[4];
int j, j1;
for (j = 0; j < 4; j++)
{
j1 = 7 - j;
sBuffer[j] = sInput[j] + sInput[j1];
sBuffer[j1] = sInput[j] - sInput[j1];
}
sBuffer2[0] = sBuffer[0] + sBuffer[3];
sBuffer2[1] = sBuffer[1] + sBuffer[2];
sBuffer2[2] = sBuffer[1] - sBuffer[2];
sBuffer2[3] = sBuffer[0] - sBuffer[3];
sInput[0] = ((sBuffer2[0] + sBuffer2[1]) * (int16_t) (m_c4 * 4096)) >> 8;
sInput[4] = ((sBuffer2[0] - sBuffer2[1]) * (int16_t) (m_c4 * 4096)) >> 8;
sInput[2] =
(sBuffer2[2] * (int16_t) (m_c6 * 4096) +
sBuffer2[3] * (int16_t) (m_c2 * 4096)) >> 8;
sInput[6] =
(sBuffer2[3] * (int16_t) (m_c6 * 4096) -
sBuffer2[2] * (int16_t) (m_c2 * 4096)) >> 8;
sBuffer2[0] = sBuffer[4] << 12;
sBuffer2[1] = (sBuffer[6] - sBuffer[5]) * (int16_t) (m_c0 * 4096);
sBuffer2[2] = (sBuffer[6] + sBuffer[5]) * (int16_t) (m_c0 * 4096);
sBuffer2[3] = sBuffer[7] << 12;
sBuffer[4] = (sBuffer2[0] + sBuffer2[1]) >> 10;
sBuffer[7] = (sBuffer2[3] + sBuffer2[2]) >> 10;
sBuffer[5] = (sBuffer2[0] - sBuffer2[1]) >> 10;
sBuffer[6] = (sBuffer2[3] - sBuffer2[2]) >> 10;
sInput[1] =
(sBuffer[4] * (int16_t) (m_c7 * 4096) +
sBuffer[7] * (int16_t) (m_c1 * 4096)) >> 10;
sInput[5] =
(sBuffer[5] * (int16_t) (m_c3 * 4096) +
sBuffer[6] * (int16_t) (m_c5 * 4096)) >> 10;
sInput[7] =
(sBuffer[7] * (int16_t) (m_c7 * 4096) -
sBuffer[4] * (int16_t) (m_c1 * 4096)) >> 10;
sInput[3] =
(sBuffer[6] * (int16_t) (m_c3 * 4096) -
sBuffer[5] * (int16_t) (m_c5 * 4096)) >> 10;
}
void oneDimensionalFwdDCT_fast_down(int16_t *sInput)
{
int32_t sBuffer[8];
int32_t sBuffer2[4];
int j, j1;
for (j = 0; j < 4; j++)
{
j1 = 7 - j;
sBuffer[j] = sInput[8 * j] + sInput[8 * j1];
sBuffer[j1] = sInput[8 * j] - sInput[8 * j1];
}
sBuffer2[0] = sBuffer[0] + sBuffer[3];
sBuffer2[1] = sBuffer[1] + sBuffer[2];
sBuffer2[2] = sBuffer[1] - sBuffer[2];
sBuffer2[3] = sBuffer[0] - sBuffer[3];
sInput[8 * 0] =
((sBuffer2[0] + sBuffer2[1]) * (int16_t) (m_c4 * 4096)) >> 16;
sInput[8 * 4] =
((sBuffer2[0] - sBuffer2[1]) * (int16_t) (m_c4 * 4096)) >> 16;
sInput[8 * 2] =
(sBuffer2[2] * (int16_t) (m_c6 * 4096) +
sBuffer2[3] * (int16_t) (m_c2 * 4096)) >> 16;
sInput[8 * 6] =
(sBuffer2[3] * (int16_t) (m_c6 * 4096) -
sBuffer2[2] * (int16_t) (m_c2 * 4096)) >> 16;
sBuffer2[0] = sBuffer[4] << 12;
sBuffer2[1] = (sBuffer[6] - sBuffer[5]) * (int16_t) (m_c0 * 4096);
sBuffer2[2] = (sBuffer[6] + sBuffer[5]) * (int16_t) (m_c0 * 4096);
sBuffer2[3] = sBuffer[7] << 12;
sBuffer[4] = (sBuffer2[0] + sBuffer2[1]) >> 10;
sBuffer[7] = (sBuffer2[3] + sBuffer2[2]) >> 10;
sBuffer[5] = (sBuffer2[0] - sBuffer2[1]) >> 10;
sBuffer[6] = (sBuffer2[3] - sBuffer2[2]) >> 10;
sInput[8 * 1] =
(sBuffer[4] * (int16_t) (m_c7 * 4096) +
sBuffer[7] * (int16_t) (m_c1 * 4096)) >> 18;
sInput[8 * 5] =
(sBuffer[5] * (int16_t) (m_c3 * 4096) +
sBuffer[6] * (int16_t) (m_c5 * 4096)) >> 18;
sInput[8 * 7] =
(sBuffer[7] * (int16_t) (m_c7 * 4096) -
sBuffer[4] * (int16_t) (m_c1 * 4096)) >> 18;
sInput[8 * 3] =
(sBuffer[6] * (int16_t) (m_c3 * 4096) -
sBuffer[5] * (int16_t) (m_c5 * 4096)) >> 18;
}
void fdct_enc_fast(int16_t *block)
{
int32_t i;
for (i = 0; i < 8; i++)
oneDimensionalFwdDCT_fast_up(block + 8 * i);
for (i = 0; i < 8; i++)
oneDimensionalFwdDCT_fast_down(block + i);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -