1193 lines
42 KiB
C++
1193 lines
42 KiB
C++
/*******************************************************************************
|
|
* processrenderoptions.cpp
|
|
*
|
|
* ---------------------------------------------------------------------------
|
|
* Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
|
|
* Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
|
|
*
|
|
* POV-Ray is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* POV-Ray is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
* ---------------------------------------------------------------------------
|
|
* POV-Ray is based on the popular DKB raytracer version 2.12.
|
|
* DKBTrace was originally written by David K. Buck.
|
|
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
|
|
* ---------------------------------------------------------------------------
|
|
* $File: //depot/public/povray/3.x/source/frontend/processrenderoptions.cpp $
|
|
* $Revision: #1 $
|
|
* $Change: 6069 $
|
|
* $DateTime: 2013/11/06 11:59:40 $
|
|
* $Author: chrisc $
|
|
*******************************************************************************/
|
|
|
|
#include <cctype>
|
|
|
|
// configbase.h must always be the first POV file included within base *.cpp files
|
|
#include "base/configbase.h"
|
|
#include "base/types.h"
|
|
#include "base/povmscpp.h"
|
|
#include "base/fileinputoutput.h"
|
|
#include "base/stringutilities.h"
|
|
#include "base/textstream.h"
|
|
#include "base/povms.h"
|
|
#include "base/povmsgid.h"
|
|
#include "base/pov_err.h"
|
|
|
|
#include "frontend/configfrontend.h"
|
|
#include "frontend/processrenderoptions.h"
|
|
|
|
// this must be the last file included
|
|
#include "base/povdebug.h"
|
|
|
|
namespace pov_frontend
|
|
{
|
|
|
|
using namespace pov_base;
|
|
|
|
/*****************************************************************************
|
|
* Local preprocessor defines
|
|
******************************************************************************/
|
|
|
|
#define kUseSpecialHandler kPOVMSType_WildCard
|
|
#define kNoParameter kPOVMSType_Null
|
|
|
|
/*****************************************************************************
|
|
* Local variables
|
|
******************************************************************************/
|
|
|
|
#ifdef SYS_HAS_GRAYSCALE
|
|
#define SYS_GRAYSCALE_FLAG true
|
|
#else // SYS_HAS_GRAYSCALE
|
|
#define SYS_GRAYSCALE_FLAG false
|
|
#endif // SYS_HAS_GRAYSCALE
|
|
|
|
#ifdef SYS_HAS_ALPHA
|
|
#define SYS_ALPHA_FLAG true
|
|
#else // SYS_HAS_ALPHA
|
|
#define SYS_ALPHA_FLAG false
|
|
#endif // SYS_HAS_ALPHA
|
|
|
|
/*
|
|
Keyword table for the INI-file parser.
|
|
The parser converts the INI-file options into a POVMS object using
|
|
the specifications provided in this table. The first element is the
|
|
INI-file keyword, the second element is the POVMS object attribute
|
|
key, the third is the attribute type. Entries with a POVMS attribute
|
|
key of 0 are superceded options that will generate a warning that the
|
|
option no longer is supported and will generate an error in a later
|
|
(unspecified) version of POV.
|
|
*/
|
|
struct ProcessOptions::INI_Parser_Table RenderOptions_INI_Table[] =
|
|
{
|
|
{ "All_Console", kPOVAttrib_AllConsole, kPOVMSType_Bool },
|
|
{ "All_File", kPOVAttrib_AllFile, kPOVMSType_UCS2String },
|
|
{ "Antialias_Depth", kPOVAttrib_AntialiasDepth, kPOVMSType_Int },
|
|
{ "Antialias", kPOVAttrib_Antialias, kPOVMSType_Bool },
|
|
{ "Antialias_Threshold", kPOVAttrib_AntialiasThreshold, kPOVMSType_Float },
|
|
{ "Antialias_Gamma", kPOVAttrib_AntialiasGamma, kPOVMSType_Float },
|
|
{ "Append_File", kPOVAttrib_AppendConsoleFiles, kPOVMSType_Bool },
|
|
|
|
{ "Bits_Per_Color", kPOVAttrib_BitsPerColor, kPOVMSType_Int },
|
|
{ "Bits_Per_Colour", kPOVAttrib_BitsPerColor, kPOVMSType_Int },
|
|
{ "Bounding", kPOVAttrib_Bounding, kPOVMSType_Bool },
|
|
{ "Bounding_Method", kPOVAttrib_BoundingMethod, kPOVMSType_Int },
|
|
{ "Bounding_Threshold", kPOVAttrib_BoundingThreshold, kPOVMSType_Int },
|
|
{ "BSP_BaseAccessCost", kPOVAttrib_BSP_BaseAccessCost, kPOVMSType_Float },
|
|
{ "BSP_ChildAccessCost", kPOVAttrib_BSP_ChildAccessCost,kPOVMSType_Float },
|
|
{ "BSP_ISectCost", kPOVAttrib_BSP_ISectCost, kPOVMSType_Float },
|
|
{ "BSP_MaxDepth", kPOVAttrib_BSP_MaxDepth, kPOVMSType_Int },
|
|
{ "BSP_MissChance", kPOVAttrib_BSP_MissChance, kPOVMSType_Float },
|
|
{ "Buffer_Output", 0, 0 },
|
|
{ "Buffer_Size", 0, 0 },
|
|
|
|
{ "Clock", kPOVAttrib_Clock, kPOVMSType_Float },
|
|
{ "Clockless_Animation", kPOVAttrib_ClocklessAnimation, kPOVMSType_Bool },
|
|
{ "Compression", kPOVAttrib_Compression, kPOVMSType_Int },
|
|
{ "Continue_Trace", kPOVAttrib_ContinueTrace, kPOVMSType_Bool },
|
|
{ "Create_Histogram", 0, 0 },
|
|
{ "Create_Ini", kPOVAttrib_CreateIni, kPOVMSType_UCS2String },
|
|
{ "Cyclic_Animation", kPOVAttrib_CyclicAnimation, kPOVMSType_Bool },
|
|
|
|
{ "Debug_Console", kPOVAttrib_DebugConsole, kPOVMSType_Bool },
|
|
{ "Debug_File", kPOVAttrib_DebugFile, kPOVMSType_UCS2String },
|
|
{ "Declare", kPOVAttrib_Declare, kUseSpecialHandler },
|
|
{ "Display", kPOVAttrib_Display, kPOVMSType_Bool },
|
|
{ "Display_Gamma", kPOVAttrib_DisplayGamma, kUseSpecialHandler },
|
|
{ "Dither", kPOVAttrib_Dither, kPOVMSType_Bool },
|
|
{ "Dither_Method", kPOVAttrib_DitherMethod, kUseSpecialHandler },
|
|
{ "Draw_Vistas", kPOVAttrib_DrawVistas, kPOVMSType_Bool },
|
|
|
|
{ "End_Column", kPOVAttrib_Right, kPOVMSType_Float },
|
|
{ "End_Row", kPOVAttrib_Bottom, kPOVMSType_Float },
|
|
|
|
{ "Fatal_Console", kPOVAttrib_FatalConsole, kPOVMSType_Bool },
|
|
{ "Fatal_Error_Command", kPOVAttrib_FatalErrorCommand, kUseSpecialHandler },
|
|
{ "Fatal_Error_Return", kPOVAttrib_FatalErrorCommand, kUseSpecialHandler },
|
|
{ "Fatal_File", kPOVAttrib_FatalFile, kPOVMSType_UCS2String },
|
|
{ "Field_Render", kPOVAttrib_FieldRender, kPOVMSType_Bool },
|
|
{ "File_Gamma", kPOVAttrib_FileGamma, kUseSpecialHandler },
|
|
{ "Final_Clock", kPOVAttrib_FinalClock, kPOVMSType_Float },
|
|
{ "Final_Frame", kPOVAttrib_FinalFrame, kPOVMSType_Int },
|
|
{ "Frame_Step", kPOVAttrib_FrameStep, kPOVMSType_Int },
|
|
|
|
{ "Grayscale_Output", kPOVAttrib_GrayscaleOutput, kPOVMSType_Bool },
|
|
|
|
{ "Height", kPOVAttrib_Height, kPOVMSType_Int },
|
|
{ "High_Reproducibility",kPOVAttrib_HighReproducibility,kPOVMSType_Bool },
|
|
{ "Histogram_Name", 0, 0 },
|
|
{ "Histogram_Grid_Size", 0, 0 },
|
|
{ "Histogram_Type", 0, 0 },
|
|
|
|
{ "Initial_Clock", kPOVAttrib_InitialClock, kPOVMSType_Float },
|
|
{ "Initial_Frame", kPOVAttrib_InitialFrame, kPOVMSType_Int },
|
|
{ "Input_File_Name", kPOVAttrib_InputFile, kPOVMSType_UCS2String },
|
|
{ "Include_Header", kPOVAttrib_IncludeHeader, kPOVMSType_UCS2String },
|
|
{ "Include_Ini", kPOVAttrib_IncludeIni, kUseSpecialHandler },
|
|
|
|
{ "Jitter_Amount", kPOVAttrib_JitterAmount, kPOVMSType_Float },
|
|
{ "Jitter", kPOVAttrib_Jitter, kPOVMSType_Bool },
|
|
|
|
{ "Library_Path", kPOVAttrib_LibraryPath, kUseSpecialHandler },
|
|
{ "Light_Buffer", kPOVAttrib_LightBuffer, kPOVMSType_Bool },
|
|
|
|
{ "Max_Image_Buffer_Memory", kPOVAttrib_MaxImageBufferMem, kPOVMSType_Int },
|
|
|
|
{ "Odd_Field", kPOVAttrib_OddField, kPOVMSType_Bool },
|
|
{ "Output_Alpha", kPOVAttrib_OutputAlpha, kPOVMSType_Bool },
|
|
{ "Output_File_Name", kPOVAttrib_OutputFile, kPOVMSType_UCS2String },
|
|
{ "Output_File_Type", kPOVAttrib_OutputFileType, kUseSpecialHandler },
|
|
{ "Output_To_File", kPOVAttrib_OutputToFile, kPOVMSType_Bool },
|
|
|
|
{ "Palette", kPOVAttrib_Palette, kUseSpecialHandler },
|
|
{ "Pause_When_Done", kPOVAttrib_PauseWhenDone, kPOVMSType_Bool },
|
|
{ "Post_Frame_Command", kPOVAttrib_PostFrameCommand, kUseSpecialHandler },
|
|
{ "Post_Frame_Return", kPOVAttrib_PostFrameCommand, kUseSpecialHandler },
|
|
{ "Post_Scene_Command", kPOVAttrib_PostSceneCommand, kUseSpecialHandler },
|
|
{ "Post_Scene_Return", kPOVAttrib_PostSceneCommand, kUseSpecialHandler },
|
|
{ "Preview_End_Size", kPOVAttrib_PreviewEndSize, kPOVMSType_Int },
|
|
{ "Preview_Start_Size", kPOVAttrib_PreviewStartSize, kPOVMSType_Int },
|
|
{ "Pre_Frame_Command", kPOVAttrib_PreFrameCommand, kUseSpecialHandler },
|
|
{ "Pre_Frame_Return", kPOVAttrib_PreFrameCommand, kUseSpecialHandler },
|
|
{ "Pre_Scene_Command", kPOVAttrib_PreSceneCommand, kUseSpecialHandler },
|
|
{ "Pre_Scene_Return", kPOVAttrib_PreSceneCommand, kUseSpecialHandler },
|
|
|
|
{ "Quality", kPOVAttrib_Quality, kPOVMSType_Int },
|
|
|
|
{ "Radiosity_File_Name", kPOVAttrib_RadiosityFileName, kPOVMSType_UCS2String },
|
|
{ "Radiosity_From_File", kPOVAttrib_RadiosityFromFile, kPOVMSType_Bool },
|
|
{ "Radiosity_To_File", kPOVAttrib_RadiosityToFile, kPOVMSType_Bool },
|
|
{ "Radiosity_Vain_Pretrace", kPOVAttrib_RadiosityVainPretrace, kPOVMSType_Bool },
|
|
{ "Real_Time_Raytracing",kPOVAttrib_RealTimeRaytracing, kPOVMSType_Bool },
|
|
{ "Remove_Bounds", kPOVAttrib_RemoveBounds, kPOVMSType_Bool },
|
|
{ "Render_Block_Size", kPOVAttrib_RenderBlockSize, kPOVMSType_Int },
|
|
{ "Render_Block_Step", kPOVAttrib_RenderBlockStep, kPOVMSType_Int },
|
|
{ "Render_Console", kPOVAttrib_RenderConsole, kPOVMSType_Bool },
|
|
{ "Render_File", kPOVAttrib_RenderFile, kPOVMSType_UCS2String },
|
|
{ "Render_Pattern", kPOVAttrib_RenderPattern, kPOVMSType_Int },
|
|
|
|
{ "Sampling_Method", kPOVAttrib_SamplingMethod, kPOVMSType_Int },
|
|
{ "Split_Unions", kPOVAttrib_SplitUnions, kPOVMSType_Bool },
|
|
{ "Start_Column", kPOVAttrib_Left, kPOVMSType_Float },
|
|
{ "Start_Row", kPOVAttrib_Top, kPOVMSType_Float },
|
|
{ "Statistic_Console", kPOVAttrib_StatisticsConsole, kPOVMSType_Bool },
|
|
{ "Statistic_File", kPOVAttrib_StatisticsFile, kPOVMSType_UCS2String },
|
|
{ "Subset_End_Frame", kPOVAttrib_SubsetEndFrame, kPOVMSType_Float },
|
|
{ "Subset_Start_Frame", kPOVAttrib_SubsetStartFrame, kPOVMSType_Float },
|
|
|
|
{ "Test_Abort_Count", kPOVAttrib_TestAbortCount, kPOVMSType_Int },
|
|
{ "Test_Abort", kPOVAttrib_TestAbort, kPOVMSType_Bool },
|
|
|
|
{ "User_Abort_Command", kPOVAttrib_UserAbortCommand, kUseSpecialHandler },
|
|
{ "User_Abort_Return", kPOVAttrib_UserAbortCommand, kUseSpecialHandler },
|
|
|
|
{ "Verbose", kPOVAttrib_Verbose, kPOVMSType_Bool },
|
|
{ "Version", kPOVAttrib_Version, kPOVMSType_Float },
|
|
{ "Video_Mode", kPOVAttrib_VideoMode, kUseSpecialHandler },
|
|
{ "Vista_Buffer", kPOVAttrib_VistaBuffer, kPOVMSType_Bool },
|
|
|
|
{ "Warning_Console", kPOVAttrib_WarningConsole, kPOVMSType_Bool },
|
|
{ "Warning_File", kPOVAttrib_WarningFile, kPOVMSType_UCS2String },
|
|
{ "Warning_Level", kPOVAttrib_WarningLevel, kPOVMSType_Int },
|
|
{ "Width", kPOVAttrib_Width, kPOVMSType_Int },
|
|
{ "Work_Threads", kPOVAttrib_MaxRenderThreads, kPOVMSType_Int },
|
|
|
|
{ NULL, 0, 0 }
|
|
};
|
|
|
|
/*
|
|
Keyword table for the command line parser.
|
|
The parser converts the command line options into a POVMS object using
|
|
the specifications provided in this table. The first element is the
|
|
command keyword, the second element is the POVMS object attribute key
|
|
of the parameter, the third is the attribute type and the last specifies
|
|
if the +/- switch is used as boolean parameter if an attribute key is
|
|
provided.
|
|
*/
|
|
struct ProcessOptions::Cmd_Parser_Table RenderOptions_Cmd_Table[] =
|
|
{
|
|
{ "AG", kPOVAttrib_AntialiasGamma, kPOVMSType_Float, kNoParameter },
|
|
{ "AM", kPOVAttrib_SamplingMethod, kPOVMSType_Int, kNoParameter },
|
|
{ "A0", kPOVAttrib_AntialiasThreshold, kPOVMSType_Float, kPOVAttrib_Antialias },
|
|
{ "A", kNoParameter, kNoParameter, kPOVAttrib_Antialias },
|
|
|
|
{ "BM", kPOVAttrib_BoundingMethod, kPOVMSType_Int, kNoParameter },
|
|
{ "BS", kPOVAttrib_RenderBlockSize, kPOVMSType_Int, kNoParameter },
|
|
{ "B", kNoParameter, kNoParameter, kPOVAttrib_Bounding },
|
|
|
|
{ "C", kNoParameter, kNoParameter, kPOVAttrib_ContinueTrace },
|
|
|
|
{ "D", kPOVAttrib_Display, kUseSpecialHandler, kPOVAttrib_Display },
|
|
{ "D", kNoParameter, kNoParameter, kPOVAttrib_Display },
|
|
|
|
{ "EC", kPOVAttrib_Right, kPOVMSType_Float, kNoParameter },
|
|
{ "EF0", kPOVAttrib_SubsetEndFrame, kPOVMSType_Float, kNoParameter },
|
|
{ "EF", kPOVAttrib_SubsetEndFrame, kPOVMSType_Int, kNoParameter },
|
|
{ "EP", kPOVAttrib_PreviewEndSize, kPOVMSType_Int, kNoParameter },
|
|
{ "ER", kPOVAttrib_Bottom, kPOVMSType_Float, kNoParameter },
|
|
|
|
{ "F", kPOVAttrib_OutputFileType, kUseSpecialHandler, kPOVAttrib_OutputToFile },
|
|
{ "F", kNoParameter, kNoParameter, kPOVAttrib_OutputToFile },
|
|
|
|
{ "GA", kPOVAttrib_AllFile, kPOVMSType_UCS2String, kPOVAttrib_AllConsole },
|
|
{ "GA", kNoParameter, kNoParameter, kPOVAttrib_AllConsole },
|
|
{ "GD", kPOVAttrib_DebugFile, kPOVMSType_UCS2String, kPOVAttrib_DebugConsole },
|
|
{ "GD", kNoParameter, kNoParameter, kPOVAttrib_DebugConsole },
|
|
{ "GF", kPOVAttrib_FatalFile, kPOVMSType_UCS2String, kPOVAttrib_FatalConsole },
|
|
{ "GF", kNoParameter, kNoParameter, kPOVAttrib_FatalConsole },
|
|
{ "GI", kPOVAttrib_CreateIni, kPOVMSType_UCS2String, kNoParameter },
|
|
{ "GP", kNoParameter, kNoParameter, kPOVAttrib_AppendConsoleFiles },
|
|
{ "GR", kPOVAttrib_RenderFile, kPOVMSType_UCS2String, kPOVAttrib_RenderConsole },
|
|
{ "GR", kNoParameter, kNoParameter, kPOVAttrib_RenderConsole },
|
|
{ "GS", kPOVAttrib_StatisticsFile, kPOVMSType_UCS2String, kPOVAttrib_StatisticsConsole },
|
|
{ "GS", kNoParameter, kNoParameter, kPOVAttrib_StatisticsConsole },
|
|
{ "GW", kPOVAttrib_WarningFile, kPOVMSType_UCS2String, kPOVAttrib_WarningConsole },
|
|
{ "GW", kNoParameter, kNoParameter, kPOVAttrib_WarningConsole },
|
|
|
|
{ "HI", kPOVAttrib_IncludeHeader, kPOVMSType_UCS2String, kNoParameter },
|
|
{ "HR", kNoParameter, kNoParameter, kPOVAttrib_HighReproducibility },
|
|
{ "H", kPOVAttrib_Height, kPOVMSType_Int, kNoParameter },
|
|
|
|
{ "I", kPOVAttrib_InputFile, kPOVMSType_UCS2String, kNoParameter },
|
|
|
|
{ "J", kPOVAttrib_JitterAmount, kPOVMSType_Float, kPOVAttrib_Jitter },
|
|
{ "J", kNoParameter, kNoParameter, kPOVAttrib_Jitter },
|
|
|
|
{ "KC", kNoParameter, kNoParameter, kPOVAttrib_CyclicAnimation },
|
|
{ "KI", kPOVAttrib_InitialClock, kPOVMSType_Float, kNoParameter },
|
|
{ "KFF", kPOVAttrib_FinalFrame, kPOVMSType_Int, kNoParameter },
|
|
{ "KFI", kPOVAttrib_InitialFrame, kPOVMSType_Int, kNoParameter },
|
|
{ "KF", kPOVAttrib_FinalClock, kPOVMSType_Float, kNoParameter },
|
|
{ "KLA", kNoParameter, kNoParameter, kPOVAttrib_ClocklessAnimation },
|
|
{ "K", kPOVAttrib_Clock, kPOVMSType_Float, kNoParameter },
|
|
|
|
{ "L", kPOVAttrib_LibraryPath, kUseSpecialHandler, kNoParameter },
|
|
|
|
{ "MB", kPOVAttrib_BoundingThreshold, kPOVMSType_Int, kPOVAttrib_Bounding },
|
|
{ "MB", kNoParameter, kNoParameter, kPOVAttrib_Bounding },
|
|
{ "MI", kPOVAttrib_MaxImageBufferMem, kPOVMSType_Int, kNoParameter },
|
|
{ "MV", kPOVAttrib_Version, kPOVMSType_Float, kNoParameter },
|
|
|
|
{ "O", kPOVAttrib_OutputFile, kPOVMSType_UCS2String, kNoParameter },
|
|
|
|
{ "P", kNoParameter, kNoParameter, kPOVAttrib_PauseWhenDone },
|
|
|
|
{ "Q", kPOVAttrib_Quality, kPOVMSType_Int, kNoParameter },
|
|
|
|
{ "RFI", kNoParameter, kNoParameter, kPOVAttrib_RadiosityFromFile },
|
|
{ "RFO", kNoParameter, kNoParameter, kPOVAttrib_RadiosityToFile },
|
|
{ "RF", kPOVAttrib_RadiosityFileName, kPOVMSType_UCS2String, kNoParameter },
|
|
{ "RS", kPOVAttrib_RenderBlockStep, kPOVMSType_Int, kNoParameter },
|
|
{ "RP", kPOVAttrib_RenderPattern, kPOVMSType_Int, kNoParameter },
|
|
{ "RTR", kNoParameter, kNoParameter, kPOVAttrib_RealTimeRaytracing },
|
|
{ "RVP", kNoParameter, kNoParameter, kPOVAttrib_RadiosityVainPretrace },
|
|
{ "R", kPOVAttrib_AntialiasDepth, kPOVMSType_Int, kNoParameter },
|
|
|
|
{ "SC", kPOVAttrib_Left, kPOVMSType_Float, kNoParameter },
|
|
{ "SF0", kPOVAttrib_SubsetStartFrame, kPOVMSType_Float, kNoParameter },
|
|
{ "SF", kPOVAttrib_SubsetStartFrame, kPOVMSType_Int, kNoParameter },
|
|
{ "SP", kPOVAttrib_PreviewStartSize, kPOVMSType_Int, kNoParameter },
|
|
{ "SR", kPOVAttrib_Top, kPOVMSType_Float, kNoParameter },
|
|
{ "STP", kPOVAttrib_FrameStep, kPOVMSType_Int, kNoParameter },
|
|
{ "SU", kNoParameter, kNoParameter, kPOVAttrib_SplitUnions },
|
|
|
|
{ "TH", kPOVAttrib_DitherMethod, kUseSpecialHandler, kPOVAttrib_Dither },
|
|
{ "TH", kNoParameter, kNoParameter, kPOVAttrib_Dither },
|
|
|
|
{ "UA", kNoParameter, kNoParameter, kPOVAttrib_OutputAlpha },
|
|
{ "UD", kNoParameter, kNoParameter, kPOVAttrib_DrawVistas },
|
|
{ "UF", kNoParameter, kNoParameter, kPOVAttrib_FieldRender },
|
|
{ "UL", kNoParameter, kNoParameter, kPOVAttrib_LightBuffer },
|
|
{ "UO", kNoParameter, kNoParameter, kPOVAttrib_OddField },
|
|
{ "UR", kNoParameter, kNoParameter, kPOVAttrib_RemoveBounds },
|
|
{ "UV", kNoParameter, kNoParameter, kPOVAttrib_VistaBuffer },
|
|
|
|
{ "V", kNoParameter, kNoParameter, kPOVAttrib_Verbose },
|
|
|
|
{ "WL", kPOVAttrib_WarningLevel, kPOVMSType_Int, kNoParameter },
|
|
{ "WT", kPOVAttrib_MaxRenderThreads, kPOVMSType_Int, kNoParameter },
|
|
{ "W", kPOVAttrib_Width, kPOVMSType_Int, kNoParameter },
|
|
|
|
{ "X", kPOVAttrib_TestAbortCount, kUseSpecialHandler, kPOVAttrib_TestAbort },
|
|
{ "X", kNoParameter, kNoParameter, kPOVAttrib_TestAbort },
|
|
|
|
{ NULL, 0, 0, 0 }
|
|
};
|
|
|
|
// TODO FIXME - The following are hacks of some sort, no idea what they are good for. They certainly use wrong types and probably contain other mistakes [trf]
|
|
extern struct ProcessRenderOptions::Parameter_Code_Table DitherMethodTable[];
|
|
|
|
ProcessRenderOptions::ProcessRenderOptions() : ProcessOptions(RenderOptions_INI_Table, RenderOptions_Cmd_Table)
|
|
{
|
|
}
|
|
|
|
ProcessRenderOptions::~ProcessRenderOptions()
|
|
{
|
|
}
|
|
|
|
int ProcessRenderOptions::ReadSpecialOptionHandler(INI_Parser_Table *option, char *param, POVMSObjectPtr obj)
|
|
{
|
|
POVMSAttributeList list;
|
|
double floatval = 0.0;
|
|
int intval = 0;
|
|
int intval2 = 0;
|
|
int err = kNoErr;
|
|
|
|
switch(option->key)
|
|
{
|
|
case kPOVAttrib_Palette:
|
|
case kPOVAttrib_VideoMode:
|
|
while(isspace(*param))
|
|
param++;
|
|
err = POVMSUtil_SetInt(obj, option->key, tolower(*param));
|
|
break;
|
|
case kPOVAttrib_DitherMethod:
|
|
while(isspace(*param))
|
|
param++;
|
|
err = ParseParameterCode(DitherMethodTable, param, &intval);
|
|
if (err == kNoErr)
|
|
err = POVMSUtil_SetInt(obj, option->key, intval);
|
|
else
|
|
ParseError("Unrecognized dither method '%s'.", param);
|
|
break;
|
|
case kPOVAttrib_OutputFileType:
|
|
while(isspace(*param))
|
|
param++;
|
|
err = ParseFileType(*param, option->key, &intval);
|
|
if (err == kNoErr)
|
|
err = POVMSUtil_SetInt(obj, option->key, intval);
|
|
break;
|
|
case kPOVAttrib_IncludeIni:
|
|
case kPOVAttrib_LibraryPath:
|
|
POVMSAttribute attr;
|
|
|
|
if(err == kNoErr)
|
|
{
|
|
// parse INI file (recursive)
|
|
if(option->key == kPOVAttrib_IncludeIni)
|
|
err = ParseFile(param, obj);
|
|
|
|
// create list if it isn't there
|
|
if(err == kNoErr)
|
|
{
|
|
if(POVMSObject_Exist(obj, option->key) == kFalseErr)
|
|
err = POVMSAttrList_New(&list);
|
|
else if(POVMSObject_Exist(obj, option->key) != kNoErr)
|
|
err = kObjectAccessErr;
|
|
else
|
|
err = POVMSObject_Get(obj, &list, option->key);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ParseError("File name or path parameter expected for option '%s', found '%s'.", option->keyword, param);
|
|
err = kParamErr;
|
|
}
|
|
|
|
// add path or file to list
|
|
if(err == kNoErr)
|
|
err = POVMSAttr_New(&attr);
|
|
if(err == kNoErr)
|
|
{
|
|
err = POVMSAttr_SetUTF8String(&attr, kPOVMSType_UCS2String, param);
|
|
if(err == kNoErr)
|
|
err = POVMSAttrList_Append(&list, &attr);
|
|
else
|
|
err = POVMSAttr_Delete(&attr);
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &list, option->key);
|
|
break;
|
|
case kPOVAttrib_Declare:
|
|
POVMSObject decobj;
|
|
|
|
// create list if it isn't there
|
|
if(POVMSObject_Exist(obj, option->key) == kFalseErr)
|
|
err = POVMSAttrList_New(&list);
|
|
else if(POVMSObject_Exist(obj, option->key) != kNoErr)
|
|
err = kObjectAccessErr;
|
|
else
|
|
err = POVMSObject_Get(obj, &list, option->key);
|
|
|
|
// add value to list
|
|
if(err == kNoErr)
|
|
err = POVMSObject_New(&decobj, kPOVMSType_WildCard);
|
|
if(err == kNoErr)
|
|
{
|
|
char *ptr = NULL;
|
|
|
|
err = POVMSUtil_SetString(&decobj, kPOVAttrib_Identifier, strtok(param, "="));
|
|
if(err == kNoErr)
|
|
{
|
|
ptr = strtok(NULL, "");
|
|
if(ptr == NULL)
|
|
err = kParseErr;
|
|
}
|
|
if(err == kNoErr)
|
|
{
|
|
if(strchr(ptr, '"') != NULL)
|
|
{
|
|
ptr = strchr(ptr, '"') + 1;
|
|
strtok(ptr, "\"");
|
|
err = POVMSUtil_SetString(&decobj, kPOVAttrib_Value, ptr);
|
|
}
|
|
else
|
|
err = POVMSUtil_SetFloat(&decobj, kPOVAttrib_Value, atof(ptr));
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSAttrList_Append(&list, &decobj);
|
|
else
|
|
err = POVMSObject_Delete(&decobj);
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &list, option->key);
|
|
break;
|
|
case kPOVAttrib_FatalErrorCommand:
|
|
case kPOVAttrib_PostFrameCommand:
|
|
case kPOVAttrib_PostSceneCommand:
|
|
case kPOVAttrib_PreFrameCommand:
|
|
case kPOVAttrib_PreSceneCommand:
|
|
case kPOVAttrib_UserAbortCommand:
|
|
POVMSObject cmdobj;
|
|
|
|
if(POVMSObject_Exist(obj, option->key) == kNoErr)
|
|
err = POVMSObject_Get(obj, &cmdobj, option->key);
|
|
else
|
|
err = POVMSObject_New(&cmdobj, kPOVMSType_WildCard);
|
|
if(toupper(*(option->keyword + strlen(option->keyword) - 1)) == 'D')
|
|
{
|
|
if(err == kNoErr)
|
|
err = POVMSUtil_SetString(&cmdobj, kPOVAttrib_CommandString, param);
|
|
}
|
|
else
|
|
{
|
|
if(err == kNoErr)
|
|
{
|
|
int i = 0;
|
|
|
|
if((*param == '-') || (*param == '!'))
|
|
i = toupper(*(param + 1)); // use upper-case to indicate negation of process result
|
|
else
|
|
i = tolower(*param); // lower-case for normal interpretation of process result
|
|
err = POVMSUtil_SetInt(&cmdobj, kPOVAttrib_ReturnAction, i);
|
|
}
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &cmdobj, option->key);
|
|
break;
|
|
case kPOVAttrib_AntialiasGamma:
|
|
case kPOVAttrib_DisplayGamma:
|
|
case kPOVAttrib_FileGamma:
|
|
POVMSType typeKey;
|
|
switch (option->key)
|
|
{
|
|
case kPOVAttrib_AntialiasGamma: typeKey = kPOVAttrib_AntialiasGammaType; break;
|
|
case kPOVAttrib_DisplayGamma: typeKey = kPOVAttrib_DisplayGammaType; break;
|
|
case kPOVAttrib_FileGamma: typeKey = kPOVAttrib_FileGammaType; break;
|
|
}
|
|
floatval = atof(param);
|
|
if (floatval == 1.0)
|
|
intval = kPOVList_GammaType_Neutral;
|
|
else if (floatval > 0)
|
|
intval = kPOVList_GammaType_PowerLaw;
|
|
else
|
|
err = ParseGammaType(param, &intval);
|
|
|
|
if (err == kNoErr)
|
|
err = POVMSUtil_SetFloat(obj, option->key, fabs(floatval));
|
|
if (err == kNoErr)
|
|
err = POVMSUtil_SetInt(obj, typeKey, intval);
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int ProcessRenderOptions::ReadSpecialSwitchHandler(Cmd_Parser_Table *option, char *param, POVMSObjectPtr obj, bool)
|
|
{
|
|
int intval = 0;
|
|
int intval2 = 0;
|
|
int err = 0;
|
|
char chr = 0;
|
|
char file_type;
|
|
bool has16BitGrayscale;
|
|
|
|
switch(option->key)
|
|
{
|
|
case kPOVAttrib_Display:
|
|
if(param[0] != '\0')
|
|
{
|
|
err = POVMSUtil_SetInt(obj, kPOVAttrib_VideoMode, (int)toupper(param[0]));
|
|
if((param[1] != '\0') && (err == 0))
|
|
err = POVMSUtil_SetInt(obj, kPOVAttrib_Palette, (int)toupper(param[1]));
|
|
}
|
|
break;
|
|
case kPOVAttrib_DitherMethod:
|
|
err = ParseParameterCode(DitherMethodTable, param, &intval);
|
|
if (err == kNoErr)
|
|
err = POVMSUtil_SetInt(obj, option->key, intval);
|
|
else
|
|
ParseError("Unrecognized dither method '%s'.", param);
|
|
break;
|
|
case kPOVAttrib_OutputFileType:
|
|
err = ParseFileType(*param, option->key, &intval, &has16BitGrayscale);
|
|
if (err == kNoErr)
|
|
{
|
|
err = POVMSUtil_SetInt(obj, option->key, intval);
|
|
file_type = *param++;
|
|
}
|
|
if ((err == kNoErr) && (*param > ' '))
|
|
{
|
|
if (tolower(*param) == 'g')
|
|
{
|
|
if(!has16BitGrayscale)
|
|
{
|
|
ParseError("Grayscale not currently supported with output file format '%c'.", file_type);
|
|
err = kParamErr;
|
|
}
|
|
else
|
|
{
|
|
if ((err = POVMSUtil_SetBool(obj, kPOVAttrib_GrayscaleOutput, true)) == kNoErr && *++param > ' ')
|
|
{
|
|
ParseError("Unexpected '%s' following grayscale flag in +F%c option.", param, file_type);
|
|
err = kParamErr;
|
|
}
|
|
}
|
|
}
|
|
else if (isdigit(*param) != 0)
|
|
{
|
|
if (sscanf(param, "%d%n", &intval, &intval2) == 1)
|
|
{
|
|
if ((err = POVMSUtil_SetInt(obj, kPOVAttrib_BitsPerColor, intval)) == kNoErr)
|
|
{
|
|
param += intval2;
|
|
if (*param > ' ')
|
|
{
|
|
ParseError("Unexpected '%s' following bits per color in +F%c option.", param, file_type);
|
|
err = kParamErr;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ParseError("Invalid bits per color '%s' found in +F%c option.", param, file_type);
|
|
err = kParamErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ParseError("Invalid modifier '%s' following +F%c option.", param, file_type);
|
|
err = kParamErr;
|
|
}
|
|
}
|
|
break;
|
|
case kPOVAttrib_LibraryPath:
|
|
POVMSAttributeList list;
|
|
POVMSAttribute attr;
|
|
|
|
if(err == kNoErr)
|
|
{
|
|
// create list if it isn't there
|
|
if(POVMSObject_Exist(obj, option->key) == kFalseErr)
|
|
err = POVMSAttrList_New(&list);
|
|
else if(POVMSObject_Exist(obj, option->key) != kNoErr)
|
|
err = kObjectAccessErr;
|
|
else
|
|
err = POVMSObject_Get(obj, &list, option->key);
|
|
}
|
|
else
|
|
{
|
|
ParseError("File name or path parameter expected for switch '%s', found '%s'.", option->command, param);
|
|
err = kParamErr;
|
|
}
|
|
|
|
// add path or file to list
|
|
if(err == kNoErr)
|
|
err = POVMSAttr_New(&attr);
|
|
if(err == kNoErr)
|
|
{
|
|
err = POVMSAttr_SetUTF8String(&attr, kPOVMSType_UCS2String, param);
|
|
if(err == kNoErr)
|
|
err = POVMSAttrList_Append(&list, &attr);
|
|
else
|
|
err = POVMSAttr_Delete(&attr);
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &list, option->key);
|
|
break;
|
|
case kPOVAttrib_TestAbortCount:
|
|
if((*param) == 0)
|
|
break;
|
|
if(sscanf(param, "%d", &intval) == 1)
|
|
err = POVMSUtil_SetInt(obj, option->key, intval);
|
|
else
|
|
{
|
|
ParseError("No or integer parameter expected for switch '%s', found '%s'.", option->command, param);
|
|
err = kParamErr;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int ProcessRenderOptions::WriteSpecialOptionHandler(INI_Parser_Table *option, POVMSObjectPtr obj, OTextStream *file)
|
|
{
|
|
POVMSAttributeList list;
|
|
POVMSFloat floatval;
|
|
POVMSInt intval;
|
|
int err = 0;
|
|
int l;
|
|
int i,imax;
|
|
POVMSAttribute item;
|
|
char *bufptr;
|
|
char chr;
|
|
|
|
switch(option->key)
|
|
{
|
|
case kPOVAttrib_Palette:
|
|
case kPOVAttrib_VideoMode:
|
|
if(POVMSUtil_GetInt(obj, option->key, &intval) == 0)
|
|
{
|
|
chr = intval;
|
|
if(chr > 32)
|
|
file->printf("%s=%c\n", option->keyword, chr);
|
|
}
|
|
break;
|
|
case kPOVAttrib_OutputFileType:
|
|
if(POVMSUtil_GetInt(obj, option->key, &intval) == 0)
|
|
{
|
|
chr = UnparseFileType(intval);
|
|
if(chr > 32)
|
|
file->printf("%s=%c\n", option->keyword, chr);
|
|
}
|
|
break;
|
|
case kPOVAttrib_IncludeIni:
|
|
break;
|
|
case kPOVAttrib_Declare:
|
|
POVMSObject decobj;
|
|
|
|
err = POVMSObject_Get(obj, &list, option->key);
|
|
if(err != 0)
|
|
break;
|
|
|
|
l = 0;
|
|
err = POVMSAttrList_Count(&list, &l);
|
|
if(err != 0)
|
|
break;
|
|
if(l == 0)
|
|
break;
|
|
|
|
imax = l;
|
|
for(i = 1; i <= imax; i++)
|
|
{
|
|
err = POVMSAttrList_GetNth(&list, i, &decobj);
|
|
if(err == 0)
|
|
err = POVMSObject_Get(&decobj, &item, kPOVAttrib_Identifier);
|
|
if(err == 0)
|
|
{
|
|
l = 0;
|
|
err = POVMSAttr_Size(&item, &l);
|
|
if(l > 0)
|
|
{
|
|
bufptr = new char[l];
|
|
bufptr[0] = 0;
|
|
if((POVMSUtil_GetFloat(&decobj, kPOVAttrib_Value, &floatval) == 0) &&
|
|
(POVMSAttr_Get(&item, kPOVMSType_CString, bufptr, &l) == 0))
|
|
file->printf("%s=%s=%g\n", option->keyword, bufptr, (float)floatval);
|
|
delete[] bufptr;
|
|
}
|
|
(void)POVMSAttr_Delete(&item);
|
|
}
|
|
}
|
|
break;
|
|
case kPOVAttrib_LibraryPath:
|
|
err = POVMSObject_Get(obj, &list, option->key);
|
|
if(err != 0)
|
|
break;
|
|
|
|
l = 0;
|
|
err = POVMSAttrList_Count(&list, &l);
|
|
if(err != 0)
|
|
break;
|
|
if(l == 0)
|
|
break;
|
|
|
|
imax = l;
|
|
for(i = 1; i <= imax; i++)
|
|
{
|
|
err = POVMSAttrList_GetNth(&list, i, &item);
|
|
if(err == 0)
|
|
{
|
|
l = 0;
|
|
err = POVMSAttr_Size(&item, &l);
|
|
if(l > 0)
|
|
{
|
|
bufptr = new char[l * 3];
|
|
bufptr[0] = 0;
|
|
if(POVMSAttr_GetUTF8String(&item, kPOVMSType_UCS2String, bufptr, &l) == 0)
|
|
file->printf("%s=\"%s\"\n", option->keyword, bufptr);
|
|
delete[] bufptr;
|
|
}
|
|
(void)POVMSAttr_Delete(&item);
|
|
}
|
|
}
|
|
break;
|
|
case kPOVAttrib_FatalErrorCommand:
|
|
case kPOVAttrib_PostFrameCommand:
|
|
case kPOVAttrib_PostSceneCommand:
|
|
case kPOVAttrib_PreFrameCommand:
|
|
case kPOVAttrib_PreSceneCommand:
|
|
case kPOVAttrib_UserAbortCommand:
|
|
POVMSObject cmdobj;
|
|
|
|
err = POVMSObject_Get(obj, &cmdobj, option->key);
|
|
if(err != 0)
|
|
break;
|
|
|
|
err = POVMSObject_Get(&cmdobj, &item, kPOVAttrib_CommandString);
|
|
if(err == 0)
|
|
{
|
|
if(toupper(*(option->keyword + strlen(option->keyword) - 1)) == 'D')
|
|
{
|
|
l = 0;
|
|
err = POVMSAttr_Size(&item, &l);
|
|
if(l > 0)
|
|
{
|
|
bufptr = new char[l];
|
|
bufptr[0] = 0;
|
|
if(POVMSAttr_Get(&item, kPOVMSType_CString, bufptr, &l) == 0)
|
|
file->printf("%s=%s\n", option->keyword, bufptr);
|
|
delete[] bufptr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(POVMSUtil_GetInt(&cmdobj, kPOVAttrib_ReturnAction, &intval) == 0)
|
|
{
|
|
if(intval < 0)
|
|
{
|
|
chr = -intval;
|
|
file->printf("%s=!%c\n", option->keyword, chr);
|
|
}
|
|
else
|
|
{
|
|
chr = intval;
|
|
file->printf("%s=%c\n", option->keyword, chr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(err == 0)
|
|
err = POVMSObject_Delete(&cmdobj);
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
bool ProcessRenderOptions::WriteOptionFilter(INI_Parser_Table *table)
|
|
{
|
|
// So that we don't get both Bits_Per_Color and Bits_Per_Colour in the INI file.
|
|
return (strcmp(table->keyword, "Bits_Per_Colour") != 0);
|
|
}
|
|
|
|
int ProcessRenderOptions::ProcessUnknownString(char *str, POVMSObjectPtr obj)
|
|
{
|
|
POVMSAttributeList list;
|
|
POVMSAttribute attr;
|
|
int state = 0; // INI file
|
|
int err = kNoErr;
|
|
|
|
if(str == NULL)
|
|
{
|
|
ParseError("Expected filename, nothing was found.");
|
|
return kParamErr;
|
|
}
|
|
|
|
// add filename or path
|
|
|
|
// see if it is a POV file
|
|
if(state == 0)
|
|
{
|
|
char *ptr = strrchr(str, '.');
|
|
if(ptr != NULL)
|
|
{
|
|
if(pov_stricmp(ptr, ".pov") == 0)
|
|
state = 1; // POV file
|
|
}
|
|
}
|
|
|
|
// see if it is a path
|
|
if(state == 0)
|
|
{
|
|
if(strlen(str) > 0)
|
|
{
|
|
if(str[strlen(str) - 1] == POV_FILE_SEPARATOR)
|
|
state = 2; // library path
|
|
#ifdef POV_FILE_SEPARATOR_2
|
|
else if(str[strlen(str) - 1] == POV_FILE_SEPARATOR_2)
|
|
state = 2; // library path
|
|
#endif
|
|
}
|
|
}
|
|
|
|
switch(state)
|
|
{
|
|
// INI file
|
|
case 0:
|
|
// parse INI file (recursive)
|
|
err = ParseFile(str, obj);
|
|
if(err == kNoErr)
|
|
{
|
|
// create list if it isn't there
|
|
if(POVMSObject_Exist(obj, kPOVAttrib_IncludeIni) == kFalseErr)
|
|
err = POVMSAttrList_New(&list);
|
|
else if(POVMSObject_Exist(obj, kPOVAttrib_IncludeIni) != kNoErr)
|
|
err = kObjectAccessErr;
|
|
else
|
|
err = POVMSObject_Get(obj, &list, kPOVAttrib_IncludeIni);
|
|
}
|
|
|
|
// add INI file to list
|
|
if(err == kNoErr)
|
|
err = POVMSAttr_New(&attr);
|
|
if(err == kNoErr)
|
|
{
|
|
err = POVMSAttr_SetUTF8String(&attr, kPOVMSType_UCS2String, str);
|
|
if(err == kNoErr)
|
|
err = POVMSAttrList_Append(&list, &attr);
|
|
else
|
|
err = POVMSAttr_Delete(&attr);
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &list, kPOVAttrib_IncludeIni);
|
|
break;
|
|
// POV file
|
|
case 1:
|
|
// set POV file
|
|
err = POVMSUtil_SetUTF8String(obj, kPOVAttrib_InputFile, str);
|
|
break;
|
|
// library path
|
|
case 2:
|
|
// create list if it isn't there
|
|
if(POVMSObject_Exist(obj, kPOVAttrib_LibraryPath) == kFalseErr)
|
|
err = POVMSAttrList_New(&list);
|
|
else if(POVMSObject_Exist(obj, kPOVAttrib_LibraryPath) != kNoErr)
|
|
err = kObjectAccessErr;
|
|
else
|
|
err = POVMSObject_Get(obj, &list, kPOVAttrib_LibraryPath);
|
|
|
|
// add library path to list
|
|
if(err == kNoErr)
|
|
err = POVMSAttr_New(&attr);
|
|
if(err == kNoErr)
|
|
{
|
|
err = POVMSAttr_SetUTF8String(&attr, kPOVMSType_UCS2String, str);
|
|
if(err == kNoErr)
|
|
err = POVMSAttrList_Append(&list, &attr);
|
|
else
|
|
err = POVMSAttr_Delete(&attr);
|
|
}
|
|
if(err == kNoErr)
|
|
err = POVMSObject_Set(obj, &list, kPOVAttrib_LibraryPath);
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
ITextStream *ProcessRenderOptions::OpenFileForRead(const char *filename, POVMSObjectPtr obj)
|
|
{
|
|
return OpenINIFileStream(filename, pov_base::POV_File_Text_INI, obj);
|
|
}
|
|
|
|
OTextStream *ProcessRenderOptions::OpenFileForWrite(const char *filename, POVMSObjectPtr)
|
|
{
|
|
return new OTextStream(ASCIItoUCS2String(filename).c_str(), pov_base::POV_File_Text_INI);
|
|
}
|
|
|
|
ITextStream *ProcessRenderOptions::OpenINIFileStream(const char *filename, unsigned int stype, POVMSObjectPtr obj) // TODO FIXME - Use new Path class!
|
|
{
|
|
// TODO FIXME - we should join forces with SceneData::FindFile()
|
|
// TODO FIXME - use proper C++ strings instead of C character arrays
|
|
|
|
int i,ii,l[POV_FILE_EXTENSIONS_PER_TYPE];
|
|
char pathname[1024];
|
|
char file[1024];
|
|
char file_x[POV_FILE_EXTENSIONS_PER_TYPE][1024];
|
|
int cnt = 0;
|
|
int ll;
|
|
POVMSAttribute attr, item;
|
|
const char *xstr = strrchr(filename, '.');
|
|
bool hasextension = ((xstr != NULL) && (strlen(xstr) <= 4)); // TODO FIXME - we shouldn't rely on extensions being at most 1+3 chars long
|
|
|
|
if(POV_ALLOW_FILE_READ(ASCIItoUCS2String(filename).c_str(),stype) == 0) // TODO FIXME - Remove dependency on this macro!!! [trf]
|
|
return NULL;
|
|
|
|
for(i = 0; i < POV_FILE_EXTENSIONS_PER_TYPE; i++)
|
|
{
|
|
if((l[i] = strlen(pov::gPOV_File_Extensions[stype].ext[i])) > 0)
|
|
{
|
|
strcpy(file_x[i], filename);
|
|
strcat(file_x[i], pov::gPOV_File_Extensions[stype].ext[i]);
|
|
}
|
|
}
|
|
|
|
// Check the current directory first
|
|
|
|
if((hasextension == true) && (CheckIfFileExists(filename) == true))
|
|
{
|
|
return new ITextStream(ASCIItoUCS2String(filename).c_str(), stype);
|
|
}
|
|
|
|
for(i = 0; i < POV_FILE_EXTENSIONS_PER_TYPE; i++)
|
|
{
|
|
if(l[i])
|
|
{
|
|
if(CheckIfFileExists(file_x[i]) == true)
|
|
{
|
|
return new ITextStream(ASCIItoUCS2String(file_x[i]).c_str(), stype);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(POVMSObject_Get(obj, &attr, kPOVAttrib_LibraryPath) != 0)
|
|
return NULL;
|
|
|
|
if(POVMSAttrList_Count(&attr, &cnt) != 0)
|
|
{
|
|
(void)POVMSAttrList_Delete(&attr);
|
|
return NULL;
|
|
}
|
|
|
|
for (i = 1; i <= cnt; i++)
|
|
{
|
|
(void)POVMSAttr_New(&item);
|
|
if(POVMSAttrList_GetNth(&attr, i, &item) != 0)
|
|
continue;
|
|
ll = 0;
|
|
if(POVMSAttr_Size(&item, &ll) != 0)
|
|
{
|
|
(void)POVMSAttr_Delete(&item);
|
|
continue;
|
|
}
|
|
if(ll <= 0)
|
|
{
|
|
(void)POVMSAttr_Delete(&item);
|
|
continue;
|
|
}
|
|
if(POVMSAttr_GetUTF8String(&item, kPOVMSType_UCS2String, file, &ll) != 0) // TODO FIXME!!!
|
|
{
|
|
(void)POVMSAttr_Delete(&item);
|
|
continue;
|
|
}
|
|
(void)POVMSAttr_Delete(&item);
|
|
|
|
file[strlen(file)+1] = '\0';
|
|
file[strlen(file)] = POV_FILE_SEPARATOR;
|
|
|
|
strcpy(pathname, file);
|
|
strcat(pathname, filename);
|
|
if((hasextension == true) && (CheckIfFileExists(pathname) == true))
|
|
{
|
|
(void)POVMSAttrList_Delete(&attr);
|
|
return new ITextStream(ASCIItoUCS2String(pathname).c_str(), stype);
|
|
}
|
|
|
|
for(ii = 0; ii < POV_FILE_EXTENSIONS_PER_TYPE; ii++)
|
|
{
|
|
if(l[ii])
|
|
{
|
|
strcpy(pathname, file);
|
|
strcat(pathname, file_x[ii]);
|
|
if(CheckIfFileExists(pathname) == true)
|
|
{
|
|
(void)POVMSAttrList_Delete(&attr);
|
|
return new ITextStream(ASCIItoUCS2String(pathname).c_str(), stype);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
(void)POVMSAttrList_Delete(&attr);
|
|
|
|
if(l[0])
|
|
ParseError("Could not find file '%s%s'", filename, pov::gPOV_File_Extensions[stype].ext[0]);
|
|
else
|
|
ParseError("Could not find file '%s'", filename);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// TODO - the following code might need reviewing, according to trf
|
|
|
|
/* Supported output file types */
|
|
struct ProcessRenderOptions::Output_FileType_Table FileTypeTable[] =
|
|
{
|
|
// attribute-specific file types (must go first)
|
|
// code, attribute, internalId, has16BitGrayscale hasAlpha
|
|
// { 'C', kPOVAttrib_HistogramFileType, kPOVList_FileType_CSV, false, false },
|
|
|
|
// generic file types
|
|
// code, attribute, internalId, has16BitGrayscale hasAlpha
|
|
{ 'T', 0, kPOVList_FileType_Targa, false, true },
|
|
{ 'C', 0, kPOVList_FileType_CompressedTarga, false, true },
|
|
{ 'N', 0, kPOVList_FileType_PNG, true, true },
|
|
{ 'J', 0, kPOVList_FileType_JPEG, false, false },
|
|
{ 'P', 0, kPOVList_FileType_PPM, true, false },
|
|
{ 'B', 0, kPOVList_FileType_BMP, false, false /*[1]*/ },
|
|
{ 'E', 0, kPOVList_FileType_OpenEXR, false /*[2]*/, true },
|
|
{ 'H', 0, kPOVList_FileType_RadianceHDR, false, false },
|
|
#ifdef SYS_TO_STANDARD
|
|
{ 'S', 0, kPOVList_FileType_System, SYS_GRAYSCALE_FLAG, SYS_ALPHA_FLAG },
|
|
#endif // SYS_TO_STANDARD
|
|
|
|
// [1] Alpha support for BMP uses an inofficial extension to the BMP file format, which is not recognized by
|
|
// most image pocessing software.
|
|
|
|
// [2] While OpenEXR does support greyscale output at >8 bits, the variants currently supported by POV-Ray
|
|
// use 16-bit floating-point values with 10 bit mantissa, which might be insufficient for various purposes
|
|
// such as height fields.
|
|
|
|
// end-of-list marker
|
|
{ '\0', 0, 0, false }
|
|
};
|
|
|
|
/* Supported special gamma types */
|
|
struct ProcessRenderOptions::Parameter_Code_Table GammaTypeTable[] =
|
|
{
|
|
|
|
// code, internalId,
|
|
{ "SRGB", kPOVList_GammaType_SRGB },
|
|
|
|
// end-of-list marker
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
/* Supported dither types */
|
|
struct ProcessRenderOptions::Parameter_Code_Table DitherMethodTable[] =
|
|
{
|
|
|
|
// code, internalId,
|
|
{ "B2", kPOVList_DitherMethod_Bayer2x2 },
|
|
{ "B3", kPOVList_DitherMethod_Bayer3x3 },
|
|
{ "B4", kPOVList_DitherMethod_Bayer4x4 },
|
|
{ "D1", kPOVList_DitherMethod_Diffusion1D },
|
|
{ "D2", kPOVList_DitherMethod_Diffusion2D },
|
|
{ "FS", kPOVList_DitherMethod_FloydSteinberg },
|
|
|
|
// end-of-list marker
|
|
{ NULL, 0 }
|
|
};
|
|
|
|
int ProcessRenderOptions::ParseFileType(char code, POVMSType attribute, int* pInternalId, bool* pHas16BitGreyscale)
|
|
{
|
|
*pInternalId = kPOVList_FileType_Unknown;
|
|
int err = kNoErr;
|
|
for (int i = 0; FileTypeTable[i].code != '\0'; i ++)
|
|
{
|
|
if ( (toupper(code) == FileTypeTable[i].code) &&
|
|
((FileTypeTable[i].attribute == 0) || (FileTypeTable[i].attribute == attribute )) )
|
|
{
|
|
if (pHas16BitGreyscale != NULL)
|
|
*pHas16BitGreyscale = FileTypeTable[i].has16BitGrayscale;
|
|
*pInternalId = FileTypeTable[i].internalId;
|
|
break;
|
|
}
|
|
}
|
|
#ifdef OPENEXR_MISSING
|
|
if (*pInternalId == kPOVList_FileType_OpenEXR)
|
|
{
|
|
ParseError(
|
|
"This unofficial POV-Ray binary was built without support for the OpenEXR \
|
|
file format. You must either use an official POV-Ray binary or recompile \
|
|
the POV-Ray sources on a system providing you with the OpenEXR library \
|
|
to make use of this facility. Alternatively, you may use any of the \
|
|
following built-in formats: HDR."
|
|
);
|
|
err = kParamErr;
|
|
}
|
|
#endif // OPENEXR_MISSING
|
|
if (*pInternalId == kPOVList_FileType_Unknown)
|
|
{
|
|
ParseError("Unrecognized output file format %c.", code);
|
|
err = kParamErr;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
char ProcessRenderOptions::UnparseFileType(int fileType)
|
|
{
|
|
for (int i = 0; FileTypeTable[i].code != '\0'; i ++)
|
|
if (fileType == FileTypeTable[i].internalId)
|
|
return FileTypeTable[i].code;
|
|
return '\0';
|
|
}
|
|
|
|
int ProcessRenderOptions::ParseGammaType(char* code, int* pInternalId)
|
|
{
|
|
*pInternalId = kPOVList_GammaType_Unknown;
|
|
int err = ParseParameterCode(GammaTypeTable, code, pInternalId);
|
|
if (err == kParamErr)
|
|
ParseError("Unrecognized gamma setting '%s'.", code);
|
|
return err;
|
|
}
|
|
|
|
const char* ProcessRenderOptions::UnparseGammaType(int gammaType)
|
|
{
|
|
return UnparseParameterCode(GammaTypeTable, gammaType);
|
|
}
|
|
|
|
int ProcessRenderOptions::ParseParameterCode(const ProcessRenderOptions::Parameter_Code_Table* codeTable, char* code, int* pInternalId)
|
|
{
|
|
for (int i = 0; code[i] != '\0'; i ++)
|
|
code[i] = toupper(code[i]);
|
|
for (int i = 0; codeTable[i].code != NULL; i ++)
|
|
{
|
|
if ( strcmp(code, codeTable[i].code) == 0 )
|
|
{
|
|
*pInternalId = codeTable[i].internalId;
|
|
return kNoErr;
|
|
}
|
|
}
|
|
return kParamErr;
|
|
}
|
|
|
|
const char* ProcessRenderOptions::UnparseParameterCode(const ProcessRenderOptions::Parameter_Code_Table* codeTable, int internalId)
|
|
{
|
|
for (int i = 0; codeTable[i].code != NULL; i ++)
|
|
if (internalId == codeTable[i].internalId)
|
|
return codeTable[i].code;
|
|
return NULL;
|
|
}
|
|
|
|
}
|