diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a703d7b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,232 @@ +name: 020-Release + +on: + workflow_run: + workflows: + - 010-Test + types: [completed] + branches: + - master + - release/** + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + semantic-release: + name: 🤖 Semantic release + runs-on: ubuntu-latest + if: "!contains(github.event.pull_request.labels.*.name, 'skip-release')" + # if: ${{ github.ref_name == 'master' && github.event_name == 'push' }} + outputs: + release: ${{ steps.tag_release.outputs.release }} + version: ${{ steps.tag_release.outputs.version }} + steps: + - uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: latest + - name: Install semantic-release + run: | + npm i npx + npm i semantic-release/changelog + - name: Tag release + id: tag_release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npx semantic-release | tee semantic-release.log + if [[ `git tag --points-at HEAD` == "" ]]; then + echo "release=False" >> $GITHUB_OUTPUT + else + echo "release=True" >> $GITHUB_OUTPUT + awk '/Published release/ { printf("version=v%s\n",$8) }' semantic-release.log >> $GITHUB_OUTPUT + fi + + linux-build: + name: 🐧 linux build + runs-on: ubuntu-latest + needs: [semantic-release] + if: ${{ needs.semantic-release.outputs.release == 'True' }} + steps: + - uses: actions/checkout@v3 + - name: apt install deps + run: | + sudo apt-get update -y -q + sudo apt-get install -y -q --no-install-recommends cmake ninja-build libopencv-dev libgavl-dev libfreetype-dev libcairo-dev + - name: Build using cmake+ninja + run: | + mkdir build && cd build + cmake -G "Ninja" ../ + ninja + - name: Upload linux filter + uses: actions/upload-artifact@v3 + with: + name: release-linux-filter + path: build/src/filter/**/*.so + - name: Upload linux mixer2 + uses: actions/upload-artifact@v3 + with: + name: release-linux-mixer2 + path: build/src/mixer2/**/*.so + - name: Upload linux mixer3 + uses: actions/upload-artifact@v3 + with: + name: release-linux-mixer3 + path: build/src/mixer3/**/*.so + - name: Upload linux generator + uses: actions/upload-artifact@v3 + with: + name: release-linux-generator + path: build/src/generator/**/*.so + + win-build: + name: 🪟 win64 build + runs-on: windows-latest + needs: [semantic-release] + if: ${{ needs.semantic-release.outputs.release == 'True' }} + steps: + - uses: actions/checkout@v3 + - uses: ilammy/msvc-dev-cmd@v1 + - name: choco install deps + uses: crazy-max/ghaction-chocolatey@v2 + with: + args: install libopencv-dev + - name: Build using nmake + run: | + mkdir build && cd build + cmake -G "NMake Makefiles" ../ + nmake + - name: Upload win64 filter + uses: actions/upload-artifact@v3 + with: + name: release-win64-filter + path: build/src/filter/**/*.dll + - name: Upload win64 mixer2 + uses: actions/upload-artifact@v3 + with: + name: release-win64-mixer2 + path: build/src/mixer2/**/*.dll + - name: Upload win64 mixer3 + uses: actions/upload-artifact@v3 + with: + name: release-win64-mixer3 + path: build/src/mixer3/**/*.dll + - name: Upload win64 generator + uses: actions/upload-artifact@v3 + with: + name: release-win64-generator + path: build/src/generator/**/*.dll + + osx-build: + name: 🍏 osx build + runs-on: macos-latest + needs: [semantic-release] + if: ${{ needs.semantic-release.outputs.release == 'True' }} + steps: + - uses: actions/checkout@v3 + - name: Update Homebrew + run: | + brew update --preinstall + - name: Install Homebrew dependencies + run: | + env HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 \ + brew install cmake ninja cairo + - name: Build using ninja + run: | + mkdir build && cd build + cmake -G "Ninja" ../ + ninja + - name: Upload osx filter + uses: actions/upload-artifact@v3 + with: + name: release-osx-filter + path: build/src/filter/**/*.so + - name: Upload osx mixer2 + uses: actions/upload-artifact@v3 + with: + name: release-osx-mixer2 + path: build/src/mixer2/**/*.so + - name: Upload osx mixer3 + uses: actions/upload-artifact@v3 + with: + name: release-osx-mixer3 + path: build/src/mixer3/**/*.so + - name: Upload osx generator + uses: actions/upload-artifact@v3 + with: + name: release-osx-generator + path: build/src/generator/**/*.so + + draft-binary-release: + name: 📦 Pack release + needs: [semantic-release, win-build, osx-build, linux-build] + if: ${{ needs.semantic-release.outputs.release == 'True' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: download binary artifacts + uses: actions/download-artifact@v3 + with: + path: | + frei0r-bin + - name: create compressed archives + run: | + dst=frei0r-${{ needs.semantic-release.outputs.version }}_win64 + mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3 + find frei0r-bin/release-win64-filter -type f -name '*.dll' -exec cp {} $dst/filter \; + find frei0r-bin/release-win64-generator -type f -name '*.dll' -exec cp {} $dst/generator \; + find frei0r-bin/release-win64-mixer2 -type f -name '*.dll' -exec cp {} $dst/mixer2 \; + find frei0r-bin/release-win64-mixer3 -type f -name '*.dll' -exec cp {} $dst/mixer3 \; + cp README.md $dst/README.txt + cp COPYING $dst/LICENSE.txt + cp ChangeLog $dst/ChangeLog.txt + cp AUTHORS $dst/AUTHORS.txt + cp include/frei0r.h include/frei0r.hpp $dst/ + echo "${{ needs.semantic-release.outputs.version }}" > $dst/VERSION.txt + zip -r -9 $dst.zip $dst + + dst=frei0r-${{ needs.semantic-release.outputs.version }}_osx + mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3 + find frei0r-bin/release-osx-filter -type f -name '*.so' -exec cp {} $dst/filter \; + find frei0r-bin/release-osx-generator -type f -name '*.so' -exec cp {} $dst/generator \; + find frei0r-bin/release-osx-mixer2 -type f -name '*.so' -exec cp {} $dst/mixer2 \; + find frei0r-bin/release-osx-mixer3 -type f -name '*.so' -exec cp {} $dst/mixer3 \; + cp README.md $dst/README.txt + cp COPYING $dst/LICENSE.txt + cp ChangeLog $dst/ChangeLog.txt + cp AUTHORS $dst/AUTHORS.txt + cp include/frei0r.h include/frei0r.hpp $dst/ + echo "${{ needs.semantic-release.outputs.version }}" > $dst/VERSION.txt + zip -r -9 $dst.zip $dst + + dst=frei0r-${{ needs.semantic-release.outputs.version }}_linux + mkdir -p $dst/filter $dst/generator $dst/mixer2 $dst/mixer3 + find frei0r-bin/release-linux-filter -type f -name '*.so' -exec cp {} $dst/filter \; + find frei0r-bin/release-linux-generator -type f -name '*.so' -exec cp {} $dst/generator \; + find frei0r-bin/release-linux-mixer2 -type f -name '*.so' -exec cp {} $dst/mixer2 \; + find frei0r-bin/release-linux-mixer3 -type f -name '*.so' -exec cp {} $dst/mixer3 \; + cp README.md $dst/README.txt + cp COPYING $dst/LICENSE.txt + cp ChangeLog $dst/ChangeLog.txt + cp AUTHORS $dst/AUTHORS.txt + cp include/frei0r.h include/frei0r.hpp $dst/ + echo "${{ needs.semantic-release.outputs.version }}" > $dst/VERSION.txt + tar cvfz $dst.tar.gz $dst + + sha256sum *.zip *.tar.gz > SHA256SUMS.txt + + - name: release all archives + uses: softprops/action-gh-release@v1 + with: + files: | + *.zip + *.tar.gz + SHA256SUMS.txt + tag_name: ${{ needs.semantic-release.outputs.version }} + draft: true + prerelease: false + fail_on_unmatched_files: true + generate_release_notes: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..7c12a9c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,97 @@ +name: 010-Test + +on: + push: + paths-ignore: + - 'doc/**' + - '*.md' + branches: + - master + - release/** + + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + branches: + - master + - release/** + +concurrency: + group: ${{ github.workflow }}-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + + # reuse: + # name: 🚨 REUSE Compliance + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v3 + # - uses: fsfe/reuse-action@v1 + + c-lint: + name: 🚨 C lint + runs-on: ubuntu-latest + if: "!contains(github.event.pull_request.labels.*.name, 'skip-lint')" + steps: + - uses: actions/checkout@v3 + - uses: reviewdog/action-cpplint@master + env: + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-pr-check + targets: --recursive src + level: warning + flags: --linelength=120 # Optional + filter: "-readability/braces\ + ,-readability/casting\ + ,-readability/todo\ + ,-whitespace/comma\ + ,-whitespace/braces\ + ,-whitespace/comments\ + ,-whitespace/indent\ + ,-whitespace/newline\ + ,-whitespace/operators\ + ,-whitespace/parens\ + ,-whitespace/tab\ + ,-whitespace/end_of_line\ + ,-whitespace/line_length\ + ,-whitespace/blank_line\ + ,-whitespace/semicolon\ + ,-build/include_subdir\ + ,-build/include_order\ + " + + test-suite: + name: 🔬 test + needs: [c-lint] + if: "!contains(github.event.pull_request.labels.*.name, 'skip-test')" + strategy: + matrix: + compiler: [clang-14] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: install dependencies + run: | + sudo apt-get update -qy + sudo apt-get install --no-install-recommends -y ${{ matrix.compiler }} cmake ninja-build libfreetype-dev libopencv-dev libcairo2-dev libgavl-dev + - name: ${{ matrix.compiler }} initialize cmake build + run: | + mkdir -p build && cd build + cmake -G "Ninja" ../ + - name: ${{ matrix.compiler }} run ninja build + run: | + cd build && ninja + - name: ${{ matrix.compiler }} analyze plugins + run: | + cd test && make + - name: ${{ matrix.compiler }} upload plugin analysis + uses: actions/upload-artifact@v3 + with: + name: release-plugin-analysis + path: test/*.json + diff --git a/.releaserc b/.releaserc new file mode 100644 index 0000000..9564b5e --- /dev/null +++ b/.releaserc @@ -0,0 +1,9 @@ +{ + "repositoryUrl": "git@github.com:dyne/frei0r.git", + "dryRun": false, + "plugins": [ + "@semantic-release/changelog", + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator" + ] +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..94c7443 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +notifications: + email: false +env: + - RELEASE_BRANCH="master" +language: c +os: +- linux +- osx +sudo: required +services: + - docker + +before_install: +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull dyne/devuan:beowulf && docker build -t dyne/frei0r-plugins .; fi + +script: +- cmake . && make -j && sudo make install +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run dyne/frei0r-plugins /bin/sh -c "git clean -fd && ./autogen.sh && ./configure && make -j && make install" ; fi diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..802e49f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,51 @@ +# Frei0r developers union + +Read here an account of [Frei0r's project history](https://medium.com/think-do-tank/frei0r-the-free-and-open-source-video-effect-preservation-project-604134dde8b3). + +Frei0r is maintained by [Jaromil](https://jaromil.dyne.org) for the Dyne.org Foundation. + +## Developers who contributed, in alphabetic order: + +Akito Iwakura +Albert Frisch +Brendan Hack +Brian Matherly +Burkhard Plaum +Carlo E. Prelz +Christoph Willing +Dan Dennedy +Filippo Giunchedi +Gabriel Finch (Salsaman) +Georg Seidel +Henner Zeller +Hedde Bosman +IOhannes M. Zmölnig +Janne Liljeblad +Jean-Baptiste Mardelle +Jean-François Fortin Tam +Jean-Sebastien Senecal +Jerome Blanchi (d.j.a.y) +Joshua M. Doe +Luca Bigliardi +Maksim Golovkin (Максим Головкин) +Marko Cebokli +Martin Bayer +Mathieu Guindon +Matthias Schnoell +Nicolas Carion +Niels Elburg +Phillip Promesberger +Raphael Graf +Richard Spindler +Richard Ling (Chungzuwalla) +Robert Schweikert +Ross Lagerwall +Samuel Mimram +Simon A. Eugster +Sofian Audry +Stefano Sabatini +Steinar H. Gunderson +Thomas Coldrick +Thomas Perl +Till Theato +Vincent Pinon diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..5fd9481 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,50 @@ + +Project initiated at the Piksel Festival in 2004 +hosted by BEK - Bergen Senter for Elektronisk Kunst +Maintained at the Dyne.org Foundation + +Developers who contributed, in alphabetic order: + +Akito Iwakura +Albert Frisch +Brian Matherly +Burkhard Plaum +Carlo E. Prelz +Christoph Willing +Dan Dennedy +Denis Roio (Jaromil) +Filippo Giunchedi +Gabriel Finch (Salsaman) +Georg Seidel +Henner Zeller +Hedde Bosman +IOhannes M. Zmölnig +Janne Liljeblad +Jean-Baptiste Mardelle +Jean-François Fortin Tam +Jean-Sebastien Senecal +Jerome Blanchi (d.j.a.y) +Joshua M. Doe +Luca Bigliardi +Maksim Golovkin (Максим Головкин) +Marko Cebokli +Martin Bayer +Mathieu Guindon +Matthias Schnoell +Nicolas Carion +Niels Elburg +Phillip Promesberger +Raphael Graf +Richard Spindler +Richard Ling (Chungzuwalla) +Robert Schweikert +Ross Lagerwall +Samuel Mimram +Simon A. Eugster +Sofian Audry +Stefano Sabatini +Steinar H. Gunderson +Thomas Coldrick +Thomas Perl +Till Theato +Vincent Pinon diff --git a/AUTHORS.txt b/AUTHORS.txt deleted file mode 100644 index 5fd9481..0000000 --- a/AUTHORS.txt +++ /dev/null @@ -1,50 +0,0 @@ - -Project initiated at the Piksel Festival in 2004 -hosted by BEK - Bergen Senter for Elektronisk Kunst -Maintained at the Dyne.org Foundation - -Developers who contributed, in alphabetic order: - -Akito Iwakura -Albert Frisch -Brian Matherly -Burkhard Plaum -Carlo E. Prelz -Christoph Willing -Dan Dennedy -Denis Roio (Jaromil) -Filippo Giunchedi -Gabriel Finch (Salsaman) -Georg Seidel -Henner Zeller -Hedde Bosman -IOhannes M. Zmölnig -Janne Liljeblad -Jean-Baptiste Mardelle -Jean-François Fortin Tam -Jean-Sebastien Senecal -Jerome Blanchi (d.j.a.y) -Joshua M. Doe -Luca Bigliardi -Maksim Golovkin (Максим Головкин) -Marko Cebokli -Martin Bayer -Mathieu Guindon -Matthias Schnoell -Nicolas Carion -Niels Elburg -Phillip Promesberger -Raphael Graf -Richard Spindler -Richard Ling (Chungzuwalla) -Robert Schweikert -Ross Lagerwall -Samuel Mimram -Simon A. Eugster -Sofian Audry -Stefano Sabatini -Steinar H. Gunderson -Thomas Coldrick -Thomas Perl -Till Theato -Vincent Pinon diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..95cec0a --- /dev/null +++ b/BUILD.md @@ -0,0 +1,26 @@ +# Build instructions + +Frei0r can be built using CMake. + +The presence of optional libraries on the system will trigger compilation of extra plugins. These libraries are: + + + [Gavl](http://gmerlin.sourceforge.net) required for scale0tilt and vectorscope filters + + + [OpenCV](http://opencvlibrary.sourceforge.net) required for facebl0r filter + + + [Cairo](http://cairographics.org) required for cairo- filters and mixers + +It is recommended to use a separate `build` sub-folder. + +``` +mkdir -p build +cd build && cmake ../ +make +``` + +Also ninja and nmake are supported through cmake: +``` +cmake -G 'Ninja' ../ +cmake -G 'NMake Makefiles' ../ +``` + diff --git a/CMakeLists.txt b/CMakeLists.txt index fc1b851..96d4c85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,11 @@ -cmake_minimum_required (VERSION 2.8) -include(GNUInstallDirs) +cmake_minimum_required (VERSION 3.1) list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) project (frei0r) set (VERSION 1.8) + +include(GNUInstallDirs) option (WITHOUT_OPENCV "Disable plugins dependent upon OpenCV" OFF) if (NOT WITHOUT_OPENCV) @@ -20,10 +21,6 @@ endif () include_directories (AFTER include) - -if (MSVC) - include_directories (include/msvc) -endif (MSVC) if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING @@ -41,7 +38,9 @@ # See this thread for a ridiculous discussion about the simple question how to install a header file with CMake: http://www.cmake.org/pipermail/cmake/2009-October/032874.html install (DIRECTORY include DESTINATION . FILES_MATCHING PATTERN "frei0r.h" PATTERN "msvc" EXCLUDE) -add_subdirectory (doc) +# For code documentation run: doxygen doc/Doxyfile +# add_subdirectory (doc) + add_subdirectory (src) # Generate frei0r.pc and install it. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..623b625 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.txt b/COPYING.txt deleted file mode 100644 index 623b625..0000000 --- a/COPYING.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..43e16fb --- /dev/null +++ b/ChangeLog @@ -0,0 +1,108 @@ +OLD, NOT UPDATED ANYMORE + +*** See also the Changes @section in include/frei0r.h or git log +** See also the Release section on https://github.com/dyne/frei0r/releases +* Usernames prefixed by '@' and issues prefixed by '#' refer to github/dyne/frei0r + +1.8 - 27 March 2021 + +What's Changed: +Consolidated opencv4 support by @kwizart in #101 +spelling fixes by @umlaeute in #98 +Fix build warning in 64 bit Windows by @gbendy in #107 +using the void keyword in function declaration by @mypopydev in #104 +Add FX aech0r . Aim to simulate an analog video echo. by @d-j-a-y in #73 +Fix build for opencv4 by @mingwandroid in #112 +Support MSYS2/mingw-w64 by @mingwandroid in #113 +Fill uninitialized gaps between grid images by @bmatherly in #118 +Avoid destructing alpha channel. by @andre-caldas in #119 +pixeliz0r: Limit the blocksize to a minimum of 1 pixel by @rrrapha in #120 +edgeglow: Fix hsl to rgb conversion by @rrrapha in #121 + +New Contributors: +@kwizart made their first contribution in #101 +@gbendy made their first contribution in #107 +@mypopydev made their first contribution in #104 +@mingwandroid made their first contribution in #112 +@bmatherly made their first contribution in #118 +@andre-caldas made their first contribution in #119 + +1.7 - 6 December 2019 + + This release includes three new filters, code cleanups and several + bugfixes improving stability of existing plugins. + New filters (3): normaliz0r, elastic_scale, premultiply. + Updated (47): alpha0ps, baltan, bgsubtractor, bluescreen0r, blur, + c0rners, cairogradient, cairoimagegrid, cartoon, cluster, + coloradj, colorhalftone, curves, d90stairsteppingfix, defish0r, + delay0r, edgeglow, emboss, facebl0r, facedetect, levels, + lightgraffiti, measure, ndvi, nervous, nosync0r, primaries, + rgbnoice, rgbsplit0r, scanline0r, select0r, sopsat, spillsupress, + three_point_balance, timeout, tutorial, vertigo, vignette, water, + alphaatop, alphain, alphaout, alphaover, alphaxor, + cairoaffineblend, cairoblend, xfade0r + +1.6.1 - 25 May 2017 + + Minor fixes to the build system. Version correctly updated. + +1.6.0 - 24 March 2017 + + This release contains new filters and some bugfixes to parameters + and building environment, documentation is updated accordingly. + New filters (3): bgsubtract0r, glitch0r, rgbsplit0r + Updated (2): Distort0r now mode and velocity, Curves has improved + precision. + +1.5.0 - 2 April 2016 + + This release fixes several major bugs in existing plugins and adds + one new filter: NDVI (Normalized Difference Vegetation Index). + +1.4.0 - 24 February 2013 + + This release fixes several major bugs in existing plugins, + adds new filters and the optional dependency to cairo. + New filters (18): IIRblur, Vignette, Keyspillm0pup, Timeout, + Posterize, Dither, Spillsupress, Emboss, Colgate, RGBNoise, + Colorize, Softglow, ColrHalftone, Sigmoidaltransfer, + Colortap, cairogradient, cairoimagegrid, medians + New mixers: cairoblend, cairoaffineblend + +1.3.0 - 8 March 2011 + + This release adds more plugins, better documentation and better + examples for writing code that makes use of thed opencv library. + New filters (4): tutorial, sharpness, denoise, lightgraffiti + New generator: test_pat (broadcast test patterns) + New mixer: addition_alpha + +1.2.1 - 4 October 2010 + + This is a bugfix release which avoids a crash on load of the + Vertigo plugin and corrects the install path according do + distribution needs. + +1.2.0 - 13 September 2010 + + This release adds many new filters, cross-platform compatibility + to build Win32 plugins, some fixes to the specification, a new Web + page, and more documentation. + +1.1.22 - 28 October 2008 + + Three new plugins were added: UV Map, Edge Glow, and K-Means + Clustering. Various bugfixes were done. + +1.1.21 - 1 April 2008 + + This release adds six new plugins: Lenscorrection, Transparency, + Color Distance, Perspective, RGB Parade, and Vector Scope. + +1.1.20 - 7 November 2007 + + This is the first release as a standard autoconf tarball. It + contains various bugfixes and some new plugins. + + +*** At last, see also git --log from repository diff --git a/ChangeLog.txt b/ChangeLog.txt deleted file mode 100644 index 540e723..0000000 --- a/ChangeLog.txt +++ /dev/null @@ -1,106 +0,0 @@ -*** See also the Changes @section in include/frei0r.h or git log -** See also the Release section on https://github.com/dyne/frei0r/releases -* Usernames prefixed by '@' and issues prefixed by '#' refer to github/dyne/frei0r - -1.8 - 27 March 2021 - -What's Changed: -Consolidated opencv4 support by @kwizart in #101 -spelling fixes by @umlaeute in #98 -Fix build warning in 64 bit Windows by @gbendy in #107 -using the void keyword in function declaration by @mypopydev in #104 -Add FX aech0r . Aim to simulate an analog video echo. by @d-j-a-y in #73 -Fix build for opencv4 by @mingwandroid in #112 -Support MSYS2/mingw-w64 by @mingwandroid in #113 -Fill uninitialized gaps between grid images by @bmatherly in #118 -Avoid destructing alpha channel. by @andre-caldas in #119 -pixeliz0r: Limit the blocksize to a minimum of 1 pixel by @rrrapha in #120 -edgeglow: Fix hsl to rgb conversion by @rrrapha in #121 - -New Contributors: -@kwizart made their first contribution in #101 -@gbendy made their first contribution in #107 -@mypopydev made their first contribution in #104 -@mingwandroid made their first contribution in #112 -@bmatherly made their first contribution in #118 -@andre-caldas made their first contribution in #119 - -1.7 - 6 December 2019 - - This release includes three new filters, code cleanups and several - bugfixes improving stability of existing plugins. - New filters (3): normaliz0r, elastic_scale, premultiply. - Updated (47): alpha0ps, baltan, bgsubtractor, bluescreen0r, blur, - c0rners, cairogradient, cairoimagegrid, cartoon, cluster, - coloradj, colorhalftone, curves, d90stairsteppingfix, defish0r, - delay0r, edgeglow, emboss, facebl0r, facedetect, levels, - lightgraffiti, measure, ndvi, nervous, nosync0r, primaries, - rgbnoice, rgbsplit0r, scanline0r, select0r, sopsat, spillsupress, - three_point_balance, timeout, tutorial, vertigo, vignette, water, - alphaatop, alphain, alphaout, alphaover, alphaxor, - cairoaffineblend, cairoblend, xfade0r - -1.6.1 - 25 May 2017 - - Minor fixes to the build system. Version correctly updated. - -1.6.0 - 24 March 2017 - - This release contains new filters and some bugfixes to parameters - and building environment, documentation is updated accordingly. - New filters (3): bgsubtract0r, glitch0r, rgbsplit0r - Updated (2): Distort0r now mode and velocity, Curves has improved - precision. - -1.5.0 - 2 April 2016 - - This release fixes several major bugs in existing plugins and adds - one new filter: NDVI (Normalized Difference Vegetation Index). - -1.4.0 - 24 February 2013 - - This release fixes several major bugs in existing plugins, - adds new filters and the optional dependency to cairo. - New filters (18): IIRblur, Vignette, Keyspillm0pup, Timeout, - Posterize, Dither, Spillsupress, Emboss, Colgate, RGBNoise, - Colorize, Softglow, ColrHalftone, Sigmoidaltransfer, - Colortap, cairogradient, cairoimagegrid, medians - New mixers: cairoblend, cairoaffineblend - -1.3.0 - 8 March 2011 - - This release adds more plugins, better documentation and better - examples for writing code that makes use of thed opencv library. - New filters (4): tutorial, sharpness, denoise, lightgraffiti - New generator: test_pat (broadcast test patterns) - New mixer: addition_alpha - -1.2.1 - 4 October 2010 - - This is a bugfix release which avoids a crash on load of the - Vertigo plugin and corrects the install path according do - distribution needs. - -1.2.0 - 13 September 2010 - - This release adds many new filters, cross-platform compatibility - to build Win32 plugins, some fixes to the specification, a new Web - page, and more documentation. - -1.1.22 - 28 October 2008 - - Three new plugins were added: UV Map, Edge Glow, and K-Means - Clustering. Various bugfixes were done. - -1.1.21 - 1 April 2008 - - This release adds six new plugins: Lenscorrection, Transparency, - Color Distance, Perspective, RGB Parade, and Vector Scope. - -1.1.20 - 7 November 2007 - - This is the first release as a standard autoconf tarball. It - contains various bugfixes and some new plugins. - - -*** At last, see also git --log from repository diff --git a/INSTALL.txt b/INSTALL.txt deleted file mode 100644 index 5eca51c..0000000 --- a/INSTALL.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Installation Instructions - -Frei0r can be built using either Autoconf or CMake. - -The choice is open, CMake is mandatory only on Windowz. - -The presence of optional libraries on the system will trigger compilation -of extra plugins. These libraries are: - - + [Gavl](http://gmerlin.sourceforge.net) required for scale0tilt and vectorscope filters - - + [OpenCV](http://opencvlibrary.sourceforge.net) required for facebl0r filter - - + [Cairo](http://cairographics.org) required for cairo- filters and mixers - -## Autoconf build - -``` -./configure -make -``` - -## CMake build - -``` -cmake . -make -``` - -## Proceed with install - -Default prefix is `/usr/local`, target directory is `frei0r-1` - -A default `make install` as root will put the plugins into `/usr/local/lib/frei0r-1` unless the prefix path is specified. Most applications will look into that directory on GNU/Linux, or it should be possible to configure where to look for frei0r plugins. - -When using Apple/OSX, the `dlopen()` mechanism (in FFMpeg for instance) will look for `.dylib` extensions and not the `.so` that frei0r plugins have by default. To fix this problem one can rename the plugins simply so: - -``` -for file in /usr/local/lib/frei0r-1/*.so ; do - cp $file "${file%.*}.dylib" -done -``` - - diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 3ebc7d0..0000000 --- a/Makefile.am +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2007 Richard Spindler -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -ACLOCAL_AMFLAGS= -I m4 - -SUBDIRS=src include - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = frei0r.pc - -docsdir = ${prefix}/share/doc/${PACKAGE} -docs_DATA = README.md ChangeLog TODO AUTHORS diff --git a/README.md b/README.md new file mode 100644 index 0000000..018f659 --- /dev/null +++ b/README.md @@ -0,0 +1,159 @@ +[![Frei0r logo](https://github.com/dyne/frei0r/raw/gh_pages/pics/frei0r.png)](https://frei0r.dyne.org) + + + +[![frei0r](https://github.com/dyne/frei0r/actions/workflows/test.yml/badge.svg)](https://github.com/dyne/frei0r/actions/workflows/test.yml) +[![frei0r](https://github.com/dyne/frei0r/actions/workflows/release.yml/badge.svg)](https://github.com/dyne/frei0r/actions/workflows/release.yml) + + +# What frei0r is + +The frei0r project is a collection of free and open source video effects plugins that can be used with a variety of video editing and processing software. + +[For an extensive introduction to frei0r please read this story.](https://jaromil.medium.com/frei0r-the-free-and-open-source-video-effect-preservation-project-604134dde8b3?source=friends_link&sk=c83a054b979d421279f5fc3d2ea1acd8) + +The frei0r project welcomes contributions by people who are passionate about video effects, its collection consists of more than 100 plugins made to work on any target platform (GNU/Linux, Apple/OSX and MS/Win) without the need for special video hardware. These plugins can be used to add a wide range of effects to video, such as color correction, blurring, and distortion. + +The frei0r project is a great resource for anyone interested in algorithms for video transformation and effects, as it provides a wide range of open source formulas available for free and can be easily integrated into a variety of software. + + +## What frei0r is not + +Frei0r itself is just a C/C++ header and a collection of small programs using it to accept an input frame, change it in any possible way and return an output frame. + +It is not meant as a generic API for all kinds of video applications, as it doesn't provides things like an extensive parameter mechanism or event handling. + +Eventually the frei0r API can be wrapped by higher level APIs expanding its functionalities, for instance GStreamer, MLT, FFmpeg and Pure Data do. + +## Links + +Wikipedia page about frei0r: https://en.wikipedia.org/wiki/Frei0r + +Some applications using frei0r, sorted in order of most recent activity + +- [MLT](https://www.mltframework.org/) +- [LiquidSoap](https://www.liquidsoap.info/) +- [KDEnLive](https://www.kdenlive.org/) +- [Shotcut](https://www.shotcut.org/) +- [FFMpeg](https://ffmpeg.org) +- [PureData](https://puredata.info/) +- [Open Movie Editor](http://www.openmovieeditor.org/) +- [Gephex](https://gephex.org/) +- [LiVES](http://lives.sf.net) +- [FreeJ](https://freej.dyne.org) +- [VeeJay](http://veejayhq.net) +- [Flowblade](https://jliljebl.github.io/flowblade/) + + +# Downloads + +Stable frei0r releases are built automatically and made available on + +## https://github.com/dyne/frei0r/releases + +Frei0r sourcecode is released under the terms of the GNU General Public License and, eventually other compatible Free Software licenses. + +## Build dependencies + +Frei0r can be built on GNU/Linux, M$/Windows and Apple/OSX platforms, possibly in even more environments like embedded devices. + +For details see the [BUILD](/BUILD.md) file. + +### MS / Windows + +We distribute official builds of frei0r plugins as .dll for the Win64 platform from the releases page. + +### BSD + +Ports of frei0r are included in all major BSD distros: +- FreeBSD https://www.freshports.org/graphics/frei0r +- OpenBSD +- NetBSD https://pkgsrc.se/multimedia/frei0r + +### GNU / Linux + +Binary packages are maintained on various distributions, but they may not be completely up to date with the latest release. + +- [frei0r*](https://repology.org/project/frei0r/versions) +- [frei0r-plugins*](https://repology.org/project/frei0r-plugins/versions) +- [ocaml:frei0r*](https://repology.org/project/ocaml:frei0r/versions) + +### Apple / OSX + +A [frei0r Brew formula](https://formulae.brew.sh/formula/frei0r) is available. + +Official builds of frei0r plugins as .dlsym for the Apple/OSX platform will be soon included in the releases page. + +# Documentation + + +If you are new to frei0r (but not to programming) the best thing is probably to have a look at the [frei0r header](/include/frei0r.h), which is quite simple and well documented. The [doxyfied documentation](https://frei0r.dyne.org/codedoc/html) is also available for browsing online. + + +## C++ Filter example + +You could find a tutorial filter [here](https://github.com/dyne/frei0r/tree/master/src/filter/tutorial) in the source code. +A simple skeleton for a frei0r video filter looks like this: + +```c++ + #include + + typedef struct { + int16_t w, h; + uint8_t bpp; + uint32_t size; + } ScreenGeometry; + + class MyExample: public frei0r::filter { + public: + MyExample(int wdt, int hgt); + ~MyExample(); + virtual void update(); + private: + ScreenGeometry geo; + void _init(int wdt, int hgt); + } + + MyExample::MyExample() { /* constructor */ } + MyExample::~MyExample() { /* destructor */ } + + void MyExample::_init(int wdt, int hgt) { + geo.w = wdt; + geo.h = hgt; + geo.bpp = 32; // this filter works only in RGBA 32bit + geo.size = geo.w*geo.h*(geo.bpp/8); // calculate the size in bytes + } + + void MyExample::update() { + // we get video input via buffer pointer (void*)in + uint32_t *src = (uint32_t*)in; + // and we give video output via buffer pointer (void*)out + uint32_t *dst = (uint32_t*)out; + // this example here does just a copy of input to output + memcpy(dst, src, geo.size); + } + + frei0r::construct + plugin("MyExample", "short and simple description for my example", + "Who did it", 1, 0); +``` + +## Join us + +To contribute your plugin please open a [pull request](https://github.com/dyne/frei0r/pulls). + +For bug reporting please use our [issue tracker](https://github.com/dyne/frei0r/issues). + +You can get in touch with some developers over various dyne.org chat channels, for instance + +### https://t.me/frei0r + +We also have an (old) mailing list open to [subscription](https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/frei0r) and we provide [public archives](https://lists.dyne.org/lurker/list/frei0r.en.html) of discussions, searchable and indexed online. + +## Acknowledgments + +Frei0r is the result of a collective effort in coordination with several software developers meeting to find a common standard for video effect plugins to be used among their applications. + +For a full list of contributors and the project history, see the file [AUTHORS](/AUTHORS), the [ChangeLog](/ChangeLog) and the project web page: https://frei0r.dyne.org + + diff --git a/README.txt b/README.txt deleted file mode 100644 index 5941fb6..0000000 --- a/README.txt +++ /dev/null @@ -1,197 +0,0 @@ -``` - ___________ ._________ - \_ _____/______ ____ |__\ _ \_______ - | __) \_ __ \_/ __ \| / /_\ \_ __ \ - | \ | | \/\ ___/| \ \_/ \ | \/ - \___ / |__| \___ >__|\_____ /__| - \/ \/ \/ - -``` - -*Minimalistic plugin API for video effects, by the Piksel Developers Union* - -Updated info on https://frei0r.dyne.org - -[![software by Dyne.org](https://files.dyne.org/software_by_dyne.png)](http://www.dyne.org) - -[![Build Status](https://travis-ci.org/dyne/frei0r.svg?branch=master)](https://travis-ci.org/dyne/frei0r) - -# What frei0r is - -Frei0r is a minimalistic plugin API for video effects. - -The main emphasis is on simplicity for an API that will round up the -most common video effects into simple filters, sources and mixers that -can be controlled by parameters. - -It's our hope that this way these simple effects can be shared between -many applications, avoiding their reimplementation by different -projects. - -## What frei0r is not - -Frei0r is not meant as a competing standard to more ambitious efforts -that try to satisfy the needs of many different applications and more -complex effects. - -It is not meant as a generic API for all kinds of video applications, -as it doesn't provides things like an extensive parameter mechanism or -event handling. - -Eventually the frei0r API can be wrapped by higher level APIs -expanding its functionalities -(for instance as GStreamer, MLT, FFmpeg and others do). - -## Current status - -Developers are sporadically contributing and we are happy if more -people like to get involved, so let us know about your creations! Code -and patches are well accepted, get in touch with us on the -mailinglist (see the section Communication below). - - -## History - -Frei0r has been around since 2004, born from yearly brainstormings -held at the Piksel conference with the participation of various free -and open source video software developers. - -It works on all hardware platforms without the need for any particular -hardware acceleration (GNU/Linux, Apple/OSX and MS/Win) and consists -of more than 100 plugins. Among the free and open source video -application supporting frei0r are: KDEnLive, FFmpeg, MLT, PureData, -Open Movie Editor, DVEdit, Gephex, LiVES, FreeJ, VeeJay, Flowblade, and -Shotcut among the others. - -Wikipedia page about frei0r: http://en.wikipedia.org/wiki/Frei0r - - -[Piksel]: http://www.piksel.no -[PureData]: http://www.artefacte.org/pd/ -[Open Movie Editor]: http://openmovieeditor.sourceforge.net/ -[DVEdit]: http://www.freenet.org.nz/dvedit -[Gephex]: http://www.gephex.org/ -[LiVES]: http://lives.sf.net -[FreeJ]: http://freej.dyne.org -[MøB]: http://mob.bek.no/ -[VeeJay]: http://veejayhq.net -[MLT]: http://www.mltframework.org/ -[KDEnLive]: http://www.kdenlive.org/ -[Flowblade]: http://code.google.com/p/flowblade/ -[Shotcut]: https://www.shotcut.org/ - - -# Downloads - -## Source code - -Stable frei0r releases are packaged periodically and distributed on - - https://files.dyne.org/frei0r - -Frei0r sourcecode is released under the terms of the GNU General Public License and, eventually other compatible Free Software licenses. - -The latest source for frei0r plugins can be attained using git on https://github.com/dyne/frei0r - -Make sure to get in touch with our mailinglist if you like to contribute. - -## Build dependencies - -Frei0r can be built on GNU/Linux, M$/Windows and Apple/OSX platforms, possibly in even more environments like embedded devices. - -For details see the [INSTALL](/INSTALL.md) file. - -### GNU / Linux - -Binary packages are mantained on various distributions, but they may not be completely up to date with latest release. - -### Apple / OSX - -MacPorts provides packages for OSX: -[MacPorts]: http://www.macports.org - $ sudo port install frei0r-plugins - -Pre-compiled binaries are also uploaded on our website. - -We encourage Apple/OSX application distributors to compile the plugins -directly and to include frei0r within their bundle. - - - -### Microsoft / Windows - -Pre-compiled binaries are often provided by third-parties, but they may not to be up to date. - -We encourage MS/Win application distributors to compile the plugins directly and to include frei0r within their bundle. - - -# Documentation - - -If you are new to frei0r (but not to programming) the best thing is probably to have a look at the [frei0r header](/include/frei0r.h), which is quite simple and well documented. The [doxyfied documentation](http://frei0r.dyne.org/codedoc/html) is also available for browsing on-line. - - -## C++ Filter example - -You could find a tutorial filter [here](https://github.com/dyne/frei0r/tree/master/src/filter/tutorial) in the source code. -A simple skeleton for a frei0r video filter looks like this: - -```c++ - #include - - typedef struct { - int16_t w, h; - uint8_t bpp; - uint32_t size; - } ScreenGeometry; - - class MyExample: public frei0r::filter { - public: - MyExample(int wdt, int hgt); - ~MyExample(); - virtual void update(); - private: - ScreenGeometry geo; - void _init(int wdt, int hgt); - } - - MyExample::MyExample() { /* constructor */ } - MyExample::~MyExample() { /* destructor */ } - - void MyExample::_init(int wdt, int hgt) { - geo.w = wdt; - geo.h = hgt; - geo.bpp = 32; // this filter works only in RGBA 32bit - geo.size = geo.w*geo.h*(geo.bpp/8); // calculate the size in bytes - } - - void MyExample::update() { - // we get video input via buffer pointer (void*)in - uint32_t *src = (uint32_t*)in; - // and we give video output via buffer pointer (void*)out - uint32_t *dst = (uint32_t*)out; - // this example here does just a copy of input to output - memcpy(dst, src, geo.size); - } - - frei0r::construct - plugin("MyExample", "short and simple description for my example", - "Who did it", 1, 0); -``` - - -## Communication - -You can get in touch with our developer community, send your new effects and share your intentions with us. - -We have a free mailinglist open to [subscription](https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/frei0r) and we provide [public archives](https://lists.dyne.org/lurker/list/frei0r.en.html) of the discussions there that are also searchable and indexed online. - -For bug reporting the mailinglist is preferred, but is also possible to use an [issue tracker](https://github.com/dyne/frei0r/issues). - -## Acknowledgments - -Frei0r is the result of a collective effort in coordination with several software developers meeting to find a common standard for video effect plugins to be used among their applications. - -For a full list of contributors and the project history, see the file [AUTHORS](/AUTHORS), the [ChangeLog](/ChangeLog) and the project web page: https://frei0r.dyne.org - - diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 22b78a5..0000000 --- a/autogen.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# Run this to set up the build system: configure, makefiles, etc. -# (based on the version in enlightenment's cvs) -# - -package="frei0r" - -olddir=`pwd` -srcdir=`dirname $0` - -AUTOHEADER=autoheader -if [ "`uname -s`" = "Darwin" ]; then - LIBTOOLIZE=glibtoolize - ACLOCAL=aclocal - AUTOMAKE=automake -else - LIBTOOLIZE=libtoolize - ACLOCAL=aclocal - AUTOMAKE=automake -fi -AUTOCONF=autoconf - -test -z "$srcdir" && srcdir=. - -cd "$srcdir" -DIE=0 - -($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have autoconf installed to compile $package." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have automake installed to compile $package." - echo "Download the appropriate package for your system," - echo "or get the source from one of the GNU ftp sites" - echo "listed in http://www.gnu.org/order/ftp.html" - DIE=1 -} - -($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || { - echo - echo "You must have libtool installed to compile $package." - echo "Download the appropriate package for your system," - echo "or get the source from one of the GNU ftp sites" - echo "listed in http://www.gnu.org/order/ftp.html" - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -# if test -z "$*"; then -# echo "I am going to run ./configure with no arguments - if you wish " -# echo "to pass any to it, please specify them on the $0 command line." -# fi - -echo "Generating configuration files for $package, please wait...." - -echo " $ACLOCAL" -mkdir -p m4 -$ACLOCAL || exit -1 -echo " $AUTOHEADER" -$AUTOHEADER || exit -1 -echo " $LIBTOOLIZE --automake -c" -$LIBTOOLIZE --automake -c || exit -1 -echo " $AUTOMAKE --add-missing -c" -$AUTOMAKE --add-missing -c || exit -1 -echo " $AUTOCONF" -$AUTOCONF || exit -1 - -echo "Now you can run $srcdir/configure" - -cd $olddir diff --git a/cmake/modules/LibFindMacros.cmake b/cmake/modules/LibFindMacros.cmake index 69975c5..85601ed 100644 --- a/cmake/modules/LibFindMacros.cmake +++ b/cmake/modules/LibFindMacros.cmake @@ -79,12 +79,6 @@ macro(libfind_library PREFIX basename) set(TMP "") - if(MSVC80) - set(TMP -vc80) - endif(MSVC80) - if(MSVC90) - set(TMP -vc90) - endif(MSVC90) set(${PREFIX}_LIBNAMES ${basename}${TMP}) if(${ARGC} GREATER 2) set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2}) diff --git a/configure.ac b/configure.ac deleted file mode 100644 index af5d445..0000000 --- a/configure.ac +++ /dev/null @@ -1,183 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.59c) -AC_INIT(frei0r-plugins, [1.8], [frei0r-devel@dyne.org]) -AC_CONFIG_MACRO_DIR([m4]) - -AM_INIT_AUTOMAKE([foreign subdir-objects]) - -# Checks for programs. -AC_PROG_CXX -AC_PROG_CC -AC_PROG_CC_C99 -LT_INIT([disable-static win32-dll]) - - -AC_CONFIG_HEADERS([include/config.h]) - -if test "x${prefix}" = "xNONE"; then - prefix=${ac_default_prefix} -fi -PACKAGE_LIB_DIR="${prefix}/lib/frei0r-1" -AC_SUBST(PACKAGE_LIB_DIR) -PACKAGE_DATA_DIR="${prefix}/share/frei0r-1" -AC_SUBST(PACKAGE_DATA_DIR) - -AC_MSG_CHECKING([host platform]) -case $host_os in - *linux*) - AC_MSG_RESULT([Linux]) - have_linux=yes - ;; - *freebsd*) - AC_MSG_RESULT([FreeBSD]) - have_freebsd=yes - ;; - *darwin*) - AC_MSG_RESULT([Darwin/OSX]) - have_darwin=yes - ;; - *mingw*) - AC_MSG_RESULT([MinGW-w64]) - have_mingw=yes - ;; - *) - AC_MSG_RESULT([ $host_os ? ... let us try]) - ;; -esac - -AC_ARG_ENABLE(cpuflags, - [ --enable-cpuflags compile with advanced cpu instructions (yes)], - [ - if test ! x$enableval = xyes; then - have_cpuflags=no - else - have_cpuflags=yes; - fi ],[ have_cpuflags=yes ]) - -if test x$have_cpuflags = xyes; then - if test x$have_linux = xyes; then - CPUFLAGS=`cat /proc/cpuinfo | grep flags` - if grep "^flags.* mmx" /proc/cpuinfo > /dev/null; then - have_mmx=yes - AC_DEFINE(HAVE_MMX,1,[define if enabling MMX acceleration]) - fi - if grep "^flags.* sse" /proc/cpuinfo > /dev/null; then - have_sse=yes - AC_DEFINE(HAVE_SSE,1,[define if enabling SSE acceleration]) - fi - if grep "^flags.* sse2" /proc/cpuinfo > /dev/null; then - have_sse=yes - AC_DEFINE(HAVE_SSE2,1,[define if enabling SSE2 acceleration]) - fi - if grep "^flags.* ssse3" /proc/cpuinfo > /dev/null; then - have_ssse3=yes - AC_DEFINE(HAVE_SSSE3,1,[define if enabling SSSE3 acceleration]) - fi - fi - if test x$have_freebsd = xyes; then - if sysctl -n hw.instruction_sse; then - have_mmx=yes - AC_DEFINE(HAVE_MMX,1,[define if enabling MMX acceleration]) - fi - fi -fi - -AM_CONDITIONAL([HAVE_MINGW], [test x$have_mingw = xyes]) - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([float.h inttypes.h limits.h stdlib.h string.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE - -# Checks for library functions. -AC_FUNC_MALLOC -AC_CHECK_FUNCS([floor memset pow sqrt]) - -HAVE_OPENCV=false -PKG_CHECK_MODULES([OPENCV], [opencv4 >= 4.0.0], - [AC_DEFINE([HAVE_OPENCV], true, [compiled including OpenCV >= 4])], - [PKG_CHECK_MODULES([OPENCV], [opencv > 1.0.0], - [AC_DEFINE([HAVE_OPENCV], true, [compiled including OpenCV < 4]) - ], [true]) -]) -if test ! "x$OPENCV_LIBS" = "x"; then - HAVE_OPENCV=true - AC_DEFINE(OPENCV_DATA_DIR,[${prefix}/share/opencv],opencv data prefix) - OPENCV_DATA_DIR=${prefix}/share/opencv - AC_SUBST([OPENCV_CFLAGS]) - AC_SUBST([OPENCV_LIBS]) -fi -AM_CONDITIONAL([HAVE_OPENCV], [test x$HAVE_OPENCV = xtrue]) -AC_SUBST(HAVE_OPENCV) - -HAVE_GAVL=false -PKG_CHECK_MODULES(GAVL, gavl >= 0.2.3, [HAVE_GAVL=true], [true]) -AM_CONDITIONAL([HAVE_GAVL], [test x$HAVE_GAVL = xtrue]) - -HAVE_CAIRO=false -PKG_CHECK_MODULES(CAIRO, cairo >= 1.0.0, [HAVE_CAIRO=true], [true]) -AM_CONDITIONAL([HAVE_CAIRO], [test x$HAVE_CAIRO = xtrue]) - -AC_CHECK_PROG([DOXYGEN], [doxygen], [doxygen]) - - -AC_CONFIG_FILES([ - frei0r.pc - Makefile - include/Makefile - src/Makefile - doc/Makefile -]) - -AC_OUTPUT - -echo -echo -echo "Compile $PACKAGE $VERSION for ${host}" -echo -echo " - INSTALL prefix: $prefix" - -if test x$have_cpuflags = xyes; then -echo " - CPU optimization: YES" -else -echo " - CPU optimization: NO" -fi - -if test x$HAVE_OPENCV = xtrue; then -echo " - opencv: YES" -echo " data dir: $OPENCV_DATA_DIR" -else -echo " - opencv: NO" -echo " opencv >= 1.0.0 not found - this program enables optional" -echo " plugin with the Open Source Computer Vision library >= 1.0.0" -echo " http://opencvlibrary.sourceforge.net/" -fi - -if test x$HAVE_GAVL = xtrue; then -echo " - gavl: YES" -else -echo " - gavl: NO" -echo " gavl >= 0.2.3 not found - this program enables optional" -echo " plugin with the gmerlin audio video library >= 0.2.3" -echo " http://gmerlin.sourceforge.net/" -fi - -if test x$HAVE_CAIRO = xtrue; then -echo " - cairo: YES" -else -echo " - cairo: NO" -echo " cairo >= 1.0.0 not found - this program enables optional" -echo " plugin with the Cairo 2D vector graphics library >= 1.0.0" -echo " http://www.cairographics.org/" -fi - -echo -echo "Now you can run make." -echo -echo diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt deleted file mode 100644 index 4be9cf3..0000000 --- a/doc/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -find_package(Doxygen) -if(DOXYGEN_FOUND) -# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) -add_custom_target(doc -${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile -WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} -COMMENT "Generating API documentation with Doxygen" VERBATIM -) -endif(DOXYGEN_FOUND) - diff --git a/doc/Doxyfile b/doc/Doxyfile index 47b3157..b7bda63 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -568,7 +568,7 @@ # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = "../include/frei0r.h" +INPUT = "include/frei0r.h" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index c06d7e7..0000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2007 Richard Spindler -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -html: - $(DOXYGEN) Doxyfile - -htmldocs_DATA = html - -htmldocsdir=${prefix}/share/doc/${PACKAGE} - -clean: - rm -rf html - -dist-hook: - -cp -ra html $(distdir)/doc/ - -install-data: - install -c -m 644 -d $(htmldocs_DATA) $(DESTDIR)$(htmldocsdir) - -# Modify the install hook, so we can install directories -install-htmldocsDATA: - mkdir -p $(DESTDIR)$(htmldocsdir) - cp -r ./html $(DESTDIR)$(htmldocsdir)/ - diff --git a/include/Makefile.am b/include/Makefile.am deleted file mode 100644 index 1d6041a..0000000 --- a/include/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (C) 2007 Richard Spindler -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -include_HEADERS = frei0r.h -noinst_HEADERS = frei0r_colorspace.h frei0r.hpp frei0r_math.h diff --git a/include/frei0r.h b/include/frei0r.h index 38fdfc8..09b6e31 100644 --- a/include/frei0r.h +++ b/include/frei0r.h @@ -23,7 +23,7 @@ * @section sec_overview Overview * * If you are new to frei0r, the best thing is probably to have - * a look at the frei0r header, + * a look at the frei0r header, * which is quite simple. * * After that, you might want to look at the diff --git a/include/msvc/inttypes.h b/include/msvc/inttypes.h deleted file mode 100644 index ead903f..0000000 --- a/include/msvc/inttypes.h +++ /dev/null @@ -1,305 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - - -#endif // _MSC_INTTYPES_H_ ] diff --git a/include/msvc/stdint.h b/include/msvc/stdint.h deleted file mode 100644 index c66fbb8..0000000 --- a/include/msvc/stdint.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 39b1171..9d8baf4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,7 @@ set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed") -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_subdirectory (filter) add_subdirectory (generator) add_subdirectory (mixer2) diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 7d397c4..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,364 +0,0 @@ -# Copyright (C) 2007 Richard Spindler -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -plugin_LTLIBRARIES = \ - 3dflippo.la \ - addition.la \ - addition_alpha.la \ - aech0r.la \ - alpha0ps.la \ - alphaatop.la \ - alphagrad.la \ - alphain.la \ - alphainjection.la \ - alphaout.la \ - alphaover.la \ - alphaspot.la \ - alphaxor.la \ - B.la \ - balanc0r.la \ - baltan.la \ - blend.la \ - bluescreen0r.la \ - bgsubtract0r.la \ - brightness.la \ - burn.la \ - bw0r.la \ - c0rners.la \ - cartoon.la \ - cluster.la \ - colgate.la \ - coloradj_RGB.la \ - colordistance.la \ - colorhalftone.la \ - colorize.la \ - colortap.la \ - color_only.la \ - composition.la \ - contrast0r.la \ - curves.la \ - d90stairsteppingfix.la \ - darken.la \ - defish0r.la \ - delay0r.la \ - delaygrab.la \ - difference.la \ - distort0r.la \ - dither.la \ - divide.la \ - dodge.la \ - edgeglow.la \ - elastic_scale.la \ - emboss.la \ - equaliz0r.la \ - flippo.la \ - G.la \ - gamma.la \ - glow.la \ - glitch0r.la \ - grain_extract.la \ - grain_merge.la \ - hardlight.la \ - hqdn3d.la \ - hue.la \ - hueshift0r.la \ - IIRblur.la \ - invert0r.la \ - ising0r.la \ - keyspillm0pup.la \ - lenscorrection.la \ - letterb0xed.la \ - levels.la \ - lighten.la \ - lightgraffiti.la \ - lissajous0r.la \ - luminance.la \ - mask0mate.la \ - medians.la \ - multiply.la \ - ndvi.la \ - nervous.la \ - nois0r.la \ - normaliz0r.la \ - nosync0r.la \ - onecol0r.la \ - overlay.la \ - partik0l.la \ - perspective.la \ - pixeliz0r.la \ - plasma.la \ - posterize.la \ - pr0be.la \ - pr0file.la \ - premultiply.la \ - primaries.la \ - R.la \ - RGB.la \ - rgbnoise.la \ - rgbsplit0r.la \ - saturation.la \ - saturat0r.la \ - scanline0r.la \ - screen.la \ - select0r.la \ - sharpness.la \ - sigmoidaltransfer.la \ - sobel.la \ - softglow.la \ - softlight.la \ - sopsat.la \ - spillsupress.la \ - squareblur.la \ - subtract.la \ - tehroxx0r.la \ - test_pat_B.la \ - test_pat_C.la \ - test_pat_G.la \ - test_pat_I.la \ - test_pat_L.la \ - test_pat_R.la \ - three_point_balance.la \ - threshold0r.la \ - threelay0r.la \ - timeout.la \ - tint0r.la \ - transparency.la \ - twolay0r.la \ - uvmap.la \ - value.la \ - vertigo.la \ - vignette.la \ - xfade0r.la - -if HAVE_GAVL -plugin_LTLIBRARIES += scale0tilt.la -scale0tilt_la_SOURCES = filter/scale0tilt/scale0tilt.c -scale0tilt_la_CFLAGS = @GAVL_CFLAGS@ @CFLAGS@ -scale0tilt_la_LIBADD = @GAVL_LIBS@ - -plugin_LTLIBRARIES += vectorscope.la -vectorscope_la_SOURCES = filter/vectorscope/vectorscope.c filter/vectorscope/vectorscope_image.h -vectorscope_la_CFLAGS = @GAVL_CFLAGS@ @CFLAGS@ -vectorscope_la_LIBADD = @GAVL_LIBS@ - -plugin_LTLIBRARIES += rgbparade.la -rgbparade_la_SOURCES = filter/rgbparade/rgbparade.c filter/rgbparade/rgbparade_image.h -rgbparade_la_CFLAGS = @GAVL_CFLAGS@ @CFLAGS@ -rgbparade_la_LIBADD = @GAVL_LIBS@ -endif - -if HAVE_OPENCV -plugin_LTLIBRARIES += facebl0r.la -facebl0r_la_SOURCES = filter/facebl0r/facebl0r.cpp -facebl0r_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ -facebl0r_la_CXXFLAGS = @OPENCV_CFLAGS@ @CXXFLAGS@ -facebl0r_la_LIBADD = @OPENCV_LIBS@ -plugin_LTLIBRARIES += facedetect.la -facedetect_la_SOURCES = filter/facedetect/facedetect.cpp -facedetect_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ -facedetect_la_CXXFLAGS = @OPENCV_CFLAGS@ @CXXFLAGS@ -facedetect_la_LIBADD = @OPENCV_LIBS@ -endif - -if HAVE_CAIRO -plugin_LTLIBRARIES += cairogradient.la -cairogradient_la_SOURCES = filter/cairogradient/cairogradient.c -cairogradient_la_CFLAGS = @CAIRO_CFLAGS@ @CFLAGS@ -cairogradient_la_LIBADD = @CAIRO_LIBS@ - -plugin_LTLIBRARIES += cairoimagegrid.la -cairoimagegrid_la_SOURCES = filter/cairoimagegrid/cairoimagegrid.c -cairoimagegrid_la_CFLAGS = @CAIRO_CFLAGS@ @CFLAGS@ -cairoimagegrid_la_LIBADD = @CAIRO_LIBS@ - -plugin_LTLIBRARIES += cairoaffineblend.la -cairoaffineblend_la_SOURCES = mixer2/cairoaffineblend/cairoaffineblend.c -cairoaffineblend_la_CFLAGS = @CAIRO_CFLAGS@ @CFLAGS@ -cairoaffineblend_la_LIBADD = @CAIRO_LIBS@ - -plugin_LTLIBRARIES += cairoblend.la -cairoblend_la_SOURCES = mixer2/cairoblend/cairoblend.c -cairoblend_la_CFLAGS = @CAIRO_CFLAGS@ @CFLAGS@ -cairoblend_la_LIBADD = @CAIRO_LIBS@ - -ndvi_la_CPPFLAGS = @CAIRO_CFLAGS@ @CPPFLAGS@ -DHAVE_CAIRO -ndvi_la_LIBADD = @CAIRO_LIBS@ -endif - -# -# FILTERS -# -3dflippo_la_SOURCES = filter/3dflippo/3dflippo.c -alpha0ps_la_SOURCES = filter/alpha0ps/alpha0ps.c filter/alpha0ps/fibe_f.h -alphagrad_la_SOURCES = filter/alpha0ps/alphagrad.c -alphaspot_la_SOURCES = filter/alpha0ps/alphaspot.c -aech0r_la_SOURCES = filter/aech0r/aech0r.cpp -B_la_SOURCES = filter/RGB/B.c -balanc0r_la_SOURCES = filter/balanc0r/balanc0r.c -baltan_la_SOURCES = filter/baltan/baltan.cpp -bgsubtract0r_la_SOURCES = filter/bgsubtract0r/bgsubtract0r.c -bluescreen0r_la_SOURCES = filter/bluescreen0r/bluescreen0r.cpp -brightness_la_SOURCES = filter/brightness/brightness.c -bw0r_la_SOURCES = filter/bw0r/bw0r.c -c0rners_la_SOURCES = filter/c0rners/c0rners.c filter/c0rners/interp.h -cartoon_la_SOURCES = filter/cartoon/cartoon.cpp -cluster_la_SOURCES = filter/cluster/cluster.c -colgate_la_SOURCES = filter/colgate/colgate.c -coloradj_RGB_la_SOURCES = filter/coloradj/coloradj_RGB.c -colordistance_la_SOURCES = filter/colordistance/colordistance.c -colorhalftone_la_SOURCES = filter/colorhalftone/colorhalftone.c -colorize_la_SOURCES = filter/colorize/colorize.c -colortap_la_SOURCES = filter/colortap/colortap.c -contrast0r_la_SOURCES = filter/contrast0r/contrast0r.c -curves_la_SOURCES = filter/curves/curves.c -d90stairsteppingfix_la_SOURCES = filter/d90stairsteppingfix/d90stairsteppingfix.cpp -defish0r_la_SOURCES = filter/defish0r/defish0r.c filter/defish0r/interp.h -delay0r_la_SOURCES = filter/delay0r/delay0r.cpp -delaygrab_la_SOURCES = filter/delaygrab/delaygrab.cpp -distort0r_la_SOURCES = filter/distort0r/distort0r.c -dither_la_SOURCES = filter/dither/dither.c -edgeglow_la_SOURCES = filter/edgeglow/edgeglow.cpp -elastic_scale_la_SOURCES = filter/elastic_scale/elastic_scale.cpp -emboss_la_SOURCES = filter/emboss/emboss.c -emboss_la_LIBADD = -lm -equaliz0r_la_SOURCES = filter/equaliz0r/equaliz0r.cpp -flippo_la_SOURCES = filter/flippo/flippo.c -G_la_SOURCES = filter/RGB/G.c -gamma_la_SOURCES = filter/gamma/gamma.c -glow_la_SOURCES = filter/glow/glow.c -glitch0r_la_SOURCES = filter/glitch0r/glitch0r.c -hqdn3d_la_SOURCES = filter/denoise/hqdn3d.c -hueshift0r_la_SOURCES = filter/hueshift0r/hueshift0r.c filter/hueshift0r/matrix.h -IIRblur_la_SOURCES = filter/blur/IIRblur.c filter/blur/fibe.h -invert0r_la_SOURCES = filter/invert0r/invert0r.c -keyspillm0pup_la_SOURCES = filter/keyspillm0pup/keyspillm0pup.c -lenscorrection_la_SOURCES = filter/lenscorrection/lenscorrection.c -letterb0xed_la_SOURCES = filter/letterb0xed/letterb0xed.c -levels_la_SOURCES = filter/levels/levels.c -lightgraffiti_la_SOURCES = filter/lightgraffiti/lightgraffiti.cpp -luminance_la_SOURCES = filter/luminance/luminance.c -mask0mate_la_SOURCES = filter/mask0mate/mask0mate.c -medians_la_SOURCES = filter/medians/medians.c filter/medians/ctmf.h filter/medians/small_medians.h -ndvi_la_SOURCES = filter/ndvi/ndvi.cpp filter/ndvi/gradientlut.hpp -nervous_la_SOURCES = filter/nervous/nervous.cpp -normaliz0r_la_SOURCES = filter/normaliz0r/normaliz0r.c -nosync0r_la_SOURCES = filter/nosync0r/nosync0r.cpp -partik0l_la_SOURCES = generator/partik0l/partik0l.cpp -perspective_la_SOURCES = filter/perspective/perspective.c -pixeliz0r_la_SOURCES = filter/pixeliz0r/pixeliz0r.c -posterize_la_SOURCES = filter/posterize/posterize.c -pr0be_la_SOURCES = filter/measure/pr0be.c filter/measure/measure.h filter/measure/font2.h -pr0file_la_SOURCES = filter/measure/pr0file.c filter/measure/measure.h filter/measure/font2.h -premultiply_la_SOURCES = filter/premultiply/premultiply.cpp -primaries_la_SOURCES = filter/primaries/primaries.cpp -R_la_SOURCES = filter/RGB/R.c -rgbnoise_la_SOURCES = filter/rgbnoise/rgbnoise.c -rgbsplit0r_la_SOURCES = filter/rgbsplit0r/rgbsplit0r.c -saturat0r_la_SOURCES = filter/saturat0r/saturat0r.c -scanline0r_la_SOURCES = filter/scanline0r/scanline0r.cpp -select0r_la_SOURCES = filter/select0r/select0r.c -sharpness_la_SOURCES = filter/sharpness/sharpness.c -sigmoidaltransfer_la_SOURCES = filter/sigmoidaltransfer/sigmoidaltransfer.c -sobel_la_SOURCES = filter/sobel/sobel.cpp -softglow_la_SOURCES = filter/softglow/softglow.c -sopsat_la_SOURCES = filter/sopsat/sopsat.cpp -spillsupress_la_SOURCES = filter/spillsupress/spillsupress.c -squareblur_la_SOURCES = filter/squareblur/squareblur.c -tehroxx0r_la_SOURCES = filter/tehroxx0r/tehRoxx0r.c -threelay0r_la_SOURCES = filter/threelay0r/threelay0r.cpp -three_point_balance_la_SOURCES = filter/three_point_balance/three_point_balance.c -threshold0r_la_SOURCES = filter/threshold0r/threshold0r.c -timeout_la_SOURCES = filter/timeout/timeout.cpp -tint0r_la_SOURCES = filter/tint0r/tint0r.c -transparency_la_SOURCES = filter/transparency/transparency.c -twolay0r_la_SOURCES = filter/twolay0r/twolay0r.cpp -vertigo_la_SOURCES = filter/vertigo/vertigo.c -vignette_la_SOURCES = filter/vignette/vignette.cpp - -# -# GENERATORS -# -ising0r_la_SOURCES = generator/ising0r/ising0r.c -lissajous0r_la_SOURCES = generator/lissajous0r/lissajous0r.cpp -nois0r_la_SOURCES = generator/nois0r/nois0r.cpp -onecol0r_la_SOURCES = generator/onecol0r/onecol0r.cpp -plasma_la_SOURCES = generator/dem0scene/plasma.cpp -test_pat_B_la_SOURCES = generator/test_pat/test_pat_B.c -test_pat_C_la_SOURCES = generator/test_pat/test_pat_C.c -test_pat_G_la_SOURCES = generator/test_pat/test_pat_G.c -test_pat_I_la_SOURCES = generator/test_pat/test_pat_I.c -test_pat_L_la_SOURCES = generator/test_pat/test_pat_L.c -test_pat_R_la_SOURCES = generator/test_pat/test_pat_R.c - -# -# MIXERS -# -addition_la_SOURCES = mixer2/addition/addition.cpp -addition_alpha_la_SOURCES = mixer2/addition_alpha/addition_alpha.cpp -alphaatop_la_SOURCES = mixer2/alphaatop/alphaatop.cpp -alphainjection_la_SOURCES = mixer2/alphainjection/alphainjection.c -alphain_la_SOURCES = mixer2/alphain/alphain.cpp -alphaout_la_SOURCES = mixer2/alphaout/alphaout.cpp -alphaover_la_SOURCES = mixer2/alphaover/alphaover.cpp -alphaxor_la_SOURCES = mixer2/alphaxor/alphaxor.cpp -blend_la_SOURCES = mixer2/blend/blend.cpp -burn_la_SOURCES = mixer2/burn/burn.cpp -color_only_la_SOURCES = mixer2/color_only/color_only.cpp -composition_la_SOURCES = mixer2/composition/composition.c -darken_la_SOURCES = mixer2/darken/darken.cpp -difference_la_SOURCES = mixer2/difference/difference.cpp -divide_la_SOURCES = mixer2/divide/divide.cpp -dodge_la_SOURCES = mixer2/dodge/dodge.cpp -grain_extract_la_SOURCES = mixer2/grain_extract/grain_extract.cpp -grain_merge_la_SOURCES = mixer2/grain_merge/grain_merge.cpp -hardlight_la_SOURCES = mixer2/hardlight/hardlight.cpp -hue_la_SOURCES = mixer2/hue/hue.cpp -lighten_la_SOURCES = mixer2/lighten/lighten.cpp -multiply_la_SOURCES = mixer2/multiply/multiply.cpp -overlay_la_SOURCES = mixer2/overlay/overlay.cpp -RGB_la_SOURCES = mixer3/RGB/RGB.c -saturation_la_SOURCES = mixer2/saturation/saturation.cpp -screen_la_SOURCES = mixer2/screen/screen.cpp -softlight_la_SOURCES = mixer2/softlight/softlight.cpp -subtract_la_SOURCES = mixer2/subtract/subtract.cpp -uvmap_la_SOURCES = mixer2/uvmap/uvmap.c -value_la_SOURCES = mixer2/value/value.cpp -xfade0r_la_SOURCES = mixer2/xfade0r/xfade0r.cpp - - -AM_CPPFLAGS = -I@top_srcdir@/include -Waddress -Wtype-limits -Wsign-compare -AM_CFLAGS = -I@top_srcdir@/include -Waddress -Wtype-limits -Wsign-compare -AM_CXXFLAGS = -I@top_srcdir@/include -Waddress -Wtype-limits -Wsign-compare -AM_LIBTOOLFLAGS = --tag=disable-static - -plugindir = @libdir@/frei0r-1 - -if HAVE_MINGW -SO_EXT = .dll -AM_LDFLAGS = -module -avoid-version -export-dynamic -no-undefined -else -SO_EXT = .so -AM_LDFLAGS = -module -avoid-version -lm -export-dynamic -endif - -install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) - mkdir -p $(DESTDIR)/$(plugindir) - list='$(plugin_LTLIBRARIES)'; \ - for file in $$list; do \ - sofile=`basename $$file .la`$(SO_EXT); \ - $(INSTALL_PROGRAM) .libs/$$sofile $(DESTDIR)/$(plugindir); \ - done - -uninstall-pluginLTLIBRARIES: - list='$(plugin_LTLIBRARIES)'; \ - for file in $$list; do \ - sofile=`basename $$file .la`$(SO_EXT); \ - rm -f $(DESTDIR)/$(plugindir)/$$sofile; \ - done diff --git a/src/filter/3dflippo/CMakeLists.txt b/src/filter/3dflippo/CMakeLists.txt index 8089bfa..4d2878e 100644 --- a/src/filter/3dflippo/CMakeLists.txt +++ b/src/filter/3dflippo/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET 3dflippo) if (MSVC) - set_source_files_properties (3dflippo.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/CMakeLists.txt b/src/filter/CMakeLists.txt index 22b3802..0c22852 100644 --- a/src/filter/CMakeLists.txt +++ b/src/filter/CMakeLists.txt @@ -46,13 +46,16 @@ add_subdirectory (elastic_scale) add_subdirectory (emboss) add_subdirectory (equaliz0r) +add_subdirectory (filmgrain) add_subdirectory (flippo) add_subdirectory (gamma) +add_subdirectory (gateweave) add_subdirectory (glow) add_subdirectory (glitch0r) #add_subdirectory (host_param_test) add_subdirectory (hueshift0r) add_subdirectory (invert0r) +add_subdirectory (kaleid0sc0pe) add_subdirectory (keyspillm0pup) add_subdirectory (lenscorrection) add_subdirectory (letterb0xed) @@ -61,16 +64,14 @@ add_subdirectory (luminance) add_subdirectory (mask0mate) add_subdirectory (medians) -if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - # clang 3.1 on OSX fails to compile this one - add_subdirectory (measure) -endif () +add_subdirectory (measure) add_subdirectory (ndvi) add_subdirectory (nervous) add_subdirectory (normaliz0r) add_subdirectory (nosync0r) add_subdirectory (perspective) add_subdirectory (pixeliz0r) +add_subdirectory (pixs0r) add_subdirectory (posterize) add_subdirectory (premultiply) add_subdirectory (primaries) diff --git a/src/filter/RGB/CMakeLists.txt b/src/filter/RGB/CMakeLists.txt index 596fa12..3febb37 100644 --- a/src/filter/RGB/CMakeLists.txt +++ b/src/filter/RGB/CMakeLists.txt @@ -3,7 +3,6 @@ set (B_SOURCES B.c) if (MSVC) - set_source_files_properties (R.c G.c B.c PROPERTIES LANGUAGE CXX) set (R_SOURCES ${R_SOURCES} ${FREI0R_DEF}) set (G_SOURCES ${G_SOURCES} ${FREI0R_DEF}) set (B_SOURCES ${B_SOURCES} ${FREI0R_DEF}) diff --git a/src/filter/alpha0ps/CMakeLists.txt b/src/filter/alpha0ps/CMakeLists.txt index d21422e..7fdfec1 100644 --- a/src/filter/alpha0ps/CMakeLists.txt +++ b/src/filter/alpha0ps/CMakeLists.txt @@ -1,26 +1,27 @@ -set (O_SOURCES alpha0ps.c fibe_f.h) -set (G_SOURCES alphagrad.c) -set (S_SOURCES alphaspot.c) +set (O_SOURCES alpha0ps_alpha0ps.c fibe_f.h) +set (G_SOURCES alpha0ps_alphagrad.c) +set (S_SOURCES alpha0ps_alphaspot.c) if (MSVC) - set_source_files_properties (alpha0ps.c alphagrad.c alphaspot.c PROPERTIES LANGUAGE CXX) set (O_SOURCES ${O_SOURCES} ${FREI0R_DEF}) set (G_SOURCES ${G_SOURCES} ${FREI0R_DEF}) set (S_SOURCES ${S_SOURCES} ${FREI0R_DEF}) endif (MSVC) -add_library (alpha0ps MODULE ${O_SOURCES}) -add_library (alphagrad MODULE ${G_SOURCES}) -add_library (alphaspot MODULE ${S_SOURCES}) +add_library (alpha0ps_alpha0ps MODULE ${O_SOURCES}) +add_library (alpha0ps_alphagrad MODULE ${G_SOURCES}) +add_library (alpha0ps_alphaspot MODULE ${S_SOURCES}) -target_link_libraries(alpha0ps -lm) -target_link_libraries(alphagrad -lm) -target_link_libraries(alphaspot -lm) +if(NOT MSVC) + target_link_libraries(alpha0ps_alpha0ps -lm) + target_link_libraries(alpha0ps_alphagrad -lm) + target_link_libraries(alpha0ps_alphaspot -lm) +endif() -set_target_properties (alpha0ps PROPERTIES PREFIX "") -set_target_properties (alphagrad PROPERTIES PREFIX "") -set_target_properties (alphaspot PROPERTIES PREFIX "") +set_target_properties (alpha0ps_alpha0ps PROPERTIES PREFIX "") +set_target_properties (alpha0ps_alphagrad PROPERTIES PREFIX "") +set_target_properties (alpha0ps_alphaspot PROPERTIES PREFIX "") -install (TARGETS alpha0ps LIBRARY DESTINATION ${LIBDIR}) -install (TARGETS alphagrad LIBRARY DESTINATION ${LIBDIR}) -install (TARGETS alphaspot LIBRARY DESTINATION ${LIBDIR}) +install (TARGETS alpha0ps_alpha0ps LIBRARY DESTINATION ${LIBDIR}) +install (TARGETS alpha0ps_alphagrad LIBRARY DESTINATION ${LIBDIR}) +install (TARGETS alpha0ps_alphaspot LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/alpha0ps/alpha0ps.c b/src/filter/alpha0ps/alpha0ps.c deleted file mode 100644 index f532994..0000000 --- a/src/filter/alpha0ps/alpha0ps.c +++ /dev/null @@ -1,705 +0,0 @@ -/* -alpha0ps.c - -This frei0r plugin is for display & manipulation of alpha channel -Version 0.1 jul 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - - - 28 aug 2012 ver 0.2 endian proofing - - 03 sep 2012 ver 0.3 add alpha blur - -*/ - - -//compile: gcc -c -fPIC -Wall alpha0ps.c -o alpha0ps.o -//link: gcc -shared -o alpha0ps.so alpha0ps.o - -#include -#include -#include -#include -#include - - -#include "fibe_f.h" - - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ - int h; - int w; - - //parameters - int disp; - int din; - int op; - float thr; - float sga; - int inv; - - //auxilliary variables for fibe2o - float f,q,a0,a1,a2,b0,b1,b2,rd1,rd2,rs1,rs2,rc1,rc2; - -} inst; - - -//--------------------------------------------------- -void alphagray(inst *in, uint8_t *infr, uint8_t *oufr) -{ - uint8_t s; - int i; - - if (in->din==0) - for (i=0;iw*in->h;i++) - { - s=oufr[4*i+3]; - oufr[4*i]=s; - oufr[4*i+1]=s; - oufr[4*i+2]=s; - oufr[4*i+3]=0xFF; - } - else - for (i=0;iw*in->h;i++) - { - s=infr[4*i+3]; - oufr[4*i]=s; - oufr[4*i+1]=s; - oufr[4*i+2]=s; - oufr[4*i+3]=0xFF; - } -} - -//--------------------------------------------------- -void grayred(inst *in, uint8_t *infr, uint8_t *oufr) -{ - int i,rr; - uint8_t r,g,b,a,y; - - if (in->din==0) - for (i=0;iw*in->h;i++) - { - b=infr[4*i+2]; - g=infr[4*i+1]; - r=infr[4*i]; - a=oufr[4*i+3]; - y=(r>>2)+(g>>1)+(b>>2); //approx luma - y=64+(y>>1); - rr=y+(a>>1); - if (rr>255) rr=255; - oufr[4*i]=rr; - oufr[4*i+1]=y; - oufr[4*i+2]=y; - oufr[4*i+3]=0xFF; - } - else - for (i=0;iw*in->h;i++) - { - b=infr[4*i+2]; - g=infr[4*i+1]; - r=infr[4*i]; - a=infr[4*i+3]; - y=(r>>2)+(g>>1)+(b>>2); //approx luma - y=64+(y>>1); - rr=y+(a>>1); - if (rr>255) rr=255; - oufr[4*i]=rr; - oufr[4*i+1]=y; - oufr[4*i+2]=y; - oufr[4*i+3]=0xFF; - } -} - -//--------------------------------------------------- -void drawsel(inst *in, uint8_t *infr, uint8_t *oufr, int bg) -{ - int i; - uint32_t bk; - uint32_t r,g,b,a; - - switch (bg) - { - case 0: bk=0x00; break; - case 1: bk=0x80; break; - case 2: bk=0xFF; break; - default: break; - } - - if (in->din==0) - for (i=0;iw*in->h;i++) - { - if (bg==3) - { - if (((i/8)%2)^((i/8/in->w)%2)) - bk=0x64; - else - bk=0x9B; - } - b=oufr[4*i+2]; - g=oufr[4*i+1]; - r=oufr[4*i]; - a=oufr[4*i+3]; - r=(a*r+(255-a)*bk)>>8; - g=(a*g+(255-a)*bk)>>8; - b=(a*b+(255-a)*bk)>>8; - oufr[4*i]=r; - oufr[4*i+1]=g; - oufr[4*i+2]=b; - oufr[4*i+3]=0xFF; - } - else - for (i=0;iw*in->h;i++) - { - if (bg==3) - { - if (((i/8)%2)^((i/8/in->w)%2)) - bk=0x64; - else - bk=0x9B; - } - b=infr[4*i+2]; - g=infr[4*i+1]; - r=infr[4*i]; - a=infr[4*i+3]; - r=(a*r+(255-a)*bk)>>8; - g=(a*g+(255-a)*bk)>>8; - b=(a*b+(255-a)*bk)>>8; - oufr[4*i]=r; - oufr[4*i+1]=g; - oufr[4*i+2]=b; - oufr[4*i+3]=0xFF; - } -} - -//---------------------------------------------------------- -//shave based on average of 8 neighbors -void shave_alpha(float *sl, float *ab, int w, int h) -{ - int i,j,p; - float m; - - for (i=1;ial[p-1]) - ab[p]=al[p-1]; - if (al[p]>al[p+1]) - ab[p]=al[p+1]; - if (al[p]>al[p-w]) - ab[p]=al[p-w]; - if (al[p]>al[p+w]) - ab[p]=al[p+w]; - p++; - } - } - break; - case 1: - for (i=1;ial[p-1]) - m=al[p-1]; - if (al[p]>al[p+1]) - m=al[p+1]; - if (al[p]>al[p-w]) - m=al[p-w]; - if (al[p]>al[p+w]) - m=al[p+w]; - md=al[p]; - if (al[p]>al[p-1-w]) - md=al[p-1-w]; - if (al[p]>al[p+1-w]) - md=al[p+1-w]; - if (al[p]>al[p-1+w]) - md=al[p-1+w]; - if (al[p]>al[p+1+w]) - md=al[p+1+w]; - - ab[p]=0.4*al[p]+0.4*m+0.2*md; - // ab[p]=0.3*al[p]+0.4*m+0.3*md; - p++; - } - } - break; - } - - - - for (i=0;ithr) ? hi : lo; -} - -//---------------------------------------------------------- -void blur_alpha(inst *in, float *falpha) -{ - int i; - - for (i=0;iw*in->h;i++) falpha[i]*=0.0039215; - - fibe2o_f(falpha, in->w, in->h, in->a1, in->a2, in->rd1, in->rd2, in->rs1, in->rs2, in->rc1, in->rc2, 1); - - for (i=0;iw*in->h;i++) - { - falpha[i]*=255.0; - if (falpha[i]>255.0) falpha[i]=255.0; - if (falpha[i]<0.0) falpha[i]=0.0; - } -} - -//-------------------------------------------------------- -//Aitken-Neville interpolacija iz 4 tock (tretjega reda) -//t = stevilo tock v arrayu -//array xt naj bo v rastocem zaporedju, lahko neekvidistanten -float AitNev3(int t, float xt[], float yt[], float x) -{ - float p[10]; - int i,j,m; - - if ((xxt[t-1])) - { - // printf("\n\n x=%f je izven mej tabele!",x); - return 1.0/0.0; - } - - //poisce, katere tocke bo uporabil - m=0; while (x>xt[m++]); - m=m-4/2-1; if (m<0) m=0; if ((m+4)>(t-1)) m=t-4; - - for (i=0;i<4;i++) - p[i]=yt[i+m]; - - for (j=1;j<4;j++) - for (i=(4-1);i>=j;i--) - { - p[i]=p[i]+(x-xt[i+m])/(xt[i+m]-xt[i-j+m])*(p[i]-p[i-1]); - } - return p[4-1]; -} - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ - return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ - return (v-min)/(max-min); -} - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ - return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - - info->name="alpha0ps"; - info->author="Marko Cebokli"; - info->plugin_type=F0R_PLUGIN_TYPE_FILTER; - info->color_model=F0R_COLOR_MODEL_RGBA8888; - info->frei0r_version=FREI0R_MAJOR_VERSION; - info->major_version=0; - info->minor_version=4; - info->num_params=6; - info->explanation="Display and manipulation of the alpha channel"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ - switch(param_index) - { - case 0: - info->name = "Display"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 1: - info->name = "Display input alpha"; - info->type = F0R_PARAM_BOOL; - info->explanation = ""; - break; - case 2: - info->name = "Operation"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 3: - info->name = "Threshold"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 4: - info->name = "Shrink/Grow/Blur amount"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 5: - info->name = "Invert"; - info->type = F0R_PARAM_BOOL; - info->explanation = ""; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ - inst *in; - - in=calloc(1,sizeof(inst)); - in->w=width; - in->h=height; - - in->disp=0; - in->din=0; - in->op=0; - in->thr=0.5; - in->sga=1.0; - in->inv=0; - - in->f=0.05; in->q=0.55; //blur - calcab_lp1(in->f, in->q, &in->a0, &in->a1, &in->a2, &in->b0, &in->b1, &in->b2); - in->a1=in->a1/in->a0; in->a2=in->a2/in->a0; - rep(-0.5, 0.5, 0.0, &in->rd1, &in->rd2, 256, in->a1, in->a2); - rep(1.0, 1.0, 0.0, &in->rs1, &in->rs2, 256, in->a1, in->a2); - rep(0.0, 0.0, 1.0, &in->rc1, &in->rc2, 256, in->a1, in->a2); - - return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ - inst *in; - - in=(inst*)instance; - - free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ - inst *p; - double tmpf; - int tmpi,chg; - - p=(inst*)instance; - - float am1[]={0.499999,0.7,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0,15.0,20.0,30.0,40.0,50.0,70.0,100.0,150.0,200.00001}; - float iir2f[]={0.475,0.39,0.325,0.26,0.21,0.155,0.112,0.0905,0.065,0.0458,0.031,0.0234,0.01575,0.0118,0.0093,0.00725,0.00505,0.0033,0.0025}; - float iir2q[]={0.53,0.53,0.54,0.54,0.54,0.55,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6}; - - chg=0; - switch(param_index) - { - case 0: //Display - tmpi=map_value_forward(*((double*)parm), 0.0, 6.9999); - if (p->disp != tmpi) chg=1; - p->disp=tmpi; - break; - case 1: //Display input alpha - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->din != tmpi) chg=1; - p->din=tmpi; - break; - case 2: //Operation - tmpi=map_value_forward(*((double*)parm), 0.0, 7.9999); - if (p->op != tmpi) chg=1; - p->op=tmpi; - break; - case 3: //Threshold - tmpf=*(double*)parm; - if (tmpf!=p->thr) chg=1; - p->thr=tmpf; - break; - case 4: //Shrink/Grow/Blur amount - tmpf=map_value_forward(*((double*)parm), 0.0, 4.9999); - if (p->sga != tmpf) chg=1; - p->sga=tmpf; - break; - case 5: //Invert - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->inv != tmpi) chg=1; - p->inv=tmpi; - break; - } - - if (chg==0) return; - - if (param_index==4) // blur amount changed - { - p->f=AitNev3(19, am1, iir2f, 0.5+3.0*p->sga); - p->q=AitNev3(19, am1, iir2q, 0.5+3.0*p->sga); - calcab_lp1(p->f, p->q, &p->a0, &p->a1, &p->a2, &p->b0, &p->b1, &p->b2); - p->a1=p->a1/p->a0; p->a2=p->a2/p->a0; - rep(-0.5, 0.5, 0.0, &p->rd1, &p->rd2, 256, p->a1, p->a2); - rep(1.0, 1.0, 0.0, &p->rs1, &p->rs2, 256, p->a1, p->a2); - rep(0.0, 0.0, 1.0, &p->rc1, &p->rc2, 256, p->a1, p->a2); - } - -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ - inst *p; - - p=(inst*)instance; - - switch(param_index) - { - case 0: - *((double*)param)=map_value_backward(p->disp, 0.0, 6.9999); - break; - case 1: - *((double*)param)=map_value_backward(p->din, 0.0, 1.0);//BOOL!! - break; - case 2: - *((double*)param)=map_value_backward(p->op, 0.0, 6.9999); - break; - case 3: - *((double*)param)=p->thr; - break; - case 4: - *((double*)param)=map_value_backward(p->sga, 0.0, 2.9999); - break; - case 5: - *((double*)param)=map_value_backward(p->inv, 0.0, 1.0);//BOOL!! - break; - } -} - -//------------------------------------------------- -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ - inst *in; - int i; - float *falpha, *ab; - uint8_t *infr, *oufr; - - assert(instance); - in=(inst*)instance; - infr=(uint8_t*)inframe; - oufr=(uint8_t*)outframe; - - falpha = calloc(in->w * in->h, sizeof(float)); - ab = calloc(in->w * in->h, sizeof(float)); - for (i=0;iw*in->h;i++) - falpha[i] = infr[4*i+3]; - - switch (in->op) - { - case 0: break; - case 1: - for (i=0;isga;i++) - shave_alpha(falpha, ab, in->w, in->h); - break; - case 2: - for (i=0;isga;i++) - shrink_alpha(falpha, ab, in->w, in->h, 0); - break; - case 3: - for (i=0;isga;i++) - shrink_alpha(falpha, ab, in->w, in->h, 1); - break; - case 4: - for (i=0;isga;i++) - grow_alpha(falpha, ab, in->w, in->h, 0); - break; - case 5: - for (i=0;isga;i++) - grow_alpha(falpha, ab, in->w, in->h, 1); - break; - case 6: - threshold_alpha(falpha, in->w, in->h, 255.0*in->thr, 255.0, 0.0); - break; - case 7: - blur_alpha(in, falpha); - break; - default: - break; - } - - if (in->inv==1) - for (i=0;iw*in->h;i++) - falpha[i] = 255.0 - falpha[i]; - - for (i=0;iw*in->h;i++) - { - outframe[i] = inframe[i]; - oufr[4*i+3] = (uint8_t) falpha[i]; - } - - switch (in->disp) - { - case 0: - break; - case 1: - alphagray(in, infr, oufr); - break; - case 2: - grayred(in, infr, oufr); - break; - case 3: - drawsel(in, infr, oufr, 0); - break; - case 4: - drawsel(in, infr, oufr, 1); - break; - case 5: - drawsel(in, infr, oufr, 2); - break; - case 6: - drawsel(in, infr, oufr, 3); - break; - default: - break; - } - free(falpha); - free(ab); -} - -//********************************************************** diff --git a/src/filter/alpha0ps/alpha0ps_alpha0ps.c b/src/filter/alpha0ps/alpha0ps_alpha0ps.c new file mode 100644 index 0000000..e4ac4e6 --- /dev/null +++ b/src/filter/alpha0ps/alpha0ps_alpha0ps.c @@ -0,0 +1,706 @@ +/* +alpha0ps.c + +This frei0r plugin is for display & manipulation of alpha channel +Version 0.1 jul 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + + 28 aug 2012 ver 0.2 endian proofing + + 03 sep 2012 ver 0.3 add alpha blur + +*/ + + +//compile: gcc -c -fPIC -Wall alpha0ps.c -o alpha0ps.o +//link: gcc -shared -o alpha0ps.so alpha0ps.o + +#include +#include +#include +#include +#include + + +#include "fibe_f.h" + + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ + int h; + int w; + + //parameters + int disp; + int din; + int op; + float thr; + float sga; + int inv; + + //auxilliary variables for fibe2o + float f,q,a0,a1,a2,b0,b1,b2,rd1,rd2,rs1,rs2,rc1,rc2; + +} inst; + + +//--------------------------------------------------- +void alphagray(inst *in, uint8_t *infr, uint8_t *oufr) +{ + uint8_t s; + int i; + + if (in->din==0) + for (i=0;iw*in->h;i++) + { + s=oufr[4*i+3]; + oufr[4*i]=s; + oufr[4*i+1]=s; + oufr[4*i+2]=s; + oufr[4*i+3]=0xFF; + } + else + for (i=0;iw*in->h;i++) + { + s=infr[4*i+3]; + oufr[4*i]=s; + oufr[4*i+1]=s; + oufr[4*i+2]=s; + oufr[4*i+3]=0xFF; + } +} + +//--------------------------------------------------- +void grayred(inst *in, uint8_t *infr, uint8_t *oufr) +{ + int i,rr; + uint8_t r,g,b,a,y; + + if (in->din==0) + for (i=0;iw*in->h;i++) + { + b=infr[4*i+2]; + g=infr[4*i+1]; + r=infr[4*i]; + a=oufr[4*i+3]; + y=(r>>2)+(g>>1)+(b>>2); //approx luma + y=64+(y>>1); + rr=y+(a>>1); + if (rr>255) rr=255; + oufr[4*i]=rr; + oufr[4*i+1]=y; + oufr[4*i+2]=y; + oufr[4*i+3]=0xFF; + } + else + for (i=0;iw*in->h;i++) + { + b=infr[4*i+2]; + g=infr[4*i+1]; + r=infr[4*i]; + a=infr[4*i+3]; + y=(r>>2)+(g>>1)+(b>>2); //approx luma + y=64+(y>>1); + rr=y+(a>>1); + if (rr>255) rr=255; + oufr[4*i]=rr; + oufr[4*i+1]=y; + oufr[4*i+2]=y; + oufr[4*i+3]=0xFF; + } +} + +//--------------------------------------------------- +void drawsel(inst *in, uint8_t *infr, uint8_t *oufr, int bg) +{ + int i; + uint32_t bk; + uint32_t r,g,b,a; + + switch (bg) + { + case 0: bk=0x00; break; + case 1: bk=0x80; break; + case 2: bk=0xFF; break; + default: break; + } + + if (in->din==0) + for (i=0;iw*in->h;i++) + { + if (bg==3) + { + if (((i/8)%2)^((i/8/in->w)%2)) + bk=0x64; + else + bk=0x9B; + } + b=oufr[4*i+2]; + g=oufr[4*i+1]; + r=oufr[4*i]; + a=oufr[4*i+3]; + r=(a*r+(255-a)*bk)>>8; + g=(a*g+(255-a)*bk)>>8; + b=(a*b+(255-a)*bk)>>8; + oufr[4*i]=r; + oufr[4*i+1]=g; + oufr[4*i+2]=b; + oufr[4*i+3]=0xFF; + } + else + for (i=0;iw*in->h;i++) + { + if (bg==3) + { + if (((i/8)%2)^((i/8/in->w)%2)) + bk=0x64; + else + bk=0x9B; + } + b=infr[4*i+2]; + g=infr[4*i+1]; + r=infr[4*i]; + a=infr[4*i+3]; + r=(a*r+(255-a)*bk)>>8; + g=(a*g+(255-a)*bk)>>8; + b=(a*b+(255-a)*bk)>>8; + oufr[4*i]=r; + oufr[4*i+1]=g; + oufr[4*i+2]=b; + oufr[4*i+3]=0xFF; + } +} + +//---------------------------------------------------------- +//shave based on average of 8 neighbors +void shave_alpha(float *sl, float *ab, int w, int h) +{ + int i,j,p; + float m; + + for (i=1;ial[p-1]) + ab[p]=al[p-1]; + if (al[p]>al[p+1]) + ab[p]=al[p+1]; + if (al[p]>al[p-w]) + ab[p]=al[p-w]; + if (al[p]>al[p+w]) + ab[p]=al[p+w]; + p++; + } + } + break; + case 1: + for (i=1;ial[p-1]) + m=al[p-1]; + if (al[p]>al[p+1]) + m=al[p+1]; + if (al[p]>al[p-w]) + m=al[p-w]; + if (al[p]>al[p+w]) + m=al[p+w]; + md=al[p]; + if (al[p]>al[p-1-w]) + md=al[p-1-w]; + if (al[p]>al[p+1-w]) + md=al[p+1-w]; + if (al[p]>al[p-1+w]) + md=al[p-1+w]; + if (al[p]>al[p+1+w]) + md=al[p+1+w]; + + ab[p]=0.4*al[p]+0.4*m+0.2*md; + // ab[p]=0.3*al[p]+0.4*m+0.3*md; + p++; + } + } + break; + } + + + + for (i=0;ithr) ? hi : lo; +} + +//---------------------------------------------------------- +void blur_alpha(inst *in, float *falpha) +{ + int i; + + for (i=0;iw*in->h;i++) falpha[i]*=0.0039215; + + fibe2o_f(falpha, in->w, in->h, in->a1, in->a2, in->rd1, in->rd2, in->rs1, in->rs2, in->rc1, in->rc2, 1); + + for (i=0;iw*in->h;i++) + { + falpha[i]*=255.0; + if (falpha[i]>255.0) falpha[i]=255.0; + if (falpha[i]<0.0) falpha[i]=0.0; + } +} + +//-------------------------------------------------------- +//Aitken-Neville interpolacija iz 4 tock (tretjega reda) +//t = stevilo tock v arrayu +//array xt naj bo v rastocem zaporedju, lahko neekvidistanten +float AitNev3(int t, float xt[], float yt[], float x) +{ + float p[10]; + int i,j,m; + float zero = 0.0f; // MSVC doesn't allow division through a zero literal, but allows it through non-const variable set to zero + + if ((xxt[t-1])) + { + // printf("\n\n x=%f je izven mej tabele!",x); + return 1.0/zero; + } + + //poisce, katere tocke bo uporabil + m=0; while (x>xt[m++]); + m=m-4/2-1; if (m<0) m=0; if ((m+4)>(t-1)) m=t-4; + + for (i=0;i<4;i++) + p[i]=yt[i+m]; + + for (j=1;j<4;j++) + for (i=(4-1);i>=j;i--) + { + p[i]=p[i]+(x-xt[i+m])/(xt[i+m]-xt[i-j+m])*(p[i]-p[i-1]); + } + return p[4-1]; +} + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ + return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ + return (v-min)/(max-min); +} + +//*********************************************** +// OBVEZNE FREI0R FUNKCIJE + +//----------------------------------------------- +int f0r_init() +{ + return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + + info->name="alpha0ps"; + info->author="Marko Cebokli"; + info->plugin_type=F0R_PLUGIN_TYPE_FILTER; + info->color_model=F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version=FREI0R_MAJOR_VERSION; + info->major_version=0; + info->minor_version=4; + info->num_params=6; + info->explanation="Display and manipulation of the alpha channel"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + switch(param_index) + { + case 0: + info->name = "Display"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 1: + info->name = "Display input alpha"; + info->type = F0R_PARAM_BOOL; + info->explanation = ""; + break; + case 2: + info->name = "Operation"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 3: + info->name = "Threshold"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 4: + info->name = "Shrink/Grow/Blur amount"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 5: + info->name = "Invert"; + info->type = F0R_PARAM_BOOL; + info->explanation = ""; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + inst *in; + + in=calloc(1,sizeof(inst)); + in->w=width; + in->h=height; + + in->disp=0; + in->din=0; + in->op=0; + in->thr=0.5; + in->sga=1.0; + in->inv=0; + + in->f=0.05; in->q=0.55; //blur + calcab_lp1(in->f, in->q, &in->a0, &in->a1, &in->a2, &in->b0, &in->b1, &in->b2); + in->a1=in->a1/in->a0; in->a2=in->a2/in->a0; + rep(-0.5, 0.5, 0.0, &in->rd1, &in->rd2, 256, in->a1, in->a2); + rep(1.0, 1.0, 0.0, &in->rs1, &in->rs2, 256, in->a1, in->a2); + rep(0.0, 0.0, 1.0, &in->rc1, &in->rc2, 256, in->a1, in->a2); + + return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ + inst *in; + + in=(inst*)instance; + + free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ + inst *p; + double tmpf; + int tmpi,chg; + + p=(inst*)instance; + + float am1[]={0.499999,0.7,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0,15.0,20.0,30.0,40.0,50.0,70.0,100.0,150.0,200.00001}; + float iir2f[]={0.475,0.39,0.325,0.26,0.21,0.155,0.112,0.0905,0.065,0.0458,0.031,0.0234,0.01575,0.0118,0.0093,0.00725,0.00505,0.0033,0.0025}; + float iir2q[]={0.53,0.53,0.54,0.54,0.54,0.55,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6,0.6}; + + chg=0; + switch(param_index) + { + case 0: //Display + tmpi=map_value_forward(*((double*)parm), 0.0, 6.9999); + if (p->disp != tmpi) chg=1; + p->disp=tmpi; + break; + case 1: //Display input alpha + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->din != tmpi) chg=1; + p->din=tmpi; + break; + case 2: //Operation + tmpi=map_value_forward(*((double*)parm), 0.0, 7.9999); + if (p->op != tmpi) chg=1; + p->op=tmpi; + break; + case 3: //Threshold + tmpf=*(double*)parm; + if (tmpf!=p->thr) chg=1; + p->thr=tmpf; + break; + case 4: //Shrink/Grow/Blur amount + tmpf=map_value_forward(*((double*)parm), 0.0, 4.9999); + if (p->sga != tmpf) chg=1; + p->sga=tmpf; + break; + case 5: //Invert + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->inv != tmpi) chg=1; + p->inv=tmpi; + break; + } + + if (chg==0) return; + + if (param_index==4) // blur amount changed + { + p->f=AitNev3(19, am1, iir2f, 0.5+3.0*p->sga); + p->q=AitNev3(19, am1, iir2q, 0.5+3.0*p->sga); + calcab_lp1(p->f, p->q, &p->a0, &p->a1, &p->a2, &p->b0, &p->b1, &p->b2); + p->a1=p->a1/p->a0; p->a2=p->a2/p->a0; + rep(-0.5, 0.5, 0.0, &p->rd1, &p->rd2, 256, p->a1, p->a2); + rep(1.0, 1.0, 0.0, &p->rs1, &p->rs2, 256, p->a1, p->a2); + rep(0.0, 0.0, 1.0, &p->rc1, &p->rc2, 256, p->a1, p->a2); + } + +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + inst *p; + + p=(inst*)instance; + + switch(param_index) + { + case 0: + *((double*)param)=map_value_backward(p->disp, 0.0, 6.9999); + break; + case 1: + *((double*)param)=map_value_backward(p->din, 0.0, 1.0);//BOOL!! + break; + case 2: + *((double*)param)=map_value_backward(p->op, 0.0, 6.9999); + break; + case 3: + *((double*)param)=p->thr; + break; + case 4: + *((double*)param)=map_value_backward(p->sga, 0.0, 2.9999); + break; + case 5: + *((double*)param)=map_value_backward(p->inv, 0.0, 1.0);//BOOL!! + break; + } +} + +//------------------------------------------------- +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ + inst *in; + int i; + float *falpha, *ab; + uint8_t *infr, *oufr; + + assert(instance); + in=(inst*)instance; + infr=(uint8_t*)inframe; + oufr=(uint8_t*)outframe; + + falpha = calloc(in->w * in->h, sizeof(float)); + ab = calloc(in->w * in->h, sizeof(float)); + for (i=0;iw*in->h;i++) + falpha[i] = infr[4*i+3]; + + switch (in->op) + { + case 0: break; + case 1: + for (i=0;isga;i++) + shave_alpha(falpha, ab, in->w, in->h); + break; + case 2: + for (i=0;isga;i++) + shrink_alpha(falpha, ab, in->w, in->h, 0); + break; + case 3: + for (i=0;isga;i++) + shrink_alpha(falpha, ab, in->w, in->h, 1); + break; + case 4: + for (i=0;isga;i++) + grow_alpha(falpha, ab, in->w, in->h, 0); + break; + case 5: + for (i=0;isga;i++) + grow_alpha(falpha, ab, in->w, in->h, 1); + break; + case 6: + threshold_alpha(falpha, in->w, in->h, 255.0*in->thr, 255.0, 0.0); + break; + case 7: + blur_alpha(in, falpha); + break; + default: + break; + } + + if (in->inv==1) + for (i=0;iw*in->h;i++) + falpha[i] = 255.0 - falpha[i]; + + for (i=0;iw*in->h;i++) + { + outframe[i] = inframe[i]; + oufr[4*i+3] = (uint8_t) falpha[i]; + } + + switch (in->disp) + { + case 0: + break; + case 1: + alphagray(in, infr, oufr); + break; + case 2: + grayred(in, infr, oufr); + break; + case 3: + drawsel(in, infr, oufr, 0); + break; + case 4: + drawsel(in, infr, oufr, 1); + break; + case 5: + drawsel(in, infr, oufr, 2); + break; + case 6: + drawsel(in, infr, oufr, 3); + break; + default: + break; + } + free(falpha); + free(ab); +} + +//********************************************************** diff --git a/src/filter/alpha0ps/alpha0ps_alphagrad.c b/src/filter/alpha0ps/alpha0ps_alphagrad.c new file mode 100644 index 0000000..fff4b4f --- /dev/null +++ b/src/filter/alpha0ps/alpha0ps_alphagrad.c @@ -0,0 +1,336 @@ +/* +alphagrad.c + +This frei0r plugin fills alpha channel with a gradient +Version 0.1 aug 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +//compile: gcc -c -fPIC -Wall alphagrad.c -o alphagrad.o +//link: gcc -shared -o alphagrad.so alphagrad.o + +#include +#include +#include +#include +#include + + + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ +int h; +int w; + +float poz,wdt,tilt,min,max; +uint32_t *gr8; +int op; + +} inst; + +//----------------------------------------------------- +//RGBA8888 little endian +void fill_grad(inst *in) +{ +int i,j; +float st,ct,po,wd,d,a; + +st=sinf(in->tilt); +ct=cosf(in->tilt); +po=(-in->w/2.0+in->poz*in->w)*1.5; +wd=in->wdt*in->w; + +if (in->min==in->max) + { + for (i=0;ih*in->w;i++) + in->gr8[i]=(((uint32_t)(in->min*255.0))<<24)&0xFF000000; + return; + } + +for (i=0;ih;i++) + for (j=0;jw;j++) + { + d=(i-in->h/2)*ct+(j-in->w/2)*st-po; + if (fabsf(d)>wd/2.0) + { + if (d>0.0) + a=in->min; + else + a=in->max; + } + else + { + if (d>wd/2.0) d=wd/2.0; + a = in->min+(wd/2.0-d) / wd*(in->max-in->min); + } + a=255.0*a; + in->gr8[i*in->w+j] = (((uint32_t)a)<<24)&0xFF000000; + } +} + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ +return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ +return (v-min)/(max-min); +} + +//*********************************************** +// OBVEZNE FREI0R FUNKCIJE + +//----------------------------------------------- +int f0r_init() +{ +return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + +info->name="alphagrad"; +info->author="Marko Cebokli"; +info->plugin_type=F0R_PLUGIN_TYPE_FILTER; +info->color_model=F0R_COLOR_MODEL_RGBA8888; +info->frei0r_version=FREI0R_MAJOR_VERSION; +info->major_version=0; +info->minor_version=2; +info->num_params=6; +info->explanation="Fills alpha channel with a gradient"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ +switch(param_index) + { + case 0: + info->name = "Position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 1: + info->name = "Transition width"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 2: + info->name = "Tilt"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 3: + info->name = "Min"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 4: + info->name = "Max"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 5: + info->name = "Operation"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ +inst *in; + +in=calloc(1,sizeof(inst)); +in->w=width; +in->h=height; + +in->poz=0.5; +in->wdt=0.5; +in->tilt=0.0; +in->min=0.0; +in->max=1.0; +in->op=0; + +in->gr8 = (uint32_t*)calloc(in->w*in->h, sizeof(uint32_t)); + +fill_grad(in); + +return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ +inst *in; + +in=(inst*)instance; + +free(in->gr8); +free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ +inst *p; +double tmpf; +int tmpi,chg; + +p=(inst*)instance; + +chg=0; +switch(param_index) + { + case 0: + tmpf=*((double*)parm); + if (tmpf!=p->poz) chg=1; + p->poz=tmpf; + break; + case 1: + tmpf=*((double*)parm); + if (tmpf!=p->wdt) chg=1; + p->wdt=tmpf; + break; + case 2: + tmpf=map_value_forward(*((double*)parm), -3.15, 3.15); + if (tmpf!=p->tilt) chg=1; + p->tilt=tmpf; + break; + case 3: + tmpf=*((double*)parm); + if (tmpf!=p->min) chg=1; + p->min=tmpf; + break; + case 4: + tmpf=*((double*)parm); + if (tmpf!=p->max) chg=1; + p->max=tmpf; + break; + case 5: + tmpi=map_value_forward(*((double*)parm), 0.0, 4.9999); + if (p->op != tmpi) chg=1; + p->op=tmpi; + break; + } + +if (chg==0) return; + +fill_grad(p); +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ +inst *p; + +p=(inst*)instance; + +switch(param_index) + { + case 0: + *((double*)param)=p->poz; + break; + case 1: + *((double*)param)=p->wdt; + break; + case 2: + *((double*)param)=map_value_backward(p->tilt, -3.15, 3.15); + break; + case 3: + *((double*)param)=p->min; + break; + case 4: + *((double*)param)=p->max; + break; + case 5: + *((double*)param)=map_value_backward(p->op, 0.0, 4.9999); + break; + } +} + +//------------------------------------------------- +//RGBA8888 little endian +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ +inst *in; +int i; +uint32_t t; + +assert(instance); +in=(inst*)instance; + +switch (in->op) + { + case 0: //write on clear + for (i=0;ih*in->w;i++) + outframe[i] = (inframe[i]&0x00FFFFFF) | in->gr8[i]; + break; + case 1: //max + for (i=0;ih*in->w;i++) + { + t=((inframe[i]&0xFF000000)>in->gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; + outframe[i] = (inframe[i]&0x00FFFFFF) | t; + } + break; + case 2: //min + for (i=0;ih*in->w;i++) + { + t=((inframe[i]&0xFF000000)gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; + outframe[i] = (inframe[i]&0x00FFFFFF) | t; + } + break; + case 3: //add + for (i=0;ih*in->w;i++) + { + t=((inframe[i]&0xFF000000)>>1)+(in->gr8[i]>>1); + t = (t>0x7F800000) ? 0xFF000000 : t<<1; + outframe[i] = (inframe[i]&0x00FFFFFF) | t; + } + break; + case 4: //subtract + for (i=0;ih*in->w;i++) + { + t= ((inframe[i]&0xFF000000)>in->gr8[i]) ? (inframe[i]&0xFF000000)-in->gr8[i] : 0; + outframe[i] = (inframe[i]&0x00FFFFFF) | t; + } + break; + default: + break; + } +} + +//********************************************************** diff --git a/src/filter/alpha0ps/alpha0ps_alphaspot.c b/src/filter/alpha0ps/alpha0ps_alphaspot.c new file mode 100644 index 0000000..2bb8c5b --- /dev/null +++ b/src/filter/alpha0ps/alpha0ps_alphaspot.c @@ -0,0 +1,514 @@ +/* +alphaspot.c + +This frei0r plugin draws simple shapes into the alpha channel +Version 0.1 aug 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +//compile: gcc -c -fPIC -Wall alphaspot.c -o alphaspot.o +//link: gcc -shared -o alphaspot.so alphaspot.o + +//#include +#include +#include +#include +#include +#include +#include + + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ + int h; + int w; + + float pozx,pozy,sizx,sizy,wdt,tilt,min,max; + int shp,op; + + uint8_t *gr8; + +} inst; + + +//---------------------------------------------------------- +//general (rotated) rectangle with soft border +void gen_rec_s(uint8_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) +{ + int i,j; + float d1,d2,d,db,st,ct,g,is1,is2; + + if ((siz1 == 0.0f) || (siz2 == 0.0f)) return; + st = sinf(tilt); + ct = cosf(tilt); + is1 = 1.0f/siz1; + is2 = 1.0f/siz2; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + d1 = (i-pozy)*st+(j-pozx)*ct; + d2 = (i-pozy)*ct-(j-pozx)*st; + d1 = fabsf(d1)*is1; + d2 = fabsf(d2)*is2; + d = (d1 1.0f) { + g = min; + } else { + if (db <= 1.004f - wb) { + g = max; + } else { + g = min + (1.0f - wb-db)/wb*(max-min); + } + } + sl[i*w+j] = lrintf(g * 255.0f); + } + } +} + +//---------------------------------------------------------- +//general (rotated) ellipse with soft border +void gen_eli_s(uint8_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) +{ + int i,j; + float d1,d2,d,db,st,ct,is1,is2,g; + + if ((siz1 == 0.0f) || (siz2 == 0.0f)) return; + st = sinf(tilt); + ct = cosf(tilt); + is1 = 1.0f/siz1; + is2 = 1.0f/siz2; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + d1 = (i-pozy)*st+(j-pozx)*ct; + d2 = (i-pozy)*ct-(j-pozx)*st; + d = hypotf(d1*is1,d2*is2); + + db = d; //neenakomeren rob!!! + + if (d > 1.0f) { + g = min; + } else { + if (db <= 1.004f - wb) { + g = max; + } else { + g = min + (1.0f - wb-db)/wb*(max-min); + } + } + sl[i*w+j] = lrintf(g * 255.0f); + } + } +} + +//---------------------------------------------------------- +//general (rotated) triangle with soft border +void gen_tri_s(uint8_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) +{ + int i,j; + float d1,d2,d3,d4,d,st,ct,is1,is2,k5,lim,db,g; + + if ((siz1 == 0.0f) || (siz2 == 0.0f)) return; + st =sinf(tilt); + ct = cosf(tilt); + is1 = 1.0f/siz1; + is2 = 1.0f/siz2; + k5 = 1.0f/sqrtf(5.0f); + lim = 0.82f; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + d1 = (i-pozy)*st+(j-pozx)*ct; + d2 = (i-pozy)*ct-(j-pozx)*st; + d1 = d1*is1; + d2 = d2*is2; + d3 = (2.0f * d1+d2 + 1.0f)*k5; + d4 = (2.0f* d1-d2 - 1.0f)*k5; + d2 = fabsf(d2); + d3 = fabsf(d3); + d4 = fabsf(d4); + d = d2; + if (d3 > d) d=d3; + if (d4 > d) d=d4; + db = d; + + if (fabsf(d) > lim) { + g = min; + } else { + if (db <= 1.004f * lim-wb) { + g = max; + } else { + g = min + (lim-wb-db)/wb*(max-min); + } + } + sl[i*w+j] = lrintf(g * 255.0f); + } + } +} + +//---------------------------------------------------------- +//general (rotated) diamond shape with soft border +void gen_dia_s(uint8_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) +{ + int i,j; + float d1,d2,d,db,st,ct,is1,is2,g; + + if ((siz1 == 0.0f) || (siz2 == 0.0f)) return; + st = sinf(tilt); + ct = cosf(tilt); + is1 = 1.0f/siz1; + is2 = 1.0f/siz2; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + d1 = (i-pozy)*st+(j-pozx)*ct; + d2 = (i-pozy)*ct-(j-pozx)*st; + d = fabsf(d1*is1)+fabsf(d2*is2); + db = d; + if (fabsf(d) > 1.0f) { + g = min; + } else { + if (db <= 1.004f - wb) { + g = max; + } else { + g = min + (1.0f - wb-db)/wb*(max-min); + } + } + sl[i*w+j] = lrintf(g * 255.0f); + } + } +} + +//----------------------------------------------------- +void draw(inst *in) +{ + switch (in->shp) + { + case 0: + gen_rec_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); + break; + case 1: + gen_eli_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); + break; + case 2: + gen_tri_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); + break; + case 3: + gen_dia_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); + break; + default: + break; + } +} + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ + return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ + return (v-min)/(max-min); +} + +//*********************************************** +// MANDATORY FREI0R FUNCTIONS + +//----------------------------------------------- +int f0r_init() +{ + return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + + info->name = "alphaspot"; + info->author = "Marko Cebokli"; + info->plugin_type = F0R_PLUGIN_TYPE_FILTER; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 2; + info->num_params = 10; + info->explanation = "Draws simple shapes into the alpha channel"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + switch(param_index) { + case 0: + info->name = "Shape"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 1: + info->name = "Position X"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 2: + info->name = "Position Y"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 3: + info->name = "Size X"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 4: + info->name = "Size Y"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 5: + info->name = "Tilt"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 6: + info->name = "Transition width"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 7: + info->name = "Min"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 8: + info->name = "Max"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + case 9: + info->name = "Operation"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = ""; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + inst *in; + + in = calloc(1, sizeof(inst)); + in->w = width; + in->h = height; + + in->shp = 0; + in->pozx = 0.5f; + in->pozy = 0.5f; + in->sizx = 0.1f; + in->sizy = 0.1f; + in->wdt = 0.2f; + in->tilt = 0.0f; + in->min = 0.0f; + in->max = 1.0f; + in->op = 0; + + in->gr8 = calloc(in->w*in->h, sizeof(*in->gr8)); + + draw(in); + + return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ + inst *in; + + in = (inst*) instance; + + free(in->gr8); + free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ + inst *p; + double tmpf; + int tmpi,chg; + + p = (inst*) instance; + + chg = 0; + switch (param_index) { + case 0: + tmpi = map_value_forward(*((double*)parm), 0.0f, 3.9999f); + if (p->shp != tmpi) chg=1; + p->shp = tmpi; + break; + case 1: + tmpf = *(double*)parm; + if (tmpf != p->pozx) chg = 1; + p->pozx = tmpf; + break; + case 2: + tmpf = *(double*)parm; + if (tmpf != p->pozy) chg = 1; + p->pozy = tmpf; + break; + case 3: + tmpf = *(double*)parm; + if (tmpf != p->sizx) chg = 1; + p->sizx = tmpf; + break; + case 4: + tmpf = *(double*)parm; + if (tmpf != p->sizy) chg = 1; + p->sizy = tmpf; + break; + case 5: + tmpf = map_value_forward(*((double*)parm), -3.15f, 3.15f); + if (tmpf != p->tilt) chg = 1; + p->tilt = tmpf; + break; + case 6: + tmpf = *(double*)parm; + if (tmpf != p->wdt) chg = 1; + p->wdt = tmpf; + break; + case 7: + tmpf = *(double*)parm; + if (tmpf != p->min) chg = 1; + p->min = tmpf; + break; + case 8: + tmpf = *(double*)parm; + if (tmpf != p->max) chg = 1; + p->max = tmpf; + break; + case 9: + tmpi = map_value_forward(*((double*)parm), 0.0f, 4.9999f); + if (p->op != tmpi) chg = 1; + p->op = tmpi; + break; + } + + if (chg == 0) return; + + draw(p); + +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + inst *p; + + p=(inst*)instance; + + switch(param_index) { + case 0: + *((double*)param) = map_value_backward(p->shp, 0.0f, 3.9999f); + break; + case 1: + *((double*)param) = p->pozx; + break; + case 2: + *((double*)param) = p->pozy; + break; + case 3: + *((double*)param) = p->sizx; + break; + case 4: + *((double*)param) = p->sizy; + break; + case 5: + *((double*)param) = map_value_backward(p->tilt, -3.15f, 3.15f); + break; + case 6: + *((double*)param) = p->wdt; + break; + case 7: + *((double*)param) = p->min; + break; + case 8: + *((double*)param) = p->max; + break; + case 9: + *((double*)param) = map_value_backward(p->op, 0.0f, 4.9999f); + break; + } +} + +//------------------------------------------------- +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ + inst *in; + int i; + uint8_t *inp = (uint8_t*) inframe; + uint8_t *outp = (uint8_t*) outframe; + + assert(instance); + in = (inst*)instance; + memcpy(outframe, inframe, sizeof(*inframe) * in->w * in->h); + + switch (in->op) { + case 0: //write on clear + for (i = 0; i < in->h*in->w; i++) { + outp[4*i+3] = in->gr8[i]; + } + break; + case 1: //max + for (i = 0; i < in->h*in->w; i++) { + outp[4*i+3] = (inp[4*i+3] > in->gr8[i]) ? inp[4*i+3] : in->gr8[i]; + } + break; + case 2: //min + for (i = 0; i < in->h*in->w; i++) { + outp[4*i+3] = (inp[4*i+3] < in->gr8[i]) ? inp[4*i+3] : in->gr8[i]; + } + break; + case 3: //add + for (i = 0;i < in->h*in->w; i++) { + outp[4*i+3] = MAX255(inp[4*i+3] + in->gr8[i]); + } + break; + case 4: //subtract + for (i = 0; i < in->h*in->w; i++) { + outp[4*i+3] = (inp[4*i+3] > in->gr8[i]) ? inp[4*i+3] - in->gr8[i] : 0; + } + break; + default: + break; + } +} diff --git a/src/filter/alpha0ps/alphagrad.c b/src/filter/alpha0ps/alphagrad.c deleted file mode 100644 index fff4b4f..0000000 --- a/src/filter/alpha0ps/alphagrad.c +++ /dev/null @@ -1,336 +0,0 @@ -/* -alphagrad.c - -This frei0r plugin fills alpha channel with a gradient -Version 0.1 aug 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -//compile: gcc -c -fPIC -Wall alphagrad.c -o alphagrad.o -//link: gcc -shared -o alphagrad.so alphagrad.o - -#include -#include -#include -#include -#include - - - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ -int h; -int w; - -float poz,wdt,tilt,min,max; -uint32_t *gr8; -int op; - -} inst; - -//----------------------------------------------------- -//RGBA8888 little endian -void fill_grad(inst *in) -{ -int i,j; -float st,ct,po,wd,d,a; - -st=sinf(in->tilt); -ct=cosf(in->tilt); -po=(-in->w/2.0+in->poz*in->w)*1.5; -wd=in->wdt*in->w; - -if (in->min==in->max) - { - for (i=0;ih*in->w;i++) - in->gr8[i]=(((uint32_t)(in->min*255.0))<<24)&0xFF000000; - return; - } - -for (i=0;ih;i++) - for (j=0;jw;j++) - { - d=(i-in->h/2)*ct+(j-in->w/2)*st-po; - if (fabsf(d)>wd/2.0) - { - if (d>0.0) - a=in->min; - else - a=in->max; - } - else - { - if (d>wd/2.0) d=wd/2.0; - a = in->min+(wd/2.0-d) / wd*(in->max-in->min); - } - a=255.0*a; - in->gr8[i*in->w+j] = (((uint32_t)a)<<24)&0xFF000000; - } -} - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ -return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ -return (v-min)/(max-min); -} - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ -return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - -info->name="alphagrad"; -info->author="Marko Cebokli"; -info->plugin_type=F0R_PLUGIN_TYPE_FILTER; -info->color_model=F0R_COLOR_MODEL_RGBA8888; -info->frei0r_version=FREI0R_MAJOR_VERSION; -info->major_version=0; -info->minor_version=2; -info->num_params=6; -info->explanation="Fills alpha channel with a gradient"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ -switch(param_index) - { - case 0: - info->name = "Position"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 1: - info->name = "Transition width"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 2: - info->name = "Tilt"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 3: - info->name = "Min"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 4: - info->name = "Max"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 5: - info->name = "Operation"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ -inst *in; - -in=calloc(1,sizeof(inst)); -in->w=width; -in->h=height; - -in->poz=0.5; -in->wdt=0.5; -in->tilt=0.0; -in->min=0.0; -in->max=1.0; -in->op=0; - -in->gr8 = (uint32_t*)calloc(in->w*in->h, sizeof(uint32_t)); - -fill_grad(in); - -return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ -inst *in; - -in=(inst*)instance; - -free(in->gr8); -free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ -inst *p; -double tmpf; -int tmpi,chg; - -p=(inst*)instance; - -chg=0; -switch(param_index) - { - case 0: - tmpf=*((double*)parm); - if (tmpf!=p->poz) chg=1; - p->poz=tmpf; - break; - case 1: - tmpf=*((double*)parm); - if (tmpf!=p->wdt) chg=1; - p->wdt=tmpf; - break; - case 2: - tmpf=map_value_forward(*((double*)parm), -3.15, 3.15); - if (tmpf!=p->tilt) chg=1; - p->tilt=tmpf; - break; - case 3: - tmpf=*((double*)parm); - if (tmpf!=p->min) chg=1; - p->min=tmpf; - break; - case 4: - tmpf=*((double*)parm); - if (tmpf!=p->max) chg=1; - p->max=tmpf; - break; - case 5: - tmpi=map_value_forward(*((double*)parm), 0.0, 4.9999); - if (p->op != tmpi) chg=1; - p->op=tmpi; - break; - } - -if (chg==0) return; - -fill_grad(p); -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ -inst *p; - -p=(inst*)instance; - -switch(param_index) - { - case 0: - *((double*)param)=p->poz; - break; - case 1: - *((double*)param)=p->wdt; - break; - case 2: - *((double*)param)=map_value_backward(p->tilt, -3.15, 3.15); - break; - case 3: - *((double*)param)=p->min; - break; - case 4: - *((double*)param)=p->max; - break; - case 5: - *((double*)param)=map_value_backward(p->op, 0.0, 4.9999); - break; - } -} - -//------------------------------------------------- -//RGBA8888 little endian -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ -inst *in; -int i; -uint32_t t; - -assert(instance); -in=(inst*)instance; - -switch (in->op) - { - case 0: //write on clear - for (i=0;ih*in->w;i++) - outframe[i] = (inframe[i]&0x00FFFFFF) | in->gr8[i]; - break; - case 1: //max - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)>in->gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 2: //min - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 3: //add - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)>>1)+(in->gr8[i]>>1); - t = (t>0x7F800000) ? 0xFF000000 : t<<1; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 4: //subtract - for (i=0;ih*in->w;i++) - { - t= ((inframe[i]&0xFF000000)>in->gr8[i]) ? (inframe[i]&0xFF000000)-in->gr8[i] : 0; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - default: - break; - } -} - -//********************************************************** diff --git a/src/filter/alpha0ps/alphaspot.c b/src/filter/alpha0ps/alphaspot.c deleted file mode 100644 index d237592..0000000 --- a/src/filter/alpha0ps/alphaspot.c +++ /dev/null @@ -1,538 +0,0 @@ -/* -alphaspot.c - -This frei0r plugin draws simple shapes into the alpha channel -Version 0.1 aug 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -//compile: gcc -c -fPIC -Wall alphaspot.c -o alphaspot.o -//link: gcc -shared -o alphaspot.so alphaspot.o - -//#include -#include -#include -#include -#include - - - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ -int h; -int w; - -float pozx,pozy,sizx,sizy,wdt,tilt,min,max; -int shp,op; - -uint32_t *gr8; - -} inst; - - -//---------------------------------------------------------- -//general (rotated) rectangle with soft border -void gen_rec_s(uint32_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) -{ -int i,j; -float d1,d2,d,db,st,ct,g,is1,is2; - -if ((siz1==0.0)||(siz2==0.0)) return; -st=sinf(tilt); -ct=cosf(tilt); -is1=1.0/siz1; -is2=1.0/siz2; - -for (i=0;i1.0) - g=min; - else - { - if (db<=1.004-wb) - g=max; - else - { - g=min+(1.0-wb-db)/wb*(max-min); - } - } - g=g*255.0; - sl[i*w+j] = (((uint32_t)g)<<24)&0xFF000000; - } -} - -//---------------------------------------------------------- -//general (rotated) ellipse with soft border -void gen_eli_s(uint32_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) -{ -int i,j; -float d1,d2,d,db,st,ct,is1,is2,g,wbb; - -if ((siz1==0.0)||(siz2==0.0)) return; -st=sinf(tilt); -ct=cosf(tilt); -is1=1.0/siz1; -is2=1.0/siz2; -wbb=wb; - -for (i=0;i1.0) - g=min; - else - { - if (db<=1.004-wb) - g=max; - else - { - g=min+(1.0-wb-db)/wb*(max-min); - } - } - g=g*255.0; - sl[i*w+j] = (((uint32_t)g)<<24)&0xFF000000; - } -} - -//---------------------------------------------------------- -//general (rotated) triangle with soft border -void gen_tri_s(uint32_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) -{ -int i,j; -float d1,d2,d3,d4,d,st,ct,is1,is2,k5,lim,db,g; - -if ((siz1==0.0)||(siz2==0.0)) return; -st=sinf(tilt); -ct=cosf(tilt); -is1=1.0/siz1; -is2=1.0/siz2; -k5=1.0/sqrtf(5.0); -lim=0.82; - -for (i=0;id) d=d3; - if (d4>d) d=d4; - db=d; - - if (fabsf(d)>lim) - g=min; - else - { - if (db<=1.004*lim-wb) - g=max; - else - { - g=min+(lim-wb-db)/wb*(max-min); - } - } - g=g*255.0; - sl[i*w+j] = (((uint32_t)g)<<24)&0xFF000000; - } -} - -//---------------------------------------------------------- -//general (rotated) diamond shape with soft border -void gen_dia_s(uint32_t* sl, int w, int h, float siz1, float siz2, float tilt, float pozx, float pozy, float min, float max, float wb) -{ -int i,j; -float d1,d2,d,db,st,ct,is1,is2,g; - -if ((siz1==0.0)||(siz2==0.0)) return; -st=sinf(tilt); -ct=cosf(tilt); -is1=1.0/siz1; -is2=1.0/siz2; - -for (i=0;i1.0) - g=min; - else - { - if (db<=1.004-wb) - g=max; - else - { - g=min+(1.0-wb-db)/wb*(max-min); - } - } - g=g*255.0; - sl[i*w+j] = (((uint32_t)g)<<24)&0xFF000000; - } -} - -//----------------------------------------------------- -void draw(inst *in) -{ -switch (in->shp) - { - case 0: - gen_rec_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); - break; - case 1: - gen_eli_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); - break; - case 2: - gen_tri_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); - break; - case 3: - gen_dia_s(in->gr8, in->w, in->h, in->sizx*in->w, in->sizy*in->h, in->tilt, in->pozx*in->w, in->pozy*in->h, in->min, in->max, in->wdt); - break; - default: - break; - } -} - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ -return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ -return (v-min)/(max-min); -} - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ -return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - -info->name="alphaspot"; -info->author="Marko Cebokli"; -info->plugin_type=F0R_PLUGIN_TYPE_FILTER; -info->color_model=F0R_COLOR_MODEL_RGBA8888; -info->frei0r_version=FREI0R_MAJOR_VERSION; -info->major_version=0; -info->minor_version=1; -info->num_params=10; -info->explanation="Draws simple shapes into the alpha channel"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ -switch(param_index) - { - case 0: - info->name = "Shape"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 1: - info->name = "Position X"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 2: - info->name = "Position Y"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 3: - info->name = "Size X"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 4: - info->name = "Size Y"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 5: - info->name = "Tilt"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 6: - info->name = "Transition width"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 7: - info->name = "Min"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 8: - info->name = "Max"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - case 9: - info->name = "Operation"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = ""; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ -inst *in; - -in=calloc(1,sizeof(inst)); -in->w=width; -in->h=height; - -in->shp=0; -in->pozx=0.5; -in->pozy=0.5; -in->sizx=0.1; -in->sizy=0.1; -in->wdt=0.2; -in->tilt=0.0; -in->min=0.0; -in->max=1.0; -in->op=0; - -in->gr8 = (uint32_t*)calloc(in->w*in->h, sizeof(uint32_t)); - -draw(in); - -return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ -inst *in; - -in=(inst*)instance; - -free(in->gr8); -free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ -inst *p; -double tmpf; -int tmpi,chg; - -p=(inst*)instance; - -chg=0; -switch(param_index) - { - case 0: - tmpi=map_value_forward(*((double*)parm), 0.0, 3.9999); - if (p->shp != tmpi) chg=1; - p->shp=tmpi; - break; - case 1: - tmpf=*(double*)parm; - if (tmpf!=p->pozx) chg=1; - p->pozx=tmpf; - break; - case 2: - tmpf=*(double*)parm; - if (tmpf!=p->pozy) chg=1; - p->pozy=tmpf; - break; - case 3: - tmpf=*(double*)parm; - if (tmpf!=p->sizx) chg=1; - p->sizx=tmpf; - break; - case 4: - tmpf=*(double*)parm; - if (tmpf!=p->sizy) chg=1; - p->sizy=tmpf; - break; - case 5: - tmpf=map_value_forward(*((double*)parm), -3.15, 3.15); - if (tmpf!=p->tilt) chg=1; - p->tilt=tmpf; - break; - case 6: - tmpf=*(double*)parm; - if (tmpf!=p->wdt) chg=1; - p->wdt=tmpf; - break; - case 7: - tmpf=*(double*)parm; - if (tmpf!=p->min) chg=1; - p->min=tmpf; - break; - case 8: - tmpf=*(double*)parm; - if (tmpf!=p->max) chg=1; - p->max=tmpf; - break; - case 9: - tmpi=map_value_forward(*((double*)parm), 0.0, 4.9999); - if (p->op != tmpi) chg=1; - p->op=tmpi; - break; - } - -if (chg==0) return; - -draw(p); - -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ -inst *p; - -p=(inst*)instance; - -switch(param_index) - { - case 0: - *((double*)param)=map_value_backward(p->shp, 0.0, 3.9999); - break; - case 1: - *((double*)param)=p->pozx; - break; - case 2: - *((double*)param)=p->pozy; - break; - case 3: - *((double*)param)=p->sizx; - break; - case 4: - *((double*)param)=p->sizy; - break; - case 5: - *((double*)param)=map_value_backward(p->tilt, -3.15, 3.15); - break; - case 6: - *((double*)param)=p->wdt; - break; - case 7: - *((double*)param)=p->min; - break; - case 8: - *((double*)param)=p->max; - break; - case 9: - *((double*)param)=map_value_backward(p->op, 0.0, 4.9999); - break; - } -} - -//------------------------------------------------- -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ -inst *in; -int i; -uint32_t t; - -assert(instance); -in=(inst*)instance; - -switch (in->op) - { - case 0: //write on clear - for (i=0;ih*in->w;i++) - outframe[i] = (inframe[i]&0x00FFFFFF) | in->gr8[i]; - break; - case 1: //max - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)>in->gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 2: //min - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)gr8[i]) ? inframe[i]&0xFF000000 : in->gr8[i]; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 3: //add - for (i=0;ih*in->w;i++) - { - t=((inframe[i]&0xFF000000)>>1)+(in->gr8[i]>>1); - t = (t>0x7F800000) ? 0xFF000000 : t<<1; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - case 4: //subtract - for (i=0;ih*in->w;i++) - { - t= ((inframe[i]&0xFF000000)>in->gr8[i]) ? (inframe[i]&0xFF000000)-in->gr8[i] : 0; - outframe[i] = (inframe[i]&0x00FFFFFF) | t; - } - break; - default: - break; - } -} - -//********************************************************** diff --git a/src/filter/balanc0r/CMakeLists.txt b/src/filter/balanc0r/CMakeLists.txt index 3036124..7d1df11 100644 --- a/src/filter/balanc0r/CMakeLists.txt +++ b/src/filter/balanc0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET balanc0r) if (MSVC) - set_source_files_properties (balanc0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/bgsubtract0r/CMakeLists.txt b/src/filter/bgsubtract0r/CMakeLists.txt index 2a9979f..1aefb27 100644 --- a/src/filter/bgsubtract0r/CMakeLists.txt +++ b/src/filter/bgsubtract0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET bgsubtract0r) if (MSVC) - set_source_files_properties (bgsubtract0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/blur/CMakeLists.txt b/src/filter/blur/CMakeLists.txt index d1fd4b7..dd30e7e 100644 --- a/src/filter/blur/CMakeLists.txt +++ b/src/filter/blur/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET IIRblur) if (MSVC) - set_source_files_properties (IIRblur.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/blur/IIRblur.c b/src/filter/blur/IIRblur.c index 8cd544a..4eb9055 100644 --- a/src/filter/blur/IIRblur.c +++ b/src/filter/blur/IIRblur.c @@ -80,11 +80,12 @@ { float p[10]; int i,j,m; + float zero = 0.0f; // MSVC doesn't allow division through a zero literal, but allows it through non-const variable set to zero if ((xxt[t-1])) { // printf("\n\n x=%f je izven mej tabele!",x); - return 1.0/0.0; + return 1.0/zero; } //poisce, katere tocke bo uporabil diff --git a/src/filter/brightness/CMakeLists.txt b/src/filter/brightness/CMakeLists.txt index cacfcaa..7ec4c88 100644 --- a/src/filter/brightness/CMakeLists.txt +++ b/src/filter/brightness/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET brightness) if (MSVC) - set_source_files_properties (brightness.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/bw0r/CMakeLists.txt b/src/filter/bw0r/CMakeLists.txt index 7ad040e..e97b34b 100644 --- a/src/filter/bw0r/CMakeLists.txt +++ b/src/filter/bw0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET bw0r) if (MSVC) - set_source_files_properties (bw0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/c0rners/CMakeLists.txt b/src/filter/c0rners/CMakeLists.txt index fba422d..0ec0abe 100644 --- a/src/filter/c0rners/CMakeLists.txt +++ b/src/filter/c0rners/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET c0rners) if (MSVC) - set_source_files_properties (c0rners.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/c0rners/interp.h b/src/filter/c0rners/interp.h index 7db495b..3777ddc 100644 --- a/src/filter/c0rners/interp.h +++ b/src/filter/c0rners/interp.h @@ -107,11 +107,6 @@ //************************************** //HERE BEGIN THE INTERPOLATION FUNCTIONS -#if defined(_MSC_VER) -__inline const float roundf(float x){ - return (int)floor(x+0.5); -} -#endif /* _MSC_VER */ //------------------------------------------------------ //za debugging - z izpisovanjem diff --git a/src/filter/cairogradient/CMakeLists.txt b/src/filter/cairogradient/CMakeLists.txt index 119ef17..77a4dfd 100644 --- a/src/filter/cairogradient/CMakeLists.txt +++ b/src/filter/cairogradient/CMakeLists.txt @@ -5,7 +5,6 @@ set(LIBS ${LIBS} ${Cairo_LIBRARY}) if (MSVC) - set_source_files_properties (cairogradient.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/cairogradient/cairogradient.c b/src/filter/cairogradient/cairogradient.c index ffa3820..9e10428 100644 --- a/src/filter/cairogradient/cairogradient.c +++ b/src/filter/cairogradient/cairogradient.c @@ -333,6 +333,9 @@ unsigned char* src = (unsigned char*)inframe; int pixels = inst->width * inst->height; + // Clear the destination + memset(dst, 0, pixels * sizeof(uint32_t)); + frei0r_cairo_premultiply_rgba (src, pixels, -1); draw_gradient(inst, dst, src, time); frei0r_cairo_unpremultiply_rgba (dst, pixels); diff --git a/src/filter/cairoimagegrid/CMakeLists.txt b/src/filter/cairoimagegrid/CMakeLists.txt index 6e6b729..52045ff 100644 --- a/src/filter/cairoimagegrid/CMakeLists.txt +++ b/src/filter/cairoimagegrid/CMakeLists.txt @@ -5,7 +5,6 @@ set(LIBS ${LIBS} ${Cairo_LIBRARY}) if (MSVC) - set_source_files_properties (cairoimagegrid.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/cluster/CMakeLists.txt b/src/filter/cluster/CMakeLists.txt index e335568..8ff0bd1 100644 --- a/src/filter/cluster/CMakeLists.txt +++ b/src/filter/cluster/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET cluster) if (MSVC) - set_source_files_properties (cluster.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/colgate/CMakeLists.txt b/src/filter/colgate/CMakeLists.txt index b2575dc..76c6202 100644 --- a/src/filter/colgate/CMakeLists.txt +++ b/src/filter/colgate/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET colgate) if (MSVC) - set_source_files_properties (colgate.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/coloradj/CMakeLists.txt b/src/filter/coloradj/CMakeLists.txt index 0a2398c..d4d519e 100644 --- a/src/filter/coloradj/CMakeLists.txt +++ b/src/filter/coloradj/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET coloradj_RGB) if (MSVC) - set_source_files_properties (coloradj_RGB.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/colordistance/CMakeLists.txt b/src/filter/colordistance/CMakeLists.txt index 6ab5bfc..f109eb4 100644 --- a/src/filter/colordistance/CMakeLists.txt +++ b/src/filter/colordistance/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET colordistance) if (MSVC) - set_source_files_properties (colordistance.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/colordistance/colordistance.c b/src/filter/colordistance/colordistance.c index 4dbcbcb..6c68ff3 100644 --- a/src/filter/colordistance/colordistance.c +++ b/src/filter/colordistance/colordistance.c @@ -109,12 +109,6 @@ } -#if defined(_MSC_VER) -__inline const int rint(float x){ - return (int)(x+0.5); -} -#endif - void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) { diff --git a/src/filter/colorhalftone/CMakeLists.txt b/src/filter/colorhalftone/CMakeLists.txt index 0d1d84f..599fdc6 100644 --- a/src/filter/colorhalftone/CMakeLists.txt +++ b/src/filter/colorhalftone/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET colorhalftone) if (MSVC) - set_source_files_properties (colorhalftone.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/colorize/CMakeLists.txt b/src/filter/colorize/CMakeLists.txt index 11115e0..2333a6c 100644 --- a/src/filter/colorize/CMakeLists.txt +++ b/src/filter/colorize/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET colorize) if (MSVC) - set_source_files_properties (colorize.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/colortap/CMakeLists.txt b/src/filter/colortap/CMakeLists.txt index dad252c..02d42aa 100644 --- a/src/filter/colortap/CMakeLists.txt +++ b/src/filter/colortap/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET colortap) if (MSVC) - set_source_files_properties (colortap.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/colortap/colortap.c b/src/filter/colortap/colortap.c index 41e70d1..3ffaf63 100644 --- a/src/filter/colortap/colortap.c +++ b/src/filter/colortap/colortap.c @@ -348,6 +348,8 @@ void f0r_destruct(f0r_instance_t instance) { + colortap_instance_t* inst = (colortap_instance_t*)instance; + free(inst->table); free(instance); } diff --git a/src/filter/contrast0r/CMakeLists.txt b/src/filter/contrast0r/CMakeLists.txt index 4df0d03..e4e3dc6 100644 --- a/src/filter/contrast0r/CMakeLists.txt +++ b/src/filter/contrast0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET contrast0r) if (MSVC) - set_source_files_properties (contrast0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/curves/CMakeLists.txt b/src/filter/curves/CMakeLists.txt index 6a71f7e..61eeb12 100644 --- a/src/filter/curves/CMakeLists.txt +++ b/src/filter/curves/CMakeLists.txt @@ -1,17 +1,11 @@ -# Set C99 flag for gcc -if (CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "-std=c99") -endif (CMAKE_COMPILER_IS_GNUCC) - set (SOURCES curves.c) set (TARGET curves) if (MSVC) - set_source_files_properties (curves.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) add_library (${TARGET} MODULE ${SOURCES}) -set_target_properties (${TARGET} PROPERTIES PREFIX "") +set_target_properties (${TARGET} PROPERTIES PREFIX "" C_STANDARD 99) install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/curves/curves.c b/src/filter/curves/curves.c index 56e4fb0..2e80a3a 100644 --- a/src/filter/curves/curves.c +++ b/src/filter/curves/curves.c @@ -234,7 +234,7 @@ case 5: info->name = "Bézier spline"; info->type = F0R_PARAM_STRING; - info->explanation = "Use cubic Bézier spline. Has to be a sorted list of points in the format \"handle1x;handle1y#pointx;pointy#handle2x;handle2y\"(pointx = in, pointy = out). Points are separated by a \"|\".The values can have \"double\" precision. x, y for points should be in the range 0-1. x,y for handles might also be out of this range."; + info->explanation = "Use cubic Bézier spline. Has to be a sorted list of points in the format 'handle1x;handle1y#pointx;pointy#handle2x;handle2y'(pointx = in, pointy = out). Points are separated by a '|'.The values can have 'double' precision. x, y for points should be in the range 0-1. x,y for handles might also be out of this range."; default: if (param_index > 5) { info->name = get_param_name(param_index - 6); @@ -255,9 +255,9 @@ inst->pointNumber = 2; inst->formula = 1; inst->bspline = calloc(1, sizeof(char)); - inst->bsplineMap = malloc(sizeof(double)); - inst->csplineMap = malloc(sizeof(double)); - inst->curveMap = malloc(sizeof(float)); + inst->bsplineMap = NULL; + inst->csplineMap = NULL; + inst->curveMap = NULL; inst->points[0] = 0; inst->points[1] = 0; inst->points[2] = 1; @@ -273,12 +273,12 @@ void f0r_destruct(f0r_instance_t instance) { - if (((curves_instance_t*)instance)->bspline) - free(((curves_instance_t*)instance)->bspline); - free(((curves_instance_t*)instance)->bsplineMap); - free(((curves_instance_t*)instance)->csplineMap); - free(((curves_instance_t*)instance)->curveMap); - free(instance); + curves_instance_t* inst = (curves_instance_t*)instance; + free(inst->bspline); + free(inst->bsplineMap); + free(inst->csplineMap); + free(inst->curveMap); + free(inst); } void f0r_set_param_value(f0r_instance_t instance, @@ -608,7 +608,7 @@ char **pointStr = calloc(1, sizeof(char *)); int count = tokenise(inst->bspline, "|", &pointStr); - bspline_point points[count]; + bspline_point *points = (bspline_point *) malloc(count * sizeof(bspline_point)); for (int i = 0; i < count; ++i) { char **positionsStr = calloc(1, sizeof(char *)); @@ -666,7 +666,7 @@ c = 1; } step = 1 / (double)c; - position curve[c]; + position *curve = (position *) malloc((c + 1) * sizeof(position)); while (t <= 1) { curve[pn++] = pointOnBezier(t, p); t += step; @@ -697,7 +697,11 @@ else inst->bsplineMap[j] = CLAMP0255(ROUND(y * 255)); } + + free(curve); } + + free(points); } /** @@ -755,9 +759,10 @@ } if (inst->drawCurves) { int scale = inst->height / 2; + free(inst->curveMap); inst->curveMap = malloc(scale * sizeof(float)); for(i = 0; i < scale; i++) - inst->curveMap[i] = spline((float)i / scale, points, (size_t)inst->pointNumber, coeffs) * scale; + inst->curveMap[i] = spline((double)i / scale, points, (size_t)inst->pointNumber, coeffs) * scale; } free(coeffs); @@ -770,6 +775,13 @@ assert(instance); curves_instance_t* inst = (curves_instance_t*)instance; unsigned int len = inst->width * inst->height; + + // test initalization c/b spline + double *splinemap = strlen(inst->bspline)>0 ? inst->bsplineMap : inst->csplineMap; + if(!splinemap) { + memcpy(outframe,inframe,inst->width * inst->height * 4); + return; + } unsigned char* dst = (unsigned char*)outframe; const unsigned char* src = (unsigned char*)inframe; diff --git a/src/filter/d90stairsteppingfix/d90stairsteppingfix.cpp b/src/filter/d90stairsteppingfix/d90stairsteppingfix.cpp index db916ea..1b44136 100644 --- a/src/filter/d90stairsteppingfix/d90stairsteppingfix.cpp +++ b/src/filter/d90stairsteppingfix/d90stairsteppingfix.cpp @@ -135,7 +135,7 @@ * and therefore get the number (line1+line2)/2, here 6.5. * This positions will later be used for interpolation. */ - float filled[newHeight]; + float *filled = (float *) malloc(newHeight * sizeof(float)); int count = 0; int index = 0; @@ -160,7 +160,7 @@ * Calculate scaling numbers to scale the full height matrix * with the slice lines down to the original height (720p). */ - float downScaling[height]; + float *downScaling = (float *) malloc(height * sizeof(float)); float scaleFactor = (float) newHeight/height; // printf("scale factor: %f\n", scaleFactor); @@ -184,6 +184,9 @@ m_mesh[i] = (1-offset)*filled[index] + offset*filled[index+1]; // printf("%f at %d with weights %f and %f\n", m_mesh[i], i, (1-offset)*downScaling[i], offset*downScaling[i+1]); } + + free(downScaling); + free(filled); } else { // Not a 720p file. diff --git a/src/filter/defish0r/CMakeLists.txt b/src/filter/defish0r/CMakeLists.txt index 6d426b9..adbdde4 100644 --- a/src/filter/defish0r/CMakeLists.txt +++ b/src/filter/defish0r/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET defish0r) if (MSVC) - set_source_files_properties (defish0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/defish0r/defish0r.c b/src/filter/defish0r/defish0r.c index 2d92962..e3060f3 100644 --- a/src/filter/defish0r/defish0r.c +++ b/src/filter/defish0r/defish0r.c @@ -37,6 +37,39 @@ double PI=3.14159265358979; +//add simplified 'Elestic Scale' to fix superview +float stretchWidth(int width, int widthCentre, float currentXPos, float stretchFactor) +{ + double ratio, lowerWeight = 0.0, higherWeight = 0.0, linearRatio; + unsigned int lengthSection; + float relativeXPos = 0.0f; + + //midline? + if (currentXPos < (float)widthCentre) + { + lengthSection = widthCentre - 1; + linearRatio = (double) ( currentXPos ) / lengthSection; + ratio = sin(linearRatio * PI - PI) * stretchFactor + linearRatio; + } + else + { + lengthSection = width - widthCentre - 1; + linearRatio = (double) ( currentXPos - widthCentre ) / lengthSection; + ratio = sin(linearRatio * PI) * stretchFactor + linearRatio; + } + ratio = ratio <= 0.0 ? 0.0 : ratio; + + relativeXPos = (float) ( ratio * lengthSection ); + + if (currentXPos < (float)widthCentre) + relativeXPos -= currentXPos; + else + relativeXPos -= ( currentXPos - widthCentre ); + + return relativeXPos; +} + + //--------------------------------------------------------- // r = 0...1 izhod = 0...maxr //ta funkcija da popacenje v odvisnosti od r @@ -48,7 +81,7 @@ switch (n) { case 0: //equidistant - ff=f*2.0/PI; + ff=f*2.0f/(float)PI; rr=tanf(r/ff); break; case 1: //ortographic @@ -59,15 +92,15 @@ rr=tanf(asinf(ff)); break; case 2: //equiarea - ff=r/2.0/f; - if (ff>1.0) - rr=-1.0; + ff=r/2.0f/f; + if (ff>1.0f) + rr=-1.0f; else - rr=tanf(2.0*asinf(r/2.0/f)); + rr=tanf(2.0f*asinf(r/2.0f/f)); break; case 3: //stereographic - ff=f*2.0/PI; - rr=tanf(2.0*atanf(r/2.0/ff)); + ff=f*2.0f/(float)PI; + rr=tanf(2.0f*atanf(r/2.0f/ff)); break; default: // printf("Neznana fishitvena funkcija %d\n",n); @@ -86,16 +119,16 @@ switch (n) { case 0: //equidistant - rr=f*2.0/PI*atanf(r*mr); + rr=f*2.0f/(float)PI*atanf(r*mr); break; case 1: //ortographic rr=f*sinf(atanf(r*mr)); break; case 2: //equiarea - rr=2.0*f*sinf(atanf(r*mr)/2.0); + rr=2.0f*f*sinf(atanf(r*mr)/2.0f); break; case 3: //stereographic - rr=f*4.0/PI*tanf(atanf(r*mr)/2.0); + rr=f*4.0f/(float)PI*tanf(atanf(r*mr)/2.0f); break; default: // printf("Neznana fishitvena funkcija %d\n",n); @@ -103,10 +136,6 @@ } return rr; } - -#if defined(_MSC_VER) -#define hypotf _hypotf -#endif //---------------------------------------------------------------- //nafila array map s polozaji pikslov @@ -119,26 +148,28 @@ //scal = scaling factor //pari, paro = pixel aspect ratio (input / output) //dx, dy offset on input (for non-cosited chroma subsampling) -void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map) +void fishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map + , float stretchFactor, float yScale) { float rmax,maxr,r,kot,x,y,imax; - int i,j,ww,wi2,hi2,wo2,ho2; + int i, j, ww; float ii,jj,sc; - - rmax=hypotf(ho/2.0,wo/2.0*paro); + int wiMid = wi/2; + int hiMid = hi/2; + + rmax=hypotf(ho/2.0f,wo/2.0f*paro); maxr=fish(n,1.0,f); - imax=hypotf(hi/2.0,wi/2.0*pari); + imax=hypotf(hi/2.0f,wi/2.0f*pari); sc=imax/maxr; //printf("Fishmap: F=%5.2f Rmax= %7.2f Maxr=%6.2f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal); - wi2=wi/2; hi2=hi/2; wo2=wo/2; ho2=ho/2; - for (i=0;i0)&(x<(wi-1))&(y>0)&(y<(hi-1))) { + if (stretchFactor != 0.0f) + x += stretchWidth(wo, wiMid, x, stretchFactor); //add stretch map[ww]=x+dx; map[ww+1]=y+dy; } @@ -165,8 +198,8 @@ } } } - -} +} + //---------------------------------------------------------------- //nafila array map s polozaji pikslov @@ -179,30 +212,35 @@ //scal = scaling factor //pari,paro = pixel aspect ratio (input / output) //dx, dy offset on input (for non-cosited chroma subsampling) -void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map) +//lbox = letterbox +//stretch = dymanic stretch, convert between 4:3 and 16:9 +//yScale = -0.5.. 0.5 change aspect ratio on y acess only +void defishmap(int wi, int hi, int wo, int ho, int n, float f, float scal, float pari, float paro, float dx, float dy, float *map + , int lbox, float stretchFactor, float yScale) { float rmax,maxr,r,kot,x,y,imax; - int i,j,ww,wi2,hi2,wo2,ho2; + int i,j,ww; float ii,jj,sc; - - rmax=hypotf(ho/2.0,wo/2.0*paro); + int wiMid = wi/2; + int hiMid = hi/2; + + rmax=hypotf(ho/2.0f,wo/2.0f*paro); maxr=fish(n,1.0,f); - imax=hypotf(hi/2.0,wi/2.0*pari); + imax=hypotf(hi/2.0f,wi/2.0f*pari); sc=imax/maxr; //printf("Defishmap: F=%f rmax= %f Maxr=%f sc=%6.2f scal=%6.2f\n",f,rmax,maxr,sc,scal); - wi2=wi/2; hi2=hi/2; wo2=wo/2; ho2=ho/2; - for (i=0;i0)&(x<(wi-1))&(y>0)&(y<(hi-1))) + x=wiMid+r*cosf(kot)/pari; + y=hiMid+r*sinf(kot); + + if ((x>0)&&(x<(wi-1))&&(y>0)&&(y<(hi-1))) { + if (stretchFactor != 0.0f) + x += stretchWidth(wi, wiMid, x, stretchFactor); //add stretch + map[ww]=x; map[ww+1]=y; } @@ -225,6 +267,38 @@ } } } + + //crop all 4 borders + if (lbox) + { //top/bottom + for (i = 0; i < hi; i++) + { + ww = 2 * (wi*i + wiMid); + if (map[ww] <= 0) + { + for (j = 0; j < wi; j++) + { //clear entire row + ww = 2 * (wi*i + j); + map[ww] = -1; + map[ww + 1] = -1; + } + } + } + //left/right + for (i = 0; i < wi; i++) + { + ww = 2 * (wi*hiMid +i); + if (map[ww] <= 0) + { + for (j = 0; j < hi; j++) + { //clear entire column + ww = 2 * (wi*j + i); + map[ww] = -1; + map[ww + 1] = -1; + } + } + } + } } //===================================================== @@ -237,6 +311,8 @@ //intp: 0..6 type of interpolator //aspt: 0..4 aspect type square, PAL, NTSC, HDV, manual //par: pixel aspect ratio +//lbox: 1=letterbox +//stretch 0..1 stretch video to fix superview distorsion typedef struct { int w; @@ -251,6 +327,9 @@ float mpar; float par; float *map; + int lbox; + float stretch; + float yScale; interpp interpol; } param; @@ -297,7 +376,7 @@ case 3: //manual dscal=p.mscale; break; } - defishmap(p.w ,p.h ,p.w ,p.h, p.type, p.f, dscal, p.par, p.par, 0.0, 0.0, p.map); + defishmap(p.w ,p.h ,p.w ,p.h, p.type, p.f, dscal, p.par, p.par, 0.0, 0.0, p.map, p.lbox, p.stretch, p.yScale); } else //fish { @@ -315,7 +394,7 @@ case 3: //manual fscal=1.0/p.mscale; break; } - fishmap(p.w, p.h, p.w ,p.h, p.type, p.f, fscal, p.par, p.par, 0.0, 0.0, p.map); + fishmap(p.w, p.h, p.w ,p.h, p.type, p.f, fscal, p.par, p.par, 0.0, 0.0, p.map, p.stretch, p.yScale); } } @@ -344,8 +423,8 @@ info->color_model=F0R_COLOR_MODEL_RGBA8888; info->frei0r_version=FREI0R_MAJOR_VERSION; info->major_version=0; - info->minor_version=3; - info->num_params=8; + info->minor_version=4; + info->num_params=11; info->explanation="Non rectilinear lens mappings"; } @@ -393,6 +472,21 @@ info->name = "Manual Aspect"; info->type = F0R_PARAM_DOUBLE; info->explanation = "Manual Pixel Aspect ratio"; + break; + case 8: + info->name = "Crop"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Straighten all edges of video frame"; + break; + case 9: + info->name = "Non-Linear scale"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Fix camera scaling between 4:3 and 16:9"; + break; + case 10: + info->name = "Y Scale"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Scale Y to affect aspect ratio"; break; } @@ -417,6 +511,9 @@ p->aspt=0; //square pixels p->par=1.0; //square pixels p->mpar=1.0; + p->lbox=0; //letterbox + p->stretch = 0.0f; //dynamic stretch + p->yScale = 1.0f; //seperate Y stretch p->map=(float*)calloc(1, sizeof(float)*(p->w*p->h*2+2)); p->interpol=set_intp(*p); @@ -577,6 +674,21 @@ tmpf=map_value_forward_log(*((double*)parm), 0.5, 2.0); if (p->mpar != tmpf) chg=1; p->mpar=tmpf; + break; + case 8: //letterbox + tmpi=(int)map_value_forward(*((double*)parm), 0.0f, 1.0f);//BOOL!! + if (p->lbox != tmpi) chg=1; + p->lbox=tmpi; + break; + case 9: //stretch + tmpf=map_value_forward(*((double*)parm), -0.2f, 0.2f); + if (p->stretch != tmpf) chg=1; + p->stretch=tmpf; + break; + case 10: //Y scale + tmpf=map_value_forward(*((double*)parm), 1.5f, 0.5f); + if (p->yScale != tmpf) chg=1; + p->yScale=tmpf; break; } @@ -633,6 +745,15 @@ case 7: //manual aspect *((double*)parm)=map_value_backward_log(p->mpar, 0.5, 2.0); break; + case 8: //letterbox + *((double*)parm)=map_value_backward((float)p->lbox, 0.0f, 1.0f); //BOOL!! + break; + case 9: //stretch/upscale fix + *((double*)parm)=map_value_backward_log(p->stretch, -0.2f, 0.2f); + break; + case 10: //Y scale + *((double*)parm)=map_value_backward(p->yScale, 1.5f, 0.5f); + break; } } diff --git a/src/filter/defish0r/interp.h b/src/filter/defish0r/interp.h index 6a44cce..b1234d0 100644 --- a/src/filter/defish0r/interp.h +++ b/src/filter/defish0r/interp.h @@ -107,7 +107,7 @@ //************************************** //HERE BEGIN THE INTERPOLATION FUNCTIONS -#if defined(_MSC_VER) +#if defined(_MSC_VER) && _MSC_VER < 1800 __inline const float roundf(float x){ return (int)floor(x+0.5); } @@ -162,14 +162,17 @@ // *v interpolirana vrednost int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, unsigned char *v) { -#ifdef TEST_XY_LIMITS - if ((x<0)||(x>w)||(y<0)||(y>h)) return -1; -#endif - - v[0]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w]; - v[1]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+1]; - v[2]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+2]; - v[3]=sl[(int)roundf(x)*4+(int)roundf(y)*4*w+3]; + //int index = (int)(x+0.5f)*4+(int)(y+0.5f)*4*w; //fast rounding + int index = (int)roundf(x)*4+(int)roundf(y)*4*w; //call once + +#ifdef TEST_XY_LIMITS + if ((x<0)||(x>w)||(y<0)||(y>h)) return -1; +#endif + + v[0]=sl[index]; + v[1]=sl[index+1]; + v[2]=sl[index+2]; + v[3]=sl[index+3]; return 0; } diff --git a/src/filter/delaygrab/delaygrab.cpp b/src/filter/delaygrab/delaygrab.cpp index fa24126..0c36c4c 100644 --- a/src/filter/delaygrab/delaygrab.cpp +++ b/src/filter/delaygrab/delaygrab.cpp @@ -131,7 +131,7 @@ } DelayGrab::~DelayGrab() { - if(delaymap) free(delaymap); + free(delaymap); free(imagequeue); } @@ -271,7 +271,7 @@ delaymapheight = (geo.h)/blocksize; delaymapsize = delaymapheight*delaymapwidth; - if(delaymap) { free(delaymap); delaymap = NULL; } + free(delaymap); delaymap = malloc(delaymapsize*4); createDelaymap(current_mode); diff --git a/src/filter/denoise/CMakeLists.txt b/src/filter/denoise/CMakeLists.txt index 090dbab..fe55ece 100644 --- a/src/filter/denoise/CMakeLists.txt +++ b/src/filter/denoise/CMakeLists.txt @@ -1,12 +1,13 @@ -set (SOURCES hqdn3d.c) -set (TARGET hqdn3d) +set (SOURCES denoise_hqdn3d.c) +set (TARGET denoise_hqdn3d) if (MSVC) - set_source_files_properties (hqdn3d.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/denoise/denoise_hqdn3d.c b/src/filter/denoise/denoise_hqdn3d.c new file mode 100644 index 0000000..83d2cc5 --- /dev/null +++ b/src/filter/denoise/denoise_hqdn3d.c @@ -0,0 +1,421 @@ +/* +hqdn3d.c + +This frei0r plugin is a port of Mplayer's hqdb3d denoiser +original by Daniel Moreno + +Version 0.1 nov 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +//compile: gcc -c -fPIC -Wall hqdn3d.c -o hqdn3d.o +//link: gcc -shared -o hqdn3d.so hqdn3d.o + +//#include +#include +#include +#include +#include +#include + +#define MIN_MATRIX_SIZE 3 +#define MAX_MATRIX_SIZE 63 + + +//---------------------------------------- +typedef struct { + int Coefs[4][512*16]; + unsigned int *Line; + unsigned short *Frame[3]; +}vf_priv_s; + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ +int h; +int w; + +double LumSpac,LumTmp; +vf_priv_s vps; + +unsigned char *Rplani,*Gplani,*Bplani,*Rplano,*Gplano,*Bplano; +} inst; + + +//======================================================== +//functions LowPassMul, deNoiseTemporal, deNoiseSpacial, +//deNoise and PrecalaCoefs are from Mplayer "hqdn3d" filter +//by Daniel Moreno + +static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){ +// int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF); + int dMul= PrevMul-CurrMul; + unsigned int d=((dMul+0x10007FF)>>12); + return CurrMul + Coef[d]; +} + +void deNoiseTemporal( + unsigned char *Frame, // mpi->planes[x] + unsigned char *FrameDest, // dmpi->planes[x] + unsigned short *FrameAnt, + int W, int H, int sStride, int dStride, + int *Temporal) +{ + long X, Y; + unsigned int PixelDst; + + for (Y = 0; Y < H; Y++){ + for (X = 0; X < W; X++){ + PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal); + FrameAnt[X] = ((PixelDst+0x1000007F)>>8); + FrameDest[X]= ((PixelDst+0x10007FFF)>>16); + } + Frame += sStride; + FrameDest += dStride; + FrameAnt += W; + } +} + +void deNoiseSpacial( + unsigned char *Frame, // mpi->planes[x] + unsigned char *FrameDest, // dmpi->planes[x] + unsigned int *LineAnt, // vf->priv->Line (width bytes) + int W, int H, int sStride, int dStride, + int *Horizontal, int *Vertical) +{ + long X, Y; + long sLineOffs = 0, dLineOffs = 0; + unsigned int PixelAnt; + unsigned int PixelDst; + + /* First pixel has no left nor top neighbor. */ + PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16; + FrameDest[0]= ((PixelDst+0x10007FFF)>>16); + + /* First line has no top neighbor, only left. */ + for (X = 1; X < W; X++){ + PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal); + FrameDest[X]= ((PixelDst+0x10007FFF)>>16); + } + + for (Y = 1; Y < H; Y++){ + unsigned int PixelAnt; + sLineOffs += sStride, dLineOffs += dStride; + /* First pixel on each line doesn't have previous pixel */ + PixelAnt = Frame[sLineOffs]<<16; + PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical); + FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16); + + for (X = 1; X < W; X++){ + unsigned int PixelDst; + /* The rest are normal */ + PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal); + PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical); + FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16); + } + } +} + +void deNoise(unsigned char *Frame, // mpi->planes[x] + unsigned char *FrameDest, // dmpi->planes[x] + unsigned int *LineAnt, // vf->priv->Line (width bytes) + unsigned short **FrameAntPtr, + int W, int H, int sStride, int dStride, + int *Horizontal, int *Vertical, int *Temporal) +{ + long X, Y; + long sLineOffs = 0, dLineOffs = 0; + unsigned int PixelAnt; + unsigned int PixelDst; + unsigned short* FrameAnt=(*FrameAntPtr); + + if(!FrameAnt){ + (*FrameAntPtr)=FrameAnt=malloc(W*H*sizeof(unsigned short)); + for (Y = 0; Y < H; Y++){ + unsigned short* dst=&FrameAnt[Y*W]; + unsigned char* src=Frame+Y*sStride; + for (X = 0; X < W; X++) dst[X]=src[X]<<8; + } + } + + if(!Horizontal[0] && !Vertical[0]){ + deNoiseTemporal(Frame, FrameDest, FrameAnt, + W, H, sStride, dStride, Temporal); + return; + } + if(!Temporal[0]){ + deNoiseSpacial(Frame, FrameDest, LineAnt, + W, H, sStride, dStride, Horizontal, Vertical); + return; + } + + /* First pixel has no left nor top neighbor. Only previous frame */ + LineAnt[0] = PixelAnt = Frame[0]<<16; + PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal); + FrameAnt[0] = ((PixelDst+0x1000007F)>>8); + FrameDest[0]= ((PixelDst+0x10007FFF)>>16); + + /* First line has no top neighbor. Only left one for each pixel and + * last frame */ + for (X = 1; X < W; X++){ + LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal); + PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal); + FrameAnt[X] = ((PixelDst+0x1000007F)>>8); + FrameDest[X]= ((PixelDst+0x10007FFF)>>16); + } + + for (Y = 1; Y < H; Y++){ + unsigned int PixelAnt; + unsigned short* LinePrev=&FrameAnt[Y*W]; + sLineOffs += sStride, dLineOffs += dStride; + /* First pixel on each line doesn't have previous pixel */ + PixelAnt = Frame[sLineOffs]<<16; + LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical); + PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal); + LinePrev[0] = ((PixelDst+0x1000007F)>>8); + FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16); + + for (X = 1; X < W; X++){ + unsigned int PixelDst; + /* The rest are normal */ + PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal); + LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical); + PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal); + LinePrev[X] = ((PixelDst+0x1000007F)>>8); + FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16); + } + } +} + +#define ABS(A) ( (A) > 0 ? (A) : -(A) ) + +static void PrecalcCoefs(int *Ct, double Dist25) +{ + int i; + double Gamma, Simil, C; + + Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001); + + for (i = -255*16; i <= 255*16; i++) + { + Simil = 1.0 - ABS(i) / (16*255.0); + C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0; + Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5); + } + + Ct[0] = (Dist25 != 0); +} + +//end of hqdn3d functions +//=============================================== + + + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ +return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ +return (v-min)/(max-min); +} + +//*********************************************** +// OBVEZNE FREI0R FUNKCIJE + +//----------------------------------------------- +int f0r_init() +{ +return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + +info->name="hqdn3d"; +info->author="Marko Cebokli, Daniel Moreno"; +info->plugin_type=F0R_PLUGIN_TYPE_FILTER; +info->color_model=F0R_COLOR_MODEL_RGBA8888; +info->frei0r_version=FREI0R_MAJOR_VERSION; +info->major_version=0; +info->minor_version=1; +info->num_params=2; +info->explanation="High quality 3D denoiser from Mplayer"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ +switch(param_index) + { + case 0: + info->name = "Spatial"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Amount of spatial filtering"; + break; + case 1: + info->name = "Temporal"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Amount of temporal filtering"; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ +inst *in; + +in=calloc(1,sizeof(inst)); +in->w=width; +in->h=height; + +in->LumSpac=4; +in->LumTmp=6; +in->vps.Line=calloc(width,sizeof(int)); +in->Rplani=calloc(width*height,sizeof(unsigned char)); +in->Gplani=calloc(width*height,sizeof(unsigned char)); +in->Bplani=calloc(width*height,sizeof(unsigned char)); +in->Rplano=calloc(width*height,sizeof(unsigned char)); +in->Gplano=calloc(width*height,sizeof(unsigned char)); +in->Bplano=calloc(width*height,sizeof(unsigned char)); + +PrecalcCoefs(in->vps.Coefs[0],in->LumSpac); +PrecalcCoefs(in->vps.Coefs[1],in->LumTmp); + +return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ +inst *in; + +in=(inst*)instance; + +free(in->vps.Line); +free(in->vps.Frame[0]); +free(in->vps.Frame[1]); +free(in->vps.Frame[2]); +free(in->Rplani); +free(in->Gplani); +free(in->Bplani); +free(in->Rplano); +free(in->Gplano); +free(in->Bplano); + +free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ +inst *p; +double tmpf; +int chg; + +p=(inst*)instance; + +chg=0; +switch(param_index) + { + case 0: + tmpf=map_value_forward(*((double*)parm), 0.0, 100.0); + if (tmpf!=p->LumSpac) chg=1; + p->LumSpac=tmpf; + break; + case 1: + tmpf=map_value_forward(*((double*)parm), 0.0, 100.0); + if (tmpf!=p->LumTmp) chg=1; + p->LumTmp=tmpf; + break; + } + +if (chg==0) return; + +PrecalcCoefs(p->vps.Coefs[0],p->LumSpac); +PrecalcCoefs(p->vps.Coefs[1],p->LumTmp); + +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ +inst *p; + +p=(inst*)instance; + +switch(param_index) + { + case 0: + *((double*)param)=map_value_backward(p->LumSpac, 0.0, 100.0);//BOOL!! + break; + case 1: + *((double*)param)=map_value_backward(p->LumTmp, 0.0, 100.0);//BOOL!! + break; + } +} + +//------------------------------------------------- +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ +inst *in; +int i; + +assert(instance); +in=(inst*)instance; + +//Frei0r works with packed color, Mplayer with planar color +//I decided to copy data rather than modify the hqdn3d functions +//this takes some time, but future inmprovements in hqdn3d +//functions can be simply copied here without modification + +for (i=0;i<(in->w*in->h);i++) //copy to planar + { + in->Rplani[i]=inframe[i]&255; + in->Gplani[i]=(inframe[i]>>8)&255; + in->Bplani[i]=(inframe[i]>>16)&255; + } + +deNoise(in->Rplani, in->Rplano, in->vps.Line, &in->vps.Frame[0], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); +deNoise(in->Gplani, in->Gplano, in->vps.Line, &in->vps.Frame[1], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); +deNoise(in->Bplani, in->Bplano, in->vps.Line, &in->vps.Frame[2], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); + +for (i=0;i<(in->w*in->h);i++) //copy to packed, preserve alpha + { + outframe[i]=((uint32_t)in->Rplano[i])|((uint32_t)in->Gplano[i]<<8)|((uint32_t)in->Bplano[i]<<16)|(inframe[i]&0xFF000000); + } + + +} + diff --git a/src/filter/denoise/hqdn3d.c b/src/filter/denoise/hqdn3d.c deleted file mode 100644 index 7a91044..0000000 --- a/src/filter/denoise/hqdn3d.c +++ /dev/null @@ -1,418 +0,0 @@ -/* -hqdn3d.c - -This frei0r plugin is a port of Mplayer's hqdb3d denoiser -original by Daniel Moreno - -Version 0.1 nov 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - - -//compile: gcc -c -fPIC -Wall hqdn3d.c -o hqdn3d.o -//link: gcc -shared -o hqdn3d.so hqdn3d.o - -//#include -#include -#include -#include -#include -#include - -#define MIN_MATRIX_SIZE 3 -#define MAX_MATRIX_SIZE 63 - - -//---------------------------------------- -typedef struct { - int Coefs[4][512*16]; - unsigned int *Line; - unsigned short *Frame[3]; -}vf_priv_s; - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ -int h; -int w; - -double LumSpac,LumTmp; -vf_priv_s vps; - -unsigned char *Rplani,*Gplani,*Bplani,*Rplano,*Gplano,*Bplano; -} inst; - - -//======================================================== -//functions LowPassMul, deNoiseTemporal, deNoiseSpacial, -//deNoise and PrecalaCoefs are from Mplayer "hqdn3d" filter -//by Daniel Moreno - -static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){ -// int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF); - int dMul= PrevMul-CurrMul; - unsigned int d=((dMul+0x10007FF)>>12); - return CurrMul + Coef[d]; -} - -void deNoiseTemporal( - unsigned char *Frame, // mpi->planes[x] - unsigned char *FrameDest, // dmpi->planes[x] - unsigned short *FrameAnt, - int W, int H, int sStride, int dStride, - int *Temporal) -{ - long X, Y; - unsigned int PixelDst; - - for (Y = 0; Y < H; Y++){ - for (X = 0; X < W; X++){ - PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal); - FrameAnt[X] = ((PixelDst+0x1000007F)>>8); - FrameDest[X]= ((PixelDst+0x10007FFF)>>16); - } - Frame += sStride; - FrameDest += dStride; - FrameAnt += W; - } -} - -void deNoiseSpacial( - unsigned char *Frame, // mpi->planes[x] - unsigned char *FrameDest, // dmpi->planes[x] - unsigned int *LineAnt, // vf->priv->Line (width bytes) - int W, int H, int sStride, int dStride, - int *Horizontal, int *Vertical) -{ - long X, Y; - long sLineOffs = 0, dLineOffs = 0; - unsigned int PixelAnt; - unsigned int PixelDst; - - /* First pixel has no left nor top neighbor. */ - PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16; - FrameDest[0]= ((PixelDst+0x10007FFF)>>16); - - /* First line has no top neighbor, only left. */ - for (X = 1; X < W; X++){ - PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal); - FrameDest[X]= ((PixelDst+0x10007FFF)>>16); - } - - for (Y = 1; Y < H; Y++){ - unsigned int PixelAnt; - sLineOffs += sStride, dLineOffs += dStride; - /* First pixel on each line doesn't have previous pixel */ - PixelAnt = Frame[sLineOffs]<<16; - PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical); - FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16); - - for (X = 1; X < W; X++){ - unsigned int PixelDst; - /* The rest are normal */ - PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal); - PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical); - FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16); - } - } -} - -void deNoise(unsigned char *Frame, // mpi->planes[x] - unsigned char *FrameDest, // dmpi->planes[x] - unsigned int *LineAnt, // vf->priv->Line (width bytes) - unsigned short **FrameAntPtr, - int W, int H, int sStride, int dStride, - int *Horizontal, int *Vertical, int *Temporal) -{ - long X, Y; - long sLineOffs = 0, dLineOffs = 0; - unsigned int PixelAnt; - unsigned int PixelDst; - unsigned short* FrameAnt=(*FrameAntPtr); - - if(!FrameAnt){ - (*FrameAntPtr)=FrameAnt=malloc(W*H*sizeof(unsigned short)); - for (Y = 0; Y < H; Y++){ - unsigned short* dst=&FrameAnt[Y*W]; - unsigned char* src=Frame+Y*sStride; - for (X = 0; X < W; X++) dst[X]=src[X]<<8; - } - } - - if(!Horizontal[0] && !Vertical[0]){ - deNoiseTemporal(Frame, FrameDest, FrameAnt, - W, H, sStride, dStride, Temporal); - return; - } - if(!Temporal[0]){ - deNoiseSpacial(Frame, FrameDest, LineAnt, - W, H, sStride, dStride, Horizontal, Vertical); - return; - } - - /* First pixel has no left nor top neighbor. Only previous frame */ - LineAnt[0] = PixelAnt = Frame[0]<<16; - PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal); - FrameAnt[0] = ((PixelDst+0x1000007F)>>8); - FrameDest[0]= ((PixelDst+0x10007FFF)>>16); - - /* First line has no top neighbor. Only left one for each pixel and - * last frame */ - for (X = 1; X < W; X++){ - LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal); - PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal); - FrameAnt[X] = ((PixelDst+0x1000007F)>>8); - FrameDest[X]= ((PixelDst+0x10007FFF)>>16); - } - - for (Y = 1; Y < H; Y++){ - unsigned int PixelAnt; - unsigned short* LinePrev=&FrameAnt[Y*W]; - sLineOffs += sStride, dLineOffs += dStride; - /* First pixel on each line doesn't have previous pixel */ - PixelAnt = Frame[sLineOffs]<<16; - LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical); - PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal); - LinePrev[0] = ((PixelDst+0x1000007F)>>8); - FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16); - - for (X = 1; X < W; X++){ - unsigned int PixelDst; - /* The rest are normal */ - PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal); - LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical); - PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal); - LinePrev[X] = ((PixelDst+0x1000007F)>>8); - FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16); - } - } -} - -#define ABS(A) ( (A) > 0 ? (A) : -(A) ) - -static void PrecalcCoefs(int *Ct, double Dist25) -{ - int i; - double Gamma, Simil, C; - - Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001); - - for (i = -255*16; i <= 255*16; i++) - { - Simil = 1.0 - ABS(i) / (16*255.0); - C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0; - Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5); - } - - Ct[0] = (Dist25 != 0); -} - -//end of hqdn3d functions -//=============================================== - - - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ -return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ -return (v-min)/(max-min); -} - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ -return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - -info->name="hqdn3d"; -info->author="Marko Cebokli, Daniel Moreno"; -info->plugin_type=F0R_PLUGIN_TYPE_FILTER; -info->color_model=F0R_COLOR_MODEL_RGBA8888; -info->frei0r_version=FREI0R_MAJOR_VERSION; -info->major_version=0; -info->minor_version=1; -info->num_params=2; -info->explanation="High quality 3D denoiser from Mplayer"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ -switch(param_index) - { - case 0: - info->name = "Spatial"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Amount of spatial filtering"; - break; - case 1: - info->name = "Temporal"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Amount of temporal filtering"; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ -inst *in; - -in=calloc(1,sizeof(inst)); -in->w=width; -in->h=height; - -in->LumSpac=4; -in->LumTmp=6; -in->vps.Line=calloc(width,sizeof(int)); -in->Rplani=calloc(width*height,sizeof(unsigned char)); -in->Gplani=calloc(width*height,sizeof(unsigned char)); -in->Bplani=calloc(width*height,sizeof(unsigned char)); -in->Rplano=calloc(width*height,sizeof(unsigned char)); -in->Gplano=calloc(width*height,sizeof(unsigned char)); -in->Bplano=calloc(width*height,sizeof(unsigned char)); - -PrecalcCoefs(in->vps.Coefs[0],in->LumSpac); -PrecalcCoefs(in->vps.Coefs[1],in->LumTmp); - -return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ -inst *in; - -in=(inst*)instance; - -free(in->vps.Line); -free(in->Rplani); -free(in->Gplani); -free(in->Bplani); -free(in->Rplano); -free(in->Gplano); -free(in->Bplano); - -free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ -inst *p; -double tmpf; -int chg; - -p=(inst*)instance; - -chg=0; -switch(param_index) - { - case 0: - tmpf=map_value_forward(*((double*)parm), 0.0, 100.0); - if (tmpf!=p->LumSpac) chg=1; - p->LumSpac=tmpf; - break; - case 1: - tmpf=map_value_forward(*((double*)parm), 0.0, 100.0); - if (tmpf!=p->LumTmp) chg=1; - p->LumTmp=tmpf; - break; - } - -if (chg==0) return; - -PrecalcCoefs(p->vps.Coefs[0],p->LumSpac); -PrecalcCoefs(p->vps.Coefs[1],p->LumTmp); - -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ -inst *p; - -p=(inst*)instance; - -switch(param_index) - { - case 0: - *((double*)param)=map_value_backward(p->LumSpac, 0.0, 100.0);//BOOL!! - break; - case 1: - *((double*)param)=map_value_backward(p->LumTmp, 0.0, 100.0);//BOOL!! - break; - } -} - -//------------------------------------------------- -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ -inst *in; -int i; - -assert(instance); -in=(inst*)instance; - -//Frei0r works with packed color, Mplayer with planar color -//I decided to copy data rather than modify the hqdn3d functions -//this takes some time, but future inmprovements in hqdn3d -//functions can be simply copied here without modification - -for (i=0;i<(in->w*in->h);i++) //copy to planar - { - in->Rplani[i]=inframe[i]&255; - in->Gplani[i]=(inframe[i]>>8)&255; - in->Bplani[i]=(inframe[i]>>16)&255; - } - -deNoise(in->Rplani, in->Rplano, in->vps.Line, &in->vps.Frame[0], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); -deNoise(in->Gplani, in->Gplano, in->vps.Line, &in->vps.Frame[1], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); -deNoise(in->Bplani, in->Bplano, in->vps.Line, &in->vps.Frame[2], in->w, in->h, in->w, in->w, in->vps.Coefs[0], in->vps.Coefs[0], in->vps.Coefs[1]); - -for (i=0;i<(in->w*in->h);i++) //copy to packed, preserve alpha - { - outframe[i]=((uint32_t)in->Rplano[i])|((uint32_t)in->Gplano[i]<<8)|((uint32_t)in->Bplano[i]<<16)|(inframe[i]&0xFF000000); - } - - -} - diff --git a/src/filter/distort0r/CMakeLists.txt b/src/filter/distort0r/CMakeLists.txt index 8210bd6..13d3f92 100644 --- a/src/filter/distort0r/CMakeLists.txt +++ b/src/filter/distort0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET distort0r) if (MSVC) - set_source_files_properties (distort0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/dither/CMakeLists.txt b/src/filter/dither/CMakeLists.txt index 6cbb21b..7ed7435 100644 --- a/src/filter/dither/CMakeLists.txt +++ b/src/filter/dither/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET dither) if (MSVC) - set_source_files_properties (dither.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/dither/dither.c b/src/filter/dither/dither.c index 13fac58..8d4aa18 100644 --- a/src/filter/dither/dither.c +++ b/src/filter/dither/dither.c @@ -253,7 +253,7 @@ // init look-ups int rows, cols; rows = cols = (int)sqrt(matrixLength); - int map[levels]; + int *map = (int *) malloc(levels * sizeof(int)); int i,v; for (i = 0; i < levels; i++) { @@ -297,6 +297,8 @@ *dst++ = *src++;//copy alpha } } -} - - + + free(map); +} + + diff --git a/src/filter/emboss/CMakeLists.txt b/src/filter/emboss/CMakeLists.txt index 5b64b31..39d589e 100644 --- a/src/filter/emboss/CMakeLists.txt +++ b/src/filter/emboss/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET emboss) if (MSVC) - set_source_files_properties (emboss.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/filmgrain/CMakeLists.txt b/src/filter/filmgrain/CMakeLists.txt new file mode 100644 index 0000000..f2f9e42 --- /dev/null +++ b/src/filter/filmgrain/CMakeLists.txt @@ -0,0 +1,11 @@ +set (SOURCES filmgrain.c) +set (TARGET filmgrain) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) +set_target_properties (${TARGET} PROPERTIES PREFIX "") + +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/filmgrain/filmgrain.c b/src/filter/filmgrain/filmgrain.c new file mode 100644 index 0000000..dc80989 --- /dev/null +++ b/src/filter/filmgrain/filmgrain.c @@ -0,0 +1,306 @@ +#include +#include "frei0r.h" +#include "frei0r_math.h" + + +typedef struct flimgrain_instance +{ + // image dimensions + int width; + int height; + + // parameters + double grain_amt; + double grain_r; + double grain_g; + double grain_b; + double blur_amt; + double dust_amt; + double flicker_amt; + +} filmgrain_instance_t; + + +// these functions are for the effect +static inline uint8_t random_range_uint8(uint8_t x) +{ + // never divide by zero + if(x < 1) + { + return 0; + } + return rand() % x; +} + +static inline uint32_t reduce_color_range(uint32_t color, uint8_t threshold, int flicker) +{ + return CLAMP0255(CLAMP(color, threshold >> 1, 255 - threshold) + flicker); +} + +#define DUST_RAND_LIMIT 1000000000 +static inline int big_rand() +{ + #if RAND_MAX > DUST_RAND_LIMIT + return rand() % DUST_RAND_LIMIT; + #else + return (rand() * (RAND_MAX + 1) + rand()) % DUST_RAND_LIMIT; + #endif +} + + +// these functions are for frei0r +// mostly copy/paste/slightly modified from the other frei0r effects +int f0r_init() +{ + return 1; +} + +void f0r_deinit() +{} + +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + info->name = "Film Grain"; + info->author = "esmane"; + info->explanation = "Adds film-like grain and softens the picture."; + info->plugin_type = F0R_PLUGIN_TYPE_FILTER; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 7; +} + +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + switch(param_index) + { + case 0: + info->name = "Grain Amount"; + info->explanation = "The intensity of the grain."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 1: + info->name = "Red Grain"; + info->explanation = "The percentage of grain applied to the red channel."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 2: + info->name = "Green Grain"; + info->explanation = "The percentage of grain applied to the green channel."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 3: + info->name = "Blue Grain"; + info->explanation = "The percentage of grain applied to the blue channel."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 4: + info->name = "Blur Amount"; + info->explanation = "The intensity of the blur."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 5: + info->name = "Dust Amount"; + info->explanation = "The amount of dust particles on the image."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 6: + info->name = "Flicker"; + info->explanation = "The amount of variation in brightness between frames."; + info->type = F0R_PARAM_DOUBLE; + break; + } +} + +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + filmgrain_instance_t* inst = (filmgrain_instance_t*)calloc(1, sizeof(*inst)); + + inst->width = width; + inst->height = height; + inst->grain_amt = 0.5; + inst->grain_r = 0.75; + inst->grain_g = 1.0; + inst->grain_b = 0.5; + inst->blur_amt = 0.5; + inst->dust_amt = 0.2; + inst->flicker_amt = 0.5; + + return (f0r_instance_t)inst; +} + +void f0r_destruct(f0r_instance_t instance) +{ + filmgrain_instance_t* inst = (filmgrain_instance_t*)instance; + free(instance); +} + + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + filmgrain_instance_t* inst = (filmgrain_instance_t*)instance; + switch(param_index) + { + case 0: + inst->grain_amt = *((double*)param); + break; + case 1: + inst->grain_r = *((double*)param); + break; + case 2: + inst->grain_g = *((double*)param); + break; + case 3: + inst->grain_b = *((double*)param); + break; + case 4: + inst->blur_amt = *((double*)param); + break; + case 5: + inst->dust_amt = *((double*)param); + break; + case 6: + inst->flicker_amt = *((double*)param); + break; + } +} + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + filmgrain_instance_t* inst = (filmgrain_instance_t*)instance; + switch(param_index) + { + case 0: + *((double*)param) = inst->grain_amt; + break; + case 1: + *((double*)param) = inst->grain_r; + break; + case 2: + *((double*)param) = inst->grain_g; + break; + case 3: + *((double*)param) = inst->grain_b; + break; + case 4: + *((double*)param) = inst->blur_amt; + break; + case 5: + *((double*)param) = inst->dust_amt; + break; + case 6: + *((double*)param) = inst->flicker_amt; + break; + } +} + + +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ + filmgrain_instance_t* inst = (filmgrain_instance_t*)instance; + uint32_t* buf = outframe; + + uint32_t r; + uint32_t g; + uint32_t b; + uint8_t grain; + uint8_t reduce_t = random_range_uint8(inst->flicker_amt * 5) + inst->grain_amt * 40; + int flicker = random_range_uint8(inst->flicker_amt * 8); + + if(rand() % 2) + { + flicker *= -1; + } + + // first grain + if(inst->blur_amt != 0.0) + { + // only need a buf if blur is > 0 + buf = (uint32_t*)calloc(inst->width * inst->height, sizeof(uint32_t)); + } + + for(unsigned int i = 0; i < inst->height * inst->width; i++) + { + // dust + if(big_rand() < inst->dust_amt * 1000) + { + if(rand() % 2 == 0) + { + r = 0; + g = 0; + b = 0; + } + else + { + r = 255; + g = 255; + b = 255; + } + } + else + { + // reducing the range of each color helps look more "filmish" + b = reduce_color_range((*(inframe + i) & 0x00FF0000) >> 16, reduce_t, flicker); + g = reduce_color_range((*(inframe + i) & 0x0000FF00) >> 8, reduce_t, flicker); + r = reduce_color_range( *(inframe + i) & 0x000000FF , reduce_t, flicker); + + grain = random_range_uint8(inst->grain_amt * (40 + ((r + g + b) >> 5))); + + b = CLAMP0255(b - (grain * inst->grain_b)); + g = CLAMP0255(g - (grain * inst->grain_g)); + r = CLAMP0255(r - (grain * inst->grain_r)); + } + + *(buf + i) = (*(buf + i) & 0xFFFFFF00) | r; + *(buf + i) = (*(buf + i) & 0xFFFF00FF) | (g << 8); + *(buf + i) = (*(buf + i) & 0xFF00FFFF) | (b << 16); + + // alpha channel is preserved and no grain is applied to it + *(outframe + i) = (*(outframe + i) & 0x00FFFFFF) | (*(inframe + i) & 0xFF000000); + } + + // then blur + if(inst->blur_amt != 0.0) + { + unsigned int pixel_count; + int blur_range; + for(int i = 0; i < inst->height * inst->width; i++) + { + pixel_count = 1; + b = ((*(buf + i) & 0x00FF0000) >> 16); + g = ((*(buf + i) & 0x0000FF00) >> 8); + r = ((*(buf + i) & 0x000000FF) ); + + blur_range = random_range_uint8(inst->blur_amt * 4); + for(int xx = -blur_range - 1; xx < blur_range; xx++) + { + for(int yy = -blur_range - 1; yy < blur_range; yy++) + { + if((i + xx + (yy * inst->width)) > 0 && (i + xx + (yy * inst->width)) < (inst->width * inst->height) - 1) + { + b += (*(buf + i + xx + (yy * inst->width)) & 0x00FF0000) >> 16; + g += (*(buf + i + xx + (yy * inst->width)) & 0x0000FF00) >> 8; + r += (*(buf + i + xx + (yy * inst->width)) & 0x000000FF); + pixel_count++; + } + } + } + + b = b / pixel_count; + g = g / pixel_count; + r = r / pixel_count; + + *(outframe + i) = (*(outframe + i) & 0xFFFFFF00) | r; + *(outframe + i) = (*(outframe + i) & 0xFFFF00FF) | (g << 8); + *(outframe + i) = (*(outframe + i) & 0xFF00FFFF) | (b << 16); + } + free(buf); + } +} diff --git a/src/filter/flippo/CMakeLists.txt b/src/filter/flippo/CMakeLists.txt index e169ffa..645d98f 100644 --- a/src/filter/flippo/CMakeLists.txt +++ b/src/filter/flippo/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET flippo) if (MSVC) - set_source_files_properties (flippo.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/gamma/CMakeLists.txt b/src/filter/gamma/CMakeLists.txt index 9844625..829ba76 100644 --- a/src/filter/gamma/CMakeLists.txt +++ b/src/filter/gamma/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET gamma) if (MSVC) - set_source_files_properties (gamma.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/gateweave/CMakeLists.txt b/src/filter/gateweave/CMakeLists.txt new file mode 100644 index 0000000..e686b19 --- /dev/null +++ b/src/filter/gateweave/CMakeLists.txt @@ -0,0 +1,11 @@ +set (SOURCES gateweave.c) +set (TARGET gateweave) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) +set_target_properties (${TARGET} PROPERTIES PREFIX "") + +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/gateweave/gateweave.c b/src/filter/gateweave/gateweave.c new file mode 100644 index 0000000..2a5fb4f --- /dev/null +++ b/src/filter/gateweave/gateweave.c @@ -0,0 +1,286 @@ +#include +#include +#include "frei0r.h" +#include "frei0r_math.h" + + +// let's try to walk through everything because i'm a moron +// this is the struct for the effect instance +typedef struct gateweave_instance +{ + // image dimensions + unsigned int width; + unsigned int height; + + // parameters + double interval; + double max_move_x; + double max_move_y; + + // other variables that the effect uses to keep track of things + double next_key_x; + double next_key_y; + double prev_key_x; + double prev_key_y; + +} gateweave_instance_t; + + +// these functions are for the effect +static double gateweave_random_range(double range, double last) +{ + if(range <= 0) + { + return 0; + } + + // the maximum shift is 10 pixels + // since range includes fractional values, we want to multiply it by 100 + // this will generate an integer between -100 and 100 for the shift + // and then we divide by 100 to receive a decimal answer between -10.00 and 10.00 + range *= 10; + int int_range = range * 100; + int_range = (rand() % (int_range * 2)) - int_range; + double ret = int_range / 100.0; + + // we don't want to generate a value similar to one we already generated twice in a row + ret = CLAMP(ret, -range, range); + if((ret > 0 && ret >= last - 0.12) || (ret < 0 && ret <= last + 0.12)) + { + ret *= -1; + } + return ret; +} + +static inline double gateweave_lerp(double v0, double v1, double t) +{ + return v0 + t * (v1 - v0); +} + + +// this function mixes the colors of two pixels +// a is the original pixel that will be changed +// b is the second pixel that will not be changed +// the amount is how much of the second pixel will be mixed +// an amount of 1 means pixel a will be equal to pixel b +// an amount of 0 means pixel a will be equal to pixel a (no change) +// an amount of 0.5 means pixel a will be equal to 0.5 * pixel a + 0.5 * pixel b +static uint32_t gateweave_blend_color(uint32_t a, uint32_t b, double amount) +{ + uint8_t c_a; + uint8_t c_b; + uint8_t c_g; + uint8_t c_r; + uint32_t output; + + // RRGGBBAA + // 0xFFFFFFFF + c_a = CLAMP0255(((a & 0xFF000000) >> 24) * (1 - amount) + ((b & 0xFF000000) >> 24) * (amount)); + c_b = CLAMP0255(((a & 0x00FF0000) >> 16) * (1 - amount) + ((b & 0x00FF0000) >> 16) * (amount)); + c_g = CLAMP0255(((a & 0x0000FF00) >> 8) * (1 - amount) + ((b & 0x0000FF00) >> 8) * (amount)); + c_r = CLAMP0255(((a & 0x000000FF)) * (1 - amount) + ((b & 0x000000FF)) * (amount)); + + output = (output & 0xFFFFFF00) | (uint32_t)c_r; + output = (output & 0xFFFF00FF) | ((uint32_t)c_g << 8); + output = (output & 0xFF00FFFF) | ((uint32_t)c_b << 16); + output = (output & 0x00FFFFFF) | ((uint32_t)c_a << 24); + + return output; +} + +// this function is the one that ultimately manipulates the image +// it shifts the image and can do so to a value less than one pixel +static inline void gateweave_shift_picture(const uint32_t* in, uint32_t* out, double shift_x, double shift_y, int w, int h) +{ + uint32_t* buf = (uint32_t*)calloc(w * h, sizeof(uint32_t)); + + // first we shift to the nearest whole pixel + int int_shift_x = shift_x; + int int_shift_y = shift_y; + int pixel_shift = int_shift_x + (int_shift_y * w); + for(unsigned int i = 0; i < w * h; i++) + { + if(i + pixel_shift < 0 || i + pixel_shift >= w * h) + { + *(buf + i) = 0; + } + else + { + *(buf + i) = *(in + i + pixel_shift); + } + } + + // then we shift the fractional component + // let's think about how this works + // let's suppose we shift left 1.5 pixels and shift down 1.25 pixels + // after shifting 1 pixel left and 1 pixel down, we still have the 0.5 and 0.25 shifts left to do + // to do this we want each pixel to equal 50% the current pixel and 50% the pixel to its left + // we also want each pixel to equal 75% the current pixel and 25% the pixel below it + // but this isn't actually possible to do + shift_x -= int_shift_x; + shift_y -= int_shift_y; + + int shift_component_x; + int shift_component_y; + + char larger_x_comp = 0; + if(fabs(shift_x) > fabs(shift_y)) + { + larger_x_comp = 1; + } + + if(shift_x < 0) + { + shift_component_x = -1; + } + else + { + shift_component_x = 1; + } + if(shift_y < 0) + { + shift_component_y = -w; + } + else + { + shift_component_y = w; + } + + uint32_t v = 0; + for(unsigned int i = 0; i < w * h; i++) + { + if(!(i + shift_component_x < 0 || i + shift_component_x >= w * h || i + shift_component_x + shift_component_y < 0 || i + shift_component_x + shift_component_y >= w * h)) + { + if(larger_x_comp) + { + v = gateweave_blend_color(*(buf + i + shift_component_x), *(buf + i + shift_component_x + shift_component_y), shift_y); + *(out + i) = gateweave_blend_color(*(buf + i), v, shift_x); + } + else + { + v = gateweave_blend_color(*(buf + i + shift_component_y), *(buf + i + shift_component_x + shift_component_y), shift_x); + *(out + i) = gateweave_blend_color(*(buf + i), v, shift_y); + } + } + } + free(buf); +} + + +// these functions are for frei0r +// mostly copy/paste/slightly modified from the other frei0r effects +int f0r_init() +{ + return 1; +} + +void f0r_deinit() +{} + +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + info->name = "Gate Weave"; + info->author = "esmane"; + info->explanation = "Randomly moves frame around to simulate film gate weave."; + info->plugin_type = F0R_PLUGIN_TYPE_FILTER; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 2; + info->num_params = 3; +} + +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + switch(param_index) + { + case 0: + info->name = "Interval"; + info->explanation = "The amount of time before the position is randomized again. The larger the number the slower the picture will move."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 1: + info->name = "Maximum Horizontal Movement"; + info->explanation = "The maximum distance the picture could move left or right. The larger the number the more the picture moves and the less subtle the effect."; + info->type = F0R_PARAM_DOUBLE; + break; + + case 2: + info->name = "Maximum Vertical Movement"; + info->explanation = "The maximum distance the picture could move up or down. The larger the number the more the picture moves and the less subtle the effect."; + info->type = F0R_PARAM_DOUBLE; + break; + } +} + +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + gateweave_instance_t* inst = (gateweave_instance_t*)calloc(1, sizeof(*inst)); + + inst->width = width; + inst->height = height; + inst->interval = 0.6; + inst->max_move_x = 0.2; + inst->max_move_y = 0.2; + + // other variables that the effect uses to keep track of things + inst->next_key_x = gateweave_random_range(inst->max_move_x, 0); + inst->next_key_y = gateweave_random_range(inst->max_move_y, 0); + inst->prev_key_x = 0; + inst->prev_key_y = 0; + + return (f0r_instance_t)inst; +} + +void f0r_destruct(f0r_instance_t instance) +{ + gateweave_instance_t* inst = (gateweave_instance_t*)instance; + free(instance); +} + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + gateweave_instance_t* inst = (gateweave_instance_t*)instance; + switch(param_index) + { + case 0: + inst->interval = *((double*)param); + break; + case 1: + inst->max_move_x = *((double*)param); + break; + case 2: + inst->max_move_y = *((double*)param); + break; + } +} + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ + gateweave_instance_t* inst = (gateweave_instance_t*)instance; + switch(param_index) + { + case 0: + *((double*)param) = inst->interval; + break; + case 1: + *((double*)param) = inst->max_move_x; + break; + case 2: + *((double*)param) = inst->max_move_y; + break; + } +} + +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ + gateweave_instance_t* inst = (gateweave_instance_t*)instance; + inst->next_key_x = gateweave_random_range(inst->max_move_x, inst->next_key_x); + inst->next_key_y = gateweave_random_range(inst->max_move_y, inst->next_key_y); + + inst->prev_key_x = gateweave_lerp(inst->next_key_x, inst->prev_key_x, inst->interval); + inst->prev_key_y = gateweave_lerp(inst->next_key_y, inst->prev_key_y, inst->interval); + + gateweave_shift_picture(inframe, outframe, inst->prev_key_x, inst->prev_key_y, inst->width, inst->height); +} diff --git a/src/filter/glitch0r/CMakeLists.txt b/src/filter/glitch0r/CMakeLists.txt index 55abe62..e14c025 100644 --- a/src/filter/glitch0r/CMakeLists.txt +++ b/src/filter/glitch0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET glitch0r) if (MSVC) - set_source_files_properties (glitch0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/glow/CMakeLists.txt b/src/filter/glow/CMakeLists.txt index a1c0350..23925b6 100644 --- a/src/filter/glow/CMakeLists.txt +++ b/src/filter/glow/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET glow) if (MSVC) - set_source_files_properties (glow.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/host_param_test/CMakeLists.txt b/src/filter/host_param_test/CMakeLists.txt index 5e77cc0..ef22b65 100644 --- a/src/filter/host_param_test/CMakeLists.txt +++ b/src/filter/host_param_test/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET host_param_test) if (MSVC) - set_source_files_properties (host_param_test.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/hueshift0r/CMakeLists.txt b/src/filter/hueshift0r/CMakeLists.txt index 593dcb8..a6441be 100644 --- a/src/filter/hueshift0r/CMakeLists.txt +++ b/src/filter/hueshift0r/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET hueshift0r) if (MSVC) - set_source_files_properties (hueshift0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/invert0r/CMakeLists.txt b/src/filter/invert0r/CMakeLists.txt index e20e559..7b5c0e7 100644 --- a/src/filter/invert0r/CMakeLists.txt +++ b/src/filter/invert0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET invert0r) if (MSVC) - set_source_files_properties (invert0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/kaleid0sc0pe/CMakeLists.txt b/src/filter/kaleid0sc0pe/CMakeLists.txt new file mode 100644 index 0000000..91b001a --- /dev/null +++ b/src/filter/kaleid0sc0pe/CMakeLists.txt @@ -0,0 +1,69 @@ +include(CheckIncludeFileCXX) +include(CheckCSourceCompiles) +include(CheckCXXSourceCompiles) + +cmake_policy(SET CMP0056 NEW) +cmake_policy(SET CMP0066 NEW) +cmake_policy(SET CMP0067 NEW) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set (SOURCES api.cpp ikaleid0sc0pe.h kaleid0sc0pe.cpp kaleid0sc0pe.h sse_mathfun_extension.h sse_mathfun.h) +set (TARGET kaleid0sc0pe) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) +set_target_properties (${TARGET} PROPERTIES PREFIX "") + +if (NOT WIN32) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) + target_link_libraries(${TARGET} PRIVATE Threads::Threads) +endif() + +if(NO_SSE2) + message(STATUS "SSE2 is disabled") + add_definitions(-DNO_SSE2) +else() + check_include_file_cxx(immintrin.h HAS_INTEL_INTRINSICS) + if (HAS_INTEL_INTRINSICS) + add_definitions(-DHAS_INTEL_INTRINSICS) + if (NOT WIN32) + target_compile_options(${TARGET} PRIVATE -msse2) + set(CMAKE_REQUIRED_FLAGS "-msse2") + endif() + check_c_source_compiles(" + #include + #include + int main(){ __m128 a = _mm_set1_ps(0.0f); a = _mm_sin_ps(a); return 0;}" HAS_SIN_INTRINSIC) + check_c_source_compiles(" + #include + #include + int main(){ __m128 a = _mm_set1_ps(0.0f); a = _mm_cos_ps(a); return 0;}" HAS_COS_INTRINSIC) + check_c_source_compiles(" + #include + #include + int main(){ __m128 a = _mm_set1_ps(0.0f); __m128 b = _mm_set1_ps(0.0f); a = _mm_atan2_ps(a,b); return 0;}" HAS_ATAN2_INTRINSIC) + if (HAS_SIN_INTRINSIC) + add_definitions(-DHAS_SIN_INTRINSIC) + endif() + if (HAS_COS_INTRINSIC) + add_definitions(-DHAS_COS_INTRINSIC) + endif() + if (HAS_ATAN2_INTRINSIC) + add_definitions(-DHAS_ATAN2_INTRINSIC) + endif() + endif() +endif() + +check_cxx_source_compiles(" + #include + int main(){ std::future f; return 0;}" HAS_WORKING_FUTURE) +if (NOT HAS_WORKING_FUTURE) + add_definitions(-DNO_FUTURE) +endif() +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/kaleid0sc0pe/README.md b/src/filter/kaleid0sc0pe/README.md new file mode 100644 index 0000000..d13375e --- /dev/null +++ b/src/filter/kaleid0sc0pe/README.md @@ -0,0 +1,46 @@ +# Kaleidoscope + +A [frei0r](https://frei0r.dyne.org "frei0r") plugin to produce a kaleidoscope effect. + +Written by Brendan Hack. Original source repository at [https://github.com/gbendy/kaleidoscope](https://github.com/gbendy/kaleidoscope "https://github.com/gbendy/kaleidoscope"). + +| ["Colorful Stones"](https://www.flickr.com/photos/82955120@N05/7995277667 "Colorful Stones") by ["Bold Frontiers"](https://www.flickr.com/photos/82955120@N05 "Bold Frontiers") | kaleid0sc0ped | +| - | - | +| [![Colorful Stones](colorful_stones-400.jpg)](colorful_stones.jpg) | [![Kaleidoscoped Colorful Stones](colorful_stones-tr16-400.jpg)](colorful_stones-tr16.jpg) | +|Licensed under [CC BY 2.0](https://creativecommons.org/licenses/by/2.0/?ref=ccsearch&atype=html "CC BY 2.0") | Segmentation 16, source segment centred to top right| + +| Source Image | ["New Years Day 2024"](https://www.youtube.com/watch?v=9tZwRUTyD08 "New Years Day 2024)") (YouTube)| +| - | - | +| [![New Years Day 2024 Source](new-years-day-2024-source-480.jpg)](new-years-day-2024-source-480.jpg) | [![New Years Day 2024 YouTube](https://img.youtube.com/vi/9tZwRUTyD08/0.jpg)](https://www.youtube.com/watch?v=9tZwRUTyD08) | +| Video created from single source image via zoom/rotate/pan and kaleidoscope animation | Animated Music Video created in [KdenLive](https://kdenlive.org) by [Paul Haesler](https://www.youtube.com/@PaulHaesler) | + +| [Created Many and Strange (Official Music Video)](https://www.youtube.com/watch?v=2r9ggSie1wI) (YouTube) by [Spaceman Paul](https://github.com/SpacemanPaul "Spaceman Paul") | +| --- | +| [![Created Many and Strange (Official Music Video) by @SpacemanPaul](https://img.youtube.com/vi/2r9ggSie1wI/0.jpg)](https://www.youtube.com/watch?v=2r9ggSie1wI) | +| Animated Music Video created in [KdenLive](https://kdenlive.org) by [Spaceman Paul](https://www.youtube.com/channel/UCBVFfRZw4Vbk3j6mNCukztg) | + +Allows for specification of number of segments (mirrors), auto selection of optimal source reflection segment, placement of origin and much more! + +# Parameters + +1. `origin_x` `(float=0.5)` - Origin of the kaleid0sc0pe in x. Range `[0, 1]`. +2. `origin_y` `(float=0.5)` - Origin of the kaleid0sc0pe in y. Range `[0, 1]`. +3. `segmentation` `(float=16/128)` - The kaleid0sc0pe effect is broken into `segmentation * 128` segments. Segmentations of 1, 2 or multiples of 4 work best. Range `[0, 1]`. +4. `specify_source` `(bool=false)` - If `true` then the source segment for the mirror is specified by `source_segment`. Otherwise the furthest corner from the origin is used as the source segment and the segment's orientation is defined by `segmentation_direction`. When multiple corners are the same distance the tie is broken according to the `preferred_corner` and `corner_search` parameters. +5. `source_segment` `(float=0)` - Normalized angle that specifies the centre of the source segment if `specify_source` is `true`. `0` is in `+x` and rotates counter clockwise. Range `[0, 1]`. +6. `segmentation_direction` `(float=1)` - When `source_segment` is `false` the source segement is either centred on the corner (< `1/3`), extends counter clockwise from the corner (< `2/3`) or clockwise from the corner (>= `2/3` the default). Range `[0, 1]`. +7. `reflect_edges` `(bool=true)` - If `true` then reflections that end up outside the frame reflect back into it, otherwise the colour specified in `bg_color` is used. +8. `edge_threshold` `(float=0)` - if `reflect_edges` is `false` then reflections outside the frame but within `edge_threshold * 4` pixels of the frame clamp to the edge value rather than use the background color. Range `[0, 1]`. +9. `preferred_corner` `(float=0)` - The preferred corner when breaking ties when searching for the furthest corner. Searching starts in this corner and proceeds in the direction given in `corner_search`. The first and furthest corner found wins. Supported values are `0`: top right (default), `0.25`: top left, `0.5`: bottom left, `0.75`: bottom right. +10. `corner_search` `(bool=true)` - If `true` search clockwise for furthest corner, otherwise counter clockwise. +11. `bg_color` `(color=1,0,1)` - Color used when reflections end up outside the frame and `reflect_edges` is `false`. +12. `bg_alpha` `(float=1)` - Alpha value to use when reflections end up outside the frame and `reflect_edges` is `false`. Range `[0, 1]`. +13. `multithreaded` `(bool=true)` - If `true` then processing is multithreaded. +14. `n_threads` `(float=0)` - If `multithreaded` is `true` then the number of threads to use. `0` autocalculates otherwise `n_threads * 32` threads are used. Range `[0, 1]`. + +# Contributors + +This filter exists thanks to all the people who contribute. + +- [Brendan Hack](https://github.com/gbendy "Brendan Hack") +- [Spaceman Paul](https://github.com/SpacemanPaul "Spaceman Paul") diff --git a/src/filter/kaleid0sc0pe/api.cpp b/src/filter/kaleid0sc0pe/api.cpp new file mode 100644 index 0000000..c8874b1 --- /dev/null +++ b/src/filter/kaleid0sc0pe/api.cpp @@ -0,0 +1,178 @@ +/* + * api.cpp + * Copyright (C) 2020-2023 Brendan Hack (github@bendys.com) + * This file is part of a Frei0r plugin that applies a kaleidoscope + * effect. + * Version 1.1 july 2023 + * + * Implements the Frei0r interface + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include "frei0r.hpp" +#include "ikaleid0sc0pe.h" + +class kaleid0sc0pe : public frei0r::filter +{ +public: + kaleid0sc0pe(unsigned int width, unsigned int height): + m_kaleid0sc0pe(libkaleid0sc0pe::IKaleid0sc0pe::factory(width,height,1,4)), + m_origin_x(0.5), + m_origin_y(0.5), + m_segmentation(16/128.0), + m_direction(1.0), + m_corner(0), + m_corner_direction(true), + m_reflect_edges(true), + m_edge_threshold(0), + m_bg_alpha(1), + m_specify_source(false), + m_source_segment(0), + m_multithreaded(true), + m_threads(0) + { + m_bg_colour.r = 1.0; + m_bg_colour.g = 0.0; + m_bg_colour.b = 1.0; + + register_param(m_origin_x, + "origin_x", + "origin of the kaleid0sc0pe in x. default 0.5"); + register_param(m_origin_y, + "origin_y", + "origin of the kaleid0sc0pe in y. default 0.5"); + register_param(m_segmentation, + "segmentation", + "kaleid0sc0pe segmentation / 128, segmentations of 1, 2 or multiples of 4 work best. default 16/128"); + register_param(m_specify_source, + "specify_source", + "if true then source angle is read from source_segment, otherwise auto-calculated"); + register_param(m_source_segment, + "source_segment", + "centre of source segment if specify_source is true. 0 is in +x and rotates counter clockwise"); + register_param(m_direction, + "segmentation_direction", + "segmentation direction, < 1/3 is none, < 2/3 is counter clockwise, otherwise clockwise"); + register_param(m_reflect_edges, + "reflect_edges", + "if true then reflections that end up outside the source reflect back into it, otherwise the specified background colour is used."); + register_param(m_edge_threshold, + "edge_threshold", + "edge threshold / 4, reflections outside the image but within this distance clamp to the edge. default 0"); + register_param(m_corner, + "preferred_corner", + "preferred corner, 0 is top right, 0.25 top left, 0.5 bottom left, 0.75 bottom right"); + register_param(m_corner_direction, + "corner_search", + "if true search clockwise for furthest corner, otherwise counter clockwise"); + register_param(m_bg_colour, + "bg_color", + "colour to use if reflection lies outside of source image and not reflecting back in. default 1,0,1"); + register_param(m_bg_alpha, + "bg_alpha", + "alpha to use if reflection lies outside of source image and not reflecting back in. default 1"); + register_param(m_multithreaded, + "multithreaded", + "set to true to enable multithreaded calculation. default true"); + register_param(m_threads, + "n_threads", + "the number of threads to use, if 0 then autocalculate otherwise value * 32. default 0"); + + + m_kaleid0sc0pe->set_background_colour(m_background); + } + + virtual void update(double time, + uint32_t* out, + const uint32_t* in) { + + update_params(); + m_kaleid0sc0pe->process(in, out); + } + +private: + void update_params() + { + m_kaleid0sc0pe->set_origin(static_cast(m_origin_x), static_cast(m_origin_y)); + m_kaleid0sc0pe->set_segmentation(static_cast(m_segmentation * 128)); + if (m_direction < 1/3.0) { + m_kaleid0sc0pe->set_segment_direction(libkaleid0sc0pe::IKaleid0sc0pe::Direction::NONE); + } else if (m_direction < 2/3.0) { + m_kaleid0sc0pe->set_segment_direction(libkaleid0sc0pe::IKaleid0sc0pe::Direction::ANTICLOCKWISE); + } else { + m_kaleid0sc0pe->set_segment_direction(libkaleid0sc0pe::IKaleid0sc0pe::Direction::CLOCKWISE); + } + if (m_corner < 0.25) { + m_kaleid0sc0pe->set_preferred_corner(libkaleid0sc0pe::IKaleid0sc0pe::Corner::TR); + } else if (m_corner < 0.5) { + m_kaleid0sc0pe->set_preferred_corner(libkaleid0sc0pe::IKaleid0sc0pe::Corner::TL); + } else if (m_corner < 0.75) { + m_kaleid0sc0pe->set_preferred_corner(libkaleid0sc0pe::IKaleid0sc0pe::Corner::BL); + } else { + m_kaleid0sc0pe->set_preferred_corner(libkaleid0sc0pe::IKaleid0sc0pe::Corner::BR); + } + if (m_corner_direction) { + m_kaleid0sc0pe->set_preferred_corner_search_direction(libkaleid0sc0pe::IKaleid0sc0pe::Direction::CLOCKWISE); + } else { + m_kaleid0sc0pe->set_preferred_corner_search_direction(libkaleid0sc0pe::IKaleid0sc0pe::Direction::ANTICLOCKWISE); + } + m_kaleid0sc0pe->set_reflect_edges(m_reflect_edges); + m_kaleid0sc0pe->set_edge_threshold(static_cast(m_edge_threshold * 4)); + + if (m_specify_source) { + m_kaleid0sc0pe->set_source_segment(static_cast(m_source_segment) * 3.141592654f * 2); + } else { + m_kaleid0sc0pe->set_source_segment(-1); + } + if (m_multithreaded) { + m_kaleid0sc0pe->set_threading(static_cast(m_threads * 32)); + } else { + m_kaleid0sc0pe->set_threading(1); + } + m_background[0] = static_cast(m_bg_colour.r * 255); + m_background[1] = static_cast(m_bg_colour.g * 255); + m_background[2] = static_cast(m_bg_colour.b * 255); + m_background[3] = static_cast(m_bg_alpha * 255); + } + + double m_origin_x; + double m_origin_y; + + double m_segmentation; + double m_direction; + + double m_corner; + bool m_corner_direction; + + bool m_reflect_edges; + + double m_edge_threshold; + + f0r_param_color m_bg_colour; + double m_bg_alpha; + + bool m_specify_source; + double m_source_segment; + + bool m_multithreaded; + double m_threads; + + std::uint8_t m_background[4]; + + std::unique_ptr m_kaleid0sc0pe; +}; + +frei0r::construct plugin("Kaleid0sc0pe", "Applies a kaleid0sc0pe effect", "Brendan Hack", 1, 1, F0R_COLOR_MODEL_RGBA8888); diff --git a/src/filter/kaleid0sc0pe/colorful_stones-400.jpg b/src/filter/kaleid0sc0pe/colorful_stones-400.jpg new file mode 100644 index 0000000..1928369 Binary files /dev/null and b/src/filter/kaleid0sc0pe/colorful_stones-400.jpg differ diff --git a/src/filter/kaleid0sc0pe/colorful_stones-tr16-400.jpg b/src/filter/kaleid0sc0pe/colorful_stones-tr16-400.jpg new file mode 100644 index 0000000..3d11787 Binary files /dev/null and b/src/filter/kaleid0sc0pe/colorful_stones-tr16-400.jpg differ diff --git a/src/filter/kaleid0sc0pe/ikaleid0sc0pe.h b/src/filter/kaleid0sc0pe/ikaleid0sc0pe.h new file mode 100644 index 0000000..4a35e89 --- /dev/null +++ b/src/filter/kaleid0sc0pe/ikaleid0sc0pe.h @@ -0,0 +1,308 @@ +/* + * ikaleid0sc0pe.h + * Copyright (C) 2020-2023 Brendan Hack (github@bendys.com) + * This file is part of a Frei0r plugin that applies a kaleidoscope + * effect. + * Version 1.1 july 2023 + * + * Interface and factory function to the kaleidoscope library + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#ifndef SRC_FILTER_KALEID0SC0PE_IKALEID0SC0PE_H_ +#define SRC_FILTER_KALEID0SC0PE_IKALEID0SC0PE_H_ 1 + +#include +#include + +namespace libkaleid0sc0pe { +class IKaleid0sc0pe; +} + +namespace std +{ + +// default delete for IKaleid0sc0pe +// this isn't going to work across an actaul shared object boundary but +// not particular worried about that at the moment +template<> +class default_delete +{ +public: + void operator()(libkaleid0sc0pe::IKaleid0sc0pe* p); +}; + +} // namespace std + +namespace libkaleid0sc0pe { + +/** + * Class which implements the kaleid0sc0pe effect + */ +class IKaleid0sc0pe { +public: + /** + * Sets the origin of the kaleid0sc0pe effect. These are given in the range 0 -> 1. + * Values other than 0.5,0.5 may end up reflecting outside the source image. + * These areas will be filled depending on the settings in #set_reflect_edges and + * #set_background_colour. + * Defaults to 0.5, 0.5. + * @param x x coordinate of the origin + * @param y y coordinate of the origin + * @return + * - 0: Success + * - -1: Error + * - -2: Parameter out of range + */ + virtual std::int32_t set_origin(float x, float y) = 0; + + /** + * Returns the origin x coordinate. + */ + virtual float get_origin_x() const = 0; + + /** + * Returns the origin y coordinate. + */ + virtual float get_origin_y() const = 0; + + /** + * Sets the segmentation resulting in \p segmentation * 2 segments in the output frame. + * Segmentation values that are 1, 2 or a multiple of 4, are oriented to an image corner + * and centred will always reflect back to the source segment. + * Other settings may end up reflecting outside the source image. These areas will be filled + * depending on the settings in #set_reflect_edges and #set_background_colour. + * Defaults to 16. + * @param segmentation the segmentation value + * @return + * - 0: Success + * - -1: Error + * - -2: Parameter out of range + */ + virtual std::int32_t set_segmentation(std::uint32_t segmentation) = 0; + + /** + * Returns the segmentation value + */ + virtual std::uint32_t get_segmentation() const = 0; + + /** + * When #set_reflect_edges is not true and a reflected pixel ends up outside the image + * we can clamp the pixels that fall outside the image but within \p threshold pixels + * of the edge to the edge. + * Defaults to 0 + * @param threshold the threshold in pixels. + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_edge_threshold(std::uint32_t threshold) = 0; + + /** + * Returns the edge threshold + */ + virtual std::uint32_t get_edge_threshold() const = 0; + + /// Defines a corner + enum class Corner { + TL = 0, //< Top Left + TR, //< Top Right + BR, //< Bottom Right + BL //< Bottom Left + }; + + /// Defines an angular direction + enum class Direction { + CLOCKWISE = 0, //< Clockwise + ANTICLOCKWISE, //< Anti Clockwise + NONE //< No direction + }; + + /** + * Sets the direction that the source segment rotates in. If + * Direction::NONE then the source segment is centred on the corner. + * Otherwise it extends in the given direction. + * Defaults to Direction::NONE + * @param direction the direction + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_segment_direction(Direction direction) = 0; + + /** + * Returns the segment direction + */ + virtual Direction get_segment_direction() const = 0; + + /** + * Unless directly specified with #set_source_segment the source segment is always aligned to + * the furthest corner of the image from the origin. + * The source segment has it's edge (or centre) on a line from the origin to the furthest corner, + * and extends in the direction given by #set_segment_direction. + * If multiple corners are equidistant from the origin then this indicates which + * corner is preferred. The algorithm searches from this corner, in the direction + * specified in #set_preferred_corner_search_direction to find the furthest corner. + * Defaults to Corner::BR + * @param corner the preferred corner + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_preferred_corner(Corner corner) = 0; + + /** + * Returns the preferred corner + */ + virtual Corner get_preferred_corner() const = 0; + + /** + * The direction to search for the furthest corner in. + * Defaults to Direction::CLOCKWISE + * @param direction the search direction + * @return + * - 0: Success + * - -1: Error + * - -2: Invalid parameter (\p direction cannot by Direction::NONE) + */ + virtual std::int32_t set_preferred_corner_search_direction(Direction direction) = 0; + + /** + * Returns the corner search direction + */ + virtual Direction get_preferred_corner_search_direction() const = 0; + + /** + * Reflected points can end up outside the source image depending on segmentation, + * source segment and origin settings. When this occurs three options are provided, + * lookup the pixel in a reflected tessellation of the original image, set the pixel + * to the background colour provided in #set_background_colour or write nothing to the + * output frame for that pixel. + * Defaults to \c true which is to lookup in the reflected tessellation. + * @param reflect if \c true then lookup in a reflection, if \c false use background color + * or do nothing if no background color was set. + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_reflect_edges(bool reflect) = 0; + + /** + * Returns the reflect edges setting + */ + virtual bool get_reflect_edges() const = 0; + + /** + * If not reflecting edges then this sets the colour to use when the kaleid0sc0pe effect + * for a point ends up outside the source image. The data pointed to should be at least as + * wide as a pixel and must be valid for the lifetime of the class instance. + * The caller retains ownership of the passed memory. + * Defaults to \c nullptr + * @param colour the background colour, if \c nullptr then the output buffer is not modified + * if reflection does not land in the source segment. + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_background_colour(void* colour) = 0; + + /** + * Returns the background colour + */ + virtual void* get_background_colour() const = 0; + + /** + * Allows to explicitly specify the location of the source segment. 0 radians is in the positive + * horizontal direction and +ve rotates anti-clockwise. + * @param angle If positive or 0 then the angle of the centre of the source segment in radians. If negative + * (the default) then the source segment is auto calculated based on origin, preferred corner, + * direction and corner search direction. + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_source_segment(float angle) = 0; + + /** + * Returns the source segment + */ + virtual float get_source_segment() const = 0; + + /** + * Applies the kaleid0sc0pe effect to \p in_frame and returns it in \p out_frame. + * Each parameter must point to enough memory to contain the image specified in the + * constructor and must be aligned to an integer multiple of 16 bytes in memory. + * @param in_frame the input frame to process + * @param out_frame receives the output image + * @return + * - 0: Success + * - -1: Error + * - -2: Invalid parameter (nullptr) + */ + virtual std::int32_t process(const void* in_frame, void* out_frame) = 0; + + /** + * Sets the number of threads to use when processing. + * Default to 0. + * @param threading the nubmer of threads to use. \c 0, calculate automatically, + * otherwise the explicit thread count. + * @return + * - 0: Success + * - -1: Error + */ + virtual std::int32_t set_threading(std::uint32_t threading) = 0; + + /** + * Returns the number of threads to use. + */ + virtual std::uint32_t get_threading() const = 0; + + /** + * Visualises the currently configured segmentation. The pure green segment is the + * source segment. + * @param out_frame receives the output image + * @return + * - 0: Success + * - -1: Error + * - -2: Invalid parameter (nullptr) + */ + virtual std::int32_t visualise(void* out_frame) = 0; + + /** + * Virtual destructor + */ + virtual ~IKaleid0sc0pe() {}; + + /** + * Static factory function. Frame width and height must be a multiple of 4. + * @param width the frame width + * @param height the frame height + * @param component_size the byte size of each frame pixel component + * @param num_components the number of components per pixel + * @param stride the image stride, if \c 0 then calculated as \p width * \p component_size * \p num_components + */ + static std::unique_ptr factory(std::uint32_t width, std::uint32_t height, std::uint32_t component_size, std::uint32_t num_components, std::uint32_t stride = 0) { + return std::unique_ptr(create(width, height, component_size, num_components, stride)); + } + +private: + static IKaleid0sc0pe* create(std::uint32_t width, std::uint32_t height, std::uint32_t component_size, std::uint32_t num_components, std::uint32_t stride = 0); + +}; + +} // namespace libkaleid0sc0pe + +#endif // SRC_FILTER_KALEID0SC0PE_IKALEID0SC0PE_H_ diff --git a/src/filter/kaleid0sc0pe/kaleid0sc0pe.cpp b/src/filter/kaleid0sc0pe/kaleid0sc0pe.cpp new file mode 100644 index 0000000..4a40882 --- /dev/null +++ b/src/filter/kaleid0sc0pe/kaleid0sc0pe.cpp @@ -0,0 +1,777 @@ +/* + * kaleid0sc0pe.cpp + * Copyright (C) 2020-2023 Brendan Hack (github@bendys.com) + * This file is part of a Frei0r plugin that applies a kaleidoscope + * effect. + * Version 1.1 july 2023 + * + * The kaleidoscope class implementation. + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include "kaleid0sc0pe.h" +#include +#include +#ifndef NO_FUTURE +#include +#endif + +#ifdef __SSE2__ +#define USE_SSE2 +#include "sse_mathfun_extension.h" +#undef USE_SSE2 +#ifdef HAS_INTEL_INTRINSICS +#include +#endif +#ifdef HAS_SIN_INTRINSIC +#define _mm_call_sin_ps _mm_sin_ps +#else +#define _mm_call_sin_ps sin_ps +#endif +#ifdef HAS_COS_INTRINSIC +#define _mm_call_cos_ps _mm_cos_ps +#else +#define _mm_call_cos_ps cos_ps +#endif +#ifdef HAS_ATAN2_INTRINSIC +#define _mm_call_atan2_ps _mm_atan2_ps +#else +#define _mm_call_atan2_ps atan2_ps +#endif +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#ifndef M_2PI +#define M_2PI 6.28318530717958647693 +#endif +#ifndef MF_PI +#define MF_PI 3.14159265358979323846f +#endif +#ifndef MF_2PI +#define MF_2PI 6.28318530717958647693f +#endif + +namespace std +{ + +void default_delete::operator()(libkaleid0sc0pe::IKaleid0sc0pe *p) +{ + delete p; +} + +} // namespace std + +namespace libkaleid0sc0pe { + +IKaleid0sc0pe *IKaleid0sc0pe::create(std::uint32_t width, std::uint32_t height, std::uint32_t component_size, std::uint32_t num_components, std::uint32_t stride) +{ + return new Kaleid0sc0pe(width, height, component_size, num_components, stride); +} + +Kaleid0sc0pe::Kaleid0sc0pe(std::uint32_t width, std::uint32_t height, std::uint32_t component_size, std::uint32_t num_components, std::uint32_t stride): +m_width(width), +m_height(height), +m_component_size(component_size), +m_num_components(num_components), +m_stride(stride ? stride : width * component_size * num_components), +m_pixel_size(component_size * num_components), +m_aspect(width/static_cast(height)), +m_origin_x(0.5f), +m_origin_y(0.5f), +m_origin_native_x(m_origin_x * width), +m_origin_native_y(m_origin_y * height), +m_segmentation(16), +m_segment_direction(Direction::NONE), +m_preferred_corner(Corner::BR), +m_preferred_search_dir(Direction::CLOCKWISE), +m_edge_reflect(true), +m_background_colour(nullptr), +m_edge_threshold(0), +m_source_segment_angle(-1), +m_n_segments(0), +m_start_angle(0), +m_segment_width(0), +m_n_threads(0) +{ +#ifdef __SSE2__ + m_sse_width = _mm_set1_ps(static_cast(m_width)); + m_sse_height = _mm_set1_ps(static_cast(m_height)); + m_sse_aspect = _mm_set1_ps(m_width / static_cast(m_height)); + m_sse_ps_0 = _mm_set1_ps(0.0f); + m_sse_ps_1 = _mm_set1_ps(1.0f); + m_sse_ps_1 = _mm_set1_ps(1.0f); + m_sse_ps_2 = _mm_set1_ps(2.0f); + m_sse_epi32_1 = _mm_set1_epi32(1); + m_sse_epi32_2 = _mm_set1_epi32(2); + m_sse_shift_1 = _mm_cvtsi32_si128(1); +#endif +} + +std::int32_t Kaleid0sc0pe::set_origin(float x, float y) +{ + if (x < 0 || y < 0 || x > 1 || y > 1) { + return -2; + } + m_origin_x = x; + m_origin_y = y; + + m_origin_native_x = m_origin_x * m_width; + m_origin_native_y = m_origin_y * m_height; + + m_n_segments = 0; + + return 0; +} + +float Kaleid0sc0pe::get_origin_x() const +{ + return m_origin_x; +} + +float Kaleid0sc0pe::get_origin_y() const +{ + return m_origin_y; +} + +std::int32_t Kaleid0sc0pe::set_segmentation(std::uint32_t segmentation) +{ + if (segmentation == 0) { + return -2; + } + m_segmentation = segmentation; + m_n_segments = 0; + + return 0; +} + +std::uint32_t Kaleid0sc0pe::get_segmentation() const +{ + return m_segmentation; +} + +std::int32_t Kaleid0sc0pe::set_edge_threshold(std::uint32_t threshold) +{ + m_edge_threshold = threshold; + return 0; +} + +std::uint32_t Kaleid0sc0pe::get_edge_threshold() const +{ + return m_edge_threshold; +} + +std::int32_t Kaleid0sc0pe::set_preferred_corner(Corner corner) +{ + m_preferred_corner = corner; + m_n_segments = 0; + return 0; +} + +Kaleid0sc0pe::Corner Kaleid0sc0pe::get_preferred_corner() const +{ + return m_preferred_corner; +} + +std::int32_t Kaleid0sc0pe::set_preferred_corner_search_direction(Direction direction) +{ + if (direction == Direction::NONE) { + return -2; + } + m_preferred_search_dir = direction; + m_n_segments = 0; + return 0; +} + +Kaleid0sc0pe::Direction Kaleid0sc0pe::get_preferred_corner_search_direction() const +{ + return m_preferred_search_dir; +} + +std::int32_t Kaleid0sc0pe::set_reflect_edges(bool reflect) +{ + m_edge_reflect = reflect; + return 0; +} + +bool Kaleid0sc0pe::get_reflect_edges() const +{ + return m_edge_reflect; +} + +std::int32_t Kaleid0sc0pe::set_background_colour(void* colour) +{ + m_background_colour = colour; + return 0; +} + +void* Kaleid0sc0pe::get_background_colour() const +{ + return m_background_colour; +} + +std::int32_t Kaleid0sc0pe::set_source_segment(float angle) +{ + m_source_segment_angle = angle; + return 0; +} + +float Kaleid0sc0pe::get_source_segment() const +{ + return m_source_segment_angle; +} + +static double distance_sq(double x1, double y1, double x2, double y2) +{ + return std::pow(x1 - x2, 2) + std::pow(y1 - y2, 2); +} + +std::int32_t inc_idx(std::int32_t start_idx, std::int32_t inc, std::int32_t max) +{ + start_idx += inc; + return (start_idx < 0) ? max - 1 : start_idx % max; +} + +void Kaleid0sc0pe::init() +{ + m_n_segments = m_segmentation * 2; + m_segment_width = MF_PI * 2 / m_n_segments; + + if (m_source_segment_angle < 0) { + // find origin rotation + std::uint32_t corners[4][2] = { + { 0, 0 }, + { 1, 0 }, + { 1, 1 }, + { 0, 1 } + }; + std::int32_t start_idx(0); + switch (m_preferred_corner) { + case Corner::TL: start_idx = 0; break; + case Corner::TR: start_idx = 1; break; + case Corner::BR: start_idx = 2; break; + case Corner::BL: start_idx = 3; break; + } + std::int32_t dir = m_preferred_search_dir == Direction::CLOCKWISE ? 1 : -1; + std::uint32_t idx = start_idx; + float origin_x = m_origin_x; + float origin_y = m_origin_y; + double dist = distance_sq(origin_x, origin_y, corners[idx][0], corners[idx][1]); + std::int32_t corner = idx; + idx = inc_idx(idx, dir, 4); + while (idx != start_idx) { + double d = distance_sq(origin_x, origin_y, corners[idx][0], corners[idx][1]); + if (d > dist) { + dist = d; + corner = idx; + } + idx = inc_idx(idx, dir, 4); + } + + float start_line_x = corners[corner][0] - origin_x; + float start_line_y = corners[corner][1] - origin_y; + m_start_angle = std::atan2(start_line_y, start_line_x) - (m_segment_direction == Direction::NONE ? + 0 : + (m_segment_width / (m_segment_direction == Direction::CLOCKWISE ? -2 : 2))); + } else { + m_start_angle = -m_source_segment_angle; + } +#ifdef __SSE2__ + m_sse_origin_native_x = _mm_set1_ps(m_origin_x * m_width); + m_sse_origin_native_y = _mm_set1_ps(m_origin_y * m_height); + m_sse_start_angle = _mm_set1_ps(m_start_angle); + m_sse_segment_width = _mm_set1_ps(m_segment_width); + m_sse_half_segment_width = _mm_set1_ps(m_segment_width/2); +#endif +} + +#ifdef __SSE2__ +Kaleid0sc0pe::Reflect_info Kaleid0sc0pe::calculate_reflect_info(__m128i* x, __m128i* y) +{ + Reflect_info info; + + to_screen(&info.screen_x, &info.screen_y, x, y); + + info.angle = _mm_sub_ps(_mm_call_atan2_ps(info.screen_y, info.screen_x), m_sse_start_angle); + info.reference_angle = _mm_add_ps(_mm_and_ps(info.angle, *(v4sf*)_ps_inv_sign_mask), m_sse_half_segment_width); + // we do a max with 0 since atan2_ps will return nan for atan2(0,0) which ends up with a negative reference angle. + info.segment_number_i = _mm_cvttps_epi32(_mm_max_ps(_mm_div_ps(info.reference_angle, m_sse_segment_width), m_sse_ps_0)); + info.segment_number = _mm_cvtepi32_ps(info.segment_number_i); + + return info; +} + +void Kaleid0sc0pe::to_screen(__m128* x, __m128* y, __m128i* sx, __m128i* sy) +{ + *x = _mm_cvtepi32_ps(*sx); + *x = _mm_sub_ps(*x, m_sse_origin_native_x); + *y = _mm_cvtepi32_ps(*sy); + *y = _mm_sub_ps(*y, m_sse_origin_native_y); + *y = _mm_mul_ps(*y, m_sse_aspect); +} + +void Kaleid0sc0pe::from_screen(__m128* x, __m128* y) +{ + *x = _mm_add_ps(*x, m_sse_origin_native_x); + *y = _mm_div_ps(*y, m_sse_aspect); + *y = _mm_add_ps(*y, m_sse_origin_native_y); +} + +void Kaleid0sc0pe::rotate(int x, int y, __m128 *source_x, __m128 *source_y) +{ + ALIGN16_BEG int ALIGN16_END mx[4] = { x, x + 1, x + 2, x + 3 }; + ALIGN16_BEG int ALIGN16_END my[4] = { y, y, y, y }; + + Reflect_info info = calculate_reflect_info((__m128i*)mx, (__m128i*)my); + + __m128 reflection_angle = _mm_mul_ps(info.segment_number, m_sse_segment_width); + + __m128i segi_p1 = _mm_add_epi32(info.segment_number_i, m_sse_epi32_1); + __m128 refl_factor = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_srl_epi32(segi_p1, m_sse_shift_1), _mm_srl_epi32(info.segment_number_i, m_sse_shift_1))); + + reflection_angle = _mm_sub_ps(reflection_angle, _mm_mul_ps(refl_factor, _mm_sub_ps(m_sse_segment_width, _mm_mul_ps(m_sse_ps_2, _mm_sub_ps(info.reference_angle, reflection_angle))))); + + reflection_angle = _mm_mul_ps(reflection_angle, _mm_sub_ps(m_sse_ps_0, _mm_or_ps(_mm_and_ps(info.angle, *(v4sf*)_ps_sign_mask), m_sse_ps_1))); + + reflection_angle = _mm_mul_ps(reflection_angle, _mm_and_ps(_mm_cmpge_ps(info.segment_number, m_sse_ps_1), m_sse_ps_1)); + + __m128 cos_angle = _mm_call_cos_ps(reflection_angle); + __m128 sin_angle = _mm_call_sin_ps(reflection_angle); + *source_x = _mm_sub_ps(_mm_mul_ps(info.screen_x, cos_angle), _mm_mul_ps(info.screen_y, sin_angle)); + *source_y = _mm_add_ps(_mm_mul_ps(info.screen_y, cos_angle), _mm_mul_ps(info.screen_x, sin_angle)); + + from_screen(source_x, source_y); +} + +#else +Kaleid0sc0pe::Reflect_info Kaleid0sc0pe::calculate_reflect_info(std::uint32_t x, std::uint32_t y) +{ + Reflect_info info; + + to_screen(&(info.screen_x), &(info.screen_y), x, y); + + info.angle = std::atan2(info.screen_y, info.screen_x) - m_start_angle; + info.reference_angle = std::fabs(info.angle) + m_segment_width / 2; + info.segment_number = std::uint32_t(info.reference_angle / m_segment_width); + + return info; +} +void Kaleid0sc0pe::to_screen(float *x, float *y, std::uint32_t sx, std::uint32_t sy) +{ + *x = sx - m_origin_native_x; + *y = (sy - m_origin_native_y) * m_aspect; +} + +void Kaleid0sc0pe::from_screen(float *x, float *y) +{ + *x = *x + m_origin_native_x; + *y = *y / m_aspect + m_origin_native_y; +} +#endif + +const std::uint8_t *Kaleid0sc0pe::lookup(const std::uint8_t* p, std::uint32_t x, std::uint32_t y) +{ + return p + m_stride * static_cast(y) + m_pixel_size * static_cast(x); +} + +std::uint8_t* Kaleid0sc0pe::lookup(std::uint8_t* p, std::uint32_t x, std::uint32_t y) +{ + return p + m_stride * static_cast(y) + m_pixel_size * static_cast(x); +} + +void Kaleid0sc0pe::process_bg(float x, float y, const std::uint8_t* in, std::uint8_t* out) +{ + if (x < 0 && -x <= m_edge_threshold) { + x = 0; + } + else if (x >= m_width && x < m_width + m_edge_threshold) { + x = m_width - 1.0f; + } + if (y < 0 && -y <= m_edge_threshold) { + y = 0; + } + else if (y >= m_height && y < m_height + m_edge_threshold) { + y = m_height - 1.0f; + } + if (static_cast(x) >= 0 && static_cast(x) < m_width && + static_cast(y) >= 0 && static_cast(y) < m_height) { + std::memcpy(out, lookup(in, static_cast(x), static_cast(y)), m_pixel_size); + } + else if (m_background_colour) { + std::memcpy(out, reinterpret_cast(m_background_colour), m_pixel_size); + } +} + +#ifdef __SSE2__ +void Kaleid0sc0pe::process_block(Block* block) +{ + for (std::int32_t y = block->y_start; y <= static_cast(block->y_end); ++y) { + for (std::int32_t x = block->x_start; x <= static_cast(block->x_end); x += 4) { + std::uint8_t* out = lookup(block->out_frame, x, y); + __m128 source_x; + __m128 source_y; + + // rotate points to source_x,source_y + rotate(x, y, &source_x, &source_y); + + // reflect back into image if necessary + + source_x = _mm_and_ps(source_x, *(v4sf*)_ps_inv_sign_mask); + __m128 ge_width = _mm_cmpge_ps(source_x, m_sse_width); + source_x = _mm_or_ps(_mm_and_ps(_mm_sub_ps(m_sse_width, _mm_sub_ps(source_x, m_sse_width)), ge_width), _mm_andnot_ps(ge_width, source_x)); + + // same for y + source_y = _mm_and_ps(source_y, *(v4sf*)_ps_inv_sign_mask); + __m128 ge_height = _mm_cmpge_ps(source_y, m_sse_height); + source_y = _mm_or_ps(_mm_and_ps(_mm_sub_ps(m_sse_height, _mm_sub_ps(source_y, m_sse_height)), ge_height), _mm_andnot_ps(ge_height,source_y)); + + __m128i source_xi = _mm_cvttps_epi32(_mm_min_ps(source_x, _mm_sub_ps(m_sse_width, m_sse_ps_1))); + __m128i source_yi = _mm_cvttps_epi32(_mm_min_ps(source_y, _mm_sub_ps(m_sse_height, m_sse_ps_1))); + + std::int32_t* sx = reinterpret_cast(&source_xi); + std::int32_t* sy = reinterpret_cast(&source_yi); + std::memcpy(out, lookup(block->in_frame, sx[0], sy[0]), m_pixel_size); + out += m_pixel_size; + std::memcpy(out, lookup(block->in_frame, sx[1], sy[1]), m_pixel_size); + out += m_pixel_size; + std::memcpy(out, lookup(block->in_frame, sx[2], sy[2]), m_pixel_size); + out += m_pixel_size; + std::memcpy(out, lookup(block->in_frame, sx[3], sy[3]), m_pixel_size); + } + } +} + +void Kaleid0sc0pe::process_block_bg(Block* block) +{ + for (std::int32_t y = block->y_start; y <= static_cast(block->y_end); ++y) { + for (std::int32_t x = block->x_start; x <= static_cast(block->x_end); x += 4) { + std::uint8_t* out = lookup(block->out_frame, x, y); + __m128 source_x; + __m128 source_y; + + // rotate points to source_x,source_y + rotate(x, y, &source_x, &source_y); + + float* sx = reinterpret_cast(&source_x); + float* sy = reinterpret_cast(&source_y); + process_bg(sx[0], sy[0], block->in_frame, out); + out += m_pixel_size; + process_bg(sx[1], sy[1], block->in_frame, out); + out += m_pixel_size; + process_bg(sx[2], sy[2], block->in_frame, out); + out += m_pixel_size; + process_bg(sx[3], sy[3], block->in_frame, out); + } + } +} + + +#else +void Kaleid0sc0pe::process_block(Block *block) +{ + for (std::uint32_t y = block->y_start; y <= block->y_end; ++y) { + for (std::uint32_t x = block->x_start; x <= block->x_end; ++x) { + std::uint8_t* out = lookup(block->out_frame, x, y); + + Reflect_info info = calculate_reflect_info(x, y); + + if (info.segment_number) { + float reflection_angle = (info.segment_number * m_segment_width); + reflection_angle -= info.segment_number % 2 ? (m_segment_width - 2 * (info.reference_angle - reflection_angle)) : 0; + + reflection_angle *= std::signbit(info.angle) ? 1 : -1; + float cos_angle = std::cos(reflection_angle); + float sin_angle = std::sin(reflection_angle); + float source_x = info.screen_x * cos_angle - info.screen_y * sin_angle; + float source_y = info.screen_y * cos_angle + info.screen_x * sin_angle; + + from_screen(&source_x, &source_y); + + if (m_edge_reflect) { + if (source_x < 0) { + source_x = -source_x; + } else if (source_x > m_width - 10e-4f) { + source_x = m_width - (source_x - m_width + 10e-4f); + } if (source_y < 0) { + source_y = -source_y; + } else if (source_y > m_height - 10e-4f) { + source_y = m_height - (source_y - m_height + 10e-4f); + } + std::memcpy(out, lookup(block->in_frame, static_cast(source_x), static_cast(source_y)), m_pixel_size); + } else { + process_bg(source_x, source_y, block->in_frame, out); + } + } else { + std::memcpy(out, lookup(block->in_frame, x, y), m_pixel_size); + } + } + } +} +#endif + +std::uint8_t colours[63][3] = { + { 0x00, 0xFF, 0x00 }, + { 0x00, 0x00, 0xFF }, + { 0xFF, 0x00, 0x00 }, + { 0x01, 0xFF, 0xFE }, + { 0xFF, 0xA6, 0xFE }, + { 0xFF, 0xDB, 0x66 }, + { 0x00, 0x64, 0x01 }, + { 0x01, 0x00, 0x67 }, + { 0x95, 0x00, 0x3A }, + { 0x00, 0x7D, 0xB5 }, + { 0xFF, 0x00, 0xF6 }, + { 0xFF, 0xEE, 0xE8 }, + { 0x77, 0x4D, 0x00 }, + { 0x90, 0xFB, 0x92 }, + { 0x00, 0x76, 0xFF }, + { 0xD5, 0xFF, 0x00 }, + { 0xFF, 0x93, 0x7E }, + { 0x6A, 0x82, 0x6C }, + { 0xFF, 0x02, 0x9D }, + { 0xFE, 0x89, 0x00 }, + { 0x7A, 0x47, 0x82 }, + { 0x7E, 0x2D, 0xD2 }, + { 0x85, 0xA9, 0x00 }, + { 0xFF, 0x00, 0x56 }, + { 0xA4, 0x24, 0x00 }, + { 0x00, 0xAE, 0x7E }, + { 0x68, 0x3D, 0x3B }, + { 0xBD, 0xC6, 0xFF }, + { 0x26, 0x34, 0x00 }, + { 0xBD, 0xD3, 0x93 }, + { 0x00, 0xB9, 0x17 }, + { 0x9E, 0x00, 0x8E }, + { 0x00, 0x15, 0x44 }, + { 0xC2, 0x8C, 0x9F }, + { 0xFF, 0x74, 0xA3 }, + { 0x01, 0xD0, 0xFF }, + { 0x00, 0x47, 0x54 }, + { 0xE5, 0x6F, 0xFE }, + { 0x78, 0x82, 0x31 }, + { 0x0E, 0x4C, 0xA1 }, + { 0x91, 0xD0, 0xCB }, + { 0xBE, 0x99, 0x70 }, + { 0x96, 0x8A, 0xE8 }, + { 0xBB, 0x88, 0x00 }, + { 0x43, 0x00, 0x2C }, + { 0xDE, 0xFF, 0x74 }, + { 0x00, 0xFF, 0xC6 }, + { 0xFF, 0xE5, 0x02 }, + { 0x62, 0x0E, 0x00 }, + { 0x00, 0x8F, 0x9C }, + { 0x98, 0xFF, 0x52 }, + { 0x75, 0x44, 0xB1 }, + { 0xB5, 0x00, 0xFF }, + { 0x00, 0xFF, 0x78 }, + { 0xFF, 0x6E, 0x41 }, + { 0x00, 0x5F, 0x39 }, + { 0x6B, 0x68, 0x82 }, + { 0x5F, 0xAD, 0x4E }, + { 0xA7, 0x57, 0x40 }, + { 0xA5, 0xFF, 0xD2 }, + { 0xFF, 0xB1, 0x67 }, + { 0x00, 0x9B, 0xFF }, + { 0xE8, 0x5E, 0xBE } +}; + +std::int32_t Kaleid0sc0pe::set_segment_direction(Direction direction) +{ + m_segment_direction = direction; + m_n_segments = 0; + return 0; +} + +libkaleid0sc0pe::Kaleid0sc0pe::Direction Kaleid0sc0pe::get_segment_direction() const +{ + return m_segment_direction; +} + +std::int32_t Kaleid0sc0pe::process(const void* in_frame, void* out_frame) +{ + if (in_frame == nullptr || out_frame == nullptr) { + return -2; + } +#ifdef __SSE2__ + if (m_width % 4 != 0) { + return -2; + } +#endif + if (m_n_segments == 0) { + init(); + } +#ifdef NO_FUTURE + Block block(reinterpret_cast(in_frame), + reinterpret_cast(out_frame), + 0, 0, + m_width - 1, m_height - 1); +#ifdef __SSE2__ + if (m_edge_reflect) { + process_block(&block); + } else { + process_block_bg(&block); + } +#else + process_block(&block); +#endif +#else + if (m_n_threads == 1) { + Block block(reinterpret_cast(in_frame), + reinterpret_cast(out_frame), + 0, 0, + m_width - 1, m_height - 1); +#ifdef __SSE2__ + if (m_edge_reflect) { + process_block(&block); + } else { + process_block_bg(&block); + } +#else + process_block(&block); +#endif + } else { + std::uint32_t n_threads = m_n_threads == 0 ? std::thread::hardware_concurrency() : m_n_threads; + + std::vector> futures; + std::vector> blocks; + + std::uint32_t block_height = m_height / n_threads; + std::uint32_t y_start = 0; + std::uint32_t y_end = m_height - block_height * (n_threads - 1) - 1; + + for (std::uint32_t i = 0; i < n_threads; ++i) { + blocks.emplace_back(new Block( + reinterpret_cast(in_frame), + reinterpret_cast(out_frame), + 0, y_start, + m_width - 1, y_end)); + +#ifdef __SSE2__ + futures.push_back(std::async(std::launch::async, m_edge_reflect ? &Kaleid0sc0pe::process_block : &Kaleid0sc0pe::process_block_bg, this, blocks[i].get())); +#else + futures.push_back(std::async(std::launch::async, &Kaleid0sc0pe::process_block, this, blocks[i].get())); +#endif + y_start = y_end + 1; + y_end += block_height; + } + for (auto& f : futures) { + f.wait(); + } + } +#endif + + return 0; +} + +std::int32_t Kaleid0sc0pe::set_threading(std::uint32_t threading) +{ + m_n_threads = threading; + return 0; +} + +std::uint32_t Kaleid0sc0pe::get_threading() const +{ + return m_n_threads; +} + +std::int32_t Kaleid0sc0pe::visualise(void* out_frame) +{ + if (out_frame == nullptr) { + return -2; + } +#ifdef __SSE2__ + if (m_width % 4 != 0) { + return -2; + } +#endif + if (m_n_segments == 0) { + init(); + } + + for (std::uint32_t y = 0; y < m_height; ++y) { +#ifdef __SSE2__ + for (std::uint32_t x = 0; x < m_width; x+=4) { +#else + for (std::uint32_t x = 0; x < m_width; ++x) { +#endif + std::uint8_t* out = lookup(reinterpret_cast(out_frame), x, y); +#ifdef __SSE2__ + ALIGN16_BEG int ALIGN16_END mx[4] = { static_cast(x), static_cast(x) + 1, static_cast(x) + 2, static_cast(x) + 3}; + ALIGN16_BEG int ALIGN16_END my[4] = { static_cast(y), static_cast(y), static_cast(y), static_cast(y) }; + + Reflect_info info = calculate_reflect_info((__m128i*)mx, (__m128i*)my); + //float* segment_number = reinterpret_cast(&info.segment_number); + std::int32_t* segment_number = reinterpret_cast(&info.segment_number_i); + std::uint32_t col_idx = (*segment_number) % 63; + out[0] = colours[col_idx][0]; + out[1] = colours[col_idx][1]; + out[2] = colours[col_idx][2]; + if (m_num_components > 3) { + out[3] = 0xff; + out++; + } + segment_number++; + out += 3; + + col_idx = (*segment_number) % 63; + out[0] = colours[col_idx][0]; + out[1] = colours[col_idx][1]; + out[2] = colours[col_idx][2]; + if (m_num_components > 3) { + out[3] = 0xff; + out++; + } + segment_number++; + out += 3; + + col_idx = (*segment_number) % 63; + out[0] = colours[col_idx][0]; + out[1] = colours[col_idx][1]; + out[2] = colours[col_idx][2]; + if (m_num_components > 3) { + out[3] = 0xff; + out++; + } + segment_number++; + out += 3; + + col_idx = (*segment_number) % 63; + out[0] = colours[col_idx][0]; + out[1] = colours[col_idx][1]; + out[2] = colours[col_idx][2]; + if (m_num_components > 3) { + out[3] = 0xff; + out++; + } + +#else + Reflect_info info = calculate_reflect_info(x, y); + std::uint32_t col_idx = info.segment_number % 63; + out[0] = colours[col_idx][0]; + out[1] = colours[col_idx][1]; + out[2] = colours[col_idx][2]; + if (m_num_components > 3) { + out[3] = 0xff; + } +#endif + + } + } + return 0; +} + +} // namespace libkaleid0sc0pe diff --git a/src/filter/kaleid0sc0pe/kaleid0sc0pe.h b/src/filter/kaleid0sc0pe/kaleid0sc0pe.h new file mode 100644 index 0000000..699cde7 --- /dev/null +++ b/src/filter/kaleid0sc0pe/kaleid0sc0pe.h @@ -0,0 +1,279 @@ +/* + * kaleid0sc0pe.h + * Copyright (C) 2020-2023 Brendan Hack (github@bendys.com) + * This file is part of a Frei0r plugin that applies a kaleidoscope + * effect. + * Version 1.1 july 2023 + * + * The kaleidoscope class definition. + * + * This source code is free software; you can redistribute it and/or + * modify it under the terms of the GNU Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer + * to the GNU Public License for more details. + * + * You should have received a copy of the GNU Public License along + * with this source code; if not, write to: Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#ifndef SRC_FILTER_KALEID0SC0PE_KALEID0SC0PE_H_ +#define SRC_FILTER_KALEID0SC0PE_KALEID0SC0PE_H_ 1 + +#include "ikaleid0sc0pe.h" + +#include +#include +#include + +#ifdef NO_SSE2 +#ifdef __SSE2__ +#undef __SSE2__ +#endif +#else +// set sse2 flag on windows +#if _M_IX86_FP == 2 || _M_X64 == 100 +#ifndef _M_ARM +#define __SSE2__ +#endif +#endif +#endif + +#ifdef __SSE2__ +#include +#endif + +namespace libkaleid0sc0pe { + +/** + * Class which implements the kaleid0sc0pe effect + */ +class Kaleid0sc0pe: public IKaleid0sc0pe { +public: + /** + * Constructor + * @param width the frame width + * @param height the frame height + * @param component_size the byte size of each frame pixel component + * @param num_components the number of components per pixel + * @param stride the image stride, if \c 0 then calculated as \p width * \p component_size * \p num_components + */ + Kaleid0sc0pe(std::uint32_t width, std::uint32_t height, std::uint32_t component_size, std::uint32_t num_components, std::uint32_t stride = 0); + + virtual std::int32_t set_origin(float x, float y); + + virtual float get_origin_x() const; + + virtual float get_origin_y() const; + + virtual std::int32_t set_segmentation(std::uint32_t segmentation); + + virtual std::uint32_t get_segmentation() const; + + virtual std::int32_t set_edge_threshold(std::uint32_t threshold); + + virtual std::uint32_t get_edge_threshold() const; + + virtual std::int32_t set_segment_direction(Direction direction); + + virtual Direction get_segment_direction() const; + + virtual std::int32_t set_preferred_corner(Corner corner); + + virtual Corner get_preferred_corner() const; + + virtual std::int32_t set_preferred_corner_search_direction(Direction direction); + + virtual Direction get_preferred_corner_search_direction() const; + + virtual std::int32_t set_reflect_edges(bool reflect); + + virtual bool get_reflect_edges() const; + + virtual std::int32_t set_background_colour(void* colour); + + virtual void *get_background_colour() const; + + virtual std::int32_t set_source_segment(float angle); + + virtual float get_source_segment() const; + + virtual std::int32_t process(const void* in_frame, void* out_frame); + + virtual std::int32_t set_threading(std::uint32_t threading); + + virtual std::uint32_t get_threading() const; + + virtual std::int32_t visualise(void* out_frame); + +private: + void init(); + +#ifdef __SSE2__ + /// Defines reflection information for a given point in the frame + struct Reflect_info { + __m128 screen_x; ///< x coordinate in screen space (range -0.5->0.5, left negative) + __m128 screen_y; ///< y coordinate in screen space (range -0.5->0.5, top negative) + __m128 angle; ///< angle from this point to the start of the source segment + __m128 segment_number; ///< segment number the point resides in + __m128i segment_number_i; + __m128 reference_angle; ///< positive angle to start of source segment + }; + + Reflect_info calculate_reflect_info(__m128i *x, __m128i *y); + + /// Converts coordinates to screen space + /// @param x x coordinate + /// @param y y coordinate + /// @param sx source x coordinate + /// @param sy source y coordinate + void to_screen(__m128 *x, __m128 *y, __m128i *sx, __m128i *sy); + + /// Converts coordinates from screen space in place + /// @param x x coordinate + /// @param y y coordinate + void from_screen(__m128 *x, __m128 *y); + + /// Rotate the four coordinates from x,y to x+4,y and store results in + /// source_x,source_y + /// @param x x coordinate to start rotate from + /// @param y y coordinate to rotate + /// @param source_x receives the x coordiante results + /// @param source_y receives the y coordinate results + inline void rotate(int x, int y, __m128 *source_x, __m128 *source_y); +#else + /// Defines reflection information for a given point in the frame + struct Reflect_info { + float screen_x; ///< x coordinate in screen space (range -0.5->0.5, left negative) + float screen_y; ///< y coordinate in screen space (range -0.5->0.5, top negative) + float angle; ///< angle from this point to the start of the source segment + std::uint32_t segment_number; ///< segment number the point resides in + float reference_angle; ///< positive angle to start of source segment + }; + + /// Calculates the reflection information for a given point. + /// NB: init() must have already been called. + /// @param x the x coordinate + /// @param x the y coordinate + /// @return the reflection information for the point + Reflect_info calculate_reflect_info(std::uint32_t x, std::uint32_t y); + + /// Converts coordinates to screen space + /// @param x recieves x coordinate + /// @param y recieves y coordinate + /// @param sx source x coordinate + /// @param sy source y coordinate + void to_screen(float *x, float *y, std::uint32_t sx, std::uint32_t sy); + + /// Converts coordinates from screen space in place + /// @param x x coordinate + /// @param y y coordinate + void from_screen(float *x, float *y); +#endif + /// A block of data to process + struct Block { + const std::uint8_t* in_frame; + std::uint8_t* out_frame; + std::uint32_t x_start; + std::uint32_t y_start; + std::uint32_t x_end; + std::uint32_t y_end; + + /// \param in_frame the input frame + /// \param out_frame the output frame + /// \param x_start start x coordinate of block to process + /// \param y_start start y coordinate of block to process + /// \param x_end end x coordinate of block to process (inclusive) + /// \param y_end end y coordinate of block to process (inclusive) + Block(const std::uint8_t* _in_frame, std::uint8_t* _out_frame, std::uint32_t _x_start, std::uint32_t _y_start, std::uint32_t _x_end, std::uint32_t _y_end): + in_frame(_in_frame), + out_frame(_out_frame), + x_start(_x_start), + y_start(_y_start), + x_end(_x_end), + y_end(_y_end) + {} + }; + + /// Process a block + void process_block(Block *block); + + /// Copy pixel x,y from \p in to \p out using the background colour + /// if the pixel is out of range + /// @param x x coordinate to copy + /// @param y y coordinate to copy + /// @param in the first pixel in the source image + /// @param out destination + void process_bg(float x, float y, const std::uint8_t* in, std::uint8_t* out); + + +#ifdef __SSE2__ + // Process a block using background colour copy + void process_block_bg(Block* block); +#endif + + std::uint8_t *lookup(std::uint8_t *p, std::uint32_t x, std::uint32_t y); + + const std::uint8_t* lookup(const std::uint8_t* p, std::uint32_t x, std::uint32_t y); + + std::uint32_t m_width; + std::uint32_t m_height; + std::uint32_t m_component_size; + std::uint32_t m_num_components; + std::uint32_t m_stride; + std::uint32_t m_pixel_size; + + float m_aspect; + + float m_origin_x; + float m_origin_y; + float m_origin_native_x; + float m_origin_native_y; + + std::uint32_t m_segmentation; + Direction m_segment_direction; + + Corner m_preferred_corner; + Direction m_preferred_search_dir; + + bool m_edge_reflect; + + void* m_background_colour; + std::uint32_t m_edge_threshold; + + float m_source_segment_angle; + + std::uint32_t m_n_segments; + float m_start_angle; + float m_segment_width; + + std::uint32_t m_n_threads; + +#ifdef __SSE2__ + __m128 m_sse_aspect; + __m128 m_sse_origin_native_x; + __m128 m_sse_origin_native_y; + __m128 m_sse_start_angle; + __m128 m_sse_segment_width; + __m128 m_sse_half_segment_width; + __m128 m_sse_ps_0; + __m128 m_sse_ps_1; + __m128 m_sse_ps_2; + __m128i m_sse_epi32_1; + __m128i m_sse_epi32_2; + __m128i m_sse_shift_1; + __m128 m_sse_width; + __m128 m_sse_height; + __m128 m_sse_width_m1; + __m128 m_sse_height_m1; +#endif +}; + +} // namespace libkaleid0sc0pe + +#endif // SRC_FILTER_KALEID0SC0PE_KALEID0SC0PE_H_ diff --git a/src/filter/kaleid0sc0pe/kaleid0sc0pe.xml b/src/filter/kaleid0sc0pe/kaleid0sc0pe.xml new file mode 100644 index 0000000..437a8c2 --- /dev/null +++ b/src/filter/kaleid0sc0pe/kaleid0sc0pe.xml @@ -0,0 +1,50 @@ + + + Kaleid0sc0pe + Does what a kaleidoscope does + Brendan Hack + + Origin-X + + + Origin-Y + + + segmentation + + + Manual source segment + + + Centred,Anti Clockwise,Clockwise + Rotation direction + + + Source angle + + + Reflect into edges + + + Edge Threshold + + + Top Right,Top Left,Bottom Left,Bottom Right + Preferred Corner + + + Search CW for preferred corner + + + Background Colour + + + Background Alpha + + + Multithreaded + + + Thread count + + diff --git a/src/filter/kaleid0sc0pe/new-years-day-2024-source-480.jpg b/src/filter/kaleid0sc0pe/new-years-day-2024-source-480.jpg new file mode 100644 index 0000000..0b3f4de Binary files /dev/null and b/src/filter/kaleid0sc0pe/new-years-day-2024-source-480.jpg differ diff --git a/src/filter/kaleid0sc0pe/sse_mathfun.h b/src/filter/kaleid0sc0pe/sse_mathfun.h new file mode 100644 index 0000000..fd0570f --- /dev/null +++ b/src/filter/kaleid0sc0pe/sse_mathfun.h @@ -0,0 +1,711 @@ +/* SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log + + Inspired by Intel Approximate Math library, and based on the + corresponding algorithms of the cephes math library + + The default is to use the SSE1 version. If you define USE_SSE2 the + the SSE2 intrinsics will be used in place of the MMX intrinsics. Do + not expect any significant performance improvement with SSE2. +*/ + +/* Copyright (C) 2007 Julien Pommier + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + (this is the zlib license) +*/ + +#include + +/* yes I know, the top of this file is quite ugly */ + +#ifdef _MSC_VER /* visual c++ */ +# define ALIGN16_BEG __declspec(align(16)) +# define ALIGN16_END +#else /* gcc or icc */ +# define ALIGN16_BEG +# define ALIGN16_END __attribute__((aligned(16))) +#endif + +/* __m128 is ugly to write */ +typedef __m128 v4sf; // vector of 4 float (sse1) + +#ifdef USE_SSE2 +# include +typedef __m128i v4si; // vector of 4 int (sse2) +#else +typedef __m64 v2si; // vector of 2 int (mmx) +#endif + +/* declare some SSE constants -- why can't I figure a better way to do that? */ +#define _PS_CONST(Name, Val) \ + static const ALIGN16_BEG float _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val } +#define _PI32_CONST(Name, Val) \ + static const ALIGN16_BEG int _pi32_##Name[4] ALIGN16_END = { Val, Val, Val, Val } +#define _PS_CONST_TYPE(Name, Type, Val) \ + static const ALIGN16_BEG Type _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val } + +_PS_CONST(1 , 1.0f); +_PS_CONST(0p5, 0.5f); +/* the smallest non denormalized float number */ +_PS_CONST_TYPE(min_norm_pos, int, 0x00800000); +_PS_CONST_TYPE(mant_mask, int, 0x7f800000); +_PS_CONST_TYPE(inv_mant_mask, int, ~0x7f800000); + +_PS_CONST_TYPE(sign_mask, int, (int)0x80000000); +_PS_CONST_TYPE(inv_sign_mask, int, ~0x80000000); + +_PI32_CONST(1, 1); +_PI32_CONST(inv1, ~1); +_PI32_CONST(2, 2); +_PI32_CONST(4, 4); +_PI32_CONST(0x7f, 0x7f); + +_PS_CONST(cephes_SQRTHF, 0.707106781186547524); +_PS_CONST(cephes_log_p0, 7.0376836292E-2); +_PS_CONST(cephes_log_p1, - 1.1514610310E-1); +_PS_CONST(cephes_log_p2, 1.1676998740E-1); +_PS_CONST(cephes_log_p3, - 1.2420140846E-1); +_PS_CONST(cephes_log_p4, + 1.4249322787E-1); +_PS_CONST(cephes_log_p5, - 1.6668057665E-1); +_PS_CONST(cephes_log_p6, + 2.0000714765E-1); +_PS_CONST(cephes_log_p7, - 2.4999993993E-1); +_PS_CONST(cephes_log_p8, + 3.3333331174E-1); +_PS_CONST(cephes_log_q1, -2.12194440e-4); +_PS_CONST(cephes_log_q2, 0.693359375); + +#ifndef USE_SSE2 +typedef union xmm_mm_union { + __m128 xmm; + __m64 mm[2]; +} xmm_mm_union; + +#define COPY_XMM_TO_MM(xmm_, mm0_, mm1_) { \ + xmm_mm_union u; u.xmm = xmm_; \ + mm0_ = u.mm[0]; \ + mm1_ = u.mm[1]; \ +} + +#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { \ + xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; \ + } + +#endif // USE_SSE2 + +/* natural logarithm computed for 4 simultaneous float + return NaN for x <= 0 +*/ +v4sf log_ps(v4sf x) { +#ifdef USE_SSE2 + v4si emm0; +#else + v2si mm0, mm1; +#endif + v4sf one = *(v4sf*)_ps_1; + + v4sf invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps()); + + x = _mm_max_ps(x, *(v4sf*)_ps_min_norm_pos); /* cut off denormalized stuff */ + +#ifndef USE_SSE2 + /* part 1: x = frexpf(x, &e); */ + COPY_XMM_TO_MM(x, mm0, mm1); + mm0 = _mm_srli_pi32(mm0, 23); + mm1 = _mm_srli_pi32(mm1, 23); +#else + emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23); +#endif + /* keep only the fractional part */ + x = _mm_and_ps(x, *(v4sf*)_ps_inv_mant_mask); + x = _mm_or_ps(x, *(v4sf*)_ps_0p5); + +#ifndef USE_SSE2 + /* now e=mm0:mm1 contain the really base-2 exponent */ + mm0 = _mm_sub_pi32(mm0, *(v2si*)_pi32_0x7f); + mm1 = _mm_sub_pi32(mm1, *(v2si*)_pi32_0x7f); + v4sf e = _mm_cvtpi32x2_ps(mm0, mm1); + _mm_empty(); /* bye bye mmx */ +#else + emm0 = _mm_sub_epi32(emm0, *(v4si*)_pi32_0x7f); + v4sf e = _mm_cvtepi32_ps(emm0); +#endif + + e = _mm_add_ps(e, one); + + /* part2: + if( x < SQRTHF ) { + e -= 1; + x = x + x - 1.0; + } else { x = x - 1.0; } + */ + v4sf mask = _mm_cmplt_ps(x, *(v4sf*)_ps_cephes_SQRTHF); + v4sf tmp = _mm_and_ps(x, mask); + x = _mm_sub_ps(x, one); + e = _mm_sub_ps(e, _mm_and_ps(one, mask)); + x = _mm_add_ps(x, tmp); + + + v4sf z = _mm_mul_ps(x,x); + + v4sf y = *(v4sf*)_ps_cephes_log_p0; + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p1); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p2); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p3); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p4); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p5); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p6); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p7); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p8); + y = _mm_mul_ps(y, x); + + y = _mm_mul_ps(y, z); + + + tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q1); + y = _mm_add_ps(y, tmp); + + + tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5); + y = _mm_sub_ps(y, tmp); + + tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q2); + x = _mm_add_ps(x, y); + x = _mm_add_ps(x, tmp); + x = _mm_or_ps(x, invalid_mask); // negative arg will be NAN + return x; +} + +_PS_CONST(exp_hi, 88.3762626647949f); +_PS_CONST(exp_lo, -88.3762626647949f); + +_PS_CONST(cephes_LOG2EF, 1.44269504088896341); +_PS_CONST(cephes_exp_C1, 0.693359375); +_PS_CONST(cephes_exp_C2, -2.12194440e-4); + +_PS_CONST(cephes_exp_p0, 1.9875691500E-4); +_PS_CONST(cephes_exp_p1, 1.3981999507E-3); +_PS_CONST(cephes_exp_p2, 8.3334519073E-3); +_PS_CONST(cephes_exp_p3, 4.1665795894E-2); +_PS_CONST(cephes_exp_p4, 1.6666665459E-1); +_PS_CONST(cephes_exp_p5, 5.0000001201E-1); + +v4sf exp_ps(v4sf x) { + v4sf tmp = _mm_setzero_ps(), fx; +#ifdef USE_SSE2 + v4si emm0; +#else + v2si mm0, mm1; +#endif + v4sf one = *(v4sf*)_ps_1; + + x = _mm_min_ps(x, *(v4sf*)_ps_exp_hi); + x = _mm_max_ps(x, *(v4sf*)_ps_exp_lo); + + /* express exp(x) as exp(g + n*log(2)) */ + fx = _mm_mul_ps(x, *(v4sf*)_ps_cephes_LOG2EF); + fx = _mm_add_ps(fx, *(v4sf*)_ps_0p5); + + /* how to perform a floorf with SSE: just below */ +#ifndef USE_SSE2 + /* step 1 : cast to int */ + tmp = _mm_movehl_ps(tmp, fx); + mm0 = _mm_cvttps_pi32(fx); + mm1 = _mm_cvttps_pi32(tmp); + /* step 2 : cast back to float */ + tmp = _mm_cvtpi32x2_ps(mm0, mm1); +#else + emm0 = _mm_cvttps_epi32(fx); + tmp = _mm_cvtepi32_ps(emm0); +#endif + /* if greater, substract 1 */ + v4sf mask = _mm_cmpgt_ps(tmp, fx); + mask = _mm_and_ps(mask, one); + fx = _mm_sub_ps(tmp, mask); + + tmp = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C1); + v4sf z = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C2); + x = _mm_sub_ps(x, tmp); + x = _mm_sub_ps(x, z); + + z = _mm_mul_ps(x,x); + + v4sf y = *(v4sf*)_ps_cephes_exp_p0; + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p1); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p2); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p3); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p4); + y = _mm_mul_ps(y, x); + y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p5); + y = _mm_mul_ps(y, z); + y = _mm_add_ps(y, x); + y = _mm_add_ps(y, one); + + /* build 2^n */ +#ifndef USE_SSE2 + z = _mm_movehl_ps(z, fx); + mm0 = _mm_cvttps_pi32(fx); + mm1 = _mm_cvttps_pi32(z); + mm0 = _mm_add_pi32(mm0, *(v2si*)_pi32_0x7f); + mm1 = _mm_add_pi32(mm1, *(v2si*)_pi32_0x7f); + mm0 = _mm_slli_pi32(mm0, 23); + mm1 = _mm_slli_pi32(mm1, 23); + + v4sf pow2n; + COPY_MM_TO_XMM(mm0, mm1, pow2n); + _mm_empty(); +#else + emm0 = _mm_cvttps_epi32(fx); + emm0 = _mm_add_epi32(emm0, *(v4si*)_pi32_0x7f); + emm0 = _mm_slli_epi32(emm0, 23); + v4sf pow2n = _mm_castsi128_ps(emm0); +#endif + y = _mm_mul_ps(y, pow2n); + return y; +} + +_PS_CONST(minus_cephes_DP1, -0.78515625); +_PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4); +_PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8); +_PS_CONST(sincof_p0, -1.9515295891E-4); +_PS_CONST(sincof_p1, 8.3321608736E-3); +_PS_CONST(sincof_p2, -1.6666654611E-1); +_PS_CONST(coscof_p0, 2.443315711809948E-005); +_PS_CONST(coscof_p1, -1.388731625493765E-003); +_PS_CONST(coscof_p2, 4.166664568298827E-002); +_PS_CONST(cephes_FOPI, 1.27323954473516); // 4 / M_PI + + +/* evaluation of 4 sines at onces, using only SSE1+MMX intrinsics so + it runs also on old athlons XPs and the pentium III of your grand + mother. + + The code is the exact rewriting of the cephes sinf function. + Precision is excellent as long as x < 8192 (I did not bother to + take into account the special handling they have for greater values + -- it does not return garbage for arguments over 8192, though, but + the extra precision is missing). + + Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the + surprising but correct result. + + Performance is also surprisingly good, 1.33 times faster than the + macos vsinf SSE2 function, and 1.5 times faster than the + __vrs4_sinf of amd's ACML (which is only available in 64 bits). Not + too bad for an SSE1 function (with no special tuning) ! + However the latter libraries probably have a much better handling of NaN, + Inf, denormalized and other special arguments.. + + On my core 1 duo, the execution of this function takes approximately 95 cycles. + + From what I have observed on the experiments with Intel AMath lib, switching to an + SSE2 version would improve the perf by only 10%. + + Since it is based on SSE intrinsics, it has to be compiled at -O2 to + deliver full speed. +*/ +v4sf sin_ps(v4sf x) { // any x + v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; + +#ifdef USE_SSE2 + v4si emm0, emm2; +#else + v2si mm0, mm1, mm2, mm3; +#endif + sign_bit = x; + /* take the absolute value */ + x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask); + /* extract the sign bit (upper one) */ + sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask); + + /* scale by 4/Pi */ + y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI); + +#ifdef USE_SSE2 + /* store the integer part of y in mm0 */ + emm2 = _mm_cvttps_epi32(y); + /* j=(j+1) & (~1) (see the cephes sources) */ + emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1); + emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1); + y = _mm_cvtepi32_ps(emm2); + + /* get the swap sign flag */ + emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4); + emm0 = _mm_slli_epi32(emm0, 29); + /* get the polynom selection mask + there is one polynom for 0 <= x <= Pi/4 + and another one for Pi/4> precision OK for the tan_ps <<- + +checking tan on [-0.49*Pi, 0.49*Pi] +max deviation from tanf(x): 3.8147e-06 at -0.490000009841*Pi, max deviation from cephes_tan(x): +9.53674e-07 + ->> precision OK for the tan_ps <<- + +checking cot on [0.2*Pi, 0.7*Pi] +max deviation from cotf(x): 1.19209e-07 at 0.204303119606*Pi, max deviation from cephes_cot(x): +1.19209e-07 + ->> precision OK for the cot_ps <<- + +checking cot on [0.01*Pi, 0.99*Pi] +max deviation from cotf(x): 3.8147e-06 at 0.987876517942*Pi, max deviation from cephes_cot(x): +9.53674e-07 + ->> precision OK for the cot_ps <<- + +With atan_ps and atan2_ps you get pretty good precision, atan_ps max deviation is < 2e-7 and +atan2_ps max deviation is < 2.5e-7 +*/ + +/* Copyright (C) 2016 Tolga Mizrak + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + (this is the zlib license) +*/ + +#pragma once + +#ifndef _SSE_MATHFUN_EXTENSION_H_INCLUDED_ +#define _SSE_MATHFUN_EXTENSION_H_INCLUDED_ + +#ifndef USE_SSE2 +#error sse1 & mmx version not implemented +#endif + +#ifdef _MSC_VER +#pragma warning( push ) +/* warning C4838: conversion from 'double' to 'const float' requires a narrowing conversion */ +#pragma warning( disable : 4838 ) +/* warning C4305: 'initializing': truncation from 'double' to 'const float' */ +#pragma warning( disable : 4305 ) +#endif + +#include "sse_mathfun.h" + +_PS_CONST( 0, 0 ); +_PS_CONST( 2, 2 ); +_PI32_CONST( neg1, 1 ); + +_PS_CONST( tancof_p0, 9.38540185543E-3 ); +_PS_CONST( tancof_p1, 3.11992232697E-3 ); +_PS_CONST( tancof_p2, 2.44301354525E-2 ); +_PS_CONST( tancof_p3, 5.34112807005E-2 ); +_PS_CONST( tancof_p4, 1.33387994085E-1 ); +_PS_CONST( tancof_p5, 3.33331568548E-1 ); + +_PS_CONST( tancot_eps, 1.0e-4 ); + +v4sf tancot_ps( v4sf x, int cotFlag ) +{ + v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; + +#ifdef USE_SSE2 + v4si emm2; +#else +#endif + sign_bit = x; + /* take the absolute value */ + x = _mm_and_ps( x, *(v4sf*)_ps_inv_sign_mask ); + /* extract the sign bit (upper one) */ + sign_bit = _mm_and_ps( sign_bit, *(v4sf*)_ps_sign_mask ); + + /* scale by 4/Pi */ + y = _mm_mul_ps( x, *(v4sf*)_ps_cephes_FOPI ); + +#ifdef USE_SSE2 + /* store the integer part of y in mm0 */ + emm2 = _mm_cvttps_epi32( y ); + /* j=(j+1) & (~1) (see the cephes sources) */ + emm2 = _mm_add_epi32( emm2, *(v4si*)_pi32_1 ); + emm2 = _mm_and_si128( emm2, *(v4si*)_pi32_inv1 ); + y = _mm_cvtepi32_ps( emm2 ); + + emm2 = _mm_and_si128( emm2, *(v4si*)_pi32_2 ); + emm2 = _mm_cmpeq_epi32( emm2, _mm_setzero_si128() ); + + v4sf poly_mask = _mm_castsi128_ps( emm2 ); +#else +#endif + /* The magic pass: "Extended precision modular arithmetic" + x = ((x - y * DP1) - y * DP2) - y * DP3; */ + xmm1 = *(v4sf*)_ps_minus_cephes_DP1; + xmm2 = *(v4sf*)_ps_minus_cephes_DP2; + xmm3 = *(v4sf*)_ps_minus_cephes_DP3; + xmm1 = _mm_mul_ps( y, xmm1 ); + xmm2 = _mm_mul_ps( y, xmm2 ); + xmm3 = _mm_mul_ps( y, xmm3 ); + v4sf z = _mm_add_ps( x, xmm1 ); + z = _mm_add_ps( z, xmm2 ); + z = _mm_add_ps( z, xmm3 ); + + v4sf zz = _mm_mul_ps( z, z ); + + y = *(v4sf*)_ps_tancof_p0; + y = _mm_mul_ps( y, zz ); + y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p1 ); + y = _mm_mul_ps( y, zz ); + y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p2 ); + y = _mm_mul_ps( y, zz ); + y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p3 ); + y = _mm_mul_ps( y, zz ); + y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p4 ); + y = _mm_mul_ps( y, zz ); + y = _mm_add_ps( y, *(v4sf*)_ps_tancof_p5 ); + y = _mm_mul_ps( y, zz ); + y = _mm_mul_ps( y, z ); + y = _mm_add_ps( y, z ); + + v4sf y2; + if( cotFlag ) { + y2 = _mm_xor_ps( y, *(v4sf*)_ps_sign_mask ); + /* y = _mm_rcp_ps( y ); */ + /* using _mm_rcp_ps here loses on way too much precision, better to do a div */ + y = _mm_div_ps( *(v4sf*)_ps_1, y ); + } else { + /* y2 = _mm_rcp_ps( y ); */ + /* using _mm_rcp_ps here loses on way too much precision, better to do a div */ + y2 = _mm_div_ps( *(v4sf*)_ps_1, y ); + y2 = _mm_xor_ps( y2, *(v4sf*)_ps_sign_mask ); + } + + /* select the correct result from the two polynoms */ + xmm3 = poly_mask; + y = _mm_and_ps( xmm3, y ); + y2 = _mm_andnot_ps( xmm3, y2 ); + y = _mm_or_ps( y, y2 ); + + /* update the sign */ + y = _mm_xor_ps( y, sign_bit ); + + return y; +} + +v4sf tan_ps( v4sf x ) { return tancot_ps( x, 0 ); } + +v4sf cot_ps( v4sf x ) { return tancot_ps( x, 1 ); } + +_PS_CONST( atanrange_hi, 2.414213562373095 ); +_PS_CONST( atanrange_lo, 0.4142135623730950 ); +const float PIF = 3.141592653589793238; +const float PIO2F = 1.5707963267948966192; +_PS_CONST( cephes_PIF, 3.141592653589793238 ); +_PS_CONST( cephes_PIO2F, 1.5707963267948966192 ); +_PS_CONST( cephes_PIO4F, 0.7853981633974483096 ); + +_PS_CONST( atancof_p0, 8.05374449538e-2 ); +_PS_CONST( atancof_p1, 1.38776856032E-1 ); +_PS_CONST( atancof_p2, 1.99777106478E-1 ); +_PS_CONST( atancof_p3, 3.33329491539E-1 ); + +v4sf atan_ps( v4sf x ) +{ + v4sf sign_bit, y; + + sign_bit = x; + /* take the absolute value */ + x = _mm_and_ps( x, *(v4sf*)_ps_inv_sign_mask ); + /* extract the sign bit (upper one) */ + sign_bit = _mm_and_ps( sign_bit, *(v4sf*)_ps_sign_mask ); + +/* range reduction, init x and y depending on range */ +#ifdef USE_SSE2 + /* x > 2.414213562373095 */ + v4sf cmp0 = _mm_cmpgt_ps( x, *(v4sf*)_ps_atanrange_hi ); + /* x > 0.4142135623730950 */ + v4sf cmp1 = _mm_cmpgt_ps( x, *(v4sf*)_ps_atanrange_lo ); + + /* x > 0.4142135623730950 && !( x > 2.414213562373095 ) */ + v4sf cmp2 = _mm_andnot_ps( cmp0, cmp1 ); + + /* -( 1.0/x ) */ + v4sf y0 = _mm_and_ps( cmp0, *(v4sf*)_ps_cephes_PIO2F ); + v4sf x0 = _mm_div_ps( *(v4sf*)_ps_1, x ); + x0 = _mm_xor_ps( x0, *(v4sf*)_ps_sign_mask ); + + v4sf y1 = _mm_and_ps( cmp2, *(v4sf*)_ps_cephes_PIO4F ); + /* (x-1.0)/(x+1.0) */ + v4sf x1_o = _mm_sub_ps( x, *(v4sf*)_ps_1 ); + v4sf x1_u = _mm_add_ps( x, *(v4sf*)_ps_1 ); + v4sf x1 = _mm_div_ps( x1_o, x1_u ); + + v4sf x2 = _mm_and_ps( cmp2, x1 ); + x0 = _mm_and_ps( cmp0, x0 ); + x2 = _mm_or_ps( x2, x0 ); + cmp1 = _mm_or_ps( cmp0, cmp2 ); + x2 = _mm_and_ps( cmp1, x2 ); + x = _mm_andnot_ps( cmp1, x ); + x = _mm_or_ps( x2, x ); + + y = _mm_or_ps( y0, y1 ); +#else +#error sse1 & mmx version not implemented +#endif + + v4sf zz = _mm_mul_ps( x, x ); + v4sf acc = *(v4sf*)_ps_atancof_p0; + acc = _mm_mul_ps( acc, zz ); + acc = _mm_sub_ps( acc, *(v4sf*)_ps_atancof_p1 ); + acc = _mm_mul_ps( acc, zz ); + acc = _mm_add_ps( acc, *(v4sf*)_ps_atancof_p2 ); + acc = _mm_mul_ps( acc, zz ); + acc = _mm_sub_ps( acc, *(v4sf*)_ps_atancof_p3 ); + acc = _mm_mul_ps( acc, zz ); + acc = _mm_mul_ps( acc, x ); + acc = _mm_add_ps( acc, x ); + y = _mm_add_ps( y, acc ); + + /* update the sign */ + y = _mm_xor_ps( y, sign_bit ); + + return y; +} + +v4sf atan2_ps( v4sf y, v4sf x ) +{ + v4sf x_eq_0 = _mm_cmpeq_ps( x, *(v4sf*)_ps_0 ); + v4sf x_gt_0 = _mm_cmpgt_ps( x, *(v4sf*)_ps_0 ); + v4sf x_le_0 = _mm_cmple_ps( x, *(v4sf*)_ps_0 ); + v4sf y_eq_0 = _mm_cmpeq_ps( y, *(v4sf*)_ps_0 ); + v4sf x_lt_0 = _mm_cmplt_ps( x, *(v4sf*)_ps_0 ); + v4sf y_lt_0 = _mm_cmplt_ps( y, *(v4sf*)_ps_0 ); + + v4sf zero_mask = _mm_and_ps( x_eq_0, y_eq_0 ); + v4sf zero_mask_other_case = _mm_and_ps( y_eq_0, x_gt_0 ); + zero_mask = _mm_or_ps( zero_mask, zero_mask_other_case ); + + v4sf pio2_mask = _mm_andnot_ps( y_eq_0, x_eq_0 ); + v4sf pio2_mask_sign = _mm_and_ps( y_lt_0, *(v4sf*)_ps_sign_mask ); + v4sf pio2_result = *(v4sf*)_ps_cephes_PIO2F; + pio2_result = _mm_xor_ps( pio2_result, pio2_mask_sign ); + pio2_result = _mm_and_ps( pio2_mask, pio2_result ); + + v4sf pi_mask = _mm_and_ps( y_eq_0, x_le_0 ); + v4sf pi = *(v4sf*)_ps_cephes_PIF; + v4sf pi_result = _mm_and_ps( pi_mask, pi ); + + v4sf swap_sign_mask_offset = _mm_and_ps( x_lt_0, y_lt_0 ); + swap_sign_mask_offset = _mm_and_ps( swap_sign_mask_offset, *(v4sf*)_ps_sign_mask ); + + v4sf offset0 = _mm_setzero_ps(); + v4sf offset1 = *(v4sf*)_ps_cephes_PIF; + offset1 = _mm_xor_ps( offset1, swap_sign_mask_offset ); + + v4sf offset = _mm_andnot_ps( x_lt_0, offset0 ); + offset = _mm_and_ps( x_lt_0, offset1 ); + + v4sf arg = _mm_div_ps( y, x ); + v4sf atan_result = atan_ps( arg ); + atan_result = _mm_add_ps( atan_result, offset ); + + /* select between zero_result, pio2_result and atan_result */ + + v4sf result = _mm_andnot_ps( zero_mask, pio2_result ); + atan_result = _mm_andnot_ps( pio2_mask, atan_result ); + atan_result = _mm_andnot_ps( pio2_mask, atan_result); + result = _mm_or_ps( result, atan_result ); + result = _mm_or_ps( result, pi_result ); + + return result; +} + +/* for convenience of calling simd sqrt */ +float sqrt_ps( float x ) +{ + v4sf sse_value = _mm_set_ps1( x ); + sse_value = _mm_sqrt_ps( sse_value ); + return _mm_cvtss_f32( sse_value ); +} +float rsqrt_ps( float x ) +{ + v4sf sse_value = _mm_set_ps1( x ); + sse_value = _mm_rsqrt_ps( sse_value ); + return _mm_cvtss_f32( sse_value ); +} + +/* atan2 implementation using atan, used as a reference to implement atan2_ps */ +float atan2_ref( float y, float x ) +{ + if( x == 0.0f ) { + if( y == 0.0f ) { + return 0.0f; + } + float result = _ps_cephes_PIO2F[0]; + if( y < 0.0f ) { + result = -result; + } + return result; + } + + if( y == 0.0f ) { + if( x > 0.0f ) { + return 0.0f; + } + return PIF; + } + + float offset = 0; + if( x < 0.0f ) { + offset = PIF; + if( y < 0.0f ) { + offset = -offset; + } + } + + v4sf val = _mm_set_ps1( y / x ); + val = atan_ps( val ); + return offset + _mm_cvtss_f32( val ); +} + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif diff --git a/src/filter/keyspillm0pup/CMakeLists.txt b/src/filter/keyspillm0pup/CMakeLists.txt index 5e5bc80..90ec389 100644 --- a/src/filter/keyspillm0pup/CMakeLists.txt +++ b/src/filter/keyspillm0pup/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET keyspillm0pup) if (MSVC) - set_source_files_properties (keyspillm0pup.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/keyspillm0pup/keyspillm0pup.c b/src/filter/keyspillm0pup/keyspillm0pup.c index a7be836..daa78c0 100644 --- a/src/filter/keyspillm0pup/keyspillm0pup.c +++ b/src/filter/keyspillm0pup/keyspillm0pup.c @@ -839,6 +839,8 @@ //--------------------------------------------------- void f0r_destruct(f0r_instance_t instance) { + inst* in = (inst*)instance; + free(in->liststr); free(instance); } diff --git a/src/filter/lenscorrection/CMakeLists.txt b/src/filter/lenscorrection/CMakeLists.txt index 3ca9175..e5740bf 100644 --- a/src/filter/lenscorrection/CMakeLists.txt +++ b/src/filter/lenscorrection/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET lenscorrection) if (MSVC) - set_source_files_properties (lenscorrection.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/letterb0xed/CMakeLists.txt b/src/filter/letterb0xed/CMakeLists.txt index 68df4cf..e4be355 100644 --- a/src/filter/letterb0xed/CMakeLists.txt +++ b/src/filter/letterb0xed/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET letterb0xed) if (MSVC) - set_source_files_properties (letterb0xed.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/levels/CMakeLists.txt b/src/filter/levels/CMakeLists.txt index ef66de8..081fcd8 100644 --- a/src/filter/levels/CMakeLists.txt +++ b/src/filter/levels/CMakeLists.txt @@ -7,7 +7,6 @@ set (TARGET levels) if (MSVC) - set_source_files_properties (levels.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/lightgraffiti/lightgraffiti.cpp b/src/filter/lightgraffiti/lightgraffiti.cpp index 2a699a3..9f9ae77 100644 --- a/src/filter/lightgraffiti/lightgraffiti.cpp +++ b/src/filter/lightgraffiti/lightgraffiti.cpp @@ -64,9 +64,15 @@ [3] http://kdenlive.org/users/granjow/writing-light-graffiti-effect */ + +#if defined(_MSC_VER) +#define _USE_MATH_DEFINES +#endif /* _MSC_VER */ +#include + #include "frei0r.hpp" -#include + #include #include #include diff --git a/src/filter/luminance/CMakeLists.txt b/src/filter/luminance/CMakeLists.txt index db99d31..03cf633 100644 --- a/src/filter/luminance/CMakeLists.txt +++ b/src/filter/luminance/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET luminance) if (MSVC) - set_source_files_properties (luminance.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/mask0mate/CMakeLists.txt b/src/filter/mask0mate/CMakeLists.txt index a4ae9db..b316273 100644 --- a/src/filter/mask0mate/CMakeLists.txt +++ b/src/filter/mask0mate/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET mask0mate) if (MSVC) - set_source_files_properties (mask0mate.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/measure/CMakeLists.txt b/src/filter/measure/CMakeLists.txt index 2f09f47..19529e0 100644 --- a/src/filter/measure/CMakeLists.txt +++ b/src/filter/measure/CMakeLists.txt @@ -1,17 +1,17 @@ -set (B_SOURCES pr0be.c measure.h font2.h) -set (F_SOURCES pr0file.c measure.h font2.h) +set (B_SOURCES measure_pr0be.c measure.h font2.h) +set (F_SOURCES measure_pr0file.c measure.h font2.h) if (MSVC) - set_source_files_properties (pr0be.c pr0file.c PROPERTIES LANGUAGE CXX) set (B_SOURCES ${B_SOURCES} ${FREI0R_DEF}) set (F_SOURCES ${F_SOURCES} ${FREI0R_DEF}) endif (MSVC) -add_library (pr0be MODULE ${B_SOURCES}) -add_library (pr0file MODULE ${F_SOURCES}) +# link_libraries(m) +add_library (measure_pr0be MODULE ${B_SOURCES}) +add_library (measure_pr0file MODULE ${F_SOURCES}) -set_target_properties (pr0be PROPERTIES PREFIX "") -set_target_properties (pr0file PROPERTIES PREFIX "") +set_target_properties (measure_pr0be PROPERTIES PREFIX "") +set_target_properties (measure_pr0file PROPERTIES PREFIX "") -install (TARGETS pr0be LIBRARY DESTINATION ${LIBDIR}) -install (TARGETS pr0file LIBRARY DESTINATION ${LIBDIR}) +install (TARGETS measure_pr0be LIBRARY DESTINATION ${LIBDIR}) +install (TARGETS measure_pr0file LIBRARY DESTINATION ${LIBDIR}) diff --git a/src/filter/measure/measure_pr0be.c b/src/filter/measure/measure_pr0be.c new file mode 100644 index 0000000..d9d7e17 --- /dev/null +++ b/src/filter/measure/measure_pr0be.c @@ -0,0 +1,748 @@ +/* +pr0be.c + +This frei0r plugin measures pixels in video +Version 0.1 jun 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +//compile: gcc -c -fPIC -Wall pr0be.c -o pr0be.o +//link: gcc -shared -o pr0be.so pr0be.o + +#include +#include +#include +#include +#include + +#include "font2.h" +#include "measure.h" + +double PI=3.14159265358979; + +//--------------------------------------------------------------- +void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c) +{ +int i,j; +int zx,kx,zy,ky; + +zx=x; if (zx<0) zx=0; +zy=y; if (zy<0) zy=0; +kx=x+wr; if (kx>w) kx=w; +ky=y+hr; if (ky>h) ky=h; +for (i=zy;iw) kx=w; +ky=y+hr; if (ky>h) ky=h; +for (i=zy;i127)) return; +if (x<0) return; +if ((x+8)>=w) return; +if (y<0) return; +if ((y+16)>=h)return; + +z=(c-32)%32+((c-32)/32)*512; + +for (i=0;i<16;i++) + for (j=0;j<8;j++) + if ((font2_bits[z+32*i]&(1<=10.0)&&(b<100.0)) ss=p1m1; + ss=p3m; + } + } +sprintf(s,"%s",ss); +} + +//------------------------------------------------------------- +//print avg,rms,min,max into a string +//u=units 0=0.0-1.0 1=0-255 +//m=sign 0=unsigned +//mm=1 print min/max +void izpis(char *str, char *lab, stat s, int u, int m, int mm) +{ +char fs[256],as[16],rs[16],ns[16],xs[16]; + +if (u==1) + { + s.avg=255.0*s.avg; + s.rms=255.0*s.rms; + s.min=255.0*s.min; + s.max=255.0*s.max; + } + +if (mm==1) + { + forstr(s.avg,1-u,m,as); + forstr(s.rms,1-u,0,rs); + forstr(s.min,1-u,m,ns); + forstr(s.max,1-u,m,xs); + sprintf(fs,"%s%s%s %s%s", lab, as, rs, ns, xs); + sprintf(str,fs,s.avg,s.rms,s.min,s.max); + } +else + { + forstr(s.avg,1-u,m,as); + forstr(s.rms,1-u,0,rs); + sprintf(fs,"%s%s%s", lab, as, rs); + sprintf(str,fs,s.avg,s.rms); + } +} + +//----------------------------------------------------------- +//probe size markers in the magnifier diaplay +void sxmarkers(float_rgba *s, int w, int h, int x0, int y0, int np, int sx, int sy, int vp) +{ +int np2,x,y,i,j; +float_rgba white={1.0,1.0,1.0,1.0}; + +np2=np/2+1; + +//top left +x=x0+(np2-sx/2)*vp-1; if (sx>np) x=x0; +y=y0+(np2-sy/2)*vp-1; if (sy>np) y=y0; +if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); +if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); +//top right +x=x0+(np2+sx/2+1)*vp-1; +y=y0+(np2-sy/2)*vp-1; if (sy>np) y=y0; +if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); +x=x0+(np2+sx/2)*vp; +y=y0+(np2-sy/2)*vp-1; if (sx>np) x=x0+(np+1)*vp-1; +if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); +//bottom left +x=x0+(np2-sx/2)*vp-1; +y=y0+(np2+sy/2)*vp; if (sy>np) y=y0+(np+1)*vp; +if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); +x=x0+(np2-sx/2)*vp-1; if (sx>np) x=x0; +y=y0+(np2+sy/2+1)*vp-1; +if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); +//bottom right +x=x0+(np2+sx/2)*vp+vp-1; +y=y0+(np2+sy/2)*vp; if (sy>np) y=y0+(np+1)*vp; +if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); +x=x0+(np2+sx/2)*vp; +y=y0+(np2+sy/2+1)*vp-1; if (sx>np) x=x0+(np+1)*vp-1; +if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); + +//"out of box" arrows +if (sx>np) + { + for (i=1;inp) + { + for (i=1;i7*w/12) *poz=0; //left +if (xw/2+30) *poz=0; //left +vp=9; //pixel size in magnifier +y0=h/20; +if (bw==1) //big window + { + vx=240; + vy = (m<=2) ? 320 : 300; + x0 = (*poz==0) ? h/20 : w-h/20-vx; + np=25; //size of magnifier + xn = (m<=2) ? x0+8 : x0+70; + yn=y0+(np+1)*vp+8; + } +else //small window + { + vx=152; + vy = (m<=2) ? 230 : 210; + x0 = (*poz==0) ? h/20 : w-h/20-vx; + np=15; //size of magnifier + xn = (m<=2) ? x0+15 : x0+25; + yn=y0+(np+1)*vp+8; + } +np2=np/2+1; +if (sha==1) vy=vy+20; + +//keep probe inside +if (x=(w-sx/2)) x=w-sx/2-1; +if (y=(h-sy/2)) y=h-sy/2-1; + +//info window background +darken_rectangle(s, w, h, x0, y0, vx, vy, 0.4); + +//magnifier background +draw_rectangle(s, w, h, x0+vp-1, y0+vp-1, np*vp+1, np*vp+1, black); +//sx,sy marks +sxmarkers(s, w, h, x0, y0, np, sx, sy, vp); +//magnifier pixels +for (i=0;i=0)&&(xp=0)&&(ypva) va=gg.avg; if (bb.avg>va) va=bb.avg; + li=rr.avg; + if (gg.avgva) va=gg.avg; if (bb.avg>va) va=bb.avg; + li=rr.avg; + if (gg.avg>8))*0.00392157; + sl[i].b=((float)((inframe[i] & 0x00FF0000)>>16))*0.00392157; + sl[i].a=((float)((inframe[i] & 0xFF000000)>>24))*0.00392157; + } +} + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ +return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ +return (v-min)/(max-min); +} + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ +int h; +int w; + +int mer; +int x; +int y; +int sx; +int sy; +int un; +int sha; +int bw; + +int poz; +float_rgba *sl; +} inst; + +//*********************************************** +// OBVEZNE FREI0R FUNKCIJE + +//----------------------------------------------- +int f0r_init() +{ +return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + +info->name="pr0be"; +info->author="Marko Cebokli"; +info->plugin_type=F0R_PLUGIN_TYPE_FILTER; +info->color_model=F0R_COLOR_MODEL_RGBA8888; +info->frei0r_version=FREI0R_MAJOR_VERSION; +info->major_version=0; +info->minor_version=1; +info->num_params=8; +info->explanation="Measure video values"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ +switch(param_index) + { + case 0: + info->name = "Measurement"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "What measurement to display"; + break; + case 1: + info->name = "X"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "X position of probe"; + break; + case 2: + info->name = "Y"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Y position of probe"; + break; + case 3: + info->name = "X size"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "X size of probe"; + break; + case 4: + info->name = "Y size"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Y size of probe"; + break; + case 5: + info->name = "256 scale"; + info->type = F0R_PARAM_BOOL; + info->explanation = "use 0-255 instead of 0.0-1.0"; + break; + case 6: + info->name = "Show alpha"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Display alpha value too"; + break; + case 7: + info->name = "Big window"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Display more data"; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ +inst *in; + +in=calloc(1,sizeof(inst)); +in->w=width; +in->h=height; + +in->mer=0; +in->x=width/2; +in->y=height/2; +in->sx=3; +in->sy=3; +in->un=0; +in->sha=0; +in->bw=0; + +in->poz=0; +in->sl=(float_rgba*)calloc(width*height,sizeof(float_rgba)); + +return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ +inst *in; + +in=(inst*)instance; + +free(in->sl); +free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ +inst *p; +int tmpi,chg; + +p=(inst*)instance; + +chg=0; +switch(param_index) + { + case 0: + tmpi=map_value_forward(*((double*)parm), 0.0, 4.9999); + if (tmpi != p->mer) chg=1; + p->mer=tmpi; + break; + case 1: + tmpi=map_value_forward(*((double*)parm), 0.0, p->w); + if (tmpi != p->x) chg=1; + p->x=tmpi; + break; + case 2: + tmpi=map_value_forward(*((double*)parm), 0.0, p->h); + if (tmpi != p->y) chg=1; + p->y=tmpi; + break; + case 3: + tmpi=map_value_forward(*((double*)parm), 0.0, 12.0); + if (tmpi != p->sx) chg=1; + p->sx=tmpi; + break; + case 4: + tmpi=map_value_forward(*((double*)parm), 0.0, 12.0); + if (tmpi != p->sy) chg=1; + p->sy=tmpi; + break; + case 5: + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->un != tmpi) chg=1; + p->un=tmpi; + break; + case 6: + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->sha != tmpi) chg=1; + p->sha=tmpi; + break; + case 7: + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->bw != tmpi) chg=1; + p->bw=tmpi; + break; + } + +if (chg==0) return; + +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ +inst *p; + +p=(inst*)instance; + +switch(param_index) + { + case 0: + *((double*)param)=map_value_backward(p->mer, 0.0, 4.9999); + break; + case 1: + *((double*)param)=map_value_backward(p->x, 0.0, p->w); + break; + case 2: + *((double*)param)=map_value_backward(p->y, 0.0, p->h); + break; + case 3: + *((double*)param)=map_value_backward(p->sx, 0.0, 12.0); + break; + case 4: + *((double*)param)=map_value_backward(p->sy, 0.0, 12.0); + break; + case 5: + *((double*)param)=map_value_backward(p->un, 0.0, 1.0);//BOOL!! + break; + case 6: + *((double*)param)=map_value_backward(p->sha, 0.0, 1.0);//BOOL!! + break; + case 7: + *((double*)param)=map_value_backward(p->bw, 0.0, 1.0);//BOOL!! + break; + } +} + +//------------------------------------------------- +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ +inst *in; + +assert(instance); +in=(inst*)instance; + +color2floatrgba(inframe, in->sl, in->w , in->h); + +sonda(in->sl, in->w, in->h, in->x, in->y, 2*in->sx+1, 2*in->sy+1, &in->poz, in->mer, in->un, in->sha, in->bw); +crosshair(in->sl, in->w, in->h, in->x, in->y, 2*in->sx+1, 2*in->sy+1, 15); + +floatrgba2color(in->sl, outframe, in->w , in->h); +} + diff --git a/src/filter/measure/measure_pr0file.c b/src/filter/measure/measure_pr0file.c new file mode 100644 index 0000000..83c5ef6 --- /dev/null +++ b/src/filter/measure/measure_pr0file.c @@ -0,0 +1,1038 @@ +/* +pr0file.c + +This frei0r plugin ia an "2D video oscilloscope" +Version 0.1 jun 2010 + +Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +//compile: gcc -c -fPIC -Wall pr0file.c -o pr0file.o +//link: gcc -shared -o pr0file.so pr0file.o + +#include + +#include +#include +#include +#include +#include + +#include "font2.h" +#include "measure.h" + +double PI=3.14159265358979; + +//--------------------------------------------------------------- +void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c) +{ +int i,j; +int zx,kx,zy,ky; + +zx=x; if (zx<0) zx=0; +zy=y; if (zy<0) zy=0; +kx=x+wr; if (kx>w) kx=w; +ky=y+hr; if (ky>h) ky=h; +for (i=zy;iw) kx=w; +ky=y+hr; if (ky>h) ky=h; +for (i=zy;i127)) return; +if (x<0) return; +if ((x+8)>=w) return; +if (y<0) return; +if ((y+16)>=h)return; + +z=(c-32)%32+((c-32)/32)*512; //position in font image + +for (i=0;i<16;i++) + for (j=0;j<8;j++) + if ((font2_bits[z+32*i]&(1<=10.0)&&(b<100.0)) ss=p1m1; + ss=p3m; + } + } +sprintf(s,"%s",ss); +} + +//------------------------------------------------------------- +//draws a simple line (no antialiasing) +//xz,yz=start point +//xk,yk=end point +void draw_line(float_rgba *s, int w, int h, int xz, int yz, int xk, int yk, float_rgba c) +{ +int x,y,d,i; + +d = (abs(xk-xz)>abs(yk-yz)) ? abs(xk-xz) : abs(yk-yz); +if (d==0) return; +for (i=0;i=0)&&(x=0)&&(y0.0) + { + xm=xz+dd*dx*m1; + ym=yz+dd*dy*m1; + draw_line(s, w, h, xm+s2*dy, ym-s2*dx, xm+s3*dy, ym-s3*dx, c); + draw_line(s, w, h, xm-s2*dy, ym+s2*dx, xm-s3*dy, ym+s3*dx, c); + } +if (m2>0.0) + { + xm=xz+dd*dx*m2; + ym=yz+dd*dy*m2; + draw_line(s, w, h, xm+s2*dy, ym-s2*dx, xm+s3*dy, ym-s3*dx, c); + draw_line(s, w, h, xm-s2*dy, ym+s2*dx, xm-s3*dy, ym+s3*dx, c); + } +} + +//-------------------------------------------------------- +//select one of 8 colors for the crosshair +float_rgba mcolor(int c) +{ +float_rgba wh={1.0,1.0,1.0,1.0}; +float_rgba ye={1.0,1.0,0.0,1.0}; +float_rgba cy={0.0,1.0,1.0,1.0}; +float_rgba gr={0.0,1.0,0.0,1.0}; +float_rgba mg={1.0,0.0,1.0,1.0}; +float_rgba rd={1.0,0.0,0.0,1.0}; +float_rgba bl={0.0,0.0,1.0,1.0}; +float_rgba bk={0.0,0.0,0.0,1.0}; + +switch (c) + { + case 0: return wh; //white + case 1: return ye; //yellow + case 2: return cy; //cyan + case 3: return gr; //green + case 4: return mg; //magenta + case 5: return rd; //red + case 6: return bl; //blue + case 7: return bk; //black + default: return bk; //black + } +} + +//-------------------------------------------------------- +//graph p[], p[]+ofs should be between 0.0 and 1.0 +void draw_trace(float_rgba *s, int w, int h, int x0, int y0, int vx, int vy, float p[], int n, float ofs, float_rgba c) +{ +int i,x,y,xs,ys; + +if (n==0) return; +xs=x0; ys=y0+vy*(1.0-p[0]-ofs); +for (i=0;i=w) x=w-1; + y=y0+(vy-1)*(1.0-p[i]-ofs)+1; + if (y=(y0+vy)) y=y0+vy-1; if (y>=h) y=h-1; + draw_line(s, w, h, xs, ys, xs, y, c); + draw_line(s, w, h, xs, y, x, y, c); + xs=x; ys=y; + } +} + +//------------------------------------------------------------- +//numeric display below the "oscilloscope" +//m=which channel to display (one of seven) +//dit=what data to display (display items flags) +//m1,m2 marker positions as indexes into p.x arrays +//output is written into string *str +void izpis(profdata p, char *str, int m, int u, int m1, int m2, int dit) +{ +int i; +char fs[256],frs[16]; +float data[8]; + +for (i=0;i<8;i++) data[i]=0; + +switch (m>>24) //select channel (r,g,b....) & copy data + { + case 0: //display nothing + return; + case 1: //display R channel + data[0]=p.r[m1]; data[1]=p.r[m2]; data[2]=data[1]-data[0]; + data[3]=p.sr.avg; data[4]=p.sr.rms; data[5]=p.sr.min; + data[6]=p.sr.max; + break; + case 2: //display G channel + data[0]=p.g[m1]; data[1]=p.g[m2]; data[2]=data[1]-data[0]; + data[3]=p.sg.avg; data[4]=p.sg.rms; data[5]=p.sg.min; + data[6]=p.sg.max; + break; + case 3: //display B channel + data[0]=p.b[m1]; data[1]=p.b[m2]; data[2]=data[1]-data[0]; + data[3]=p.sb.avg; data[4]=p.sb.rms; data[5]=p.sb.min; + data[6]=p.sb.max; + break; + case 4: //display Y channel + data[0]=p.y[m1]; data[1]=p.y[m2]; data[2]=data[1]-data[0]; + data[3]=p.sy.avg; data[4]=p.sy.rms; data[5]=p.sy.min; + data[6]=p.sy.max; + break; + case 5: //display Pr channel + data[0]=p.u[m1]; data[1]=p.u[m2]; data[2]=data[1]-data[0]; + data[3]=p.su.avg; data[4]=p.su.rms; data[5]=p.su.min; + data[6]=p.su.max; + break; + case 6: //display Pb channel + data[0]=p.v[m1]; data[1]=p.v[m2]; data[2]=data[1]-data[0]; + data[3]=p.sv.avg; data[4]=p.sv.rms; data[5]=p.sv.min; + data[6]=p.sv.max; + break; + case 7: //display alpha channel + data[0]=p.a[m1]; data[1]=p.a[m2]; data[2]=data[1]-data[0]; + data[3]=p.sa.avg; data[4]=p.sa.rms; data[5]=p.sa.min; + data[6]=p.sa.max; + break; + default: + break; + } + +if (u!=0) for (i=0;i<8;i++) data[i]=data[i]*255.0; + +for (i=0;i<256;i++) {fs[i]=0; str[i]=0;} +if ((dit&0x00000001)!=0) //marker 1 value + { + if (m1>0) + { + forstr(data[0],1-u,0,frs); + sprintf(fs,"%%s Mk1=%s", frs); + sprintf(str,fs,str,data[0]); + } + else + sprintf(str,"%s %s",str,"Mk1= -----"); + } +if ((dit&0x00000004)!=0) //marker 2 value + { + if (m2>0) + { + forstr(data[1],1-u,0,frs); + sprintf(fs,"%%s Mk2=%s", frs); + sprintf(str,fs,str,data[1]); + } + else + sprintf(str,"%s %s",str,"Mk2= -----"); + } +if ((dit&0x00000010)!=0) //difference marker2-marker1 + { + if ((m2>0)&&(m1>0)) + { + forstr(data[2],1-u,0,frs); + sprintf(fs,"%%s D=%s", frs); + sprintf(str,fs,str,data[2]); + } + else + sprintf(str,"%s %s",str,"D= -----"); + } +if ((dit&0x00000020)!=0) //average of profile + { + forstr(data[3],1-u,0,frs); + sprintf(fs,"%%s Avg=%s", frs); + sprintf(str,fs,str,data[3]); + } +if ((dit&0x00000040)!=0) //RMS of profile + { + forstr(data[4],1-u,0,frs); + sprintf(fs,"%%s RMS=%s", frs); + sprintf(str,fs,str,data[4]); + } +if ((dit&0x00000080)!=0) //MIN of profile + { + forstr(data[5],1-u,0,frs); + sprintf(fs,"%%s Min=%s", frs); + sprintf(str,fs,str,data[5]); + } +if ((dit&0x00000100)!=0) //MAX of profile + { + forstr(data[6],1-u,0,frs); + sprintf(fs,"%%s Max=%s", frs); + sprintf(str,fs,str,data[6]); + } +} + +//-------------------------------------------------------------- +//draw info window +//sx,sy=size of probe (must be odd) +//poz=position of info window 0=left 1=right +//m=measurement channel, trace/numeric display +//u=units 0=0.0-1.0 1=0-255 +//as = auto scale +//m1,m2=marker positions +//dit=display items flags +//cc=crosshair color [0...7] +//cm=0 rec 601, cm=1 rec 709 +void prof(float_rgba *s, int w, int h, int *poz, int x, int y, float tilt, int len, int sir, int m, int u, int as, int m1, int m2, int dit, int cc, int cm, profdata *p) +{ +int x0,y0,vx,vy; +int xz,xk,yz,yk; //zacetna in koncna tocka +char string[256]; +int i,sl; +float_rgba white={1.0,1.0,1.0,1.0}; +float_rgba lgray={0.7,0.7,0.7,1.0}; +float_rgba gray={0.5,0.5,0.5,1.0}; +float_rgba dgray={0.3,0.3,0.3,1.0}; +float_rgba red={1.0,0.0,0.0,1.0}; +float_rgba dgreen={0.0,0.7,0.0,1.0}; +float_rgba lblue={0.3,0.3,1.0,1.0}; +float_rgba yellow={0.7,0.7,0.0,1.0}; +float_rgba pink={0.8,0.4,0.5,1.0}; +float_rgba magenta={0.8,0.0,0.8,1.0}; +float_rgba cyan={0.0,0.7,0.8,1.0}; + +//position and size of info window +if (yh/2+20) *poz=0; //top +x0=h/20; +vx=w*15/16; +vy = h*6/16; +y0 = (*poz==0) ? h/20 : h-h/20-vy; + +//end points of profile +xz=x-len/2.0*cosf(tilt); +xk=x+len/2.0*cosf(tilt); +yz=y-len/2.0*sinf(tilt); +yk=y+len/2.0*sinf(tilt); + +//measure +meriprof(s, w, h, xz, yz, xk, yk, sir, p); +prof_yuv(p,cm); +prof_stat(p); + +//draw crosshair +pmarker(s, w, h, xz, yz, xk, yk, sir, mcolor(cc), (float)m1/p->n, (float)m2/p->n); + +//info window background +darken_rectangle(s, w, h, x0, y0, vx, vy, 0.4); + +//draw scope +//background +//draw_rectangle(s, w, h, x0+50, y0+5, vx-55, vy-40, black); +//grid +yz=y0+6; yk=y0+vy-36; +for (i=0;i<9;i++) + { + xz=x0+49+(i+1)*(vx-55)/10; + draw_line(s, w, h, xz, yz, xz, yk, dgray); + } +xz=x0+50;xk=x0+vx-6; +for (i=0;i<3;i++) + { + yz=y0+5+(i+1)*(vy-40)/4; + draw_line(s, w, h, xz, yz, xk, yz, dgray); + } +//traces +if ((m&0x00000001)!=0) //R + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->r, p->n, 0.0, red); +if ((m&0x00000002)!=0) //G + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->g, p->n, 0.0, dgreen); +if ((m&0x00000004)!=0) //B + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->b, p->n, 0.0, lblue); +if ((m&0x00000008)!=0) //Y + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->y, p->n, 0.0, lgray); +if ((m&0x00000010)!=0) //Pr + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->u, p->n, 0.5, magenta); +if ((m&0x00000020)!=0) //Pb + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->v, p->n, 0.5, cyan); +if ((m&0x00000040)!=0) //alpha + draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->a, p->n, 0.0, gray); +//markers +if ((m1>=0)&&(m1n)) + { + draw_line(s, w, h, x0+50+(m1+0.5)*(vx-55)/p->n, y0+5, x0+50+(m1+0.5)*(vx-55)/p->n, y0+vy-35, yellow); + } +if ((m2>=0)&&(m2n)) + { + draw_line(s, w, h, x0+50+(m2+0.5)*(vx-55)/p->n, y0+5, x0+50+(m2+0.5)*(vx-55)/p->n, y0+vy-35, pink); + } +//frame +draw_line(s, w, h, x0+49, y0+5, x0+vx-5, y0+5, gray); +draw_line(s, w, h, x0+49, y0+vy-35, x0+vx-5, y0+vy-35, gray); +draw_line(s, w, h, x0+49, y0+5, x0+49, y0+vy-35, gray); +draw_line(s, w, h, x0+vx-5, y0+5, x0+vx-5, y0+vy-35, gray); + +//numeric display +izpis(*p,string,m,u,m1,m2,dit); +sl=strlen(string); +if (sl>((vx-55)/8)) + { + sprintf(string,"<- NOT ENOUGH SPACE ->"); + draw_string(s, w, h, x0+vx/2-88, y0+vy-25, string, white); + return; + } +switch (m>>24) //which channel data under the scope + { + case 0: + break; + case 1: + draw_string(s, w, h, x0+20, y0+vy-25, "R", red); + draw_string(s, w, h, x0+60, y0+vy-25, string, red); + break; + case 2: + draw_string(s, w, h, x0+20, y0+vy-25, "G", dgreen); + draw_string(s, w, h, x0+60, y0+vy-25, string, dgreen); + break; + case 3: + draw_string(s, w, h, x0+20, y0+vy-25, "B", lblue); + draw_string(s, w, h, x0+60, y0+vy-25, string, lblue); + break; + case 4: + draw_string(s, w, h, x0+20, y0+vy-25, "Y", lgray); + draw_string(s, w, h, x0+60, y0+vy-25, string, lgray); + break; + case 5: + draw_string(s, w, h, x0+20, y0+vy-25, "Pr", magenta); + draw_string(s, w, h, x0+60, y0+vy-25, string, magenta); + break; + case 6: + draw_string(s, w, h, x0+20, y0+vy-25, "Pb", cyan); + draw_string(s, w, h, x0+60, y0+vy-25, string, cyan); + break; + case 7: + draw_string(s, w, h, x0+20, y0+vy-25, "a", gray); + draw_string(s, w, h, x0+60, y0+vy-25, string, gray); + break; + default: + break; + } + +} + +//----------------------------------------------------- +//converts the internal RGBA float image into +//Frei0r rgba8888 color +void floatrgba2color(float_rgba *sl, uint32_t* outframe, int w , int h) +{ +int i; +uint32_t p; + +for (i=0;i>8))*0.00392157; + sl[i].b=((float)((inframe[i] & 0x00FF0000)>>16))*0.00392157; + sl[i].a=((float)((inframe[i] & 0xFF000000)>>24))*0.00392157; + } +} + +//----------------------------------------------------- +//stretch [0...1] to parameter range [min...max] linear +float map_value_forward(double v, float min, float max) +{ +return min+(max-min)*v; +} + +//----------------------------------------------------- +//collapse from parameter range [min...max] to [0...1] linear +double map_value_backward(float v, float min, float max) +{ +return (v-min)/(max-min); +} + +//---------------------------------------- +//struktura za instanco efekta +typedef struct +{ +int h; +int w; + +int x; //horizontal position +int y; //vertical position +float tilt; //tilt of profile +int len; //length of profile +int chn; //channel for numeric display +int m1; //marker 1 position along profile +int m2; //marker 2 position along profile +int rt; //show r trace BOOL +int gt; //show g trace BOOL +int bt; //show b trace BOOL +int yt; //show Y' trace BOOL +int ut; //show Pr trace BOOL +int vt; //show Pb trace BOOL +int at; //show alpha trace BOOL +int davg; //display average BOOL +int drms; //display rms BOOL +int dmin; //display minimum BOOL +int dmax; //display maximum BOOL +int un; //0...255 units BOOL +int col; //color, rec 601 or rec 709 +int chc; //crosshair color [0...7] + +int poz; +int mer; //display channel + trace flags +int dit; //numeric display items flags + +float_rgba *sl; +profdata *p; + +} inst; + +//*********************************************** +// OBVEZNE FREI0R FUNKCIJE + +//----------------------------------------------- +int f0r_init() +{ +return 1; +} + +//------------------------------------------------ +void f0r_deinit() +{ +} + +//----------------------------------------------- +void f0r_get_plugin_info(f0r_plugin_info_t* info) +{ + +info->name="pr0file"; +info->author="Marko Cebokli"; +info->plugin_type=F0R_PLUGIN_TYPE_FILTER; +info->color_model=F0R_COLOR_MODEL_RGBA8888; +info->frei0r_version=FREI0R_MAJOR_VERSION; +info->major_version=0; +info->minor_version=2; +info->num_params=21; +info->explanation="2D video oscilloscope"; +} + +//-------------------------------------------------- +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + +switch(param_index) + { + case 0: + info->name = "X"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "X position of profile"; + break; + case 1: + info->name = "Y"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Y position of profile"; + break; + case 2: + info->name = "Tilt"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Tilt of profile"; + break; + case 3: + info->name = "Length"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Length of profile"; + break; + case 4: + info->name = "Channel"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Channel to numerically display"; + break; + case 5: + info->name = "Marker 1"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Position of marker 1"; + break; + case 6: + info->name = "Marker 2"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Position of marker 2"; + break; + case 7: + info->name = "R trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show R trace on scope"; + break; + case 8: + info->name = "G trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show G trace on scope"; + break; + case 9: + info->name = "B trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show B trace on scope"; + break; + case 10: + info->name = "Y trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show Y' trace on scope"; + break; + case 11: + info->name = "Pr trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show Pr trace on scope"; + break; + case 12: + info->name = "Pb trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show Pb trace on scope"; + break; + case 13: + info->name = "Alpha trace"; + info->type = F0R_PARAM_BOOL; + info->explanation = "Show Alpha trace on scope"; + break; + case 14: + info->name = "Display average"; + info->type = F0R_PARAM_BOOL; + info->explanation = "e"; + break; + case 15: + info->name = "Display RMS"; + info->type = F0R_PARAM_BOOL; + info->explanation = ""; + break; + case 16: + info->name = "Display minimum"; + info->type = F0R_PARAM_BOOL; + info->explanation = ""; + break; + case 17: + info->name = "Display maximum"; + info->type = F0R_PARAM_BOOL; + info->explanation = ""; + break; + case 18: + info->name = "256 scale"; + info->type = F0R_PARAM_BOOL; + info->explanation = "use 0-255 instead of 0.0-1.0"; + break; + case 19: + info->name = "Color"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "rec 601 or rec 709"; + break; + case 20: + info->name = "Crosshair color"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Color of the profile marker"; + break; + } +} + +//---------------------------------------------- +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ +inst *in; + +in=calloc(1,sizeof(inst)); +in->w=width; +in->h=height; + +in->x=width/2; +in->y=height/2; +in->tilt=0.0; +in->len=3*width/4; +in->chn=3; +in->m1=0; +in->m2=0; +in->rt=1; +in->gt=1; +in->bt=1; +in->yt=0; +in->ut=0; +in->vt=0; +in->at=0; +in->davg=1; +in->drms=1; +in->dmin=0; +in->dmax=0; +in->un=0; +in->col=0; +in->chc=0; + +in->poz=1; +in->mer=(3<<24)+7; //Y display + R,G,B traces +in->dit=32+64; //avg+RMS + +in->sl=(float_rgba*)calloc(width*height,sizeof(float_rgba)); +in->p=(profdata*)calloc(1,sizeof(profdata)); + +in->p->n=5; + +return (f0r_instance_t)in; +} + +//--------------------------------------------------- +void f0r_destruct(f0r_instance_t instance) +{ +inst *in; + +in=(inst*)instance; + +free(in->sl); +free(in->p); +free(instance); +} + +//----------------------------------------------------- +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) +{ +inst *p; +double tmpf; +int tmpi,chg; + +p=(inst*)instance; + +chg=0; +switch(param_index) + { + case 0: //X + tmpi=map_value_forward(*((double*)parm), 0.0, p->w); + if (tmpi != p->x) chg=1; + p->x=tmpi; + break; + case 1: //Y + tmpi=map_value_forward(*((double*)parm), 0.0, p->h); + if (tmpi != p->y) chg=1; + p->y=tmpi; + break; + case 2: //tilt + tmpf=map_value_forward(*((double*)parm), -PI/2.0, PI/2.0); + if (tmpf != p->tilt) chg=1; + p->tilt=tmpf; + break; + case 3: //length + tmpi=map_value_forward(*((double*)parm), 20.0, sqrtf(p->w*p->w+p->h*p->h)); + if (tmpi != p->len) chg=1; + p->len=tmpi; + break; + case 4: //channel + tmpi=map_value_forward(*((double*)parm), 1.0, 7.9999); + if (tmpi != p->chn) chg=1; + p->chn=tmpi; + break; + case 5: //marker 1 + tmpi=map_value_forward(*((double*)parm), -1.0, p->p->n); + if (tmpi != p->m1) chg=1; + p->m1=tmpi; + break; + case 6: //marker 2 + tmpi=map_value_forward(*((double*)parm), -1.0, p->p->n); + if (tmpi != p->m2) chg=1; + p->m2=tmpi; + break; + case 7: //R trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->rt != tmpi) chg=1; + p->rt=tmpi; + break; + case 8: //G trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->gt != tmpi) chg=1; + p->gt=tmpi; + break; + case 9: //B trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->bt != tmpi) chg=1; + p->bt=tmpi; + break; + case 10: //Y trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->yt != tmpi) chg=1; + p->yt=tmpi; + break; + case 11: //U trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->ut != tmpi) chg=1; + p->ut=tmpi; + break; + case 12: //V trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->vt != tmpi) chg=1; + p->vt=tmpi; + break; + case 13: //alpha trace + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->at != tmpi) chg=1; + p->at=tmpi; + break; + case 14: //display avg + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->davg != tmpi) chg=1; + p->davg=tmpi; + break; + case 15: //display RMS + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->drms != tmpi) chg=1; + p->drms=tmpi; + break; + case 16: //display min + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->dmin != tmpi) chg=1; + p->dmin=tmpi; + break; + case 17: //display max + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->dmax != tmpi) chg=1; + p->dmax=tmpi; + break; + case 18: //256 units + tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! + if (p->un != tmpi) chg=1; + p->un=tmpi; + break; + case 19: //color mode + tmpi=map_value_forward(*((double*)parm), 0.0, 1.9999); + if (p->col != tmpi) chg=1; + p->col=tmpi; + break; + case 20: //Crosshair color + tmpi=map_value_forward(*((double*)parm), 0.0, 7.9999); + if (p->chc != tmpi) chg=1; + p->chc=tmpi; + break; + } + +if (chg==0) return; + +p->mer=p->chn<<24; +p->mer=p->mer+p->rt; +p->mer=p->mer+2*p->gt; +p->mer=p->mer+4*p->bt; +p->mer=p->mer+8*p->yt; +p->mer=p->mer+16*p->ut; +p->mer=p->mer+32*p->vt; +p->mer=p->mer+64*p->at; + +p->dit=0; +if (p->m1>=0) p->dit=p->dit+1; +if (p->m2>=0) p->dit=p->dit+4; +if ((p->m1>=0)&&(p->m2>=0)) p->dit=p->dit+16; +p->dit=p->dit+32*p->davg; +p->dit=p->dit+64*p->drms; +p->dit=p->dit+128*p->dmin; +p->dit=p->dit+256*p->dmax; + +} + +//-------------------------------------------------- +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) +{ +inst *p; + +p=(inst*)instance; + +switch(param_index) + { + case 0: + *((double*)param)=map_value_backward(p->x, 0.0, p->w); + break; + case 1: + *((double*)param)=map_value_backward(p->y, 0.0, p->h); + break; + case 2: + *((double*)param)=map_value_backward(p->tilt, -PI/2.0, PI/2.0); + break; + case 3: + *((double*)param)=map_value_backward(p->len, 20.0, sqrtf(p->w*p->w+p->h*p->h)); + break; + case 4: + *((double*)param)=map_value_backward(p->chn, 0.0, 7.9999); + break; + case 5: + *((double*)param)=map_value_backward(p->m1, 0.0, p->p->n); + break; + case 6: + *((double*)param)=map_value_backward(p->m2, 0.0, p->p->n); + break; + case 7: + *((double*)param)=map_value_backward(p->rt, 0.0, 1.0);//BOOL!! + break; + case 8: + *((double*)param)=map_value_backward(p->gt, 0.0, 1.0);//BOOL!! + break; + case 9: + *((double*)param)=map_value_backward(p->bt, 0.0, 1.0);//BOOL!! + break; + case 10: + *((double*)param)=map_value_backward(p->yt, 0.0, 1.0);//BOOL!! + break; + case 11: + *((double*)param)=map_value_backward(p->ut, 0.0, 1.0);//BOOL!! + break; + case 12: + *((double*)param)=map_value_backward(p->vt, 0.0, 1.0);//BOOL!! + break; + case 13: + *((double*)param)=map_value_backward(p->at, 0.0, 1.0);//BOOL!! + break; + case 14: + *((double*)param)=map_value_backward(p->davg, 0.0, 1.0);//BOOL!! + break; + case 15: + *((double*)param)=map_value_backward(p->drms, 0.0, 1.0);//BOOL!! + break; + case 16: + *((double*)param)=map_value_backward(p->dmin, 0.0, 1.0);//BOOL!! + break; + case 17: + *((double*)param)=map_value_backward(p->dmax, 0.0, 1.0);//BOOL!! + break; + case 18: + *((double*)param)=map_value_backward(p->un, 0.0, 1.0);//BOOL!! + break; + case 19: + *((double*)param)=map_value_backward(p->col, 0.0, 1.9999); + break; + case 20: + *((double*)param)=map_value_backward(p->chc, 0.0, 7.9999); + break; + } +} + +//------------------------------------------------- +void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) +{ +inst *in; + +assert(instance); +in=(inst*)instance; + +color2floatrgba(inframe, in->sl, in->w , in->h); + +prof(in->sl, in->w, in->h, &in->poz, in->x, in->y, in->tilt, in->len, 1, in->mer, in->un, 0, in->m1, in->m2, in->dit, in->chc, in->col, in->p); + +floatrgba2color(in->sl, outframe, in->w , in->h); +} + diff --git a/src/filter/measure/pr0be.c b/src/filter/measure/pr0be.c deleted file mode 100644 index d9d7e17..0000000 --- a/src/filter/measure/pr0be.c +++ /dev/null @@ -1,748 +0,0 @@ -/* -pr0be.c - -This frei0r plugin measures pixels in video -Version 0.1 jun 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//compile: gcc -c -fPIC -Wall pr0be.c -o pr0be.o -//link: gcc -shared -o pr0be.so pr0be.o - -#include -#include -#include -#include -#include - -#include "font2.h" -#include "measure.h" - -double PI=3.14159265358979; - -//--------------------------------------------------------------- -void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c) -{ -int i,j; -int zx,kx,zy,ky; - -zx=x; if (zx<0) zx=0; -zy=y; if (zy<0) zy=0; -kx=x+wr; if (kx>w) kx=w; -ky=y+hr; if (ky>h) ky=h; -for (i=zy;iw) kx=w; -ky=y+hr; if (ky>h) ky=h; -for (i=zy;i127)) return; -if (x<0) return; -if ((x+8)>=w) return; -if (y<0) return; -if ((y+16)>=h)return; - -z=(c-32)%32+((c-32)/32)*512; - -for (i=0;i<16;i++) - for (j=0;j<8;j++) - if ((font2_bits[z+32*i]&(1<=10.0)&&(b<100.0)) ss=p1m1; - ss=p3m; - } - } -sprintf(s,"%s",ss); -} - -//------------------------------------------------------------- -//print avg,rms,min,max into a string -//u=units 0=0.0-1.0 1=0-255 -//m=sign 0=unsigned -//mm=1 print min/max -void izpis(char *str, char *lab, stat s, int u, int m, int mm) -{ -char fs[256],as[16],rs[16],ns[16],xs[16]; - -if (u==1) - { - s.avg=255.0*s.avg; - s.rms=255.0*s.rms; - s.min=255.0*s.min; - s.max=255.0*s.max; - } - -if (mm==1) - { - forstr(s.avg,1-u,m,as); - forstr(s.rms,1-u,0,rs); - forstr(s.min,1-u,m,ns); - forstr(s.max,1-u,m,xs); - sprintf(fs,"%s%s%s %s%s", lab, as, rs, ns, xs); - sprintf(str,fs,s.avg,s.rms,s.min,s.max); - } -else - { - forstr(s.avg,1-u,m,as); - forstr(s.rms,1-u,0,rs); - sprintf(fs,"%s%s%s", lab, as, rs); - sprintf(str,fs,s.avg,s.rms); - } -} - -//----------------------------------------------------------- -//probe size markers in the magnifier diaplay -void sxmarkers(float_rgba *s, int w, int h, int x0, int y0, int np, int sx, int sy, int vp) -{ -int np2,x,y,i,j; -float_rgba white={1.0,1.0,1.0,1.0}; - -np2=np/2+1; - -//top left -x=x0+(np2-sx/2)*vp-1; if (sx>np) x=x0; -y=y0+(np2-sy/2)*vp-1; if (sy>np) y=y0; -if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); -if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); -//top right -x=x0+(np2+sx/2+1)*vp-1; -y=y0+(np2-sy/2)*vp-1; if (sy>np) y=y0; -if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); -x=x0+(np2+sx/2)*vp; -y=y0+(np2-sy/2)*vp-1; if (sx>np) x=x0+(np+1)*vp-1; -if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); -//bottom left -x=x0+(np2-sx/2)*vp-1; -y=y0+(np2+sy/2)*vp; if (sy>np) y=y0+(np+1)*vp; -if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); -x=x0+(np2-sx/2)*vp-1; if (sx>np) x=x0; -y=y0+(np2+sy/2+1)*vp-1; -if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); -//bottom right -x=x0+(np2+sx/2)*vp+vp-1; -y=y0+(np2+sy/2)*vp; if (sy>np) y=y0+(np+1)*vp; -if (sx<=np) draw_rectangle(s, w, h, x, y, 1, vp, white); -x=x0+(np2+sx/2)*vp; -y=y0+(np2+sy/2+1)*vp-1; if (sx>np) x=x0+(np+1)*vp-1; -if (sy<=np) draw_rectangle(s, w, h, x, y, vp, 1, white); - -//"out of box" arrows -if (sx>np) - { - for (i=1;inp) - { - for (i=1;i7*w/12) *poz=0; //left -if (xw/2+30) *poz=0; //left -vp=9; //pixel size in magnifier -y0=h/20; -if (bw==1) //big window - { - vx=240; - vy = (m<=2) ? 320 : 300; - x0 = (*poz==0) ? h/20 : w-h/20-vx; - np=25; //size of magnifier - xn = (m<=2) ? x0+8 : x0+70; - yn=y0+(np+1)*vp+8; - } -else //small window - { - vx=152; - vy = (m<=2) ? 230 : 210; - x0 = (*poz==0) ? h/20 : w-h/20-vx; - np=15; //size of magnifier - xn = (m<=2) ? x0+15 : x0+25; - yn=y0+(np+1)*vp+8; - } -np2=np/2+1; -if (sha==1) vy=vy+20; - -//keep probe inside -if (x=(w-sx/2)) x=w-sx/2-1; -if (y=(h-sy/2)) y=h-sy/2-1; - -//info window background -darken_rectangle(s, w, h, x0, y0, vx, vy, 0.4); - -//magnifier background -draw_rectangle(s, w, h, x0+vp-1, y0+vp-1, np*vp+1, np*vp+1, black); -//sx,sy marks -sxmarkers(s, w, h, x0, y0, np, sx, sy, vp); -//magnifier pixels -for (i=0;i=0)&&(xp=0)&&(ypva) va=gg.avg; if (bb.avg>va) va=bb.avg; - li=rr.avg; - if (gg.avgva) va=gg.avg; if (bb.avg>va) va=bb.avg; - li=rr.avg; - if (gg.avg>8))*0.00392157; - sl[i].b=((float)((inframe[i] & 0x00FF0000)>>16))*0.00392157; - sl[i].a=((float)((inframe[i] & 0xFF000000)>>24))*0.00392157; - } -} - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ -return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ -return (v-min)/(max-min); -} - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ -int h; -int w; - -int mer; -int x; -int y; -int sx; -int sy; -int un; -int sha; -int bw; - -int poz; -float_rgba *sl; -} inst; - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ -return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - -info->name="pr0be"; -info->author="Marko Cebokli"; -info->plugin_type=F0R_PLUGIN_TYPE_FILTER; -info->color_model=F0R_COLOR_MODEL_RGBA8888; -info->frei0r_version=FREI0R_MAJOR_VERSION; -info->major_version=0; -info->minor_version=1; -info->num_params=8; -info->explanation="Measure video values"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ -switch(param_index) - { - case 0: - info->name = "Measurement"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "What measurement to display"; - break; - case 1: - info->name = "X"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "X position of probe"; - break; - case 2: - info->name = "Y"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Y position of probe"; - break; - case 3: - info->name = "X size"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "X size of probe"; - break; - case 4: - info->name = "Y size"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Y size of probe"; - break; - case 5: - info->name = "256 scale"; - info->type = F0R_PARAM_BOOL; - info->explanation = "use 0-255 instead of 0.0-1.0"; - break; - case 6: - info->name = "Show alpha"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Display alpha value too"; - break; - case 7: - info->name = "Big window"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Display more data"; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ -inst *in; - -in=calloc(1,sizeof(inst)); -in->w=width; -in->h=height; - -in->mer=0; -in->x=width/2; -in->y=height/2; -in->sx=3; -in->sy=3; -in->un=0; -in->sha=0; -in->bw=0; - -in->poz=0; -in->sl=(float_rgba*)calloc(width*height,sizeof(float_rgba)); - -return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ -inst *in; - -in=(inst*)instance; - -free(in->sl); -free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ -inst *p; -int tmpi,chg; - -p=(inst*)instance; - -chg=0; -switch(param_index) - { - case 0: - tmpi=map_value_forward(*((double*)parm), 0.0, 4.9999); - if (tmpi != p->mer) chg=1; - p->mer=tmpi; - break; - case 1: - tmpi=map_value_forward(*((double*)parm), 0.0, p->w); - if (tmpi != p->x) chg=1; - p->x=tmpi; - break; - case 2: - tmpi=map_value_forward(*((double*)parm), 0.0, p->h); - if (tmpi != p->y) chg=1; - p->y=tmpi; - break; - case 3: - tmpi=map_value_forward(*((double*)parm), 0.0, 12.0); - if (tmpi != p->sx) chg=1; - p->sx=tmpi; - break; - case 4: - tmpi=map_value_forward(*((double*)parm), 0.0, 12.0); - if (tmpi != p->sy) chg=1; - p->sy=tmpi; - break; - case 5: - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->un != tmpi) chg=1; - p->un=tmpi; - break; - case 6: - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->sha != tmpi) chg=1; - p->sha=tmpi; - break; - case 7: - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->bw != tmpi) chg=1; - p->bw=tmpi; - break; - } - -if (chg==0) return; - -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ -inst *p; - -p=(inst*)instance; - -switch(param_index) - { - case 0: - *((double*)param)=map_value_backward(p->mer, 0.0, 4.9999); - break; - case 1: - *((double*)param)=map_value_backward(p->x, 0.0, p->w); - break; - case 2: - *((double*)param)=map_value_backward(p->y, 0.0, p->h); - break; - case 3: - *((double*)param)=map_value_backward(p->sx, 0.0, 12.0); - break; - case 4: - *((double*)param)=map_value_backward(p->sy, 0.0, 12.0); - break; - case 5: - *((double*)param)=map_value_backward(p->un, 0.0, 1.0);//BOOL!! - break; - case 6: - *((double*)param)=map_value_backward(p->sha, 0.0, 1.0);//BOOL!! - break; - case 7: - *((double*)param)=map_value_backward(p->bw, 0.0, 1.0);//BOOL!! - break; - } -} - -//------------------------------------------------- -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ -inst *in; - -assert(instance); -in=(inst*)instance; - -color2floatrgba(inframe, in->sl, in->w , in->h); - -sonda(in->sl, in->w, in->h, in->x, in->y, 2*in->sx+1, 2*in->sy+1, &in->poz, in->mer, in->un, in->sha, in->bw); -crosshair(in->sl, in->w, in->h, in->x, in->y, 2*in->sx+1, 2*in->sy+1, 15); - -floatrgba2color(in->sl, outframe, in->w , in->h); -} - diff --git a/src/filter/measure/pr0file.c b/src/filter/measure/pr0file.c deleted file mode 100644 index 83c5ef6..0000000 --- a/src/filter/measure/pr0file.c +++ /dev/null @@ -1,1038 +0,0 @@ -/* -pr0file.c - -This frei0r plugin ia an "2D video oscilloscope" -Version 0.1 jun 2010 - -Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -//compile: gcc -c -fPIC -Wall pr0file.c -o pr0file.o -//link: gcc -shared -o pr0file.so pr0file.o - -#include - -#include -#include -#include -#include -#include - -#include "font2.h" -#include "measure.h" - -double PI=3.14159265358979; - -//--------------------------------------------------------------- -void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c) -{ -int i,j; -int zx,kx,zy,ky; - -zx=x; if (zx<0) zx=0; -zy=y; if (zy<0) zy=0; -kx=x+wr; if (kx>w) kx=w; -ky=y+hr; if (ky>h) ky=h; -for (i=zy;iw) kx=w; -ky=y+hr; if (ky>h) ky=h; -for (i=zy;i127)) return; -if (x<0) return; -if ((x+8)>=w) return; -if (y<0) return; -if ((y+16)>=h)return; - -z=(c-32)%32+((c-32)/32)*512; //position in font image - -for (i=0;i<16;i++) - for (j=0;j<8;j++) - if ((font2_bits[z+32*i]&(1<=10.0)&&(b<100.0)) ss=p1m1; - ss=p3m; - } - } -sprintf(s,"%s",ss); -} - -//------------------------------------------------------------- -//draws a simple line (no antialiasing) -//xz,yz=start point -//xk,yk=end point -void draw_line(float_rgba *s, int w, int h, int xz, int yz, int xk, int yk, float_rgba c) -{ -int x,y,d,i; - -d = (abs(xk-xz)>abs(yk-yz)) ? abs(xk-xz) : abs(yk-yz); -if (d==0) return; -for (i=0;i=0)&&(x=0)&&(y0.0) - { - xm=xz+dd*dx*m1; - ym=yz+dd*dy*m1; - draw_line(s, w, h, xm+s2*dy, ym-s2*dx, xm+s3*dy, ym-s3*dx, c); - draw_line(s, w, h, xm-s2*dy, ym+s2*dx, xm-s3*dy, ym+s3*dx, c); - } -if (m2>0.0) - { - xm=xz+dd*dx*m2; - ym=yz+dd*dy*m2; - draw_line(s, w, h, xm+s2*dy, ym-s2*dx, xm+s3*dy, ym-s3*dx, c); - draw_line(s, w, h, xm-s2*dy, ym+s2*dx, xm-s3*dy, ym+s3*dx, c); - } -} - -//-------------------------------------------------------- -//select one of 8 colors for the crosshair -float_rgba mcolor(int c) -{ -float_rgba wh={1.0,1.0,1.0,1.0}; -float_rgba ye={1.0,1.0,0.0,1.0}; -float_rgba cy={0.0,1.0,1.0,1.0}; -float_rgba gr={0.0,1.0,0.0,1.0}; -float_rgba mg={1.0,0.0,1.0,1.0}; -float_rgba rd={1.0,0.0,0.0,1.0}; -float_rgba bl={0.0,0.0,1.0,1.0}; -float_rgba bk={0.0,0.0,0.0,1.0}; - -switch (c) - { - case 0: return wh; //white - case 1: return ye; //yellow - case 2: return cy; //cyan - case 3: return gr; //green - case 4: return mg; //magenta - case 5: return rd; //red - case 6: return bl; //blue - case 7: return bk; //black - default: return bk; //black - } -} - -//-------------------------------------------------------- -//graph p[], p[]+ofs should be between 0.0 and 1.0 -void draw_trace(float_rgba *s, int w, int h, int x0, int y0, int vx, int vy, float p[], int n, float ofs, float_rgba c) -{ -int i,x,y,xs,ys; - -if (n==0) return; -xs=x0; ys=y0+vy*(1.0-p[0]-ofs); -for (i=0;i=w) x=w-1; - y=y0+(vy-1)*(1.0-p[i]-ofs)+1; - if (y=(y0+vy)) y=y0+vy-1; if (y>=h) y=h-1; - draw_line(s, w, h, xs, ys, xs, y, c); - draw_line(s, w, h, xs, y, x, y, c); - xs=x; ys=y; - } -} - -//------------------------------------------------------------- -//numeric display below the "oscilloscope" -//m=which channel to display (one of seven) -//dit=what data to display (display items flags) -//m1,m2 marker positions as indexes into p.x arrays -//output is written into string *str -void izpis(profdata p, char *str, int m, int u, int m1, int m2, int dit) -{ -int i; -char fs[256],frs[16]; -float data[8]; - -for (i=0;i<8;i++) data[i]=0; - -switch (m>>24) //select channel (r,g,b....) & copy data - { - case 0: //display nothing - return; - case 1: //display R channel - data[0]=p.r[m1]; data[1]=p.r[m2]; data[2]=data[1]-data[0]; - data[3]=p.sr.avg; data[4]=p.sr.rms; data[5]=p.sr.min; - data[6]=p.sr.max; - break; - case 2: //display G channel - data[0]=p.g[m1]; data[1]=p.g[m2]; data[2]=data[1]-data[0]; - data[3]=p.sg.avg; data[4]=p.sg.rms; data[5]=p.sg.min; - data[6]=p.sg.max; - break; - case 3: //display B channel - data[0]=p.b[m1]; data[1]=p.b[m2]; data[2]=data[1]-data[0]; - data[3]=p.sb.avg; data[4]=p.sb.rms; data[5]=p.sb.min; - data[6]=p.sb.max; - break; - case 4: //display Y channel - data[0]=p.y[m1]; data[1]=p.y[m2]; data[2]=data[1]-data[0]; - data[3]=p.sy.avg; data[4]=p.sy.rms; data[5]=p.sy.min; - data[6]=p.sy.max; - break; - case 5: //display Pr channel - data[0]=p.u[m1]; data[1]=p.u[m2]; data[2]=data[1]-data[0]; - data[3]=p.su.avg; data[4]=p.su.rms; data[5]=p.su.min; - data[6]=p.su.max; - break; - case 6: //display Pb channel - data[0]=p.v[m1]; data[1]=p.v[m2]; data[2]=data[1]-data[0]; - data[3]=p.sv.avg; data[4]=p.sv.rms; data[5]=p.sv.min; - data[6]=p.sv.max; - break; - case 7: //display alpha channel - data[0]=p.a[m1]; data[1]=p.a[m2]; data[2]=data[1]-data[0]; - data[3]=p.sa.avg; data[4]=p.sa.rms; data[5]=p.sa.min; - data[6]=p.sa.max; - break; - default: - break; - } - -if (u!=0) for (i=0;i<8;i++) data[i]=data[i]*255.0; - -for (i=0;i<256;i++) {fs[i]=0; str[i]=0;} -if ((dit&0x00000001)!=0) //marker 1 value - { - if (m1>0) - { - forstr(data[0],1-u,0,frs); - sprintf(fs,"%%s Mk1=%s", frs); - sprintf(str,fs,str,data[0]); - } - else - sprintf(str,"%s %s",str,"Mk1= -----"); - } -if ((dit&0x00000004)!=0) //marker 2 value - { - if (m2>0) - { - forstr(data[1],1-u,0,frs); - sprintf(fs,"%%s Mk2=%s", frs); - sprintf(str,fs,str,data[1]); - } - else - sprintf(str,"%s %s",str,"Mk2= -----"); - } -if ((dit&0x00000010)!=0) //difference marker2-marker1 - { - if ((m2>0)&&(m1>0)) - { - forstr(data[2],1-u,0,frs); - sprintf(fs,"%%s D=%s", frs); - sprintf(str,fs,str,data[2]); - } - else - sprintf(str,"%s %s",str,"D= -----"); - } -if ((dit&0x00000020)!=0) //average of profile - { - forstr(data[3],1-u,0,frs); - sprintf(fs,"%%s Avg=%s", frs); - sprintf(str,fs,str,data[3]); - } -if ((dit&0x00000040)!=0) //RMS of profile - { - forstr(data[4],1-u,0,frs); - sprintf(fs,"%%s RMS=%s", frs); - sprintf(str,fs,str,data[4]); - } -if ((dit&0x00000080)!=0) //MIN of profile - { - forstr(data[5],1-u,0,frs); - sprintf(fs,"%%s Min=%s", frs); - sprintf(str,fs,str,data[5]); - } -if ((dit&0x00000100)!=0) //MAX of profile - { - forstr(data[6],1-u,0,frs); - sprintf(fs,"%%s Max=%s", frs); - sprintf(str,fs,str,data[6]); - } -} - -//-------------------------------------------------------------- -//draw info window -//sx,sy=size of probe (must be odd) -//poz=position of info window 0=left 1=right -//m=measurement channel, trace/numeric display -//u=units 0=0.0-1.0 1=0-255 -//as = auto scale -//m1,m2=marker positions -//dit=display items flags -//cc=crosshair color [0...7] -//cm=0 rec 601, cm=1 rec 709 -void prof(float_rgba *s, int w, int h, int *poz, int x, int y, float tilt, int len, int sir, int m, int u, int as, int m1, int m2, int dit, int cc, int cm, profdata *p) -{ -int x0,y0,vx,vy; -int xz,xk,yz,yk; //zacetna in koncna tocka -char string[256]; -int i,sl; -float_rgba white={1.0,1.0,1.0,1.0}; -float_rgba lgray={0.7,0.7,0.7,1.0}; -float_rgba gray={0.5,0.5,0.5,1.0}; -float_rgba dgray={0.3,0.3,0.3,1.0}; -float_rgba red={1.0,0.0,0.0,1.0}; -float_rgba dgreen={0.0,0.7,0.0,1.0}; -float_rgba lblue={0.3,0.3,1.0,1.0}; -float_rgba yellow={0.7,0.7,0.0,1.0}; -float_rgba pink={0.8,0.4,0.5,1.0}; -float_rgba magenta={0.8,0.0,0.8,1.0}; -float_rgba cyan={0.0,0.7,0.8,1.0}; - -//position and size of info window -if (yh/2+20) *poz=0; //top -x0=h/20; -vx=w*15/16; -vy = h*6/16; -y0 = (*poz==0) ? h/20 : h-h/20-vy; - -//end points of profile -xz=x-len/2.0*cosf(tilt); -xk=x+len/2.0*cosf(tilt); -yz=y-len/2.0*sinf(tilt); -yk=y+len/2.0*sinf(tilt); - -//measure -meriprof(s, w, h, xz, yz, xk, yk, sir, p); -prof_yuv(p,cm); -prof_stat(p); - -//draw crosshair -pmarker(s, w, h, xz, yz, xk, yk, sir, mcolor(cc), (float)m1/p->n, (float)m2/p->n); - -//info window background -darken_rectangle(s, w, h, x0, y0, vx, vy, 0.4); - -//draw scope -//background -//draw_rectangle(s, w, h, x0+50, y0+5, vx-55, vy-40, black); -//grid -yz=y0+6; yk=y0+vy-36; -for (i=0;i<9;i++) - { - xz=x0+49+(i+1)*(vx-55)/10; - draw_line(s, w, h, xz, yz, xz, yk, dgray); - } -xz=x0+50;xk=x0+vx-6; -for (i=0;i<3;i++) - { - yz=y0+5+(i+1)*(vy-40)/4; - draw_line(s, w, h, xz, yz, xk, yz, dgray); - } -//traces -if ((m&0x00000001)!=0) //R - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->r, p->n, 0.0, red); -if ((m&0x00000002)!=0) //G - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->g, p->n, 0.0, dgreen); -if ((m&0x00000004)!=0) //B - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->b, p->n, 0.0, lblue); -if ((m&0x00000008)!=0) //Y - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->y, p->n, 0.0, lgray); -if ((m&0x00000010)!=0) //Pr - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->u, p->n, 0.5, magenta); -if ((m&0x00000020)!=0) //Pb - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->v, p->n, 0.5, cyan); -if ((m&0x00000040)!=0) //alpha - draw_trace(s, w, h, x0+50, y0+5, vx-55, vy-40, p->a, p->n, 0.0, gray); -//markers -if ((m1>=0)&&(m1n)) - { - draw_line(s, w, h, x0+50+(m1+0.5)*(vx-55)/p->n, y0+5, x0+50+(m1+0.5)*(vx-55)/p->n, y0+vy-35, yellow); - } -if ((m2>=0)&&(m2n)) - { - draw_line(s, w, h, x0+50+(m2+0.5)*(vx-55)/p->n, y0+5, x0+50+(m2+0.5)*(vx-55)/p->n, y0+vy-35, pink); - } -//frame -draw_line(s, w, h, x0+49, y0+5, x0+vx-5, y0+5, gray); -draw_line(s, w, h, x0+49, y0+vy-35, x0+vx-5, y0+vy-35, gray); -draw_line(s, w, h, x0+49, y0+5, x0+49, y0+vy-35, gray); -draw_line(s, w, h, x0+vx-5, y0+5, x0+vx-5, y0+vy-35, gray); - -//numeric display -izpis(*p,string,m,u,m1,m2,dit); -sl=strlen(string); -if (sl>((vx-55)/8)) - { - sprintf(string,"<- NOT ENOUGH SPACE ->"); - draw_string(s, w, h, x0+vx/2-88, y0+vy-25, string, white); - return; - } -switch (m>>24) //which channel data under the scope - { - case 0: - break; - case 1: - draw_string(s, w, h, x0+20, y0+vy-25, "R", red); - draw_string(s, w, h, x0+60, y0+vy-25, string, red); - break; - case 2: - draw_string(s, w, h, x0+20, y0+vy-25, "G", dgreen); - draw_string(s, w, h, x0+60, y0+vy-25, string, dgreen); - break; - case 3: - draw_string(s, w, h, x0+20, y0+vy-25, "B", lblue); - draw_string(s, w, h, x0+60, y0+vy-25, string, lblue); - break; - case 4: - draw_string(s, w, h, x0+20, y0+vy-25, "Y", lgray); - draw_string(s, w, h, x0+60, y0+vy-25, string, lgray); - break; - case 5: - draw_string(s, w, h, x0+20, y0+vy-25, "Pr", magenta); - draw_string(s, w, h, x0+60, y0+vy-25, string, magenta); - break; - case 6: - draw_string(s, w, h, x0+20, y0+vy-25, "Pb", cyan); - draw_string(s, w, h, x0+60, y0+vy-25, string, cyan); - break; - case 7: - draw_string(s, w, h, x0+20, y0+vy-25, "a", gray); - draw_string(s, w, h, x0+60, y0+vy-25, string, gray); - break; - default: - break; - } - -} - -//----------------------------------------------------- -//converts the internal RGBA float image into -//Frei0r rgba8888 color -void floatrgba2color(float_rgba *sl, uint32_t* outframe, int w , int h) -{ -int i; -uint32_t p; - -for (i=0;i>8))*0.00392157; - sl[i].b=((float)((inframe[i] & 0x00FF0000)>>16))*0.00392157; - sl[i].a=((float)((inframe[i] & 0xFF000000)>>24))*0.00392157; - } -} - -//----------------------------------------------------- -//stretch [0...1] to parameter range [min...max] linear -float map_value_forward(double v, float min, float max) -{ -return min+(max-min)*v; -} - -//----------------------------------------------------- -//collapse from parameter range [min...max] to [0...1] linear -double map_value_backward(float v, float min, float max) -{ -return (v-min)/(max-min); -} - -//---------------------------------------- -//struktura za instanco efekta -typedef struct -{ -int h; -int w; - -int x; //horizontal position -int y; //vertical position -float tilt; //tilt of profile -int len; //length of profile -int chn; //channel for numeric display -int m1; //marker 1 position along profile -int m2; //marker 2 position along profile -int rt; //show r trace BOOL -int gt; //show g trace BOOL -int bt; //show b trace BOOL -int yt; //show Y' trace BOOL -int ut; //show Pr trace BOOL -int vt; //show Pb trace BOOL -int at; //show alpha trace BOOL -int davg; //display average BOOL -int drms; //display rms BOOL -int dmin; //display minimum BOOL -int dmax; //display maximum BOOL -int un; //0...255 units BOOL -int col; //color, rec 601 or rec 709 -int chc; //crosshair color [0...7] - -int poz; -int mer; //display channel + trace flags -int dit; //numeric display items flags - -float_rgba *sl; -profdata *p; - -} inst; - -//*********************************************** -// OBVEZNE FREI0R FUNKCIJE - -//----------------------------------------------- -int f0r_init() -{ -return 1; -} - -//------------------------------------------------ -void f0r_deinit() -{ -} - -//----------------------------------------------- -void f0r_get_plugin_info(f0r_plugin_info_t* info) -{ - -info->name="pr0file"; -info->author="Marko Cebokli"; -info->plugin_type=F0R_PLUGIN_TYPE_FILTER; -info->color_model=F0R_COLOR_MODEL_RGBA8888; -info->frei0r_version=FREI0R_MAJOR_VERSION; -info->major_version=0; -info->minor_version=2; -info->num_params=21; -info->explanation="2D video oscilloscope"; -} - -//-------------------------------------------------- -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ - -switch(param_index) - { - case 0: - info->name = "X"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "X position of profile"; - break; - case 1: - info->name = "Y"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Y position of profile"; - break; - case 2: - info->name = "Tilt"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Tilt of profile"; - break; - case 3: - info->name = "Length"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Length of profile"; - break; - case 4: - info->name = "Channel"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Channel to numerically display"; - break; - case 5: - info->name = "Marker 1"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Position of marker 1"; - break; - case 6: - info->name = "Marker 2"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Position of marker 2"; - break; - case 7: - info->name = "R trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show R trace on scope"; - break; - case 8: - info->name = "G trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show G trace on scope"; - break; - case 9: - info->name = "B trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show B trace on scope"; - break; - case 10: - info->name = "Y trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show Y' trace on scope"; - break; - case 11: - info->name = "Pr trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show Pr trace on scope"; - break; - case 12: - info->name = "Pb trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show Pb trace on scope"; - break; - case 13: - info->name = "Alpha trace"; - info->type = F0R_PARAM_BOOL; - info->explanation = "Show Alpha trace on scope"; - break; - case 14: - info->name = "Display average"; - info->type = F0R_PARAM_BOOL; - info->explanation = "e"; - break; - case 15: - info->name = "Display RMS"; - info->type = F0R_PARAM_BOOL; - info->explanation = ""; - break; - case 16: - info->name = "Display minimum"; - info->type = F0R_PARAM_BOOL; - info->explanation = ""; - break; - case 17: - info->name = "Display maximum"; - info->type = F0R_PARAM_BOOL; - info->explanation = ""; - break; - case 18: - info->name = "256 scale"; - info->type = F0R_PARAM_BOOL; - info->explanation = "use 0-255 instead of 0.0-1.0"; - break; - case 19: - info->name = "Color"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "rec 601 or rec 709"; - break; - case 20: - info->name = "Crosshair color"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Color of the profile marker"; - break; - } -} - -//---------------------------------------------- -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ -inst *in; - -in=calloc(1,sizeof(inst)); -in->w=width; -in->h=height; - -in->x=width/2; -in->y=height/2; -in->tilt=0.0; -in->len=3*width/4; -in->chn=3; -in->m1=0; -in->m2=0; -in->rt=1; -in->gt=1; -in->bt=1; -in->yt=0; -in->ut=0; -in->vt=0; -in->at=0; -in->davg=1; -in->drms=1; -in->dmin=0; -in->dmax=0; -in->un=0; -in->col=0; -in->chc=0; - -in->poz=1; -in->mer=(3<<24)+7; //Y display + R,G,B traces -in->dit=32+64; //avg+RMS - -in->sl=(float_rgba*)calloc(width*height,sizeof(float_rgba)); -in->p=(profdata*)calloc(1,sizeof(profdata)); - -in->p->n=5; - -return (f0r_instance_t)in; -} - -//--------------------------------------------------- -void f0r_destruct(f0r_instance_t instance) -{ -inst *in; - -in=(inst*)instance; - -free(in->sl); -free(in->p); -free(instance); -} - -//----------------------------------------------------- -void f0r_set_param_value(f0r_instance_t instance, f0r_param_t parm, int param_index) -{ -inst *p; -double tmpf; -int tmpi,chg; - -p=(inst*)instance; - -chg=0; -switch(param_index) - { - case 0: //X - tmpi=map_value_forward(*((double*)parm), 0.0, p->w); - if (tmpi != p->x) chg=1; - p->x=tmpi; - break; - case 1: //Y - tmpi=map_value_forward(*((double*)parm), 0.0, p->h); - if (tmpi != p->y) chg=1; - p->y=tmpi; - break; - case 2: //tilt - tmpf=map_value_forward(*((double*)parm), -PI/2.0, PI/2.0); - if (tmpf != p->tilt) chg=1; - p->tilt=tmpf; - break; - case 3: //length - tmpi=map_value_forward(*((double*)parm), 20.0, sqrtf(p->w*p->w+p->h*p->h)); - if (tmpi != p->len) chg=1; - p->len=tmpi; - break; - case 4: //channel - tmpi=map_value_forward(*((double*)parm), 1.0, 7.9999); - if (tmpi != p->chn) chg=1; - p->chn=tmpi; - break; - case 5: //marker 1 - tmpi=map_value_forward(*((double*)parm), -1.0, p->p->n); - if (tmpi != p->m1) chg=1; - p->m1=tmpi; - break; - case 6: //marker 2 - tmpi=map_value_forward(*((double*)parm), -1.0, p->p->n); - if (tmpi != p->m2) chg=1; - p->m2=tmpi; - break; - case 7: //R trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->rt != tmpi) chg=1; - p->rt=tmpi; - break; - case 8: //G trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->gt != tmpi) chg=1; - p->gt=tmpi; - break; - case 9: //B trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->bt != tmpi) chg=1; - p->bt=tmpi; - break; - case 10: //Y trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->yt != tmpi) chg=1; - p->yt=tmpi; - break; - case 11: //U trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->ut != tmpi) chg=1; - p->ut=tmpi; - break; - case 12: //V trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->vt != tmpi) chg=1; - p->vt=tmpi; - break; - case 13: //alpha trace - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->at != tmpi) chg=1; - p->at=tmpi; - break; - case 14: //display avg - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->davg != tmpi) chg=1; - p->davg=tmpi; - break; - case 15: //display RMS - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->drms != tmpi) chg=1; - p->drms=tmpi; - break; - case 16: //display min - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->dmin != tmpi) chg=1; - p->dmin=tmpi; - break; - case 17: //display max - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->dmax != tmpi) chg=1; - p->dmax=tmpi; - break; - case 18: //256 units - tmpi=map_value_forward(*((double*)parm), 0.0, 1.0); //BOOL!! - if (p->un != tmpi) chg=1; - p->un=tmpi; - break; - case 19: //color mode - tmpi=map_value_forward(*((double*)parm), 0.0, 1.9999); - if (p->col != tmpi) chg=1; - p->col=tmpi; - break; - case 20: //Crosshair color - tmpi=map_value_forward(*((double*)parm), 0.0, 7.9999); - if (p->chc != tmpi) chg=1; - p->chc=tmpi; - break; - } - -if (chg==0) return; - -p->mer=p->chn<<24; -p->mer=p->mer+p->rt; -p->mer=p->mer+2*p->gt; -p->mer=p->mer+4*p->bt; -p->mer=p->mer+8*p->yt; -p->mer=p->mer+16*p->ut; -p->mer=p->mer+32*p->vt; -p->mer=p->mer+64*p->at; - -p->dit=0; -if (p->m1>=0) p->dit=p->dit+1; -if (p->m2>=0) p->dit=p->dit+4; -if ((p->m1>=0)&&(p->m2>=0)) p->dit=p->dit+16; -p->dit=p->dit+32*p->davg; -p->dit=p->dit+64*p->drms; -p->dit=p->dit+128*p->dmin; -p->dit=p->dit+256*p->dmax; - -} - -//-------------------------------------------------- -void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) -{ -inst *p; - -p=(inst*)instance; - -switch(param_index) - { - case 0: - *((double*)param)=map_value_backward(p->x, 0.0, p->w); - break; - case 1: - *((double*)param)=map_value_backward(p->y, 0.0, p->h); - break; - case 2: - *((double*)param)=map_value_backward(p->tilt, -PI/2.0, PI/2.0); - break; - case 3: - *((double*)param)=map_value_backward(p->len, 20.0, sqrtf(p->w*p->w+p->h*p->h)); - break; - case 4: - *((double*)param)=map_value_backward(p->chn, 0.0, 7.9999); - break; - case 5: - *((double*)param)=map_value_backward(p->m1, 0.0, p->p->n); - break; - case 6: - *((double*)param)=map_value_backward(p->m2, 0.0, p->p->n); - break; - case 7: - *((double*)param)=map_value_backward(p->rt, 0.0, 1.0);//BOOL!! - break; - case 8: - *((double*)param)=map_value_backward(p->gt, 0.0, 1.0);//BOOL!! - break; - case 9: - *((double*)param)=map_value_backward(p->bt, 0.0, 1.0);//BOOL!! - break; - case 10: - *((double*)param)=map_value_backward(p->yt, 0.0, 1.0);//BOOL!! - break; - case 11: - *((double*)param)=map_value_backward(p->ut, 0.0, 1.0);//BOOL!! - break; - case 12: - *((double*)param)=map_value_backward(p->vt, 0.0, 1.0);//BOOL!! - break; - case 13: - *((double*)param)=map_value_backward(p->at, 0.0, 1.0);//BOOL!! - break; - case 14: - *((double*)param)=map_value_backward(p->davg, 0.0, 1.0);//BOOL!! - break; - case 15: - *((double*)param)=map_value_backward(p->drms, 0.0, 1.0);//BOOL!! - break; - case 16: - *((double*)param)=map_value_backward(p->dmin, 0.0, 1.0);//BOOL!! - break; - case 17: - *((double*)param)=map_value_backward(p->dmax, 0.0, 1.0);//BOOL!! - break; - case 18: - *((double*)param)=map_value_backward(p->un, 0.0, 1.0);//BOOL!! - break; - case 19: - *((double*)param)=map_value_backward(p->col, 0.0, 1.9999); - break; - case 20: - *((double*)param)=map_value_backward(p->chc, 0.0, 7.9999); - break; - } -} - -//------------------------------------------------- -void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) -{ -inst *in; - -assert(instance); -in=(inst*)instance; - -color2floatrgba(inframe, in->sl, in->w , in->h); - -prof(in->sl, in->w, in->h, &in->poz, in->x, in->y, in->tilt, in->len, 1, in->mer, in->un, 0, in->m1, in->m2, in->dit, in->chc, in->col, in->p); - -floatrgba2color(in->sl, outframe, in->w , in->h); -} - diff --git a/src/filter/medians/CMakeLists.txt b/src/filter/medians/CMakeLists.txt index c953d43..8c6e786 100644 --- a/src/filter/medians/CMakeLists.txt +++ b/src/filter/medians/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET medians) if (MSVC) - set_source_files_properties (medians.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/medians/ctmf.h b/src/filter/medians/ctmf.h index 2722e1b..f956aa6 100644 --- a/src/filter/medians/ctmf.h +++ b/src/filter/medians/ctmf.h @@ -36,17 +36,7 @@ #include #include #include - -/* Type declarations */ -#ifdef _MSC_VER -#include -typedef UINT8 uint8_t; -typedef UINT16 uint16_t; -typedef UINT32 uint32_t; -#pragma warning( disable: 4799 ) -#else #include -#endif /* Intrinsic declarations */ #if defined(__SSE2__) || defined(__MMX__) diff --git a/src/filter/nervous/nervous.cpp b/src/filter/nervous/nervous.cpp index df575d5..1a2d8d7 100644 --- a/src/filter/nervous/nervous.cpp +++ b/src/filter/nervous/nervous.cpp @@ -99,7 +99,7 @@ } Nervous::~Nervous() { - if(buffer) free(buffer); + free(buffer); } void Nervous::_init(int wdt, int hgt) { diff --git a/src/filter/normaliz0r/CMakeLists.txt b/src/filter/normaliz0r/CMakeLists.txt index 27eb50f..520860b 100644 --- a/src/filter/normaliz0r/CMakeLists.txt +++ b/src/filter/normaliz0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET normaliz0r) if (MSVC) - set_source_files_properties (normaliz0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/nosync0r/nosync0r.cpp b/src/filter/nosync0r/nosync0r.cpp index 5cb231f..023b7f6 100644 --- a/src/filter/nosync0r/nosync0r.cpp +++ b/src/filter/nosync0r/nosync0r.cpp @@ -17,7 +17,7 @@ const uint32_t* in) { unsigned int - first_line=static_cast(height*std::fmod(hsync,1.0)); + first_line=static_cast(height*std::fmod(std::fabs(hsync),1.0)); std::copy(in+width*first_line, in+width*height, out); std::copy(in, in+width*first_line, out+width*(height-first_line)); diff --git a/src/filter/perspective/CMakeLists.txt b/src/filter/perspective/CMakeLists.txt index 85df84a..f1da62b 100644 --- a/src/filter/perspective/CMakeLists.txt +++ b/src/filter/perspective/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET perspective) if (MSVC) - set_source_files_properties (perspective.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/perspective/perspective.c b/src/filter/perspective/perspective.c index d84c39a..cbd7e79 100644 --- a/src/filter/perspective/perspective.c +++ b/src/filter/perspective/perspective.c @@ -173,12 +173,6 @@ break; } } - -#if defined(_MSC_VER) -__inline const long lrint(double x){ - return (long)(x+0.5); -} -#endif void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe) diff --git a/src/filter/pixeliz0r/CMakeLists.txt b/src/filter/pixeliz0r/CMakeLists.txt index c3a60c0..b437cd0 100644 --- a/src/filter/pixeliz0r/CMakeLists.txt +++ b/src/filter/pixeliz0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET pixeliz0r) if (MSVC) - set_source_files_properties (pixeliz0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/pixeliz0r/pixeliz0r.c b/src/filter/pixeliz0r/pixeliz0r.c index 5eb9020..c1d9d30 100644 --- a/src/filter/pixeliz0r/pixeliz0r.c +++ b/src/filter/pixeliz0r/pixeliz0r.c @@ -50,12 +50,12 @@ case 0: info->name = "Block width"; info->type = F0R_PARAM_DOUBLE; - info->explanation = "Horizontal size of one \"pixel\""; + info->explanation = "Horizontal size of one 'pixel'"; break; case 1: info->name = "Block height"; info->type = F0R_PARAM_DOUBLE; - info->explanation = "Vertical size of one \"pixel\""; + info->explanation = "Vertical size of one 'pixel'"; break; } } diff --git a/src/filter/pixs0r/CMakeLists.txt b/src/filter/pixs0r/CMakeLists.txt new file mode 100644 index 0000000..dc962e1 --- /dev/null +++ b/src/filter/pixs0r/CMakeLists.txt @@ -0,0 +1,11 @@ +set (SOURCES pixs0r.cc) +set (TARGET pixs0r) + +if (MSVC) + set (SOURCES ${SOURCES} ${FREI0R_DEF}) +endif (MSVC) + +add_library (${TARGET} MODULE ${SOURCES}) +set_target_properties (${TARGET} PROPERTIES PREFIX "") + +install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR}) \ No newline at end of file diff --git a/src/filter/pixs0r/pixs0r.cc b/src/filter/pixs0r/pixs0r.cc new file mode 100644 index 0000000..3c72b41 --- /dev/null +++ b/src/filter/pixs0r/pixs0r.cc @@ -0,0 +1,218 @@ +#include + +struct pixshift0r +{ + unsigned int m_width; + unsigned int m_height; + + unsigned int m_shift_intensity; + unsigned int m_block_height; + + // If m_block_height == 0, then these bound block heights + unsigned int m_block_height_min; + unsigned int m_block_height_max; + + // FIXME: It might be better to make it global variable. + std::random_device m_rng_dev; + + std::uniform_int_distribution m_shift_rng; + std::uniform_int_distribution m_block_height_rng; + + pixshift0r(unsigned int width, unsigned int height) + : m_width(width), m_height(height), m_block_height(0) {} + + void process(const uint32_t *inframe, uint32_t *outframe) + { + for (unsigned int b = 0; b < m_height;) + { + unsigned int block_height = m_block_height ? m_block_height : m_block_height_rng(m_rng_dev); + + // Number of rows to shift is either block size or + // what we can *safely* operate on (avoids corruption). + block_height = std::min(block_height, m_height - b); + + long long shift = m_shift_rng(m_rng_dev); + + for (unsigned int j = 0; j < block_height; ++j) + { + // NOTE: Faulty implementations, such as FFmpeg don't + // check for (width % 8 == 0 && height % 8 == 0). + // + // A possible workaround for all filters, is a scale filter: + // (e.g "scale=round(in_w/8)*8:round(in_h/8)*8:flags=neighbor"). + // + // https://ffmpeg.org/doxygen/trunk/vf__frei0r_8c_source.html#l00352 + size_t pitch = static_cast(b + j) * m_width; + + const uint32_t *inrow = inframe + pitch; + uint32_t *outrow = outframe + pitch; + + if (shift > 0) + { + std::copy (inrow, inrow + m_width - shift, outrow + shift); + std::copy (inrow + m_width - shift, inrow + m_width, outrow); + } + else if (shift < 0) + { + std::copy (inrow, inrow - shift, outrow + m_width + shift); + std::copy (inrow - shift, inrow + m_width, outrow); + } + else + { + std::copy (inrow, inrow + m_width, outrow); + } + } + + b += block_height; + } + } + + void set_block_height_range(unsigned int min_bh, unsigned int max_bh) + { + this->m_block_height_min = min_bh; + this->m_block_height_max = max_bh; + + auto rng_params = decltype(this->m_block_height_rng)::param_type(min_bh, max_bh); + + this->m_block_height_rng.param(rng_params); + } + + void set_shift_intensity(unsigned int shift_intensity) + { + this->m_shift_intensity = shift_intensity; + + long long intensity = static_cast(shift_intensity); + + auto rng_params = decltype(this->m_shift_rng)::param_type(-intensity, intensity); + + this->m_shift_rng.param(rng_params); + } +}; + +extern "C" { +#include + +int f0r_init() +{ + return 0; +} + +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + pixshift0r *instance = new pixshift0r(width, height); + + instance->set_shift_intensity(width / 100); + instance->set_block_height_range(height / 100, height / 10); + + return instance; +} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) +{ + info->name = "pixs0r"; + info->author = "xsbee"; + info->explanation = "Glitch image shifting rows to and fro"; + info->major_version = 1; + info->minor_version = 0; + info->frei0r_version = FREI0R_MAJOR_VERSION; + + info->color_model = F0R_COLOR_MODEL_PACKED32; + info->plugin_type = F0R_PLUGIN_TYPE_FILTER; + info->num_params = 4; +} + +void f0r_get_param_info (f0r_param_info_t *info, int param_index) +{ + switch (param_index) + { + case 0: + info->name = "shift_intensity"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Agressiveness of row/column-shifting"; + break; + + case 1: + info->name = "block_height"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Height of each block whose shift is invariant (0 = random)"; + break; + + case 2: + info->name = "block_height_min"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Minimum height of block (if random mode)"; + break; + + case 3: + info->name = "block_height_max"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Maximum height of block (if random mode)"; + break; + } +} + +void f0r_get_param_value( + f0r_instance_t instance, + f0r_param_t param, + int param_index +) +{ + pixshift0r* context = (pixshift0r*)instance; + + switch (param_index) { + case 0: + *static_cast(param) = static_cast(context->m_shift_intensity) / context->m_width; + break; + case 1: + *static_cast(param) = static_cast(context->m_block_height) / context->m_height; + break; + case 2: + *static_cast(param) = static_cast(context->m_block_height_min) / context->m_height; + break; + case 3: + *static_cast(param) = static_cast(context->m_block_height_max) / context->m_height; + break; + } +} + +void f0r_set_param_value( + f0r_instance_t instance, + f0r_param_t param, + int param_index +) +{ + pixshift0r* context = (pixshift0r*)instance; + + switch (param_index) { + case 0: + context->set_shift_intensity (*static_cast(param) * context->m_width); + break; + case 1: + context->m_block_height = *static_cast(param) * context->m_height; + break; + case 2: + context->set_block_height_range (*static_cast(param) * context->m_height, context->m_block_height_max); + break; + case 3: + context->set_block_height_range (context->m_block_height_min, *static_cast(param) * context->m_height); + break; + } +} + +void f0r_update ( + f0r_instance_t instance, + double, + const uint32_t *inframe, + uint32_t *outframe +) +{ + static_cast(instance)->process(inframe, outframe); +} + +void f0r_deinit() {} + +void f0r_destruct (f0r_instance_t instance) +{ + delete static_cast(instance); +} +} diff --git a/src/filter/posterize/CMakeLists.txt b/src/filter/posterize/CMakeLists.txt index 0e6c1b0..cb59dc0 100644 --- a/src/filter/posterize/CMakeLists.txt +++ b/src/filter/posterize/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET posterize) if (MSVC) - set_source_files_properties (posterize.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/rgbnoise/CMakeLists.txt b/src/filter/rgbnoise/CMakeLists.txt index 15eebd2..f437caf 100644 --- a/src/filter/rgbnoise/CMakeLists.txt +++ b/src/filter/rgbnoise/CMakeLists.txt @@ -2,11 +2,12 @@ set (TARGET rgbnoise) if (MSVC) - set_source_files_properties (rgbnoise.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") diff --git a/src/filter/rgbparade/CMakeLists.txt b/src/filter/rgbparade/CMakeLists.txt index 597995b..5a44153 100644 --- a/src/filter/rgbparade/CMakeLists.txt +++ b/src/filter/rgbparade/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET rgbparade) if (MSVC) - set_source_files_properties (rgbparade.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/rgbsplit0r/CMakeLists.txt b/src/filter/rgbsplit0r/CMakeLists.txt index 9da2a69..516359c 100644 --- a/src/filter/rgbsplit0r/CMakeLists.txt +++ b/src/filter/rgbsplit0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET rgbsplit0r) if (MSVC) - set_source_files_properties (rgbsplit0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/saturat0r/CMakeLists.txt b/src/filter/saturat0r/CMakeLists.txt index d03401d..3a9be1a 100644 --- a/src/filter/saturat0r/CMakeLists.txt +++ b/src/filter/saturat0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET saturat0r) if (MSVC) - set_source_files_properties (saturat0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/scale0tilt/CMakeLists.txt b/src/filter/scale0tilt/CMakeLists.txt index 71887dc..f2adafb 100644 --- a/src/filter/scale0tilt/CMakeLists.txt +++ b/src/filter/scale0tilt/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET scale0tilt) if (MSVC) - set_source_files_properties (scale0tilt.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/select0r/CMakeLists.txt b/src/filter/select0r/CMakeLists.txt index f12e4ee..9ae3379 100644 --- a/src/filter/select0r/CMakeLists.txt +++ b/src/filter/select0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET select0r) if (MSVC) - set_source_files_properties (select0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/select0r/select0r.c b/src/filter/select0r/select0r.c index 6ff475d..45b642f 100644 --- a/src/filter/select0r/select0r.c +++ b/src/filter/select0r/select0r.c @@ -104,7 +104,7 @@ float ax,ay,az,r; // wrap hue term -0.5 .. 0.5 - ax = 0.5 - fabsf(fabsf(hue - chue) - 0.5); + ax = 0.5f - fabsf(fabsf(hue - chue) - 0.5f); ax=ax*dhue; ay=fabsf(y-cy)*dy; az=fabsf(z-cz)*dz; @@ -119,7 +119,7 @@ { float ax,ay,az,r; - ax = 0.5 - fabsf(fabsf(hue - chue) - 0.5); + ax = 0.5f - fabsf(fabsf(hue - chue) - 0.5f); ax=ax*dhue; ay=(y-cy)*dy; az=(z-cz)*dz; @@ -131,7 +131,7 @@ { float ax,ay,az,r; - ax = 0.5 - fabsf(fabsf(hue - chue) - 0.5); + ax = 0.5f - fabsf(fabsf(hue - chue) - 0.5f); ax=ax*dhue; ay=fabsf(y-cy)*dy; az=fabsf(z-cz)*dz; @@ -797,10 +797,6 @@ //--------------------------------------------------- void f0r_destruct(f0r_instance_t instance) { - inst *in; - - in=(inst*)instance; - free(instance); } diff --git a/src/filter/sharpness/CMakeLists.txt b/src/filter/sharpness/CMakeLists.txt index 3db05e4..027c846 100644 --- a/src/filter/sharpness/CMakeLists.txt +++ b/src/filter/sharpness/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET sharpness) if (MSVC) - set_source_files_properties (sharpness.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/sigmoidaltransfer/CMakeLists.txt b/src/filter/sigmoidaltransfer/CMakeLists.txt index 185b984..592b8c0 100644 --- a/src/filter/sigmoidaltransfer/CMakeLists.txt +++ b/src/filter/sigmoidaltransfer/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET sigmoidaltransfer) if (MSVC) - set_source_files_properties (sigmoidaltransfer.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/softglow/CMakeLists.txt b/src/filter/softglow/CMakeLists.txt index 759fcb8..dfc4fa4 100644 --- a/src/filter/softglow/CMakeLists.txt +++ b/src/filter/softglow/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET softglow) if (MSVC) - set_source_files_properties (softglow.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/spillsupress/CMakeLists.txt b/src/filter/spillsupress/CMakeLists.txt index 125c2f9..06d9a80 100644 --- a/src/filter/spillsupress/CMakeLists.txt +++ b/src/filter/spillsupress/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET spillsupress) if (MSVC) - set_source_files_properties (spillsupress.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/squareblur/CMakeLists.txt b/src/filter/squareblur/CMakeLists.txt index 30c33fd..1095118 100644 --- a/src/filter/squareblur/CMakeLists.txt +++ b/src/filter/squareblur/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET squareblur) if (MSVC) - set_source_files_properties (squareblur.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/tehroxx0r/CMakeLists.txt b/src/filter/tehroxx0r/CMakeLists.txt index e5bb4d0..f3b0396 100644 --- a/src/filter/tehroxx0r/CMakeLists.txt +++ b/src/filter/tehroxx0r/CMakeLists.txt @@ -1,8 +1,7 @@ -set (SOURCES tehRoxx0r.c) -set (TARGET tehRoxx0r) +set (SOURCES tehroxx0r.c) +set (TARGET tehroxx0r) if (MSVC) - set_source_files_properties (tehRoxx0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/tehroxx0r/tehRoxx0r.c b/src/filter/tehroxx0r/tehRoxx0r.c deleted file mode 100644 index b7cd6fe..0000000 --- a/src/filter/tehroxx0r/tehRoxx0r.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "frei0r.h" -#include -#include -#include -#include - -/** - * This is our instance. - * It has a buffer allocated to place a small version of the incoming - * frame into. - */ -typedef struct teh_roxx0r -{ - unsigned int width; // frame size in x-dimension - unsigned int height; // frame size in y-dimension - unsigned int block_size; // x/y size of one block - - double change_speed; - double last_time; - double time_stack; - - uint32_t* small_block; // buffer to write downscaled frame - -} tehRoxx0r_instance_t; - - -// returns greatest common divisor of to int numbers -int gcd(int a, int b); - -int f0r_init() -{ - return 1; -} - -void f0r_deinit() -{ /* no initialization required */ } - -void f0r_get_plugin_info(f0r_plugin_info_t* tehRoxx0rInfo) -{ - tehRoxx0rInfo->name = "TehRoxx0r"; - tehRoxx0rInfo->author = "Coma"; - tehRoxx0rInfo->plugin_type = F0R_PLUGIN_TYPE_FILTER; - tehRoxx0rInfo->color_model = F0R_COLOR_MODEL_PACKED32; - tehRoxx0rInfo->frei0r_version = FREI0R_MAJOR_VERSION; - tehRoxx0rInfo->major_version = 0; - tehRoxx0rInfo->minor_version = 9; - tehRoxx0rInfo->num_params = 1; - tehRoxx0rInfo->explanation = "Something videowall-ish"; -} - -void f0r_get_param_info(f0r_param_info_t* info, int param_index) -{ - - info->name = "Interval"; - info->type = F0R_PARAM_DOUBLE; - info->explanation = "Changing speed of small blocks"; -} - -f0r_instance_t f0r_construct(unsigned int width, unsigned int height) -{ - int blocksize; - tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)calloc(1, sizeof(*inst)); - inst->width = width; inst->height = height; - inst->change_speed = 0.01; - - // get greatest common divisor - blocksize = gcd(width, height); - // this will sometimes be to large, so roughly estimate a check - if(blocksize >= (width/3) || blocksize >= (height/3)) - blocksize /= 2; - - inst->block_size = blocksize; - - inst->small_block = - (uint32_t*)malloc(sizeof(uint32_t)*inst->block_size*inst->block_size); - - return (f0r_instance_t)inst; -} - -void f0r_destruct(f0r_instance_t instance) -{ - tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)instance; - free(inst->small_block); - free(inst); -} - -void f0r_set_param_value(f0r_instance_t instance, - f0r_param_t param, int param_index) -{ - tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t *)instance; - // (tehRoxx0r_instance_t*)malloc(sizeof(tehRoxx0r_instance_t)); - - switch(param_index) - { - case 0: - inst->change_speed = *((double*)param); - break; - }; -} - -void f0r_get_param_value(f0r_instance_t instance, - f0r_param_t param, int param_index) -{ - tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t *)instance; - // (tehRoxx0r_instance_t*)malloc(sizeof(tehRoxx0r_instance_t)); - - switch(param_index) - { - case 0: - *((double*)param) = inst->change_speed; - break; - }; -} - - -void f0r_update(f0r_instance_t instance, double time, - const uint32_t* inframe, uint32_t* outframe) -{ - assert(instance); - tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)instance; - unsigned int w = inst->width; - unsigned int h = inst->height; - uint32_t* dst; - const uint32_t* src; - uint32_t* small_block = inst->small_block; - unsigned int x,y; - unsigned int small_x, small_y; - unsigned int small_w, small_h; - double step_x, step_y; - unsigned int pos_w, pos_h; - - // get x/y-size of middle block - small_w = w-2*inst->block_size; - small_h = h-2*inst->block_size; - - // get interpolation step for that - step_x = (double)w / (double)small_w; - step_y = (double)h / (double)small_h; - - // make background black transparent - memset(outframe, 0, w * h * sizeof(uint32_t)); - - // copy a downscaled version into the middle of the result frame - // (blocksize to x-blocksize and blocksize to y-blocksize) - for(y = 0, small_y=inst->block_size;small_yblock_size;small_y++, - y=step_y*(small_y-inst->block_size)) - { - src = inframe + y*w; - dst = outframe + small_y*w + inst->block_size; - for(x=0;xblock_size;x++) - { - *dst++ = *(src + (int)(x*step_x)); - } - } - - // add elapsed time to timestack - inst->time_stack += (time-inst->last_time); - - - // get interpolation step size - step_x = w / inst->block_size; - step_y = h / inst->block_size; - - // create a small picture - for(y=0,small_y=0; small_yblock_size; small_y++,y+=step_y) - { - src = inframe + y*w; - dst = small_block + small_y*inst->block_size; - for(x=0,small_x = 0; small_xblock_size; small_x++)//,x+=step_x) - { - *dst++ = *src; - src += (unsigned int)step_x; - } - } - // do we actually changed anything? - if(inst->time_stack > inst->change_speed) - { - // get random position - pos_w = inst->block_size * - (unsigned int)(rand()/(double)RAND_MAX * ((w / inst->block_size))); - pos_h = inst->block_size * - (unsigned int)(rand()/(double)RAND_MAX * ((h / inst->block_size))); - - // now copy to some (random) places along the border of - // the incoming frame..... - dst = outframe + pos_w; - src = small_block; - for(x=0; xblock_size; - x++, dst += w, src += inst->block_size) - memcpy(dst, src, sizeof(int32_t)*inst->block_size); - - dst = outframe + pos_h * w; - src = small_block; - for(x=0; xblock_size; - x++, dst += w, src += inst->block_size) - memcpy(dst, src, sizeof(int32_t)*inst->block_size); - - dst = outframe + pos_h* w + w - inst->block_size; - src = small_block; - for(x=0; xblock_size; - x++, dst += w, src += inst->block_size) - memcpy(dst, src, sizeof(int32_t)*inst->block_size); - - - dst = outframe + (h-inst->block_size) *w + pos_w; - src = small_block; - for(x=0; xblock_size; - x++, dst += w, src += inst->block_size) - memcpy(dst, src, sizeof(int32_t)*inst->block_size); - - - // reset timestack - inst->time_stack = 0.0; - } - - - inst->last_time = time; -} - -// greatest common divisor. this will never become smaller than 8. -int gcd(int a, int b) -{ - if(b==0) return a; - else return gcd(b, a%b); -} diff --git a/src/filter/tehroxx0r/tehroxx0r.c b/src/filter/tehroxx0r/tehroxx0r.c new file mode 100644 index 0000000..b7cd6fe --- /dev/null +++ b/src/filter/tehroxx0r/tehroxx0r.c @@ -0,0 +1,225 @@ +#include "frei0r.h" +#include +#include +#include +#include + +/** + * This is our instance. + * It has a buffer allocated to place a small version of the incoming + * frame into. + */ +typedef struct teh_roxx0r +{ + unsigned int width; // frame size in x-dimension + unsigned int height; // frame size in y-dimension + unsigned int block_size; // x/y size of one block + + double change_speed; + double last_time; + double time_stack; + + uint32_t* small_block; // buffer to write downscaled frame + +} tehRoxx0r_instance_t; + + +// returns greatest common divisor of to int numbers +int gcd(int a, int b); + +int f0r_init() +{ + return 1; +} + +void f0r_deinit() +{ /* no initialization required */ } + +void f0r_get_plugin_info(f0r_plugin_info_t* tehRoxx0rInfo) +{ + tehRoxx0rInfo->name = "TehRoxx0r"; + tehRoxx0rInfo->author = "Coma"; + tehRoxx0rInfo->plugin_type = F0R_PLUGIN_TYPE_FILTER; + tehRoxx0rInfo->color_model = F0R_COLOR_MODEL_PACKED32; + tehRoxx0rInfo->frei0r_version = FREI0R_MAJOR_VERSION; + tehRoxx0rInfo->major_version = 0; + tehRoxx0rInfo->minor_version = 9; + tehRoxx0rInfo->num_params = 1; + tehRoxx0rInfo->explanation = "Something videowall-ish"; +} + +void f0r_get_param_info(f0r_param_info_t* info, int param_index) +{ + + info->name = "Interval"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Changing speed of small blocks"; +} + +f0r_instance_t f0r_construct(unsigned int width, unsigned int height) +{ + int blocksize; + tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)calloc(1, sizeof(*inst)); + inst->width = width; inst->height = height; + inst->change_speed = 0.01; + + // get greatest common divisor + blocksize = gcd(width, height); + // this will sometimes be to large, so roughly estimate a check + if(blocksize >= (width/3) || blocksize >= (height/3)) + blocksize /= 2; + + inst->block_size = blocksize; + + inst->small_block = + (uint32_t*)malloc(sizeof(uint32_t)*inst->block_size*inst->block_size); + + return (f0r_instance_t)inst; +} + +void f0r_destruct(f0r_instance_t instance) +{ + tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)instance; + free(inst->small_block); + free(inst); +} + +void f0r_set_param_value(f0r_instance_t instance, + f0r_param_t param, int param_index) +{ + tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t *)instance; + // (tehRoxx0r_instance_t*)malloc(sizeof(tehRoxx0r_instance_t)); + + switch(param_index) + { + case 0: + inst->change_speed = *((double*)param); + break; + }; +} + +void f0r_get_param_value(f0r_instance_t instance, + f0r_param_t param, int param_index) +{ + tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t *)instance; + // (tehRoxx0r_instance_t*)malloc(sizeof(tehRoxx0r_instance_t)); + + switch(param_index) + { + case 0: + *((double*)param) = inst->change_speed; + break; + }; +} + + +void f0r_update(f0r_instance_t instance, double time, + const uint32_t* inframe, uint32_t* outframe) +{ + assert(instance); + tehRoxx0r_instance_t* inst = (tehRoxx0r_instance_t*)instance; + unsigned int w = inst->width; + unsigned int h = inst->height; + uint32_t* dst; + const uint32_t* src; + uint32_t* small_block = inst->small_block; + unsigned int x,y; + unsigned int small_x, small_y; + unsigned int small_w, small_h; + double step_x, step_y; + unsigned int pos_w, pos_h; + + // get x/y-size of middle block + small_w = w-2*inst->block_size; + small_h = h-2*inst->block_size; + + // get interpolation step for that + step_x = (double)w / (double)small_w; + step_y = (double)h / (double)small_h; + + // make background black transparent + memset(outframe, 0, w * h * sizeof(uint32_t)); + + // copy a downscaled version into the middle of the result frame + // (blocksize to x-blocksize and blocksize to y-blocksize) + for(y = 0, small_y=inst->block_size;small_yblock_size;small_y++, + y=step_y*(small_y-inst->block_size)) + { + src = inframe + y*w; + dst = outframe + small_y*w + inst->block_size; + for(x=0;xblock_size;x++) + { + *dst++ = *(src + (int)(x*step_x)); + } + } + + // add elapsed time to timestack + inst->time_stack += (time-inst->last_time); + + + // get interpolation step size + step_x = w / inst->block_size; + step_y = h / inst->block_size; + + // create a small picture + for(y=0,small_y=0; small_yblock_size; small_y++,y+=step_y) + { + src = inframe + y*w; + dst = small_block + small_y*inst->block_size; + for(x=0,small_x = 0; small_xblock_size; small_x++)//,x+=step_x) + { + *dst++ = *src; + src += (unsigned int)step_x; + } + } + // do we actually changed anything? + if(inst->time_stack > inst->change_speed) + { + // get random position + pos_w = inst->block_size * + (unsigned int)(rand()/(double)RAND_MAX * ((w / inst->block_size))); + pos_h = inst->block_size * + (unsigned int)(rand()/(double)RAND_MAX * ((h / inst->block_size))); + + // now copy to some (random) places along the border of + // the incoming frame..... + dst = outframe + pos_w; + src = small_block; + for(x=0; xblock_size; + x++, dst += w, src += inst->block_size) + memcpy(dst, src, sizeof(int32_t)*inst->block_size); + + dst = outframe + pos_h * w; + src = small_block; + for(x=0; xblock_size; + x++, dst += w, src += inst->block_size) + memcpy(dst, src, sizeof(int32_t)*inst->block_size); + + dst = outframe + pos_h* w + w - inst->block_size; + src = small_block; + for(x=0; xblock_size; + x++, dst += w, src += inst->block_size) + memcpy(dst, src, sizeof(int32_t)*inst->block_size); + + + dst = outframe + (h-inst->block_size) *w + pos_w; + src = small_block; + for(x=0; xblock_size; + x++, dst += w, src += inst->block_size) + memcpy(dst, src, sizeof(int32_t)*inst->block_size); + + + // reset timestack + inst->time_stack = 0.0; + } + + + inst->last_time = time; +} + +// greatest common divisor. this will never become smaller than 8. +int gcd(int a, int b) +{ + if(b==0) return a; + else return gcd(b, a%b); +} diff --git a/src/filter/three_point_balance/CMakeLists.txt b/src/filter/three_point_balance/CMakeLists.txt index 7a3b35f..b3e09f3 100644 --- a/src/filter/three_point_balance/CMakeLists.txt +++ b/src/filter/three_point_balance/CMakeLists.txt @@ -7,7 +7,6 @@ set (TARGET three_point_balance) if (MSVC) - set_source_files_properties (three_point_balance.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/threshold0r/CMakeLists.txt b/src/filter/threshold0r/CMakeLists.txt index f5c480a..04beb52 100644 --- a/src/filter/threshold0r/CMakeLists.txt +++ b/src/filter/threshold0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET threshold0r) if (MSVC) - set_source_files_properties (threshold0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/tint0r/CMakeLists.txt b/src/filter/tint0r/CMakeLists.txt index 2ea47bf..835e8de 100644 --- a/src/filter/tint0r/CMakeLists.txt +++ b/src/filter/tint0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET tint0r) if (MSVC) - set_source_files_properties (tint0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/transparency/CMakeLists.txt b/src/filter/transparency/CMakeLists.txt index b65ab76..f1f2890 100644 --- a/src/filter/transparency/CMakeLists.txt +++ b/src/filter/transparency/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET transparency) if (MSVC) - set_source_files_properties (transparency.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/tutorial/tutorial.cpp b/src/filter/tutorial/tutorial.cpp index 15f02f0..e291546 100644 --- a/src/filter/tutorial/tutorial.cpp +++ b/src/filter/tutorial/tutorial.cpp @@ -57,7 +57,7 @@ // http://stackoverflow.com/questions/381621/using-arrays-or-stdvectors-in-c-whats-the-performance-gap // Using std::numeric_limits just for fun here. lookupTable = std::vector(std::numeric_limits::max()+1, 0); - std::cout << lookupTable.size() << " elements in the lookup table." << std::endl; + // std::cerr << lookupTable.size() << " elements in the lookup table." << std::endl; // Calculate the entries in the lookup table. Applied on the R value in this example. // If the R value of an input pixel is r, then the output R value will be mapped to lookupTable[r]. diff --git a/src/filter/vectorscope/CMakeLists.txt b/src/filter/vectorscope/CMakeLists.txt index 302566d..7d1b4f6 100644 --- a/src/filter/vectorscope/CMakeLists.txt +++ b/src/filter/vectorscope/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET vectorscope) if (MSVC) - set_source_files_properties (vectorscope.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/vertigo/CMakeLists.txt b/src/filter/vertigo/CMakeLists.txt index bc29ac9..6d222f1 100644 --- a/src/filter/vertigo/CMakeLists.txt +++ b/src/filter/vertigo/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET vertigo) if (MSVC) - set_source_files_properties (vertigo.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/filter/vertigo/vertigo.c b/src/filter/vertigo/vertigo.c index 253da8c..98b48f3 100644 --- a/src/filter/vertigo/vertigo.c +++ b/src/filter/vertigo/vertigo.c @@ -121,11 +121,7 @@ void f0r_destruct(f0r_instance_t instance) { vertigo_instance_t* inst = (vertigo_instance_t*)instance; - if(inst->buffer!=NULL) - { - free(inst->buffer); - inst->buffer = NULL; - } + free(inst->buffer); free(instance); } diff --git a/src/filter/vignette/vignette.cpp b/src/filter/vignette/vignette.cpp index cf3685c..3aa7281 100644 --- a/src/filter/vignette/vignette.cpp +++ b/src/filter/vignette/vignette.cpp @@ -17,6 +17,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#if defined(_MSC_VER) +#define _USE_MATH_DEFINES +#endif /* _MSC_VER */ #include #include "frei0r.hpp" #include "frei0r_math.h" diff --git a/src/filter/water/water.cpp b/src/filter/water/water.cpp index 1d9a589..66073d5 100644 --- a/src/filter/water/water.cpp +++ b/src/filter/water/water.cpp @@ -33,7 +33,6 @@ #include #include - #define CLIP_EDGES \ if(x - radius < 1) left -= (x-radius-1); \ @@ -66,23 +65,32 @@ class Water: public frei0r::filter { public: - double physics; - bool rain; - bool distort; - bool smooth; - bool surfer; - bool swirl; - bool randomize_swirl; + f0r_param_double physics; + f0r_param_bool swirl; + f0r_param_bool rain; + f0r_param_bool surfer; + f0r_param_bool smooth; + f0r_param_bool distort; + f0r_param_position position; + //bool randomize_swirl; Water(unsigned int width, unsigned int height) { - physics = 0.0; - register_param(physics, "physics", "water density: from 1 to 4"); + physics = 1.0; + swirl = 1; + rain = 0; + surfer = 0; + distort = 0; + smooth = 0; + position.x = 0; + position.y = 0; + register_param(physics, "physics", "water density: from 0.0 to 1.0"); + register_param(swirl, "swirl", "swirling whirpool in the center"); register_param(rain, "rain", "rain drops all over"); + register_param(surfer, "surfer", "surf the surface with a wandering finger"); + register_param(smooth, "smooth", "smooth up all perturbations on the surface"); register_param(distort, "distort", "distort all surface like dropping a bucket to the floor"); - register_param(smooth, "smooth", "smooth up all perturbations on the surface"); - register_param(surfer, "surfer", "surf the surface with a wandering finger"); - register_param(swirl, "swirl", "swirling whirpool in the center"); - register_param(randomize_swirl, "randomize_swirl", "randomize the swirling angle"); + register_param(position, "position", "swirl position coordinate, Relative center coordinate"); + //register_param(randomize_swirl, "randomize_swirl", "randomize the swirling angle"); Hpage = 0; ox = 80; @@ -92,26 +100,26 @@ BkGdImagePre = BkGdImage = BkGdImagePost = 0; Height[0] = Height[1] = 0; - + /* default physics */ density = 4; pheight = 600; radius = 30; - + raincount = 0; blend = 0; - + fastsrand(::time(NULL)); - + FCreateSines(); geo = new ScreenGeometry(); geo->w = width; geo->h = height; - geo->size = width*height*sizeof(uint32_t); + geo->size = width*(height+1)*sizeof(uint32_t); water_surfacesize = geo->size; - calc_optimization = (height-1)*width; + calc_optimization = (height)*(width); xang = fastrand()%2048; yang = fastrand()%2048; @@ -119,19 +127,14 @@ /* buffer allocation tango */ if ( width*height > 0 ) { - Height[0] = (uint32_t*)calloc(width*height, sizeof(uint32_t)); - Height[1] = (uint32_t*)calloc(width*height, sizeof(uint32_t)); - } - // buffer = (uint32_t*) malloc(geo->size); + Height[0] = (uint32_t*)calloc(width*(height+1), sizeof(uint32_t)); + Height[1] = (uint32_t*)calloc(width*(height+1), sizeof(uint32_t)); + } if ( geo->size > 0 ) { BkGdImagePre = (uint32_t*) malloc(geo->size); BkGdImage = (uint32_t*) malloc(geo->size); BkGdImagePost = (uint32_t*)malloc(geo->size); } - - - swirl = 1; - } ~Water() { @@ -141,15 +144,13 @@ free(BkGdImagePre); free(BkGdImage); free(BkGdImagePost); - // free(buffer); - } - - virtual void update() { - + } + + virtual void update(double time, + uint32_t* out, + const uint32_t* in) { memcpy(BkGdImage, in, width*height*sizeof(uint32_t)); - - water_update(); - + water_update(out); } private: @@ -190,14 +191,14 @@ void water_clear(); void water_distort(); void water_setphysics(double physics); - void water_update(); + void water_update(uint32_t* out); void water_drop(int x, int y); void water_bigsplash(int x, int y); void water_surfer(); void water_swirl(); void water_3swirls(); - void DrawWater(int page); + void DrawWater(int page,uint32_t* out); void CalcWater(int npage, int density); void CalcWaterBigFilter(int npage, int density); @@ -236,58 +237,6 @@ } }; - - - - - -/* TODO: port as parameters: - -int kbd_input(char key) { - int res = 1; - switch(key) { - case 'e': // bigsplash in center - water_bigsplash(geo->w>>1,geo->y>>1); - break; - case 'r': // random splash - water_bigsplash(fastrand()%geo->w,fastrand()%geo->h); - break; - case 't': // rain - rain = (rain)?0:1; - break; - case 'd': // distort surface - if(!rain) water_distort(); - break; - case 'f': // smooth surface - SmoothWater(Hpage); - break; - case 'y': // swirl - swirl = (swirl)?0:1; - break; - case 'u': // surfer - surfer = (surfer)?0:1; - break; - case 'g': // randomize swirl angles - swirlangle = fastrand()%2048; - xang = fastrand()%2048; - yang = fastrand()%2048; - break; - - case 'q': - if(physics>1) physics--; - water_setphysics(physics); - break; - case 'w': - if(physics<4) physics++; - water_setphysics(physics); - - default: - res = 0; - break; - } - return(res); -} -*/ void Water::water_clear() { memset(Height[0], 0, water_surfacesize); @@ -322,7 +271,9 @@ } } -void Water::water_update() { +void Water::water_update(uint32_t* out) { + if(distort && !rain) water_distort(); + if(smooth) SmoothWater(Hpage); if(rain) { raincount++; @@ -334,7 +285,7 @@ if(swirl) water_swirl(); if(surfer) water_surfer(); - DrawWater(Hpage); + DrawWater(Hpage,out); CalcWater(Hpage^1, density); Hpage ^=1 ; @@ -357,18 +308,18 @@ void Water::water_surfer() { x = (geo->w>>1) + (( - ( - (FSin( (xang* 65) >>8) >>8) * - (FSin( (xang*349) >>8) >>8) - ) * ((geo->w-8)>>1) - ) >> 16); + ( + (FSin( (xang* 65) >>8) >>8) * + (FSin( (xang*349) >>8) >>8) + ) * ((geo->w-8)>>1) + ) >> 16); y = (geo->h>>1) + (( - ( - (FSin( (yang*377) >>8) >>8) * - (FSin( (yang* 84) >>8) >>8) - ) * ((geo->h-8)>>1) - ) >> 16); + ( + (FSin( (yang*377) >>8) >>8) * + (FSin( (yang* 84) >>8) >>8) + ) * ((geo->h-8)>>1) + ) >> 16); xang += 13; yang += 12; @@ -377,16 +328,16 @@ offset = (oy+y)/2*geo->w + ((ox+x)>>1); // QUAAA Height[Hpage][offset] = pheight; Height[Hpage][offset + 1] = - Height[Hpage][offset - 1] = - Height[Hpage][offset + geo->w] = - Height[Hpage][offset - geo->w] = pheight >> 1; + Height[Hpage][offset - 1] = + Height[Hpage][offset + geo->w] = + Height[Hpage][offset - geo->w] = pheight >> 1; offset = y*geo->w + x; Height[Hpage][offset] = pheight<<1; Height[Hpage][offset + 1] = - Height[Hpage][offset - 1] = - Height[Hpage][offset + geo->w] = - Height[Hpage][offset - geo->w] = pheight; + Height[Hpage][offset - 1] = + Height[Hpage][offset + geo->w] = + Height[Hpage][offset - geo->w] = pheight; } else { @@ -401,84 +352,88 @@ void Water::water_swirl() { x = (geo->w>>1) + (( - (FCos(swirlangle)) * (25) - ) >> 16); + (FCos(swirlangle)) * (25) + ) >> 16); + y = (geo->h>>1) + (( - (FSin(swirlangle)) * (25) - ) >> 16); + (FSin(swirlangle)) * (25) + ) >> 16); + x += position.x; + y += position.y; + swirlangle += 50; if(mode & 0x4000) - HeightBlob(x,y, radius>>2, pheight, Hpage); + HeightBlob(x, y, radius>>2, pheight, Hpage); else WarpBlob(x, y, radius, pheight, Hpage); } - void Water::water_3swirls() { #define ANGLE 15 x = (95) + (( - (FCos(swirlangle)) * (ANGLE) - ) >> 16); + (FCos(swirlangle)) * (ANGLE) + ) >> 16); y = (45) + (( - (FSin(swirlangle)) * (ANGLE) - ) >> 16); + (FSin(swirlangle)) * (ANGLE) + ) >> 16); if(mode & 0x4000) HeightBlob(x,y, radius>>2, pheight, Hpage); else WarpBlob(x, y, radius, pheight, Hpage); x = (95) + (( - (FCos(swirlangle)) * (ANGLE) - ) >> 16); + (FCos(swirlangle)) * (ANGLE) + ) >> 16); y = (255) + (( - (FSin(swirlangle)) * (ANGLE) - ) >> 16); + (FSin(swirlangle)) * (ANGLE) + ) >> 16); if(mode & 0x4000) HeightBlob(x,y, radius>>2, pheight, Hpage); else WarpBlob(x, y, radius, pheight, Hpage); x = (345) + (( - (FCos(swirlangle)) * (ANGLE) - ) >> 16); + (FCos(swirlangle)) * (ANGLE) + ) >> 16); y = (150) + (( - (FSin(swirlangle)) * (ANGLE) - ) >> 16); + (FSin(swirlangle)) * (ANGLE) + ) >> 16); if(mode & 0x4000) HeightBlob(x,y, radius>>2, pheight, Hpage); else WarpBlob(x, y, radius, pheight, Hpage); - swirlangle += 50; } /* internal physics routines */ -void Water::DrawWater(int page) { +void Water::DrawWater(int page,uint32_t* out) { int dx, dy; int x, y; - int c; - int offset=geo->w + 1; + uint32_t offset=geo->w + 1; + uint32_t newoffset; int *ptr = (int*)&Height[page][0]; - - for (y = calc_optimization; offset < y; offset += 2) { + int maxoffset=geo->size/sizeof(uint32_t); + + for (y = calc_optimization; offset < y; offset+=2) { for (x = offset+geo->w-2; offset < x; offset++) { + dx = ptr[offset] - ptr[offset+1]; dy = ptr[offset] - ptr[offset+geo->w]; - c = BkGdImage[offset + geo->w*(dy>>3) + (dx>>3)]; - - out[offset] = c; - + newoffset = offset + geo->w*(dy>>3) + (dx>>3); + if(newoffsetw]; - c = BkGdImage[offset + geo->w*(dy>>3) + (dx>>3)]; - - out[offset] = c; + newoffset = offset + geo->w*(dy>>3) + (dx>>3); + if(newoffsetw-2; count < x; count++) { /* eight pixels */ newh = ((oldptr[count + geo->w] - + oldptr[count - geo->w] - + oldptr[count + 1] - + oldptr[count - 1] - + oldptr[count - geo->w - 1] - + oldptr[count - geo->w + 1] - + oldptr[count + geo->w - 1] - + oldptr[count + geo->w + 1] - ) >> 2 ) - - newptr[count]; + + oldptr[count - geo->w] + + oldptr[count + 1] + + oldptr[count - 1] + + oldptr[count - geo->w - 1] + + oldptr[count - geo->w + 1] + + oldptr[count + geo->w - 1] + + oldptr[count + geo->w + 1] + ) >> 2 ) + - newptr[count]; newptr[count] = newh - (newh >> density); } } @@ -519,15 +474,15 @@ for(x=1; xw-1; x++) { /* eight pixel */ newh = ((oldptr[count + geo->w] - + oldptr[count - geo->w] - + oldptr[count + 1] - + oldptr[count - 1] - + oldptr[count - geo->w - 1] - + oldptr[count - geo->w + 1] - + oldptr[count + geo->w - 1] - + oldptr[count + geo->w + 1] - ) >> 3 ) - + newptr[count]; + + oldptr[count - geo->w] + + oldptr[count + 1] + + oldptr[count - 1] + + oldptr[count - geo->w - 1] + + oldptr[count - geo->w + 1] + + oldptr[count + geo->w - 1] + + oldptr[count + geo->w + 1] + ) >> 3 ) + + newptr[count]; newptr[count] = newh>>1; @@ -548,36 +503,36 @@ for(x=2; xw-2; x++) { /* 25 pixels */ newh = ( - ( - ( - (oldptr[count + geo->w] - + oldptr[count - geo->w] - + oldptr[count + 1] - + oldptr[count - 1] - )<<1) - + ((oldptr[count - geo->w - 1] - + oldptr[count - geo->w + 1] - + oldptr[count + geo->w - 1] - + oldptr[count + geo->w + 1])) - + ( ( - oldptr[count - (geo->w<<1)] - + oldptr[count + (geo->w<<1)] - + oldptr[count - 2] - + oldptr[count + 2] - ) >> 1 ) - + ( ( - oldptr[count - (geo->w<<1) - 1] - + oldptr[count - (geo->w<<1) + 1] - + oldptr[count + (geo->w<<1) - 1] - + oldptr[count + (geo->w<<1) + 1] - + oldptr[count - 2 - geo->w] - + oldptr[count - 2 + geo->w] - + oldptr[count + 2 - geo->w] - + oldptr[count + 2 + geo->w] - ) >> 2 ) - ) - >> 3) - - (newptr[count]); + ( + ( + (oldptr[count + geo->w] + + oldptr[count - geo->w] + + oldptr[count + 1] + + oldptr[count - 1] + )<<1) + + ((oldptr[count - geo->w - 1] + + oldptr[count - geo->w + 1] + + oldptr[count + geo->w - 1] + + oldptr[count + geo->w + 1])) + + ( ( + oldptr[count - (geo->w<<1)] + + oldptr[count + (geo->w<<1)] + + oldptr[count - 2] + + oldptr[count + 2] + ) >> 1 ) + + ( ( + oldptr[count - (geo->w<<1) - 1] + + oldptr[count - (geo->w<<1) + 1] + + oldptr[count + (geo->w<<1) - 1] + + oldptr[count + (geo->w<<1) + 1] + + oldptr[count - 2 - geo->w] + + oldptr[count - 2 + geo->w] + + oldptr[count + 2 - geo->w] + + oldptr[count + 2 + geo->w] + ) >> 2 ) + ) + >> 3) + - (newptr[count]); newptr[count] = newh - (newh >> density); count++; } @@ -649,7 +604,7 @@ for(cx = left; cx < right; cx++) { square = cy*cy + cx*cx; if(square < radsquare) { - Height[page][geo->w*(cy+y) + cx+x] + Height[page][geo->w*(cy+y) + cx+x] += (int)((radius-isqrt(square))*(float)(height)); } } @@ -685,7 +640,6 @@ } frei0r::construct plugin("Water", - "water drops on a video surface", - "Jaromil", - 3,0); - + "water drops on a video surface", + "Jaromil", + 4,0); diff --git a/src/generator/CMakeLists.txt b/src/generator/CMakeLists.txt index 79ef3aa..0e3f8b9 100644 --- a/src/generator/CMakeLists.txt +++ b/src/generator/CMakeLists.txt @@ -4,7 +4,4 @@ add_subdirectory (nois0r) add_subdirectory (onecol0r) add_subdirectory (partik0l) -if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - # clang 3.1 on OSX fails to compile this one - add_subdirectory (test_pat) -endif () +add_subdirectory (test_pat) diff --git a/src/generator/ising0r/CMakeLists.txt b/src/generator/ising0r/CMakeLists.txt index 0432ec8..82be928 100644 --- a/src/generator/ising0r/CMakeLists.txt +++ b/src/generator/ising0r/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET ising0r) if (MSVC) - set_source_files_properties (ising0r.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/generator/partik0l/partik0l.cpp b/src/generator/partik0l/partik0l.cpp index 40c3674..f7a1657 100644 --- a/src/generator/partik0l/partik0l.cpp +++ b/src/generator/partik0l/partik0l.cpp @@ -24,17 +24,17 @@ * */ - -#include "frei0r.hpp" - -#include -#include - -#include #if defined(_MSC_VER) #define _USE_MATH_DEFINES #endif /* _MSC_VER */ #include + +#include "frei0r.hpp" + +#include +#include + +#include #include #include diff --git a/src/generator/test_pat/CMakeLists.txt b/src/generator/test_pat/CMakeLists.txt index 5a8c34f..eed76bc 100644 --- a/src/generator/test_pat/CMakeLists.txt +++ b/src/generator/test_pat/CMakeLists.txt @@ -6,7 +6,6 @@ set (R_SOURCES test_pat_R.c) if (MSVC) - set_source_files_properties (test_pat_B.c test_pat_C.c test_pat_G.c test_pat_I.c test_pat_L.c test_pat_R.c PROPERTIES LANGUAGE CXX) set (B_SOURCES ${B_SOURCES} ${FREI0R_DEF}) set (C_SOURCES ${C_SOURCES} ${FREI0R_DEF}) set (G_SOURCES ${G_SOURCES} ${FREI0R_DEF}) @@ -15,7 +14,9 @@ set (R_SOURCES ${R_SOURCES} ${FREI0R_DEF}) endif (MSVC) -link_libraries(m) +if(NOT MSVC) + link_libraries(m) +endif() add_library (test_pat_B MODULE ${B_SOURCES}) add_library (test_pat_C MODULE ${C_SOURCES}) add_library (test_pat_G MODULE ${G_SOURCES}) diff --git a/src/mixer2/CMakeLists.txt b/src/mixer2/CMakeLists.txt index 8ad473a..ee327af 100644 --- a/src/mixer2/CMakeLists.txt +++ b/src/mixer2/CMakeLists.txt @@ -33,3 +33,4 @@ add_subdirectory (uvmap) add_subdirectory (value) add_subdirectory (xfade0r) +add_subdirectory (sleid0r) diff --git a/src/mixer2/alphainjection/CMakeLists.txt b/src/mixer2/alphainjection/CMakeLists.txt index c8349e2..87d687d 100644 --- a/src/mixer2/alphainjection/CMakeLists.txt +++ b/src/mixer2/alphainjection/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET alphainjection) if (MSVC) - set_source_files_properties (alphainjection.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_1_1_DEF}) endif (MSVC) diff --git a/src/mixer2/burn/burn.cpp b/src/mixer2/burn/burn.cpp index c611e30..e5e6eb1 100644 --- a/src/mixer2/burn/burn.cpp +++ b/src/mixer2/burn/burn.cpp @@ -77,8 +77,7 @@ frei0r::construct plugin("burn", - "Perform an RGB[A] dodge operation between the pixel sources, using the generalised algorithm:\n" - "D = saturation of 255 or depletion of 0, of ((255 - A) * 256) / (B + 1)", + "Perform an RGB[A] dodge operation between the pixel sources, using the generalised algorithm: D = saturation of 255 or depletion of 0, of ((255 - A) * 256) / (B + 1)", "Jean-Sebastien Senecal", 0,2, F0R_COLOR_MODEL_RGBA8888); diff --git a/src/mixer2/cairoaffineblend/CMakeLists.txt b/src/mixer2/cairoaffineblend/CMakeLists.txt index 1c3b13c..7ade4b9 100644 --- a/src/mixer2/cairoaffineblend/CMakeLists.txt +++ b/src/mixer2/cairoaffineblend/CMakeLists.txt @@ -5,7 +5,6 @@ set(LIBS ${LIBS} ${Cairo_LIBRARY}) if (MSVC) - set_source_files_properties (cairoaffineblend.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/mixer2/cairoblend/CMakeLists.txt b/src/mixer2/cairoblend/CMakeLists.txt index 8209127..b0e2bb3 100644 --- a/src/mixer2/cairoblend/CMakeLists.txt +++ b/src/mixer2/cairoblend/CMakeLists.txt @@ -5,7 +5,6 @@ set(LIBS ${LIBS} ${Cairo_LIBRARY}) if (MSVC) - set_source_files_properties (cairoblend.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) diff --git a/src/mixer2/composition/CMakeLists.txt b/src/mixer2/composition/CMakeLists.txt index 26ec93f..8f518a1 100644 --- a/src/mixer2/composition/CMakeLists.txt +++ b/src/mixer2/composition/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET composition) if (MSVC) - set_source_files_properties (composition.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_1_1_DEF}) endif (MSVC) diff --git a/src/mixer2/dodge/dodge.cpp b/src/mixer2/dodge/dodge.cpp index fe234bd..47cd6fa 100644 --- a/src/mixer2/dodge/dodge.cpp +++ b/src/mixer2/dodge/dodge.cpp @@ -57,7 +57,7 @@ { tmp = src1[b] << 8; tmp /= 256 - src2[b]; - dst[b] = MAX255(tmp); + dst[b] = MIN(tmp, 255); } dst[ALPHA] = MIN (src1[ALPHA], src2[ALPHA]); @@ -71,9 +71,8 @@ }; frei0r::construct plugin("dodge", - "Perform an RGB[A] dodge operation between the pixel sources, using the generalised algorithm:\n" - "D = saturation of 255 or (A * 256) / (256 - B)", + "Perform an RGB[A] dodge operation between the pixel sources, using the generalised algorithm: D = saturation of 255 or (A * 256) / (256 - B)", "Jean-Sebastien Senecal", - 0,2, + 0,3, F0R_COLOR_MODEL_RGBA8888); diff --git a/src/mixer2/overlay/overlay.cpp b/src/mixer2/overlay/overlay.cpp index e252fcf..75386ca 100644 --- a/src/mixer2/overlay/overlay.cpp +++ b/src/mixer2/overlay/overlay.cpp @@ -72,8 +72,7 @@ frei0r::construct plugin("overlay", - "Perform an RGB[A] overlay operation between the pixel sources, using the generalised algorithm:\n" - "D = A * (B + (2 * B) * (255 - A))", + "Perform an RGB[A] overlay operation between the pixel sources, using the generalised algorithm: D = A * (B + (2 * B) * (255 - A))", "Jean-Sebastien Senecal", 0,2, F0R_COLOR_MODEL_RGBA8888); diff --git a/src/mixer2/screen/screen.cpp b/src/mixer2/screen/screen.cpp index 78e2f53..7b82e0c 100644 --- a/src/mixer2/screen/screen.cpp +++ b/src/mixer2/screen/screen.cpp @@ -70,8 +70,7 @@ frei0r::construct plugin("screen", - "Perform an RGB[A] screen operation between the pixel sources, using the generalised algorithm:\n" - "D = 255 - (255 - A) * (255 - B)", + "Perform an RGB[A] screen operation between the pixel sources, using the generalised algorithm: D = 255 - (255 - A) * (255 - B)", "Jean-Sebastien Senecal", 0,2, F0R_COLOR_MODEL_RGBA8888); diff --git a/src/mixer2/sleid0r/CMakeLists.txt b/src/mixer2/sleid0r/CMakeLists.txt new file mode 100644 index 0000000..56bdf78 --- /dev/null +++ b/src/mixer2/sleid0r/CMakeLists.txt @@ -0,0 +1,30 @@ +set(MIXERS + WIPE-UP + WIPE-LEFT + WIPE-BARN-DOOR-V + SLIDE-RIGHT + PUSH-UP + PUSH-DOWN + WIPE-RIGHT + WIPE-DOWN + WIPE-BARN-DOOR-H + SLIDE-LEFT + PUSH-RIGHT + WIPE-RECT + WIPE-CIRCLE + SLIDE-UP + SLIDE-DOWN + PUSH-LEFT +) + +foreach(MIXER IN LISTS MIXERS) + string(TOLOWER ${MIXER} LOWERCASE_MIXER) + set(${MIXER}_SOURCES sleid0r_${LOWERCASE_MIXER}.c) + if(MSVC) + set(${MIXER}_SOURCES ${${MIXER}_SOURCES} ${FREI0R_1_2_DEF}) + endif(MSVC) + add_library(sleid0r_${LOWERCASE_MIXER} MODULE ${${MIXER}_SOURCES}) + set_target_properties (sleid0r_${LOWERCASE_MIXER} PROPERTIES PREFIX "") + install (TARGETS sleid0r_${LOWERCASE_MIXER} LIBRARY DESTINATION ${LIBDIR}) +endforeach() + diff --git a/src/mixer2/sleid0r/sleid0r_push-down.c b/src/mixer2/sleid0r/sleid0r_push-down.c new file mode 100644 index 0000000..e93d655 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_push-down.c @@ -0,0 +1,132 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "push-down"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_PACKED32; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Push from top to bottom"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Push position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + double t; + unsigned off; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + off = (unsigned)(inst->h * t + 0.5); + + memcpy(outframe, inframe2 + (inst->h - off) * inst->w, + off * inst->w * sizeof(*outframe)); + + memcpy(outframe + off * inst->w, inframe1, + (inst->h - off) * inst->w * sizeof(*outframe)); + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_push-left.c b/src/mixer2/sleid0r/sleid0r_push-left.c new file mode 100644 index 0000000..34fa06f --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_push-left.c @@ -0,0 +1,134 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "push-left"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_PACKED32; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Push from right to left"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Push position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y, off; + double t; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + off = (unsigned)(inst->w * t + 0.5); + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe1 + inst->w * y + off, + (inst->w - off) * sizeof(*outframe)); + memcpy(outframe + inst->w * y + inst->w - off, inframe2 + inst->w * y, + off * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_push-right.c b/src/mixer2/sleid0r/sleid0r_push-right.c new file mode 100644 index 0000000..afaf5d2 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_push-right.c @@ -0,0 +1,134 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "push-right"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_PACKED32; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Push from left to right"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Push position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y, off; + double t; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + off = (unsigned)(inst->w * t + 0.5); + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe2 + inst->w * y + inst->w - off, + off * sizeof(*outframe)); + memcpy(outframe + inst->w * y + off, inframe1 + inst->w * y, + (inst->w - off) * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_push-up.c b/src/mixer2/sleid0r/sleid0r_push-up.c new file mode 100644 index 0000000..e6dd87c --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_push-up.c @@ -0,0 +1,132 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "push-up"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_PACKED32; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Push from bottom to top"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Push position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + double t; + unsigned off; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + off = (unsigned)(inst->h * t + 0.5); + + memcpy(outframe, inframe1 + off * inst->w, + (inst->h - off) * inst->w * sizeof(*outframe)); + + memcpy(outframe + (inst->h - off) * inst->w, inframe2, + off * inst->w * sizeof(*outframe)); + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_slide-down.c b/src/mixer2/sleid0r/sleid0r_slide-down.c new file mode 100644 index 0000000..898c0d6 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_slide-down.c @@ -0,0 +1,153 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "slide-down"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Slide from top to bottom"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Slide position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + double t; + int off; + unsigned bw; + unsigned xy; + uint32_t px; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + + bw = inst->h / 64; + + off = (int)((inst->h + bw) * t + 0.5) - bw; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->h < off + bw) + bw = inst->h - off; + + memcpy(outframe, inframe2 + (inst->h - off) * inst->w, + off * inst->w * sizeof(*outframe)); + + for(xy = off * inst->w; xy < (off + bw) * inst->w; ++xy) + { + px = (inframe1[xy] >> 2) & 0x3F3F3F3F; + ((uint8_t *)(&px))[3] = ((uint8_t *)(inframe1 + xy))[3]; + outframe[xy] = px; + } + + memcpy(outframe + (off + bw) * inst->w, inframe1 + (off + bw) * inst->w, + (inst->h - off - bw) * inst->w * sizeof(*outframe)); + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_slide-left.c b/src/mixer2/sleid0r/sleid0r_slide-left.c new file mode 100644 index 0000000..c10e9ff --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_slide-left.c @@ -0,0 +1,156 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "slide-left"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Slide from right to left"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Slide position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y; + int off; + unsigned bw, x; + double t; + uint32_t px; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + + bw = inst->w / 64; + + off = (int)((inst->w + bw) * t + 0.5) - bw; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->w < off + bw) + bw = inst->w - off; + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe1 + inst->w * y, + (inst->w - off - bw) * sizeof(*outframe)); + + for(x = inst->w - off - bw; x < inst->w - off; ++x) + { + px = (inframe1[inst->w * y + x] >> 2) & 0x3F3F3F3F; + ((uint8_t *)(&px))[3] = ((uint8_t *)(inframe1 + inst->w * y + x))[3]; + outframe[inst->w * y + x] = px; + } + + memcpy(outframe + inst->w * y + inst->w - off, inframe2 + inst->w * y, + off * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_slide-right.c b/src/mixer2/sleid0r/sleid0r_slide-right.c new file mode 100644 index 0000000..4bd9ffa --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_slide-right.c @@ -0,0 +1,156 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "slide-right"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Slide from left to right"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Slide position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y; + int off; + unsigned bw, x; + double t; + uint32_t px; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + + bw = inst->w / 64; + + off = (int)((inst->w + bw) * t + 0.5) - bw; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->w < off + bw) + bw = inst->w - off; + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe2 + inst->w * y + inst->w - off, + off * sizeof(*outframe)); + + for(x = off; x < off + bw; ++x) + { + px = (inframe1[inst->w * y + x] >> 2) & 0x3F3F3F3F; + ((uint8_t *)(&px))[3] = ((uint8_t *)(inframe1 + inst->w * y + x))[3]; + outframe[inst->w * y + x] = px; + } + + memcpy(outframe + inst->w * y + off + bw, inframe1 + inst->w * y + off + bw, + (inst->w - off - bw) * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_slide-up.c b/src/mixer2/sleid0r/sleid0r_slide-up.c new file mode 100644 index 0000000..8f442fb --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_slide-up.c @@ -0,0 +1,153 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "slide-up"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Slide from bottom to top"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Slide position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + + inst = calloc(1, sizeof(*inst)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + double t; + int off; + unsigned bw; + unsigned xy; + uint32_t px; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + if(inst->pos < 0.5) + { + t = inst->pos; + t = t * t * 2.0; + } + else + { + t = 1.0 - inst->pos; + t = 1.0 - t * t * 2.0; + } + + bw = inst->h / 64; + + off = (int)((inst->h + bw) * t + 0.5) - bw; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->h < off + bw) + bw = inst->h - off; + + memcpy(outframe, inframe1, + (inst->h - off - bw) * inst->w * sizeof(*outframe)); + + for(xy = (inst->h - off - bw) * inst->w; xy < (inst->h - off) * inst->w; ++xy) + { + px = (inframe1[xy] >> 2) & 0x3F3F3F3F; + ((uint8_t *)(&px))[3] = ((uint8_t *)(inframe1 + xy))[3]; + outframe[xy] = px; + } + + memcpy(outframe + (inst->h - off) * inst->w, inframe2, + off * inst->w * sizeof(*outframe)); + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-barn-door-h.c b/src/mixer2/sleid0r/sleid0r_wipe-barn-door-h.c new file mode 100644 index 0000000..a06e77d --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-barn-door-h.c @@ -0,0 +1,193 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-barn-door-h"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Horizontal barn door wipe"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edges position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = height / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y, x; + int off; + unsigned bw, dbw1, dbw2; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->h / 2 + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw1 = 0; + dbw2 = 0; + + if(off < 0) + { + bw += off; + off = 0; + dbw1 = inst->bw - bw; + } + else if(inst->h / 2 < off + bw) + { + bw = inst->h / 2 - off; + dbw2 = inst->bw - bw; + } + + memcpy(outframe, inframe1, + inst->w * (inst->h / 2 - off - bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * (inst->h / 2 + off + bw), + inframe1 + inst->w * (inst->h / 2 + off + bw), + inst->w * (inst->h / 2 - off - bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * (inst->h / 2 - off), + inframe2 + inst->w * (inst->h / 2 - off), + inst->w * off * 2 * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * (inst->h / 2 - off - bw)); + c2 = (uint8_t *)(inframe2 + inst->w * (inst->h / 2 - off - bw)); + co = (uint8_t *)(outframe + inst->w * (inst->h / 2 - off - bw)); + for(y = 0; y < bw; ++y) + { + unsigned k = inst->bwk[y + dbw2]; + + for(x = 0; x < inst->w * 4; ++x) + { + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + } + + c1 = (uint8_t *)(inframe1 + inst->w * (inst->h / 2 + off)); + c2 = (uint8_t *)(inframe2 + inst->w * (inst->h / 2 + off)); + co = (uint8_t *)(outframe + inst->w * (inst->h / 2 + off)); + for(y = 0; y < bw; ++y) + { + unsigned k = inst->bwk[y + dbw1]; + + for(x = 0; x < inst->w * 4; ++x) + { + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + } + + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-barn-door-v.c b/src/mixer2/sleid0r/sleid0r_wipe-barn-door-v.c new file mode 100644 index 0000000..d605408 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-barn-door-v.c @@ -0,0 +1,189 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-barn-door-v"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Vertical barn door wipe"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edges position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = width / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y; + int off; + unsigned bw, i, dbw1, dbw2; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->w / 2 + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw1 = 0; + dbw2 = 0; + + if(off < 0) + { + bw += off; + off = 0; + dbw1 = inst->bw - bw; + } + else if(inst->w / 2 < off + bw) + { + bw = inst->w / 2 - off; + dbw2 = inst->bw - bw; + } + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe1 + inst->w * y, + (inst->w / 2 - off - bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * y + inst->w / 2 + off + bw, + inframe1 + inst->w * y+ inst->w / 2 + off + bw, + (inst->w / 2 - off - bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * y + inst->w / 2 - off, + inframe2 + inst->w * y + inst->w / 2 - off, + off * 2 * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * y + inst->w / 2 - off - bw); + c2 = (uint8_t *)(inframe2 + inst->w * y + inst->w / 2 - off - bw); + co = (uint8_t *)(outframe + inst->w * y + inst->w / 2 - off - bw); + for(i = 0; i < bw * 4; ++i) + { + unsigned k = inst->bwk[i / 4 + dbw2]; + + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + + c1 = (uint8_t *)(inframe1 + inst->w * y + inst->w / 2 + off); + c2 = (uint8_t *)(inframe2 + inst->w * y + inst->w / 2 + off); + co = (uint8_t *)(outframe + inst->w * y + inst->w / 2 + off); + for(i = 0; i < bw * 4; ++i) + { + unsigned k = inst->bwk[i / 4 + dbw1]; + + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-circle.c b/src/mixer2/sleid0r/sleid0r_wipe-circle.c new file mode 100644 index 0000000..4ad751f --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-circle.c @@ -0,0 +1,238 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#define _USE_MATH_DEFINES +#include +#include + +typedef struct instance_s + { + int w; + int h; + double pos; + int r; + int bw; + int bw_scale; + int *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-circle"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Circle wipe"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Circle size"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + int r; + int bw; + int i; + + r = (int)(hypotf((float)height, (float)width) / 2.0f + 0.5f); + + bw = r / 16; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst-> pos = 0.0; + inst->r = r; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (int *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + int x0, y0, r0, r1; + int y, x, dy, dx, ox, oy; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + r1 = (int)((inst->r + inst->bw) * inst->pos + 0.5); + r0 = r1 - inst->bw; + + x0 = inst->w / 2; + y0 = inst->h / 2; + + dy = inst->h / 2 - r1; + dx = inst->w / 2 - r1; + + if(r0 > 0) + { + ox = (int)((float)r0 * (float)M_SQRT1_2 + 0.5f); + oy = ox; + + if(ox > inst->w / 2) + ox = inst->w / 2; + + if(oy > inst->h / 2) + oy = inst->h / 2; + } + else + { + ox = 0; + oy = 0; + } + + if(ox > 0 && oy > 0) + { + for(y = y0 - oy; y < y0 + oy; ++y) + memcpy(outframe + inst->w * y + x0 - ox, + inframe2 + inst->w * y + x0 - ox, ox * 2 * sizeof(*outframe)); + } + + if(dy > 0) + { + memcpy(outframe, inframe1, inst->w * dy * sizeof(*outframe)); + + memcpy(outframe + inst->w * (y0 + r1), inframe1 + inst->w * (y0 + r1), + inst->w * dy * sizeof(*outframe)); + + inframe1 += dy * inst->w; + inframe2 += dy * inst->w; + outframe += dy * inst->w; + } + else + dy = 0; + + if(dx > 0) + { + for(y = 0; y < inst->h - dy * 2; ++y) + { + memcpy(outframe + inst->w * y, inframe1 + inst->w * y, dx * sizeof(*outframe)); + + memcpy(outframe + inst->w * y + inst->w - dx, + inframe1 + inst->w * y + inst->w - dx, dx * sizeof(*outframe)); + } + + inframe1 += dx; + inframe2 += dx; + outframe += dx; + } + else + dx = 0; + + for(y = dy; y < inst->h - dy; ++y) + { + for(x = dx; x < inst->w - dx; ++x) + { + if(y < y0 - oy || y >= y0 + oy || x < x0 - ox || x >= x0 + ox) + { + int r = (int)(hypotf((float)(x - x0), (float)(y - y0)) + 0.5f); + + if(r >= r1) + *outframe = *inframe1; + else if(r < r0) + *outframe = *inframe2; + else + { + int k1 = inst->bwk[r - r0]; + int k2 = inst->bw_scale - k1; + uint8_t *c1 = (uint8_t *)inframe1; + uint8_t *c2 = (uint8_t *)inframe2; + uint8_t *co = (uint8_t *)outframe; + + co[0] = (c1[0] * k1 + c2[0] * k2 + inst->bw_scale / 2) / inst->bw_scale; + co[1] = (c1[1] * k1 + c2[1] * k2 + inst->bw_scale / 2) / inst->bw_scale; + co[2] = (c1[2] * k1 + c2[2] * k2 + inst->bw_scale / 2) / inst->bw_scale; + co[3] = (c1[3] * k1 + c2[3] * k2 + inst->bw_scale / 2) / inst->bw_scale; + } + } + + ++inframe1; + ++inframe2; + ++outframe; + } + + inframe1 += dx * 2; + inframe2 += dx * 2; + outframe += dx * 2; + } + } + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-down.c b/src/mixer2/sleid0r/sleid0r_wipe-down.c new file mode 100644 index 0000000..2e2e180 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-down.c @@ -0,0 +1,167 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-down"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Wipe from top to bottom"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edge position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = height / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y, x; + int off; + unsigned bw, dbw; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->h + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw = 0; + + if(off < 0) + { + bw += off; + off = 0; + dbw = inst->bw - bw; + } + else if(inst->h < off + bw) + bw = inst->h - off; + + memcpy(outframe, inframe2, inst->w * off * sizeof(*outframe)); + + memcpy(outframe + inst->w * (off + bw), inframe1 + inst->w * (off + bw), + inst->w * (inst->h - off - bw) * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * off); + c2 = (uint8_t *)(inframe2 + inst->w * off); + co = (uint8_t *)(outframe + inst->w * off); + for(y = 0; y < bw; ++y) + { + unsigned k = inst->bwk[y + dbw]; + + for(x = 0; x < inst->w * 4; ++x) + { + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-left.c b/src/mixer2/sleid0r/sleid0r_wipe-left.c new file mode 100644 index 0000000..a3bf6f9 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-left.c @@ -0,0 +1,169 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-left"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Wipe from right to left"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edge position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = width / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y; + int off; + unsigned bw, i, dbw; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->w + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw = 0; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->w < off + bw) + { + bw = inst->w - off; + dbw = inst->bw - bw; + } + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe1 + inst->w * y, + (inst->w - off - bw) * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * y + inst->w - off - bw); + c2 = (uint8_t *)(inframe2 + inst->w * y + inst->w - off - bw); + co = (uint8_t *)(outframe + inst->w * y + inst->w - off - bw); + for(i = 0; i < bw * 4; ++i) + { + unsigned k = inst->bwk[i / 4 + dbw]; + + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + + memcpy(outframe + inst->w * y + inst->w - off, inframe2 + inst->w * y + inst->w - off, + off * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-rect.c b/src/mixer2/sleid0r/sleid0r_wipe-rect.c new file mode 100644 index 0000000..ebe014f --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-rect.c @@ -0,0 +1,295 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + int w; + int h; + double pos; + int bw; + int bw_scale; + int *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-rect"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Rectangular wipe"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Rectangle size"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw; + unsigned i; + + if(height < width) + bw = height / 16; + else + bw = width / 16; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (int *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + int y, x; + int off_h, off_v; + uint8_t *c1, *c2, *co; + int b, k; + int x0, x1; + int y0, y1; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off_v = (int)((inst->w / 2 + inst->bw) * inst->pos + 0.5) - inst->bw; + + off_h = (int)((inst->h / 2 + inst->bw) * inst->pos + 0.5) - inst->bw; + + if(inst->h / 2 > off_h + inst->bw) + { + memcpy(outframe, inframe1, + inst->w * (inst->h / 2 - off_h - inst->bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * (inst->h / 2 + off_h + inst->bw), + inframe1 + inst->w * (inst->h / 2 + off_h + inst->bw), + inst->w * (inst->h / 2 - off_h - inst->bw) * sizeof(*outframe)); + } + + if(inst->w / 2 > off_v + inst->bw) + { + for(y = inst->h / 2 - off_h - inst->bw; y < inst->h / 2 + off_h + inst->bw; ++y) + { + if(y < 0 || y >= inst->h) + continue; + + memcpy(outframe + inst->w * y, inframe1 + inst->w * y, + (inst->w / 2 - off_v - inst->bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * y + inst->w / 2 + off_v + inst->bw, + inframe1 + inst->w * y + inst->w / 2 + off_v + inst->bw, + (inst->w / 2 - off_v - inst->bw) * sizeof(*outframe)); + } + } + + if(off_v > 0) + { + for(y = inst->h / 2 - off_h; y < inst->h / 2 + off_h; ++y) + memcpy( + outframe + inst->w * y + inst->w / 2 - off_v, + inframe2 + inst->w * y + inst->w / 2 - off_v, + off_v * 2 * sizeof(*outframe) + ); + } + + for(b = 0; b < inst->bw; ++b) + { + k = inst->bwk[b]; + + y = inst->h / 2 - off_h - inst->bw + b; + if(y < 0) + continue; + + x0 = inst->w / 2 - off_v - inst->bw + b; + if(x0 < 0) + x0 = 0; + + x1 = inst->w / 2 + off_v + inst->bw - b; + if(x1 > inst->w) + x1 = inst->w; + + c1 = (uint8_t *)(inframe1 + inst->w * y + x0); + c2 = (uint8_t *)(inframe2 + inst->w * y + x0); + co = (uint8_t *)(outframe + inst->w * y + x0); + + for(x = 0; x < (x1 - x0) * 4; ++x) + { + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + } + + for(b = 0; b < inst->bw; ++b) + { + k = inst->bwk[b]; + + y = inst->h / 2 + off_h + b; + if(y >= inst->h) + continue; + + x0 = inst->w / 2 - off_v - b; + if(x0 < 0) + x0 = 0; + + x1 = inst->w / 2 + off_v + b + 1; + if(x1 > inst->w) + x1 = inst->w; + + c1 = (uint8_t *)(inframe1 + inst->w * y + x0); + c2 = (uint8_t *)(inframe2 + inst->w * y + x0); + co = (uint8_t *)(outframe + inst->w * y + x0); + + for(x = 0; x < (x1 - x0) * 4; ++x) + { + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + } + + for(b = 0; b < inst->bw * 4; ++b) + { + k = inst->bwk[b / 4]; + + x0 = inst->w / 2 - off_v - inst->bw; + if(x0 + b / 4 < 0) + continue; + + y0 = inst->h / 2 - off_h - inst->bw + b / 4; + if(y0 < 0) + y0 = 0; + + y1 = inst->h / 2 + off_h + inst->bw - b / 4; + if(y1 > inst->h) + y1 = inst->h; + + c1 = (uint8_t *)(inframe1 + inst->w * y0 + x0) + b; + c2 = (uint8_t *)(inframe2 + inst->w * y0 + x0) + b; + co = (uint8_t *)(outframe + inst->w * y0 + x0) + b; + + for(y = 0; y < y1 - y0; ++y) + { + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + c1 += inst->w * 4; + c2 += inst->w * 4; + co += inst->w * 4; + } + } + + for(b = 0; b < inst->bw * 4; ++b) + { + k = inst->bwk[b / 4]; + + x0 = inst->w / 2 + off_v; + if(x0 + b / 4 >= inst->w) + continue; + + y0 = inst->h / 2 - off_h - b / 4; + if(y0 < 0) + y0 = 0; + + y1 = inst->h / 2 + off_h + b / 4 + 1; + if(y1 > inst->h) + y1 = inst->h; + + c1 = (uint8_t *)(inframe1 + inst->w * y0 + x0) + b; + c2 = (uint8_t *)(inframe2 + inst->w * y0 + x0) + b; + co = (uint8_t *)(outframe + inst->w * y0 + x0) + b; + + for(y = 0; y < y1 - y0; ++y) + { + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + c1 += inst->w * 4; + c2 += inst->w * 4; + co += inst->w * 4; + } + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-right.c b/src/mixer2/sleid0r/sleid0r_wipe-right.c new file mode 100644 index 0000000..653b637 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-right.c @@ -0,0 +1,167 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-right"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Wipe from left to right"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edge position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = width / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y; + int off; + unsigned bw, i, dbw; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->w + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw = 0; + + if(off < 0) + { + bw += off; + off = 0; + dbw = inst->bw - bw; + } + else if(inst->w < off + bw) + bw = inst->w - off; + + for(y = 0; y < inst->h; ++y) + { + memcpy(outframe + inst->w * y, inframe2 + inst->w * y, + off * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * y + off); + c2 = (uint8_t *)(inframe2 + inst->w * y + off); + co = (uint8_t *)(outframe + inst->w * y + off); + for(i = 0; i < bw * 4; ++i) + { + unsigned k = inst->bwk[i / 4 + dbw]; + + *co = (*c1 * k + *c2 * (inst->bw_scale - k) + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + + memcpy(outframe + inst->w * y + off + bw, inframe1 + inst->w * y + off + bw, + (inst->w - off - bw) * sizeof(*outframe)); + } + } + + + diff --git a/src/mixer2/sleid0r/sleid0r_wipe-up.c b/src/mixer2/sleid0r/sleid0r_wipe-up.c new file mode 100644 index 0000000..627f229 --- /dev/null +++ b/src/mixer2/sleid0r/sleid0r_wipe-up.c @@ -0,0 +1,169 @@ +/* +Copyright (C) 2013 Vadim Druzhin + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include + +typedef struct instance_s + { + unsigned w; + unsigned h; + double pos; + unsigned bw; + unsigned bw_scale; + unsigned *bwk; + } instance_t; + +int f0r_init(void) + { + return 1; + } + +void f0r_deinit(void) {} + +void f0r_get_plugin_info(f0r_plugin_info_t *info) + { + info->name = "wipe-up"; + info->author = "Vadim Druzhin"; + info->plugin_type = F0R_PLUGIN_TYPE_MIXER2; + info->color_model = F0R_COLOR_MODEL_RGBA8888; + info->frei0r_version = FREI0R_MAJOR_VERSION; + info->major_version = 0; + info->minor_version = 1; + info->num_params = 1; + info->explanation = "Wipe from bottom to top"; + } + +void f0r_get_param_info(f0r_param_info_t *info, int index) + { + if(0 == index) + { + info->name = "position"; + info->type = F0R_PARAM_DOUBLE; + info->explanation = "Edge position"; + } + } + +f0r_instance_t f0r_construct(unsigned width, unsigned height) + { + instance_t *inst; + unsigned bw = height / 16; + unsigned i; + + inst = malloc(sizeof(*inst) + bw * sizeof(*inst->bwk)); + if(NULL == inst) + return NULL; + + inst->w = width; + inst->h = height; + inst->pos = 0.0; + inst->bw = bw; + inst->bw_scale = bw * bw; + inst->bwk = (unsigned *)(inst + 1); + + for(i = 0; i < bw; ++i) + { + if(i < bw / 2) + inst->bwk[i] = i * i * 2; + else + inst->bwk[i] = inst->bw_scale - (bw - i) * (bw - i) * 2; + } + + return inst; + } + +void f0r_destruct(f0r_instance_t inst) + { + free(inst); + } + +void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + inst->pos = *(f0r_param_double *)param; + } + +void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) + { + instance_t *inst = instance; + + if(0 == param_index) + *(f0r_param_double *)param = inst->pos; + } + +void f0r_update2( + f0r_instance_t instance, + double time, + const uint32_t* inframe1, + const uint32_t* inframe2, + const uint32_t* inframe3, + uint32_t* outframe + ) + { + instance_t *inst = instance; + unsigned y, x; + int off; + unsigned bw, dbw; + uint8_t *c1, *c2, *co; + + (void)time; /* Unused */ + (void)inframe3; /* Unused */ + + off = (int)((inst->h + inst->bw) * inst->pos + 0.5) - inst->bw; + bw = inst->bw; + dbw = 0; + + if(off < 0) + { + bw += off; + off = 0; + } + else if(inst->h < off + bw) + { + bw = inst->h - off; + dbw = inst->bw - bw; + } + + memcpy(outframe, inframe1, inst->w * (inst->h - off - bw) * sizeof(*outframe)); + + memcpy(outframe + inst->w * (inst->h - off), inframe2 + inst->w * (inst->h - off), + inst->w * off * sizeof(*outframe)); + + c1 = (uint8_t *)(inframe1 + inst->w * (inst->h - off - bw)); + c2 = (uint8_t *)(inframe2 + inst->w * (inst->h - off - bw)); + co = (uint8_t *)(outframe + inst->w * (inst->h - off - bw)); + for(y = 0; y < bw; ++y) + { + unsigned k = inst->bwk[y + dbw]; + + for(x = 0; x < inst->w * 4; ++x) + { + *co = (*c1 * (inst->bw_scale - k) + *c2 * k + inst->bw_scale / 2) / inst->bw_scale; + ++c1; + ++c2; + ++co; + } + + } + } + + + diff --git a/src/mixer2/uvmap/CMakeLists.txt b/src/mixer2/uvmap/CMakeLists.txt index ad7afd0..60c6496 100644 --- a/src/mixer2/uvmap/CMakeLists.txt +++ b/src/mixer2/uvmap/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET uvmap) if (MSVC) - set_source_files_properties (uvmap.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_1_1_DEF}) endif (MSVC) diff --git a/src/mixer2/uvmap/uvmap.c b/src/mixer2/uvmap/uvmap.c index 93c97db..731da02 100644 --- a/src/mixer2/uvmap/uvmap.c +++ b/src/mixer2/uvmap/uvmap.c @@ -75,12 +75,6 @@ f0r_param_t param, int param_index) { /* no params */ } -#if defined(_MSC_VER) -__inline const long int lrintf(float x){ - return (long int)(x+0.5); -} -#endif /* _MSC_VER */ - void f0r_update2(f0r_instance_t instance, double time, const uint32_t* inframe1, diff --git a/src/mixer3/RGB/CMakeLists.txt b/src/mixer3/RGB/CMakeLists.txt index cc0feda..c5bda36 100644 --- a/src/mixer3/RGB/CMakeLists.txt +++ b/src/mixer3/RGB/CMakeLists.txt @@ -2,7 +2,6 @@ set (TARGET RGB) if (MSVC) - set_source_files_properties (RGB.c PROPERTIES LANGUAGE CXX) set (SOURCES ${SOURCES} ${FREI0R_1_1_DEF}) endif (MSVC) diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..70e924c --- /dev/null +++ b/test/Makefile @@ -0,0 +1,22 @@ +INCLUDES ?= -I ../include + +PLUGINDIR ?= ../build/src + +all: build scan-plugins + +scan-plugins: + @$(if $(wildcard ${PLUGINDIR}),,>&2 echo "Scan dir not found: ${PLUGINDIR}" && exit 1) + @find ${PLUGINDIR} -type f -name '*.so' -exec ./frei0r-info {} \; > tmp.json + @echo "[" > frei0r-plugin-list.json + @head -n -1 tmp.json >> frei0r-plugin-list.json + @echo "}\n]" >> frei0r-plugin-list.json + @rm tmp.json + $(info frei0r-plugin-list.json) + +build: + @${CC} -o frei0r-info -ggdb frei0r-info.c ${INCLUDES} + +clean: + rm -f *.o + rm -f frei0r-info + rm -f *.json diff --git a/test/frei0r-info.c b/test/frei0r-info.c new file mode 100644 index 0000000..de03085 --- /dev/null +++ b/test/frei0r-info.c @@ -0,0 +1,103 @@ + +#include +#include +#include +#include +#include +#include + +#include + +// frei0r function prototypes +typedef int (*f0r_init_f)(void); +typedef void (*f0r_deinit_f)(void); +typedef void (*f0r_get_plugin_info_f)(f0r_plugin_info_t *info); +typedef void (*f0r_get_param_info_f)(f0r_param_info_t *info, int param_index); + +int main(int argc, char **argv) { + + // instance frei0r pointers + static void *dl_handle; + static f0r_init_f f0r_init; + static f0r_init_f f0r_deinit; + static f0r_plugin_info_t pi; + static f0r_get_plugin_info_f f0r_get_plugin_info; + static f0r_get_param_info_f f0r_get_param_info; + static f0r_param_info_t param; + + int c; + + if(argc<2) exit(1); + const char *file = basename(argv[1]); + const char *dir = dirname(argv[1]); + char path[256];; + snprintf(path, 255,"%s/%s",dir,file); + // fprintf(stderr,"%s %s\n",argv[0], file); + // load shared library + dl_handle = dlopen(path, RTLD_NOW|RTLD_LOCAL); + if(!dl_handle) { + fprintf(stderr,"error: %s\n",dlerror()); + exit(1); + } + // get plugin function calls + f0r_init = dlsym(dl_handle,"f0r_init"); + f0r_deinit = dlsym(dl_handle,"f0r_deinit"); + f0r_get_plugin_info = dlsym(dl_handle,"f0r_get_plugin_info"); + f0r_get_param_info = dlsym(dl_handle,"f0r_get_param_info"); + // always initialize plugin first + f0r_init(); + // get info about plugin + f0r_get_plugin_info(&pi); + fprintf(stdout, + "{\n \"name\":\"%s\",\n \"type\":\"%s\",\n \"author\":\"%s\",\n" + " \"explanation\":\"%s\",\n \"color_model\":\"%s\",\n" + " \"frei0r_version\":\"%d\",\n \"version\":\"%d.%d\",\n \"num_params\":\"%d\"", + pi.name, + pi.plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" : + pi.plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" : + pi.plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" : + pi.plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown", + pi.author, pi.explanation, + pi.color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" : + pi.color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" : + pi.color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown", + pi.frei0r_version, pi.major_version, pi.minor_version, pi.num_params); + + /* // check icon */ + /* char icon[256]; */ + /* char *dot = rindex(file, '.'); */ + /* *dot = 0x0; */ + /* snprintf(icon,255,"%s/%s.png",dir,file); */ + /* FILE *icon_fd = fopen(icon,"r"); */ + /* if(icon_fd) { */ + /* fprintf(stderr," icon found: %s\n",icon); */ + /* } */ + + // get info about params + if(pi.num_params>0) { + fprintf(stdout,",\n \"params\":[\n"); + for(c=0; cc+1) { + fprintf(stdout,",\n"); + } else { + fprintf(stdout,"\n"); + } + } + fprintf(stdout," ]\n"); + } + fprintf(stdout,"\n},\n"); + fflush(stdout); + f0r_deinit(); + dlclose(dl_handle); + exit(0); +}