📄 jp2.cpp
字号:
/*****************************************************************************/// File: jp2.cpp [scope = APPS/JP2]// Version: Kakadu, V2.2.1// Author: David Taubman// Last Revised: 5 July, 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 the internal machinery whose external interfaces are definedin the compressed-io header file, "jp2.h".******************************************************************************/#include <assert.h>#include <string.h>#include <math.h>#include "kdu_elementary.h"#include "kdu_compressed.h"#include "kdu_messaging.h"#include "jp2.h"#include "jp2_local.h"/* ========================================================================= *//* Box Type Codes *//* ========================================================================= */static inline kdu_uint32 string_to_int(char *string){ assert((string[0] != '\0') && (string[1] != '\0') && (string[2] != '\0') && (string[3] != '\0') && (string[4] == '\0')); kdu_uint32 result = ((kdu_byte) string[0]); result = (result<<8) + ((kdu_byte) string[1]); result = (result<<8) + ((kdu_byte) string[2]); result = (result<<8) + ((kdu_byte) string[3]); return result;}static const kdu_uint32 j2_signature_box = string_to_int("jP ");static const kdu_uint32 j2_file_type_box = string_to_int("ftyp");static const kdu_uint32 j2_header_box = string_to_int("jp2h");static const kdu_uint32 j2_image_header_box = string_to_int("ihdr");static const kdu_uint32 j2_bits_per_component_box = string_to_int("bpcc");static const kdu_uint32 j2_colour_box = string_to_int("colr");static const kdu_uint32 j2_palette_box = string_to_int("pclr");static const kdu_uint32 j2_component_mapping_box = string_to_int("cmap");static const kdu_uint32 j2_channel_definition_box = string_to_int("cdef");static const kdu_uint32 j2_resolution_box = string_to_int("res ");static const kdu_uint32 j2_capture_resolution_box = string_to_int("resc");static const kdu_uint32 j2_display_resolution_box = string_to_int("resd");static const kdu_uint32 j2_codestream_box = string_to_int("jp2c");static const kdu_uint32 j2_signature = 0x0D0A870A;static const kdu_uint32 j2_brand = string_to_int("jp2 ");/* ========================================================================= *//* ICC Profile Signatures *//* ========================================================================= */static const kdu_uint32 icc_input_device = string_to_int("scnr");static const kdu_uint32 icc_gray_data = string_to_int("GRAY");static const kdu_uint32 icc_rgb_data = string_to_int("RGB ");static const kdu_uint32 icc_pcs_xyz = string_to_int("XYZ ");static const kdu_uint32 icc_file_signature = string_to_int("acsp");static const kdu_uint32 icc_gray_trc = string_to_int("kTRC");static const kdu_uint32 icc_red_trc = string_to_int("rTRC");static const kdu_uint32 icc_green_trc = string_to_int("gTRC");static const kdu_uint32 icc_blue_trc = string_to_int("bTRC");static const kdu_uint32 icc_red_colorant = string_to_int("rXYZ");static const kdu_uint32 icc_green_colorant = string_to_int("gXYZ");static const kdu_uint32 icc_blue_colorant = string_to_int("bXYZ");static const kdu_uint32 icc_curve_type = string_to_int("curv");static const kdu_uint32 icc_xyz_type = string_to_int("XYZ ");/* ========================================================================= *//* Internal Functions *//* ========================================================================= *//*****************************************************************************//* INLINE store_big *//*****************************************************************************/static inline void store_big(kdu_uint32 val, kdu_byte * &bp){ bp += 4; bp[-1] = (kdu_byte) val; val >>= 8; bp[-2] = (kdu_byte) val; val >>= 8; bp[-3] = (kdu_byte) val; val >>= 8; bp[-4] = (kdu_byte) val;}static inline void store_big(kdu_uint16 val, kdu_byte * &bp){ bp += 2; bp[-1] = (kdu_byte) val; val >>= 8; bp[-2] = (kdu_byte) val;}static inline void store_big(kdu_byte val, kdu_byte * &bp){ bp += 1; bp[-1] = (kdu_byte) val;}/* ========================================================================= *//* j2_input_box *//* ========================================================================= *//*****************************************************************************//* j2_input_box::read_header *//*****************************************************************************/void j2_input_box::read_header(){ remaining_bytes = 0xFFFFFFFF; // So initial reads do not fail. box_type = 1; // Dummy value until we can read the actual length if (!(read(box_bytes) && read(box_type) && (box_type != 0))) { box_bytes = remaining_bytes = box_type = 0; return; } if (box_bytes == 1) { // 64-bit box length kdu_uint32 box_bytes_high; if (!(read(box_bytes_high) && read(box_bytes))) { box_bytes = remaining_bytes = box_type = 0; return; } if (box_bytes_high) box_bytes = 0; // Can't hold such big lengths. Treat as rubber length. else if (box_bytes < 16) { kdu_error e; e << "Illegal extended box length encountered in JP2 file."; } remaining_bytes = box_bytes - 16; } else if (box_bytes != 0) { if (box_bytes < 8) { kdu_error e; e << "Illegal box length field encountered in JP2 file."; } remaining_bytes = box_bytes - 8; }}/*****************************************************************************//* j2_input_box::close *//*****************************************************************************/bool j2_input_box::close(){ if (box_type == 0) return true; if (box_bytes == 0) { // Rubber length box. box_bytes = remaining_bytes = box_type = 0; if (super_box != NULL) return super_box->close(); else { char dummy; if (fread(&dummy,1,1,file) > 0) return false; return true; } } else if (remaining_bytes > 0) { if (super_box != NULL) super_box->ignore(remaining_bytes); else fseek(file,remaining_bytes,SEEK_CUR); remaining_bytes = box_bytes = box_type = 0; return false; } remaining_bytes = box_bytes = box_type = 0; return true;}/*****************************************************************************//* j2_input_box::ignore *//*****************************************************************************/int j2_input_box::ignore(int num_bytes){ if (box_type == 0) return 0; if ((box_bytes != 0) && (remaining_bytes < (kdu_uint32) num_bytes)) num_bytes = remaining_bytes; if (super_box != NULL) num_bytes = super_box->ignore(num_bytes); else { long int tmp_pos = ftell(file); fseek(file,num_bytes,SEEK_CUR); num_bytes = (int)(ftell(file) - tmp_pos); } remaining_bytes -= (kdu_uint32) num_bytes; return num_bytes;}/*****************************************************************************//* j2_input_box::read (array) *//*****************************************************************************/int j2_input_box::read(kdu_byte buf[], int num_bytes){ if (box_type == 0) { kdu_error e; e << "Attempting to read from a closed JP2 file box."; } if ((box_bytes != 0) && (remaining_bytes < (kdu_uint32) num_bytes)) num_bytes = remaining_bytes; if (super_box != NULL) num_bytes = super_box->read(buf,num_bytes); else num_bytes = fread(buf,1,(size_t) num_bytes,file); remaining_bytes -= (kdu_uint32) num_bytes; return num_bytes;}/*****************************************************************************//* j2_input_box::read (dword) *//*****************************************************************************/bool j2_input_box::read(kdu_uint32 &dword){ kdu_byte buf[4]; if (read(buf,4) < 4) return false; dword = buf[0]; dword = (dword<<8) + buf[1]; dword = (dword<<8) + buf[2]; dword = (dword<<8) + buf[3]; return true;}/*****************************************************************************//* j2_input_box::read (word) *//*****************************************************************************/bool j2_input_box::read(kdu_uint16 &word){ kdu_byte buf[2]; if (read(buf,2) < 2) return false; word = buf[0]; word = (word<<8) + buf[1]; return true;}/* ========================================================================= *//* j2_output_box *//* ========================================================================= *//*****************************************************************************//* j2_output_box::write_header *//*****************************************************************************/void j2_output_box::write_header(){ if (rubber_length) { write((kdu_uint32) 0); write(box_type); } else { kdu_uint32 box_bytes = 8 + (kdu_uint32) buffered_bytes; rubber_length = true; // So that the header is output directly. write(box_bytes); write(box_type); rubber_length = false; }}/*****************************************************************************//* j2_output_box::set_rubber_length *//*****************************************************************************/void j2_output_box::set_rubber_length(){ assert(box_type != 0); if (rubber_length) return; if (super_box != NULL) super_box->set_rubber_length(); rubber_length = true; write_header(); if (buffer != NULL) { if (super_box != NULL) output_failed = !super_box->write(buffer,buffered_bytes); else output_failed = (fwrite(buffer,1,(size_t) buffered_bytes,file) != (size_t) buffered_bytes); delete[] buffer; buffer_size = buffered_bytes = 0; buffer = NULL; }}/*****************************************************************************//* j2_output_box::close *//*****************************************************************************/bool j2_output_box::close(){ if (buffer != NULL) { assert(!rubber_length); write_header(); if (super_box != NULL) output_failed = !super_box->write(buffer,buffered_bytes); else output_failed = (fwrite(buffer,1,(size_t) buffered_bytes,file) != (size_t) buffered_bytes); delete[] buffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -