mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-07-01 22:06:10 -04:00
1.0.0.2 12/05/2016
--User changes -Add many tooltips to help clarify functionality. -Select multiple flames in library for del/move. Still only one allowed to be set as the current. -Show checkbox for current flame. Remember this is not necessarily what's selected. -User can now drag a square to select xforms, which keeps in sync with checkboxes. -Remove --nframes from command line. Replace with new params: --loopframes, --interpframes, --interploops. -Add two new options to EmberGenome: --cwloops --cwinterploops to specify whether rotation should go clockwise instead of the default counter clockwise. -Add these to Fractorium as checkboxes. -Apply All now also works for toggling animate flag on xforms. -Options dialog now allows user to set whether double click toggles spinners, or right click does. --Bug fixes -Selecting final and non-final xforms, and then dragging the non-final did not drag the final with it. -Selecting all xforms when a final was present, then deleting crashed the program. -Remove support for ppm files in the command line programs, it's an outdated format. -Switching between SP and DP kept reapplying the palette adjustments. --Code changes -Move build system to Visual Studio 2015 and Qt 5.6. -SSE used during addition of points to the histogram. -Remove last remnants of old flam3 C code and replace with C++. -Remove unused code involving tbb::task_group. -Make settings object a global shared_ptr singleton, so it doesn't have to be passed around.
This commit is contained in:
@ -18,13 +18,11 @@
|
||||
#include <BaseTsd.h>
|
||||
#include <crtdbg.h>
|
||||
#include <tchar.h>
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#define _TCHAR char
|
||||
#define _tmain main
|
||||
#define _T
|
||||
#define fprintf_s fprintf
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@ -43,7 +41,6 @@
|
||||
#define PNG_SKIP_SETJMP_CHECK 1
|
||||
|
||||
#include "png.h"
|
||||
//#include "pnginfo.h"
|
||||
|
||||
//Ember.
|
||||
#include "Ember.h"
|
||||
|
@ -65,6 +65,8 @@ enum class eOptionIDs : et
|
||||
OPT_ENCLOSED,
|
||||
OPT_NO_EDITS,
|
||||
OPT_UNSMOOTH_EDGE,
|
||||
OPT_CW_LOOPS,
|
||||
OPT_CW_INTERP_LOOPS,
|
||||
OPT_LOCK_ACCUM,
|
||||
OPT_DUMP_KERNEL,
|
||||
|
||||
@ -80,7 +82,9 @@ enum class eOptionIDs : et
|
||||
OPT_END,
|
||||
OPT_FRAME,
|
||||
OPT_DTIME,
|
||||
OPT_NFRAMES,
|
||||
OPT_LOOP_FRAMES,
|
||||
OPT_INTERP_FRAMES,
|
||||
OPT_INTERP_LOOPS,
|
||||
OPT_SYMMETRY,
|
||||
OPT_SHEEP_GEN,
|
||||
OPT_SHEEP_ID,
|
||||
@ -236,7 +240,7 @@ private:
|
||||
{ \
|
||||
if (member.m_Option.nArgType == SO_OPT) \
|
||||
{ \
|
||||
member(!strcmp(args.OptionArg(), "true")); \
|
||||
member(!_stricmp(args.OptionArg(), "true")); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@ -245,50 +249,40 @@ private:
|
||||
} \
|
||||
break
|
||||
|
||||
//Parsing is the same for all numerical option types.
|
||||
#define PARSEOPTION(e, member) \
|
||||
case (e): \
|
||||
{ \
|
||||
ss.clear(); \
|
||||
ss.str(args.OptionArg()); \
|
||||
ss >> member.m_Val; \
|
||||
break; \
|
||||
}
|
||||
|
||||
//Int.
|
||||
#define Eoi EmberOptionEntry<intmax_t>
|
||||
#define INITINTOPTION(member, option) \
|
||||
member = option; \
|
||||
m_IntArgs.push_back(&member)
|
||||
|
||||
#define PARSEINTOPTION(e, member) \
|
||||
case (e): \
|
||||
sscanf_s(args.OptionArg(), "%ld", &member.m_Val); \
|
||||
break
|
||||
|
||||
//Uint.
|
||||
#define Eou EmberOptionEntry<size_t>
|
||||
#define INITUINTOPTION(member, option) \
|
||||
member = option; \
|
||||
m_UintArgs.push_back(&member)
|
||||
|
||||
#define PARSEUINTOPTION(e, member) \
|
||||
case (e): \
|
||||
sscanf_s(args.OptionArg(), "%lu", &member.m_Val); \
|
||||
break
|
||||
|
||||
//Double.
|
||||
#define Eod EmberOptionEntry<double>
|
||||
#define INITDOUBLEOPTION(member, option) \
|
||||
member = option; \
|
||||
m_DoubleArgs.push_back(&member)
|
||||
|
||||
#define PARSEDOUBLEOPTION(e, member) \
|
||||
case (e): \
|
||||
sscanf_s(args.OptionArg(), "%lf", &member.m_Val); \
|
||||
break
|
||||
|
||||
//String.
|
||||
#define Eos EmberOptionEntry<string>
|
||||
#define INITSTRINGOPTION(member, option) \
|
||||
member = option; \
|
||||
m_StringArgs.push_back(&member)
|
||||
|
||||
#define PARSESTRINGOPTION(e, member) \
|
||||
case (e): \
|
||||
member.m_Val = args.OptionArg(); \
|
||||
break
|
||||
|
||||
/// <summary>
|
||||
/// Class for holding all available options across all command line programs.
|
||||
/// Some are used only for a single program, while others are used for more than one.
|
||||
@ -345,6 +339,8 @@ public:
|
||||
INITBOOLOPTION(Enclosed, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_ENCLOSED, _T("--enclosed"), true, SO_OPT, " --enclosed Use enclosing Xml tags [default: true].\n"));
|
||||
INITBOOLOPTION(NoEdits, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_NO_EDITS, _T("--noedits"), false, SO_NONE, " --noedits Exclude edit tags when writing Xml [default: false].\n"));
|
||||
INITBOOLOPTION(UnsmoothEdge, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_UNSMOOTH_EDGE, _T("--unsmoother"), false, SO_NONE, " --unsmoother Do not use smooth blending for sheep edges [default: false].\n"));
|
||||
INITBOOLOPTION(CwLoops, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_CW_LOOPS, _T("--cwloops"), false, SO_NONE, " --cwloops Rotate loops clockwise [default: false].\n"));
|
||||
INITBOOLOPTION(CwInterpLoops, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_CW_INTERP_LOOPS, _T("--cwinterploops"), false, SO_NONE, " --cwinterploops Rotate clockwise during interpolation, ignored if --interploops is 0 [default: false].\n"));
|
||||
INITBOOLOPTION(LockAccum, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_LOCK_ACCUM, _T("--lock_accum"), false, SO_NONE, " --lock_accum Lock threads when accumulating to the histogram using the CPU. This will drop performance to that of single threading [default: false].\n"));
|
||||
INITBOOLOPTION(DumpKernel, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_DUMP_KERNEL, _T("--dump_kernel"), false, SO_NONE, " --dump_kernel Print the iteration kernel string when using OpenCL (ignored for CPU) [default: false].\n"));
|
||||
//Int.
|
||||
@ -368,20 +364,22 @@ public:
|
||||
INITUINTOPTION(LastFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, " --end=<val> Time of last frame to render [default: last time specified in the input file].\n"));
|
||||
INITUINTOPTION(Frame, Eou(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_FRAME, _T("--frame"), UINT_MAX, SO_REQ_SEP, " --frame=<val> Time of first and last frame (ie do one frame).\n"));
|
||||
INITUINTOPTION(Dtime, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_DTIME, _T("--dtime"), 1, SO_REQ_SEP, " --dtime=<val> Time between frames [default: 1].\n"));
|
||||
INITUINTOPTION(Frames, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_NFRAMES, _T("--nframes"), 20, SO_REQ_SEP, " --nframes=<val> Number of frames per loop and per interpolation in the animation [default: 20].\n"));
|
||||
INITUINTOPTION(LoopFrames, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_LOOP_FRAMES, _T("--loopframes"), 20, SO_REQ_SEP, " --loopframes=<val> Number of frames per loop in the animation [default: 20].\n"));
|
||||
INITUINTOPTION(InterpFrames, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_INTERP_FRAMES, _T("--interpframes"), 20, SO_REQ_SEP, " --interpframes=<val> Number of frames per interpolation in the animation [default: 20].\n"));
|
||||
INITUINTOPTION(InterpLoops, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_INTERP_LOOPS, _T("--interploops"), 1, SO_REQ_SEP, " --interploops=<val> The number of 360 degree loops to rotate when interpolating between keyframes [default: 1].\n"));
|
||||
INITUINTOPTION(Repeat, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_REPEAT, _T("--repeat"), 1, SO_REQ_SEP, " --repeat=<val> Number of new flames to create. Ignored if sequence, inter or rotate were specified [default: 1].\n"));
|
||||
INITUINTOPTION(Tries, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_TRIES, _T("--tries"), 10, SO_REQ_SEP, " --tries=<val> Number times to try creating a flame that meets the specified constraints. Ignored if sequence, inter or rotate were specified [default: 10].\n"));
|
||||
INITUINTOPTION(MaxXforms, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, " --maxxforms=<val> The maximum number of xforms allowed in the final output.\n"));
|
||||
INITUINTOPTION(StartCount, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_START_COUNT, _T("--startcount"), 0, SO_REQ_SEP, " --startcount=<val> The number to add to each flame name when generating a sequence. Useful for programs like ffmpeg which require numerically increasing filenames [default: 0].\n"));
|
||||
INITUINTOPTION(Padding, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_PADDING, _T("--padding"), 0, SO_REQ_SEP, " --padding=<val> Override the amount of zero padding added to each flame name when generating a sequence. Useful for programs like ffmpeg which require fixed width filenames [default: 0 (auto calculate padding)].\n"));
|
||||
//Double.
|
||||
INITDOUBLEOPTION(SizeScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SS, _T("--ss"), 1, SO_REQ_SEP, " --ss=<val> Size scale. All dimensions are scaled by this amount [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(QualityScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_QS, _T("--qs"), 1, SO_REQ_SEP, " --qs=<val> Quality scale. All quality values are scaled by this amount [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(Quality, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_QUALITY, _T("--quality"), 0, SO_REQ_SEP, " --quality=<val> Override the quality of the flame if not 0 [default: 0].\n"));
|
||||
INITDOUBLEOPTION(DeMin, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_DE_MIN, _T("--demin"), -1, SO_REQ_SEP, " --demin=<val> Override the minimum size of the density estimator filter radius if not -1 [default: -1].\n"));
|
||||
INITDOUBLEOPTION(DeMax, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_DE_MAX, _T("--demax"), -1, SO_REQ_SEP, " --demax=<val> Override the maximum size of the density estimator filter radius if not -1 [default: -1].\n"));
|
||||
INITDOUBLEOPTION(AspectRatio, Eod(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PIXEL_ASPECT, _T("--pixel_aspect"), 1, SO_REQ_SEP, " --pixel_aspect=<val> Aspect ratio of pixels (width over height), eg. 0.90909 for NTSC [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(Stagger, Eod(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_STAGGER, _T("--stagger"), 0, SO_REQ_SEP, " --stagger=<val> Affects simultaneity of xform interpolation during flame interpolation.\n"
|
||||
INITDOUBLEOPTION(SizeScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SS, _T("--ss"), 1.0, SO_REQ_SEP, " --ss=<val> Size scale. All dimensions are scaled by this amount [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(QualityScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_QS, _T("--qs"), 1.0, SO_REQ_SEP, " --qs=<val> Quality scale. All quality values are scaled by this amount [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(Quality, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_QUALITY, _T("--quality"), 0.0, SO_REQ_SEP, " --quality=<val> Override the quality of the flame if not 0 [default: 0].\n"));
|
||||
INITDOUBLEOPTION(DeMin, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_DE_MIN, _T("--demin"), -1.0, SO_REQ_SEP, " --demin=<val> Override the minimum size of the density estimator filter radius if not -1 [default: -1].\n"));
|
||||
INITDOUBLEOPTION(DeMax, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_DE_MAX, _T("--demax"), -1.0, SO_REQ_SEP, " --demax=<val> Override the maximum size of the density estimator filter radius if not -1 [default: -1].\n"));
|
||||
INITDOUBLEOPTION(AspectRatio, Eod(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PIXEL_ASPECT, _T("--pixel_aspect"), 1.0, SO_REQ_SEP, " --pixel_aspect=<val> Aspect ratio of pixels (width over height), eg. 0.90909 for NTSC [default: 1.0].\n"));
|
||||
INITDOUBLEOPTION(Stagger, Eod(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_STAGGER, _T("--stagger"), 0.0, SO_REQ_SEP, " --stagger=<val> Affects simultaneity of xform interpolation during flame interpolation.\n"
|
||||
"\t Represents how 'separate' the xforms are interpolated. Set to 1 for each\n"
|
||||
"\t xform to be interpolated individually, fractions control interpolation overlap [default: 0].\n"));
|
||||
INITDOUBLEOPTION(AvgThresh, Eod(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_AVG_THRESH, _T("--avg"), 20.0, SO_REQ_SEP, " --avg=<val> Minimum average pixel channel sum (r + g + b) threshold from 0 - 765. Ignored if sequence, inter or rotate were specified [default: 20].\n"));
|
||||
@ -399,7 +397,7 @@ public:
|
||||
INITSTRINGOPTION(Out, Eos(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_OUT, _T("--out"), "", SO_REQ_SEP, " --out=<val> Name of a single output file. Not recommended when rendering more than one image.\n"));
|
||||
INITSTRINGOPTION(Prefix, Eos(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PREFIX, _T("--prefix"), "", SO_REQ_SEP, " --prefix=<val> Prefix to prepend to all output files.\n"));
|
||||
INITSTRINGOPTION(Suffix, Eos(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SUFFIX, _T("--suffix"), "", SO_REQ_SEP, " --suffix=<val> Suffix to append to all output files.\n"));
|
||||
INITSTRINGOPTION(Format, Eos(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_FORMAT, _T("--format"), "png", SO_REQ_SEP, " --format=<val> Format of the output file. Valid values are: bmp, jpg, png, ppm [default: png].\n"));
|
||||
INITSTRINGOPTION(Format, Eos(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_FORMAT, _T("--format"), "png", SO_REQ_SEP, " --format=<val> Format of the output file. Valid values are: bmp, jpg, png [default: png].\n"));
|
||||
INITSTRINGOPTION(PalettePath, Eos(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PALETTE_FILE, _T("--flam3_palettes"), "flam3-palettes.xml", SO_REQ_SEP, " --flam3_palettes=<val> Path and name of the palette file [default: flam3-palettes.xml].\n"));
|
||||
INITSTRINGOPTION(Id, Eos(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_ID, _T("--id"), "", SO_REQ_SEP, " --id=<val> ID to use in <edit> tags / image comments.\n"));
|
||||
INITSTRINGOPTION(Url, Eos(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_URL, _T("--url"), "", SO_REQ_SEP, " --url=<val> URL to use in <edit> tags / image comments.\n"));
|
||||
@ -436,6 +434,7 @@ public:
|
||||
EmberOptions options;
|
||||
vector<CSimpleOpt::SOption> sOptions = options.GetSimpleOptions();
|
||||
CSimpleOpt args(argc, argv, sOptions.data());
|
||||
stringstream ss;
|
||||
|
||||
//Process args.
|
||||
while (args.Next())
|
||||
@ -492,72 +491,76 @@ public:
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_ENCLOSED, Enclosed);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_NO_EDITS, NoEdits);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_UNSMOOTH_EDGE, UnsmoothEdge);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_CW_LOOPS, CwLoops);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_CW_INTERP_LOOPS, CwInterpLoops);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_LOCK_ACCUM, LockAccum);
|
||||
PARSEBOOLOPTION(eOptionIDs::OPT_DUMP_KERNEL, DumpKernel);
|
||||
PARSEINTOPTION(eOptionIDs::OPT_SYMMETRY, Symmetry);//Int args
|
||||
PARSEINTOPTION(eOptionIDs::OPT_SHEEP_GEN, SheepGen);
|
||||
PARSEINTOPTION(eOptionIDs::OPT_SHEEP_ID, SheepId);
|
||||
PARSEINTOPTION(eOptionIDs::OPT_PRIORITY, Priority);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_NTHREADS, ThreadCount);//uint args.
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_STRIPS, Strips);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_SUPERSAMPLE, Supersample);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_TEMPSAMPLES, TemporalSamples);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_BPC, BitsPerChannel);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_PRINT_EDIT_DEPTH, PrintEditDepth);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_JPEG, JpegQuality);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_BEGIN, FirstFrame);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_END, LastFrame);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_FRAME, Frame);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_DTIME, Dtime);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_NFRAMES, Frames);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_REPEAT, Repeat);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_TRIES, Tries);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_MAX_XFORMS, MaxXforms);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_START_COUNT, StartCount);
|
||||
PARSEUINTOPTION(eOptionIDs::OPT_PADDING, Padding);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_SS, SizeScale);//Float args.
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_QS, QualityScale);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_QUALITY, Quality);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_DE_MIN, DeMin);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_DE_MAX, DeMax);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_PIXEL_ASPECT, AspectRatio);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_STAGGER, Stagger);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_AVG_THRESH, AvgThresh);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_BLACK_THRESH, BlackThresh);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_WHITE_LIMIT, WhiteLimit);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_SPEED, Speed);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_OFFSETX, OffsetX);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_OFFSETY, OffsetY);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_USEMEM, UseMem);
|
||||
PARSEDOUBLEOPTION(eOptionIDs::OPT_LOOPS, Loops);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_OPENCL_DEVICE, Device);//String args.
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_ISAAC_SEED, IsaacSeed);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_IN, Input);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_OUT, Out);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_PREFIX, Prefix);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_SUFFIX, Suffix);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_FORMAT, Format);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_PALETTE_FILE, PalettePath);
|
||||
PARSEOPTION(eOptionIDs::OPT_SYMMETRY, Symmetry);//Int args
|
||||
PARSEOPTION(eOptionIDs::OPT_SHEEP_GEN, SheepGen);
|
||||
PARSEOPTION(eOptionIDs::OPT_SHEEP_ID, SheepId);
|
||||
PARSEOPTION(eOptionIDs::OPT_PRIORITY, Priority);
|
||||
PARSEOPTION(eOptionIDs::OPT_NTHREADS, ThreadCount);//uint args.
|
||||
PARSEOPTION(eOptionIDs::OPT_STRIPS, Strips);
|
||||
PARSEOPTION(eOptionIDs::OPT_SUPERSAMPLE, Supersample);
|
||||
PARSEOPTION(eOptionIDs::OPT_TEMPSAMPLES, TemporalSamples);
|
||||
PARSEOPTION(eOptionIDs::OPT_BPC, BitsPerChannel);
|
||||
PARSEOPTION(eOptionIDs::OPT_PRINT_EDIT_DEPTH, PrintEditDepth);
|
||||
PARSEOPTION(eOptionIDs::OPT_JPEG, JpegQuality);
|
||||
PARSEOPTION(eOptionIDs::OPT_BEGIN, FirstFrame);
|
||||
PARSEOPTION(eOptionIDs::OPT_END, LastFrame);
|
||||
PARSEOPTION(eOptionIDs::OPT_FRAME, Frame);
|
||||
PARSEOPTION(eOptionIDs::OPT_DTIME, Dtime);
|
||||
PARSEOPTION(eOptionIDs::OPT_LOOP_FRAMES, LoopFrames);
|
||||
PARSEOPTION(eOptionIDs::OPT_INTERP_FRAMES, InterpFrames);
|
||||
PARSEOPTION(eOptionIDs::OPT_INTERP_LOOPS, InterpLoops);
|
||||
PARSEOPTION(eOptionIDs::OPT_REPEAT, Repeat);
|
||||
PARSEOPTION(eOptionIDs::OPT_TRIES, Tries);
|
||||
PARSEOPTION(eOptionIDs::OPT_MAX_XFORMS, MaxXforms);
|
||||
PARSEOPTION(eOptionIDs::OPT_START_COUNT, StartCount);
|
||||
PARSEOPTION(eOptionIDs::OPT_PADDING, Padding);
|
||||
PARSEOPTION(eOptionIDs::OPT_SS, SizeScale);//Float args.
|
||||
PARSEOPTION(eOptionIDs::OPT_QS, QualityScale);
|
||||
PARSEOPTION(eOptionIDs::OPT_QUALITY, Quality);
|
||||
PARSEOPTION(eOptionIDs::OPT_DE_MIN, DeMin);
|
||||
PARSEOPTION(eOptionIDs::OPT_DE_MAX, DeMax);
|
||||
PARSEOPTION(eOptionIDs::OPT_PIXEL_ASPECT, AspectRatio);
|
||||
PARSEOPTION(eOptionIDs::OPT_STAGGER, Stagger);
|
||||
PARSEOPTION(eOptionIDs::OPT_AVG_THRESH, AvgThresh);
|
||||
PARSEOPTION(eOptionIDs::OPT_BLACK_THRESH, BlackThresh);
|
||||
PARSEOPTION(eOptionIDs::OPT_WHITE_LIMIT, WhiteLimit);
|
||||
PARSEOPTION(eOptionIDs::OPT_SPEED, Speed);
|
||||
PARSEOPTION(eOptionIDs::OPT_OFFSETX, OffsetX);
|
||||
PARSEOPTION(eOptionIDs::OPT_OFFSETY, OffsetY);
|
||||
PARSEOPTION(eOptionIDs::OPT_USEMEM, UseMem);
|
||||
PARSEOPTION(eOptionIDs::OPT_LOOPS, Loops);
|
||||
PARSEOPTION(eOptionIDs::OPT_OPENCL_DEVICE, Device);//String args.
|
||||
PARSEOPTION(eOptionIDs::OPT_ISAAC_SEED, IsaacSeed);
|
||||
PARSEOPTION(eOptionIDs::OPT_IN, Input);
|
||||
PARSEOPTION(eOptionIDs::OPT_OUT, Out);
|
||||
PARSEOPTION(eOptionIDs::OPT_PREFIX, Prefix);
|
||||
PARSEOPTION(eOptionIDs::OPT_SUFFIX, Suffix);
|
||||
PARSEOPTION(eOptionIDs::OPT_FORMAT, Format);
|
||||
PARSEOPTION(eOptionIDs::OPT_PALETTE_FILE, PalettePath);
|
||||
//PARSESTRINGOPTION(eOptionIDs::OPT_PALETTE_IMAGE, PaletteImage);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_ID, Id);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_URL, Url);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_NICK, Nick);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_COMMENT, Comment);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_TEMPLATE, TemplateFile);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_CLONE, Clone);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_CLONE_ALL, CloneAll);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_CLONE_ACTION, CloneAction);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_ANIMATE, Animate);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_MUTATE, Mutate);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_CROSS0, Cross0);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_CROSS1, Cross1);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_METHOD, Method);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_INTER, Inter);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_ROTATE, Rotate);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_SEQUENCE, Sequence);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_USE_VARS, UseVars);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_DONT_USE_VARS, DontUseVars);
|
||||
PARSESTRINGOPTION(eOptionIDs::OPT_EXTRAS, Extras);
|
||||
PARSEOPTION(eOptionIDs::OPT_ID, Id);
|
||||
PARSEOPTION(eOptionIDs::OPT_URL, Url);
|
||||
PARSEOPTION(eOptionIDs::OPT_NICK, Nick);
|
||||
PARSEOPTION(eOptionIDs::OPT_COMMENT, Comment);
|
||||
PARSEOPTION(eOptionIDs::OPT_TEMPLATE, TemplateFile);
|
||||
PARSEOPTION(eOptionIDs::OPT_CLONE, Clone);
|
||||
PARSEOPTION(eOptionIDs::OPT_CLONE_ALL, CloneAll);
|
||||
PARSEOPTION(eOptionIDs::OPT_CLONE_ACTION, CloneAction);
|
||||
PARSEOPTION(eOptionIDs::OPT_ANIMATE, Animate);
|
||||
PARSEOPTION(eOptionIDs::OPT_MUTATE, Mutate);
|
||||
PARSEOPTION(eOptionIDs::OPT_CROSS0, Cross0);
|
||||
PARSEOPTION(eOptionIDs::OPT_CROSS1, Cross1);
|
||||
PARSEOPTION(eOptionIDs::OPT_METHOD, Method);
|
||||
PARSEOPTION(eOptionIDs::OPT_INTER, Inter);
|
||||
PARSEOPTION(eOptionIDs::OPT_ROTATE, Rotate);
|
||||
PARSEOPTION(eOptionIDs::OPT_SEQUENCE, Sequence);
|
||||
PARSEOPTION(eOptionIDs::OPT_USE_VARS, UseVars);
|
||||
PARSEOPTION(eOptionIDs::OPT_DONT_USE_VARS, DontUseVars);
|
||||
PARSEOPTION(eOptionIDs::OPT_EXTRAS, Extras);
|
||||
|
||||
default:
|
||||
{
|
||||
@ -775,6 +778,8 @@ public:
|
||||
Eob Enclosed;
|
||||
Eob NoEdits;
|
||||
Eob UnsmoothEdge;
|
||||
Eob CwLoops;
|
||||
Eob CwInterpLoops;
|
||||
Eob LockAccum;
|
||||
Eob DumpKernel;
|
||||
|
||||
@ -794,7 +799,9 @@ public:
|
||||
Eou LastFrame;
|
||||
Eou Frame;
|
||||
Eou Dtime;
|
||||
Eou Frames;
|
||||
Eou LoopFrames;
|
||||
Eou InterpFrames;
|
||||
Eou InterpLoops;
|
||||
Eou Repeat;
|
||||
Eou Tries;
|
||||
Eou MaxXforms;
|
||||
|
@ -4,31 +4,6 @@
|
||||
|
||||
#define PNG_COMMENT_MAX 8
|
||||
|
||||
/// <summary>
|
||||
/// Write a PPM file.
|
||||
/// </summary>
|
||||
/// <param name="filename">The full path and name of the file</param>
|
||||
/// <param name="image">Pointer to the image data to write</param>
|
||||
/// <param name="width">Width of the image in pixels</param>
|
||||
/// <param name="height">Height of the image in pixels</param>
|
||||
/// <returns>True if success, else false</returns>
|
||||
static bool WritePpm(const char* filename, byte* image, size_t width, size_t height)
|
||||
{
|
||||
bool b = false;
|
||||
size_t size = width * height * 3;
|
||||
FILE* file;
|
||||
|
||||
if (fopen_s(&file, filename, "wb") == 0)
|
||||
{
|
||||
fprintf_s(file, "P6\n");
|
||||
fprintf_s(file, "%lu %lu\n255\n", width, height);
|
||||
b = (size == fwrite(image, 1, size, file));
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a JPEG file.
|
||||
/// </summary>
|
||||
@ -53,15 +28,16 @@ static bool WriteJpeg(const char* filename, byte* image, size_t width, size_t he
|
||||
size_t i;
|
||||
jpeg_error_mgr jerr;
|
||||
jpeg_compress_struct info;
|
||||
char nickString[64], urlString[128], idString[128];
|
||||
char bvString[64], niString[64], rtString[64];
|
||||
char genomeString[65536], verString[64];
|
||||
string nickString, urlString, idString;
|
||||
string bvString, niString, rtString;
|
||||
string genomeString, verString;
|
||||
//Create the mandatory comment strings.
|
||||
snprintf_s(genomeString, 65536, "flam3_genome: %s", comments.m_Genome.c_str());
|
||||
snprintf_s(bvString, 64, "flam3_error_rate: %s", comments.m_Badvals.c_str());
|
||||
snprintf_s(niString, 64, "flam3_samples: %s", comments.m_NumIters.c_str());
|
||||
snprintf_s(rtString, 64, "flam3_time: %s", comments.m_Runtime.c_str());
|
||||
snprintf_s(verString, 64, "flam3_version: %s", EmberVersion());
|
||||
ostringstream os;
|
||||
os << "genome: " << comments.m_Genome; genomeString = os.str(); os.str("");
|
||||
os << "error_rate: " << comments.m_Badvals; bvString = os.str(); os.str("");
|
||||
os << "samples: " << comments.m_NumIters; niString = os.str(); os.str("");
|
||||
os << "time: " << comments.m_Runtime; rtString = os.str(); os.str("");
|
||||
os << "version: " << EmberVersion(); verString = os.str(); os.str("");
|
||||
info.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&info);
|
||||
jpeg_stdio_dest(&info, file);
|
||||
@ -83,36 +59,43 @@ static bool WriteJpeg(const char* filename, byte* image, size_t width, size_t he
|
||||
//Write comments to jpeg.
|
||||
if (enableComments)
|
||||
{
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(verString), uint(strlen(verString)));
|
||||
string s;
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(verString.c_str()), uint(verString.size()));
|
||||
|
||||
if (nick != "")
|
||||
{
|
||||
snprintf_s(nickString, 64, "flam3_nickname: %s", nick.c_str());
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(nickString), uint(strlen(nickString)));
|
||||
os.str("");
|
||||
os << "nickname: " << nick;
|
||||
s = os.str();
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(s.c_str()), uint(s.size()));
|
||||
}
|
||||
|
||||
if (url != "")
|
||||
{
|
||||
snprintf_s(urlString, 128, "flam3_url: %s", url.c_str());
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(urlString), uint(strlen(urlString)));
|
||||
os.str("");
|
||||
os << "url: " << url;
|
||||
s = os.str();
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(s.c_str()), uint(s.size()));
|
||||
}
|
||||
|
||||
if (id != "")
|
||||
{
|
||||
snprintf_s(idString, 128, "flam3_id: %s", id.c_str());
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(idString), uint(strlen(idString)));
|
||||
os.str("");
|
||||
os << "id: " << id;
|
||||
s = os.str();
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(s.c_str()), uint(s.size()));
|
||||
}
|
||||
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(bvString), uint(strlen(bvString)));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(niString), uint(strlen(niString)));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(rtString), uint(strlen(rtString)));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<byte*>(genomeString), uint(strlen(genomeString)));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(bvString.c_str()), uint(bvString.size()));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(niString.c_str()), uint(niString.size()));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(rtString.c_str()), uint(rtString.size()));
|
||||
jpeg_write_marker(&info, JPEG_COM, reinterpret_cast<const byte*>(genomeString.c_str()), uint(genomeString.size()));
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
JSAMPROW row_pointer[1];
|
||||
row_pointer[0] = reinterpret_cast<byte*>(image) + (3 * width * i);
|
||||
row_pointer[0] = image + (3 * width * i);
|
||||
jpeg_write_scanlines(&info, row_pointer, 1);
|
||||
}
|
||||
|
||||
@ -209,7 +192,7 @@ static bool WritePng(const char* filename, byte* image, size_t width, size_t hei
|
||||
png_set_swap(png_ptr);
|
||||
}
|
||||
|
||||
png_write_image(png_ptr, const_cast<png_bytepp>(rows.data()));
|
||||
png_write_image(png_ptr, rows.data());
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(file);
|
||||
@ -227,10 +210,10 @@ static bool WritePng(const char* filename, byte* image, size_t width, size_t hei
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="newSize">The size of the new buffer created</param>
|
||||
/// <returns>The converted buffer if successful, else NULL.</returns>
|
||||
static byte* ConvertRGBToBMPBuffer(byte* buffer, size_t width, size_t height, size_t& newSize)
|
||||
static vector<byte> ConvertRGBToBMPBuffer(byte* buffer, size_t width, size_t height, size_t& newSize)
|
||||
{
|
||||
if (buffer == nullptr || width == 0 || height == 0)
|
||||
return nullptr;
|
||||
return vector<byte>();
|
||||
|
||||
size_t padding = 0;
|
||||
size_t scanlinebytes = width * 3;
|
||||
@ -240,34 +223,27 @@ static byte* ConvertRGBToBMPBuffer(byte* buffer, size_t width, size_t height, si
|
||||
|
||||
size_t psw = scanlinebytes + padding;
|
||||
newSize = height * psw;
|
||||
byte* newBuf = new byte[newSize];
|
||||
vector<byte> newBuf(newSize);
|
||||
size_t bufpos = 0;
|
||||
size_t newpos = 0;
|
||||
|
||||
if (newBuf)
|
||||
for (size_t y = 0; y < height; y++)
|
||||
{
|
||||
memset (newBuf, 0, newSize);
|
||||
size_t bufpos = 0;
|
||||
size_t newpos = 0;
|
||||
|
||||
for (size_t y = 0; y < height; y++)
|
||||
for (size_t x = 0; x < 3 * width; x += 3)
|
||||
{
|
||||
for (size_t x = 0; x < 3 * width; x += 3)
|
||||
{
|
||||
bufpos = y * 3 * width + x; // position in original buffer
|
||||
newpos = (height - y - 1) * psw + x; // position in padded buffer
|
||||
newBuf[newpos] = buffer[bufpos + 2]; // swap r and b
|
||||
newBuf[newpos + 1] = buffer[bufpos + 1]; // g stays
|
||||
newBuf[newpos + 2] = buffer[bufpos]; // swap b and r
|
||||
//No swap.
|
||||
//newBuf[newpos] = buffer[bufpos];
|
||||
//newBuf[newpos + 1] = buffer[bufpos + 1];
|
||||
//newBuf[newpos + 2] = buffer[bufpos + 2];
|
||||
}
|
||||
bufpos = y * 3 * width + x; // position in original buffer
|
||||
newpos = (height - y - 1) * psw + x; // position in padded buffer
|
||||
newBuf[newpos] = buffer[bufpos + 2]; // swap r and b
|
||||
newBuf[newpos + 1] = buffer[bufpos + 1]; // g stays
|
||||
newBuf[newpos + 2] = buffer[bufpos]; // swap b and r
|
||||
//No swap.
|
||||
//newBuf[newpos] = buffer[bufpos];
|
||||
//newBuf[newpos + 1] = buffer[bufpos + 1];
|
||||
//newBuf[newpos + 2] = buffer[bufpos + 2];
|
||||
}
|
||||
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return newBuf;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -279,7 +255,7 @@ static byte* ConvertRGBToBMPBuffer(byte* buffer, size_t width, size_t height, si
|
||||
/// <param name="height">Height of the image in pixels</param>
|
||||
/// <param name="paddedSize">Padded size, greater than or equal to total image size.</param>
|
||||
/// <returns>True if success, else false</returns>
|
||||
static bool SaveBmp(const char* filename, byte* image, size_t width, size_t height, size_t paddedSize)
|
||||
static bool SaveBmp(const char* filename, const byte* image, size_t width, size_t height, size_t paddedSize)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
BITMAPFILEHEADER bmfh;
|
||||
@ -346,10 +322,7 @@ static bool WriteBmp(const char* filename, byte* image, size_t width, size_t hei
|
||||
{
|
||||
bool b = false;
|
||||
size_t newSize;
|
||||
unique_ptr<byte> bgrBuf(ConvertRGBToBMPBuffer(image, width, height, newSize));
|
||||
|
||||
if (bgrBuf.get())
|
||||
b = SaveBmp(filename, bgrBuf.get(), width, height, newSize);
|
||||
|
||||
auto bgrBuf = ConvertRGBToBMPBuffer(image, width, height, newSize);
|
||||
b = SaveBmp(filename, bgrBuf.data(), width, height, newSize);
|
||||
return b;
|
||||
}
|
||||
|
Reference in New Issue
Block a user