📄 jp2.cpp
字号:
buffer_size = buffered_bytes = 0; buffer = NULL; } box_type = 0; return !output_failed;}/*****************************************************************************//* j2_output_box::write (buffer) *//*****************************************************************************/bool j2_output_box::write(kdu_byte buf[], int num_bytes){ if ((box_type == 0) || output_failed) return false; if (rubber_length) { // Flush data directly to the output. if (super_box != NULL) output_failed = !super_box->write(buf,num_bytes); else output_failed = (fwrite(buf,1,(size_t) num_bytes,file) != (size_t) num_bytes); return !output_failed; } buffered_bytes += num_bytes; if (buffered_bytes > buffer_size) { buffer_size += buffered_bytes + 1024; kdu_byte *tmp_buf = new kdu_byte[buffer_size]; if (buffer != NULL) { memcpy(tmp_buf,buffer,(size_t)(buffered_bytes-num_bytes)); delete[] buffer; } buffer = tmp_buf; } memcpy(buffer+buffered_bytes-num_bytes,buf,(size_t) num_bytes); return true;}/*****************************************************************************//* j2_output_box::write (dword) *//*****************************************************************************/bool j2_output_box::write(kdu_uint32 dword){ kdu_byte buf[4]; buf[3] = (kdu_byte) dword; dword >>= 8; buf[2] = (kdu_byte) dword; dword >>= 8; buf[1] = (kdu_byte) dword; dword >>= 8; buf[0] = (kdu_byte) dword; return write(buf,4);}/*****************************************************************************//* j2_output_box::write (word) *//*****************************************************************************/bool j2_output_box::write(kdu_uint16 word){ kdu_byte buf[2]; buf[1] = (kdu_byte) word; word >>= 8; buf[0] = (kdu_byte) word; return write(buf,2);}/* ========================================================================= *//* j2_dimensions *//* ========================================================================= *//*****************************************************************************//* j2_dimensions::init (output) *//*****************************************************************************/void j2_dimensions::init(kdu_coords size, int num_components, bool unknown_space){ if (this->num_components != 0) { kdu_error e; e << "JP2 dimensions may be initialized only once!"; } assert(num_components > 0); this->size = size; this->num_components = num_components; this->colour_space_unknown = unknown_space; ipr_box_available = false; bit_depths = new int[num_components]; for (int c=0; c < num_components; c++) bit_depths[c] = 0; // Uninitialized state}/*****************************************************************************//* j2_dimensions::init (input) *//*****************************************************************************/void j2_dimensions::init(j2_input_box *ihdr){ if (this->num_components != 0) { kdu_error e; e << "JP2 file contains multiple image header (ihdr) boxes!"; } assert(ihdr->get_box_type() == j2_image_header_box); kdu_uint32 height, width; kdu_uint16 nc; kdu_byte bpc, c_type, unk, ipr; if (!(ihdr->read(height) && ihdr->read(width) && ihdr->read(nc) && ihdr->read(bpc) && ihdr->read(c_type) && ihdr->read(unk) && ihdr->read(ipr))) { kdu_error e; e << "Malformed image header box (ihdr) found in JP2 " "file. Not all fields were present."; } if (!ihdr->close()) { kdu_error e; e << "Malformed image header box (ihdr) found in JP2 " "file. The box appears to be too long."; } if ((nc < 1) || (nc > 16384) || (c_type != 7) || (unk != (unk & 1)) || (ipr != (ipr & 1)) || ((bpc != 0xFF) && ((bpc & 0x7F) > 37))) { kdu_error e; e << "Malformed image header box (ihdr) found in JP2 " "file. The box contains fields which do not conform to their legal " "range."; } if ((height & 0x80000000) || (width & 0x80000000)) { kdu_error e; e << "Sorry: Cannot process JP2 files whose image header " "box contains height and width values larger than 2^{31}-1."; } size.y = (int) height; size.x = (int) width; num_components = (int) nc; colour_space_unknown = (unk != 0); ipr_box_available = (ipr != 0); bit_depths = new int[num_components]; for (int c=0; c < num_components; c++) if (bpc == 0xFF) bit_depths[c] = 0; else bit_depths[c] = (bpc & 0x80)?(-((bpc & 0x7F)+1)):(bpc+1);}/*****************************************************************************//* j2_dimensions::process_bpcc_box *//*****************************************************************************/void j2_dimensions::process_bpcc_box(j2_input_box *bpcc){ kdu_byte bpc; for (int c=0; c < num_components; c++) if (bit_depths[c]) { kdu_error e; e << "Encountered an illegal bits per component (bpcc) " "box in a JP2 header box. The bpcc box is legal only if " "the image header box does not specify bit-depth information."; } else if (!bpcc->read(bpc)) { kdu_error e; e << "Malformed bits per component (bpcc) box found in " "JP2 file. The box contains insufficient bit-depth specifiers."; } else if ((bpc & 0x7F) > 37) { kdu_error e; e << "Malformed bits per component (bpcc) box found in " "JP2 file. The box contains an illegal bit-depth specifier. Bit " "depths may not exceed 38 bits per sample."; } else bit_depths[c] = (bpc & 0x80)?(-((bpc & 0x7F)+1)):(bpc+1); if (!bpcc->close()) { kdu_error e; e << "Malformed bits per component (bpcc) box found in JP2 " "file. The box appears to be too long."; }}/*****************************************************************************//* j2_dimensions::finalize *//*****************************************************************************/void j2_dimensions::finalize(){ int c; for (c=0; c < num_components; c++) if ((bit_depths[c] == 0) || (bit_depths[c] > 38) || (bit_depths[c] < -38)) break; if ((num_components < 1) || (c < num_components) || (num_components > 16384)) { kdu_error e; e << "Incomplete or invalid dimensional information " "provided for the JP2 file image header box."; }}/*****************************************************************************//* j2_dimensions::save_boxes *//*****************************************************************************/void j2_dimensions::save_boxes(j2_output_box *super_box){ finalize(); int c; kdu_byte bpc = 0; for (c=1; c < num_components; c++) if (bit_depths[c] != bit_depths[0]) bpc = 0xFF; if (bpc == 0) bpc = (kdu_byte) ((bit_depths[0]>0)?(bit_depths[0]-1):(0x80 | (-bit_depths[0]-1))); j2_output_box ihdr; ihdr.open(super_box,j2_image_header_box); ihdr.write((kdu_uint32) size.y); ihdr.write((kdu_uint32) size.x); ihdr.write((kdu_uint16) num_components); ihdr.write(bpc); ihdr.write((kdu_byte) 7); ihdr.write((kdu_byte)((colour_space_unknown)?1:0)); ihdr.write((kdu_byte)((ipr_box_available)?1:0)); ihdr.close(); if (bpc != 0xFF) return; j2_output_box bpcc; bpcc.open(super_box,j2_bits_per_component_box); for (c=0; c < num_components; c++) { bpc = (kdu_byte) ((bit_depths[c]>0)?(bit_depths[c]-1):(0x80 | (-bit_depths[c]-1))); bpcc.write(bpc); } bpcc.close();}/* ========================================================================= *//* jp2_dimensions *//* ========================================================================= *//*****************************************************************************//* jp2_dimensions::init *//*****************************************************************************/void jp2_dimensions::init(kdu_coords size, int num_components, bool unknown_space){ assert(state != NULL); state->init(size,num_components,unknown_space);}/*****************************************************************************//* jp2_dimensions::init (siz) *//*****************************************************************************/void jp2_dimensions::init(siz_params *siz, bool unknown_space){ kdu_coords size, origin; int num_components; if (!(siz->get(Ssize,0,0,size.y) && siz->get(Ssize,0,1,size.x) && siz->get(Sorigin,0,0,origin.y) && siz->get(Sorigin,0,1,origin.x) && siz->get(Scomponents,0,0,num_components))) { kdu_error e; e << "Attempting to initialize a `jp2_dimensions' object " "using an incomplete `siz_params' object."; } size -= origin; init(size,num_components,unknown_space); for (int c=0; c < num_components; c++) { bool is_signed; int bit_depth; if (!(siz->get(Ssigned,c,0,is_signed) && siz->get(Sprecision,c,0,bit_depth))) { kdu_error e; e << "Attempting to initialize a `jp2_dimensions' " "object using an incomplete `siz_params' object."; } set_precision(c,bit_depth,is_signed); }}/*****************************************************************************//* jp2_dimensions::set_precision *//*****************************************************************************/void jp2_dimensions::set_precision(int component_idx, int bit_depth, bool is_signed){ assert((state != NULL) && (component_idx >= 0) && (component_idx < state->num_components)); state->bit_depths[component_idx] = (is_signed)?-bit_depth:bit_depth;}/*****************************************************************************//* jp2_dimensions::get_size *//*****************************************************************************/kdu_coords jp2_dimensions::get_size(){ assert(state != NULL); return state->size;}/*****************************************************************************//* jp2_dimensions::get_num_components *//*****************************************************************************/int jp2_dimensions::get_num_components(){ assert(state != NULL); return state->num_components;}/*****************************************************************************//* jp2_dimensions::colour_space_known *//*****************************************************************************/bool jp2_dimensions::colour_space_known(){ assert(state != NULL); return state->colour_space_unknown;}/*****************************************************************************//* jp2_dimensions::get_bit_depth *//*****************************************************************************/int jp2_dimensions::get_bit_depth(int component_idx){ assert((state != NULL) && (component_idx >= 0) && (component_idx < state->num_components)); int depth = state->bit_depths[component_idx]; return (depth < 0)?-depth:depth;}/*****************************************************************************//* jp2_dimensions::get_signed *//*****************************************************************************/bool jp2_dimensions::get_signed(int component_idx){ assert((state != NULL) && (component_idx >= 0) && (component_idx < state->num_components)); return (state->bit_depths[component_idx] < 0);}/* ========================================================================= *//* j2_palette *//* ========================================================================= *//*****************************************************************************//* j2_palette::init (output) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -