📄 kdu_compress.cpp
字号:
{ jp2_palette pclr = jp2_out.access_palette(); if (palette.is_monochrome()) { pclr.init(1,1<<palette.input_bits); pclr.set_lut(0,palette.red,palette.output_bits); assert(num_colours == 1); jp2_channels channels = jp2_out.access_channels(); channels.init(1); channels.set_colour_mapping(0,palette.source_component,0); } else { pclr.init(3,1<<palette.input_bits); pclr.set_lut(0,palette.red,palette.output_bits); pclr.set_lut(1,palette.green,palette.output_bits); pclr.set_lut(2,palette.blue,palette.output_bits); assert(num_colours == 3); jp2_channels channels = jp2_out.access_channels(); channels.init(3); channels.set_colour_mapping(0,palette.source_component,0); channels.set_colour_mapping(1,palette.source_component,1); channels.set_colour_mapping(2,palette.source_component,2); } }}/*****************************************************************************//* STATIC assign_layer_bytes *//*****************************************************************************/static int * assign_layer_bytes(kdu_args &args, siz_params *siz, int &num_specs) /* Returns a pointer to an array of `num_specs' quality layer byte targets. The value of `num_specs' is determined in this function, based on the number of rates (or slopes) specified on the command line, together with any knowledge about the number of desired quality layers. Before calling this function, you must parse all parameter attribute strings into the code-stream parameter lists rooted at `siz'. Note that the returned array will contain 0's whenever a quality layer's bit-rate is unspecified. This allows the compressor's rate allocator to assign the target size for those quality layers on the fly. */{ char *cp; char *string = NULL; int arg_specs = 0; int slope_specs = 0; int cod_specs = 0; if (args.find("-slope") != NULL) { string = args.advance(false); // Need to process this arg again later. if (string != NULL) { while (string != NULL) { slope_specs++; string = strchr(string+1,','); } } } // Determine how many rates are specified on the command-line if (args.find("-rate") != NULL) { string = args.advance(); if (string == NULL) { kdu_error e; e << "\"-rate\" argument must be followed by a " "string identifying one or more bit-rates, separated by commas."; } cp = string; while (cp != NULL) { arg_specs++; cp = strchr(cp,','); if (cp != NULL) cp++; } } // Find the number of layers specified by the main COD marker kdu_params *cod = siz->access_cluster(COD_params); assert(cod != NULL); cod->get(Clayers,0,0,cod_specs); if (!cod_specs) cod_specs = (arg_specs>slope_specs)?arg_specs:slope_specs; num_specs = cod_specs; if (num_specs == 0) num_specs = 1; if ((arg_specs != num_specs) && ((arg_specs > 2) || ((arg_specs == 2) && (num_specs == 1)))) { kdu_error e; e << "The relationship between the number of bit-rates " "specified by the \"-rate\" argument and the number of quality layers " "explicitly specified via \"Clayers\" does not conform to the rules " "supplied in the description of the \"-rate\" argument. Use \"-u\" " "to print the usage statement."; } cod->set(Clayers,0,0,num_specs); int n; int *result = new int[num_specs]; for (n=0; n < num_specs; n++) result[n] = 0; int total_pels = get_bpp_dims(siz); bool have_dash = false; for (n=0; n < arg_specs; n++) { cp = strchr(string,','); if (cp != NULL) *cp = '\0'; // Temporarily terminate string. if (strcmp(string,"-") == 0) { have_dash = true; result[n] = INT_MAX; } else { double bpp; if ((!sscanf(string,"%lf",&bpp)) || (bpp <= 0.0)) { kdu_error e; e << "Illegal sub-string encoutered in parameter " "string supplied to the \"-rate\" argument. Rate parameters " "must be strictly positive real numbers, with multiple " "parameters separated by commas only. Problem encountered at " "sub-string: \"" << string << "\"."; } result[n] = (int) floor(bpp * 0.125 * total_pels); } if (cp != NULL) { *cp = ','; string = cp+1; } } if (arg_specs) { // Bubble sort the supplied specs. bool done = false; while (!done) { // Use trivial bubble sort. done = true; for (int n=1; n < arg_specs; n++) if (result[n-1] > result[n]) { // Swap misordered pair. int tmp=result[n]; result[n]=result[n-1]; result[n-1]=tmp; done = false; } } } if (arg_specs && (arg_specs != num_specs)) { // Arrange for specified rates to identify max and/or min layer rates assert((arg_specs < num_specs) && (arg_specs <= 2)); result[num_specs-1] = result[arg_specs-1]; result[arg_specs-1] = 0; } if (have_dash) { // Convert final rate target of INT_MAX into 0 (forces rate allocator // to assign all remaining compressed bits to that layer.) assert(result[num_specs-1] == INT_MAX); result[num_specs-1] = 0; } if (string != NULL) args.advance(); return result;}/*****************************************************************************//* STATIC assign_layer_thresholds *//*****************************************************************************/static kdu_uint16 * assign_layer_thresholds(kdu_args &args, int num_specs) /* Returns a pointer to an array of `num_specs' slope threshold values, all of which are set to 0 unless the command-line arguments contain an explicit request for particular distortion-length slope thresholds. */{ int n; kdu_uint16 *result = new kdu_uint16[num_specs]; for (n=0; n < num_specs; n++) result[n] = 0; if (args.find("-slope") == NULL) return result; char *string = args.advance(); if (string == NULL) { kdu_error e; e << "The `-slope' argument must be followed by a " "comma-separated list of slope values."; } for (n=0; (n < num_specs) && (string != NULL); n++) { char *delim = strchr(string,','); if (delim != NULL) { *delim = '\0'; delim++; } int val; if ((sscanf(string,"%d",&val) != 1) || (val < 0) || (val > 65535)) { kdu_error e; e << "The `-slope' argument must be followed by a " "comma-separated list of integer distortion-length slope values, " "each of which must be in the range 0 to 65535, inclusive."; } result[n] = (kdu_uint16) val; string = delim; } // Now sort the entries into decreasing order. int k; if (n > 1) { bool done = false; while (!done) { // Use trivial bubble sort. done = true; for (k=1; k < n; k++) if (result[k-1] < result[k]) { // Swap misordered pair. kdu_uint16 tmp=result[k]; result[k]=result[k-1]; result[k-1]=tmp; done = false; } } } // Fill in any remaining missing values. for (k=n; k < num_specs; k++) result[k] = result[n-1]; args.advance(); return result;}/*****************************************************************************//* STATIC create_roi_source *//*****************************************************************************/static kdu_roi_image * create_roi_source(kdu_codestream codestream, kdu_args &args){ if (args.find("-roi") == NULL) return NULL; char *string = args.advance(); kdu_roi_image *result = NULL; if ((string != NULL) && (*string == '{')) { double top, left, height, width; if ((sscanf(string,"{%lf,%lf},{%lf,%lf}", &top,&left,&height,&width) != 4) || ((top < 0.0) || (left < 0.0) || (height < 0.0) || (width < 0.0))) { kdu_error e; e << "The `-roi' argument requires a set of " "coordinates of the form, \"{<top>,<left>},{<height>,<width>}\", " "where all quantities must be real numbers in the range 0 to 1."; } kdu_dims region; codestream.get_dims(-1,region); 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); result = new kdu_roi_rect(codestream,region); } else { // Must be file-name/threshold form. char *fname = string; float threshold; if ((fname == NULL) || ((string = strchr(fname,',')) == NULL) || (sscanf(string+1,"%f",&threshold) == 0) || (threshold < 0.0F) || (threshold >= 1.0F)) { kdu_error e; e << "The `-roi' argument requires a single parameter " "string, which should either identify the four coordinates of a " "rectangular foreground region or else an image file and threshold " "value, separated by a comma. The threshold may be no less than 0 " "and must be strictly less than 1."; } *string = '\0'; result = new kdu_roi_graphics(codestream,fname,threshold); } args.advance(); return result;}/* ========================================================================= *//* kdc_flow_control *//* ========================================================================= *//*****************************************************************************//* kdc_flow_control::kdc_flow_control *//*****************************************************************************/kdc_flow_control::kdc_flow_control(kdc_file_binding *files, kdu_codestream codestream, int x_tnum, bool allow_shorts, kdu_roi_image *roi_source){ int n; this->codestream = codestream; this->x_tnum = x_tnum; codestream.get_valid_tiles(valid_tile_indices); assert((x_tnum >= 0) && (x_tnum < valid_tile_indices.size.x)); tile_idx = valid_tile_indices.pos; tile_idx.x += x_tnum; tile = codestream.open_tile(tile_idx); num_components = tile.get_num_components(); assert(num_components > 0); roi_image = roi_source; // Set up the individual components. components = new kdc_component_flow_control[num_components]; count_delta = 0; for (n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; if (files != NULL) { assert(n >= files->first_comp_idx); if ((n-files->first_comp_idx) >= files->num_components) { files = files->next; assert((files != NULL) && (files->first_comp_idx == n)); } comp->reader = files->reader; } kdu_tile_comp tc = tile.access_component(n); comp->reversible = tc.get_reversible(); kdu_coords subsampling; tc.get_subsampling(subsampling); kdu_resolution res = tc.access_resolution(); kdu_dims dims; res.get_dims(dims); comp->vert_subsampling = subsampling.y; if ((n == 0) || (comp->vert_subsampling < count_delta)) count_delta = comp->vert_subsampling; comp->allow_shorts = allow_shorts; bool use_shorts = (tc.get_bit_depth(true)>16)?false:(comp->allow_shorts); comp->line.pre_create(&(comp->allocator),dims.size.x, comp->reversible,use_shorts); kdu_roi_node *roi_node = NULL; if (roi_image != NULL) roi_node = roi_image->acquire_node(n,dims); if (res.which() == 0) comp->compressor = kdu_encoder(res.access_subband(LL_BAND),&(comp->allocator), use_shorts,1.0F,roi_node); else comp->compressor = kdu_analysis(res,&(comp->allocator),use_shorts,1.0F,roi_node); comp->allocator.finalize(); comp->line.create(); comp->ratio_counter = 0; comp->remaining_lines = dims.size.y; } use_ycc = tile.get_ycc(); if (use_ycc) assert((num_components >= 3) && (components[0].reversible == components[1].reversible) && (components[1].reversible == components[2].reversible));}/*****************************************************************************//* kdc_flow_control::~kdc_flow_control *//*****************************************************************************/kdc_flow_control::~kdc_flow_control(){ for (int n=0; n < num_components; n++) { kdc_component_flow_control *comp = components + n; if (comp->compressor.exists()) comp->compressor.destroy(); } delete[] components;}/*****************************************************************************//* kdc_flow_control::advance_components *//*****************************************************************************/bool
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -