📄 jpgdecodercomponent.~cpp
字号:
}
return ;
}
//
// This function upsamples a component that has a sampling frequency less
// than the maximum for the image. In such a component, each compressed value
// represents multiple pixels.
//
// The function upsamples using a "block filter" which simply means the
// compressed values are stretched across multiple pixels by duplicating them.
//
void JpegDecoderComponent::blockFilter ()
{
unsigned output = 0 ;
unsigned int startdu = 0 ;
for (unsigned int durow = 0 ; durow < du_rows ; ++ durow)
{
for (unsigned int ii = 0 ; ii < JPEGSAMPLEWIDTH ; ++ ii)
{
for (unsigned int vv = 0 ; vv < v_sampling ; ++ vv)
{
unsigned int du = startdu ;
for (unsigned int ducol = 0 ; ducol < du_cols ; ++ ducol)
{
unsigned int jj ;
JPEGSAMPLE *dataunits = data_units [du][ii] ;
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [0] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [1] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [2] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [3] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [4] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [5] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [6] ; ++ output ;
}
for (jj = 0 ; jj < h_sampling ; ++ jj)
{
upsample_data [output] = dataunits [7] ; ++ output ;
}
++ du ;
}
}
}
startdu += du_cols ;
}
return ;
}
//
// Description:
//
// If the width of the image is such that the image does not span a complete
// data unit, this function copies the rightmost column to the next column
// in the last data units of each data unit row.
//
//
void JpegDecoderComponent::extendRightColumn ()
{
if (image_width % (h_sampling * JPEGSAMPLEWIDTH) != 0)
{
unsigned int col = (image_width % (h_sampling * JPEGSAMPLEWIDTH) + h_sampling - 1) / h_sampling ;
for (unsigned int durow = 0 ; durow < du_rows ; ++ durow)
{
for (unsigned int row = 0 ; row < JPEGSAMPLEWIDTH ; ++ row)
{
data_units [du_cols * durow - 1][row][col] =
data_units [du_cols * durow - 1][row][col - 1] ;
}
}
// Handle the lower right corner.
if (image_height % (v_sampling * JPEGSAMPLEWIDTH) != 0)
{
unsigned int row = image_height % JPEGSAMPLEWIDTH ;
data_units [du_cols * du_rows - 1][row][col] =
data_units [du_cols * du_rows - 1][row - 1][col - 1] ;
}
}
return ;
}
//
// Description:
//
// If the image height is such that it does not span an integral number
// of data unit rows, this function copies the last row of the image to
// the next row.
//
void JpegDecoderComponent::extendBottomRow ()
{
// If the image height does not fill the data unit height, extend the last row.
if (image_height % (v_sampling * JPEGSAMPLEWIDTH) != 0)
{
unsigned int row = (image_height % (v_sampling * JPEGSAMPLEWIDTH) + v_sampling - 1) / v_sampling ;
for (unsigned int du = du_cols * (du_rows - 1) ;
du < du_cols * du_rows ;
++ du)
{
for (unsigned int col = 0 ; col < JPEGSAMPLEWIDTH ; ++ col)
{
data_units [du][row][col] = data_units [du][row - 1][col] ;
}
}
}
return ;
}
void JpegDecoderComponent::triangleFilter ()
{
ASSERT (h_sampling % 2 == 0 && v_sampling % 2 == 0) ;
const unsigned int rowwidth = du_cols * h_sampling * JPEGSAMPLEWIDTH ;
const unsigned int LAST = JPEGSAMPLEWIDTH - 1 ;
extendRightColumn () ;
extendBottomRow () ;
// These are dummy data units that are used to fill in round the edges.
JpegDecoderDataUnit upperleft ;
JpegDecoderDataUnit uppercenter ;
JpegDecoderDataUnit upperright ;
JpegDecoderDataUnit left ;
JpegDecoderDataUnit right ;
JpegDecoderDataUnit lowerleft ;
JpegDecoderDataUnit lowercenter ;
JpegDecoderDataUnit lowerright ;
if (du_rows == 1 && du_cols == 1)
{
// Special case where the component has just one data unit.
FillEdges (data_units [0],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
FilterDataUnit (upsample_data, rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
left, data_units [0], right,
lowerleft, lowercenter, lowerright) ;
}
else if (du_rows == 1)
{
// Special case where the component has just one row of data units.
unsigned int offset = 0 ;
FillEdges (data_units [0],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
// Except in the case of a component with one data unit,
// FillEdges makes a mistake with at least two edge positions.
upperright [LAST][0] = data_units [1][0][0] ;
lowerright [0][0] = data_units [1][LAST][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
left, data_units [0], data_units [1],
lowerleft, lowercenter, lowerright) ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
for (unsigned int du = 1 ; du < du_cols - 1 ; ++ du)
{
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - 1][0][LAST] ;
lowerleft [0][LAST] = data_units [du - 1][LAST][LAST] ;
upperright [LAST][0] = data_units [du + 1][0][0] ;
lowerright [0][0] = data_units [du + 1][LAST][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
data_units [du - 1], data_units [du], data_units [du + 1],
lowerleft, lowercenter, lowerright) ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
}
FillEdges (data_units [du_cols - 1],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du_cols - 2][0][LAST] ;
lowerleft [0][LAST] = data_units [du_cols - 2][LAST][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
data_units [du_cols - 1], data_units [du_cols], right,
lowerleft, lowercenter, lowerright) ;
}
else if (du_cols == 1)
{
// Special case of a component with a single column of data units.
unsigned int offset = 0 ;
FillEdges (data_units [0],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
lowerleft [0][LAST] = data_units [1][0][0] ;
lowerright [0][0] = data_units [1][0][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
left, data_units [0], right,
lowerleft, data_units [1], lowerright) ;
offset += v_sampling * h_sampling * JPEGSAMPLESIZE ;
for (unsigned int du = 1 ; du < du_rows - 1 ; ++ du)
{
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - 1][LAST][0] ;
upperright [LAST][0] = data_units [du - 1][LAST][LAST] ;
lowerleft [0][LAST] = data_units [du + 1][0][0] ;
lowerright [0][0] = data_units [du + 1][0][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, data_units [du - 1], upperright,
left, data_units [du], right,
lowerleft, data_units [du + 1], lowerright) ;
offset += v_sampling * h_sampling * JPEGSAMPLESIZE ;
}
FillEdges (data_units [du_cols - 1],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du_cols - 2][LAST][0] ;
upperright [LAST][0] = data_units [du_cols - 2][LAST][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, data_units [du_cols - 1], upperright,
left, data_units [du_cols], right,
lowerleft, lowercenter, lowerright) ;
}
else
{
// General case. The component has at least 2 rows and two columns of data
// units.
const unsigned int LAST = JPEGSAMPLEWIDTH - 1 ;
unsigned int du = 0 ;
unsigned int offset = 0 ;
// Upper Left Corner
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperright [LAST][0] = data_units [du + 1][0][0] ;
lowerleft [0][LAST] = data_units [du + du_cols][0][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
left, data_units [du], data_units [du + 1],
lowerleft, data_units [du + du_cols], data_units [du + du_cols + 1]) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
// Top Row
for (unsigned int ii = 1 ; ii < du_cols - 1 ; ++ ii)
{
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - 1][0][LAST] ;
upperright [LAST][0] = data_units [du + 1][0][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
data_units [du - 1], data_units [du], data_units [du + 1],
data_units [du + du_cols - 1], data_units [du + du_cols], data_units [du + du_cols + 1]) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
}
// Upper Right
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - 1][0][LAST] ;
lowerright [0][0] = data_units [du + du_cols][0][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, uppercenter, upperright,
data_units [du - 1], data_units [du], right,
data_units [du + du_cols - 1], data_units [du + du_cols], lowerright) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
ASSERT (offset == rowwidth) ;
offset += rowwidth * (JPEGSAMPLEWIDTH * v_sampling - 1) ;
for (unsigned int durows = 1 ; durows < du_rows - 1 ; ++ durows)
{
ASSERT (offset == rowwidth * v_sampling * durows * JPEGSAMPLEWIDTH) ;
// Left Edge
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - du_cols][LAST][0] ;
lowerleft [0][LAST] = data_units [du + du_cols][0][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, data_units [du - du_cols], data_units [du - du_cols + 1],
left, data_units [du], data_units [du + 1],
lowerleft, data_units [du + du_cols], data_units [du + du_cols + 1]) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
for (unsigned int ducols = 1 ; ducols < du_cols - 1 ; ++ ducols)
{
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
data_units [du - du_cols - 1], data_units [du - du_cols], data_units [du - du_cols + 1],
data_units [du - 1], data_units [du], data_units [du + 1],
data_units [du + du_cols - 1], data_units [du + du_cols], data_units [du + du_cols + 1]) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
}
// Right Edge
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperright [LAST][0] = data_units [du - du_cols][LAST][LAST] ;
lowerright [0][0] = data_units [du + du_cols][0][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
data_units [du - du_cols - 1], data_units [du - du_cols], upperright,
data_units [du - 1], data_units [du], right,
data_units [du + du_cols - 1], data_units [du + du_cols], lowerright) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
offset += rowwidth * (JPEGSAMPLEWIDTH * v_sampling - 1) ;
ASSERT (offset % JPEGSAMPLEWIDTH == 0 && offset % rowwidth == 0) ;
}
// Bottom Left Corner
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
upperleft [LAST][LAST] = data_units [du - du_cols][LAST][0] ;
lowerright [0][0] = data_units [du + 1][0][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
upperleft, data_units [du - du_cols], data_units [du - du_cols + 1],
left, data_units [du], data_units [du + 1],
lowerleft, lowercenter, lowerright) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
BILLSELLSPOOP
for (unsigned int ii = 1 ; ii < du_cols - 1 ; ++ ii)
{
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
lowerleft [0][LAST] = data_units [du - 1][LAST][LAST] ;
lowerright [0][0] = data_units [du + 1][0][0] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
data_units [du - du_cols - 1], data_units [du - du_cols], data_units [du - du_cols + 1],
data_units [du - 1], data_units [du], data_units [du + 1],
lowerleft, lowercenter, lowerright) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
}
ENDBILLSELLSPOOP
FillEdges (data_units [du],
upperleft, uppercenter, upperright,
left, right,
lowerleft, lowercenter, lowerright) ;
lowerleft [0][LAST] = data_units [du - 1][LAST][LAST] ;
upperright [LAST][0] = data_units [du - du_cols][LAST][LAST] ;
FilterDataUnit (&upsample_data [offset], rowwidth,
h_sampling, v_sampling,
data_units [du - du_cols - 1], data_units [du - du_cols], upperright,
data_units [du - 1], data_units [du], right,
lowerleft, lowercenter, lowerright) ;
++ du ;
offset += h_sampling * JPEGSAMPLEWIDTH ;
}
return ;
}
} // End Namespace ColosseumPrivate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -