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

📄 compressed.cpp

📁 JPEG2000压缩解压图像源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************/// File: compressed.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 most of the compressed data management machinery which fitslogically between actual code-stream I/O (see "codestream.cpp") and individualcode-block processing (see "blocks.cpp").  Includes the machinery forgenerating, tearing down and re-entering tiles, tile-components, resolutions,subbands and precincts.******************************************************************************/#include <string.h>#include <limits.h>#include <assert.h>#include "kdu_elementary.h"#include "kdu_messaging.h"#include "kdu_utils.h"#include "kdu_kernels.h"#include "kdu_compressed.h"#include "compressed_local.h"/* ========================================================================= *//*                             Internal Functions                            *//* ========================================================================= *//*****************************************************************************//* STATIC                         get_band_dims                              *//*****************************************************************************/static kdu_dims  get_band_dims(kdu_dims res_dims, kdu_coords band_idx,                int low_extend=0, int high_extend=0)  /* Converts a region in the containing resolution level into a region     in an individual subband, given the suband indices (1 for high-pass,     0 for low-pass).  The `low_extend' and `high_extend' values are     used to extend the region in the resolution level before reducing     it to a subband region, where `low_extend' is used for low-pass     subbands and `high_extend' is used for high-pass subbands.  This is     useful for taking into account the spatial support of the synthesis     kernels when mapping regions of interest into subbands. */{  kdu_coords min = res_dims.pos;  kdu_coords lim = min + res_dims.size;  min.x -= (band_idx.x)?high_extend:low_extend;  min.y -= (band_idx.y)?high_extend:low_extend;  lim.x += (band_idx.x)?high_extend:low_extend;  lim.y += (band_idx.y)?high_extend:low_extend;  min.x = (min.x + 1 - band_idx.x) >> 1;  lim.x = (lim.x + 1 - band_idx.x) >> 1;  min.y = (min.y + 1 - band_idx.y) >> 1;  lim.y = (lim.y + 1 - band_idx.y) >> 1;  kdu_dims result;  result.pos = min; result.size = lim-min;    return result;}/*****************************************************************************//* STATIC                   get_partition_indices                            *//*****************************************************************************/static kdu_dims  get_partition_indices(kdu_dims partition, kdu_dims region)  /* Returns the range of indices for elements in the supplied partition,     which intersect with the supplied region. The `pos' field of the     partition identifies the coordinates of the upper left hand corner     of the first element in the partition, having indices (0,0), while the     `size' field indicates the dimensions of the partition elements.     Intersecting partitions with regions is a common function in JPEG2000. */{  kdu_coords min = region.pos - partition.pos;  kdu_coords lim = min + region.size;  min.x = floor_ratio(min.x,partition.size.x);  lim.x = ceil_ratio(lim.x,partition.size.x);  min.y = floor_ratio(min.y,partition.size.y);  lim.y = ceil_ratio(lim.y,partition.size.y);  if (region.size.x == 0) lim.x = min.x;  if (region.size.y == 0) lim.y = min.y;  kdu_dims indices;  indices.pos = min;  indices.size = lim-min;  return indices;}/*****************************************************************************//* STATIC                        is_power_2                                  *//*****************************************************************************/static bool  is_power_2(int val){  for (; val > 1; val >>= 1)    if (val & 1)      return false;    return (val==1);}/*****************************************************************************//* STATIC                   check_coding_partition                           *//*****************************************************************************/static void  check_coding_partition(kdu_dims partition)  /* Coding partitions (namely, code-block and precinct partitions) must have     exact power-of-2 dimensions and origins equal to 0 or 1. */{  if ((partition.pos.x != (partition.pos.x & 1)) ||      (partition.pos.y != (partition.pos.y & 1)))    { kdu_error e; e << "Coding partitions (code-blocks and precinct "      "partitions) must have origin coordinates equal to 1 or 0 only!"; }  if (!(is_power_2(partition.size.x) && is_power_2(partition.size.y)))    { kdu_error e; e << "Coding partitions (namely, code-block and precinct "      "partitions) must have exact power-of-2 dimensions!"; }}/*****************************************************************************//* INLINE                        compare_sop_num                             *//*****************************************************************************/static inline int  compare_sop_num(int sop_num, int packet_num)  /* Compares a true packet sequence number with the 16-bit sequence     number found in an SOP marker segment.  The SOP number is the least     significant 16 bits of the real packet sequence number, so the function     returns 0 (equal) if and only if the least significant 16 bits of     `packet_num' are identical to the value in `sop_num'.  Otherwise, the     function returns the expected number of packets between the one     identified by `packet_num' and that identified by `sop_num'.  The     return value is positive if `sop_num' is deemed to refer to a packet     following that identified by `packet_num', taking into account the     fact that `sop_num' contains only the least significant 16 bits of     the sequence number. */{  assert((sop_num >= 0) && (sop_num < (1<<16)));  int diff = sop_num - packet_num;  if ((diff & 0x0000FFFF) == 0)    return 0;  if ((diff > 0) || ((diff & 0x0000FFFF) <= (1<<15)))    return diff; // `sop_num' deemed to be greater than `packet_num'.  else    return diff-(1<<16); // `sop_num' deemed to be less than `packet_num'.}/* ========================================================================= *//*                                    kd_tile                                *//* ========================================================================= *//*****************************************************************************//*                              kd_tile::kd_tile                             *//*****************************************************************************/kd_tile::kd_tile(kd_codestream *codestream, int tnum){  this->codestream = codestream;  codestream->var_structure_new(sizeof(*this));  this->tnum = tnum;  int y_idx = tnum / codestream->num_tiles.x;  assert((y_idx >= 0) && (y_idx < codestream->num_tiles.y));  int x_idx = tnum - y_idx*codestream->num_tiles.x;  dims = codestream->tile_partition;  dims.pos.x += x_idx*dims.size.x;  dims.pos.y += y_idx*dims.size.y;  dims &= codestream->canvas;  region = dims;  initialized = false;  exhausted = false;  is_open = false;  closed = false;  packed_headers = NULL;  sequencer = NULL;  comps = NULL;}/*****************************************************************************//*                             kd_tile::~kd_tile                             *//*****************************************************************************/kd_tile::~kd_tile(){  codestream->var_structure_delete(sizeof(*this));  if ((codestream->in != NULL) && initialized && !exhausted)    finished_reading();  if (packed_headers != NULL)    delete packed_headers;  if (codestream->textualize_out != NULL)    {      std::ostream &out = *codestream->textualize_out;      codestream->siz->textualize_attributes(out,tnum,tnum);      out.flush();    }  kdu_params *csp;  int cluster = 1;  while ((csp=codestream->siz->access_cluster(cluster++)) != NULL)    if ((csp=csp->access_relation(tnum,-1)) != NULL)      delete csp;  if (sequencer != NULL)    delete sequencer;  if (comps != NULL)    delete[] comps;  assert(codestream->tile_refs[tnum] == this);  codestream->tile_refs[tnum] = KD_EXPIRED_TILE;}/*****************************************************************************//*                            kd_tile::initialize                            *//*****************************************************************************/void  kd_tile::initialize(){  bool read_failure = false;  num_components = codestream->num_components;  next_tpart = num_tparts = 0;  if (codestream->in != NULL)    read_failure = !read_tile_part_header();  kdu_params *cod = codestream->siz->access_cluster(COD_params);  assert(cod != NULL); cod = cod->access_relation(tnum,-1);  kdu_params *qcd = codestream->siz->access_cluster(QCD_params);  assert(qcd != NULL); qcd = qcd->access_relation(tnum,-1);  kdu_params *rgn = codestream->siz->access_cluster(RGN_params);  assert(rgn != NULL); rgn = rgn->access_relation(tnum,-1);  // Get tile-wide COD parameters.  if (!(cod->get(Cuse_sop,0,0,use_sop) &&        cod->get(Cuse_eph,0,0,use_eph) &&        cod->get(Cycc,0,0,use_ycc) &&        cod->get(Calign_blk_last,0,0,coding_origin.y) &&        cod->get(Calign_blk_last,0,1,coding_origin.x) &&        cod->get(Clayers,0,0,num_layers)))    assert(0);  if (num_layers > codestream->max_tile_layers)    codestream->max_tile_layers = num_layers;  // Initialize appearance parameters  num_apparent_components = num_components;  first_apparent_component = 0;  num_apparent_layers = num_layers;  // Build tile-components.  int c;  kd_tile_comp *tc =    comps = new kd_tile_comp[num_components];  codestream->var_structure_new(sizeof(kd_tile_comp)*num_components);  this->total_precincts = 0;  for (c=0; c < num_components; c++, tc++)    {      kdu_coords subs, min, lim;      tc->codestream = codestream;      tc->tile = this;      tc->cnum = c;      tc->sub_sampling = subs = codestream->sub_sampling[c];      min = dims.pos; lim = min + dims.size;      min.x = ceil_ratio(min.x,subs.x); lim.x = ceil_ratio(lim.x,subs.x);      min.y = ceil_ratio(min.y,subs.y); lim.y = ceil_ratio(lim.y,subs.y);      tc->dims.pos = min; tc->dims.size = lim - min;      tc->region = tc->dims;            kdu_params *coc = cod->access_relation(tnum,c);      kdu_params *qcc = qcd->access_relation(tnum,c);      kdu_params *rgc = rgn->access_relation(tnum,c);      assert((coc != NULL) && (qcc != NULL) && (rgc != NULL));      bool use_precincts;      bool derived_quant;      float base_delta = 0.0F;      if (!(coc->get(Clevels,0,0,tc->dwt_levels) &&            coc->get(Creversible,0,0,tc->reversible) &&            coc->get(Ckernels,0,0,tc->kernel_id) &&            coc->get(Cuse_precincts,0,0,use_precincts) &&            coc->get(Cblk,0,0,tc->blk.y) &&            coc->get(Cblk,0,1,tc->blk.x) &&            coc->get(Cmodes,0,0,tc->modes)))        assert(0);      if ((!tc->reversible) &&          !(qcc->get(Qderived,0,0,derived_quant) &&            ((!derived_quant) || qcc->get(Qabs_steps,0,0,base_delta))))        assert(0);      int roi_levels;      if ((codestream->out == NULL) || !rgc->get(Rlevels,0,0,roi_levels))        roi_levels = 0;      tc->apparent_dwt_levels = tc->dwt_levels;      if (tc->reversible)        tc->recommended_extra_bits = 4 + ((use_ycc)?1:0);      else        tc->recommended_extra_bits = 7;      // Create a DWT kernels object to recover energy weights.      kdu_kernels kernels(tc->kernel_id,tc->reversible);      // Now build the resolution level structure.      int r;

⌨️ 快捷键说明

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