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

📄 blocks.cpp

📁 JPEG2000的C++实现代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/// File: blocks.cpp [scope = CORESYS/COMPRESSED]// 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 a part of the compressed data management machinery, inrelation to code-blocks.  Includes packet header parsing and construction.Note that the internal representation employed for code-block stateinformation has been carefully paired down to a point where it would bedifficult to implement packet operations with substantially lessmemory.******************************************************************************/#include <string.h>#include <assert.h>#include "kdu_elementary.h"#include "kdu_messaging.h"#include "kdu_compressed.h"#include "compressed_local.h"/* ========================================================================= *//*                                kdu_block                                  *//* ========================================================================= *//*****************************************************************************//*                          kdu_block::kdu_block                             *//*****************************************************************************/kdu_block::kdu_block(){  transpose = vflip = hflip = false;  pass_lengths = NULL; pass_slopes = NULL; max_passes = 0;  byte_buffer = NULL;  max_bytes = 0;  sample_buffer = NULL; max_samples = 0;  context_buffer = NULL; max_contexts = 0;  cpu_iterations = 0;  cpu_time = 0;  cpu_unique_samples = 0;  resilient = fussy = false;}/*****************************************************************************//*                          kdu_block::~kdu_block                            *//*****************************************************************************/kdu_block::~kdu_block(){  if (pass_lengths != NULL)    delete[] pass_lengths;  if (pass_slopes != NULL)    delete[] pass_slopes;  if (byte_buffer != NULL)    delete[] (byte_buffer-1);  if (sample_buffer != NULL)    delete[] sample_buffer;  if (context_buffer != NULL)    delete[] context_buffer;}/*****************************************************************************//*                        kdu_block::set_max_passes                          *//*****************************************************************************/void  kdu_block::set_max_passes(int new_passes, bool copy_existing){  if (max_passes >= new_passes)    return;  if (max_passes == 0)    copy_existing = false;  if (copy_existing)    {      int *new_pass_lengths = new int[new_passes];      kdu_uint16 *new_pass_slopes = new kdu_uint16[new_passes];      for (int n=0; n < max_passes; n++)        {          new_pass_lengths[n] = pass_lengths[n];          new_pass_slopes[n] = pass_slopes[n];        }      delete[] pass_lengths;      delete[] pass_slopes;      pass_lengths = new_pass_lengths;      pass_slopes = new_pass_slopes;    }  else    {      if (pass_lengths != NULL)        delete[] pass_lengths;      if (pass_slopes != NULL)        delete[] pass_slopes;      pass_lengths = new int[new_passes];      pass_slopes = new kdu_uint16[new_passes];    }  max_passes = new_passes;}/*****************************************************************************//*                        kdu_block::set_max_bytes                           *//*****************************************************************************/void  kdu_block::set_max_bytes(int new_bytes, bool copy_existing){  if (max_bytes >= new_bytes)    return;  if (max_bytes == 0)    copy_existing = false;  if (copy_existing)    {      kdu_byte *new_buf = (new kdu_byte[new_bytes+1])+1;      memcpy(new_buf,byte_buffer,max_bytes);      delete[] (byte_buffer-1);      byte_buffer = new_buf;    }  else    {      if (byte_buffer != NULL)        delete[] (byte_buffer-1);      byte_buffer = (new kdu_byte[new_bytes+1])+1;    }  max_bytes = new_bytes;}/*****************************************************************************//*                        kdu_block::set_max_samples                         *//*****************************************************************************/void  kdu_block::set_max_samples(int new_samples){  if (max_samples >= new_samples)    return;  if (sample_buffer != NULL)    delete[] sample_buffer;  sample_buffer = new kdu_int32[new_samples];  max_samples = new_samples;}/*****************************************************************************//*                       kdu_block::set_max_contexts                         *//*****************************************************************************/void  kdu_block::set_max_contexts(int new_contexts){  if (max_contexts >= new_contexts)    return;  if (context_buffer != NULL)    delete[] context_buffer;  context_buffer = new kdu_int32[new_contexts];  max_contexts = new_contexts;}/* ========================================================================= *//*                                  kd_block                                 *//* ========================================================================= *//*****************************************************************************//*                             kd_block::cleanup                             *//*****************************************************************************/void  kd_block::cleanup(kd_precinct_band *pband){  kd_codestream *codestream = pband->subband->codestream;  kd_code_buffer *tmp;  while ((tmp=first_buf) != NULL)    {      first_buf = tmp->next;      codestream->buf_server->release(tmp);    }}/*****************************************************************************//*                       kd_block::parse_packet_header                       *//*****************************************************************************/int  kd_block::parse_packet_header(kd_header_in &head,                                 kd_buf_server *buf_server,                                 int layer_idx){  // Parse inclusion information first.  temp_length = 0;  if (beta == 0)    { // Not yet included. Tag tree decoding for `layer_w'.      assert(layer_wbar == layer_w);      kd_block *scan, *prev, *next;      // Walk up to the root node in the tree.      scan=this; prev=NULL;      while ((next=scan->up_down) != NULL)        { scan->up_down=prev; prev=scan; scan=next; }      scan->up_down = prev;      // Walk back down the tree, performing the decoding steps.      kdu_uint16 wbar_min = 0;      kdu_uint16 threshold = (kdu_uint16)(layer_idx+1);      prev = NULL;      while (scan != NULL)        {          if (scan->layer_wbar < wbar_min)            { scan->layer_wbar = wbar_min; scan->layer_w = wbar_min; }          while ((scan->layer_w == scan->layer_wbar) &&                 (scan->layer_wbar < threshold))            {              scan->layer_wbar++;              if (head.get_bit() == 0)                scan->layer_w++;            }          wbar_min = scan->layer_w;          next=scan->up_down; scan->up_down=prev; prev=scan; scan=next;        }      if (layer_wbar == layer_w)        return 0; // Nothing included yet.      if (layer_w != (kdu_uint16) layer_idx)        throw KDU_EXCEPTION_ILLEGAL_LAYER;    }  else    { // Already included.      if (head.get_bit() == 0)        return 0;    }  // If we get here, the code-block does contribute to the current layer.  bool discard_block = (num_passes == 255);  if (beta == 0)    { // First time contribution.  Need to get MSB's and set up buffering.      while (msbs_w == msbs_wbar)        { // Run tag tree decoder.          kd_block *scan, *prev, *next;          // Walk up to the root note in the tree.          scan=this; prev=NULL;          while ((next=scan->up_down) != NULL)            { scan->up_down=prev; prev=scan; scan=next; }          scan->up_down = prev;          // Walk back down the tree, performing the decoding steps.          kdu_byte wbar_min = 0;          kdu_byte threshold = msbs_wbar+1;          prev = NULL;          while (scan != NULL)            {              if (scan->msbs_wbar < wbar_min)                { scan->msbs_wbar = wbar_min; scan->msbs_w = wbar_min; }              while ((scan->msbs_w == scan->msbs_wbar) &&                     (scan->msbs_wbar < threshold))                {                  scan->msbs_wbar++;                  if (head.get_bit() == 0)                    scan->msbs_w++;                }              wbar_min = scan->msbs_w;              next=scan->up_down; scan->up_down=prev; prev=scan; scan=next;            }        }      num_bytes = 0;      beta = 3;      assert(pass_idx == 0);      if (!discard_block)        start_buffering(buf_server);    }  if (!discard_block)    { // Record the layer index for this new contribution.      put_byte((kdu_byte)(layer_idx>>8),buf_server);      put_byte((kdu_byte) layer_idx,buf_server);    }  // Decode number of passes.  int new_passes = 1;  new_passes += head.get_bit();  if (new_passes >= 2)    {      new_passes += head.get_bit();      if (new_passes >= 3)        {          new_passes += head.get_bits(2);          if (new_passes >= 6)            {              new_passes += head.get_bits(5);              if (new_passes >= 37)                new_passes += head.get_bits(7);            }        }    }  // Finally, decode the length information.  while (head.get_bit())    {      if (beta == 255)        throw KDU_EXCEPTION_PRECISION;      beta++;    }  bool bypass_term = ((((int) modes) & Cmodes_BYPASS) != 0);  bool all_term = ((((int) modes) & Cmodes_RESTART) != 0);  if (all_term)    bypass_term = false;  int segment_passes, segment_bytes;  int length_bits;  int idx = pass_idx;  while (new_passes > 0)    {      if (all_term)        segment_passes = 1;      else if (bypass_term)        {          if (idx < 10)            segment_passes = 10-idx;          else if (((idx-10) % 3) == 0)            segment_passes = 2;          else            segment_passes = 1;          if (segment_passes > new_passes)            segment_passes = new_passes;        }      else        segment_passes = new_passes;      for (length_bits=0; (1<<length_bits) <= segment_passes; length_bits++);      length_bits--;      length_bits += beta;      segment_bytes = head.get_bits(length_bits);      if ((segment_bytes >= (1<<15)) ||          (segment_bytes >= ((1<<16) - (int) temp_length)))        throw KDU_EXCEPTION_PRECISION;      temp_length += segment_bytes;      idx += segment_passes;      new_passes -= segment_passes;      if (new_passes > 0)        segment_bytes |= (1<<15); // Continuation flag.      if (!discard_block)        { // Record the number of bytes and the number of passes in the segment          put_byte((kdu_byte)(segment_bytes>>8),buf_server);          put_byte((kdu_byte) segment_bytes,buf_server);          put_byte((kdu_byte) segment_passes,buf_server);        }    }  pass_idx = (kdu_byte) idx;  if (!discard_block)    num_passes = pass_idx;  return temp_length;}

⌨️ 快捷键说明

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