📄 quant.cpp
字号:
/* $Id: quant.cpp,v 1.1 2003/05/05 21:24:21 wmaycisco 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 --------------------------*//* Function: --------- initQuantSingleStage - Initialization of the single-stage quantizer for a given value. Arguments: ---------- quantState *state - PoInter to the state data structure. Int *statePrevQ - PoInter to previous quantized value state. Int initialValue - Value which is to be quantized. Return Value: ------------- <None> Description: ------------ This must be called prior to single-stage quantization. A seperate state structure must be kept for each value that is quantized in parallel. Single-stage quantization is just successive calls to quantSingleStage. For each value, need only be called once, before the first call to quantSingleStage.*/Void CVTCCommon::initQuantSingleStage(quantState *state, Int *statePrevQ, Int initialVal){ state->residualValue = initialVal; state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone = 1 */ *statePrevQ = 0;}/* Function: --------- quantSingleStage - Single-stage quantizer. Arguments: ---------- Int Q - Quantization value. Represents desired quantization level size. quantState *state - State of quantizer. Int *statePrevQ - PoInter to previous quantized value state. Int updatePrevQ - 0 means don't update the statePrevQ variable. !0 means update it. Return Value: ------------- New Q index. Description: ------------ initQuantSingleStage must be called prior to using this function the first time for a given value. It will compute the new quantization index based on the current state associated with the value.*/Int CVTCEncoder::quantSingleStage(Int Q, quantState *state, Int *statePrevQ, Int updatePrevQ){ Int refLevs; /* how many refinement levels in new stage */ Int QIndex; /* new quantization index to return for this stage */ /*--------------- INITIAL QUANTIZATION STAGE -------------------*/ if (*statePrevQ==0) { QIndex = state->residualValue/Q; /* update state */ 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; } /*--------------- NON-INITIAL QUANTIZATION STAGES -------------------*/ /* get the number of refinement levels from lastQUsed state */ refLevs = IROUND(*statePrevQ,Q); /* Catch condition where there's no refinement being done. State information is not changed. */ if (refLevs<=1) QIndex = 0; else { Int inDeadZone; /* are we still in the dead zone */ Int lastQUsed; /* The "real" Q value last used */ Int val; /* value of number to be quantized */ Int lastLevSize; /* Size of quantization level used last */ Int newQUsed, newStateQ; Int excess; /* Initialize the last quant value used */ lastQUsed = *statePrevQ; /* update new Q value state */ newStateQ = newQUsed = ICEIL(lastQUsed,refLevs); if (updatePrevQ) *statePrevQ = newStateQ; /* Get last level size */ lastLevSize = lastQUsed-fromReduced(state->partitionType); /* check if a reduced level can span the last level */ if (refLevs*(newQUsed-1) >= lastLevSize) { --newQUsed; /* might overshoot (?) but can't reduce anymore */ excess=0; } else /* get excess (overshoot) */ excess=lastLevSize-refLevs*newQUsed; /* Set dead zone indicator */ inDeadZone = fromDeadZone(state->partitionType); /* Set value of leftovers from last pass */ val=state->residualValue; /*--- Calculate QIndex. Update residualValue and fromReduced states ---*/ 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; /* Where the reduced partition starts (magnitude) */ 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; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -