Mercurial > hg > aimc
view src/Modules/Output/Graphics/Devices/GraphicsOutputDevicePlotutils.cc @ 126:a9cb396529c2
- Added support for movies!
author | tomwalters |
---|---|
date | Thu, 21 Oct 2010 01:46:39 +0000 |
parents | c5ac2f0c7fc5 |
children | 73c6d61440ad |
line wrap: on
line source
// Copyright 2006, Willem van Engen // // AIM-C: A C++ implementation of the Auditory Image Model // http://www.acousticscale.org/AIMC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /*! * \file * \brief Output device for output to a graphics file using plotutils * * \author Willem van Engen <cnbh@willem.engen.nl> * \date created 2006/10/13 * \version \$Id: GraphicsOutputDevicePlotutils.cpp 493 2007-11-27 10:59:20Z tom $ */ #include "Support/Common.h" #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <stdio.h> #include <math.h> #include "Support/util.h" #include "Modules/Output/Graphics/Devices/GraphicsOutputDevicePlotutils.h" GraphicsOutputDevicePlotutils::GraphicsOutputDevicePlotutils(Parameters *pParam) : GraphicsOutputDevice(pParam) { m_iPlotHandle = 0; m_pOutputFile = NULL; m_iFileNumber = 0; m_iVertexType = VertexTypeNone; m_bUseMemoryBuffer = false; m_pMemoryBuffer = NULL; m_uWidth=0; m_uHeight=0; } bool GraphicsOutputDevicePlotutils::Initialize(const char *sDir) { Init(); //! \todo Output to file if sDir is a file, to directory with multiple //! images if it's a directory. strncpy(m_sDir, sDir, sizeof(m_sDir)/sizeof(m_sDir[0])); /* Try to open an image to see if everything is allright. We want to avoid * errors in the main Process()ing loop. */ if (!OpenFile(0)) { //! \todo Better error message that is more specific about the cause. AIM_ERROR(_T("Could not open output directory '%s' using graphics format '%s'."), m_sDir, m_pParam->GetString("output.img.format") ); return false; } CloseFile(); return true; } void GraphicsOutputDevicePlotutils::Init() { AIM_ASSERT(m_pParam); /* * Set parameters */ pl_parampl("BG_COLOR", (void*)m_pParam->GetString("output.img.color.background")); // Handle GIFs as other output formats, don't merge frames into single GIF. pl_parampl("GIF_ANIMATION", (void*)"no"); pl_parampl("INTERLACE", (void*)"no"); m_bInvertColors = m_pParam->GetBool("output.img.color.invert"); // Output size! m_uWidth = m_pParam->GetUInt("output.img.width"); m_uHeight = m_pParam->GetUInt("output.img.height"); char strSize[100]; snprintf(strSize, sizeof(strSize)/sizeof(strSize[0]), "%ux%u", m_uWidth, m_uHeight); pl_parampl("BITMAPSIZE", (void*)strSize); } bool GraphicsOutputDevicePlotutils::Initialize() { Init(); m_bUseMemoryBuffer = true; return(true); } bool GraphicsOutputDevicePlotutils::OpenFile(unsigned int index) { const char *strPlottype = m_pParam->GetString("output.img.format"); if (!m_bUseMemoryBuffer) { char sFilename[PATH_MAX]; struct stat fileinfo; // Get filename without trailing slash strncpy(sFilename, m_sDir, sizeof(sFilename)/sizeof(sFilename[0])); #ifdef _WINDOWS if (sFilename[strlen(sFilename)-1]=='\\') { sFilename[strlen(sFilename)-1]='\0'; } #else if (sFilename[strlen(sFilename)-1]=='/') { sFilename[strlen(sFilename)-1]='\0'; } #endif // Enumerate files it m_sDir is a directory. if ( stat(sFilename, &fileinfo)==0 && (fileinfo.st_mode & S_IFDIR) ) { // We have a directory: enumerate with index snprintf(sFilename, sizeof(sFilename)/sizeof(sFilename[0]),"%s%06d.%s", m_sDir, index, strPlottype); // If type is 'auto', fallback to 'png' if (strcmp(strPlottype, "auto")==0) strPlottype = "png"; } else { // We have a (probabely non-existant) file. Auto-detect type by extension if requested strncpy(sFilename, m_sDir, sizeof(sFilename)/sizeof(sFilename[0])); char *pDot = strrchr(sFilename, '.'); if (!pDot) { AIM_ERROR(_T("Please supply extension on filename when using 'auto' format: '%s'"), sFilename); return false; } strPlottype = &pDot[1]; } if ((m_pOutputFile = fopen(sFilename, "wb")) == NULL) { return false; } } else { #if !defined(_WINDOWS) && !defined(_MACOSX) if ((m_pOutputFile=open_memstream(&m_pMemoryBuffer, &m_sMemoryBufferSize))==NULL) #endif return false; strPlottype="pnm"; // Force pnm format or this doesn't work } /* * Create a plotter * * Plotutils knows the following types for file output: * pnm gif ai ps gif pcl hpgl tek meta */ if ((m_iPlotHandle = pl_newpl(strPlottype, NULL, m_pOutputFile, stderr)) < 0 ) { return false; } pl_selectpl(m_iPlotHandle); if ( pl_openpl() < 0) { return false; } // Now setup things for this plotter pl_fontname(m_pParam->GetString("output.img.fontname")); //! \todo Make fontsize work in Plotutils, currently disabled //pl_ffontsize(m_pParam->GetUInt("output.fontsize")); return true; } char* GraphicsOutputDevicePlotutils::GetBuffer() { if(m_bUseMemoryBuffer && (m_pMemoryBuffer!=NULL)) return (&m_pMemoryBuffer[m_sMemoryBufferSize-(m_uWidth*m_uHeight*3)]); else return NULL; } void GraphicsOutputDevicePlotutils::CloseFile() { // Plotting library if (m_iPlotHandle>0) { pl_closepl(); pl_selectpl(0); pl_deletepl(m_iPlotHandle); m_iPlotHandle = 0; } // And the output file if (m_pOutputFile) { fclose(m_pOutputFile); m_pOutputFile = NULL; } } GraphicsOutputDevicePlotutils::~GraphicsOutputDevicePlotutils() { // Output file should be closed by gRelease() AIM_ASSERT(!m_pOutputFile); AIM_ASSERT(!m_iPlotHandle); CloseFile(); } PixelFormat GraphicsOutputDevicePlotutils::GetPixelFormat() { return AIM_PIX_FMT_RGB24_24; } void GraphicsOutputDevicePlotutils::gGrab() { // Open file if (!OpenFile(m_iFileNumber)) { return; } // Setup plotting area pl_fspace(0.0, 0.0, 1.0, 1.0); pl_flinewidth(0.0001); pl_pencolorname("darkblue"); pl_erase(); } void GraphicsOutputDevicePlotutils::gBeginLineStrip() { m_bIsFirstVertex = true; m_iVertexType = VertexTypeLine; pl_filltype(0); } void GraphicsOutputDevicePlotutils::gBeginQuadStrip() { m_bIsFirstVertex = true; m_iVertexType = VertexTypeQuad; m_iPrevVertexCount = 0; pl_filltype(1); } void GraphicsOutputDevicePlotutils::gColor3f(float r, float g, float b) { if (m_bInvertColors) { r = 1-r; g = 1-g; b = 1-b; } int ir = (int)(r*0xffff); int ig = (int)(g*0xffff); int ib = (int)(b*0xffff); ir = MIN(0xffff, MAX(0,ir)); ig = MIN(0xffff, MAX(0,ig)); ib = MIN(0xffff, MAX(0,ib)); pl_color(ir, ig, ib); } void GraphicsOutputDevicePlotutils::gVertex3f(float x, float y, float z) { switch(m_iVertexType) { case VertexTypeLine: if (m_bIsFirstVertex) { m_bIsFirstVertex = false; pl_fmove(x, y); } else { pl_fcont(x, y); } break; case VertexTypeQuad: /* Store vertices until we got four in a row. * The order of vertices when processing quads is: * 1-----3-----5 * | | | * 0-----2-----4 */ if (m_iPrevVertexCount>=3) { // Plot this quad pl_fmove(m_aPrevX[0],m_aPrevY[0]); pl_fcont(m_aPrevX[1],m_aPrevY[1]); pl_fcont(x,y); pl_fcont(m_aPrevX[2],m_aPrevY[2]); pl_endpath(); // Last vertices of this quad are the first of the next m_aPrevX[0] = m_aPrevX[2]; m_aPrevY[0] = m_aPrevY[2]; m_aPrevX[1] = x; m_aPrevY[1] = y; m_iPrevVertexCount = 2; } else { // Not at the fourth, keep storing m_aPrevX[m_iPrevVertexCount] = x; m_aPrevY[m_iPrevVertexCount] = y; m_iPrevVertexCount++; } break; default: // Should not happen AIM_ASSERT(0); } } void GraphicsOutputDevicePlotutils::gEnd() { pl_endpath(); m_iVertexType = VertexTypeNone; } void GraphicsOutputDevicePlotutils::gText3f(float x, float y, float z, const char *sStr, bool bRotated) { if (bRotated) { pl_textangle(90); pl_fmove(x, y); pl_alabel('l', 't', sStr); } else { pl_textangle(0); pl_fmove(x, y); pl_alabel('l', 'b', sStr); } } void GraphicsOutputDevicePlotutils::gRelease() { AIM_ASSERT(m_pOutputFile); AIM_ASSERT(m_iPlotHandle>0); CloseFile(); m_iFileNumber++; }