📄 codestream.cpp
字号:
/*****************************************************************************/// File: codestream.cpp [scope = CORESYS/COMPRESSED]// Version: Kakadu, V2.2// Author: David Taubman// Last Revised: 20 June, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001). A brief summary// of the license appears below. This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,// Version 2.2, including distribution of one or more Applications built// using the software, provided such distribution is not for financial// return.// 2. The Licensee has the right to personal use of the Kakadu software,// Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including// source code and dynamically or statically linked libraries) to a Third// Party, provided the Third Party possesses a license to use the Kakadu// software, Version 2.2, and provided such distribution is not for// financial return./******************************************************************************Description: Implements a part of the compressed data management machinery, includingcode-stream I/O, packet sequencing and the top level interfaces associated withcodestream objects.******************************************************************************/#include <math.h>#include <string.h>#include <limits.h>#include <iomanip>#include <assert.h>#include "kdu_elementary.h"#include "kdu_utils.h"#include "kdu_messaging.h"#include "kdu_kernels.h"#include "kdu_compressed.h"#include "compressed_local.h"using namespace std;#define KDU_IDENTIFIER "Kakadu-2.2" // Do not disable. Allows compressed // code-streams to be identified in case of // compatibility problems down the road./* ========================================================================= *//* Internal Functions *//* ========================================================================= *//*****************************************************************************//* STATIC is_power_2 *//*****************************************************************************/static bool is_power_2(int val){ for (; val > 1; val >>= 1) if (val & 1) return false; return (val==1);}/* ========================================================================= *//* External Functions *//* ========================================================================= *//*****************************************************************************//* EXTERN print_marker_code *//*****************************************************************************/void print_marker_code(kdu_uint16 code, std::ostream &out){ const char *name=NULL; if (code == KDU_SOC) name = "SOC"; else if (code == KDU_SOT) name = "SOT"; else if (code == KDU_SOD) name = "SOD"; else if (code == KDU_SOP) name = "SOP"; else if (code == KDU_EPH) name = "EPH"; else if (code == KDU_EOC) name = "EOC"; else if (code == KDU_SIZ) name = "SIZ"; else if (code == KDU_COD) name = "COD"; else if (code == KDU_COC) name = "COC"; else if (code == KDU_QCD) name = "QCD"; else if (code == KDU_QCC) name = "QCC"; else if (code == KDU_RGN) name = "RGN"; else if (code == KDU_POC) name = "POC"; else if (code == KDU_CRG) name = "CRG"; else if (code == KDU_COM) name = "COM"; else if (code == KDU_TLM) name = "TLM"; else if (code == KDU_PLM) name = "PLM"; else if (code == KDU_PLT) name = "PLT"; else if (code == KDU_PPM) name = "PPM"; else if (code == KDU_PPT) name = "PPT"; if (name == NULL) {#ifdef GCC_VERSION_LESS_THAN_3 long int original_flags;#else ios_base::fmtflags original_flags;#endif original_flags = out.flags(ios::showbase|ios::internal|ios::right|ios::hex); out.fill('0'); out << setw(6) << code; out.flags(original_flags); } else out << "<" << name << ">";}/* ========================================================================= *//* kd_input *//* ========================================================================= *//*****************************************************************************//* kd_input::process_unexpected_marker *//*****************************************************************************/void kd_input::process_unexpected_marker(kdu_byte last_byte){ assert(throw_markers); kdu_uint16 code = 0xFF00; code += last_byte; disable_marker_throwing(); if (!reject_all) { bool bona_fide = false; if ((code == KDU_SOP) || (code == KDU_SOT)) { kdu_byte byte; kdu_uint16 length; if (!get(byte)) exhausted = false; else { length = byte; if (!get(byte)) { exhausted = false; putback((kdu_byte) code); } else { length = (length<<8) + byte; if (code == KDU_SOP) bona_fide = (length == 4); else bona_fide = (length == 10); putback(length); } } } if (!bona_fide) { enable_marker_throwing(reject_all); have_FF = (last_byte==0xFF); return; // Continue processing as though nothing had happened. } } assert(!exhausted); putback(code); throw code;}/*****************************************************************************//* kd_input::read *//*****************************************************************************/int kd_input::read(kdu_byte *buf, int count){ int xfer_bytes; int nbytes = 0; if (exhausted) return 0; while (count > 0) { if ((xfer_bytes = first_unwritten-first_unread) == 0) { if (!load_buf()) break; xfer_bytes = first_unwritten-first_unread; assert(xfer_bytes > 0); } xfer_bytes = (xfer_bytes < count)?xfer_bytes:count; nbytes += xfer_bytes; count -= xfer_bytes; if (throw_markers) { // Slower loop has to look for marker codes. kdu_byte byte; while (xfer_bytes--) { *(buf++) = byte = *(first_unread++); if (have_FF && (byte > 0x8F)) process_unexpected_marker(byte); have_FF = (byte==0xFF); } } else { // Fastest loop. Probably not beneficial to use `memcpy'. while (xfer_bytes--) *(buf++) = *(first_unread++); } } return nbytes;}/*****************************************************************************//* kd_input::ignore *//*****************************************************************************/int kd_input::ignore(int count){ int xfer_bytes; int nbytes = 0; if (exhausted) return 0; while (count > 0) { if ((xfer_bytes = first_unwritten-first_unread) == 0) { if (!load_buf()) break; xfer_bytes = first_unwritten-first_unread; assert(xfer_bytes > 0); } xfer_bytes = (xfer_bytes < count)?xfer_bytes:count; nbytes += xfer_bytes; count -= xfer_bytes; if (throw_markers) { // Slower loop has to look for marker codes. kdu_byte byte; while (xfer_bytes--) { byte = *(first_unread++); if (have_FF && (byte > 0x8F)) process_unexpected_marker(byte); have_FF = (byte==0xFF); } } else first_unread += xfer_bytes; } return nbytes;}/* ========================================================================= *//* kd_compressed_input *//* ========================================================================= *//*****************************************************************************//* kd_compressed_input::load_buf *//*****************************************************************************/bool kd_compressed_input::load_buf(){ if (bytes_available <= 0) { exhausted = true; return false; } first_unread = buffer + KD_IBUF_PUTBACK; int xfer_bytes = KD_IBUF_SIZE - KD_IBUF_PUTBACK; if (xfer_bytes > bytes_available) xfer_bytes = bytes_available; if (xfer_bytes > 0) xfer_bytes = source->read(first_unread,xfer_bytes); bytes_available -= xfer_bytes; first_unwritten = first_unread + xfer_bytes; if (xfer_bytes == 0) { exhausted = true; return false; } return true;}/* ========================================================================= *//* kd_pph_input *//* ========================================================================= *//*****************************************************************************//* kd_pph_input::~kd_pph_input *//*****************************************************************************/kd_pph_input::~kd_pph_input(){ read_buf = NULL; // Just in case. while ((write_buf=first_buf) != NULL) { first_buf = write_buf->next; buf_server->release(write_buf); }}/*****************************************************************************//* kd_pph_input::add_bytes *//*****************************************************************************/void kd_pph_input::add_bytes(kdu_byte *data, int num_bytes){ while (num_bytes > 0) { if (write_buf == NULL) { write_buf = read_buf = first_buf = buf_server->get(); write_pos = read_pos = 0; } else if (write_pos == KD_CODE_BUFFER_LEN) { write_buf = write_buf->next = buf_server->get(); write_pos = 0; } int xfer_bytes = KD_CODE_BUFFER_LEN-write_pos; if (xfer_bytes > num_bytes) xfer_bytes = num_bytes; num_bytes -= xfer_bytes; while (xfer_bytes--) write_buf->buf[write_pos++] = *(data++); }}/*****************************************************************************//* kd_pph_input::load_buf *//*****************************************************************************/bool kd_pph_input::load_buf(){ if (read_buf == NULL) { exhausted = true; return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -