📄 region_decompressor.cpp
字号:
if (interp_factor == 1) for (; fast_count > 0; fast_count--) *(dp++) = val = *(sp++); else for (; fast_count > 0; fast_count--) for (val=*(sp++), k=interp_factor; k > 0; k--) *(dp++) = val; if (fast_count == 0) val = *sp; // Otherwise, we had only one input sample. for (; num_cols > 0; num_cols--) *(dp++) = val; } else { // Source data is absolute integers. Needs to be shifted. int upshift = KDU_FIX_POINT - bit_depth; int downshift = -upshift; if (src.get_buf32() != NULL) { // Source data is 32-bit integers kdu_sample32 *sp = src.get_buf32() + src_offset; kdu_int32 val; val = (sp++)->ival; val = (upshift>0)?(val<<upshift):(val>>downshift); for (; interp_first > 0; interp_first--) (dp++)->ival = (kdu_int16) val; if (upshift > 0) { if (interp_factor == 1) for (; fast_count > 0; fast_count--) (dp++)->ival = (kdu_int16)(val = ((sp++)->ival << upshift)); else for (; fast_count > 0; fast_count--) for (val=(sp++)->ival<<upshift, k=interp_factor; k > 0; k--) (dp++)->ival = (kdu_int16) val; } else { if (interp_factor == 1) for (; fast_count > 0; fast_count--) (dp++)->ival = (kdu_int16)(val = ((sp++)->ival >> downshift)); else for (; fast_count > 0; fast_count--) for (val=(sp++)->ival>>downshift, k=interp_factor; k > 0; k--) (dp++)->ival = (kdu_int16) val; } if (fast_count == 0) { // Otherwise, we had only one input sample. val = sp->ival; val = (upshift>0)?(val<<upshift):(val>>downshift); } for (; num_cols > 0; num_cols--) (dp++)->ival = (kdu_int16) val; } else { // Source data is 16-bit absolute integers kdu_sample16 *sp = src.get_buf16() + src_offset; kdu_int16 val; val = (sp++)->ival; val = (upshift>0)?(val<<upshift):(val>>downshift); for (; interp_first > 0; interp_first--) (dp++)->ival = val; if (upshift > 0) { if (interp_factor == 1) for (; fast_count > 0; fast_count--) (dp++)->ival = val = ((sp++)->ival << upshift); else for (; fast_count > 0; fast_count--) for (val=(sp++)->ival<<upshift, k=interp_factor; k > 0; k--) (dp++)->ival = val; } else { if (interp_factor == 1) for (; fast_count > 0; fast_count--) (dp++)->ival = val = ((sp++)->ival >> downshift); else for (; fast_count > 0; fast_count--) for (val=(sp++)->ival>>downshift, k=interp_factor; k > 0; k--) (dp++)->ival = val; } if (fast_count == 0) { // Otherwise, we had only one input sample. val = sp->ival; val = (upshift>0)?(val<<upshift):(val>>downshift); } for (; num_cols > 0; num_cols--) (dp++)->ival = val; } }}/******************************************************************************//* STATIC transfer_fixed_point *//******************************************************************************/static void transfer_fixed_point(kdu_line_buf &src, kdu_byte *dest, int num_samples) /* Transfers source samples from the supplied line buffer into the output byte buffer, spacing successive output samples apart by 3 bytes (to allow for interleaving of colour components). Only `num_samples' samples are transferred and the source data is guaranteed to have a 16-bit fixed point representation. */{ assert(num_samples <= src.get_width()); kdu_sample16 *sp = src.get_buf16(); assert((sp != NULL) && !src.is_absolute()); kdu_int16 val; for (; num_samples > 0; num_samples--, sp++, dest+=3) { val = sp->ival; val += (1<<(KDU_FIX_POINT-8))>>1; val >>= (KDU_FIX_POINT-8); val += 128; if (val & ((-1)<<8)) val = (val<0)?0:255; *dest = (kdu_byte) val; }}/* ========================================================================== *//* Implementation of Member Functions *//* ========================================================================== *//******************************************************************************//* kdr_region_decompressor::start *//******************************************************************************/void kdr_region_decompressor::start(kdu_codestream codestream, kdr_channel_mapping *mapping, int single_component, int discard_levels, int max_layers, kdu_dims region, kdu_coords sampling){ int c, num_components = codestream.get_num_components(); this->codestream = codestream; codestream_failure = false; tile_open = false; // Just in case. // Set up components and channels. for (c=0; c < 6; c++) { components[c].comp_idx = -1; components[c].palette_bits = 0; } if (mapping != NULL) { num_channels = mapping->num_channels; assert((num_channels == 1) || (num_channels == 3)); for (c=0; c < num_channels; c++) { int n; for (n=0; n < 5; n++) if ((components[n].comp_idx < 0) || (components[n].comp_idx == mapping->source_components[c])) break; components[n].comp_idx = mapping->source_components[c]; channels[c].source = components + n; channels[c].lut = mapping->palette[c]; if (channels[c].lut != NULL) components[n].palette_bits = mapping->palette_bits; } colour = mapping->colour; space = (num_channels==3)?JP2_sRGB_SPACE:JP2_sLUM_SPACE; if (colour.exists()) space = colour.get_space(); } else { num_channels = 1; components[0].comp_idx = single_component; channels[0].source = components; channels[0].lut = NULL; colour = jp2_colour(NULL); space = JP2_sLUM_SPACE; } // Configure component sampling and data representation information. int first_idx = channels[0].source->comp_idx; kdu_coords first_subs; codestream.get_subsampling(first_idx,first_subs); kdu_coords max_sampling = sampling; for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++) { kdr_component *comp = components + c; comp->bit_depth = codestream.get_bit_depth(comp->comp_idx); comp->is_signed = codestream.get_signed(comp->comp_idx); kdu_coords this_subs; codestream.get_subsampling(comp->comp_idx,this_subs); comp->sampling.x = (this_subs.x * sampling.x) / first_subs.x; comp->sampling.y = (this_subs.y * sampling.y) / first_subs.y; if (comp->sampling.x > max_sampling.x) max_sampling.x = comp->sampling.x; if (comp->sampling.y > max_sampling.y) max_sampling.y = comp->sampling.y; } // Find an appropriate region (a little large) on the code-stream canvas kdu_coords min = region.pos; kdu_coords lim = min + region.size; min.x = ceil_ratio(min.x-2*max_sampling.x,sampling.x); min.y = ceil_ratio(min.y-2*max_sampling.y,sampling.y); lim.x = ceil_ratio(lim.x+2*max_sampling.x,sampling.x); lim.y = ceil_ratio(lim.y+2*max_sampling.y,sampling.y); kdu_dims first_region; first_region.pos = min; first_region.size = lim-min; codestream.apply_input_restrictions(0,0,discard_levels,max_layers,NULL); kdu_dims canvas_region; codestream.map_region(first_idx,first_region,canvas_region); codestream.apply_input_restrictions(0,0,discard_levels,max_layers, &canvas_region); // Prepare for processing tiles within the region. codestream.get_valid_tiles(valid_tiles); next_tile_idx = valid_tiles.pos; tile_open = false;}/******************************************************************************//* kdr_region_decompressor::open_tile *//******************************************************************************/void kdr_region_decompressor::open_tile(){ int c; assert(!tile_open); assert((next_tile_idx.y - valid_tiles.pos.y) < valid_tiles.size.y); current_tile = codestream.open_tile(next_tile_idx); tile_open = true; next_tile_idx.x++; if ((next_tile_idx.x-valid_tiles.pos.x) >= valid_tiles.size.x) { next_tile_idx.x = valid_tiles.pos.x; next_tile_idx.y++; } // Fill in tile-specific component fields. use_ycc = current_tile.get_ycc(); for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++) { kdr_component *comp = components + c; if (use_ycc && (comp->comp_idx < 3) && comp->palette_bits) { 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)."; } comp->line_buf_valid = false; kdu_tile_comp tc = current_tile.access_component(comp->comp_idx); comp->reversible = tc.get_reversible(); kdu_resolution res = tc.access_resolution(); res.get_dims(comp->dims); bool use_shorts = true; if (comp->reversible && (tc.get_bit_depth(true) > 16)) use_shorts = false; if (res.which() == 0) comp->engine = kdu_decoder(res.access_subband(LL_BAND),&allocator,use_shorts); else comp->engine = kdu_synthesis(res,&allocator,use_shorts); comp->line.pre_create(&allocator,comp->dims.size.x, comp->reversible,use_shorts); } if (num_channels == 1) use_ycc = false; // Establish rendering dimensions for the current tile based on the first // channel. The mapping between rendering dimensions and actual // code-stream dimensions is invariably based upon the first channel as // the reference component. This channel's sample locations are understood // as occupying locations at integer multiples of the relevant sampling // factors on the rendering canvas. kdr_component *ref_comp = channels[0].source; kdu_coords min = ref_comp->dims.pos; kdu_coords lim = min + ref_comp->dims.size; min.x = min.x * ref_comp->sampling.x - ((ref_comp->sampling.x-1) >> 1); min.y = min.y * ref_comp->sampling.y - ((ref_comp->sampling.y-1) >> 1); lim.x = lim.x * ref_comp->sampling.x - ((ref_comp->sampling.x-1) >> 1); lim.y = lim.y * ref_comp->sampling.y - ((ref_comp->sampling.y-1) >> 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -