📄 image_out.cpp
字号:
/*****************************************************************************/// File: image_out.cpp [scope = APPS/IMAGE-IO]// 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 image file writing for a variety of different file formats:currently BMP, PGM, PPM and RAW only. Readily extendible to include other fileformats without affecting the rest of the system.******************************************************************************/// System includes#include <string.h>#include <math.h>#include <assert.h>// Core includes#include "kdu_messaging.h"#include "kdu_sample_processing.h"// Image includes#include "kdu_image.h"#include "image_local.h"/* ========================================================================= *//* Internal Functions *//* ========================================================================= */static void to_little_endian(kdu_int32 * words, int num_words){ kdu_int32 test = 1; kdu_byte *first_byte = (kdu_byte *) &test; if (*first_byte) return; // Machine uses little-endian architecture already. kdu_int32 tmp; for (; num_words--; words++) { tmp = *words; *words = ((tmp >> 24) & 0x000000FF) + ((tmp >> 8) & 0x0000FF00) + ((tmp << 8) & 0x00FF0000) + ((tmp << 24) & 0xFF000000); }}/*****************************************************************************//* INLINE from_little_endian *//*****************************************************************************/static inline void from_little_endian(kdu_int32 * words, int num_words){ to_little_endian(words,num_words);}/*****************************************************************************//* STATIC convert_floats_to_bytes *//*****************************************************************************/static void convert_floats_to_bytes(kdu_sample32 *src, kdu_byte *dest, int num, int precision, int sample_gap=1){ float scale16 = (float)(1<<16); kdu_int32 val; if (precision >= 8) { for (; num > 0; num--, src++, dest+=sample_gap) { val = (kdu_int32)(src->fval*scale16); val = (val+128)>>8; // Often faster than true rounding from floats. val += 128; if (val & ((-1)<<8)) val = (val<0)?0:255; *dest = (kdu_byte) val; } } else { // Need to force zeros into one or more least significant bits. kdu_int32 downshift = 16-precision; kdu_int32 upshift = 8-precision; kdu_int32 offset = 1<<(downshift-1); for (; num > 0; num--, src++, dest+=sample_gap) { val = (kdu_int32)(src->fval*scale16); val = (val+offset)>>downshift; val <<= upshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:(256-(1<<upshift)); *dest = (kdu_byte) val; } }}/*****************************************************************************//* STATIC convert_fixpoint_to_bytes *//*****************************************************************************/static void convert_fixpoint_to_bytes(kdu_sample16 *src, kdu_byte *dest, int num, int precision, int sample_gap=1){ kdu_int16 val; if (precision >= 8) { kdu_int16 downshift = KDU_FIX_POINT-8; if (downshift < 0) { kdu_error e; e << "Cannot use 16-bit representation with high " "bit-depth data"; } kdu_int16 offset = (1<<downshift)>>1; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val = (val + offset) >> (KDU_FIX_POINT-8); val += 128; if (val & ((-1)<<8)) val = (val<0)?0:255; *dest = (kdu_byte) val; } } else { // Need to force zeros into one or more least significant bits. kdu_int16 downshift = KDU_FIX_POINT-precision; if (downshift < 0) { kdu_error e; e << "Cannot use 16-bit representation with high " "bit-depth data"; } kdu_int16 upshift = 8-precision; kdu_int16 offset = (1<<downshift)>>1; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val = (val+offset)>>downshift; val <<= upshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:(256-(1<<upshift)); *dest = (kdu_byte) val; } }}/*****************************************************************************//* STATIC convert_ints_to_bytes *//*****************************************************************************/static void convert_ints_to_bytes(kdu_sample32 *src, kdu_byte *dest, int num, int precision, int sample_gap=1){ kdu_int32 val; if (precision >= 8) { kdu_int32 downshift = precision-8; kdu_int32 offset = (1<<downshift)>>1; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val = (val+offset)>>downshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:255; *dest = (kdu_byte) val; } } else { kdu_int32 upshift = 8-precision; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val <<= upshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:(256-(1<<upshift)); *dest = (kdu_byte) val; } }}/*****************************************************************************//* STATIC convert_shorts_to_bytes *//*****************************************************************************/static void convert_shorts_to_bytes(kdu_sample16 *src, kdu_byte *dest, int num, int precision, int sample_gap=1){ kdu_int16 val; if (precision >= 8) { kdu_int16 downshift = precision-8; kdu_int16 offset = (1<<downshift)>>1; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val = (val+offset)>>downshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:255; *dest = (kdu_byte) val; } } else { kdu_int16 upshift = 8-precision; for (; num > 0; num--, src++, dest+=sample_gap) { val = src->ival; val <<= upshift; val += 128; if (val & ((-1)<<8)) val = (val<0)?0:(256-(1<<upshift)); *dest = (kdu_byte) val; } }}/*****************************************************************************//* STATIC convert_floats_to_words *//*****************************************************************************/static void convert_floats_to_words(kdu_sample32 *src, kdu_byte *dest, int num, int precision, bool is_signed, int sample_bytes){ kdu_int32 val; float scale, min, max, fval, offset; if (precision < 30) scale = (float)(1<<precision); else scale = ((float)(1<<30)) * ((float)(1<<(precision-30))); min = -0.5F; max = 0.5F - 1.0F/scale; offset = (is_signed)?0.0F:0.5F; offset = offset * scale + 0.5F; if (sample_bytes == 1) for (; num > 0; num--, src++) { fval = src->fval; fval = (fval>min)?fval:min; fval = (fval<max)?fval:max; val = (kdu_int32) floor(scale*fval + offset); *(dest++) = (kdu_byte) val; } else if (sample_bytes == 2) for (; num > 0; num--, src++) { fval = src->fval; fval = (fval>min)?fval:min; fval = (fval<max)?fval:max; val = (kdu_int32) floor(scale*fval + offset); *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else if (sample_bytes == 3) for (; num > 0; num--, src++) { fval = src->fval; fval = (fval>min)?fval:min; fval = (fval<max)?fval:max; val = (kdu_int32) floor(scale*fval + offset); *(dest++) = (kdu_byte)(val>>16); *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else if (sample_bytes == 4) for (; num > 0; num--, src++) { fval = src->fval; fval = (fval>min)?fval:min; fval = (fval<max)?fval:max; val = (kdu_int32) floor(scale*fval + offset); *(dest++) = (kdu_byte)(val>>24); *(dest++) = (kdu_byte)(val>>16); *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; } else assert(0);}/*****************************************************************************//* STATIC convert_fixpoint_to_words *//*****************************************************************************/static void convert_fixpoint_to_words(kdu_sample16 *src, kdu_byte *dest, int num, int precision, bool is_signed, int sample_bytes){ kdu_int32 val; kdu_int32 min, max; kdu_int32 downshift = KDU_FIX_POINT-precision; if (downshift < 0) { kdu_error e; e << "Cannot use 16-bit representation with high " "bit-depth data"; } kdu_int32 offset = 1<<downshift; offset += (is_signed)?0:(1<<(precision+downshift)); offset >>= 1; max = (1<<(KDU_FIX_POINT))>>1; min = -max; max -= 1<<downshift; if (sample_bytes == 1) for (; num > 0; num--, src++) { val = src->ival; val = (val < min)?min:val; val = (val >= max)?max:val; val = (val+offset)>>downshift; *(dest++) = (kdu_byte) val; } else if (sample_bytes == 2) for (; num > 0; num--, src++) { val = src->ival; val = (val < min)?min:val; val = (val >= max)?max:val; val = (val+offset)>>downshift; *(dest++) = (kdu_byte)(val>>8); *(dest++) = (kdu_byte) val; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -