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

📄 image_io_gif.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: image_io_gif.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:41:27  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6 * PRODUCTION * =========================================================================== *//*  $Id: image_io_gif.cpp,v 1000.3 2004/06/01 19:41:27 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: *    CImageIOGif -- interface class for reading/writing CompuServ GIF files *///// we include gif_lib.h first because of a conflict with windows.h// (DrawText() is both a giflib function and a Win32 GDI function)//#include <ncbi_pch.hpp>#include <ncbiconf.h>#ifdef HAVE_LIBGIF// alas, poor giflib... it isn't extern'edextern "C" {#  include <gif_lib.h>    /// !@#$%^ libunfig mis-spelled the prototype in their header,    /// so we must add it here    GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc);};#endif#include "image_io_gif.hpp"#include <util/image/image.hpp>#include <util/image/image_exception.hpp>#ifdef HAVE_LIBGIF////// LIBGIF support////BEGIN_NCBI_SCOPEstatic int s_GifRead(GifFileType* file, GifByteType* data, int len){    CNcbiIstream* istr = reinterpret_cast<CNcbiIstream*>(file->UserData);    if (istr) {        istr->read(reinterpret_cast<char*>(data), len);        return istr->gcount();    }    return -1;}static int s_GifWrite(GifFileType* file, const GifByteType* data, int len){    CNcbiOstream* ostr = reinterpret_cast<CNcbiOstream*>(file->UserData);    if (ostr) {        ostr->write(reinterpret_cast<const char*>(data), len);        if ( *ostr ) {            return len;        }    }    return -1;}//// ReadImage()// read an entire GIF image into memory.  This will read only the first image// in an image set.//CImage* CImageIOGif::ReadImage(CNcbiIstream& istr){    GifFileType* fp = NULL;    CRef<CImage> image;    try {        // open our file for reading        fp = DGifOpen(&istr, s_GifRead);        if ( !fp ) {            NCBI_THROW(CImageException, eReadError,                       "CImageIOGif::ReadImage(): "                       "cannot open file for reading");        }        // allocate an image        image.Reset(new CImage(fp->SWidth, fp->SHeight, 3));        memset(image->SetData(), fp->SBackGroundColor,               image->GetWidth() * image->GetHeight() * image->GetDepth());        // we also allocate a single row        // this row is a color indexed row, and will be decoded row-by-row into the        // image        vector<unsigned char> row_data(image->GetWidth());        unsigned char* row_ptr = &row_data[0];        bool done = false;        while ( !done ) {            // determine what sort of record type we have            // these can be image, extension, or termination            GifRecordType type;            if (DGifGetRecordType(fp, &type) == GIF_ERROR) {                NCBI_THROW(CImageException, eReadError,                    "CImageIOGif::ReadImage(): error reading file");            }            switch (type) {            case IMAGE_DESC_RECORD_TYPE:                //                // we only support the first image in a gif                //                if (DGifGetImageDesc(fp) == GIF_ERROR) {                    NCBI_THROW(CImageException, eReadError,                        "CImageIOGif::ReadImage(): error reading file");                }                if (fp->Image.Interlace) {                    // interlaced images are a bit more complex                    size_t row = fp->Image.Top;                    size_t col = fp->Image.Left;                    size_t wid = fp->Image.Width;                    size_t ht  = fp->Image.Height;                    static int interlaced_offs[4] = { 0, 4, 2, 1 };                    static int interlaced_jump[4] = { 8, 8, 4, 2 };                    for (size_t i = 0;  i < 4;  ++i) {                        for (size_t j = row + interlaced_offs[i];                             j < row + ht;  j += interlaced_jump[i]) {                            x_ReadLine(fp, row_ptr);                            x_UnpackData(fp, row_ptr,                                         image->SetData() +                                         (j * wid + col) * image->GetDepth());                        }                    }                } else {                    size_t col = fp->Image.Left;                    size_t wid = fp->Image.Width;                    size_t ht  = fp->Image.Height;                    for (size_t i = 0;  i < ht;  ++i) {                        x_ReadLine(fp, row_ptr);                        x_UnpackData(fp, row_ptr,                                     image->SetData() +                                     (i * wid + col) * image->GetDepth());                    }                }                break;            case EXTENSION_RECORD_TYPE:                {{                     int ext_code;                     GifByteType* extension;                     // we ignore extension blocks                     if (DGifGetExtension(fp, &ext_code, &extension) == GIF_ERROR) {                         NCBI_THROW(CImageException, eReadError,                                    "CImageIOGif::ReadImage(): "                                    "error reading file");                     }                     while (extension != NULL) {                         if (DGifGetExtensionNext(fp, &extension) == GIF_OK) {                             continue;                         }                         NCBI_THROW(CImageException, eReadError,                                    "CImageIOGif::ReadImage(): "                                    "error reading file");                     }                 }}                break;            default:                // terminate record - break our of our while()                done = true;                break;            }        }        // close up and exit        DGifCloseFile(fp);    }    catch (...) {        DGifCloseFile(fp);        fp = NULL;        throw;    }    return image.Release();}//// ReadImage// this version returns a sub-image from the desired image.//CImage* CImageIOGif::ReadImage(CNcbiIstream& istr,                               size_t x, size_t y, size_t w, size_t h){    // we use a brain-dead implementation here - this can be done in a more    // memory-efficient manner...    CRef<CImage> image(ReadImage(istr));    return image->GetSubImage(x, y, w, h);}//// WriteImage()// this writes out a GIF image.//void CImageIOGif::WriteImage(const CImage& image, CNcbiOstream& ostr,                             CImageIO::ECompress){    if ( !image.GetData() ) {        NCBI_THROW(CImageException, eWriteError,                   "CImageIOGif::WriteImage(): "                   "cannot write empty image to file");    }    ColorMapObject* cmap = NULL;    GifFileType* fp = NULL;    try {        // first, we need to split our image into red/green/blue channels        // we do this to get proper GIF quantization        size_t size = image.GetWidth() * image.GetHeight();        vector<unsigned char> red  (size);        vector<unsigned char> green(size);        vector<unsigned char> blue (size);

⌨️ 快捷键说明

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