📄 jpgdecodercomponent.~cpp
字号:
//
// Copyright (c) 1997,1998 Colosseum Builders, Inc.
// All rights reserved.
//
// Colosseum Builders, Inc. makes no warranty, expressed or implied
// with regards to this software. It is provided as is.
//
// See the README.TXT file that came with this software for restrictions
// on the use and redistribution of this file or send E-mail to
// info@colosseumbuilders.com
//
//
// JPEG Decoder Component Class Implementation
//
// Author: John M. Miano miano@colosseumbuilders.com
//
#include "jpgdecodercomponent.h"
#include "jpgdecoderquantization.h"
#include "jpgdecoder.h"
#include "jpgcoefficient.h"
#include "jpgpvt.h"
#include "bitmapimage.h"
using namespace Colosseum ;
using namespace ColosseumPrivate ;
namespace
{
inline void RefineAcCoefficient (Colosseum::JpegInputStream &inputstream,
unsigned int ssa,
BYTE2 &value)
{
// Section G.1.2.3
if (value > 0)
{
if (inputstream.nextBit () != 0)
{
value += (1 << ssa) ;
}
}
else if (value < 0)
{
if (inputstream.nextBit () != 0)
{
value += (-1 << ssa) ;
}
}
return ;
}
//
// Description:
//
// SequentialOnly
//
// This function extends the sign bit of a decoded value.
//
// Parameters:
// vv: The bit value
// tt: The length of the bit value
//
inline int Extend (int vv, int tt)
{
// Extend function defined in Section F.2.2.1 Figure F.12
// The tt'th bit of vv is the sign bit. One is for
// positive values and zero is for negative values.
int vt = 1 << (tt - 1) ;
if (vv < vt)
{
vt = (-1 << tt) + 1 ;
return vv + vt ;
}
else
{
return vv ;
}
}
//
// Description:
//
// This function calculates the value for a pixel using a triangle filter.
//
// The filtering is performed as follows:
//
// o We make the origin at the upper left corner and have the positive
// axis go down and to the left.
// o We place the component values [x,y] at (0,0), (hperiod, 0),
// (0, vperiod), (hperiod, vperiod).
// o We assume the physical pixels are located at
//
// (1/2, 1/2), (3/2, 1/2) ... (hperiod - 1/2, 1/2)
// (1/2, 3/2), (3/2, 3/2, ... (hperiod - 1/2, 3/2)
// ...
// (1/2, vperiod - 1/2), (3/2, vperiod - 1/2), ... (hperiod - 1/2, vperiod - 1/2)
//
// o We calculate the filter value for each pixel using a linear weighting
// of the four component values based upon the distance from each.
//
// Parameters:
//
// xpos, ypos: The position of the pixel relative to the upper left
// corner. Since the positions are always fractions (N + 1/2) the
// input valus are multiplied by 2.
// ul, ur, ll, lr: The component values at the upper left, upper right, lower
// left, and lower right.
// hperiod, vperiod: The sampling for the component. Each component value
// represents the value of hperiod x vperiod pixels.
//
//
inline JPEGSAMPLE TriangleFilter (int xpos, int ypos,
int ul, int ur,
int ll, int lr,
unsigned int hperiod,
unsigned int vperiod)
{
int result = ((ul * (2 * hperiod - xpos) + ur * xpos) * (2 * vperiod - ypos)
+ (ll * (2 * hperiod - xpos) + lr * xpos) * ypos
+ 4 * hperiod * vperiod - 1)
/ (4 * hperiod * vperiod) ;
ASSERT (result >= 0 && result <= JPEGMAXSAMPLEVALUE) ;
return result ;
}
//
// Description:
//
// This function triangle filters a block of pixels at the corner of a
// data unit. At the corner there are (hperiod/2) * (vperiod/2) pixels.
//
// Parameters:
//
// startx, starty: The position of the upper left pixel in the block relative
// to the positions of the component values. These values
// are scaled by 2 so they will not be fractions. For an
// upper left corner these values will be
// (hperiod + 1, vperiod + 1), upper right (1, vperiod + 1),
// lower left (hperiod + 1, 1), lower right (1, 1).
// startposition: The location to output the upper left pixel.
// rowwidth: The number of pixels per row in the output buffer.
// up, up, ll, lr: The component values as the four corners.
// hperiod, vperiod: The component sampling.
//
inline void FilterCorner (unsigned int startx,
unsigned int starty,
JPEGSAMPLE *startposition,
unsigned int rowwidth,
int ul, int ur,
int ll, int lr,
unsigned int hperiod,
unsigned int vperiod)
{
unsigned int yy = starty ;
unsigned int rowoffset = 0 ;
for (unsigned int ii = 0 ; ii < vperiod / 2 ; ++ ii, yy += 2)
{
unsigned int xx = startx ;
unsigned int offset = rowoffset ;
for (unsigned int jj = 0 ; jj < hperiod / 2 ; ++ jj, xx += 2)
{
startposition [offset] = TriangleFilter (xx, yy,
ul, ur,
ll, lr,
hperiod, vperiod) ;
++ offset ;
}
rowoffset += rowwidth ;
}
return ;
}
//
// Description:
//
// This function triangle filters a block of pixels at the top or bottom of
// data unit (but not at the corner). Each block contains
// hperiod * (vperiod / 2) pixels.
//
// Parameters:
//
// starty: The position of the frst row of pixels pixels in the block relative
// to the positions of the component values. These values are scaled
// by 2 to eliminate fractions. For an upper row, this value is vperiod + 1,
/// for a bottom row it is 1.
// startposition: The location to output the upper left pixel.
// rowwidth: The number of pixels per row in the output buffer.
// up, up, ll, lr: The component values as the four corners.
// hperiod, vperiod: The component sampling.
//
inline void FilterTopOrBottom (unsigned int starty,
JPEGSAMPLE *startposition,
unsigned int rowwidth,
int ul, int ur,
int ll, int lr,
unsigned int hperiod,
unsigned int vperiod)
{
unsigned int rowoffset = 0 ;
for (unsigned int ii = 0, yy = starty ; ii < vperiod / 2 ; ++ ii, yy += 2)
{
unsigned int xx = 1 ;
unsigned int offset = rowoffset ;
for (unsigned int jj = 0 ; jj < hperiod ; ++ jj, xx += 2)
{
startposition [offset] = TriangleFilter (xx, yy,
ul, ur,
ll, lr,
hperiod, vperiod) ;
++ offset ;
}
rowoffset += rowwidth ;
}
return ;
}
//
// Description:
//
// This function triangle filters a block of pixels at either side of a data
// unit (but not at the corner). Each block contains
// (hperiod / 2) * vperiod pixels.
//
// Parameters:
//
// startx: The position of the fist column of pixels pixels in the block relative
// to the positions of the component values. These values are scaled
// by 2 to eliminate fractions. For pixels at the left side of a data
// unit, this value is hperiod + 1. At the right size it is 1.
// startposition: The location to output the upper left pixel.
// rowwidth: The number of pixels per row in the output buffer.
// up, up, ll, lr: The component values as the four corners.
// hperiod, vperiod: The component sampling.
//
inline void FilterSide (unsigned int startx,
JPEGSAMPLE *startposition,
unsigned int rowwidth,
int ul, int ur,
int ll, int lr,
unsigned int hperiod,
unsigned int vperiod)
{
unsigned int rowoffset = 0 ;
for (unsigned int ii = 0, yy = 1 ; ii < vperiod ; ++ ii, yy +=2)
{
unsigned int offset = rowoffset ;
for (unsigned int jj = 0, xx = startx ; jj < hperiod / 2 ; ++ jj, xx += 2)
{
startposition [offset] = TriangleFilter (xx, yy,
ul, ur,
ll, lr,
hperiod, vperiod) ;
++ offset ;
}
rowoffset += rowwidth ;
}
return ;
}
//
// Description:
//
// This function triangle filters a vperiod x hperiod block of pixels that
/// are not at the edge of the data unit.
//
// Parameters:
//
// startposition: The location to output the upper left pixel.
// rowwidth: The number of pixels per row in the output buffer.
// up, up, ll, lr: The component values as the four corners.
// hperiod, vperiod: The component sampling.
//
inline void FilterMiddle (JPEGSAMPLE *startposition,
unsigned int rowwidth,
int ul, int ur,
int ll, int lr,
unsigned int hperiod,
unsigned int vperiod)
{
unsigned int rowoffset = 0 ;
for (unsigned int ii = 0, yy = 1 ; ii < vperiod ; ++ ii, yy +=2)
{
unsigned int offset = rowoffset ;
for (unsigned int jj = 0, xx = 1 ; jj < hperiod ; ++ jj, xx += 2)
{
startposition [offset] = TriangleFilter (xx, yy,
ul, ur,
ll, lr,
hperiod, vperiod) ;
++ offset ;
}
rowoffset += rowwidth ;
}
return ;
}
//
// Decription:
//
// This function triangle filters a data unit.
//
// Parameters:
//
// startposition: The location to output the upper left pixel.
// rowwidth: The number of pixels per row in the output buffer.
// hperiod, vperiod: The component sampling.
// upperleft, uppercenter, upperright, left: Adjacent data units (used
// to filter pixels at the edge.
// center: The data unit to filter.
// right, lowerleft, lowercenter, lowerright: More adjacent data units.
//
//
inline void FilterDataUnit (
JPEGSAMPLE *startposition,
unsigned int rowwidth,
unsigned int hperiod,
unsigned int vperiod,
const JpegDecoderDataUnit &upperleft,
const JpegDecoderDataUnit &uppercenter,
const JpegDecoderDataUnit &upperright,
const JpegDecoderDataUnit &left,
const JpegDecoderDataUnit ¢er,
const JpegDecoderDataUnit &right,
const JpegDecoderDataUnit &lowerleft,
const JpegDecoderDataUnit &lowercenter,
const JpegDecoderDataUnit &lowerright)
{
const unsigned int LAST = JPEGSAMPLEWIDTH - 1 ;
unsigned int offset = 0 ;
// Upper Right Corner
FilterCorner (hperiod + 1, vperiod + 1,
&startposition [offset], rowwidth,
upperleft [LAST][LAST], uppercenter [LAST][0],
left [0][LAST], center [0][0],
hperiod, vperiod) ;
offset += hperiod /2 ;
// Top Edges
for (unsigned int ii = 0 ; ii < LAST ; ++ ii)
{
FilterTopOrBottom (vperiod + 1,
&startposition [offset], rowwidth,
uppercenter [LAST][ii], uppercenter [LAST][ii + 1],
center [0][ii], center [0][ii + 1],
hperiod, vperiod) ;
offset += hperiod ;
}
// Upper Left Corner
FilterCorner (1, vperiod + 1,
&startposition [offset], rowwidth,
uppercenter [LAST][LAST], upperright [LAST][0],
center [0][LAST], right [0][0],
hperiod, vperiod) ;
offset += (hperiod + vperiod * rowwidth) /2 - JPEGSAMPLEWIDTH * hperiod ;
ASSERT (offset == rowwidth * vperiod / 2) ;
for (unsigned int mcurow = 0 ; mcurow < LAST ; ++ mcurow)
{
// Left Edge
FilterSide (hperiod + 1,
&startposition [offset], rowwidth,
left [mcurow][LAST], center [mcurow][0],
left [mcurow +1][LAST], center [mcurow + 1][0],
hperiod, vperiod) ;
offset += hperiod / 2 ;
// Middle
for (unsigned int mcucol = 0 ; mcucol < LAST ; ++ mcucol)
{
FilterMiddle (&startposition [offset], rowwidth,
center [mcurow][mcucol], center [mcurow][mcucol + 1],
center [mcurow + 1][mcucol], center [mcurow + 1][mcucol + 1],
hperiod, vperiod) ;
offset += hperiod ;
}
// Right Edge
FilterSide (1,
&startposition [offset], rowwidth,
center [mcurow][LAST], right [mcurow][0],
center [mcurow + 1][LAST], right [mcurow + 1][0],
hperiod, vperiod) ;
offset += (hperiod / 2 + vperiod * rowwidth) - JPEGSAMPLEWIDTH * hperiod ;
}
// Bottom Left Corner
FilterCorner (hperiod + 1, 1,
&startposition [offset], rowwidth,
left [LAST][LAST], center [LAST][0],
lowerleft [0][LAST], lowercenter [0][0],
hperiod, vperiod) ;
offset += hperiod / 2 ;
// Bottom Edge
BILLSELLSPOOP
for (unsigned int ii = 0 ; ii < LAST ; ++ ii)
{
FilterTopOrBottom (1,
&startposition [offset], rowwidth,
center [LAST][ii], center [LAST][ii + 1],
lowercenter [0][ii], lowercenter [0][ii + 1],
hperiod, vperiod) ;
offset += hperiod ;
}
ENDBILLSELLSPOOP
// Bottom Right Corner
FilterCorner (1, 1,
&startposition [offset], rowwidth,
center [LAST][LAST], right [LAST][0],
lowercenter [0][LAST], lowerright [0][0],
hperiod, vperiod) ;
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -