📄 jp2.cpp
字号:
channel_functions[3*typ].source_component = channel_functions[3*typ+1].source_component = channel_functions[3*typ+2].source_component = channel_idx; } if (!cdef->close()) { kdu_error e; e << "Malformed channel definition (cdef) box found in JP2 " "file. The box appears to be too long."; }}/*****************************************************************************//* j2_channels::process_cmap_box *//*****************************************************************************/void j2_channels::process_cmap_box(j2_input_box *cmap){ assert(cmap->get_box_type() == j2_component_mapping_box); if ((cmap_channels != NULL) || num_cmap_channels) { kdu_error e; e << "Multiple instances of the component mapping (cmap) " "box encountered in JP2 file!"; } int box_bytes = cmap->get_remaining_bytes(); if ((box_bytes & 3) || (box_bytes == 0)) { kdu_error e; e << "Malformed component mapping (cmap) box encountered " "in JP2 file. The body of any such box must contain exactly four " "bytes for each channel and there must be at least one channel."; } num_cmap_channels = box_bytes >> 2; if (num_cmap_channels < 1) { kdu_error e; e << "Malformed component mapping (cmap) box encountered " "in JP2 file. The body of the box does not appear to contain any " "channel mappings."; } cmap_channels = new j2_channel[num_cmap_channels]; for (int n=0; n < num_cmap_channels; n++) { kdu_uint16 cmp; kdu_byte mtyp, pcol; if (!(cmap->read(cmp) && cmap->read(mtyp) && cmap->read(pcol) && (mtyp < 2))) { kdu_error e; e << "Malformed component mapping (cmap) box " "encountered in JP2 file. Invalid or truncated mapping specs."; } cmap_channels[n].source_component = cmp; cmap_channels[n].palette_component = (mtyp)?((int) pcol):-1; } cmap->close();}/*****************************************************************************//* j2_channels::finalize *//*****************************************************************************/void j2_channels::finalize(int num_colours, int num_components, int num_palette_components){ int c, n; if (this->num_components != 0) { // already finalized. assert((num_colours == this->num_colours) && (num_components == this->num_components) && (num_palette_components == this->num_palette_components)); return; } assert((num_colours == 1) || (num_colours == 3)); if (num_colours == 1) for (c=0; c < 9; c+=3) // Eliminate unused colours channel_functions[c+1].source_component = channel_functions[c+2].source_component = -1; if (this->num_colours == 0) { // This is either a default output object or an input object. Need // to merge information collected from cdef and/or cmap boxes. this->num_colours = num_colours; this->num_components = num_components; this->num_palette_components = num_palette_components; if (cmap_channels != NULL) { // Transfer information to the `channel_functions' array. for (c=0; c < 9; c++) if ((n=channel_functions[c].source_component) >= 0) { if (n >= num_cmap_channels) { kdu_error e; e << "The JP2 file's colour definition " "(cdef) box references a channel which is not defined " "within the colour mapping (cmap) box."; } channel_functions[c] = cmap_channels[n]; } delete[] cmap_channels; cmap_channels = NULL; num_cmap_channels = 0; } } else { // This is an output object. if (this->num_colours != num_colours) { kdu_error e; e << "Attempting to use a `jp2_channels' object " "whose number of colours differs from that specified by the " "`jp2_colour' object."; } this->num_components = num_components; this->num_palette_components = num_palette_components; // Check requirement that no image component be used both as // input to a palette LUT and also directly. for (c=0; c < 9; c++) if (channel_functions[c].palette_component >= 0) for (n=0; n < 9; n++) if ((channel_functions[n].source_component == channel_functions[c].source_component) && (channel_functions[n].palette_component < 0)) { kdu_error e; e << "It is illegal to use any image " "component directly as well as through a colour palette " "mapping."; } // Check requirement that no image component or component/palette // combination be used for two different types of reproduction // function. for (c=0; c < 6; c++) { for (n=(c<3)?3:6; n < 9; n++) if ((channel_functions[c].source_component >= 0) && (channel_functions[c].source_component == channel_functions[n].source_component) && (channel_functions[c].palette_component == channel_functions[n].palette_component)) { kdu_error e; e << "It is illegal to specify the same " "source component/palette LUT combination for use with " "different types of colour reproduction functions, where " "the three types are colour, opacity and pre-multiplied " "opacity."; } } } // Finally, perform some general checks concerning the range of image // component and palette component indices and make sure that the // minimal set of colour functions are specified. for (c=0; c < num_colours; c++) if (channel_functions[c].source_component < 0) { kdu_error e; e << "Insufficient channel association information for " "a valid JP2 file. Every colour channel must be associated with an " "image component in some way or another."; } for (c=0; c < 9; c++) if (channel_functions[c].source_component >= num_components) { kdu_error e; e << "Attempting to describe a colour channel in terms " "of a non-existent image component!"; } else if (channel_functions[c].palette_component >= num_palette_components) { kdu_error e; e << "Attempting to describe a colour channel in terms " "of a non-existent palette component (lookup table)."; }}/*****************************************************************************//* j2_channels::save_boxes *//*****************************************************************************/void j2_channels::save_boxes(j2_output_box *super_box){ assert((num_colours > 0) && (num_components > 0)); // ensure `finalized'. int c, n; // First, determine the number of unmapped image components. For some // reason, JP2 seems to require that information for these also appear // in the channel definition and/or component mapping boxes. int num_unmapped_components = 0; for (n=0; n < num_components; n++) { for (c=0; c < 9; c++) if (channel_functions[c].source_component == n) break; if (c == 9) num_unmapped_components++; } // Now see what boxes need to be written at all. bool need_boxes = false; for (c=0; c < num_colours; c++) if (channel_functions[c].source_component != c) need_boxes = true; for (; c < 9; c++) if (channel_functions[c].source_component >= 0) need_boxes = true; if (num_unmapped_components > 0) need_boxes = true; if (num_palette_components > 0) need_boxes = true; if (!need_boxes) return; bool need_cmap_box = (num_palette_components > 0); // cmap used if and only palette box appears int channel_indices[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; int num_functional_cmap_channels = 0; if (need_cmap_box) { // Assign a unique channel index to each colour function for (c=0; c < 9; c++) if (channel_functions[c].source_component >= 0) { for (n=0; n < c; n++) if (channel_functions[c] == channel_functions[n]) break; if (n < c) channel_indices[c] = channel_indices[n]; else channel_indices[c] = num_functional_cmap_channels++; } } // Start with the channel definition box. j2_output_box cdef; cdef.open(super_box,j2_channel_definition_box); int num_descriptions = 0; for (c=0; c < 9; c++) if (channel_functions[c].source_component >= 0) num_descriptions++; num_descriptions += num_unmapped_components; cdef.write((kdu_uint16) num_descriptions); for (c=0; c < 9; c++) if ((n = channel_functions[c].source_component) >= 0) { if (need_cmap_box) n = channel_indices[c]; kdu_uint16 typ = (kdu_uint16)(c / 3); kdu_uint16 assoc = (kdu_uint16)((c % 3) + 1); cdef.write((kdu_uint16) n); cdef.write(typ); cdef.write(assoc); } if (need_cmap_box) { // We will create extra channels at the end for unmapped components. for (n=0; n < num_unmapped_components; n++) { cdef.write((kdu_uint16)(n+num_functional_cmap_channels)); cdef.write((kdu_uint16) 0xFFFF); cdef.write((kdu_uint16) 0xFFFF); } } else { // Identify unmapped components directly. for (n=0; n < num_components; n++) { for (c=0; c < 9; c++) if (channel_functions[c].source_component == n) break; if (c == 9) { cdef.write((kdu_uint16) n); cdef.write((kdu_uint16) 0xFFFF); cdef.write((kdu_uint16) 0xFFFF); num_unmapped_components--; // Check them off as we go. } } assert(num_unmapped_components == 0); } cdef.close(); if (!need_cmap_box) return; // Finish with the component mapping box, if any. j2_output_box cmap; cmap.open(super_box,j2_component_mapping_box); for (n=0; n < num_functional_cmap_channels; n++) { for (c=0; c < 9; c++) if (channel_indices[c] == n) break; assert(c < 9); cmap.write((kdu_uint16)(channel_functions[c].source_component)); if (channel_functions[c].palette_component < 0) cmap.write((kdu_uint16) 0); else { cmap.write((kdu_byte) 1); cmap.write((kdu_byte)(channel_functions[c].palette_component)); } } // Now create extra channels for any unmapped components. for (n=0; n < num_components; n++) { for (c=0; c < 9; c++) if (channel_functions[c].source_component == n) break; if (c == 9) { cmap.write((kdu_uint16) n); cmap.write((kdu_uint16) 0); // Unmapped components always direct num_unmapped_components--; } } assert(num_unmapped_components == 0); cmap.close();}/* ========================================================================= *//* jp2_channels *//* ========================================================================= *//*****************************************************************************//* jp2_channels::init *//*****************************************************************************/void jp2_channels::init(int num_colours){ assert(state != NULL); assert((num_colours == 1) || (num_colours == 3)); state->num_colours = num_colours; for (int c=num_colours; c < 9; c++) state->channel_functions[c].source_component = -1;}/*****************************************************************************//* jp2_channels::set_colour_mapping *//*****************************************************************************/void jp2_channels::set_colour_mapping(int colour_idx, int codestream_component, int palette_component){ assert((state != NULL) && (colour_idx >= 0) && (colour_idx < state->num_colours)); if (palette_component < 0) palette_component = -1; // Standardize to allow comparisons in `finalize' state->channel_functions[colour_idx].source_component = codestream_component; state->channel_functions[colour_idx].palette_component = palette_component;}/*****************************************************************************//* jp2_channels::set_opacity_mapping *//*****************************************************************************/void jp2_channels::set_opacity_mapping(int colour_idx, int codestream_component, int palette_component){ assert((state != NULL) && (colour_idx >= 0) && (colour_idx < state->num_colours)); if (palette_component < 0) palette_component = -1; // Standardize to allow comparisons in `finalize' colour_idx += 3; state->channel_functions[colour_idx].source_component = codestream_component; state->channel_functions[colour_idx].palette_component = palette_component;}/*****************************************************************************//* jp2_channels::set_premult_mapping *//*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -