📄 grayc.cpp
字号:
}
}
else {
Int width = where ().width;
const PixelC* ppxlc = pixels (rctInterest.left, rctInterest.top);
for (CoordI y = rctInterest.top; y < rctInterest.bottom; y++) {
const PixelC* ppxlcRow = ppxlc;
for (CoordI x = rctInterest.left; x < rctInterest.right; x++, ppxlcRow++) {
if (*ppxlcRow != ucVl)
nRet++;
}
ppxlc += width;
}
}
return nRet;
}
Void CU8Image::setRect (const CRct& rct)
{
assert (rct.area () == m_rc.area ());
m_rc = rct;
}
Void CU8Image::threshold (PixelC ucThresh)
{
PixelC* ppxlThis = (PixelC*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++) {
if (ppxlThis [id] < ucThresh)
ppxlThis [id] = 0;
}
}
Void CU8Image::binarize (PixelC ucThresh)
{
PixelC* ppxlcThis = (PixelC*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++, ppxlcThis) {
if (*ppxlcThis < ucThresh)
*ppxlcThis = transpValue;
else
*ppxlcThis = opaqueValue;
}
}
/* NBIT: change U8 to PixelC
Void CU8Image::checkRange (U8 ucMin, U8 ucMax)
*/
Void CU8Image::checkRange (PixelC ucMin, PixelC ucMax)
{
PixelC* ppxlcThis = (PixelC*) pixels ();
UInt area = where ().area ();
for (UInt id = 0; id < area; id++, ppxlcThis++)
*ppxlcThis = checkrange (*ppxlcThis, ucMin, ucMax);
}
own CU8Image* CU8Image::decimate (UInt rateX, UInt rateY) const
{
const CoordI left = where ().left / (CoordI) rateX;
const CoordI top = where ().top / (CoordI) rateY;
const CoordI right =
(where ().right >= 0) ? (where ().right + (CoordI) rateX - 1) / (CoordI) rateX :
(where ().right - (CoordI) rateX + 1) / (CoordI) rateX;
const CoordI bottom =
(where ().bottom >= 0) ? (where ().bottom + (CoordI) rateX - 1) / (CoordI) rateY :
(where ().bottom - (CoordI) rateX + 1) / (CoordI) rateY;
CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
const PixelC* ppxlcOrgY = pixels ();
Int skipY = rateY * where ().width;
for (CoordI y = top; y < bottom; y++) {
const PixelC* ppxlcOrgX = ppxlcOrgY;
for (CoordI x = left; x < right; x++) {
*ppxlcRet++ = *ppxlcOrgX;
ppxlcOrgX += rateX;
}
ppxlcOrgY += skipY;
}
return puciRet;
}
own CU8Image* CU8Image::decimateBinaryShape (UInt rateX, UInt rateY) const
{
const CoordI left = where ().left / (CoordI) rateX;
const CoordI top = where ().top / (CoordI) rateY;
Int roundR = (where ().right >= 0) ? rateX - 1 : 1 - rateX;
Int roundB = (where ().bottom >= 0) ? rateY - 1 : 1 - rateY;
const CoordI right = (where ().right + roundR) / (CoordI) rateX;
const CoordI bottom = (where ().bottom + roundB) / (CoordI) rateY;
CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
const PixelC* ppxlcOrgY = pixels ();
Int skipY = rateY * where ().width;
CoordI x, y;
CoordI iXOrigLeft, iYOrigTop; //left top of a sampling square
for (y = top, iYOrigTop = where().top; y < bottom; y++, iYOrigTop += rateY) {
const PixelC* ppxlcOrgX = ppxlcOrgY;
for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) {
CoordI iXOrig, iYOrig; //for scanning of the sampling square
const PixelC* ppxlcOrigScanY = ppxlcOrgX; //same
*ppxlcRet = transpValue;
for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++) {
if (iYOrig >= where().bottom || *ppxlcRet == opaqueValue)
break;
const PixelC* ppxlcOrigScanX = ppxlcOrigScanY; //for scan also
Bool bStopScan = FALSE;
for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++) {
if (iXOrig >= where().right)
break;
assert (*ppxlcOrigScanX == transpValue || *ppxlcOrigScanX == opaqueValue);
if (*ppxlcOrigScanX == opaqueValue) {
*ppxlcRet = opaqueValue;
break;
}
ppxlcOrigScanX++;
}
ppxlcOrigScanY += where().width;
}
assert (*ppxlcRet == transpValue || *ppxlcRet == opaqueValue);
ppxlcRet++;
ppxlcOrgX += rateX;
}
ppxlcOrgY += skipY;
}
return puciRet;
}
own CU8Image* CU8Image::zoomup (UInt rateX, UInt rateY) const
{
const CoordI left = where ().left * rateX; // left-top coordinate remain the same
const CoordI top = where ().top * rateY;
const CoordI right = where ().right * rateX;
const CoordI bottom = where ().bottom * rateY;
CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
PixelC* ppxlRet = (PixelC*) puciRet -> pixels ();
for (CoordI y = top; y < bottom; y++) {
for (CoordI x = left; x < right; x++)
*ppxlRet++ = pixel ((CoordI) (x / (CoordI) rateX), (CoordI) (y / (CoordI) rateY));
}
return puciRet;
}
own CU8Image* CU8Image::expand (UInt rateX, UInt rateY) const // expand by putting zeros in between
{
const CoordI left = where ().left * rateX; // left-top coordinate remain the same
const CoordI top = where ().top * rateY;
const CoordI right = where ().right * rateX;
const CoordI bottom = where ().bottom * rateY;
CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
PixelC* ppxlRet = (PixelC*) puciRet -> pixels ();
const PixelC* ppxlThis = pixels ();
for (CoordI y = top; y < bottom; y++) {
for (CoordI x = left; x < right; x++) {
if (x % rateX == 0 && y % rateY == 0)
*ppxlRet++ = *ppxlThis++;
else
*ppxlRet++ = 0;
}
}
return puciRet;
}
own CU8Image* CU8Image::biInterpolate () const // bilinearly interpolate the vframe
{
const CoordI left = where ().left << 1; // left-top coordinate remain the same
const CoordI top = where ().top << 1;
const CoordI right = where ().right << 1;
const CoordI bottom = where ().bottom << 1;
const width = right - left;
CoordI x, y;
CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
const PixelC* ppxlc = pixels ();
const right1 = right - 2;
for (y = top; y < bottom; y += 2) { // x-direction interpolation
for (x = left; x < right1; x += 2) {
*ppxlcRet++ = *ppxlc++;
*ppxlcRet++ = (*ppxlc + *(ppxlc - 1) + 1) >> 1;
}
*ppxlcRet++ = *ppxlc;
*ppxlcRet++ = *ppxlc++; // the last pixel of every row do not need average
ppxlcRet += width;
}
ppxlcRet = (PixelC*) puciRet -> pixels ();
ppxlcRet += width; // start from the second row
const width2 = width << 1;
const bottom1 = bottom - 1;
for (x = left; x < right; x++) { // y-direction interpolation
PixelC* ppxlcRett = ppxlcRet++;
for (y = top + 1; y < bottom1; y += 2) {
*ppxlcRett = (*(ppxlcRett - width) + *(ppxlcRett + width) + 1) >> 1;
ppxlcRett += width2;
}
*ppxlcRett = *(ppxlcRett - width); // the last pixel of every column do not need average
}
return puciRet;
}
own CU8Image* CU8Image::downsampleForSpatialScalability () const
{
static Int rgiFilterVertical[13] = {2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2};
static Int rgiFilterHorizontal[4] = {5, 11, 11, 5};
Int iWidthSrc = where (). width;
Int iHeightSrc = where (). height ();
assert (iWidthSrc % 2 == 0 && iHeightSrc % 2 == 0);
Int iWidthDst = iWidthSrc / 2;
Int iHeightDst = iHeightSrc / 2;
CU8Image* puciBuffer = new CU8Image (CRct (0, 0, iWidthSrc, iHeightDst));
CU8Image* puciRet = new CU8Image (CRct (0, 0, iWidthDst, iHeightDst));
assert (puciBuffer != NULL);
assert (puciRet != NULL);
//filter and downsample vertically
const PixelC* ppxlcSrc;
const PixelC* ppxlcColumnHeadSrc = pixels ();
PixelC* ppxlcDst = (PixelC*) puciBuffer->pixels ();
PixelC* ppxlcColumnHeadDst = (PixelC*) puciBuffer->pixels ();
Int i, j, k;
for (i = 0; i < iWidthSrc; i++) {
ppxlcSrc = ppxlcColumnHeadSrc;
ppxlcDst = ppxlcColumnHeadDst;
for (j = 0; j < iHeightDst; j++) {
k = j * 2;
const PixelC* ppxlcMinusOne = ( k < 1 ) ? ppxlcSrc : ppxlcSrc - iWidthSrc;
const PixelC* ppxlcMinusTwo = ( k < 2 ) ? ppxlcSrc : ppxlcMinusOne - iWidthSrc;
const PixelC* ppxlcMinusThree = ( k < 3 ) ? ppxlcSrc : ppxlcMinusTwo - iWidthSrc;
const PixelC* ppxlcMinusFour = ( k < 4 ) ? ppxlcSrc : ppxlcMinusThree - iWidthSrc;
const PixelC* ppxlcMinusFive = ( k < 5 ) ? ppxlcSrc : ppxlcMinusFour - iWidthSrc;
const PixelC* ppxlcMinusSix = ( k < 6 ) ? ppxlcSrc : ppxlcMinusFive - iWidthSrc;
const PixelC* ppxlcPlusOne = ( k >= iHeightSrc - 1) ? ppxlcSrc : ppxlcSrc + iWidthSrc;
const PixelC* ppxlcPlusTwo = ( k >= iHeightSrc - 2) ? ppxlcPlusOne : ppxlcPlusOne + iWidthSrc;
const PixelC* ppxlcPlusThree = ( k >= iHeightSrc - 3) ? ppxlcPlusTwo : ppxlcPlusTwo + iWidthSrc;
const PixelC* ppxlcPlusFour = ( k >= iHeightSrc - 4) ? ppxlcPlusThree : ppxlcPlusThree + iWidthSrc;
const PixelC* ppxlcPlusFive = ( k >= iHeightSrc - 5) ? ppxlcPlusFour : ppxlcPlusFour + iWidthSrc;
const PixelC* ppxlcPlusSix = ( k >= iHeightSrc - 6) ? ppxlcPlusFive : ppxlcPlusFive + iWidthSrc;
*ppxlcDst = checkrangeU8 (
(U8) ((*ppxlcMinusSix * rgiFilterVertical [0] +
*ppxlcMinusFive * rgiFilterVertical [1] +
*ppxlcMinusFour * rgiFilterVertical [2] +
*ppxlcMinusThree * rgiFilterVertical [3] +
*ppxlcMinusTwo * rgiFilterVertical [4] +
*ppxlcMinusOne * rgiFilterVertical [5] +
*ppxlcSrc * rgiFilterVertical [6] +
*ppxlcPlusOne * rgiFilterVertical [7] +
*ppxlcPlusTwo * rgiFilterVertical [8] +
*ppxlcPlusThree * rgiFilterVertical [9] +
*ppxlcPlusFour * rgiFilterVertical [10] +
*ppxlcPlusFive * rgiFilterVertical [11] +
*ppxlcPlusSix * rgiFilterVertical [12] + 32) >> 6),
0, 255
);
ppxlcSrc += 2 * iWidthSrc;
ppxlcDst += iWidthSrc;
}
ppxlcColumnHeadSrc++;
ppxlcColumnHeadDst++;
}
//filter and downsample horizontally
ppxlcSrc = puciBuffer->pixels ();
ppxlcDst = (PixelC*) puciRet->pixels ();
for (j = 0; j < iHeightDst; j++) {
for (i = 0; i < iWidthDst; i++) {
k = i * 2;
const PixelC* ppxlcMinusOne = ( k < 1 ) ? ppxlcSrc : ppxlcSrc - 1;
const PixelC* ppxlcPlusOne = ( k >= iWidthSrc - 1) ? ppxlcSrc : ppxlcSrc + 1;
const PixelC* ppxlcPlusTwo = ( k >= iWidthSrc - 2) ? ppxlcSrc : ppxlcSrc + 2;
*ppxlcDst = checkrangeU8 (
(U8) ((*ppxlcMinusOne * rgiFilterHorizontal [0] +
*ppxlcSrc * rgiFilterHorizontal [1] +
*ppxlcPlusOne * rgiFilterHorizontal [2] +
*ppxlcPlusTwo * rgiFilterHorizontal [3] + 16) >> 5),
0, 255
);
ppxlcSrc += 2;
ppxlcDst++;
}
}
delete puciBuffer;
return puciRet;
}
//OBSS_SAIT_991015
own CU8Image* CU8Image::upsampleForSpatialScalability ( Int iVerticalSamplingFactorM,
Int iVerticalSamplingFactorN,
Int iHorizontalSamplingFactorM,
Int iHorizontalSamplingFactorN,
Int iFrmWidth_SS,
Int iFrmHeight_SS,
Int iType,
Int iExpandYRefFrame,
Bool bShapeOnly
) const
{
CRct rctDst = where ();
rctDst.right = iFrmWidth_SS/iType+iExpandYRefFrame/iType;
rctDst.bottom= iFrmHeight_SS/iType+iExpandYRefFrame/iType;
rctDst.width = rctDst.right - rctDst.left;
Int iWidthSrc = where (). width ;
Int iHeightSrc = where (). height ();
Int iWidthDst = iFrmWidth_SS/iType+(iExpandYRefFrame*2)/iType;
Int iHeightDst = iFrmHeight_SS/iType+(iExpandYRefFrame*2)/iType;
CU8Image* puciRet = new CU8Image (CRct (rctDst.left, rctDst.top, rctDst.right, rctDst.bottom));
//upsample vertically
PixelC* ppxlcDst;
const PixelC* ppxlcColumnHeadSrc = pixels ();
Int x,y,y1,y2,x1,x2;
Int phase = 0;
Int *pict_vert;
const PixelC* pict= ppxlcColumnHeadSrc +iWidthSrc*iExpandYRefFrame/iType+iExpandYRefFrame/iType;
ppxlcDst = (PixelC *)puciRet->pixels();
//wchen: should not malloc at every call; need to change later
//pict_vert = (Int *) malloc (sizeof(Int)*((where().width-iExpandYRefFrame/iType*2)*(iHeightDst-iExpandYRefFrame/iType*2)));
// bug fix from Takefumi Nagumo 6/21/99
pict_vert = (Int *) malloc (sizeof(Int) * (Int)(1 + (where().width-iExpandYRefFrame/iType*2)
* (where().height()-iExpandYRefFrame/iType*2) * ((Float)iVerticalSamplingFactorN / (Float)iVerticalSamplingFactorM) ) );
if(bShapeOnly==FALSE) {
for(x=0;x< (where().width-iExpandYRefFrame/iType*2); x++)
for(y=0;y< (rctDst.height()-iExpandYRefFrame/iType*2); y++) {
y1 = (y*iVerticalSamplingFactorM )/iVerticalSamplingFactorN;
if(y1 < where().height() - iExpandYRefFrame/iType*2 - 1)
y2 = y1+1;
else
y2 = y1;
phase = (16*(((y)*iVerticalSamplingFactorM) %
iVerticalSamplingFactorN) + iVerticalSamplingFactorN/2 /*for rounding*/)
/iVerticalSamplingFactorN;
*(pict_vert+y*(where().width-iExpandYRefFrame/iType*2)+x) = (Int)(16-phase)*(*(pict+y1*where().width+x))
+ phase *(*(pict+y2*where().width+x));
}
for(y=0;y< rctDst.height()-iExpandYRefFrame*2/iType; y++)
for(x=0;x< rctDst.width -iExpandYRefFrame*2/iType; x++) {
x1 = (x*iHorizontalSamplingFactorM )/iHorizontalSamplingFactorN;
if(x1 < where().width - iExpandYRefFrame/iType*2 - 1)
x2 = x1+1;
else
x2 = x1;
// Warning:no rounding
phase = (16*(((x)*iHorizontalSamplingFactorM) %
iHorizontalSamplingFactorN) + iHorizontalSamplingFactorN/2 /*for rounding*/)
/ iHorizontalSamplingFactorN;
*(ppxlcDst+(x+iExpandYRefFrame/iType)+(y+iExpandYRefFrame/iType)*rctDst.width)
=(PixelC)(((16-phase)*(*(pict_vert+y*(where().width-iExpandYRefFrame/iType*2)+x1))
+ phase *(*(pict_vert+y*(where().width-iExpandYRefFrame/iType*2)+x2)) +128 )>>8 );
}
}
free(pict_vert);
return puciRet;
}
own CU8Image* CU8Image::upsampleSegForSpatialScalability ( Int iVerticalSamplingFactorM,
Int iVerticalSamplingFactorN,
Int iHorizontalSamplingFactorM,
Int iHorizontalSamplingFactorN,
Int iFrmWidth_SS,
Int iFrmHeight_SS,
Int iType,
Int iExpandYRefFrame
) const
{
Int x,y;
CRct rctDst;
rctDst.right = iFrmWidth_SS/iType+iExpandYRefFrame/iType;
rctDst.bottom = iFrmHeight_SS/iType+iExpandYRefFrame/iType;
rctDst.left = (where ().left);
rctDst.top = (where ().top);
rctDst.width = rctDst.right - rctDst.left;
CRct rctBuf2 = rctDst;
Int iWidthSrc = where (). width ;
Int iHeightSrc = where (). height ();
Int iWidthDst = rctDst.width;
Int iHeightDst = rctDst.bottom - rctDst.top;
double h_factor = log((double)iHorizontalSamplingFactorN/iHorizontalSamplingFactorM)/log(2);
int h_factor_int = (int)floor(h_factor+0.000001);
double v_factor = log((double)iVerticalSamplingFactorN/iVerticalSamplingFactorM)/log(2);
int v_factor_int = (int)floor(v_factor+0.000001);
//wchen: this approach is very slow; will have to change later
CU8Image* puciRet = new CU8Image (CRct (rctDst.left, rctDst.top, rctDst.right, rctDst.bottom));
CU8Image* puciBuffX = new CU8Image (CRct (0,0, (int)((rctDst.right - iExpandYRefFrame/iType)/(1<<h_factor_int)), where ().bottom - iExpandYRefFrame/iType));
CU8Image* puciBuffX2= new CU8Image (CRct (0,0, (int)(rctDst.right - iExpandYRefFrame/iType), where ().bottom - iExpandYRefFrame/iType));
CU8Image* puciBuffY = new CU8Image (CRct (0,0, (int)(rctDst.right - iExpandYRefFrame/iType), (int)((rctDst.bottom-iExpandYRefFrame/iType)/(1<<v_factor_int))));
Bool * Xcheck1;
Bool * Xcheck2;
Bool * Ycheck1;
Bool * Ycheck2;
Xcheck1 = new Bool [(int)((rctDst.right - iExpandYRefFrame/iType)/(1<<h_factor_int))];
Xcheck2 = new Bool [(int)(rctDst.right - iExpandYRefFrame/iType)];
Ycheck1 = new Bool [(int)((rctDst.bottom - iExpandYRefFrame/iType)/(1<<v_factor_int))];
Ycheck2 = new Bool [(int)(rctDst.bottom - iExpandYRefFrame/iType)];
//upsample vertically
PixelC* ppxlcDst;
const PixelC* ppxlcColumnHeadSrc = pixels ();
const PixelC* pict= ppxlcColumnHeadSrc + iWidthSrc*iExpandYRefFrame/iType+iExpandYRefFrame/iType;
ppxlcDst = (PixelC *)puciRet->pixels();
PixelC* ppxlcBuffX = (PixelC *)puciBuffX->pixels();
PixelC* ppxlcBuffX2 = (PixelC *)puciBuffX2->pixels();
PixelC* ppxlcBuffY = (PixelC *)puciBuffY->pixels();
//wchen: should not malloc at every call; need to change later
//for clear memory
for(y=0;y< rctDst.height(); y++)
for(x=0;x< rctDst.width; x++)
*(ppxlcDst+x+y*rctDst.width) = 0;
for(y=0;y< where ().bottom - iExpandYRefFrame/iType; y++)
for(x=0;x< (int)((rctDst.right - iExpandYRefFrame/iType)/(1<<h_factor_int)); x++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -