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

📄 image_io_jpeg.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: image_io_jpeg.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:41:34  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8 * PRODUCTION * =========================================================================== *//*  $Id: image_io_jpeg.cpp,v 1000.3 2004/06/01 19:41:34 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: *    CImageIOJpeg -- interface class for reading/writing JPEG files */#include <ncbi_pch.hpp>#include "image_io_jpeg.hpp"#include <util/image/image.hpp>#include <util/image/image_exception.hpp>#ifdef HAVE_LIBJPEG////// JPEG SUPPORT////#include <stdio.h>// hack to get around duplicate definition of INT32#ifdef NCBI_OS_MSWIN#define XMD_H#endif// jpeglib include (not extern'ed already (!))extern "C" {#include <jpeglib.h>}BEGIN_NCBI_SCOPEstatic const int sc_JpegBufLen = 4096;static void s_JpegErrorHandler(j_common_ptr ptr){    string msg("Error processing JPEG image: ");    msg += ptr->err->jpeg_message_table[ptr->err->msg_code];    if (ptr->is_decompressor) {        NCBI_THROW(CImageException, eReadError, msg);    } else {        NCBI_THROW(CImageException, eWriteError, msg);    }}static void s_JpegOutputHandler(j_common_ptr ptr){    string msg("JPEG message: ");    msg += ptr->err->jpeg_message_table[ptr->err->msg_code];    LOG_POST(Warning << msg);}//// specialized internal structs used for reading/writing from streams//struct SJpegInput {    // the input data elements    struct jpeg_source_mgr pub;    // our buffer and stream    CNcbiIstream* stream;    JOCTET* buffer;};struct SJpegOutput {    // the input data elements    struct jpeg_destination_mgr pub;    // our buffer and stream    CNcbiOstream* stream;    JOCTET* buffer;};//// JPEG stream i/o handlers handlers//// initialize reading on the streamstatic void s_JpegReadInit(j_decompress_ptr cinfo){    struct SJpegInput* sptr = (SJpegInput*)cinfo->src;    // set up our buffer for the first read    sptr->pub.bytes_in_buffer = 0;    sptr->pub.next_input_byte = sptr->buffer;}// grab data from the streamstatic boolean s_JpegReadBuffer(j_decompress_ptr cinfo){    struct SJpegInput* sptr = (SJpegInput*)cinfo->src;    // read data from the stream    sptr->stream->read(reinterpret_cast<char*>(sptr->buffer), sc_JpegBufLen);    // reset our counts    sptr->pub.bytes_in_buffer = sptr->stream->gcount();    sptr->pub.next_input_byte = sptr->buffer;    return TRUE;}// skip over some data in an input stream (rare operation)static void s_JpegReadSkipData(j_decompress_ptr cinfo, long bytes){    struct SJpegInput* sptr = (SJpegInput*)cinfo->src;    if (bytes > 0) {        while (bytes > sptr->pub.bytes_in_buffer) {            bytes -= sptr->pub.bytes_in_buffer;            s_JpegReadBuffer(cinfo);        }        sptr->pub.next_input_byte += (size_t) bytes;        sptr->pub.bytes_in_buffer -= (size_t) bytes;    }}// finalize reading in a stream (no-op)static void s_JpegReadTerminate(j_decompress_ptr){    // don't need to do anything here}// initialize writing to a streamstatic void s_JpegWriteInit(j_compress_ptr cinfo){    struct SJpegOutput* sptr = (SJpegOutput*)cinfo->dest;    // set up our buffer for the first read    sptr->pub.next_output_byte = sptr->buffer;    sptr->pub.free_in_buffer   = sc_JpegBufLen;}// fill the input bufferstatic boolean s_JpegWriteBuffer(j_compress_ptr cinfo){    struct SJpegOutput* sptr = (SJpegOutput*)cinfo->dest;    // read data from the stream    sptr->stream->write(reinterpret_cast<const char*>(sptr->buffer),                        sc_JpegBufLen);    // reset our counts    sptr->pub.next_output_byte = sptr->buffer;    sptr->pub.free_in_buffer  = sc_JpegBufLen;    return TRUE;}// finalize our JPEG outputstatic void s_JpegWriteTerminate(j_compress_ptr cinfo){    // don't need to do anything here    struct SJpegOutput* sptr = (SJpegOutput*)cinfo->dest;    size_t datacount = sc_JpegBufLen - sptr->pub.free_in_buffer;    // read data from the stream    if (datacount > 0) {        sptr->stream->write(reinterpret_cast<const char*>(sptr->buffer),                            datacount);    }    sptr->stream->flush();    if ( !*(sptr->stream) ) {        NCBI_THROW(CImageException, eWriteError,                   "Error writing to JPEG stream");    }}//// set up our read structure to handle stream sources// this is provided in place of jpeg_stdio_src()//static void s_JpegReadSetup(j_decompress_ptr cinfo,                            CNcbiIstream& istr, JOCTET* buffer){    struct SJpegInput* sptr = NULL;    if (cinfo->src == NULL) {        cinfo->src =            (struct jpeg_source_mgr*)malloc(sizeof(SJpegInput));        sptr = (SJpegInput*)cinfo->src;    }    // allocate buffer and save our stream    sptr->stream = &istr;    sptr->buffer = buffer;    // set our callbacks    sptr->pub.init_source       = s_JpegReadInit;    sptr->pub.fill_input_buffer = s_JpegReadBuffer;    sptr->pub.skip_input_data   = s_JpegReadSkipData;    sptr->pub.resync_to_restart = jpeg_resync_to_restart;    sptr->pub.term_source       = s_JpegReadTerminate;    // make sure the structure knows we're just starting now    sptr->pub.bytes_in_buffer = 0;    sptr->pub.next_input_byte = buffer;}//// set up our read structure to handle stream sources// this is provided in place of jpeg_stdio_src()//static void s_JpegWriteSetup(j_compress_ptr cinfo,                             CNcbiOstream& ostr, JOCTET* buffer){    struct SJpegOutput* sptr = NULL;    if (cinfo->dest == NULL) {        cinfo->dest =            (struct jpeg_destination_mgr*)malloc(sizeof(SJpegOutput));        sptr = (SJpegOutput*)cinfo->dest;    }    // allocate buffer and save our stream    sptr->stream = &ostr;    sptr->buffer = buffer;    // set our callbacks    sptr->pub.init_destination    = s_JpegWriteInit;    sptr->pub.empty_output_buffer = s_JpegWriteBuffer;    sptr->pub.term_destination    = s_JpegWriteTerminate;    // make sure the structure knows we're just starting now    sptr->pub.free_in_buffer = sc_JpegBufLen;    sptr->pub.next_output_byte = buffer;}//// ReadImage()// read a JPEG format image into memory, returning the image itself// This version reads the entire image//CImage* CImageIOJpeg::ReadImage(CNcbiIstream& istr){    vector<JOCTET> buffer(sc_JpegBufLen);    JOCTET* buf_ptr = &buffer[0];    CRef<CImage> image;    // standard libjpeg stuff    struct jpeg_decompress_struct cinfo;    struct jpeg_error_mgr jerr;    try {        // open our file for reading        // set up the standard error handler        cinfo.err = jpeg_std_error(&jerr);        cinfo.err->error_exit = s_JpegErrorHandler;        cinfo.err->output_message = s_JpegOutputHandler;        jpeg_create_decompress(&cinfo);        // set up our standard stream processor        s_JpegReadSetup(&cinfo, istr, buf_ptr);        //jpeg_stdio_src(&cinfo, fp);        jpeg_read_header(&cinfo, TRUE);        // decompression parameters        cinfo.dct_method = JDCT_FLOAT;        jpeg_start_decompress(&cinfo);        // allocate an image to hold our data        image.Reset(new CImage(cinfo.output_width, cinfo.output_height, 3));        // we process the image 1 scanline at a time        unsigned char *scanline[1];        const size_t stride = cinfo.output_width * cinfo.out_color_components;        switch (cinfo.out_color_components) {        case 1:            {{                 unsigned char* data = image->SetData();                 vector<unsigned char> scan_buf(stride);                 scanline[0] = &scan_buf[0];                 for (size_t i = 0;  i < image->GetHeight();  ++i) {                     jpeg_read_scanlines(&cinfo, scanline, 1);                     for (size_t j = 0;  j < stride;  ++j) {                         *data++ = scanline[0][j];                         *data++ = scanline[0][j];                         *data++ = scanline[0][j];                     }                 }             }}            break;        case 3:            scanline[0] = image->SetData();            for (size_t i = 0;  i < image->GetHeight();  ++i) {                jpeg_read_scanlines(&cinfo, scanline, 1);                scanline[0] += stride;            }            break;        default:            NCBI_THROW(CImageException, eReadError,                       "CImageIOJpeg::ReadImage(): Unhandled color components");        }        // standard clean-up        jpeg_finish_decompress(&cinfo);        jpeg_destroy_decompress(&cinfo);    }    catch (...) {        // clean up our mess        jpeg_destroy_decompress(&cinfo);        throw;    }    return image.Release();}//// ReadImage()// read a JPEG format image into memory, returning the image itself// This version reads only a subset of the image//CImage* CImageIOJpeg::ReadImage(CNcbiIstream& istr,                                size_t x, size_t y, size_t w, size_t h){    vector<JOCTET> buffer(sc_JpegBufLen);    JOCTET* buf_ptr = &buffer[0];

⌨️ 快捷键说明

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