📄 codestream.cpp
字号:
first_unread = first_unwritten = buffer + KD_IBUF_PUTBACK; int xfer_bytes = KD_IBUF_SIZE - KD_IBUF_PUTBACK; int buf_bytes; while (xfer_bytes > 0) { if (read_pos == KD_CODE_BUFFER_LEN) { if (read_buf != write_buf) { read_buf = read_buf->next; read_pos = 0; assert(read_buf != NULL); } } buf_bytes = (read_buf==write_buf)?write_pos:KD_CODE_BUFFER_LEN; buf_bytes -= read_pos; assert(buf_bytes >= 0); if (buf_bytes == 0) break; if (buf_bytes > xfer_bytes) buf_bytes = xfer_bytes; xfer_bytes -= buf_bytes; while (buf_bytes--) *(first_unwritten++) = read_buf->buf[read_pos++]; } if (first_unread == first_unwritten) { exhausted = true; return false; } return true;}/* ========================================================================= *//* kd_marker *//* ========================================================================= *//*****************************************************************************//* kd_marker::kd_marker (copy) *//*****************************************************************************/kd_marker::kd_marker(const kd_marker &orig){ source = NULL; code = orig.code; max_length = length = orig.length; if (max_length == 0) buf = NULL; else buf = new kdu_byte[max_length]; memcpy(buf,orig.buf,(size_t) length);}/*****************************************************************************//* kd_marker::read *//*****************************************************************************/bool kd_marker::read(bool exclude_stuff_bytes, bool skip_to_marker){ assert(source != NULL); kdu_byte byte = 0; bool valid_code; source->disable_marker_throwing(); do { if ((byte != 0xFF) && !source->get(byte)) { code = 0; length = 0; return false; } if (skip_to_marker) while (byte != 0xFF) if (!source->get(byte)) { code = 0; length = 0; return false; } if (byte != 0xFF) { source->putback(byte); code = 0; length = 0; return false; } if (!source->get(byte)) { code = 0; length = 0; return false; } code = 0xFF00 + byte; valid_code = true; if (exclude_stuff_bytes) valid_code = (byte > 0x8F); if ((code == KDU_SOP) || (code == KDU_SOT)) { // Want to be really sure that this is not a corrupt marker code. assert(valid_code); if (!source->get(byte)) { code = 0; length = 0; return false; } length = byte; length <<= 8; if (!source->get(byte)) { code = 0; length = 0; return false; } length += byte; if ((code == KDU_SOP) && (length != 4)) { valid_code = false; source->putback((kdu_uint16) length); kdu_warning w; w << "Skipping over corrupt SOP marker code!"; } else if ((code == KDU_SOT) && (length != 10)) { valid_code = false; source->putback((kdu_uint16) length); kdu_warning w; w << "Skipping over corrupt SOT marker code!"; } byte = (kdu_byte) code; } else if (code == KDU_EOC) { /* If the input source is about to end, we will simply skip over the EOC marker so that true EOC termination can be treated in the same way as premature termination of the code-stream. Otherwise, the EOC marker would appear to have been generated by some type of code-stream corruption. In this case, we will treat it as an invalid marker code. */ if (source->get(byte)) { valid_code = false; source->putback(byte); byte = (kdu_byte) code; kdu_warning w; w << "Disregarding non-terminal EOC marker."; } else { length = 0; code = 0; return false; } } } while (skip_to_marker && (!valid_code)); if (!valid_code) { source->putback(code); code = 0; length = 0; return false; } // Now we are committed to processing the marker, returning false only if // the source becomes exhausted. if ((code == KDU_SOC) || (code == KDU_SOD) || (code == KDU_EOC) || (code == KDU_EPH)) return true; // Delimiter found. There is no marker segment. if ((code != KDU_SOT) && (code != KDU_SOP) && (code != KDU_SIZ) && (code != KDU_COD) && (code != KDU_COC) && (code != KDU_QCD) && (code != KDU_QCC) && (code != KDU_RGN) && (code != KDU_POC) && (code != KDU_CRG) && (code != KDU_COM) && (code != KDU_TLM) && (code != KDU_PLM) && (code != KDU_PLT) && (code != KDU_PPM) && (code != KDU_PPT)) { kdu_warning w; w << "Unrecognized/unimplemented marker code, "; print_current_code(w); w << ", found in code-stream."; } if ((code != KDU_SOP) && (code != KDU_SOT)) { // Otherwise, we already have the length. if (!source->get(byte)) { code = 0; return false; } length = byte; length <<= 8; if (!source->get(byte)) { code = 0; length = 0; return false; } length += byte; } length -= 2; if (length < 0) { code = 0; length = 0; return false; } if (length > max_length) { max_length = 2*length; // Don't want to have to re-allocate too often delete[] buf; buf = new kdu_byte[max_length]; } if (source->read(buf,length) < length) { code = 0; length = 0; return false; } return true;}/* ========================================================================= *//* kd_pp_markers *//* ========================================================================= *//*****************************************************************************//* kd_pp_markers::~kd_pp_markers *//*****************************************************************************/kd_pp_markers::~kd_pp_markers(){ kd_pp_marker_list *tmp; while ((tmp=list) != NULL) { list = tmp->next; delete tmp; }}/*****************************************************************************//* kd_pp_markers::add_markers *//*****************************************************************************/void kd_pp_markers::add_marker(kd_marker ©_source){ if (copy_source.get_length() < 1) { kdu_error e; e << "PPM/PPT marker segments must be at least 3 bytes long!"; } kd_pp_marker_list *elt = new kd_pp_marker_list(copy_source); kdu_byte *data = elt->get_bytes(); elt->znum = data[0]; elt->bytes_read = 1; if (elt->get_code() == KDU_PPM) { assert((list == NULL) || is_ppm); is_ppm = true; } else { assert(elt->get_code() == KDU_PPT); assert((list == NULL) || !is_ppm); is_ppm = false; } kd_pp_marker_list *scan, *prev; for (prev=NULL, scan=list; scan != NULL; prev=scan, scan=scan->next) if (scan->znum > elt->znum) break; elt->next = scan; if (prev == NULL) list = elt; else { prev->next = elt; if (prev->znum == elt->znum) { kdu_error e; e << "Found multiple PPM/PPT markers with identical " "Zppt/Zppm indices within the same header scope (main or tile-part " "header)!"; } }}/*****************************************************************************//* kd_pp_markers::transfer_tpart *//*****************************************************************************/void kd_pp_markers::transfer_tpart(kd_pph_input *pph_input){ int xfer_bytes = INT_MAX; if (is_ppm) { while ((list != NULL) && (list->bytes_read == list->get_length())) advance_list(); if (list == NULL) { kdu_error e; e << "Insufficient packet header data in PPM marker " "segments!"; } if ((list->get_length()-list->bytes_read) < 4) { kdu_error e; e << "Encountered malformed PPM marker: 4-byte Nppm " "values may not straddle multiple PPM marker segments. Problem " "is most likely due to a previously incorrect Nppm value."; } kdu_byte *data = list->get_bytes(); xfer_bytes = data[list->bytes_read++]; xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++]; xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++]; xfer_bytes = (xfer_bytes << 8) + data[list->bytes_read++]; } while ((list != NULL) && (xfer_bytes > 0)) { int elt_bytes = list->get_length()-list->bytes_read; if (elt_bytes > xfer_bytes) elt_bytes = xfer_bytes; pph_input->add_bytes(list->get_bytes()+list->bytes_read,elt_bytes); xfer_bytes -= elt_bytes; list->bytes_read += elt_bytes; if (list->bytes_read == list->get_length()) advance_list(); } if (is_ppm && (xfer_bytes > 0)) { kdu_error e; e << "Insufficient packet header data in PPM marker " "segments, or else Nppm values must be incorrect!"; }}/*****************************************************************************//* kd_pp_markers::ignore_tpart *//*****************************************************************************/void kd_pp_markers::ignore_tpart(){ int xfer_bytes = INT_MAX; if (is_ppm) { kdu_byte byte; int len_bytes = 0; while (len_bytes < 4) { // Need to read 4 bytes of length information. if (list == NULL) { kdu_error e; e << "Insufficient packet header data in PPM " "marker segments!"; } if (list->bytes_read == list->get_length()) { advance_list(); continue; } byte = (list->get_bytes())[list->bytes_read++]; xfer_bytes = (xfer_bytes << 8) + byte; len_bytes++; } } while ((list != NULL) && (xfer_bytes > 0)) { int elt_bytes = list->get_length()-list->bytes_read; if (elt_bytes > xfer_bytes) elt_bytes = xfer_bytes; xfer_bytes -= elt_bytes; list->bytes_read += elt_bytes; if (list->bytes_read == list->get_length()) advance_list(); } if (is_ppm && (xfer_bytes > 0)) { kdu_error e; e << "Insufficient packet header data in PPM marker " "segments, or else Nppm values must be incorrect!"; }}/*****************************************************************************//* kd_pp_markers::advance_list *//*****************************************************************************/void kd_pp_markers::advance_list(){ assert((list != NULL) && (list->bytes_read == list->get_length())); kd_pp_marker_list *tmp = list; list = tmp->next; delete tmp;}/* ========================================================================= *//* kd_buf_server *//* ========================================================================= *//*****************************************************************************//* kd_buf_server::~kd_buf_server *//*****************************************************************************/kd_buf_server::~kd_buf_server(){ assert(num_users == 0); if (num_allocated_buffers != 0) { kdu_warning w; w << "The compressed data buffer server is being " "destroyed before all allocated buffers have been returned. The " "problem is most likely connected with a bug in the code-block " "destruction code."; } kd_code_alloc *tmp; while ((tmp=alloc) != NULL) { alloc = tmp->next; delete tmp; }}/*****************************************************************************//* kd_buf_server::get *//*****************************************************************************/kd_code_buffer * kd_buf_server::get(){ if (free == NULL) { assert(num_allocated_buffers == total_buffers);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -