⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image_io_png.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: image_io_png.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:41:37  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//*  $Id: image_io_png.cpp,v 1000.3 2004/06/01 19:41:37 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: *    CImageIOPng -- interface class for reading/writing PNG files */#include <ncbi_pch.hpp>#include "image_io_png.hpp"#include <util/image/image.hpp>#include <util/image/image_exception.hpp>#ifdef HAVE_LIBPNG////// PNG SUPPORT////// libpng main header#include <png.h>BEGIN_NCBI_SCOPE//// internal message handler for PNG images//static void s_PngReadErrorHandler(png_structp png_ptr, png_const_charp msg){    string str("Error reading PNG file: ");    str += msg;    NCBI_THROW(CImageException, eReadError, str);}//// internal message handler for PNG images//static void s_PngWriteErrorHandler(png_structp png_ptr, png_const_charp msg){    string str("Error writing PNG file: ");    str += msg;    NCBI_THROW(CImageException, eWriteError, str);}//// internal handler: translate PNG warnings to NCBI warnings//static void s_PngWarningHandler(png_structp png_ptr, png_const_charp msg){    LOG_POST(Warning << "Warning in PNG file: " << msg);}//// initialize PNG reading//static void s_PngReadInit(png_structp& png_ptr,                          png_infop&   info_ptr,                          png_infop&   end_info_ptr){    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,                                     s_PngReadErrorHandler,                                     s_PngWarningHandler);    if ( !png_ptr ) {        NCBI_THROW(CImageException, eReadError,                   "CImageIOPng::ReadImage(): png_create_read_struct() failed");    }    info_ptr = png_create_info_struct(png_ptr);    if ( !info_ptr ) {        NCBI_THROW(CImageException, eReadError,                   "CImageIOPng::ReadImage(): png_create_info_struct() failed");    }    end_info_ptr = png_create_info_struct(png_ptr);    if ( !end_info_ptr ) {        NCBI_THROW(CImageException, eReadError,                   "CImageIOPng::ReadImage(): png_create_info_struct() failed");    }}//// initialize PNG writing//static void s_PngWriteInit(png_structp& png_ptr,                           png_infop&   info_ptr,                           const CImage& image,                           CImageIO::ECompress compress){    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,                                      s_PngWriteErrorHandler,                                      s_PngWarningHandler);    if ( !png_ptr ) {        NCBI_THROW(CImageException, eWriteError,                   "CImageIOPng::WriteImage(): png_create_read_struct() failed");    }    info_ptr = png_create_info_struct(png_ptr);    if ( !info_ptr ) {        NCBI_THROW(CImageException, eWriteError,                   "CImageIOPng::WriteImage(): png_create_info_struct() failed");    }    png_byte color_type = PNG_COLOR_TYPE_RGB;    if (image.GetDepth() == 4) {        color_type = PNG_COLOR_TYPE_RGBA;    }    png_set_IHDR(png_ptr, info_ptr,                 image.GetWidth(), image.GetHeight(), 8, color_type,                 PNG_INTERLACE_NONE,                 PNG_COMPRESSION_TYPE_BASE,                 PNG_FILTER_TYPE_BASE);    // set our compression quality    switch (compress) {    case CImageIO::eCompress_None:        png_set_compression_level(png_ptr, Z_NO_COMPRESSION);        break;    case CImageIO::eCompress_Low:        png_set_compression_level(png_ptr, Z_BEST_SPEED);        break;    case CImageIO::eCompress_Medium:        png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);        break;    case CImageIO::eCompress_High:        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);        break;    default:        LOG_POST(Error << "unknown compression type: " << (int)compress);        break;    }}//// validate our input//static void s_PngReadValidate(png_structp png_ptr,                              png_infop info_ptr,                              size_t& width,                              size_t& height,                              size_t& depth,                              size_t& x, size_t& y, size_t& w, size_t& h){    // store and validate our image's parameters    width        = info_ptr->width;    height       = info_ptr->height;    depth        = info_ptr->channels;    png_byte color_type = info_ptr->color_type;    png_byte bit_depth  = info_ptr->bit_depth;    // we support only RGB and RGBA images    if ( color_type != PNG_COLOR_TYPE_RGB  &&         color_type != PNG_COLOR_TYPE_RGB_ALPHA ) {        string msg("CImageIOPng::ReadImage(): unhandled color type: ");        msg += NStr::IntToString((int)color_type);        NCBI_THROW(CImageException, eReadError, msg);    }    // ...and only with a bit depth of 8    if (bit_depth != 8) {        string msg("CImageIOPng::ReadImage(): unhandled bit depth: ");        msg += NStr::IntToString((int)bit_depth);        NCBI_THROW(CImageException, eReadError, msg);    }    // this goes along with RGB or RGBA    if (depth != 3  &&  depth != 4) {        string msg("CImageIOPng::ReadImage(): unhandled image channels: ");        msg += NStr::IntToString((int)depth);        NCBI_THROW(CImageException, eReadError, msg);    }    if (x != -1  &&  y != -1  &&  w != -1  &&  h != -1) {        // further validation: make sure we're actually on the image        if (x >= width  ||  y >= height) {            string msg("CImageIOPng::ReadImage(): invalid starting position: ");            msg += NStr::IntToString(x);            msg += ", ";            msg += NStr::IntToString(y);            NCBI_THROW(CImageException, eReadError, msg);        }        // clamp our width and height to the image size        if (x + w >= width) {            w = width - x;            LOG_POST(Warning                     << "CImageIOPng::ReadImage(): clamped width to " << w);        }        if (y + h >= height) {            h = height - y;            LOG_POST(Warning                     << "CImageIOPng::ReadImage(): clamped height to " << h);        }    }    png_read_update_info(png_ptr, info_ptr);}//// our local i/o handlers//static void s_PngRead(png_structp png_ptr, png_bytep data, png_size_t len){    CNcbiIfstream* istr =        reinterpret_cast<CNcbiIfstream*>(png_get_io_ptr(png_ptr));    if (istr) {        istr->read(reinterpret_cast<char*>(data), len);    }}static void s_PngWrite(png_structp png_ptr, png_bytep data, png_size_t len){    CNcbiOfstream* ostr =        reinterpret_cast<CNcbiOfstream*>(png_get_io_ptr(png_ptr));    if (ostr) {        ostr->write(reinterpret_cast<char*>(data), len);    }}static void s_PngFlush(png_structp png_ptr){    CNcbiOfstream* ostr =        reinterpret_cast<CNcbiOfstream*>(png_get_io_ptr(png_ptr));    if (ostr) {        ostr->flush();    }}//// finalize our structures//static void s_PngReadFinalize(png_structp& png_ptr,                              png_infop&   info_ptr,                              png_infop&   end_info_ptr){    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);}static void s_PngWriteFinalize(png_structp& png_ptr,                              png_infop&    info_ptr){    png_destroy_write_struct(&png_ptr, &info_ptr);}//// ReadImage()// read a PNG format image into memory, returning the image itself// This version reads the entire image//CImage* CImageIOPng::ReadImage(CNcbiIstream& istr){    png_structp png_ptr  = NULL;    png_infop   info_ptr = NULL;    png_infop   end_ptr  = NULL;    CRef<CImage> image;    try {        // create our PNG structures        s_PngReadInit(png_ptr, info_ptr, end_ptr);        // begin reading our image        png_set_read_fn(png_ptr, &istr, s_PngRead);        png_read_info(png_ptr, info_ptr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -