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

📄 block_encoder.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************/// File: block_encoder.cpp [scope = CORESYS/CODING]// Version: Kakadu, V2.2// Author: David Taubman// Last Revised: 20 June, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001).  A brief summary// of the license appears below.  This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,//    Version 2.2, including distribution of one or more Applications built//    using the software, provided such distribution is not for financial//    return.// 2. The Licensee has the right to personal use of the Kakadu software,//    Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including//    source code and dynamically or statically linked libraries) to a Third//    Party, provided the Third Party possesses a license to use the Kakadu//    software, Version 2.2, and provided such distribution is not for//    financial return./******************************************************************************Description:   Implements the embedded block coding algorithm, including distortionestimation and R-D covex hull analysis, in addition to the codingpasses themselves.  The low level services offered by the MQ arithmetic coderappear in "mq_encoder.cpp" and "mq_encoder.h".******************************************************************************/#include <math.h>#include <string.h>#include <assert.h>#include "kdu_messaging.h"#include "kdu_block_coding.h"#include "block_coding_common.h"#include "mq_encoder.h"static kdu_byte *significance_luts[4] =  {lh_sig_lut, hl_sig_lut, lh_sig_lut, hh_sig_lut};#define DISTORTION_LSBS 5#define SIGNIFICANCE_DISTORTIONS (1<<DISTORTION_LSBS)#define REFINEMENT_DISTORTIONS (1<<(DISTORTION_LSBS+1))static kdu_int32 significance_distortion_lut[SIGNIFICANCE_DISTORTIONS];static kdu_int32 significance_distortion_lut_lossless[SIGNIFICANCE_DISTORTIONS];static kdu_int32 refinement_distortion_lut[REFINEMENT_DISTORTIONS];static kdu_int32 refinement_distortion_lut_lossless[REFINEMENT_DISTORTIONS];#define EXTRA_ENCODE_CWORDS 3 // Number of extra context-words between stripes.#define MAX_POSSIBLE_PASSES (31*3-2)/* ========================================================================= *//*                   Local Class and Structure Definitions                   *//* ========================================================================= *//*****************************************************************************//*                             kd_block_encoder                              *//*****************************************************************************/class kd_block_encoder : public kdu_block_encoder_base {  /* Although we can supply a constructor and a virtual destructor in the     future, we have no need for these for the moment. */  protected:    void encode(kdu_block *block, bool reversible, double msb_wmse,                kdu_uint16 estimated_slope_threshold);  private: // Internal implementation    void reset_states()      { // See Table 12.1 in the book by Taubman and Marcellin        for (int n=0; n < 18; n++)          states[n].init(0,0);        states[KAPPA_SIG_BASE].init(4,0);        states[KAPPA_RUN_BASE].init(3,0);      }  private: // Data    mqe_state states[18];  };/* ========================================================================= *//*            Initialization of Distortion Estimation Tables                 *//* ========================================================================= */static void initialize_significance_distortion_luts();static void initialize_refinement_distortion_luts();static class encoder_local_init {    public: encoder_local_init()              { initialize_significance_distortion_luts();                initialize_refinement_distortion_luts(); }  } _do_it;/*****************************************************************************//* STATIC          initialize_significance_distortion_luts                   *//*****************************************************************************/static void  initialize_significance_distortion_luts(){  double fp_scale = (double)(1<<16);  for (kdu_int32 n=0; n < SIGNIFICANCE_DISTORTIONS; n++)    {      kdu_int32 idx = n | (1<<DISTORTION_LSBS);      double v_tilde = ((double) idx) / ((double)(1<<DISTORTION_LSBS));      assert((v_tilde >= 1.0) && (v_tilde < 2.0));      double sqe_before = v_tilde*v_tilde;      double sqe_after = (v_tilde-1.5)*(v_tilde-1.5);      significance_distortion_lut[n] = (int)        floor(0.5 + fp_scale*(sqe_before-sqe_after));      significance_distortion_lut_lossless[n] = (int)        floor(0.5 + fp_scale*sqe_before);    }}/*****************************************************************************//* STATIC            initialize_refinement_distortion_luts                   *//*****************************************************************************/static void  initialize_refinement_distortion_luts(){  double fp_scale = (double)(1<<16);  for (kdu_int32 n=0; n < REFINEMENT_DISTORTIONS; n++)    {      double v_tilde = ((double) n) / ((double)(1<<DISTORTION_LSBS));      assert(v_tilde < 2.0);      double sqe_before = (v_tilde-1.0)*(v_tilde-1.0);      v_tilde = (n >> DISTORTION_LSBS)?(v_tilde-1.0):v_tilde;      assert((v_tilde >= 0.0) && (v_tilde < 1.0));      double sqe_after = (v_tilde-0.5)*(v_tilde-0.5);      refinement_distortion_lut[n] = (int)        floor(0.5 + fp_scale*(sqe_before-sqe_after));      refinement_distortion_lut_lossless[n] = (int)        floor(0.5 + fp_scale*sqe_before);    }}/* ========================================================================= *//*             Binding of MQ and Raw Symbol Coding Services                  *//* ========================================================================= */#define USE_FAST_MACROS // Comment this out if you want functions instead.#ifdef USE_FAST_MACROS#  define _mq_check_out_(coder)                                     \     register kdu_int32 A; register kdu_int32 C; register kdu_int32 t; \     kdu_int32 temp; kdu_byte *store;                                 \     coder.check_out(A,C,t,temp,store)#  define _mq_check_in_(coder)                                      \     coder.check_in(A,C,t,temp,store)#  define _mq_enc_(coder,symbol,state)                              \     _mq_encode_(symbol,state,A,C,t,temp,store)#  define _mq_enc_run_(coder,run)                                   \     _mq_encode_run_(run,A,C,t,temp,store)#  define _raw_check_out_(coder)                                    \     register kdu_int32 t; register kdu_int32 temp; kdu_byte *store;   \     coder.check_out(t,temp,store)#  define _raw_check_in_(coder)                                     \     coder.check_in(t,temp,store)#  define _raw_enc_(coder,symbol)                                   \     _raw_encode_(symbol,t,temp,store)#else // Do not use fast macros#  define _mq_check_out_(coder)#  define _mq_check_in_(coder)#  define _mq_enc_(coder,symbol,state) coder.mq_encode(symbol,state)#  define _mq_enc_run_(coder,run) coder.mq_encode_run(run)#  define _raw_check_out_(coder)#  define _raw_check_in_(coder)#  define _raw_enc_(coder,symbol) coder.raw_encode(symbol)#endif // USE_FAST_MACROS /* The coding pass functions defined below all return a 32-bit integer,    which represents the normalized reduction in MSE associated with the    coded symbols.  Specifically, the MSE whose reduction is returned is    equal to 2^16 * sum_i (x_i/2^p - x_i_hat/2^p)^2 where x_i denotes the    integer sample values in the `samples' array and x_i_hat denotes the    quantized representation available from the current coding pass and all    previous coding passes, assuming a mid-point reconstruction rule.       The mid-point reconstruction rule satisfies x_i_hat = (q_i+1/2)*Delta    where q_i denotes the quantization indices and Delta is the quantization    step size.  This rule is modified only if the `lossless_pass' argument is    true, which is permitted only when symbols coded in the coding pass    result in a lossless representation of the corresponding subband samples.    Of course, this can only happen in the last bit-plane when the reversible    compression path is being used.  In this case, the function uses the fact    that all coded symbols have 0 distortion.       It should be noted that the MSE reduction can be negative, meaning    that the coding of symbols actually increases distortion. *//* ========================================================================= *//*                           Coding pass functions                           *//* ========================================================================= *//*****************************************************************************//* STATIC                   encode_sig_prop_pass_raw                         *//*****************************************************************************/static kdu_int32  encode_sig_prop_pass_raw(mq_encoder &coder, int p, bool causal,                           kdu_int32 *samples, kdu_int32 *contexts,                           int width, int num_stripes, int context_row_gap,                           bool lossless_pass){  /* Ideally, register storage is available for 9 32-bit integers. Two     are declared inside the "_raw_check_out_" macro.  The order of priority     for these registers corresponds roughly to the order in which their     declarations appear below.  Unfortunately, none of these register     requests are likely to be honored by the register-starved X86 family     of processors, but the register declarations may prove useful to     compilers for other architectures or for hand optimizations of     assembly code. */  register kdu_int32 *cp = contexts;  register int c;  register kdu_int32 cword;  _raw_check_out_(coder); // Declares t and temp as registers.  register kdu_int32 sym;  register kdu_int32 val;  register kdu_int32 *sp = samples;  register kdu_int32 shift = 31-p; assert(shift > 0);  int r, width_by2=width+width, width_by3=width_by2+width;  kdu_int32 distortion_change = 0;  kdu_int32 *distortion_lut = significance_distortion_lut;  if (lossless_pass)    distortion_lut = significance_distortion_lut_lossless;  assert((context_row_gap - width) == EXTRA_ENCODE_CWORDS);  for (r=num_stripes; r > 0; r--, cp += EXTRA_ENCODE_CWORDS, sp += width_by3)    for (c=width; c > 0; c--, sp++, cp++)      {        if (*cp == 0)          continue;        cword = *cp;        if ((cword & (NBRHD_MASK<<0)) && !(cword & (SIG_PROP_MEMBER_MASK<<0)))          { // Process first row of stripe column (row 0)            val = sp[0]<<shift; // Move bit p to sign bit.            sym = (kdu_int32)(((kdu_uint32) val)>>31); // Move bit into LSB            _raw_enc_(coder,sym);            if (val >= 0) // New magnitude bit was 0, so still insignificant              { cword |= (PI_BIT<<0); goto row_1; }            // Compute distortion change            val =  (val>>(31-DISTORTION_LSBS)) & (SIGNIFICANCE_DISTORTIONS-1);            distortion_change += distortion_lut[val];            // Encode sign bit            sym = sp[0];            sym = (kdu_int32)(((kdu_uint32) sym)>>31); // Move sign into LSB            _raw_enc_(coder,sym);            // Broadcast neighbourhood context changes            if (!causal)              {                cp[-context_row_gap-1] |=(SIGMA_BR_BIT<<9);                cp[-context_row_gap  ] |=(SIGMA_BC_BIT<<9)|(sym<<NEXT_CHI_POS);                cp[-context_row_gap+1] |=(SIGMA_BL_BIT<<9);              }            cp[-1] |= (SIGMA_CR_BIT<<0);            cp[1]  |= (SIGMA_CL_BIT<<0);            cword |= (SIGMA_CC_BIT<<0) | (PI_BIT<<0) | (sym<<CHI_POS);          }row_1:        if ((cword & (NBRHD_MASK<<3)) && !(cword & (SIG_PROP_MEMBER_MASK<<3)))          { // Process second row of stripe column (row 1)            val = sp[width]<<shift; // Move bit p to sign bit.            sym = (kdu_int32)(((kdu_uint32) val)>>31); // Move bit into LSB            _raw_enc_(coder,sym);            if (val >= 0) // New magnitude bit was 0, so still insignificant              { cword |= (PI_BIT<<3); goto row_2; }

⌨️ 快捷键说明

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