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

📄 roi.cpp

📁 JPEG2000的C++实现代码
💻 CPP
字号:
/*****************************************************************************/// File: roi.cpp [scope = CORESYS/ROI]// 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 core ROI processing functionality.  This includes thecapability to convert ROI masks at one resolution level into masks foreach of its subbands, in an efficient incremental manner.  It does notinclude any methods for supplying original ROI mask geometries, since thisis application dependent.  See the "kdu_compress" example application forone simple and one very powerful method for specifying ROI geometries.******************************************************************************/#include <assert.h>#include <string.h>#include "kdu_kernels.h"#include "roi_local.h"/* ========================================================================= *//*                             kdu_roi_level_node                            *//* ========================================================================= *//*****************************************************************************//*                    kd_roi_level_node::~kd_roi_level_node                  *//*****************************************************************************/kd_roi_level_node::~kd_roi_level_node(){  assert(!active); // Insist on acquired objects being released first.  if (row_buffers == NULL)    return;  for (int n=0; n < num_row_buffers; n++)    delete[] row_buffers[n];  delete[] row_buffers;}/*****************************************************************************//*                           kd_roi_level_node::pull                         *//*****************************************************************************/void  kd_roi_level_node::pull(kdu_byte buf[], int width){  assert(active && (width == cols) && (remaining_rows > 0));  while (num_valid_row_buffers == 0)    owner->advance();  memcpy(buf,row_buffers[first_valid_row_buffer],(size_t) width);  num_valid_row_buffers--;  first_valid_row_buffer++;  if (first_valid_row_buffer == num_row_buffers)    first_valid_row_buffer = 0;  remaining_rows--;}/*****************************************************************************//*                         kd_roi_level_node::advance                        *//*****************************************************************************/kdu_byte *  kd_roi_level_node::advance(){  if (!active)    {      available = false; // If not already acquired, client missed its chance.      return NULL;    }  assert(remaining_rows > num_valid_row_buffers);  if (num_valid_row_buffers == num_row_buffers)    { // Need to augment buffer.      int n, r1, r2, num_new_buffers = num_row_buffers + 2;      kdu_byte **new_buffers = new kdu_byte *[num_new_buffers];      memset(new_buffers,0,sizeof(kdu_byte *)*(size_t)num_new_buffers);      r1 = r2 = first_valid_row_buffer;      for (n=0; n < num_row_buffers; n++, r1++, r2++)        {          if (r1 == num_row_buffers)            r1 = 0;          if (r2 == num_new_buffers)            r2 = 0;          new_buffers[r2] = row_buffers[r1];        }      if (row_buffers == NULL)        delete[] row_buffers;      row_buffers = new_buffers;      num_row_buffers = num_new_buffers;      for (; n < num_new_buffers; n++, r2++)        {          if (r2 == num_new_buffers)            r2 = 0;          new_buffers[r2] = new kdu_byte[cols];        }    }  int r = num_valid_row_buffers + first_valid_row_buffer;  if (r >= num_row_buffers)    r -= num_row_buffers;  num_valid_row_buffers++;  return row_buffers[r];}/*****************************************************************************//*                         kd_roi_level_node::release                        *//*****************************************************************************/void  kd_roi_level_node::release(){  available = active = false;  owner->notify_release(this);}/* ========================================================================= *//*                               kdu_roi_level                               *//* ========================================================================= *//*****************************************************************************//*                            kdu_roi_level::create                          *//*****************************************************************************/void  kdu_roi_level::create(kdu_resolution res, kdu_roi_node *source){  state = new kd_roi_level();  try {    state->init(res,source);    }  catch(...) {      delete state;      state = NULL;      throw; // Rethrow the exception to be handled higher up the stack frame.    }}/*****************************************************************************//*                            kdu_roi_level::destroy                         *//*****************************************************************************/void  kdu_roi_level::destroy(){  if (state != NULL)    delete state;  state = NULL;}/*****************************************************************************//*                         kdu_roi_level::acquire_node                       *//*****************************************************************************/kdu_roi_node *  kdu_roi_level::acquire_node(int band_idx){  assert((band_idx >= 0) && (band_idx < 4));  state->nodes[band_idx]->acquire();  return state->nodes[band_idx];}/* ========================================================================= *//*                                kd_roi_level                               *//* ========================================================================= *//*****************************************************************************//*                         kd_roi_level::~kd_roi_level                       *//*****************************************************************************/kd_roi_level::~kd_roi_level(){  for (int b=0; b < 4; b++)    if (nodes[b] != NULL)      delete nodes[b];  if (row_buffers != NULL)    {      for (int n=0; n < num_row_buffers; n++)        if (row_buffers[n] != NULL)          delete[] row_buffers[n];      delete[] row_buffers;    }  if (out_buf != NULL)    delete[] out_buf;  if (source != NULL)    source->release();}/*****************************************************************************//*                              kd_roi_level::init                           *//*****************************************************************************/void  kd_roi_level::init(kdu_resolution res, kdu_roi_node *source){  this->source = source;  res.get_dims(dims);  for (int b=0; b < 4; b++)    {      kdu_dims node_dims;      if (b == LL_BAND)        res.access_next().get_dims(node_dims);      else        res.access_subband(b).get_dims(node_dims);      nodes[b] = new kd_roi_level_node(this,node_dims.size);      node_released[b] = false;    }  num_nodes_released = 0;  // Determine the synthesis kernel extents.    {       kdu_kernels kernels(res.get_kernel_id(),res.get_reversible());      kernels.get_impulse_response(KDU_SYNTHESIS_LOW,extent[0]);      kernels.get_impulse_response(KDU_SYNTHESIS_HIGH,extent[1]);    }  // Create the buffer.  num_row_buffers = 1+2*((extent[0] > extent[1])?extent[0]:extent[1]);  row_buffers = new kdu_byte *[num_row_buffers];  int n;  for (n=0; n < num_row_buffers; n++)    row_buffers[n] = NULL; // In case memory allocation fails later.  for (n=0; n < num_row_buffers; n++)    row_buffers[n] = new kdu_byte[dims.size.x];  out_buf = new kdu_byte[dims.size.x];  // Initialize state variables  first_buffer_idx = 0;  num_valid_rows = 0;  first_valid_row_loc = dims.pos.y;  next_row_loc = dims.pos.y;}/*****************************************************************************//*                            kd_roi_level::advance                          *//*****************************************************************************/void  kd_roi_level::advance()  /* Note: the processing performed here maps a region of interest into     each of the four subbands produced by a single stage of 2D DWT     processing.  For more information on the algorithmic details, the     reader is referred to Section 10.6.4 in the book by Taubman     and Marcellin. */{  assert(source != NULL);  kdu_coords lim = dims.pos + dims.size;  assert(next_row_loc < lim.y);  int r, min_row, max_row;  min_row = next_row_loc - extent[next_row_loc & 1];  max_row = next_row_loc + extent[next_row_loc & 1];  if (min_row < dims.pos.y)    min_row = dims.pos.y;  if (max_row >= lim.y)    max_row = lim.y-1;  while (max_row >= (first_valid_row_loc+num_valid_rows))    { // Load a new row.      r = first_buffer_idx+num_valid_rows;      if (r >= num_row_buffers)        r -= num_row_buffers;      source->pull(row_buffers[r],dims.size.x);      if (num_valid_rows == num_row_buffers)        {          first_buffer_idx++; first_valid_row_loc++;          if (first_buffer_idx == num_row_buffers)            first_buffer_idx = 0;        }      else        num_valid_rows++;    }  // Now for the vertical processing  int c;  kdu_byte *sp, *dp;  r = min_row - first_valid_row_loc + first_buffer_idx;  assert(r >= first_buffer_idx);  if (r >= num_row_buffers)    r -= num_row_buffers;  memcpy(out_buf,row_buffers[r],(size_t)(dims.size.x));  for (min_row++, r++; min_row <= max_row; min_row++, r++)    {      if (r == num_row_buffers)        r = 0;      for (sp=row_buffers[r], dp=out_buf, c=dims.size.x; c > 0; c--)        *(dp++) |= *(sp++);    }  // Finally, time for the horizontal processing  for (int band=0; band < 2; band++)    {      int node_idx = band+2*(next_row_loc&1);      if (node_released[node_idx])        continue;      kd_roi_level_node *node = nodes[node_idx];      dp = node->advance();      if (dp == NULL)        continue; // Node released but `notify_release' not called; never mind.      int ext = extent[band];      int left = (dims.pos.x + band) & 1; // Samples to left of current loc      int right = dims.size.x-left-1; // Samples to right of current loc      int width = 1 + (right>>1);      sp = out_buf+left;      kdu_byte val;      for (; (width > 0) && (left < ext);           width--, left+=2, right-=2, sp+=2, dp++)        { // Initial samples treated specially to deal with boundaries.          for (val=0, c=-left; (c <= ext) && (c <= right); c++)            val |= sp[c];          *dp = val;        }      for (; (width > 0) && (right >= ext);           width--, left+=2, right-=2, sp+=2, dp++)        {          for (val=0, c=-ext; c <= ext; c++)            val |= sp[c];          *dp = val;        }      for (; width > 0; width--, left+=2, right-=2, sp+=2, dp++)        {          for (val=0, c=-ext; c <= right; c++)            val |= sp[c];          *dp = val;        }    }  next_row_loc++;  if (num_nodes_released == 4)    {      source->release();      source = NULL;    }}/*****************************************************************************//*                        kd_roi_level::notify_release                       *//*****************************************************************************/void  kd_roi_level::notify_release(kd_roi_level_node *caller){  int n;  for (n=0; n < 4; n++)    if (nodes[n] == caller)      break;  assert((n < 4) && !node_released[n]);  node_released[n] = true;  num_nodes_released++;  if (num_nodes_released == 4)    {      source->release();      source = NULL;    }}

⌨️ 快捷键说明

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