📄 params.cpp
字号:
/*****************************************************************************/// File: params.cpp [scope = CORESYS/PARAMETERS]// Version: Kakadu, V2.2.3// Author: David Taubman// Last Revised: 27 July, 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 services defined by "kdu_params.h".******************************************************************************/#include <stdlib.h>#include <string.h>#include <math.h>#include <assert.h>#include "kdu_messaging.h"#include "kdu_utils.h"#include "kdu_params.h"#include "kdu_kernels.h"#include "kdu_compressed.h"#include "params_local.h"using namespace std;/* ========================================================================= *//* Initialization of static const class members *//* ========================================================================= */const int kdu_params::MULTI_RECORD=1;const int kdu_params::CAN_EXTRAPOLATE = 2;const int kdu_params::ALL_COMPONENTS=4;/* ========================================================================= *//* Internal Functions *//* ========================================================================= *//*****************************************************************************//* STATIC step_to_eps_mu *//*****************************************************************************/static void step_to_eps_mu(float val, int &eps, int &mu) /* Finds `eps' and `mu' such that `val' ~ 2^{-`eps'}*(1+2^{-11}`mu'). */{ if (val <= 0.0F) { kdu_error e; e << "Absolute quantization step sizes must be " "strictly positive."; } for (eps=0; val < 1.0F; eps++) val *= 2.0F; mu = (int) floor(0.5F+((val-1.0F)*(1<<11))); if (mu >= (1<<11)) { mu = 0; eps--; } if (eps > 31) { eps = 31; mu = 0; } if (eps < 0) { eps = 0; mu = (1<<11)-1; }}/*****************************************************************************//* STATIC find_lcm *//*****************************************************************************/static int find_lcm(int m, int n) /* Returns the LCM (Least Common Multiple) of the two supplied integers. Both must be strictly positive. */{ assert((m > 0) && (n > 0)); /* The idea is to remove all common factors of m and n from m and count them only once, in a `common_part'. */ int common_part = 1; int divisor = 2; for (; (divisor <= m) && (divisor <= n); divisor++) { while (((m % divisor) == 0) && ((n % divisor) == 0)) { common_part *= divisor; m /= divisor; n /= divisor; } } return m*n*common_part;}/*****************************************************************************//* STATIC parse_translator_entry *//*****************************************************************************/static char const * parse_translator_entry(char const *start, char separator, char buf[], int len, int &value) /* Attempts to parse a translator entry from the supplied string. Translator entries consist of a text string, followed by an '=' sign and an integer value. Successive entries are delimited by the character identified by `separator', which is normally either a comma or the '|' symbol. The function generates an error if a valid entry cannot be found. Otherwise, it places the string identifier in the supplied buffer and the value through the `value' reference, returning a pointer to the delimiting character. This delimiting character is either the separator itself, or one of the characters, ')' or ']'. Note that identifiers whose length exceeds `len'-1 will cause an error to be generated. */{ int i; for (i=0; i < len; i++) { if ((start[i] == separator) || (start[i] == ')') || (start[i] == ']') || (start[i] == '\0')) { kdu_error e; e << "String translators in code-stream attribute " "specifications must contain an '=' sign! Problem " "encountered at: \"" << start << "\"."; } else if (start[i] == '=') break; buf[i] = start[i]; } if (i == len) { kdu_error e; e << "String translators in code-stream attribute " "specifications may not exceed " << len-1 << " characters " "in length! Problem encountered at: \"" << start << "\"."; } buf[i] = '\0'; start += i+1; char *end_p; value = (int) strtol(start,&end_p,10); if ((end_p == start) || ((*end_p != separator) && (*end_p != ')') && (*end_p != ']'))) { kdu_error e; e << "String translators in code-stream attribute " "specifications must be identified with integers and correctly " "delimited! Problem encountered at: \"" << start << "\"."; } return(end_p);}/*****************************************************************************//* STATIC display_options *//*****************************************************************************/static void display_options(char const *pattern, ostream &stream){ char buf1[80], buf2[80], *bp, *obp, *last_bp; int val; bool multi_option; bp = buf1; obp = buf2; last_bp = NULL; multi_option = false; if (*pattern == '(') { stream << "Expect one of the identifiers, "; do { pattern = parse_translator_entry(pattern+1,',',bp,80,val); if (multi_option) stream << ", "; if (last_bp != NULL) { stream << "\"" << last_bp << "\""; multi_option = true; } last_bp = bp; bp = obp; obp = last_bp; } while (*pattern == ','); assert(*pattern == ')'); if (multi_option) stream << " or "; stream << "\"" << last_bp << "\"."; } else if (*pattern == '[') { stream << "Expect one or more of the identifiers, "; do { pattern = parse_translator_entry(pattern+1,'|',bp,80,val); if (multi_option) stream << ", "; if (last_bp != NULL) { stream << "\"" << last_bp << "\""; multi_option = true; } last_bp = bp; bp = obp; obp = last_bp; } while (*pattern == '|'); assert(*pattern == ']'); if (multi_option) stream << " or "; stream << "\"" << last_bp << "\", separated by `|' symbols."; } else assert(0);}/*****************************************************************************//* STATIC int2log *//*****************************************************************************/static int int2log(int val) /* Returns the integer exponent, e, such that 2^e=val. Returns -1 if such an integer does not exist. */{ int e; for (e=0; ((1<<e) > 0) && ((1<<e) < val); e++); if (val != (1<<e)) return 0; return e;}/*****************************************************************************//* STATIC synthesize_canvas_size *//*****************************************************************************/static bool synthesize_canvas_size(int components, int dims[], int origin, int &size) /* Determines a canvas size which is compatible with the supplied component component dimensions and image origin. Specifically, we must have dims[n] = ceil(size/subs[n])-ceil(origin/subs[n]) for each some set of valid component sub-sampling factors, subs[n]. If this is not possible within the constraint that sub-sampling factors are no greater than 255, the function returns false; otherwise, the function returns true, with the compatible size parameter in `size'. The function basically conducts an intelligent (but still somewhat tedious) search through the parameter space. */{ int ref_dim, ref_sub, n; for (ref_dim=dims[0], n=1; n < components; n++) if (dims[n] > ref_dim) ref_dim = dims[n]; for (ref_sub=1; ref_sub <= 255; ref_sub++) { // Reference component has largest dimension and smallest sub-sampling int max_size = (ceil_ratio(origin,ref_sub)+ref_dim)*ref_sub; int min_size = max_size - ref_sub + 1; for (n=0; n < components; n++) { int sz, last_sz, sub; // Find smallest sub-sampling factor compatible with existing // minimum canvas size and use this to deduce new minimum size. sub = (min_size - origin) / dims[n]; // Roughly smallest factor. if (sub <= 0) sub = 1; while ((sub > 1) && (((ceil_ratio(origin,sub)+dims[n])*sub) > min_size)) sub--; while ((sz=(ceil_ratio(origin,sub)+dims[n])*sub) < min_size) sub++; if ((sz-sub+1) > min_size) min_size = sz-sub+1; if (min_size > max_size) break; // Current reference sub-sampling factor cannot work. // Find largest sub-sampling factor compatible with existing // maximum canvas size and use this to deduce new maximum size. do { last_sz = sz; if (sub == 255) break; sub++; sz = (ceil_ratio(origin,sub)+dims[n])*sub; } while ((sz-sub+1) <= max_size); if (last_sz < max_size) max_size = last_sz; if (min_size > max_size) break; // Current reference sub-sampling factor cannot work. } if (n == components) { // Succeeded. size = min_size; return true; } } return false; // Failed to find compatible sub-sampling factors.}/*****************************************************************************//* STATIC derive_absolute_steps *//*****************************************************************************/static void derive_absolute_steps(qcd_params *qcd, int num_dwt_levels, int kernel_id, float ref_step, bool derived_from_LL) /* This function determines a suitable set of scalar quantization step sizes for the irreversible path, based on the number of DWT levels, the DWT kernel type (one of `Cparams_W9X7' or `Cparams_W5X3') and a base quantization step size. If `derived_from_LL' is true, only the LL band's step size will be determined and set into the supplied `qcd' object. Otherwise, separate step sizes will be determined for each subband and set into the `qcd' object. */{ if (num_dwt_levels == 0) { qcd->set(Qabs_steps,0,0,ref_step); return; } kdu_kernels kernels(kernel_id,false); int lev, band_idx; for (band_idx=0, lev=num_dwt_levels; lev > 0; lev--) { double low_1d = kernels.get_energy_gain(KDU_SYNTHESIS_LOW,lev); double high_1d = kernels.get_energy_gain(KDU_SYNTHESIS_HIGH,lev); if (band_idx==0) qcd->set(Qabs_steps,band_idx++,0,ref_step/low_1d); // LL subband. if (derived_from_LL) break; qcd->set(Qabs_steps,band_idx++,0,ref_step/sqrt(low_1d*high_1d)); qcd->set(Qabs_steps,band_idx++,0,ref_step/sqrt(low_1d*high_1d)); qcd->set(Qabs_steps,band_idx++,0,ref_step/high_1d); }}/* ========================================================================= *//* kd_attribute *//* ========================================================================= *//*****************************************************************************//* kd_attribute::kd_attribute *//*****************************************************************************/kd_attribute::kd_attribute(const char *name, const char *comment, int flags, const char *pattern){ char const *ch; this->name = name; this->comment = comment; this->flags = flags; this->pattern = pattern; for (ch=pattern, num_fields=0; *ch != '\0'; ch++, num_fields++) { if ((*ch == 'F') || (*ch == 'B') || (*ch == 'I')) continue; char term = '\0'; if (*ch == '(') term = ')'; else if (*ch == '[') term = ']'; for (ch++; (*ch != term) && (*ch != '\0'); ch++); if (*ch == '\0') throw pattern; } num_records = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -