📄 kdu_expand.cpp
字号:
case 0: transpose = false; vflip = false; hflip = false; break; case 1: transpose = true; vflip = false; hflip = true; break; case 2: transpose = false; vflip = true; hflip = true; break; case 3: transpose = true; vflip = true; hflip = false; break; } return(files);}/*****************************************************************************//* STATIC check_jp2_compatible_suffix *//*****************************************************************************/static bool check_jp2_compatible_suffix(char *fname) /* Returns true if the file-name has the suffix, ".jp2" or ".jpx", where the check is case insensitive. */{ char *cp = strrchr(fname,'.'); if (cp == NULL) return false; cp++; if ((*cp != 'j') && (*cp != 'J')) return false; cp++; if ((*cp != 'p') && (*cp != 'P')) return false; cp++; if ((*cp != '2') && (*cp != 'x') && (*cp != 'X')) return false; return true;}/*****************************************************************************//* STATIC set_error_behaviour *//*****************************************************************************/static void set_error_behaviour(kdu_args &args, kdu_codestream codestream){ bool fussy = false; bool resilient = false; bool ubiquitous_sops = false; if (args.find("-fussy") != NULL) { args.advance(); fussy = true; } if (args.find("-resilient") != NULL) { args.advance(); resilient = true; } if (args.find("-resilient_sop") != NULL) { args.advance(); resilient = true; ubiquitous_sops = true; } if (resilient) codestream.set_resilient(ubiquitous_sops); else if (fussy) codestream.set_fussy(); else codestream.set_fast();}/*****************************************************************************//* STATIC get_bpp_dims *//*****************************************************************************/static int get_bpp_dims(siz_params *siz){ int comps, max_width, max_height, n; siz->get(Scomponents,0,0,comps); max_width = max_height = 0; for (n=0; n < comps; n++) { int width, height; siz->get(Sdims,n,0,height); siz->get(Sdims,n,1,width); if (width > max_width) max_width = width; if (height > max_height) max_height = height; } return max_height * max_width;}/*****************************************************************************//* STATIC set_region_of_interest *//*****************************************************************************/static void set_region_of_interest(kdu_args &args, kdu_dims ®ion, siz_params *siz){ if (!(siz->get(Sorigin,0,0,region.pos.y) && siz->get(Sorigin,0,1,region.pos.x) && siz->get(Ssize,0,0,region.size.y) && siz->get(Ssize,0,1,region.size.x))) assert(0); region.size.y -= region.pos.y; region.size.x -= region.pos.x; if (args.find("-region") == NULL) return; char *string = args.advance(); if (string != NULL) { double top, left, height, width; if (sscanf(string,"{%lf,%lf},{%lf,%lf}",&top,&left,&height,&width) != 4) string = NULL; else if ((top < 0.0) || (left < 0.0) || (height < 0.0) || (width < 0.0)) string = NULL; else { region.pos.y += (int) floor(region.size.y * top); region.pos.x += (int) floor(region.size.x * left); region.size.y = (int) ceil(region.size.y * height); region.size.x = (int) ceil(region.size.x * width); } } if (string == NULL) { kdu_error e; e << "The `-region' argument requires a set of coordinates " "of the form, \"{<top>,<left>},{<height>,<width>}\". All quantities " "must be real numbers in the range 0 to 1."; } args.advance();}/*****************************************************************************//* STATIC convert_samples_to_palette_indices *//*****************************************************************************/static void convert_samples_to_palette_indices(kdu_line_buf &line, int bit_depth, bool is_signed, int palette_bits){ int i=line.get_width(); if (line.get_buf32() != NULL) { assert(line.is_absolute()); kdu_sample32 *sp = line.get_buf32(); kdu_int32 offset = (is_signed)?0:((1<<bit_depth)>>1); kdu_int32 mask = ((kdu_int32)(-1))<<palette_bits; kdu_int32 val; for (; i > 0; i--, sp++) { val = sp->ival + offset; if (val & mask) val = (val<0)?0:(~mask); sp->ival = val; } } else if (line.is_absolute()) { kdu_sample16 *sp = line.get_buf16(); kdu_int16 offset = (kdu_int16)((is_signed)?0:((1<<bit_depth)>>1)); kdu_int16 mask = ((kdu_int16)(-1))<<palette_bits; kdu_int16 val; for (; i > 0; i--, sp++) { val = sp->ival + offset; if (val & mask) val = (val<0)?0:(~mask); sp->ival = val; } } else { kdu_sample16 *sp = line.get_buf16(); kdu_int16 offset = (kdu_int16)((is_signed)?0:((1<<KDU_FIX_POINT)>>1)); int downshift = KDU_FIX_POINT-palette_bits; assert(downshift > 0); offset += (kdu_int16)((1<<downshift)>>1); kdu_int32 mask = ((kdu_int16)(-1))<<palette_bits; kdu_int16 val; for (; i > 0; i--, sp++) { val = (sp->ival + offset) >> downshift; if (val & mask) val = (val<0)?0:(~mask); sp->ival = val; } }}/* ========================================================================= *//* kde_flow_control *//* ========================================================================= *//*****************************************************************************//* kde_flow_control::kde_flow_control *//*****************************************************************************/kde_flow_control::kde_flow_control(kde_file_binding *files, int num_channels, kdu_codestream codestream, int x_tnum, bool allow_shorts, jp2_channels channel_mapping, jp2_palette palette){ int c; this->codestream = codestream; codestream.get_valid_tiles(this->valid_tile_indices); assert((x_tnum >= 0) && (x_tnum < valid_tile_indices.size.x)); this->tile_idx = valid_tile_indices.pos; this->tile_idx.x += x_tnum; this->x_tnum = x_tnum; this->tile = codestream.open_tile(tile_idx); this->num_components = codestream.get_num_components(); this->num_channels = num_channels; components = new kde_component_flow_control[num_components]; channels = new kde_channel[num_channels]; count_delta = 0; // Initialize components for (c=0; c < num_components; c++) { kde_component_flow_control *comp = components + c; comp->tc = tile.access_component(c); comp->reversible = comp->tc.get_reversible(); comp->is_signed = comp->tc.get_signed(); comp->bit_depth = comp->tc.get_bit_depth(); comp->mapped_by_channel = false; comp->palette_bits = 0; kdu_coords subsampling; comp->tc.get_subsampling(subsampling); comp->res = comp->tc.access_resolution(); kdu_dims dims; comp->res.get_dims(dims); comp->width = dims.size.x; comp->vert_subsampling = subsampling.y; if ((c == 0) || (comp->vert_subsampling < count_delta)) count_delta = comp->vert_subsampling; // Delta is min sampling factor comp->ratio_counter = 0; comp->remaining_lines = dims.size.y; comp->allow_shorts = allow_shorts; } // Initialize channels for (c=0; c < num_channels; c++) { kde_channel *chnl = channels +c; if (files != NULL) { assert(c >= files->first_channel_idx); if ((c-files->first_channel_idx) >= files->num_channels) { files = files->next; assert((files != NULL) && (files->first_channel_idx == c)); } chnl->writer = files->writer; } int cmp=c, plt_cmp=-1; if (channel_mapping.exists()) channel_mapping.get_colour_mapping(c,cmp,plt_cmp); chnl->source_component = components + cmp; chnl->source_component->mapped_by_channel = true; chnl->width = chnl->source_component->width; chnl->allocator = &(chnl->source_component->allocator); if (plt_cmp < 0) chnl->lut = NULL; else { // Set up palette lookup table. int i, num_entries = palette.get_num_entries(); assert(num_entries <= 1024); int palette_bits = 1; while ((1<<palette_bits) < num_entries) palette_bits++; chnl->source_component->palette_bits = palette_bits; chnl->lut = new kdu_sample16[1<<palette_bits]; palette.get_lut(plt_cmp,chnl->lut); for (i=num_entries; i < (1<<palette_bits); i++) chnl->lut[i] = chnl->lut[num_entries-1]; } } // Complete components and channels use_ycc = tile.get_ycc(); for (c=0; c < num_components; c++) { kde_component_flow_control *comp = components + c; if (!comp->mapped_by_channel) continue; bool use_shorts = comp->allow_shorts; if ((comp->tc.get_bit_depth(true) > 16) && ((comp->palette_bits == 0) || comp->reversible)) use_shorts = false; comp->line.pre_create(&(comp->allocator),comp->width, comp->reversible,use_shorts); if (comp->res.which() == 0) comp->decompressor = kdu_decoder(comp->res.access_subband(LL_BAND), &(comp->allocator),use_shorts); else comp->decompressor = kdu_synthesis(comp->res, &(comp->allocator),use_shorts); } for (c=0; c < num_channels; c++) if (channels[c].lut != NULL) { if (use_ycc && ((channels[c].source_component - components) < 3)) { kdu_error e; e << "It is illegal for a JP2 file to identify a " "code-stream component as index to a Palette lookup table, if the " "component is also part of a code-stream colour transform (RCT " "or ICT)."; } channels[c].line.pre_create(channels[c].allocator, channels[c].width,false,true); } // Turn off colour transforms if we only want a subset of the components if (!(components[0].mapped_by_channel && components[1].mapped_by_channel && components[2].mapped_by_channel)) use_ycc = false; // Finalize resources for (c=0; c < num_components; c++) if (components[c].mapped_by_channel) { components[c].allocator.finalize(); components[c].line.create(); } for (c=0; c < num_channels; c++) channels[c].line.create(); // Does no harm if not pre-created.}/*****************************************************************************//* kde_flow_control::~kde_flow_control *//*****************************************************************************/kde_flow_control::~kde_flow_control(){ for (int n=0; n < num_components; n++) { kde_component_flow_control *comp = components + n; if (comp->decompressor.exists()) comp->decompressor.destroy(); } delete[] components; for (int c=0; c < num_channels; c++) { kde_channel *chnl = channels + c; if (chnl->lut != NULL) delete[] (chnl->lut); } delete[] channels;}/*****************************************************************************//* kde_flow_control::advance_components *//*****************************************************************************/bool kde_flow_control::advance_components(){ bool found_line=false; while (!found_line) { bool all_done = true; for (int n=0; n < num_components; n++) { kde_component_flow_control *comp = components + n; assert(comp->ratio_counter >= 0); if (comp->mapped_by_channel && (comp->remaining_lines > 0)) { all_done = false; comp->ratio_counter -= count_delta; if (comp->ratio_counter < 0) { found_line = true; comp->decompressor.pull(comp->line,true); if (comp->palette_bits > 0) convert_samples_to_palette_indices(comp->line, comp->bit_depth,comp->is_signed,comp->palette_bits); } } } if (all_done) return false; } if ((use_ycc) && (components[0].ratio_counter < 0)) { assert((num_components >= 3) && (components[1].ratio_counter < 0) && (components[2].ratio_counter < 0)); kdu_convert_ycc_to_rgb(components[0].line, components[1].line, components[2].line); } for (int c=0; c < num_channels; c++) { kde_channel *chnl = channels + c; kde_component_flow_control *comp = chnl->source_component; if ((comp->ratio_counter < 0) && (chnl->lut != NULL)) { // Perform LUT mapping. kdu_sample16 *lut = chnl->lut;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -