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

📄 deflateencoder.cpp

📁 Jpeg编解码器的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) 1997,1998,1999 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
//

//
//  Title:  Deflate Encoder Class Implementation
//
//  Author:  John M. Miano miano@colosseumbuilders.com
//
#include <climits>
#include <cstring>

#include "deflateencoder.h"
#include "deflatehuffmanencoder.h"
#include "adler32.h"
#include "deflatepvt.h"
#include "deflateoutputstream.h"
#include "checks.h"

using namespace ColosseumPrivate ;
using namespace std ;

namespace Colosseum
{

// Size definitions for the lookahead buffer.
const unsigned int LOOKAHEADSIZE = (1 << 9) ; 
const unsigned int LOOKAHEADMASK = LOOKAHEADSIZE - 1 ;

// Hash Table size definitions.
const unsigned int HASHBITS = 5 ;
const unsigned int HASHTABLESIZE = 1 << (3 * HASHBITS) ;

// End of stream marker for the lookahead buffer.
const unsigned int ENDSTREAM = 0xFFFF ;

namespace
{
//
//  Description:
//
//    This function advances a lookahead buffer index.
//
//  Parameter:
//
//    position : The index to advance (in/out)
//
inline void AdvanceLookaheadPosition (unsigned int &position)
{
  ++ position ;
  position &= LOOKAHEADMASK ;
  return ;
}

//
//  Description:
//
//    This function advances an LZ buffer index.
//
//  Parameter:
//
//    position : The index to advance (in/out)
//
inline void AdvanceWindowPosition (unsigned int &position)
{
  ++ position ;
  position &= DEFLATEWINDOWMASK ;
  return ;
}


//
//  Description:
//
//    This function converts an LZ window position and offset to
//    a position in the LZ window.
//
//  Parameters:
//
//    windowposition : The current position in the LZ Window
//    offset : The LZ window offset
//
//  Return Value:
//
//    The window position
//
inline unsigned int WindowOffsetToPosition (unsigned int windowposition, 
                                            unsigned int offset)
{
  unsigned int result = (DEFLATEWINDOWSIZE + windowposition - offset)
                        & DEFLATEWINDOWMASK ;
  return result ;
}

//
//  Description
//
//    This is the hash function used by compressor. It converts
//    a 3-byte sequence into an integer.
//
//  Parameters:
//
//    v1, v2, v3 : The 3-byte sequence to hash.
//    
//  Return Value:
//
//    The hash value in the range (0 .. HASHTABLESIZE - 1) 
//
inline unsigned int Hash (UBYTE1 v1, UBYTE1 v2, UBYTE1 v3)
{
  const unsigned int mask = (1 << HASHBITS) - 1 ;
  unsigned int value = (v1 & mask )
                     | ((v2 & mask) << HASHBITS)
                     | ((v3 & mask) << (2 * HASHBITS)) ;
  return value ;

}

//
//  Description:
// 
//    This function converts a distance value into a code, 
//    count of extra bits, and extra bits.
//
//  Parameters:
//
//    distance  : The distance value to convert
//    code      : The corresponding distance code
//    extra     : The number of extra bits
//    value     : The extra bit value
//
void DistanceToCode (unsigned int distance, unsigned int &code,
                            unsigned int &extra, unsigned int &value)
{
  // maxvalue [n] is the maximum distance value for the code n.
  static const unsigned int maxvalue [DEFLATEMAXDISTANCECODES] =
    {
         1,     2,     3,     4,     6,     8,    12,    16,    24,    32,
        48,    64,    96,   128,   192,   256,   384,   512,   768,  1024,
      1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576, 32768,
    } ;
  // extras [n] is the number of extra bits for the code n.
  static const unsigned int extras [DEFLATEMAXDISTANCECODES] =
    {
      0, 0,  0,  0,  1,  1,  2,  2,  3, 3,
      4, 4,  5,  5,  6,  6,  7,  7,  8, 8,
      9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
    } ;

  // bases [n] is the smallest distance value for code n.
  static const unsigned int bases [DEFLATEMAXDISTANCECODES] =
    {
         1,    2,    3,    4,    5,    7,    9,    13,    17,    25,
        33,   49,   65,   97,  129,  193,  257,   385,   513,   769,
      1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
    } ;

  for (code = 0 ; code < DEFLATEMAXDISTANCECODES ; ++ code)
  {
    if (distance <=  maxvalue [code])
      break ;
  }
  extra = extras [code] ;
  value = distance - bases [code] ;
  return ;
}
//
//  Description:
//
//    This function converts a length value to a length code, 
//    count of extra bits, and extra bit value.
//
//  Parameters:
//
//    length : The value to convert
//    code      : The corresponding length code
//    extra     : The number of extra bits
//    value     : The extra bit value
//
inline static void LengthToCode (unsigned int length, unsigned int &code,
                                 unsigned int &extra, unsigned int &value)
{
  ASSERT (length <= DEFLATELONGESTLENGTH) ;

  // codes [n] is the length for for length n - 3.
  static const UBYTE2 codes [DEFLATELONGESTLENGTH-2] =
    {
      257, 258, 259, 260, 261, 262, 263, 264,
      265, 265, 266, 266, 267, 267, 268, 268,
      269, 269, 269, 269, 270, 270, 270, 270,
      271, 271, 271, 271, 272, 272, 272, 272,
      273, 273, 273, 273, 273, 273, 273, 273,
      274, 274, 274, 274, 274, 274, 274, 274,
      275, 275, 275, 275, 275, 275, 275, 275,
      276, 276, 276, 276, 276, 276, 276, 276,
      277, 277, 277, 277, 277, 277, 277, 277,
      277, 277, 277, 277, 277, 277, 277, 277,
      278, 278, 278, 278, 278, 278, 278, 278,
      278, 278, 278, 278, 278, 278, 278, 278,
      279, 279, 279, 279, 279, 279, 279, 279,
      279, 279, 279, 279, 279, 279, 279, 279,
      280, 280, 280, 280, 280, 280, 280, 280,
      280, 280, 280, 280, 280, 280, 280, 280,
      281, 281, 281, 281, 281, 281, 281, 281,
      281, 281, 281, 281, 281, 281, 281, 281,
      281, 281, 281, 281, 281, 281, 281, 281,
      281, 281, 281, 281, 281, 281, 281, 281,
      282, 282, 282, 282, 282, 282, 282, 282,
      282, 282, 282, 282, 282, 282, 282, 282,
      282, 282, 282, 282, 282, 282, 282, 282,
      282, 282, 282, 282, 282, 282, 282, 282,
      283, 283, 283, 283, 283, 283, 283, 283,
      283, 283, 283, 283, 283, 283, 283, 283,
      283, 283, 283, 283, 283, 283, 283, 283,
      283, 283, 283, 283, 283, 283, 283, 283,
      284, 284, 284, 284, 284, 284, 284, 284,
      284, 284, 284, 284, 284, 284, 284, 284,
      284, 284, 284, 284, 284, 284, 284, 284,
      284, 284, 284, 284, 284, 284, 284, 285,
    } ;

  // extras [n] is the number of extra bits for code n.
  static const UBYTE1 extras [DEFLATEMAXLENGTHCODES - DEFLATEFIRSTLENGTHCODE] =
    {
      0, 0, 0, 0, 0, 0, 0, 0,
      1, 1, 1, 1, 2, 2, 2, 2,
      3, 3, 3, 3, 4, 4, 4, 4,
      5, 5, 5, 5, 0,
    } ;
  static const UBYTE2 basevalues [DEFLATEMAXLENGTHCODES - DEFLATEFIRSTLENGTHCODE] =
    {
        3,   4,   5,   6,   7,   8,   9,  10,
       11,  13,  15,  17,  19,  23,  27,  31,
       35,  43,  51,  59,  67,  83,  99, 115,
      131, 163, 195, 227, 258,
    } ;

  code = codes [length - 3] ;
  extra = extras [code - DEFLATEFIRSTLENGTHCODE] ;
  value = length - basevalues [code - DEFLATEFIRSTLENGTHCODE] ;
  return ;
}

} // End Namespace

//
//  Description:
//
//    Class Default Constructor
//
DeflateEncoder::DeflateEncoder ()
: compression_level (DEFAULTCOMPRESSION),
  lz_window (0),
  lookahead_buffer (0),
  block_buffer (0),
  block_buffer_size (0x4000),
  distance_table (DEFLATEMAXDISTANCECODES),
  length_table (DEFLATEMAXLENGTHCODES),
  length_length_table (DEFLATEMAXLENGTHLENGTHCODES),
  compression_in_progress (false)
{
  return ;
}

//
//  Description:
//
//    Class Destructor
//
DeflateEncoder::~DeflateEncoder ()
{
  freeBuffers () ;
  return ;
}


//
//  Description:
//
//    This function frees the buffers allocated during the encoding
//    process.
//
void DeflateEncoder::freeBuffers ()
{
  delete [] lz_window ; lz_window = 0 ;
  delete [] lookahead_buffer ; lookahead_buffer = 0 ;
  delete [] hash_values ; hash_values = 0 ;
  delete [] hash_table ; hash_table = 0 ;
  delete [] block_buffer ; block_buffer = 0 ;
  return ;
}

//
//  Description:
//
//    This function returns the current block size setting.
//
//  Return Value:
//
//    The current block size.
//
unsigned long DeflateEncoder::getBlockSize () const
{
  return block_buffer_size ;
}

//
//  Description:
//
//    This function sets the block buffer size. 
//
//  Parameters:
//
//    value : The new block buffer size
//
//  Restrictions:
//
//    This function may not be called when compression is underway.
//
void DeflateEncoder::setBlockSize (unsigned long value)
{
  if (compression_in_progress)
    throw DeflateError ("Compression In Progress") ;

  if (value < 500)
    block_buffer_size = 500 ;
  else
    block_buffer_size = value ;
  return ;
}

//
//  Description:
//
//    This function sets the compression level used.  The compression level
//    determines the depth to which hash chains are searched.
//
//  Parameters:
//
//    value:  The new compression level
//
//  Restrictions:
//
//    This function may be called when compression is underway, but
//    it has no effect for the current compression operation.
//
void DeflateEncoder::setCompressionLevel (
                          DeflateEncoder::CompressionLevel value)
{
  if (value < 0 || value > 3)
    throw DeflateError ("Invalid Compression Level") ;

  compression_level = value ;
  return ;
}

//
//  Description:
//
//    The function returns the current compression level.
//
//  Return Value:
//
//    The compresion level.
//
DeflateEncoder::CompressionLevel DeflateEncoder::getCompressionLevel () const
{
  return compression_level ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -