📄 image_io_tiff.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: image_io_tiff.cpp,v $ * PRODUCTION Revision 1000.4 2004/06/01 19:41:46 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9 * PRODUCTION * =========================================================================== *//* $Id: image_io_tiff.cpp,v 1000.4 2004/06/01 19:41:46 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Mike DiCuccio * * File Description: * CImageIOTiff -- interface class for reading/writing TIFF files */#include <ncbi_pch.hpp>#include "image_io_tiff.hpp"#include <corelib/ncbifile.hpp>#include <util/image/image.hpp>#include <util/image/image_exception.hpp>#ifdef HAVE_LIBTIFF////// LIBTIFF functions////#include <tiffio.h>BEGIN_NCBI_SCOPE//// TIFFlib error / warning handlers//static void s_TiffReadErrorHandler(const char* module, const char* fmt, va_list args){ string msg("Error reading TIFF image: "); msg += module; msg += ": "; msg += NStr::FormatVarargs(fmt, args); NCBI_THROW(CImageException, eReadError, msg);}static void s_TiffWriteErrorHandler(const char* module, const char* fmt, va_list args){ string msg("Error writing TIFF image: "); msg += module; msg += ": "; msg += NStr::FormatVarargs(fmt, args); NCBI_THROW(CImageException, eWriteError, msg);}static void s_TiffWarningHandler(const char* module, const char* fmt, va_list args){ string msg = module; msg += ": "; msg += NStr::FormatVarargs(fmt, args); LOG_POST(Warning << "Warning reading TIFF image: " << msg);}//// TIFFLib i/o handlers//static tsize_t s_TIFFReadHandler(thandle_t handle, tdata_t data, tsize_t len){ CNcbiIfstream* istr = reinterpret_cast<CNcbiIfstream*>(handle); if (istr) { istr->read(reinterpret_cast<char*>(data), len); return istr->gcount(); } return 0;}static tsize_t s_TIFFWriteHandler(thandle_t handle, tdata_t data, tsize_t len){ std::ofstream* ostr = reinterpret_cast<std::ofstream*>(handle); if (ostr) { ostr->write(reinterpret_cast<char*>(data), len); if (*ostr) { return len; } } return -1;}// dummy i/o handler. TIFFLib tries to read from files opened for writingstatic tsize_t s_TIFFDummyIOHandler(thandle_t, tdata_t, tsize_t){ return -1;}static toff_t s_TIFFSeekHandler(thandle_t handle, toff_t offset, int whence){ CNcbiIfstream* istr = reinterpret_cast<CNcbiIfstream*>(handle); if (istr) { switch (whence) { case SEEK_SET: istr->seekg(offset, ios::beg); break; case SEEK_CUR: istr->seekg(offset, ios::cur); break; case SEEK_END: istr->seekg(offset, ios::end); break; } return istr->tellg() - CT_POS_TYPE(0); } return (toff_t)-1;}static int s_TIFFCloseHandler(thandle_t handle){ std::ofstream* ostr = reinterpret_cast<std::ofstream*>(handle); if (ostr) { ostr->flush(); if ( !*ostr ) { return -1; } } return 0;}static toff_t s_TIFFSizeHandler(thandle_t handle){ toff_t offs = 0; CNcbiIfstream* istr = reinterpret_cast<CNcbiIfstream*>(handle); if (istr) { CT_POS_TYPE curr_pos = istr->tellg(); istr->seekg(0, ios::end); offs = istr->tellg() - CT_POS_TYPE(0); istr->seekg(curr_pos); } return offs;}static int s_TIFFMapFileHandler(thandle_t, tdata_t*, toff_t*){ return -1;}static void s_TIFFUnmapFileHandler(thandle_t, tdata_t, toff_t){}//// ReadImage()// read an image in TIFF format. This uses a fairly inefficient read, in that// the data, once read, must be copied into the actual image. This is largely// the result of a reliance on a particular function (TIFFReadRGBAImage()); the// implementation details may change at a future date to use a more efficient// read mechanism//CImage* CImageIOTiff::ReadImage(CNcbiIstream& istr){ TIFF* tiff = NULL; uint32* raster = NULL; TIFFErrorHandler old_err_handler = NULL; TIFFErrorHandler old_warn_handler = NULL; CRef<CImage> image; try { old_err_handler = TIFFSetErrorHandler(&s_TiffReadErrorHandler); old_warn_handler = TIFFSetWarningHandler(&s_TiffWarningHandler); // open our file tiff = TIFFClientOpen("", "rm", reinterpret_cast<thandle_t>(&istr), s_TIFFReadHandler, s_TIFFDummyIOHandler, s_TIFFSeekHandler, s_TIFFCloseHandler, s_TIFFSizeHandler, s_TIFFMapFileHandler, s_TIFFUnmapFileHandler); if ( !tiff ) { NCBI_THROW(CImageException, eReadError, "CImageIOTiff::ReadImage(): error opening file "); } // extract the size parameters int width = 0; int height = 0; int depth = 0; TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &depth); if (depth != 1 && depth != 3 && depth != 4) { string msg("CImageIOTiff::ReadImage(): unhandled image depth: "); msg += NStr::IntToString(depth); NCBI_THROW(CImageException, eReadError, msg); } // NB: we treat single plane images as RGB if (depth == 1) { depth = 3; } // allocate a temporary buffer for the image raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32)); if ( !TIFFReadRGBAImage(tiff, width, height, raster, 1) ) { _TIFFfree(raster); NCBI_THROW(CImageException, eReadError, "CImageIOTiff::ReadImage(): error reading file"); } // now we need to copy this data and pack it appropriately // according to the TIFFRGBAImage man page, TIFFRGBAImage and // TIFFReadRGBAImage create the image in *RASTER* format - i.e., // with (0, 0) being the lower-left corner, not the upper-left // corner as everyone else in the world expects image = new CImage(width, height, depth); unsigned char* data = image->SetData(); for (size_t j = 0; j < height; ++j) { // implicit inversion size_t from_idx_base = j * width; size_t to_idx_base = (height - j - 1) * width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -