📄 decoder.cpp
字号:
/*****************************************************************************/// File: decoder.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 functionality offered by the "kdu_decoder" object definedin "kdu_sample_processing.h". Includes ROI adjustments, dequantization,subband sample buffering and geometric appearance transformations.******************************************************************************/#include <string.h>#include <assert.h>#include "kdu_messaging.h"#include "kdu_compressed.h"#include "kdu_sample_processing.h"#include "kdu_block_coding.h"#include "kdu_kernels.h"/* ========================================================================= *//* Local Class and Structure Definitions *//* ========================================================================= *//*****************************************************************************//* kd_decoder *//*****************************************************************************/class kd_decoder : public kdu_pull_ifc_base { public: // Member functions kd_decoder(kdu_subband band, kdu_sample_allocator *allocator, bool use_shorts, float normalization); protected: // These functions implement their namesakes in the base class virtual ~kd_decoder(); virtual void pull(kdu_line_buf &line, bool allow_exchange); private: // Internal implementation void decode_row_of_blocks(); /* Called whenever `pull' encounters an empty line buffer. */ void adjust_roi_background(kdu_block *block); /* Shifts up background samples after a block has been decoded. */ private: // Data kdu_block_decoder block_decoder; kdu_subband band; int K_max; // Maximum magnitude bit-planes, excluding ROI upshift int K_max_prime; // Maximum magnitude bit-planes, including ROI upshift. bool reversible; float delta; // For irreversible compression only. kdu_dims block_indices; // Range of block indices not yet read. int subband_rows, subband_cols; int nominal_block_height; int current_block_height; int next_buffered_row; // If 0, the current row of blocks needs to be read kdu_sample_allocator *allocator; 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 }; /* Notes: Only one of the `lines16' and `lines32' members may be non-NULL, depending on whether the transform will be pulling 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 `pull' call. *//* ========================================================================= *//* kdu_decoder *//* ========================================================================= *//*****************************************************************************//* kdu_decoder::kdu_decoder *//*****************************************************************************/kdu_decoder::kdu_decoder(kdu_subband band, kdu_sample_allocator *allocator, bool use_shorts, float normalization) // In the future, we may create separate, optimized objects for each kernel.{ state = new kd_decoder(band,allocator,use_shorts,normalization);}/* ========================================================================= *//* kd_decoder *//* ========================================================================= *//*****************************************************************************//* kd_decoder::kd_decoder *//*****************************************************************************/kd_decoder::kd_decoder(kdu_subband band, kdu_sample_allocator *allocator, bool use_shorts, float normalization){ this->band = band; K_max = band.get_K_max(); K_max_prime = band.get_K_max_prime(); assert(K_max_prime >= K_max); reversible = band.get_reversible(); delta = band.get_delta() * normalization; 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; initialized = false; lines16 = NULL; lines32 = NULL; this->allocator = NULL; if (!dims) { subband_rows = 0; return; } this->allocator = allocator; allocator->pre_alloc(use_shorts,0,subband_cols+3,nominal_block_height); // Note the extra 3 samples, for hassle free quad-word transfers if (use_shorts) lines16 = new kdu_sample16 *[nominal_block_height]; else lines32 = new kdu_sample32 *[nominal_block_height];}/*****************************************************************************//* kd_decoder::~kd_decoder *//*****************************************************************************/kd_decoder::~kd_decoder(){ if (lines16 != NULL) delete[] lines16; else if (lines32 != NULL) delete[] lines32;}/*****************************************************************************//* kd_decoder::pull *//*****************************************************************************/void kd_decoder::pull(kdu_line_buf &line, bool allow_exchange){ if (line.get_width() == 0) return; 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); initialized = true; } if ((next_buffered_row == 0) || (next_buffered_row == current_block_height)) decode_row_of_blocks(); // Transfer data assert(line.get_width() == subband_cols); if (lines32 != NULL) memcpy(line.get_buf32(),lines32[next_buffered_row], (size_t)(subband_cols<<2)); else memcpy(line.get_buf16(),lines16[next_buffered_row], (size_t)(subband_cols<<1)); // Finally, update the line buffer management state. next_buffered_row++; subband_rows--;}/*****************************************************************************//* kd_decoder::decode_row_of_blocks *//*****************************************************************************/void kd_decoder::decode_row_of_blocks(){ if (next_buffered_row == current_block_height) { next_buffered_row = 0; current_block_height = nominal_block_height; if (current_block_height > subband_rows) current_block_height = subband_rows;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -