📄 quant.cpp
字号:
/* $Id: quant.c,v 1.15 1998/05/14 21:41:40 hjlee Exp $ */
/****************************************************************************/
/* MPEG4 Visual Texture Coding (VTC) Mode Software */
/* */
/* This software was jointly developed by the following participants: */
/* */
/* Single-quant, multi-quant and flow control */
/* are provided by Sarnoff Corporation */
/* Iraj Sodagar (iraj@sarnoff.com) */
/* Hung-Ju Lee (hjlee@sarnoff.com) */
/* Paul Hatrack (hatrack@sarnoff.com) */
/* Shipeng Li (shipeng@sarnoff.com) */
/* Bing-Bing Chai (bchai@sarnoff.com) */
/* B.S. Srinivas (bsrinivas@sarnoff.com) */
/* */
/* Bi-level is provided by Texas Instruments */
/* Jie Liang (liang@ti.com) */
/* */
/* Shape Coding is provided by OKI Electric Industry Co., Ltd. */
/* Zhixiong Wu (sgo@hlabs.oki.co.jp) */
/* Yoshihiro Ueda (yueda@hlabs.oki.co.jp) */
/* Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp) */
/* */
/* OKI, Sharp, Sarnoff, TI and Microsoft contributed to bitstream */
/* exchange and bug fixing. */
/* */
/* */
/* In the course of development of the MPEG-4 standard, this software */
/* module is an implementation of a part of one or more MPEG-4 tools as */
/* specified by the MPEG-4 standard. */
/* */
/* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use */
/* of the MPEG-4 standard free license to use this software module or */
/* modifications thereof for hardware or software products claiming */
/* conformance to the MPEG-4 standard. */
/* */
/* Those intending to use this software module in hardware or software */
/* products are advised that use may infringe existing patents. The */
/* original developers of this software module and their companies, the */
/* subsequent editors and their companies, and ISO/IEC have no liability */
/* and ISO/IEC have no liability for use of this software module or */
/* modification thereof in an implementation. */
/* */
/* Permission is granted to MPEG members to use, copy, modify, */
/* and distribute the software modules ( or portions thereof ) */
/* for standardization activity within ISO/IEC JTC1/SC29/WG11. */
/* */
/* Copyright 1995, 1996, 1997, 1998 ISO/IEC */
/****************************************************************************/
/************************************************************/
/* Sarnoff Very Low Bit Rate Still Image Coder */
/* Copyright 1995, 1996, 1997, 1998 Sarnoff Corporation */
/************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "basic.hpp"
#include "dataStruct.hpp"
#include "quant.hpp"
/* sign */
#define SGN(x) (((x)<0) ? -1 : 1)
/* Integer rounding */
#define IROUND(n,d) ( ((n)/(d)) + (((n)%(d) > (d-1)/2) || (n)<(d)))
/* Integer ceiling */
#define ICEIL(n,d) ( ((n)/(d)) + ((n)%(d)!=0 || (n)<(d)) )
/* For partitionType bit field processing */
#define MASK_fromReduced ((UChar)'\1')
#define MASK_fromDeadZone ((UChar)'\2')
#define SET_fromReduced(x) ((x) |= MASK_fromReduced)
#define SET_fromDeadZone(x) ((x) |= MASK_fromDeadZone)
#define CLR_fromReduced(x) ((x) &= ~(MASK_fromReduced))
#define CLR_fromDeadZone(x) ((x) &= ~(MASK_fromDeadZone))
#define fromReduced(x) ((x) & MASK_fromReduced)
#define fromDeadZone(x) (((x) & MASK_fromDeadZone)>>1)
/*------------------------- QUANTIZATION --------------------------*/
/*
函数输入:
quantState *state: 指向表征量化器状态的指针;
Int *statePrevQ: 指向先前量化状态的指针;
Int initialValue: 进行量化的系数值。
函数功能描述:
对一个给定的系数值完成其量化器的初始化工作。
函数功能评价:
本函数必须在量化前调用。此外,对于每一次进行量化的系数,必须有一个独立的量化器状态结构来进行记录,这样可以保证系数的并行量化处理。每一个需要进行量化的系数,只需要调用一次量化器初始化即可。
*/
Void CVTCCommon::initQuantSingleStage(quantState *state, Int *statePrevQ, Int initialVal)
{
state->residualValue = initialVal;
state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone = 1 */
*statePrevQ = 0;
}
/*
函数输入:
Int Q: 量化数值,它表示预设的量化级别的多少;
quantState *state: 量化器状态值;
Int *statePrevQ: 前线量化的数值状态;
Int updatePrevQ: 是否更新statePrevQ的数值:0表示不更新;非0表示需要进行更新。
函数返回值:
Qindex,即新的量化索引(量化级别索引)。
函数功能描述:
实现系数的量化。
函数功能评价:
调用initQuantSingleStage函数对量化器完成初始化后,该函数将在当前量化值得基础上计算出一个新的量化索引。
*/
Int CVTCEncoder::quantSingleStage(Int Q, quantState *state, Int *statePrevQ,
Int updatePrevQ)
{
Int refLevs; //在新的量化级上有多少细化级别
Int QIndex; //完成本级量化后返回的新的量化索引
//完成量化器的初始化工作后第一次调用量化函数
if (*statePrevQ==0)
{
QIndex = state->residualValue/Q;
//更新量化器状态
if (QIndex)
state->residualValue = abs(state->residualValue) - (abs(QIndex)*Q);
CLR_fromReduced(state->partitionType);
if (QIndex)
CLR_fromDeadZone(state->partitionType);
else
SET_fromDeadZone(state->partitionType);
if (updatePrevQ)
*statePrevQ = Q;
return QIndex;
}
//非第一次调用量化函数
//由上一次量化状态值得到此次量化的细化级别数
refLevs = IROUND(*statePrevQ,Q);
//如果细化没有完成,继续!并且不改变量化器的状态信息
if (refLevs<=1)
QIndex = 0;
else
{
Int inDeadZone; //是否在量化静区(dead zone)
Int lastQUsed; //最后一次量化所用的Q值
Int val; //用于量化的系数值
Int lastLevSize; //上一次量化的量化级别数
Int newQUsed, newStateQ;
Int excess;
//初始化上一次实用的量化系数值
lastQUsed = *statePrevQ;
//更新得到一个新的Q值状态
newStateQ = newQUsed = ICEIL(lastQUsed,refLevs);
if (updatePrevQ)
*statePrevQ = newStateQ;
//获取最后的量化级别步长
lastLevSize = lastQUsed-fromReduced(state->partitionType);
//查看细化细节是否有效
if (refLevs*(newQUsed-1) >= lastLevSize)
{
--newQUsed;
excess=0;
}
else
excess=lastLevSize-refLevs*newQUsed;
//设置量化静区的指示
inDeadZone = fromDeadZone(state->partitionType);
//设置上一量化后的区间左端数值
val=state->residualValue;
//计算QIndex,并更新residualValue和fromReduced的状态
if (excess==0)
{
QIndex = val/newQUsed;
if (newQUsed < newStateQ)
SET_fromReduced(state->partitionType);
else
CLR_fromReduced(state->partitionType);
if (QIndex)
state->residualValue -= QIndex*newQUsed;
}
else
{
Int reducedParStart;
Int reducedIdx;
reducedParStart = newQUsed*(refLevs+excess);
if (abs(val) >= reducedParStart)
{
SET_fromReduced(state->partitionType);
QIndex = SGN(state->residualValue)*(refLevs+excess);
state->residualValue -= QIndex*newQUsed;
--newQUsed;
reducedIdx =
SGN(state->residualValue) * (abs(val)-reducedParStart) / newQUsed;
QIndex += reducedIdx;
state->residualValue -= reducedIdx*newQUsed;
}
else
{
CLR_fromReduced(state->partitionType);
QIndex = val/newQUsed;
state->residualValue -= QIndex*newQUsed;
}
}
if (inDeadZone && QIndex)
{
//系数的符号信息,那么可以保证量化差异值为正数
state->residualValue = abs(state->residualValue);
CLR_fromDeadZone(state->partitionType);
}
}
//返回新的量化索引
return QIndex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -