Browse Source

playing around and creating order

Nicolas Winkler 5 years ago
parent
commit
51ca16ac3d

+ 13 - 9
Almond.cpp

@@ -35,20 +35,22 @@ Almond::Almond(QWidget* parent) :
     QObject::connect(mw.get(), &MandelWidget::pointSelected, this, &Almond::pointSelected);
     ui.mandel_container->addWidget(mw.get());
     ui.maxIterations->setValidator(new QIntValidator(1, 1000000000, this));
-    ui.backgroundProgress->setVisible(false);
 
+    ui.backgroundProgress->setEnabled(false);
+    ui.cancelProgress->setEnabled(false);
 
-    QStatusBar* bar = new QStatusBar(this);
+
+    /*QStatusBar* bar = new QStatusBar(this);
     bar->addWidget(new QLabel("ayay"));
     auto* p = new QPushButton("About");
     bar->addPermanentWidget(p);
     QObject::connect(p, &QPushButton::clicked, [this]() {
-        /*QThread::sleep(2);
-        ui.mandel_container->addWidget(this->takeCentralWidget());
-        emit this->showNormal();*/
         toggleFullscreen();
     });
-    ui.mainContainer->addWidget(bar);
+    bar->setFixedHeight(bar->sizeHint().height());
+    //ui.mainContainer->addWidget(bar);
+    this->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
+    this->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);*/
 
     installEventFilter(this);
 
@@ -84,8 +86,9 @@ void Almond::submitBackgroundTask(BackgroundTask* task)
     backgroundTasks.start(task);
     //if (taken) {
         ui.backgroundProgress->setRange(0, 0);
-        ui.backgroundProgress->setVisible(true);
         ui.backgroundProgress->setFormat("");
+        ui.backgroundProgress->setEnabled(true);
+        ui.cancelProgress->setEnabled(true);
     //}
 }
 
@@ -132,8 +135,9 @@ void Almond::backgroundTaskFinished(bool succ, QString message)
         emit info.exec();
     }
 
-    ui.backgroundProgress->setVisible(false);
     ui.backgroundProgress->setFormat("");
+    ui.backgroundProgress->setEnabled(false);
+    ui.cancelProgress->setEnabled(false);
 }
 
 
@@ -251,7 +255,7 @@ void Almond::on_exportImage_clicked()
         iei.generator = &g;
         iei.gradient = mw->getGradient();
         iei.path = dialog.getPath().toStdString();
-        iei.options.jpegQuality = 20;
+        iei.options.jpegQuality = 95;
         submitBackgroundTask(new ImageExportTask(iei));
 
         /*auto exprt = [iei, path = dialog.getPath().toStdString()]() {

+ 29 - 18
Almond.ui

@@ -10,7 +10,7 @@
     <x>0</x>
     <y>0</y>
     <width>1202</width>
-    <height>1188</height>
+    <height>1262</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -29,7 +29,7 @@
   </widget>
   <widget class="QDockWidget" name="dockWidget_2">
    <property name="features">
-    <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetClosable</set>
+    <set>QDockWidget::AllDockWidgetFeatures</set>
    </property>
    <property name="allowedAreas">
     <set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
@@ -247,22 +247,8 @@
          <property name="title">
           <string>Export</string>
          </property>
-         <layout class="QVBoxLayout" name="verticalLayout_2">
-          <item>
-           <widget class="QPushButton" name="exportVideo">
-            <property name="text">
-             <string>Export Video</string>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="exportImage">
-            <property name="text">
-             <string>Export Image</string>
-            </property>
-           </widget>
-          </item>
-          <item>
+         <layout class="QGridLayout" name="gridLayout">
+          <item row="2" column="0">
            <widget class="QProgressBar" name="backgroundProgress">
             <property name="enabled">
              <bool>true</bool>
@@ -287,6 +273,31 @@
             </property>
            </widget>
           </item>
+          <item row="2" column="1">
+           <widget class="QPushButton" name="cancelProgress">
+            <property name="text">
+             <string/>
+            </property>
+            <property name="icon">
+             <iconset theme="cancel">
+              <normaloff>.</normaloff>.</iconset>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0" colspan="2">
+           <widget class="QPushButton" name="exportVideo">
+            <property name="text">
+             <string>Export Video</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0" colspan="2">
+           <widget class="QPushButton" name="exportImage">
+            <property name="text">
+             <string>Export Image</string>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
        </item>

+ 1 - 1
CMakeLists.txt

@@ -80,7 +80,7 @@ ELSEIF (UNIX AND NOT APPLE)
     set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "A fractal viewer")
     set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64)
     set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nicolas Winkler <nicolas.winkler@gmx.ch>")
-    set(CPACK_DEBIAN_PACKAGE_DEPENDS "qtbase5-dev,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,libgl1,ocl-icd-libopencl1,libpng16-16,libc6")
+    set(CPACK_DEBIAN_PACKAGE_DEPENDS "qtbase5-dev,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,ocl-icd-libopencl1,libpng16-16,libc6")
     set(CPACK_SET_DESTDIR True)
     set(CPACK_INSTALL_PREFIX "/usr")
     include(CPack)

+ 8 - 0
README.md

@@ -0,0 +1,8 @@
+# Almond
+
+Almond is a fast and simple fractal viewer.
+
+## Building
+
+The preferred way of building Almond is using cmake.
+

+ 8 - 5
libalmond/CMakeLists.txt

@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.13)
 
 project(libalmond VERSION 1.0.0 DESCRIPTION "almond functionality")
 
+option(LIBALMOND_LIBJPEG "use libjpeg to export jpeg images" ON)
+option(LIBALMOND_LIBPNG "use libpng to export png images" ON)
+
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CMakeModules)
 
 find_package(FFmpeg COMPONENTS AVCODEC AVDEVICE AVFORMAT AVUTIL SWSCALE REQUIRED)
@@ -28,11 +31,10 @@ set_target_properties(libalmond PROPERTIES OUTPUT_NAME almond)
 target_include_directories(libalmond SYSTEM PUBLIC ${FFMPEG_INCLUDE_DIRS})
 target_link_libraries(libalmond PUBLIC ${FFMPEG_LIBRARIES})
 
-if (PNG_FOUND)
-    #target_include_directories(libalmond SYSTEM PUBLIC ${PNG_INCLUDE_DIRS})
-    #target_link_libraries(libalmond PUBLIC ${PNG_LIBRARIES})
+if (PNG_FOUND AND LIBALMOND_LIBPNG)
     target_link_libraries(libalmond PUBLIC PNG::PNG)
-else()
+    target_compile_definitions(libalmond PUBLIC WITH_LIBPNG)
+elseif(LIBALMOND_LIBPNG)
     set(PNG_BUILD_ZLIB ON CACHE BOOL "build zlib ourselves")
     add_subdirectory(zlib-1.2.11)
     set(ZLIB_LIBRARY zlibstatic)
@@ -52,9 +54,10 @@ else()
     target_include_directories(libalmond PRIVATE ${PNG_PUB_INCLUDE})
     target_include_directories(libalmond PRIVATE ${ZLIB_INCLUDE_DIR})
     target_link_libraries(libalmond PRIVATE png_static)
+    target_compile_definitions(libalmond PUBLIC WITH_LIBPNG)
 endif()
 
-if (JPEG_FOUND AND WITH_LIBJPEG)
+if (JPEG_FOUND AND LIBALMOND_LIBJPEG)
     target_link_libraries(libalmond PUBLIC JPEG::JPEG)
     target_compile_definitions(libalmond PUBLIC WITH_LIBJPEG)
 endif()

+ 3 - 38
libalmond/include/ImageExport.h

@@ -37,7 +37,6 @@ namespace alm
         ImageExportException(const std::string& err);
     };
 
-
     /**
      * \brief generates and saves a fractal image. The format
      *        will be guessed by the file extension
@@ -48,43 +47,9 @@ namespace alm
      *                          contains a value from 0 to 100
      */
     void exportImage(const ImageExportInfo& iei,
-        std::function<void(float)> progressCallback = [](float){});
-
-    /**
-     * \brief generates and saves a fractal image in png format.
-     * 
-     * \param iei               info to generate the image
-     * \param progressCallback  optional function that is called to
-     *                          report progress; the float parameter
-     *                          contains a value from 0 to 100
-     */
-    void exportPng(const ImageExportInfo& iei,
-        std::function<void(float)> progressCallback = [](float){});
-
-
-#ifdef WITH_LIBJPEG
-    /**
-     * \brief generates and saves a fractal image in jpeg format.
-     * 
-     * \param iei               info to generate the image
-     * \param progressCallback  optional function that is called to
-     *                          report progress; the float parameter
-     *                          contains a value from 0 to 100
-     */
-    void exportJpeg(const ImageExportInfo& iei,
-        std::function<void(float)> progressCallback = [](float){});
-#endif // WITH_LIBJPEG
-
-    /**
-     * \brief generates and saves a fractal image in jpeg format.
-     * 
-     * \param iei               info to generate the image
-     * \param progressCallback  optional function that is called to
-     *                          report progress; the float parameter
-     *                          contains a value from 0 to 100
-     */
-    void exportBmp(const ImageExportInfo& iei,
-        std::function<void(float)> progressCallback = [](float){});
+        std::function<void(float)> progressCallback = [](float){},
+        std::function<bool(void)> cancelCallback = [](void){ return false; }
+        );
 }
 
 

+ 61 - 9
libalmond/src/ImageExport.cpp

@@ -1,10 +1,13 @@
 #include "ImageExport.h"
 #include "Bitmap.h"
 #include <boost/endian/buffers.hpp>
+#include <cstdio>
+
+#ifdef WITH_LIBPNG
 extern "C" {
 #   include <png.h>
 }
-#include <cstdio>
+#endif // WITH_LIBPNG
 
 #ifdef WITH_LIBJPEG
 extern "C" {
@@ -12,16 +15,35 @@ extern "C" {
 }
 #endif // WITH_LIBJPEG
 
+
 namespace alm
 {
 
+#ifdef WITH_LIBPNG
+void exportPng(const ImageExportInfo& iei,
+    std::function<void(float)> progressCallback,
+    std::function<bool(void)> cancelCallback);
+#endif // WITH_LIBPNG
+
+#ifdef WITH_LIBJPEG
+void exportJpeg(const ImageExportInfo& iei,
+    std::function<void(float)> progressCallback,
+    std::function<bool(void)> cancelCallback);
+#endif // WITH_LIBJPEG
+
+void exportBmp(const ImageExportInfo& iei,
+    std::function<void(float)> progressCallback,
+    std::function<bool(void)> cancelCallback);
+
 
 const std::vector<ImageFormat> supportedImageFormats = {
     ImageFormat::BMP,
+#ifdef WITH_LIBPNG
     ImageFormat::PNG,
+#endif // WITH_LIBPNG
 #ifdef WITH_LIBJPEG
     ImageFormat::JPEG,
-#endif
+#endif // WITH_LIBJPEG
 };
 
 bool supportsImageFormat(ImageFormat imgf)
@@ -38,7 +60,9 @@ ImageExportException::ImageExportException(const std::string& err) :
 {
 }
 
-void exportImage(const ImageExportInfo& iei, std::function<void(float)> progressCallback)
+void exportImage(const ImageExportInfo& iei,
+                 std::function<void(float)> progressCallback,
+                 std::function<bool(void)> cancelCallback)
 {
     auto hasSuffix = [] (const std::string& path, const std::string& suffix) -> bool
     {
@@ -48,15 +72,17 @@ void exportImage(const ImageExportInfo& iei, std::function<void(float)> progress
     };
     if (hasSuffix(iei.path, ".bmp") ||
         hasSuffix(iei.path, ".dib")) {
-        exportBmp(iei, progressCallback);
+        exportBmp(iei, progressCallback, cancelCallback);
     }
+#ifdef WITH_LIBPNG
     else if (hasSuffix(iei.path, ".png")) {
-        exportPng(iei, progressCallback);
+        exportPng(iei, progressCallback, cancelCallback);
     }
+#endif // WITH_LIBPNG
 #ifdef WITH_LIBJPEG
     else if (hasSuffix(iei.path, ".jpg") ||
              hasSuffix(iei.path, ".jpeg")) {
-        exportJpeg(iei, progressCallback);
+        exportJpeg(iei, progressCallback, cancelCallback);
     }
 #endif // WITH_LIBJPEG
     else {
@@ -64,7 +90,11 @@ void exportImage(const ImageExportInfo& iei, std::function<void(float)> progress
     }
 }
 
-void exportPng(const ImageExportInfo& iei, std::function<void(float)> progressCallback)
+
+#ifdef WITH_LIBPNG
+void exportPng(const ImageExportInfo& iei,
+               std::function<void(float)> progressCallback,
+               std::function<bool(void)> cancelCallback)
 {
     if (iei.generator == nullptr) {
         throw "no generator";
@@ -132,6 +162,12 @@ void exportPng(const ImageExportInfo& iei, std::function<void(float)> progressCa
         png_write_rows(png, &rowPointers[0], tmpHeight);
         if (chunkY < height)
             progressCallback(100.0f * chunkY / height);
+
+        if (cancelCallback()) {
+            fclose(file);
+            png_destroy_write_struct(&png, &info);
+            return;
+        }
     }
 
     png_write_end(png, NULL);
@@ -141,10 +177,13 @@ void exportPng(const ImageExportInfo& iei, std::function<void(float)> progressCa
     png_destroy_write_struct(&png, &info);
     progressCallback(100.0f);
 }
+#endif // WITH_LIBPNG
 
 
 #ifdef WITH_LIBJPEG
-void exportJpeg(const ImageExportInfo& iei, std::function<void(float)> progressCallback)
+void exportJpeg(const ImageExportInfo& iei,
+                std::function<void(float)> progressCallback,
+                std::function<bool(void)> cancelCallback)
 {
     if (iei.generator == nullptr) {
         throw "no generator";
@@ -214,6 +253,12 @@ void exportJpeg(const ImageExportInfo& iei, std::function<void(float)> progressC
         }
         if (chunkY < height)
             progressCallback(100.0f * chunkY / height);
+
+        if (cancelCallback()) {
+            fclose(file);
+            jpeg_destroy_compress(&jpegInfo);
+            return;
+        }
     }
 
     jpeg_finish_compress(&jpegInfo);
@@ -225,7 +270,9 @@ void exportJpeg(const ImageExportInfo& iei, std::function<void(float)> progressC
 #endif // WITH_LIBJPEG
 
 
-void exportBmp(const ImageExportInfo& iei, std::function<void(float)> progressCallback)
+void exportBmp(const ImageExportInfo& iei,
+               std::function<void(float)> progressCallback,
+               std::function<bool(void)> cancelCallback)
 {
     if (iei.generator == nullptr) {
         throw "no generator";
@@ -343,6 +390,11 @@ void exportBmp(const ImageExportInfo& iei, std::function<void(float)> progressCa
         }
         if (chunkY < height)
             progressCallback(100.0f * chunkY / height);
+
+        if (cancelCallback()) {
+            fclose(file);
+            return;
+        }
     }
 
     fflush(file);

+ 14 - 13
libmandel/CMakeLists.txt

@@ -2,16 +2,17 @@ cmake_minimum_required(VERSION 3.12)
 
 include(CheckCXXCompilerFlag)
 
-set(ARCH "X86_64" CACHE STRING "Target Architecture")
-option(AVX512 "generate code that can make use of avx-512-instructions" ON)
-option(WITH_ASMJIT "use just-in-time-compilation capabilities of asmjit" ON)
+project(mandel VERSION 1.0.0 DESCRIPTION "library for mandelbrot calculations")
+
+set(MANDEL_TARGET_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Target Architecture")
+option(MANDEL_AVX512 "generate code that can make use of avx-512-instructions" ON)
+option(MANDEL_ASMJIT "use just-in-time-compilation library asmjit" ON)
 option(MANDEL_BUILD_NATIVE
 	"use the -march=native flags if supported WARNING: when compiling with this flag, the binary might not run on machines other than the one it was compiled on"
 	OFF)
 
 #message(CMAKE_SYSTEM_PROCESSOR)
 
-project(mandel VERSION 1.0.0 DESCRIPTION "library for mandelbrot calculations")
 
 find_package(OpenCL REQUIRED)
 find_package(OpenMP)
@@ -42,12 +43,12 @@ SET(MandelSources
 )
 FILE(GLOB MandelHeaders include/*.h)
 
-if (ARCH STREQUAL "X86_64" OR ARCH STREQUAL "X86")
+if (MANDEL_TARGET_ARCHITECTURE STREQUAL "x86_64" OR MANDEL_TARGET_ARCHITECTURE STREQUAL "x86")
     list(APPEND MandelSources src/CpuGeneratorsAVX.cpp src/CpuGeneratorsAVXFMA.cpp src/CpuGeneratorsSSE2.cpp)
-    if (AVX512)
+    if (MANDEL_AVX512)
         list(APPEND MandelSources src/CpuGeneratorsAVX512.cpp)
     endif()
-elseif(ARCH STREQUAL "ARM")
+elseif(MANDEL_TARGET_ARCHITECTURE STREQUAL "aarch64")
     list(APPEND MandelSources src/CpuGeneratorsNeon.cpp)
 endif()
 
@@ -76,11 +77,11 @@ target_include_directories(qd PUBLIC qd-2.3.22/include qd-2.3.22)
 
 target_link_libraries(mandel PUBLIC qd)
 
-if(WITH_ASMJIT)
+if(MANDEL_ASMJIT)
     add_subdirectory(asmjit)
-    target_compile_definitions(mandel PUBLIC WITH_ASMJIT)
+    target_compile_definitions(mandel PUBLIC MANDEL_ASMJIT)
     target_link_libraries(mandel PUBLIC AsmJit::AsmJit)
-endif(WITH_ASMJIT)
+endif(MANDEL_ASMJIT)
 
 
 if(OPENCL_FOUND)
@@ -107,8 +108,8 @@ if(Boost_FOUND)
     target_link_libraries(mandel PRIVATE ${Boost_LIBRARIES})
 endif(Boost_FOUND)
 
-if (ARCH STREQUAL "X86_64" OR ARCH STREQUAL "X86")
-    if (AVX512)
+if (MANDEL_TARGET_ARCHITECTURE STREQUAL "x86_64" OR MANDEL_TARGET_ARCHITECTURE STREQUAL "x86")
+    if (MANDEL_AVX512)
         target_compile_definitions(mandel PUBLIC WITH_AVX512)
         if (MSVC)
             set_source_files_properties(src/CpuGeneratorsAVX512.cpp PROPERTIES COMPILE_FLAGS /arch:AVX512F)
@@ -127,6 +128,6 @@ if (ARCH STREQUAL "X86_64" OR ARCH STREQUAL "X86")
         set_source_files_properties(src/CpuGeneratorsSSE2.cpp PROPERTIES COMPILE_FLAGS -msse2)
     endif(MSVC)
 
-elseif(ARCH STREQUAL "ARM")
+elseif(MANDEL_TARGET_ARCHITECTURE STREQUAL "aarch64")
     set_source_files_properties(src/CpuGeneratorsNeon.cpp PROPERTIES COMPILE_FLAGS -march=armv8-a+simd)
 endif()

+ 14 - 12
libmandel/asmjit/CMakeLists.txt

@@ -403,18 +403,20 @@ if (NOT ASMJIT_EMBED)
   # Add AsmJit::AsmJit target (alias to asmjit).
   add_library(AsmJit::AsmJit ALIAS asmjit)
 
-  # Install 'asmjit' target (shared or static).
-  install(TARGETS asmjit RUNTIME DESTINATION "bin"
-                         LIBRARY DESTINATION "lib${LIB_SUFFIX}"
-                         ARCHIVE DESTINATION "lib${LIB_SUFFIX}")
-
-  # Install 'asmjit' header files (private headers are filtered out).
-  foreach(_src_file ${ASMJIT_SRC_LIST})
-    if ("${_src_file}" MATCHES "\\.h$" AND NOT "${_src_file}" MATCHES "_p\\.h$")
-      get_filename_component(_src_dir ${_src_file} PATH)
-      install(FILES "${ASMJIT_DIR}/src/${_src_file}" DESTINATION "include/${_src_dir}")
-    endif()
-  endforeach()
+  if (MANDEL_INSTALL_ASMJIT)
+    # Install 'asmjit' target (shared or static).
+    install(TARGETS asmjit RUNTIME DESTINATION "bin"
+                           LIBRARY DESTINATION "lib${LIB_SUFFIX}"
+                           ARCHIVE DESTINATION "lib${LIB_SUFFIX}")
+  
+    # Install 'asmjit' header files (private headers are filtered out).
+    foreach(_src_file ${ASMJIT_SRC_LIST})
+      if ("${_src_file}" MATCHES "\\.h$" AND NOT "${_src_file}" MATCHES "_p\\.h$")
+        get_filename_component(_src_dir ${_src_file} PATH)
+        install(FILES "${ASMJIT_DIR}/src/${_src_file}" DESTINATION "include/${_src_dir}")
+      endif()
+    endforeach()
+  endif(MANDEL_INSTALL_ASMJIT)
 
   # Add 'asmjit' tests.
   if (ASMJIT_TEST)