glcgi_image.cpp

来自「ncbi源码」· C++ 代码 · 共 321 行

CPP
321
字号
/* * =========================================================================== * PRODUCTION $Log: glcgi_image.cpp,v $ * PRODUCTION Revision 1000.2  2004/06/01 20:53:02  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * PRODUCTION * =========================================================================== *//*  $Id: glcgi_image.cpp,v 1000.2 2004/06/01 20:53:02 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. * * =========================================================================== * * Author:  Denis Vakatov * * File Description: *    CGlCgiImage -- base class for producing images via a CGI using OpenGL */#include <ncbi_pch.hpp>#include <gui/opengl/mesa/glcgi_image.hpp>#include <gui/opengl/mesa/gloscontext.hpp>#include <html/page.hpp>#include <util/image/image.hpp>#include <util/image/image_util.hpp>#include <util/image/image_io.hpp>BEGIN_NCBI_SCOPE//// content-type headers for images//struct SContentType{    CImageIO::EType m_Type;    const char* m_Encoding;};static const SContentType kContentTypes[] = {    { CImageIO::eBmp,  "image/bmp" },    { CImageIO::eGif,  "image/gif" },    { CImageIO::eJpeg, "image/jpeg" },    { CImageIO::ePng,  "image/png" },    { CImageIO::eSgi,  "image/sgi" },    { CImageIO::eTiff, "image/tiff" },    { CImageIO::eXpm,  "image/xmp" },    // must be last    { CImageIO::eUnknown, NULL }};//// default error template// this can be replaced as needed////// default ctor//CGlCgiImageApplication::CGlCgiImageApplication()    : m_Width (800),      m_Height(600),      m_Format(CImageIO::ePng){}CGlCgiImageApplication::~CGlCgiImageApplication(){}//// get our aspect ratio//float CGlCgiImageApplication::GetAspectRatio(void) const{    if (m_Context) {        size_t width  = m_Context->GetBuffer().GetWidth();        size_t height = m_Context->GetBuffer().GetHeight();        return (float)width / (float)height;    }    return 1.0f;}//// Init()// Initialize our renderer to a default size (800x600 pixels)void CGlCgiImageApplication::Init(){    m_ErrorTemplate = GetConfig().Get("filesystem", "ErrorTemplate");}CGlOsContext& CGlCgiImageApplication::x_GetContext(void){    if ( !m_Context ) {        // create an off-screen renderer that handles a virtual frame buffer        m_Context.Reset(new CGlOsContext(m_Width, m_Height));    }    return *m_Context;}//// ProcessRequest()// Here, we do a minimal amount of set-up and pass off to our rendering hook.// When this hook completes, we write out the resulting image to the response.//int CGlCgiImageApplication::ProcessRequest(CCgiContext& ctx){    CStopWatch sw;    sw.Start();    double render_time = 0;    double image_flip_time = 0;    try {        // user hook: pre-rpocess        x_PreProcess(ctx);        // create an off-screen renderer that handles a virtual frame buffer        if ( !x_GetContext().MakeCurrent() ) {            LOG_POST(Error << "CGlCgiImageApplication::ProcessRequest(): "                     "Failed to make off-screen renderer current");            return 1;        }        // call the rendering hook        Render(ctx);        // call glFinish() - VERY IMPORTANT FOR OFF_SCREEN RENDERING        // this forces any buffered OpenGL requests to complete now.        glFinish();        render_time = sw.Elapsed();        // final image preparation        // the image is upside-down because frame buffers are, in general,        // upside-down.  Also, we have an alpha channel we need to flatten.        m_Context->SetBuffer().SetDepth(3);        CImageUtil::FlipY(m_Context->SetBuffer());        image_flip_time = sw.Elapsed();        // user hook: post-process        x_PostProcess(ctx);    }    catch (CException& e) {        x_HandleError(ctx, e.GetMsg());        return 1;    }    catch (exception& e) {        x_HandleError(ctx, e.what());        return 1;    }#ifndef _DEBUG    catch (...) {        x_HandleError(ctx, "unknown error");        return 1;    }#endif    //    // and stream back the image    // this requires that we first write the image to a temporary file and then    // echo the contents of this image back    //    // don't forget to set our content-type    string encoding("image/unknown");    for (const SContentType* type = kContentTypes;  type->m_Encoding;  ++type) {        if (type->m_Type == m_Format) {            encoding = type->m_Encoding;            break;        }    }    CCgiResponse& response = ctx.GetResponse();    response.SetContentType(encoding);    //    // write the standard CGI headers    // if this line is commented out, the image will be dumped to stdout anc    // can be redirected to a file for local access    //    response.WriteHeader();    //    // write the image    // we wrap the management of the temporary file in a class in case one of    // our operations throws; this way, the stack unwinding for the exception    // will insure that our temporary file gets cleaned up    //    CImageIO::WriteImage(m_Context->GetBuffer(), response.out(), m_Format);    double image_encode_time = sw.Elapsed();    LOG_POST(Info << "CGlCgiImage::ProcessRequest():\n"             << "  render time  = " << render_time << "\n"             << "  process time = " << image_flip_time - render_time << "\n"             << "  encode time  = " << image_encode_time - image_flip_time << "\n");    return 0;}void CGlCgiImageApplication::x_HandleError(CCgiContext& ctx,                                           const string& msg){    CCgiResponse& response = ctx.GetResponse();    response.SetContentType("text/html");    response.WriteHeader();    if (m_ErrorTemplate.empty()) {        CHTMLPage page("CGI Error", m_ErrorTemplate);        page.AppendChild(new CHTMLPlainText(msg));        page.Print(response.out());    } else {        CHTMLPage page("", m_ErrorTemplate);        page.AddTagMap("message", new CHTMLPlainText(msg));        page.Print(response.out());    }}void CGlCgiImageApplication::x_PreProcess(CCgiContext& ctx){    // set the width and height from the 'width=' and 'height=' keys    {{         TCgiEntries::const_iterator width_iter =             ctx.GetRequest().GetEntries().find("width");         if (width_iter != ctx.GetRequest().GetEntries().end()) {             m_Width = NStr::StringToInt(width_iter->second);         }         TCgiEntries::const_iterator height_iter =             ctx.GetRequest().GetEntries().find("height");         if (height_iter != ctx.GetRequest().GetEntries().end()) {             m_Height = NStr::StringToInt(height_iter->second);         }     }}    // set the image format using the 'fmt=' key    TCgiEntries::const_iterator fmt_iter =        ctx.GetRequest().GetEntries().find("fmt");    if (fmt_iter != ctx.GetRequest().GetEntries().end()) {        string fmt(fmt_iter->second);        fmt = "." + fmt;        m_Format = CImageIO::GetTypeFromFileName(fmt);    }}void CGlCgiImageApplication::x_PostProcess(CCgiContext& ctx){}END_NCBI_SCOPE/* * =========================================================================== * $Log: glcgi_image.cpp,v $ * Revision 1000.2  2004/06/01 20:53:02  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7 * * Revision 1.7  2004/05/21 22:27:45  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.6  2004/04/08 13:40:52  dicuccio * Wrapped context creation in a simple function * * Revision 1.5  2004/03/22 17:40:57  dicuccio * Added generic error handling. * * Revision 1.4  2004/01/20 12:10:23  dicuccio * Added user hooks for process request.  Moved off-screen context creation into ProcessRequest() * * Revision 1.3  2004/01/08 12:01:14  dicuccio * Use CImageUtil::FlipY() instead of CImage::Flip().  Use direct stream write * instead of writing to a temporary file. * * Revision 1.2  2003/06/12 19:47:00  dicuccio * Added better management of temporary files, internal timing for rendering * components * * Revision 1.1  2003/06/09 19:21:44  dicuccio * Initial revision * * =========================================================================== */

⌨️ 快捷键说明

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