📄 image_io_gif.cpp
字号:
unsigned char* red_ptr = &red[0]; unsigned char* green_ptr = &green[0]; unsigned char* blue_ptr = &blue[0]; const unsigned char* from_data = image.GetData(); const unsigned char* end_data = image.GetData() + size * image.GetDepth(); switch (image.GetDepth()) { case 3: {{ for ( ; from_data != end_data; ) { *red_ptr++ = *from_data++; *green_ptr++ = *from_data++; *blue_ptr++ = *from_data++; } }} break; case 4: {{ LOG_POST(Warning << "CImageIOGif::WriteImage(): " "ignoring alpha channel"); for ( ; from_data != end_data; ) { *red_ptr++ = *from_data++; *green_ptr++ = *from_data++; *blue_ptr++ = *from_data++; // alpha channel ignored - should we use this to compute a // scaled rgb? ++from_data; } }} break; default: NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): unsupported image depth"); } // reset the color channel pointers! red_ptr = &red[0]; green_ptr = &green[0]; blue_ptr = &blue[0]; // now, create a GIF color map object int cmap_size = 256; cmap = MakeMapObject(cmap_size, NULL); if ( !cmap ) { NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): failed to allocate color map"); } // we also allocate a strip of data to hold the indexed colors vector<unsigned char> qdata(size); unsigned char* qdata_ptr = &qdata[0]; // quantize our colors if (QuantizeBuffer(image.GetWidth(), image.GetHeight(), &cmap_size, red_ptr, green_ptr, blue_ptr, qdata_ptr, cmap->Colors) == GIF_ERROR) { free(cmap); NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): failed to quantize image"); } // // we are now ready to write our file // // open our file fp = EGifOpen(&ostr, s_GifWrite); if ( !fp ) { NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): failed to open file"); } // write the GIF screen description if (EGifPutScreenDesc(fp, image.GetWidth(), image.GetHeight(), 8, 0, cmap) == GIF_ERROR) { NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): failed to write GIF screen " "description"); } // write the GIF image description if (EGifPutImageDesc(fp, 0, 0, image.GetWidth(), image.GetHeight(), false, NULL) == GIF_ERROR) { NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): failed to write GIF image " "description"); } // put our data for (size_t i = 0; i < image.GetHeight(); ++i) { if (EGifPutLine(fp, qdata_ptr, image.GetWidth()) == GIF_ERROR) { string msg("CImageIOGif::WriteImage(): error writing line "); msg += NStr::IntToString(i); NCBI_THROW(CImageException, eWriteError, msg); } qdata_ptr += image.GetWidth(); } // clean-up and close if (EGifCloseFile(fp) == GIF_ERROR) { fp = NULL; NCBI_THROW(CImageException, eWriteError, "CImageIOGif::WriteImage(): error closing file"); } free(cmap); } catch (...) { if (fp) { if (EGifCloseFile(fp) == GIF_ERROR) { LOG_POST(Error << "CImageIOGif::WriteImage(): error closing file"); } fp = NULL; } if (cmap) { free(cmap); cmap = NULL; } throw; }}//// WriteImage()// this writes out a sub-image as a GIF file. We use a brain-dead// implementation currently - subset the image and write it out, rather than// simply quantizing just the sub-image's data//void CImageIOGif::WriteImage(const CImage& image, CNcbiOstream& ostr, size_t x, size_t y, size_t w, size_t h, CImageIO::ECompress compress){ CRef<CImage> subimage(image.GetSubImage(x, y, w, h)); WriteImage(*subimage, ostr, compress);}//// x_UnpackData()// this function de-indexes a GIF image's color table, expanding the values// into RGB tuples//void CImageIOGif::x_UnpackData(GifFileType* fp, const unsigned char* from_data, unsigned char* to_data){ struct ColorMapObject* cmap = (fp->Image.ColorMap ? fp->Image.ColorMap : fp->SColorMap); for (int i = 0; i < fp->Image.Width; ++i) { *to_data++ = cmap->Colors[ from_data[i] ].Red; *to_data++ = cmap->Colors[ from_data[i] ].Green; *to_data++ = cmap->Colors[ from_data[i] ].Blue; }}//// x_ReadLine()// read a single line from a GIF file//void CImageIOGif::x_ReadLine(GifFileType* fp, unsigned char* data){ if ( DGifGetLine(fp, data, fp->Image.Width) == GIF_ERROR) { DGifCloseFile(fp); string msg("CImageIOGif::ReadImage(): error reading file"); NCBI_THROW(CImageException, eReadError, msg); }}END_NCBI_SCOPE#else // HAVE_LIBGIF//// LIBGIF not supported//BEGIN_NCBI_SCOPECImage* CImageIOGif::ReadImage(CNcbiIstream&){ NCBI_THROW(CImageException, eUnsupported, "CImageIOGif::ReadImage(): GIF format read unimplemented");}CImage* CImageIOGif::ReadImage(CNcbiIstream&, size_t, size_t, size_t, size_t){ NCBI_THROW(CImageException, eUnsupported, "CImageIOGif::ReadImage(): GIF format partial " "read unimplemented");}void CImageIOGif::WriteImage(const CImage&, CNcbiOstream&, CImageIO::ECompress){ NCBI_THROW(CImageException, eUnsupported, "CImageIOGif::WriteImage(): GIF format write unimplemented");}void CImageIOGif::WriteImage(const CImage&, CNcbiOstream&, size_t, size_t, size_t, size_t, CImageIO::ECompress){ NCBI_THROW(CImageException, eUnsupported, "CImageIOGif::WriteImage(): GIF format partial " "write unimplemented");}END_NCBI_SCOPE#endif // !HAVE_LIBGIF/* * =========================================================================== * $Log: image_io_gif.cpp,v $ * Revision 1000.3 2004/06/01 19:41:27 gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6 * * Revision 1.6 2004/05/17 21:07:58 gorelenk * Added include of PCH ncbi_pch.hpp * * Revision 1.5 2003/12/16 15:49:36 dicuccio * Large re-write of image handling. Added improved error-handling and support * for streams-based i/o (via hooks into each client library). * * Revision 1.4 2003/11/03 15:19:57 dicuccio * Added optional compression parameter * * Revision 1.3 2003/07/01 12:08:44 dicuccio * Compilation fixes for MSVC * * Revision 1.2 2003/06/09 19:28:17 dicuccio * Fixed compilation error - conversion from const char* to char* required for * gif_lib * * Revision 1.1 2003/06/03 15:17:13 dicuccio * Initial revision of image library * * =========================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -