Browse Source

workinonit

Nicolas Winkler 5 năm trước cách đây
mục cha
commit
229a5251c0

+ 3 - 0
Almond.h

@@ -34,7 +34,9 @@ class Almond : public QMainWindow
     Q_OBJECT
 private:
     mnd::MandelContext mandelContext;
+public:
     std::unique_ptr<MandelWidget> mw;
+private:
     //std::unique_ptr<BenchmarkDialog> benchmarkDialog;
     std::unique_ptr<CustomGenerator> customGeneratorDialog;
     GradientChooseDialog gcd;
@@ -48,6 +50,7 @@ private:
     mnd::MandelViewport mandelViewSave;
     mnd::MandelViewport customViewSave;
     mnd::AdaptiveGenerator* mandelGenerator;
+public:
     mnd::MandelGenerator* currentGenerator;
 public:
     Almond(QWidget *parent = Q_NULLPTR);

+ 7 - 13
Almond.pro

@@ -28,14 +28,11 @@ CONFIG += c++17
 SOURCES += \
         Almond.cpp \
         BackgroundTask.cpp \
-        Bitmap.cpp \
         Color.cpp \
         CubicSpline.cpp \
         Gradient.cpp \
         GradientWidget.cpp \
-        MandelVideoGenerator.cpp \
         MandelWidget.cpp \
-        VideoStream.cpp \
         choosegenerators.cpp \
         customgenerator.cpp \
         exportdialogs.cpp \
@@ -45,14 +42,11 @@ SOURCES += \
 HEADERS += \
         Almond.h \
         BackgroundTask.h \
-        Bitmap.h \
         Color.h \
         CubicSpline.h \
         Gradient.h \
         GradientWidget.h \
-        MandelVideoGenerator.h \
         MandelWidget.h \
-        VideoStream.h \
         choosegenerators.h \
         customgenerator.h \
         exportdialogs.h \
@@ -131,16 +125,16 @@ unix|win32: LIBS += -L$FFMPEGPATH -lswscale
 
 RESOURCES += Almond.qrc
 
-unix|win32: LIBS += -L$$PWD/libmandel/ -lmandel -lqd -lasmjit
+unix|win32: LIBS += -L$$PWD/libmandel/ -L$$PWD/libalmond/ -lmandel -lqd -lasmjit -lalmond
 unix: LIBS += -lrt
 
-INCLUDEPATH += $$PWD/libmandel/include $$PWD/libmandel/qd-2.3.22/include
-DEPENDPATH += $$PWD/libmandel/include $$PWD/libmandel/qd-2.3.22/include
-INCLUDEPATH += $$PWD/libmandel/include $$PWD/libmandel/asmjit/src
-DEPENDPATH += $$PWD/libmandel/include $$PWD/libmandel/asmjit/stc
+INCLUDEPATH += $$PWD/libmandel/include $$PWD/libmandel/qd-2.3.22/include $$PWD/libalmond/include
+DEPENDPATH += $$PWD/libmandel/include $$PWD/libmandel/qd-2.3.22/include $$PWD/libalmond/include
+INCLUDEPATH += $$PWD/libmandel/include $$PWD/libmandel/asmjit/src $$PWD/libalmond/include
+DEPENDPATH += $$PWD/libmandel/include $$PWD/libmandel/asmjit/stc $$PWD/libalmond/include
 
-win32:!win32-g++: PRE_TARGETDEPS += $$PWD/libmandel/asmjit.lib $$PWD/libmandel/mandel.lib $$PWD/libmandel/qd.lib
-else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/libmandel/libmandel.a $$PWD/libmandel/libqd.a $$PWD/libmandel/libasmjit.a
+win32:!win32-g++: PRE_TARGETDEPS += $$PWD/libmandel/asmjit.lib $$PWD/libmandel/mandel.lib $$PWD/libmandel/qd.lib $$PWD/libalmond/almond.lib
+else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/libmandel/libmandel.a $$PWD/libmandel/libqd.a $$PWD/libmandel/libasmjit.a $$PWD/libalmond/almond.a
 
 
 win32:CONFIG(release, debug|release): LIBS += -L$$PWD/'../../../../../Program Files (x86)/OCL_SDK_Light/lib/x86_64/' -lopencl

+ 2 - 1
Almond.qrc

@@ -1,9 +1,10 @@
 <RCC>
-    <qresource prefix="gradients">
+    <qresource prefix="/gradients">
         <file alias="default">gradients/default.xml</file>
         <file alias="clouds">gradients/clouds.xml</file>
         <file alias="rainbow">gradients/rainbow.xml</file>
         <file alias="grayscale">gradients/grayscale.xml</file>
         <file alias="peach">gradients/peach.xml</file>
+        <file alias="blue gold">gradients/blue_gold.xml</file>
     </qresource>
 </RCC>

+ 0 - 2
Bitmap.cpp

@@ -1,2 +0,0 @@
-#include "Bitmap.h"
-

+ 0 - 63
Bitmap.h

@@ -1,63 +0,0 @@
-#pragma once
-#ifndef BITMAP_H_
-#define BITMAP_H_
-
-#include "Color.h"
-#include <memory>
-#include <string>
-#include <functional>
-
-template<typename Pixel>
-struct Bitmap
-{
-    long width, height;
-    std::unique_ptr<Pixel[]> pixels;
-public:
-    Bitmap(void) :
-        width{ 0 },
-        height{ 0 },
-        pixels{ 0 }
-    {
-    }
-
-
-    Bitmap(long width, long height) :
-        width{ width }, height{ height },
-        pixels{ std::make_unique<Pixel[]>(width * height) }
-    {
-    }
-
-    Bitmap(Bitmap&&) = default;
-    Bitmap& operator = (Bitmap&&) = default;
-
-    ~Bitmap() = default;
-
-    template<typename T>
-    Bitmap<T> map(std::function<T(Pixel)> f) const {
-        Bitmap<T> b{ width, height };
-#pragma omp parallel for
-        for (long i = 0; i < width * height; i++) {
-            b.pixels[i] = f(pixels[i]);
-        }
-        return b;
-    }
-
-    Pixel& get(long x, long y)
-    {
-        return pixels[x + y * width];
-    }
-
-    const Pixel& get(long x, long y) const
-    {
-        return pixels[x + y * width];
-    }
-
-    void print(void)
-    {
-        for (size_t i = 0; i < width * height; i++) {
-            printf("%03d ", int(pixels[i].r));
-        }
-    }
-};
-
-#endif // BITMAP_H_

+ 2 - 2
CMakeLists.txt

@@ -30,11 +30,11 @@ ELSE()
     add_executable(Almond ${AlmondSources} Almond.qrc)
 ENDIF()
 
-add_subdirectory(libmandel)
+add_subdirectory(libalmond)
 
 target_include_directories(Almond SYSTEM PUBLIC ${FFMPEG_INCLUDE_DIRS})
 
-target_link_libraries(Almond PUBLIC mandel)
+target_link_libraries(Almond PUBLIC libalmond)
 target_link_libraries(Almond PUBLIC Qt5::Core Qt5::Widgets Qt5::OpenGL Qt5::Xml)
 target_link_libraries(Almond PUBLIC ${FFMPEG_LIBRARIES})
 target_link_libraries(Almond PUBLIC OpenGL::GL)

+ 0 - 148
MandelVideoGenerator.cpp

@@ -1,148 +0,0 @@
-#include "MandelVideoGenerator.h"
-#include "VideoStream.h"
-#include <thread>
-#include <omp.h>
-
-#include <cmath>
-
-MandelVideoGenerator::MandelVideoGenerator(const ExportVideoInfo& evi) :
-    evi{ evi }
-{
-}
-
-
-void MandelVideoGenerator::generate(void)
-{
-    mnd::MandelContext ctxt = mnd::initializeContext();
-    mnd::MandelGenerator& gen = ctxt.getDefaultGenerator();
-    mnd::MandelInfo mi;
-    mi.bWidth = evi.width * 2;
-    mi.bHeight = evi.height * 2;
-    mi.maxIter = evi.maxIterations;
-
-    VideoStream vs(evi.width, evi.height, evi.path, evi.bitrate, evi.fps, evi.preset.c_str());
-
-    mnd::Real x = evi.end.x + evi.end.width / 2;
-    mnd::Real y = evi.end.y + evi.end.height / 2;
-    mnd::Real w = evi.start.width;
-    mnd::Real h = evi.start.height;
-
-    mnd::Real bigW = 10000000000000000.0;
-    double bigFac = 1.0;
-    Bitmap<RGBColor> big;
-    Bitmap<RGBColor> small;
-
-    while(w > evi.end.width || h > evi.end.height) {
-        mi.view = mnd::MandelViewport{ x - w/2, y - h/2, w, h };
-
-        if (bigW > 2 * w) {
-            Bitmap<float> raw{ evi.width * 2, evi.height * 2 };
-            gen.generate(mi, raw.pixels.get());
-            //auto before = std::chrono::high_resolution_clock::now();
-            big = raw.map<RGBColor>([&mi, this] (float i) {
-                return i >= mi.maxIter ? RGBColor{ 0, 0, 0 } : evi.gradient.get(i);
-            });
-            /*mi.view.zoomCenter(0.5);
-            gen.generate(mi, raw.pixels.get());
-            small = raw.map<RGBColor>([] (float x) { return
-                RGBColor{ uint8_t(::sin(x / 100) * 127 + 127), uint8_t(::sin(x / 213) * 127 + 127), uint8_t(::cos(x / 173) * 127 + 127) };
-            });*/
-            bigW = w;
-            bigFac = 1.0;
-        }
-
-        vs.addFrame(overlay(big, small, bigFac));
-
-        w *= ::pow(0.99, evi.zoomSpeed);
-        h *= ::pow(0.99, evi.zoomSpeed);
-        bigFac *= ::pow(0.99, evi.zoomSpeed);
-    }
-}
-
-
-inline RGBColor biliniear(const Bitmap<RGBColor>& img, double x, double y)
-{
-    int xfloor = int(::floor(x));
-    int yfloor = int(::floor(y));
-    int xceil = int(::ceil(x));
-    int yceil = int(::ceil(y));
-
-    double xLerp = x - xfloor;
-    double yLerp = y - yfloor;
-
-    RGBColor samples[2][2] = {
-        {
-            img.get(xfloor, yfloor),
-            img.get(xfloor, yceil),
-        },
-        {
-            img.get(xceil, yfloor),
-            img.get(xceil, yceil),
-        }
-    };
-
-    double r = 0, g = 0, b = 0;
-
-    auto mklin = [] (double x) {
-        return x;
-    };
-    auto unlin = [] (double x) {
-        return x;
-    };
-
-    r += (1 - xLerp) * (1 - yLerp) * mklin(samples[0][0].r);
-    r += (1 - xLerp) * yLerp * mklin(samples[0][1].r);
-    r += xLerp * (1 - yLerp) * mklin(samples[1][0].r);
-    r += xLerp * yLerp * mklin(samples[1][1].r);
-
-    g += (1 - xLerp) * (1 - yLerp) * mklin(samples[0][0].g);
-    g += (1 - xLerp) * yLerp * mklin(samples[0][1].g);
-    g += xLerp * (1 - yLerp) * mklin(samples[1][0].g);
-    g += xLerp * yLerp * mklin(samples[1][1].g);
-
-    b += (1 - xLerp) * (1 - yLerp) * mklin(samples[0][0].b);
-    b += (1 - xLerp) * yLerp * mklin(samples[0][1].b);
-    b += xLerp * (1 - yLerp) * mklin(samples[1][0].b);
-    b += xLerp * yLerp * mklin(samples[1][1].b);
-
-    return RGBColor{ uint8_t(unlin(r)), uint8_t(unlin(g)), uint8_t(unlin(b)) };
-}
-
-
-inline RGBColor nearest(const Bitmap<RGBColor>& img, double x, double y)
-{
-    int xfloor = int(::floor(x));
-    int yfloor = int(::floor(y));
-    return img.get(xfloor, yfloor);
-}
-
-
-Bitmap<RGBColor> MandelVideoGenerator::overlay(const Bitmap<RGBColor>& outer,
-                         const Bitmap<RGBColor>& /* inner */, double scale)
-{
-    printf("%lf\n", scale);
-    Bitmap<RGBColor> ret{ outer.width / 2, outer.height / 2 };
-    double newW = outer.width * scale * 2;
-    double newH = outer.height * scale * 2;
-    double newX = outer.width * (1 - scale) / 2;
-    double newY = outer.height * (1 - scale) / 2;
-
-    //auto before = std::chrono::high_resolution_clock::now();
-#pragma omp parallel for
-    for (int i = 0; i < ret.height; i++) {
-        for (int j = 0; j < ret.width; j++) {
-            double newJ = newX + j * newW / outer.width;
-            double newI = newY + i * newH / outer.height;
-            RGBColor a = biliniear(outer, newJ, newI);
-            ret.get(j, i) = a;
-        }
-    }
-    //auto after = std::chrono::high_resolution_clock::now();
-    //printf("gradient applied in: %lld microseconds\n", std::chrono::duration_cast<std::chrono::microseconds>(after - before).count());
-    fflush(stdout);
-    /*for (int i = 0; i < ret.height * ret.width; i++) {
-        ret.pixels[i] = outer.pixels[i];
-    }*/
-
-    return ret;
-}

+ 0 - 43
MandelVideoGenerator.h

@@ -1,43 +0,0 @@
-#ifndef MANDELVIDEOGENERATOR_H
-#define MANDELVIDEOGENERATOR_H
-
-#include "Mandel.h"
-#include "Gradient.h"
-#include "Bitmap.h"
-
-struct ExportVideoInfo
-{
-    mnd::MandelViewport start;
-    mnd::MandelViewport end;
-    Gradient gradient;
-
-    int width;
-    int height;
-    int maxIterations;
-    int fps;
-    double zoomSpeed;
-
-    std::string path;
-
-    /// bitrate in kbps
-    int bitrate;
-
-    std::string preset;
-};
-
-
-class MandelVideoGenerator
-{
-    const ExportVideoInfo evi;
-public:
-    MandelVideoGenerator(const ExportVideoInfo& evi);
-
-    void generate(void);
-
-private:
-    Bitmap<RGBColor> overlay(const Bitmap<RGBColor>& outer,
-                             const Bitmap<RGBColor>& inner,
-                             double scale);
-};
-
-#endif // MANDELVIDEOGENERATOR_H

+ 0 - 236
VideoStream.cpp

@@ -1,236 +0,0 @@
-#include "VideoStream.h"
-
-#ifdef FFMPEG_ENABLED
-
-
-#include <iostream>
-
-
-
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
-#define av_frame_alloc  avcodec_alloc_frame
-#define av_frame_free  avcodec_free_frame
-#endif
-
-const uint8_t VideoStream::endcode[] = { 0, 0, 1, 0xb7 };
-
-
-VideoStream::VideoStream(int width, int height, const std::string& filename, int bitrate, int fps, const char* preset) :
-    width{ width & (~1) }, height{ height & (~1) }
-{
-    // only needed with ffmpeg version < 4
-    //avcodec_register_all();
-
-    codec = avcodec_find_encoder(AV_CODEC_ID_H264);
-    if (!codec) {
-        fprintf(stderr, "invalid codec\n");
-        exit(1);
-    }
-
-    AVOutputFormat* oformat = av_guess_format(nullptr, filename.c_str(), nullptr);
-    if (!oformat)
-        oformat = av_guess_format("mp4", nullptr, nullptr);
-    if (oformat == nullptr)
-        throw "invalid format";
-
-    codecContext = avcodec_alloc_context3(codec);
-
-    pkt = av_packet_alloc();
-    if (!pkt)
-        exit(1);
-
-    codecContext->bit_rate = bitrate * 1000;
-    codecContext->width = width;
-    codecContext->height = height;
-    codecContext->time_base = AVRational{ 1, fps };
-    codecContext->framerate = AVRational{ fps, 1 };
-
-    codecContext->gop_size = 5; /* emit one intra frame every five frames */
-    codecContext->max_b_frames = 1;
-    codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
-
-    formatContext = avformat_alloc_context();
-    formatContext->oformat = oformat;
-    formatContext->video_codec_id = oformat->video_codec;
-
-    stream = avformat_new_stream(formatContext, codec);
-    if (!stream)
-        throw "error";
-
-    params = avcodec_parameters_alloc();
-    avcodec_parameters_from_context(params, codecContext);
-    stream->codecpar = params;
-
-    /*AVCPBProperties *props;
-    props = (AVCPBProperties*) av_stream_new_side_data(
-        stream, AV_PKT_DATA_CPB_PROPERTIES, sizeof(*props));
-    props->buffer_size = 1024 * 1024;
-    props->max_bitrate = 0;
-    props->min_bitrate = 0;
-    props->avg_bitrate = 0;
-    props->vbv_delay = UINT64_MAX;*/
-
-    if (codec->id == AV_CODEC_ID_H264)
-        av_opt_set(codecContext->priv_data, "preset", preset, 0);
-
-    if (avcodec_open2(codecContext, codec, nullptr) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-    avio_open(&formatContext->pb, filename.c_str(), AVIO_FLAG_WRITE);
-
-    if (avformat_write_header(formatContext, NULL) < 0) {
-        throw "error";
-    }
-    /*file = fopen(filename.c_str(), "wb");
-    if (!file) {
-        fprintf(stderr, "could not open %s\n", filename.c_str());
-        exit(1);
-    }*/
-
-    picture = av_frame_alloc();
-    av_frame_make_writable(picture);
-    picture->format = codecContext->pix_fmt;
-    picture->width  = codecContext->width;
-    picture->height = codecContext->height;
-
-    int retval = av_frame_get_buffer(picture, 0);
-    if (retval < 0) {
-        fprintf(stderr, "could not alloc the frame data\n");
-        exit(1);
-    }
-    //av_image_alloc(picture->data, picture->linesize, width, height, codecContext->pix_fmt, 32);
-
-    swsContext = sws_getContext(width, height,
-        AV_PIX_FMT_RGB24, width, height,
-        AV_PIX_FMT_YUV420P, 0, 0, 0, 0);
-}
-
-
-void VideoStream::encode(AVFrame* frame)
-{
-    int ret;
-
-    /* send the frame to the encoder */
-    ret = avcodec_send_frame(codecContext, frame);
-    if (ret < 0) {
-        fprintf(stderr, "error sending a frame for encoding\n");
-        exit(1);
-    }
-
-    while (ret >= 0) {
-        ret = avcodec_receive_packet(codecContext, pkt);
-        //ret = avcodec_encode_video2(codecContext, pkt, picture, &gotPacket);
-        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
-            return;
-        else if (ret < 0) {
-            fprintf(stderr, "error during encoding\n");
-            exit(1);
-        }
-
-        printf("encoded frame %3ld\"PRId64\" (size=%5d)\n", long(pkt->pts), pkt->size);
-        //fwrite(pkt->data, 1, pkt->size, outfile);
-        //av_interleaved_write_frame(formatContext, pkt);
-
-        av_packet_rescale_ts(pkt, AVRational{1, 60}, stream->time_base);
-        pkt->stream_index = stream->index;
-
-        av_write_frame(formatContext, pkt);
-        av_packet_unref(pkt);
-    }
-}
-
-
-VideoStream::~VideoStream()
-{
-    /* flush the encoder */
-    encode(nullptr);
-    av_write_trailer(this->formatContext);
-
-    /* add sequence end code to have a real MPEG file */
-    //fwrite(endcode, 1, sizeof(endcode), file);
-    //fclose(file);
-
-    avcodec_close(codecContext);
-    avio_close(formatContext->pb);
-    av_frame_unref(picture);
-    //av_free(codecContext);
-    avcodec_parameters_free(&params);
-    avcodec_free_context(&codecContext);
-    av_frame_free(&picture);
-    av_packet_free(&pkt);
-
-/*
-    AVPacket pkt;
-    av_init_packet(&pkt);
-    pkt.data = nullptr;
-    pkt.size = 0;
-
-    for (;;) {
-        avcodec_send_frame(codecContext, NULL);
-        if (avcodec_receive_packet(codecContext, &pkt) == 0) {
-            av_interleaved_write_frame(codecContext, &pkt);
-            av_packet_unref(&pkt);
-        }
-        else {
-            break;
-        }
-    }
-
-    av_write_trailer();
-    if (!(oformat->flags & AVFMT_NOFILE)) {
-        int err = avio_close(ofctx->pb);
-        if (err < 0) {
-            Debug("Failed to close file", err);
-        }
-    }*/
-
-}
-
-
-void VideoStream::addFrame(const Bitmap<RGBColor>& frame)
-{
-    int retval = av_frame_make_writable(picture);
-    if (retval < 0)
-        exit(1);
-
-    /* prepare a dummy image */
-    /* Y */
-    /*for(int y = 0; y < height; y++) {
-        for(int x = 0; x < width; x++) {
-            picture->data[0][y * picture->linesize[0] + x] = frame.get(x, y).r / 2;
-        }
-    }*/
-
-    /* Cb and Cr */
-    /*for(int y=0;y<height / 2;y++) {
-        for(int x=0;x<width / 2;x++) {
-            picture->data[1][y * picture->linesize[1] + x] = frame.get(x * 2, y * 2).g / 2;
-            picture->data[2][y * picture->linesize[2] + x] = frame.get(x * 2, y * 2).b / 2;
-        }
-    }*/
-
-    /*auto gammaCorrect = [] (const RGBColor& rgb) {
-        const float gamma = 2.2f;
-        return RGBColor {
-            uint8_t(::powf(rgb.r / 255.0f, 1.0f / gamma) * 255),
-            uint8_t(::powf(rgb.g / 255.0f, 1.0f / gamma) * 255),
-            uint8_t(::powf(rgb.b / 255.0f, 1.0f / gamma) * 255),
-        };
-    };
-
-    Bitmap<RGBColor> gammaCorrected = frame.map<RGBColor>(gammaCorrect);*/
-
-    const uint8_t* pixelPointer[] = { reinterpret_cast<const uint8_t*>(frame.pixels.get()), 0 };
-    const int linesizeIn[] = { int(frame.width * sizeof(RGBColor)) };
-
-    sws_scale(swsContext, pixelPointer, linesizeIn, 0,
-        frame.height, picture->data, picture->linesize);
-
-    picture->pts = frameIndex++;
-
-    /* encode the image */
-    encode(picture);
-}
-
-#endif // FFMPEG_ENABLED

+ 0 - 50
VideoStream.h

@@ -1,50 +0,0 @@
-#pragma once
-#define FFMPEG_ENABLED
-#ifdef FFMPEG_ENABLED
-
-
-#ifndef VIDEO_STREAM_H_
-#define VIDEO_STREAM_H_
-
-#include <string>
-#include "Bitmap.h"
-
-extern "C" {
-#   include <libavformat/avformat.h>
-#   include <libavformat/avio.h>
-#   include <libavcodec/avcodec.h>
-#   include <libavformat/avformat.h>
-#   include <libavutil/imgutils.h>
-#   include <libavutil/opt.h>
-#   include <libswscale/swscale.h>
-}
-
-class VideoStream
-{
-    const AVCodec* codec;
-    AVCodecContext* codecContext;
-    AVFormatContext* formatContext;
-    AVCodecParameters* params;
-    //FILE* file;
-    AVFrame* picture;
-    AVPacket* pkt;
-    AVStream* stream;
-    SwsContext* swsContext;
-    static const uint8_t endcode[];
-
-    int width;
-    int height;
-
-    int64_t frameIndex = 0;
-public:
-    VideoStream(int width, int height, const std::string& filename, int bitrate, int fps, const char* preset);
-    ~VideoStream(void);
-
-    void encode(AVFrame* frame);
-
-    void addFrame(const Bitmap<RGBColor>& frame);
-};
-
-#endif // VIDEO_STREAM_H_
-
-#endif // FFMPEG_ENABLED

+ 8 - 2
exportdialogs.cpp

@@ -5,6 +5,7 @@
 #include <QMessageBox>
 
 #include "Mandel.h"
+#include "Almond.h"
 #include "VideoStream.h"
 
 //static bool exportVideo(const ExportVideoInfo& evi);
@@ -70,8 +71,10 @@ void ExportImageDialog::on_buttonBox_accepted()
     }
 }
 
-ExportVideoDialog::ExportVideoDialog(QWidget* parent, const ExportVideoInfo& evi) :
+
+ExportVideoDialog::ExportVideoDialog(Almond *parent, const ExportVideoInfo& evi) :
     QDialog{ parent },
+    almond{ parent },
     evi{ evi }
 {
     evd.setupUi(this);
@@ -121,6 +124,7 @@ ExportVideoDialog::ExportVideoDialog(QWidget* parent, const ExportVideoInfo& evi
     }
 }
 
+
 const ExportVideoInfo& ExportVideoDialog::getExportVideoInfo(void) const
 {
     return evi;
@@ -159,9 +163,11 @@ void ExportVideoDialog::on_buttonBox_accepted()
 
     evi.start.adjustAspectRatio(evi.width, evi.height);
     evi.end.adjustAspectRatio(evi.width, evi.height);
+    evi.
+    evi.gradient = almond->mw->getGradient();
 
     MandelVideoGenerator mvg(evi);
-    mvg.generate();
+    mvg.generate(*almond->mw->getGenerator());
     //if (exportVideo(evi)) {
         QMessageBox* msgBox = new QMessageBox;
         msgBox->setText("Video successfully exported.");

+ 4 - 1
exportdialogs.h

@@ -10,6 +10,8 @@
 
 #include "MandelVideoGenerator.h"
 
+class Almond;
+
 class ExportImageDialog : public QDialog
 {
     Q_OBJECT
@@ -36,8 +38,9 @@ private:
     Ui::ExportVideoDialog evd;
 
     ExportVideoInfo evi;
+    Almond* almond;
 public:
-    ExportVideoDialog(QWidget* parent, const ExportVideoInfo& evi);
+    ExportVideoDialog(Almond* parent, const ExportVideoInfo& evi);
 
     const ExportVideoInfo& getExportVideoInfo(void) const;
 private slots:

+ 2 - 0
gradientchoosedialog.cpp

@@ -17,6 +17,7 @@ GradientChooseDialog::GradientChooseDialog()
     gcd.presets->addItem("rainbow");
     gcd.presets->addItem("grayscale");
     gcd.presets->addItem("peach");
+    gcd.presets->addItem("blue gold");
 }
 
 
@@ -30,6 +31,7 @@ void GradientChooseDialog::on_buttonBox_clicked(QAbstractButton*)
 {
 }
 
+
 void GradientChooseDialog::on_presets_currentIndexChanged(const QString& index)
 {
     QFile res(":/gradients/" + index);

+ 14 - 0
gradients/blue_gold.xml

@@ -0,0 +1,14 @@
+<gradient repeat="true">
+    <color r="0" g="0" b="0" p="0" />
+    <color r="0" g="255" b="255" p="30" />
+    <color r="50" g="100" b="170" p="60" />
+    <color r="180" g="140" b="20" p="90" />
+    <color r="255" g="255" b="0" p="120" />
+    <color r="143" g="67" b="0" p="150" />
+    <color r="255" g="255" b="255" p="180" />
+    <color r="20" g="30" b="180" p="210" />
+    <color r="20" g="190" b="30" p="240" />
+    <color r="120" g="240" b="120" p="270" />
+    <color r="40" g="40" b="40" p="300" />
+    <color r="0" g="0" b="0" p="320" />
+</gradient>

BIN
icon.xcf


+ 2 - 2
libalmond/include/MandelVideoGenerator.h

@@ -1,7 +1,7 @@
 #ifndef MANDELVIDEOGENERATOR_H
 #define MANDELVIDEOGENERATOR_H
 
-#include "MandelUtil.h"
+#include "Mandel.h"
 #include "Gradient.h"
 #include "Bitmap.h"
 #include <functional>
@@ -43,7 +43,7 @@ private:
     public:
     MandelVideoGenerator(const ExportVideoInfo& evi);
 
-    void generate(void);
+    void generate(mnd::MandelGenerator& gen);
     void addProgressCallback(ProgressCallback pc);
 
 private:

+ 6 - 10
libalmond/src/MandelVideoGenerator.cpp

@@ -15,12 +15,8 @@ void MandelVideoGenerator::addProgressCallback(ProgressCallback pc)
     progressCallbacks.push_back(std::move(pc));
 }
 
-void MandelVideoGenerator::generate(void)
+void MandelVideoGenerator::generate(mnd::MandelGenerator& gen)
 {
-    mnd::MandelContext ctxt = mnd::initializeContext();
-    mnd::MandelGenerator& gen = ctxt.getDefaultGenerator();
-
-
     VideoStream vs(evi.width, evi.height, evi.path, evi.bitrate, evi.fps, evi.preset.c_str());
 
     mnd::Real x = evi.end.x + evi.end.width / 2;
@@ -50,8 +46,8 @@ void MandelVideoGenerator::generate(void)
 
         if (bigW > sqrt(oversizeFactor) * w) {
             mi.view = mnd::MandelViewport{ x - w/2, y - h/2, w, h };
-            Bitmap<float> raw{ evi.width * oversizeFactor, evi.height * oversizeFactor };
-            Bitmap<float> rawSmall{ evi.width * oversizeFactor, evi.height * oversizeFactor };
+            Bitmap<float> raw{ long(evi.width * oversizeFactor), long(evi.height * oversizeFactor) };
+            Bitmap<float> rawSmall{ long(evi.width * oversizeFactor), long(evi.height * oversizeFactor) };
             mi.view.zoomCenter(oversizeFactor);
             gen.generate(mi, rawSmall.pixels.get());
             //mi.view.zoomCenter(sqrt(oversizeFactor));
@@ -108,9 +104,9 @@ inline RGBColor lerpColors(const RGBColor& a, const RGBColor& b, double lerp)
     };
 
     return RGBColor{
-        a.r * lerp + b.r * (1 - lerp),
-        a.g * lerp + b.g * (1 - lerp),
-        a.b * lerp + b.b * (1 - lerp)
+        uint8_t(a.r * lerp + b.r * (1 - lerp)),
+        uint8_t(a.g * lerp + b.g * (1 - lerp)),
+        uint8_t(a.b * lerp + b.b * (1 - lerp))
     };
 }
 

+ 1 - 1
libmandel/CMakeLists.txt

@@ -99,7 +99,7 @@ endif()
 
 if(Boost_FOUND)
     target_compile_definitions(mandel PUBLIC WITH_BOOST)
-    target_include_directories(mandel PRIVATE ${Boost_INCLUDE_DIRS})
+    target_include_directories(mandel PUBLIC ${Boost_INCLUDE_DIRS})
     target_link_libraries(mandel PRIVATE ${Boost_LIBRARIES})
 endif(Boost_FOUND)
 

+ 8 - 0
libmandel/src/ClGenerators.cpp

@@ -358,6 +358,9 @@ void ClGeneratorDoubleDouble::generate(const mnd::MandelInfo& info, float* data)
     mnd::DoubleDouble psx = mnd::convert<mnd::DoubleDouble>(info.view.width / info.bWidth);
     mnd::DoubleDouble psy = mnd::convert<mnd::DoubleDouble>(info.view.height / info.bHeight);
 
+    mnd::DoubleDouble juliaX = mnd::convert<mnd::DoubleDouble>(info.juliaX);
+    mnd::DoubleDouble juliaY = mnd::convert<mnd::DoubleDouble>(info.juliaY);
+
     kernel.setArg(0, buffer_A);
     kernel.setArg(1, int(info.bWidth));
     kernel.setArg(2, x.x[0]);
@@ -370,6 +373,11 @@ void ClGeneratorDoubleDouble::generate(const mnd::MandelInfo& info, float* data)
     kernel.setArg(9, psy.x[1]);
     kernel.setArg(10, int(info.maxIter));
     kernel.setArg(11, int(info.smooth ? 1 : 0));
+    kernel.setArg(12, info.julia ? 1 : 0);
+    kernel.setArg(13, juliaX.x[0]);
+    kernel.setArg(14, juliaX.x[1]);
+    kernel.setArg(15, juliaY.x[0]);
+    kernel.setArg(16, juliaY.x[1]);
 
     cl_int result = queue.enqueueNDRangeKernel(kernel, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);

+ 5 - 4
libmandel/src/opencl/doubledouble.cl

@@ -48,7 +48,8 @@ inline double2 mulDouble(double2 a, double b) {
 
 __kernel void iterate(__global float* A, const int width,
                       double x1, double x2, double y1, double y2,
-                      double pw1, double pw2, double ph1, double ph2, int max, int smooth) {
+                      double pw1, double pw2, double ph1, double ph2, int max, int smooth,
+                      int julia, double jx1, double jx2, double jy1, double jy2) {
     int index = get_global_id(0);
     int px = index % width;
     int py = index / width;
@@ -57,11 +58,11 @@ __kernel void iterate(__global float* A, const int width,
     double2 yt = (double2)(y1, y2);
     double2 pixelScaleX = (double2)(pw1, pw2);
     double2 pixelScaleY = (double2)(ph1, ph2);
-
     double2 a = add(mulDouble(pixelScaleX, (double) px), xl); // pixelScaleX * px + xl
     double2 b = add(mulDouble(pixelScaleY, (double) py), yt); // pixelScaleY * py + yt
-    double2 ca = a;
-    double2 cb = b;
+    double2 ca = julia != 0 ? ((double2) (jx1, jx2)) : ca;
+    double2 cb = julia != 0 ? ((double2) (jy1, jy2)) : cb;
+
 
     int n = 0;
     while (n < max - 1) {

+ 113 - 100
libmandel/src/opencl/doubledouble.h

@@ -112,107 +112,120 @@ unsigned char doubledouble_cl[] = {
   0x6c, 0x65, 0x20, 0x70, 0x68, 0x31, 0x2c, 0x20, 0x64, 0x6f, 0x75, 0x62,
   0x6c, 0x65, 0x20, 0x70, 0x68, 0x32, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20,
   0x6d, 0x61, 0x78, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x73, 0x6d, 0x6f,
-  0x6f, 0x74, 0x68, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
-  0x6e, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x67,
-  0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64,
-  0x28, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74,
-  0x20, 0x70, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20,
-  0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e,
-  0x64, 0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b,
-  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
-  0x32, 0x20, 0x78, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62,
-  0x6c, 0x65, 0x32, 0x29, 0x28, 0x78, 0x31, 0x2c, 0x20, 0x78, 0x32, 0x29,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
-  0x32, 0x20, 0x79, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62,
-  0x6c, 0x65, 0x32, 0x29, 0x28, 0x79, 0x31, 0x2c, 0x20, 0x79, 0x32, 0x29,
+  0x6f, 0x74, 0x68, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61,
+  0x2c, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x6a, 0x78, 0x31,
+  0x2c, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x6a, 0x78, 0x32,
+  0x2c, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x6a, 0x79, 0x31,
+  0x2c, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x20, 0x6a, 0x79, 0x32,
+  0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20,
+  0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f,
+  0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x30, 0x29,
+  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x78,
+  0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x25, 0x20, 0x77,
+  0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e,
+  0x74, 0x20, 0x70, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78,
+  0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x78,
+  0x6c, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
+  0x29, 0x28, 0x78, 0x31, 0x2c, 0x20, 0x78, 0x32, 0x29, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x79,
+  0x74, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
+  0x29, 0x28, 0x79, 0x31, 0x2c, 0x20, 0x79, 0x32, 0x29, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x70,
+  0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x3d,
+  0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x29, 0x28, 0x70,
+  0x77, 0x31, 0x2c, 0x20, 0x70, 0x77, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x70, 0x69,
+  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x3d, 0x20,
+  0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x29, 0x28, 0x70, 0x68,
+  0x31, 0x2c, 0x20, 0x70, 0x68, 0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x61, 0x20, 0x3d,
+  0x20, 0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c, 0x44, 0x6f, 0x75, 0x62,
+  0x6c, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c,
+  0x65, 0x58, 0x2c, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x29,
+  0x20, 0x70, 0x78, 0x29, 0x2c, 0x20, 0x78, 0x6c, 0x29, 0x3b, 0x20, 0x2f,
+  0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65,
+  0x58, 0x20, 0x2a, 0x20, 0x70, 0x78, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20,
+  0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c, 0x44,
+  0x6f, 0x75, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62,
+  0x6c, 0x65, 0x29, 0x20, 0x70, 0x79, 0x29, 0x2c, 0x20, 0x79, 0x74, 0x29,
+  0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
+  0x61, 0x6c, 0x65, 0x59, 0x20, 0x2a, 0x20, 0x70, 0x79, 0x20, 0x2b, 0x20,
+  0x79, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c,
+  0x65, 0x32, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69,
+  0x61, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x3f, 0x20, 0x28, 0x28, 0x64,
+  0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x29, 0x20, 0x28, 0x6a, 0x78, 0x31,
+  0x2c, 0x20, 0x6a, 0x78, 0x32, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x63, 0x61,
   0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
-  0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65,
-  0x58, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
-  0x29, 0x28, 0x70, 0x77, 0x31, 0x2c, 0x20, 0x70, 0x77, 0x32, 0x29, 0x3b,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
-  0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59,
-  0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x29,
-  0x28, 0x70, 0x68, 0x31, 0x2c, 0x20, 0x70, 0x68, 0x32, 0x29, 0x3b, 0x0a,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
-  0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c,
-  0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c,
-  0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20, 0x28, 0x64, 0x6f, 0x75,
-  0x62, 0x6c, 0x65, 0x29, 0x20, 0x70, 0x78, 0x29, 0x2c, 0x20, 0x78, 0x6c,
-  0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
-  0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2a, 0x20, 0x70, 0x78, 0x20, 0x2b,
-  0x20, 0x78, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62,
-  0x6c, 0x65, 0x32, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28,
-  0x6d, 0x75, 0x6c, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x69,
-  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 0x20, 0x28,
-  0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x29, 0x20, 0x70, 0x79, 0x29, 0x2c,
-  0x20, 0x79, 0x74, 0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78,
-  0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x2a, 0x20, 0x70,
-  0x79, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
-  0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20,
-  0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c,
-  0x65, 0x32, 0x20, 0x63, 0x62, 0x20, 0x3d, 0x20, 0x62, 0x3b, 0x0a, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6e, 0x20, 0x3d, 0x20,
-  0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65,
-  0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x2d, 0x20,
-  0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x61, 0x61, 0x20,
-  0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x29, 0x3b,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75,
-  0x62, 0x6c, 0x65, 0x32, 0x20, 0x62, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75,
-  0x6c, 0x28, 0x62, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32,
-  0x20, 0x61, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c,
-  0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2b,
-  0x20, 0x61, 0x61, 0x2e, 0x73, 0x31, 0x20, 0x2b, 0x20, 0x62, 0x62, 0x2e,
-  0x73, 0x30, 0x20, 0x2b, 0x20, 0x62, 0x62, 0x2e, 0x73, 0x31, 0x20, 0x3e,
-  0x20, 0x31, 0x36, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a,
+  0x32, 0x20, 0x63, 0x62, 0x20, 0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61,
+  0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x3f, 0x20, 0x28, 0x28, 0x64, 0x6f,
+  0x75, 0x62, 0x6c, 0x65, 0x32, 0x29, 0x20, 0x28, 0x6a, 0x79, 0x31, 0x2c,
+  0x20, 0x6a, 0x79, 0x32, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x63, 0x62, 0x3b,
+  0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6e,
+  0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68,
+  0x69, 0x6c, 0x65, 0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78,
+  0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20,
+  0x61, 0x61, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20,
+  0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x62, 0x62, 0x20, 0x3d,
+  0x20, 0x6d, 0x75, 0x6c, 0x28, 0x62, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x75, 0x62,
-  0x6c, 0x65, 0x32, 0x20, 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x62, 0x62, 0x20,
-  0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x29, 0x28,
-  0x2d, 0x62, 0x62, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x2d, 0x62, 0x62, 0x2e,
-  0x73, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x61, 0x64, 0x64,
-  0x28, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x75, 0x73, 0x62, 0x62,
-  0x29, 0x2c, 0x20, 0x63, 0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28,
-  0x61, 0x64, 0x64, 0x28, 0x61, 0x62, 0x2c, 0x20, 0x61, 0x62, 0x29, 0x2c,
-  0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d,
-  0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x4e, 0x20, 0x2b,
-  0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x28, 0x6c, 0x6f,
-  0x67, 0x20, 0x20, 0x7c, 0x5a, 0x28, 0x4e, 0x29, 0x7c, 0x29, 0x20, 0x2f,
-  0x20, 0x6c, 0x6f, 0x67, 0x20, 0x32, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
-  0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x20,
-  0x2d, 0x20, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20,
-  0x6d, 0x61, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73,
-  0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x69, 0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21,
-  0x3d, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78,
-  0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29,
-  0x20, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f,
-  0x67, 0x28, 0x6c, 0x6f, 0x67, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2a,
-  0x20, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30,
-  0x20, 0x2a, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x20, 0x2f, 0x20, 0x32,
-  0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x32, 0x2e, 0x30, 0x66,
-  0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65,
-  0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x65, 0x32, 0x20, 0x61, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c,
+  0x28, 0x61, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x2e, 0x73,
+  0x30, 0x20, 0x2b, 0x20, 0x61, 0x61, 0x2e, 0x73, 0x31, 0x20, 0x2b, 0x20,
+  0x62, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x2b, 0x20, 0x62, 0x62, 0x2e, 0x73,
+  0x31, 0x20, 0x3e, 0x20, 0x31, 0x36, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61,
+  0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x75, 0x62, 0x6c, 0x65, 0x32, 0x20, 0x6d, 0x69, 0x6e, 0x75, 0x73,
+  0x62, 0x62, 0x20, 0x3d, 0x20, 0x28, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
+  0x32, 0x29, 0x28, 0x2d, 0x62, 0x62, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x2d,
+  0x62, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28,
+  0x61, 0x64, 0x64, 0x28, 0x61, 0x61, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x75,
+  0x73, 0x62, 0x62, 0x29, 0x2c, 0x20, 0x63, 0x61, 0x29, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61,
+  0x64, 0x64, 0x28, 0x61, 0x64, 0x64, 0x28, 0x61, 0x62, 0x2c, 0x20, 0x61,
+  0x62, 0x29, 0x2c, 0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20,
+  0x4e, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x20,
+  0x28, 0x6c, 0x6f, 0x67, 0x20, 0x20, 0x7c, 0x5a, 0x28, 0x4e, 0x29, 0x7c,
+  0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x32, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e, 0x3d, 0x20, 0x6d,
+  0x61, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d,
-  0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x6e,
-  0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65,
-  0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74,
-  0x29, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x28, 0x61,
-  0x20, 0x2a, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62,
-  0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x32, 0x35,
-  0x36, 0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x41, 0x5b, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62,
-  0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x5d, 0x20, 0x3d, 0x20,
-  0x35, 0x3b, 0x0a, 0x7d, 0x0a
+  0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74,
+  0x68, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e,
+  0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x29, 0x20, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d,
+  0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c, 0x6f, 0x67, 0x28, 0x61, 0x2e, 0x73,
+  0x30, 0x20, 0x2a, 0x20, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2b, 0x20, 0x62,
+  0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x20,
+  0x2f, 0x20, 0x32, 0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x32,
+  0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64,
+  0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x29, 0x6e, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69,
+  0x6e, 0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c,
+  0x6f, 0x61, 0x74, 0x29, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d,
+  0x20, 0x28, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x20,
+  0x2a, 0x20, 0x62, 0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x20, 0x2f, 0x20,
+  0x28, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x67, 0x65, 0x74, 0x5f, 0x67,
+  0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x5d,
+  0x20, 0x3d, 0x20, 0x35, 0x3b, 0x0a, 0x7d, 0x0a
 };
-unsigned int doubledouble_cl_len = 2573;
+unsigned int doubledouble_cl_len = 2732;

+ 2 - 0
mandelvid/CMakeLists.txt

@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.13)
 
 project(mandelvid VERSION 1.0.0 DESCRIPTION "mandel video generator")
 
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CMakeModules)
+
 add_subdirectory(../libalmond ./libalmond)
 
 set(CMAKE_CXX_STANDARD 17)