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

📄 encoder.cpp

📁 这是我刚刚完成的关于JPEG2000的C语言实现的部分程序。小波变换是采用97变换
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************Description:   Implements the functionality offered by the "kdu_encoder" object definedin "kdu_sample_processing.h".  Includes quantization, subband sample bufferingand geometric appearance transformations.******************************************************************************/#include <math.h>#include <string.h>#include "kdu_messaging.h"#include "kdu_compressed.h"#include "kdu_sample_processing.h"#include "kdu_block_coding.h"#include "kdu_kernels.h"#include "kdu_roi_processing.h"/* ========================================================================= *//*                      Class and Structure Definitions                      *//* ========================================================================= *//*****************************************************************************//*                                kd_encoder                                 *//*****************************************************************************/class kd_encoder : public kdu_push_ifc_base {  public: // Member functions    kd_encoder(kdu_subband band, kdu_sample_allocator *allocator,               bool use_shorts, float normalization, kdu_roi_node *roi);  protected: // These functions implement their namesakes in the base class    virtual ~kd_encoder();    virtual void push(kdu_line_buf &line, bool allow_exchange);  private: // Internal implementation    void encode_row_of_blocks();      /* Called whenever `push' fills the line buffer. */  private: // Data    kdu_block_encoder block_encoder;    kdu_subband band;    int K_max; // Maximum magnitude bit-planes, exclucing ROI shift    int K_max_prime; // Maximum magnitude bit-planes, including ROI shift    bool reversible;    float delta; // For irreversible compression only.    float msb_wmse; // Normalized weighted MSE associated with first mag bit    float roi_weight; // Multiply `msb_wmse' by this for ROI foreground blocks    kdu_dims block_indices; // Range of block indices not yet written.    int subband_rows, subband_cols;    int nominal_block_height;    int current_block_height;    int next_buffered_row; // When reaches `current_block_height' encode blocks    kdu_sample_allocator *allocator;    kdu_roi_node *roi_node;    bool initialized; // True once line buffers allocated in first `push' call    kdu_sample16 **lines16; // NULL or array of `nominal_block_height' pointers    kdu_sample32 **lines32; // NULL or array of `nominal_block_height' pointers    kdu_byte **roi_lines; // NULL or array of `nominal_block_height' pointers  };  /* Notes:     Only one of the `lines16' and `lines32' members may be non-NULL, depending     on whether the transform will be pushing 16- or 32-bit sample values to     us.  The relevant array is pre-created during construction and actually     allocated from the single block of memory associated with the `allocator'     object during the first `push' call.  Similar considerations apply to     the `roi_lines' array, which is used only if `roi_source' is non-NULL. *//* ========================================================================= *//*                            Internal Functions                             *//* ========================================================================= *//*****************************************************************************//* STATIC                      find_missing_msbs                             *//*****************************************************************************/static int  find_missing_msbs(kdu_int32 *sp, int num_rows, int num_cols){  kdu_int32 or_val = 0;  int n;  for (n=num_rows*num_cols; n > 3; n -= 4)//64*64    { 
	  or_val |= *(sp++); 
	  or_val |= *(sp++);      or_val |= *(sp++);
	  or_val |= *(sp++);
  }  for (; n > 0; n--)    or_val |= *(sp++);   or_val &= KDU_INT32_MAX;  if (or_val == 0)    return 31;    int missing_msbs = 0;  for (or_val<<=1; or_val >= 0; or_val<<=1)    missing_msbs++;  return missing_msbs;}/* ========================================================================= *//*                                kdu_encoder                                *//* ========================================================================= *//*****************************************************************************//*                          kdu_encoder::kdu_encoder                         *//*****************************************************************************/kdu_encoder::kdu_encoder(kdu_subband band, kdu_sample_allocator *allocator,                         bool use_shorts, float normalization,                         kdu_roi_node *roi)  // In the future, we may create separate, optimized objects for each kernel.{  state = new kd_encoder(band,allocator,use_shorts,normalization,roi);}/* ========================================================================= *//*                               kd_encoder                                  *//* ========================================================================= *//*****************************************************************************//*                         kd_encoder::kd_encoder                            *//*****************************************************************************/kd_encoder::kd_encoder(kdu_subband band, kdu_sample_allocator *allocator,                       bool use_shorts, float normalization,                       kdu_roi_node *roi){  this->band = band;    K_max = band.get_K_max();  K_max_prime = band.get_K_max_prime();  reversible = band.get_reversible();  delta = band.get_delta() * normalization;  msb_wmse = band.get_msb_wmse();  roi_weight = 1.0F;  bool have_roi_weight = band.get_roi_weight(roi_weight);  kdu_dims dims;  band.get_dims(dims);  kdu_coords nominal_block_size, first_block_size;  band.get_block_size(nominal_block_size,first_block_size);  band.get_valid_blocks(block_indices);  subband_cols = dims.size.x;  subband_rows = dims.size.y;  nominal_block_height = nominal_block_size.y;  current_block_height = first_block_size.y;  next_buffered_row = 0;  roi_node = roi;  initialized = false;  lines16 = NULL;  lines32 = NULL;  roi_lines = NULL;  this->allocator = NULL;  if (!dims)    { subband_rows = 0; return; }  this->allocator = allocator;  allocator->pre_alloc(use_shorts,0,subband_cols,nominal_block_height);  if (use_shorts)    lines16 = new kdu_sample16 *[nominal_block_height];  else    lines32 = new kdu_sample32 *[nominal_block_height];  if (roi_node != NULL)    {      if ((K_max_prime == K_max) && !have_roi_weight)        {          roi_node->release();          roi_node = NULL;          return;        }      allocator->pre_alloc(true,0,(subband_cols+1)>>1,nominal_block_height);      roi_lines = new kdu_byte *[nominal_block_height];    }}/*****************************************************************************//*                        kd_encoder::~kd_encoder                            *//*****************************************************************************/kd_encoder::~kd_encoder(){  if (lines16 != NULL)    delete[] lines16;  else if (lines32 != NULL)    delete[] lines32;  if (roi_lines != NULL)    delete[] roi_lines;  if (roi_node != NULL)    roi_node->release();  if (subband_rows != 0)    { kdu_error e; e << "Terminating before block coding complete.  Expected "      << subband_rows << " additional subband rows from the DWT analysis "      "engine!"; }}/*****************************************************************************//*                             kd_encoder::push                              *//*****************************************************************************/void  kd_encoder::push(kdu_line_buf &line, bool allow_exchange){  if (line.get_width() == 0)    return;  assert(subband_rows > 0);  assert(next_buffered_row < current_block_height);  if (!initialized)    { // Allocate all lines -- they will be aligned and contiguous in memory.      int n;      if (lines16 != NULL)        for (n=0; n < nominal_block_height; n++)          lines16[n] = allocator->alloc16(0,subband_cols);      else        for (n=0; n < nominal_block_height; n++)          lines32[n] = allocator->alloc32(0,subband_cols);      if (roi_lines != NULL)        for (n=0; n < nominal_block_height; n++)          roi_lines[n] = (kdu_byte *)            allocator->alloc16(0,(subband_cols+1)>>1);      initialized = true;    }  // Transfer data  assert(line.get_width() == subband_cols);  if (lines32 != NULL)    memcpy(lines32[next_buffered_row],line.get_buf32(),           (size_t)(subband_cols<<2));  else    memcpy(lines16[next_buffered_row],line.get_buf16(),           (size_t)(subband_cols<<1));  if (roi_node != NULL)    roi_node->pull(roi_lines[next_buffered_row],subband_cols);  // Update the buffer state, flushing if necessary.  subband_rows--;  next_buffered_row++;  if (next_buffered_row == current_block_height)    encode_row_of_blocks();}/*****************************************************************************//*                     kd_encoder::encode_row_of_blocks                      *//*****************************************************************************/void  kd_encoder::encode_row_of_blocks(){  assert(next_buffered_row == current_block_height);  assert((current_block_height > 0) && (block_indices.size.y > 0));  int offset=0;  kdu_coords idx = block_indices.pos;  int blocks_remaining = block_indices.size.x;  kdu_coords xfer_size;  kdu_block *block;  kdu_uint16 estimated_slope_threshold =    band.get_conservative_slope_threshold();  for (; blocks_remaining > 0; blocks_remaining--,       idx.x++, offset+=xfer_size.x)    {      // Open the block and make sure we have enough sample buffer storage.

⌨️ 快捷键说明

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