📄 compressed.cpp
字号:
/*****************************************************************************/// 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 + -