⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpgdecodercomponent.~cpp

📁 Jpeg编解码器的源代码
💻 ~CPP
📖 第 1 页 / 共 4 页
字号:
//
// 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 &center,
                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 + -