diff --git a/.github/workflows/linux_build.yml b/.github/workflows/linux_build.yml index 9fd3f99c..304d257a 100644 --- a/.github/workflows/linux_build.yml +++ b/.github/workflows/linux_build.yml @@ -47,6 +47,11 @@ jobs: export CC="ccache ${{ matrix.cc }}" export CXX="ccache ${{ matrix.cxx }}" ci-scripts/linux/tahoma-buildlibmypaint.sh + - name: Build libgphoto2 + run: | + export CC="ccache ${{ matrix.cc }}" + export CXX="ccache ${{ matrix.cxx }}" + ci-scripts/linux/tahoma-buildlibgphoto2.sh - name: Build Tahoma2D run: | export CC="ccache ${{ matrix.cc }}" diff --git a/.github/workflows/macOS_build.yml b/.github/workflows/macOS_build.yml index 33fa6eb4..b255eb53 100644 --- a/.github/workflows/macOS_build.yml +++ b/.github/workflows/macOS_build.yml @@ -47,6 +47,10 @@ jobs: run: | export PATH="/usr/local/opt/ccache/libexec:$PATH" ci-scripts/osx/tahoma-buildopencv.sh + - name: Build libgphoto2 + run: | + export PATH="/usr/local/opt/ccache/libexec:$PATH" + ci-scripts/osx/tahoma-buildlibgphoto2.sh - name: Build Tahoma2D run: | export PATH="/usr/local/opt/ccache/libexec:$PATH" diff --git a/ci-scripts/linux/tahoma-build.sh b/ci-scripts/linux/tahoma-build.sh old mode 100755 new mode 100644 index 36d5eb07..fd30a590 --- a/ci-scripts/linux/tahoma-build.sh +++ b/ci-scripts/linux/tahoma-build.sh @@ -13,7 +13,9 @@ cd build source /opt/qt515/bin/qt515-env.sh +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH cmake ../sources \ + -DWITH_GPHOTO2:BOOL=ON \ -DWITH_SYSTEM_SUPERLU=ON make -j7 diff --git a/ci-scripts/linux/tahoma-buildlibgphoto2.sh b/ci-scripts/linux/tahoma-buildlibgphoto2.sh new file mode 100644 index 00000000..354cd91d --- /dev/null +++ b/ci-scripts/linux/tahoma-buildlibgphoto2.sh @@ -0,0 +1,23 @@ +#!/bin/bash +cd thirdparty + +echo ">>> Cloning libgphoto2" +git clone https://github.com/tahoma2d/libgphoto2.git libgphoto2_src + +cd libgphoto2_src +echo "*" >| .gitignore + +git checkout tahoma2d-version + +echo ">>> Configuring libgphoto2" +autoreconf --install --symlink + +./configure --prefix=/usr/local + +echo ">>> Making libgphoto2" +make + +echo ">>> Installing libgphoto2" +sudo make install + +cd .. diff --git a/ci-scripts/linux/tahoma-buildpkg.sh b/ci-scripts/linux/tahoma-buildpkg.sh index 8a504a37..4cd545a8 100755 --- a/ci-scripts/linux/tahoma-buildpkg.sh +++ b/ci-scripts/linux/tahoma-buildpkg.sh @@ -61,6 +61,14 @@ then chmod 755 -R Tahoma2D/rhubarb fi +echo ">>> Copying libghoto2 supporting directories" +cp -r /usr/local/lib/libgphoto2 appdir/usr/lib +cp -r /usr/local/lib/libgphoto2_port appdir/usr/lib + +rm appdir/usr/lib/libgphoto2/print-camera-list +find appdir/usr/lib/libgphoto2* -name *.la -exec rm -f {} \; +find appdir/usr/lib/libgphoto2* -name *.so -exec patchelf --set-rpath '$ORIGIN/../..' {} \; + echo ">>> Creating Tahoma2D/Tahoma2D.AppImage" if [ ! -f linuxdeployqt*.AppImage ] @@ -78,6 +86,11 @@ export LD_LIBRARY_PATH=appdir/usr/lib/tahoma2d -executable=appdir/usr/bin/tconverter \ -executable=appdir/usr/bin/tfarmcontroller \ -executable=appdir/usr/bin/tfarmserver + +rm appdir/AppRun +cp ../sources/scripts/AppRun appdir +chmod 775 appdir/AppRun + ./linuxdeployqt*.AppImage appdir/usr/bin/Tahoma2D -appimage mv Tahoma2D*.AppImage Tahoma2D/Tahoma2D.AppImage diff --git a/ci-scripts/linux/tahoma-install.sh b/ci-scripts/linux/tahoma-install.sh index 395243ad..c17609b0 100755 --- a/ci-scripts/linux/tahoma-install.sh +++ b/ci-scripts/linux/tahoma-install.sh @@ -5,7 +5,7 @@ sudo apt-get install -y cmake liblzo2-dev liblz4-dev libfreetype6-dev libpng-dev # Removed: libopenjpeg-dev sudo apt-get install -y nasm yasm libgnutls28-dev libunistring-dev libass-dev libbluray-dev libmp3lame-dev libopus-dev libsnappy-dev libtheora-dev libvorbis-dev libvpx-dev libwebp-dev libxml2-dev libfontconfig1-dev libfreetype6-dev libopencore-amrnb-dev libopencore-amrwb-dev libspeex-dev libsoxr-dev libopenjp2-7-dev sudo apt-get install -y python3-pip -sudo apt install -y build-essential libgirepository1.0-dev autotools-dev intltool gettext libtool +sudo apt-get install -y build-essential libgirepository1.0-dev autotools-dev intltool gettext libtool patchelf pip3 install --upgrade pip pip3 install numpy diff --git a/ci-scripts/osx/tahoma-build.sh b/ci-scripts/osx/tahoma-build.sh index cbec2eb3..37a922c4 100755 --- a/ci-scripts/osx/tahoma-build.sh +++ b/ci-scripts/osx/tahoma-build.sh @@ -27,9 +27,9 @@ then export CANON_FLAG=-DWITH_CANON=ON fi -export MACOSX_DEPLOYMENT_TARGET=10.13 export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/jpeg-turbo/lib/pkgconfig" cmake ../sources $CANON_FLAG \ + -DWITH_GPHOTO2=ON \ -DQT_PATH=$USEQTLIB \ -DTIFF_INCLUDE_DIR=../../thirdparty/tiff-4.2.0/libtiff/ \ -DSUPERLU_INCLUDE_DIR=../../thirdparty/superlu/SuperLU_4.1/include/ diff --git a/ci-scripts/osx/tahoma-buildlibgphoto2.sh b/ci-scripts/osx/tahoma-buildlibgphoto2.sh new file mode 100644 index 00000000..354cd91d --- /dev/null +++ b/ci-scripts/osx/tahoma-buildlibgphoto2.sh @@ -0,0 +1,23 @@ +#!/bin/bash +cd thirdparty + +echo ">>> Cloning libgphoto2" +git clone https://github.com/tahoma2d/libgphoto2.git libgphoto2_src + +cd libgphoto2_src +echo "*" >| .gitignore + +git checkout tahoma2d-version + +echo ">>> Configuring libgphoto2" +autoreconf --install --symlink + +./configure --prefix=/usr/local + +echo ">>> Making libgphoto2" +make + +echo ">>> Installing libgphoto2" +sudo make install + +cd .. diff --git a/ci-scripts/osx/tahoma-buildpkg.sh b/ci-scripts/osx/tahoma-buildpkg.sh index 1e8cf254..e3f39134 100755 --- a/ci-scripts/osx/tahoma-buildpkg.sh +++ b/ci-scripts/osx/tahoma-buildpkg.sh @@ -50,17 +50,25 @@ then chmod -R 755 $TOONZDIR/Tahoma2D.app/rhubarb fi +if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/Frameworks ] +then + mkdir $TOONZDIR/Tahoma2D.app/Contents/Frameworks +fi + if [ -d thirdparty/canon/Framework ] then echo ">>> Copying canon framework to $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.Framework" - if [ ! -d $TOONZDIR/Tahoma2D.app/Contents/Frameworks ] - then - mkdir $TOONZDIR/Tahoma2D.app/Contents/Frameworks - fi cp -R thirdparty/canon/Framework/ $TOONZDIR/Tahoma2D.app/Contents/Frameworks chmod -R 755 $TOONZDIR/Tahoma2D.app/Contents/Frameworks/EDSDK.framework fi +echo ">>> Copying libghoto2 supporting directories" +cp -R /usr/local/lib/libgphoto2 $TOONZDIR/Tahoma2D.app/Contents/Frameworks +cp -R /usr/local/lib/libgphoto2_port $TOONZDIR/Tahoma2D.app/Contents/Frameworks + +rm $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2/print-camera-list +find $TOONZDIR/Tahoma2D.app/Contents/Frameworks/libgphoto2* -name *.la -exec rm -f {} \; + echo ">>> Configuring Tahoma2D.app for deployment" $QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -verbose=0 -always-overwrite \ @@ -73,7 +81,7 @@ $QTDIR/bin/macdeployqt $TOONZDIR/Tahoma2D.app -verbose=0 -always-overwrite \ -executable=$TOONZDIR/Tahoma2D.app/Contents/MacOS/tfarmserver echo ">>> Correcting library paths" -for X in `find $TOONZDIR/Tahoma2D.app/Contents -type f -name *.dylib -exec otool -l {} \; | grep -e "^toonz" -e"name \/usr\/local" | sed -e"s/://" -e"s/ (.*$//" -e"s/^ *name //"` +for X in `find $TOONZDIR/Tahoma2D.app/Contents -type f '(' -name *.dylib -o -name *.so ')' -exec otool -l {} \; | grep -e "^toonz" -e"name \/usr\/local" | sed -e"s/://" -e"s/ (.*$//" -e"s/^ *name //"` do Z=`echo $X | cut -c 1-1` if [ "$Z" != "/" ] @@ -82,10 +90,22 @@ do else Y=`basename $X` W=`basename $LIBFILE` - if [ -f $TOONZDIR/Tahoma2D.app/Contents/Frameworks/$Y -a "$Y" != "$W" ] + if [ ! -f $TOONZDIR/Tahoma2D.app/Contents/Frameworks/$Y ] + then + echo "Copying $X to Frameworks" + cp $X $TOONZDIR/Tahoma2D.app/Contents/Frameworks + chmod 644 $TOONZDIR/Tahoma2D.app/Contents/Frameworks/$Y + fi + if [ "$Y" != "$W" ] then echo "Fixing $X in $LIBFILE" install_name_tool -change $X @executable_path/../Frameworks/$Y $LIBFILE + FIXCHECK=`otool -D $LIBFILE | grep -e"\/usr\/local"` + if [ "$FIXCHECK" == "$X" ] + then + echo " Fixed ID!" + install_name_tool -id @executable_path/../Frameworks/$Y $LIBFILE + fi fi fi done diff --git a/ci-scripts/osx/tahoma-install.sh b/ci-scripts/osx/tahoma-install.sh index 7e858ebc..da27f1aa 100755 --- a/ci-scripts/osx/tahoma-install.sh +++ b/ci-scripts/osx/tahoma-install.sh @@ -7,4 +7,4 @@ brew unlink nghttp2 brew install boost qt@5 clang-format glew lz4 lzo libmypaint jpeg-turbo nasm yasm fontconfig freetype gnutls lame libass libbluray libsoxr libvorbis libvpx opencore-amr openh264 openjpeg opus rav1e sdl2 snappy speex tesseract theora webp xvid xz #brew install dav1d brew install meson ninja - \ No newline at end of file +brew install automake autoconf gettext pkg-config libtool libusb-compat gd libexif \ No newline at end of file diff --git a/ci-scripts/windows/tahoma-build.bat b/ci-scripts/windows/tahoma-build.bat index 19a4cb04..75cc7cea 100644 --- a/ci-scripts/windows/tahoma-build.bat +++ b/ci-scripts/windows/tahoma-build.bat @@ -25,10 +25,13 @@ IF EXIST D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.9\msvc2019_64 ( set WITH_CANON=N IF EXIST ..\..\thirdparty\canon\Header set WITH_CANON=Y +set WITH_GPHOTO2=N +IF EXIST ..\..\thirdparty\libgphoto2\include set WITH_GPHOTO2=Y + set WITH_CRASHRPT=N IF EXIST ..\..\thirdparty\crashrpt\include set WITH_CRASHRPT=Y -cmake ..\sources -G %MSVCVERSION% -Ax64 -DQT_PATH=%QT_PATH% -DBOOST_ROOT=%BOOST_ROOT% -DOpenCV_DIR=%OPENCV_DIR% -DWITH_CANON=%WITH_CANON% -DWITH_CRASHRPT=%WITH_CRASHRPT% +cmake ..\sources -G %MSVCVERSION% -Ax64 -DQT_PATH=%QT_PATH% -DBOOST_ROOT=%BOOST_ROOT% -DOpenCV_DIR=%OPENCV_DIR% -DWITH_CANON=%WITH_CANON% -DWITH_GPHOTO2=%WITH_GPHOTO2% -DWITH_CRASHRPT=%WITH_CRASHRPT% IF EXIST C:\ProgramData\chocolatey\bin\cl.exe ( diff --git a/ci-scripts/windows/tahoma-buildpkg.bat b/ci-scripts/windows/tahoma-buildpkg.bat index 10440e3d..fabb8a07 100644 --- a/ci-scripts/windows/tahoma-buildpkg.bat +++ b/ci-scripts/windows/tahoma-buildpkg.bat @@ -32,6 +32,12 @@ IF EXIST ..\..\thirdparty\canon\Header ( copy /Y ..\..\thirdparty\canon\Dll\EdsImage.dll Tahoma2D ) +IF EXIST ..\..\thirdparty\libgphoto2\include ( + xcopy /Y /E ..\..\thirdparty\libgphoto2\bin\camlibs Tahoma2D\tahomastuff + xcopy /Y /E ..\..\thirdparty\libgphoto2\bin\iolibs Tahoma2D\tahomastuff + copy /Y ..\..\thirdparty\libgphoto2\bin\*.* Tahoma2D\tahomastuff +) + IF EXIST ..\..\thirdparty\crashrpt\include ( copy /Y ..\..\thirdparty\apps\crashrpt\CrashRpt1500.dll Tahoma2D copy /Y ..\..\thirdparty\apps\crashrpt\CrashSender1500.exe Tahoma2D diff --git a/stuff/doc/LICENSE/LICENSE_libgphoto2.txt b/stuff/doc/LICENSE/LICENSE_libgphoto2.txt new file mode 100644 index 00000000..a84eb9eb --- /dev/null +++ b/stuff/doc/LICENSE/LICENSE_libgphoto2.txt @@ -0,0 +1,506 @@ +libgphoto2 library +----------------------------------------------------------------------- + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright © 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 © + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/stuff/doc/LICENSE/notice_about_modified_libgphoto2.txt b/stuff/doc/LICENSE/notice_about_modified_libgphoto2.txt new file mode 100644 index 00000000..e5f12d1e --- /dev/null +++ b/stuff/doc/LICENSE/notice_about_modified_libgphoto2.txt @@ -0,0 +1,12 @@ +Tahoma2D uses a modified version of libgphoto2. + +- Windows version was modified to allow building with MSVC 2019 using a modified + MSVC project taken from https://github.com/vividos/RemotePhotoTool. + +- OSX version was modified to allow relocation of camlib/iolibs directories relative + to libgphoto2/libgphoto2_port dylibs, post build, to allow for packaging and portability. + +- Linux version has no changes + +Modified source can be found at https://github.com/tahoma2d/libgphoto2 under +the `tahoma2d-version` branch. \ No newline at end of file diff --git a/thirdparty/libgphoto2/bin/camlibs/canon.dll b/thirdparty/libgphoto2/bin/camlibs/canon.dll new file mode 100644 index 00000000..bb4c4699 --- /dev/null +++ b/thirdparty/libgphoto2/bin/camlibs/canon.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b99af8d1b5db501d51c98ea6c90668198269c44b1c49e2d91d21254a41011512 +size 139776 diff --git a/thirdparty/libgphoto2/bin/camlibs/canon.exp b/thirdparty/libgphoto2/bin/camlibs/canon.exp new file mode 100644 index 00000000..3d794885 Binary files /dev/null and b/thirdparty/libgphoto2/bin/camlibs/canon.exp differ diff --git a/thirdparty/libgphoto2/bin/camlibs/canon.lib b/thirdparty/libgphoto2/bin/camlibs/canon.lib new file mode 100644 index 00000000..3e0b3bf1 --- /dev/null +++ b/thirdparty/libgphoto2/bin/camlibs/canon.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcbb0910b8e5a57fefcabd993c815906460f0d64424932a30b7083b55ea6fc1f +size 2064 diff --git a/thirdparty/libgphoto2/bin/camlibs/canon.pdb b/thirdparty/libgphoto2/bin/camlibs/canon.pdb new file mode 100644 index 00000000..69c1983a Binary files /dev/null and b/thirdparty/libgphoto2/bin/camlibs/canon.pdb differ diff --git a/thirdparty/libgphoto2/bin/camlibs/ptp2.dll b/thirdparty/libgphoto2/bin/camlibs/ptp2.dll new file mode 100644 index 00000000..1ff61cb0 --- /dev/null +++ b/thirdparty/libgphoto2/bin/camlibs/ptp2.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf2dc953d26edb85c32d8ed54c7c27ff07bd2cb63b008a42fd13641def484079 +size 881664 diff --git a/thirdparty/libgphoto2/bin/camlibs/ptp2.exp b/thirdparty/libgphoto2/bin/camlibs/ptp2.exp new file mode 100644 index 00000000..df93d713 Binary files /dev/null and b/thirdparty/libgphoto2/bin/camlibs/ptp2.exp differ diff --git a/thirdparty/libgphoto2/bin/camlibs/ptp2.lib b/thirdparty/libgphoto2/bin/camlibs/ptp2.lib new file mode 100644 index 00000000..9c5421cd --- /dev/null +++ b/thirdparty/libgphoto2/bin/camlibs/ptp2.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:76425341db0df1d16177de4037b83c1afbbe4220897329a286ce844c1e8dc821 +size 2052 diff --git a/thirdparty/libgphoto2/bin/camlibs/ptp2.pdb b/thirdparty/libgphoto2/bin/camlibs/ptp2.pdb new file mode 100644 index 00000000..963b0e2e Binary files /dev/null and b/thirdparty/libgphoto2/bin/camlibs/ptp2.pdb differ diff --git a/thirdparty/libgphoto2/bin/compat.pdb b/thirdparty/libgphoto2/bin/compat.pdb new file mode 100644 index 00000000..5aab47ad Binary files /dev/null and b/thirdparty/libgphoto2/bin/compat.pdb differ diff --git a/thirdparty/libgphoto2/bin/iolibs/disk.dll b/thirdparty/libgphoto2/bin/iolibs/disk.dll new file mode 100644 index 00000000..0b8e707f --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/disk.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e7112dc29f022f5a06d6fcc1525e9f2efb6c1260df233965bbf97c9e5e7fbf3 +size 11264 diff --git a/thirdparty/libgphoto2/bin/iolibs/disk.exp b/thirdparty/libgphoto2/bin/iolibs/disk.exp new file mode 100644 index 00000000..86352df9 Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/disk.exp differ diff --git a/thirdparty/libgphoto2/bin/iolibs/disk.lib b/thirdparty/libgphoto2/bin/iolibs/disk.lib new file mode 100644 index 00000000..67d13030 --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/disk.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcf15f411427f8f43db3df2bb78f6522a31fa8f6115516558d0d204c8648284a +size 2200 diff --git a/thirdparty/libgphoto2/bin/iolibs/disk.pdb b/thirdparty/libgphoto2/bin/iolibs/disk.pdb new file mode 100644 index 00000000..9fdcd2c3 Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/disk.pdb differ diff --git a/thirdparty/libgphoto2/bin/iolibs/libusb1.dll b/thirdparty/libgphoto2/bin/iolibs/libusb1.dll new file mode 100644 index 00000000..e0ab5dde --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/libusb1.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:100b348fc5d969066bb2c695fed5c1091fa313d06e1155bb0852d5afabba14f6 +size 35328 diff --git a/thirdparty/libgphoto2/bin/iolibs/libusb1.exp b/thirdparty/libgphoto2/bin/iolibs/libusb1.exp new file mode 100644 index 00000000..530c7a6b Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/libusb1.exp differ diff --git a/thirdparty/libgphoto2/bin/iolibs/libusb1.lib b/thirdparty/libgphoto2/bin/iolibs/libusb1.lib new file mode 100644 index 00000000..2cf61dc7 --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/libusb1.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ffa05edb05c8d54084ac7b3a801a0a55bb9be6d83726c92cc5cac2038279340 +size 2244 diff --git a/thirdparty/libgphoto2/bin/iolibs/libusb1.pdb b/thirdparty/libgphoto2/bin/iolibs/libusb1.pdb new file mode 100644 index 00000000..5ea4a239 Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/libusb1.pdb differ diff --git a/thirdparty/libgphoto2/bin/iolibs/ptpip.dll b/thirdparty/libgphoto2/bin/iolibs/ptpip.dll new file mode 100644 index 00000000..b706f564 --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/ptpip.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08491f209e4c7fcf49ce622d27f9211fd7d6d66c18f92490027e7cd77ffdb282 +size 11776 diff --git a/thirdparty/libgphoto2/bin/iolibs/ptpip.exp b/thirdparty/libgphoto2/bin/iolibs/ptpip.exp new file mode 100644 index 00000000..ad9cad7c Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/ptpip.exp differ diff --git a/thirdparty/libgphoto2/bin/iolibs/ptpip.lib b/thirdparty/libgphoto2/bin/iolibs/ptpip.lib new file mode 100644 index 00000000..471c52de --- /dev/null +++ b/thirdparty/libgphoto2/bin/iolibs/ptpip.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a1d05c9c0a8ebb963fb20d34aa40ccc423e7d88cc4d843212f0b75de9a8050b +size 2216 diff --git a/thirdparty/libgphoto2/bin/iolibs/ptpip.pdb b/thirdparty/libgphoto2/bin/iolibs/ptpip.pdb new file mode 100644 index 00000000..ebbd2e0a Binary files /dev/null and b/thirdparty/libgphoto2/bin/iolibs/ptpip.pdb differ diff --git a/thirdparty/libgphoto2/bin/libgphoto2.dll b/thirdparty/libgphoto2/bin/libgphoto2.dll new file mode 100644 index 00000000..9cfc49fc --- /dev/null +++ b/thirdparty/libgphoto2/bin/libgphoto2.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c99b16018528f01e3d439ceae8b5751b809aae2fbae518657a5a72c0cf3ccf3 +size 141824 diff --git a/thirdparty/libgphoto2/bin/libgphoto2.pdb b/thirdparty/libgphoto2/bin/libgphoto2.pdb new file mode 100644 index 00000000..fa55db70 Binary files /dev/null and b/thirdparty/libgphoto2/bin/libgphoto2.pdb differ diff --git a/thirdparty/libgphoto2/bin/libgphoto2_port.dll b/thirdparty/libgphoto2/bin/libgphoto2_port.dll new file mode 100644 index 00000000..c5a5cb81 --- /dev/null +++ b/thirdparty/libgphoto2/bin/libgphoto2_port.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abf9a381af54681242826b215d0490eb42f5514c34f040b83f5c4b2871e407b7 +size 43520 diff --git a/thirdparty/libgphoto2/bin/libgphoto2_port.pdb b/thirdparty/libgphoto2/bin/libgphoto2_port.pdb new file mode 100644 index 00000000..6a059699 Binary files /dev/null and b/thirdparty/libgphoto2/bin/libgphoto2_port.pdb differ diff --git a/thirdparty/libgphoto2/bin/libusb-1.0.dll b/thirdparty/libgphoto2/bin/libusb-1.0.dll new file mode 100644 index 00000000..6cbdf6bb --- /dev/null +++ b/thirdparty/libgphoto2/bin/libusb-1.0.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dac95d1eafcba057cf3df73dcf419bc14f4167ef4ac92fe1f8fdcab4278b6f4 +size 161280 diff --git a/thirdparty/libgphoto2/bin/libusb-1.0.pdb b/thirdparty/libgphoto2/bin/libusb-1.0.pdb new file mode 100644 index 00000000..049a58bd Binary files /dev/null and b/thirdparty/libgphoto2/bin/libusb-1.0.pdb differ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-abilities-list.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-abilities-list.h new file mode 100644 index 00000000..1c7db131 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-abilities-list.h @@ -0,0 +1,208 @@ +/** \file gphoto2-abilities-list.h + * \brief List of supported camera models including their abilities. + * + * \author Copyright 2000 Scott Fritzinger + * + * \par + * This library 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 2 of the License, or (at your option) any later version. + * + * \par + * This library 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. + * + * \par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_ABILITIES_LIST_H +#define LIBGPHOTO2_GPHOTO2_ABILITIES_LIST_H + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Current implementation status of the camera driver. + */ +typedef enum { + GP_DRIVER_STATUS_PRODUCTION, /**< Driver is production ready. */ + GP_DRIVER_STATUS_TESTING, /**< Driver is beta quality. */ + GP_DRIVER_STATUS_EXPERIMENTAL, /**< Driver is alpha quality and might even not work. */ + GP_DRIVER_STATUS_DEPRECATED /**< Driver is no longer recommended to use and will be removed. */ +} CameraDriverStatus; + +/** + * Type of the device represented. Currently we have Still Cameras + * and MTP Audio Players. + */ +typedef enum { + GP_DEVICE_STILL_CAMERA = 0, /**< Traditional still camera */ + GP_DEVICE_AUDIO_PLAYER = 1 << 0 /**< Audio player */ +} GphotoDeviceType; + +/** + * A bitmask of remote control related operations of the device. + * Some drivers might support additional dynamic capabilities (like the PTP driver). + */ +typedef enum { + GP_OPERATION_NONE = 0, /**< No remote control operation supported. */ + GP_OPERATION_CAPTURE_IMAGE = 1 << 0, /**< Capturing images supported. */ + GP_OPERATION_CAPTURE_VIDEO = 1 << 1, /**< Capturing videos supported. */ + GP_OPERATION_CAPTURE_AUDIO = 1 << 2, /**< Capturing audio supported. */ + GP_OPERATION_CAPTURE_PREVIEW = 1 << 3, /**< Capturing image previews supported. */ + GP_OPERATION_CONFIG = 1 << 4, /**< Camera and Driver configuration supported. */ + GP_OPERATION_TRIGGER_CAPTURE = 1 << 5 /**< Camera can trigger capture and wait for events. */ +} CameraOperation; + +/** + * A bitmask of image related operations of the device. + */ +typedef enum { + GP_FILE_OPERATION_NONE = 0, /**< No special file operations, just download. */ + GP_FILE_OPERATION_DELETE = 1 << 1, /**< Deletion of files is possible. */ + GP_FILE_OPERATION_PREVIEW = 1 << 3, /**< Previewing viewfinder content is possible. */ + GP_FILE_OPERATION_RAW = 1 << 4, /**< Raw retrieval is possible (used by non-JPEG cameras) */ + GP_FILE_OPERATION_AUDIO = 1 << 5, /**< Audio retrieval is possible. */ + GP_FILE_OPERATION_EXIF = 1 << 6 /**< EXIF retrieval is possible. */ +} CameraFileOperation; + +/** + * A bitmask of filesystem related operations of the device. + */ +typedef enum { + GP_FOLDER_OPERATION_NONE = 0, /**< No special filesystem operation. */ + GP_FOLDER_OPERATION_DELETE_ALL = 1 << 0, /**< Deletion of all files on the device. */ + GP_FOLDER_OPERATION_PUT_FILE = 1 << 1, /**< Upload of files to the device possible. */ + GP_FOLDER_OPERATION_MAKE_DIR = 1 << 2, /**< Making directories on the device possible. */ + GP_FOLDER_OPERATION_REMOVE_DIR = 1 << 3 /**< Removing directories from the device possible. */ +} CameraFolderOperation; + +#ifdef _GPHOTO2_INTERNAL_CODE + + /* enum CameraOperation */ + extern const StringFlagItem gpi_camera_operation_map[]; + + /* enum CameraFileOperation */ + extern const StringFlagItem gpi_file_operation_map[]; + + /* enum CameraFolderOperation */ + extern const StringFlagItem gpi_folder_operation_map[]; + + /* enum GphotoDeviceType */ + extern const StringFlagItem gpi_gphoto_device_type_map[]; + + /* enum CameraDriverStatus */ + extern const StringFlagItem gpi_camera_driver_status_map[]; + +#endif /* _GPHOTO2_INTERNAL_CODE */ + + +/** + * \brief Describes the properties of a specific camera. + * + * The internals of this structures are used extensively by the + * camlibs, but the status regarding use by frontends is questionable. + */ +typedef struct { + char model [128]; /**< \brief name of camera model */ + CameraDriverStatus status; /**< \brief driver quality */ + + /** \brief Supported port types. */ + GPPortType port; + /** \brief Supported serial port speeds (terminated with a value of 0). */ + int speed [64]; + + /* Supported operations */ + CameraOperation operations; /**< \brief Camera operation funcs */ + CameraFileOperation file_operations; /**< \brief Camera file op funcs */ + CameraFolderOperation folder_operations;/**< \brief Camera folder op funcs */ + + int usb_vendor; /**< \brief USB Vendor D */ + int usb_product; /**< \brief USB Product ID */ + int usb_class; /**< \brief USB device class */ + int usb_subclass; /**< \brief USB device subclass */ + int usb_protocol; /**< \brief USB device protocol */ + + /* For core use */ + char library [1024]; /**< \brief (Internal) library filename */ + char id [1024]; /**< \brief (Internal) camera ID name */ + + GphotoDeviceType device_type; /**< \brief Device type. */ + /** Reserved space to use in the future w/out changing the + * struct size */ + int reserved2; /**< reserved space \internal */ + int reserved3; /**< reserved space \internal */ + int reserved4; /**< reserved space \internal */ + int reserved5; /**< reserved space \internal */ + int reserved6; /**< reserved space \internal */ + int reserved7; /**< reserved space \internal */ + int reserved8; /**< reserved space \internal */ +} CameraAbilities; + + +/** + * \brief List of supported camera models including their abilities + * + * The internals of this list are hidden - use the access functions. + */ +typedef struct _CameraAbilitiesList CameraAbilitiesList; + + +int gp_abilities_list_new (CameraAbilitiesList **list); +int gp_abilities_list_free (CameraAbilitiesList *list); + +int gp_abilities_list_load (CameraAbilitiesList *list, GPContext *context); +int gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, GPContext *context); +int gp_abilities_list_reset (CameraAbilitiesList *list); + +int gp_abilities_list_detect (CameraAbilitiesList *list, + GPPortInfoList *info_list, CameraList *l, + GPContext *context); + +int gp_abilities_list_append (CameraAbilitiesList *list, + CameraAbilities abilities); + +int gp_abilities_list_count (CameraAbilitiesList *list); + +int gp_abilities_list_lookup_model (CameraAbilitiesList *list, + const char *model); + +int gp_abilities_list_get_abilities (CameraAbilitiesList *list, int index, + CameraAbilities *abilities); + +const char *gp_message_codeset (const char *); + +int gp_init_localedir (const char *localedir); + + +/** + * Name of the environment variable which may contain the path where + * to look for the camlibs. If this environment variable is not defined, + * use the compiled-in default constant. + * + * \internal Internal use only. + */ +#ifdef _GPHOTO2_INTERNAL_CODE +#define CAMLIBDIR_ENV "CAMLIBS" +#endif /* _GPHOTO2_INTERNAL_CODE */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_ABILITIES_LIST_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-camera.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-camera.h new file mode 100644 index 00000000..445c839f --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-camera.h @@ -0,0 +1,484 @@ +/** \file + * + * \brief Implement Camera object representing a camera attached to the system. + * + * \author Copyright 2000 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_CAMERA_H +#define LIBGPHOTO2_GPHOTO2_CAMERA_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Object representing a camera attached to the system. + * + * A Camera object represents a specific instance of a (physical of + * virtual) camera attached to the system. + * + * The abilities of this type of camera are stored in a CameraAbility + * object. + * + * The details of the Camera object are internal. + */ +typedef struct _Camera Camera; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief CameraText structure used in various functions. + * + * A text structure containing translated text returned + * by various functions (about, manual, summary). You should + * not assume a size. + */ +typedef struct { + char text [32 * 1024]; /**< \brief Character string containing the translated text. */ +} CameraText; + +/** + * \brief A structure created by the capture operation. + * + * A structure containing the folder and filename of an object + * after a successful capture and is passed as reference to the + * gp_camera_capture() function. + */ +typedef struct { + char name [128]; /**< \brief Name of the captured file. */ + char folder [1024]; /**< \brief Name of the folder of the captured file. */ +} CameraFilePath; + +/** + * \brief Type of the capture to do. + * + * Specifies the type of capture the user wants to do with the + * gp_camera_capture() function. + */ +typedef enum { + GP_CAPTURE_IMAGE, /**< \brief Capture an image. */ + GP_CAPTURE_MOVIE, /**< \brief Capture a movie. */ + GP_CAPTURE_SOUND /**< \brief Capture audio. */ +} CameraCaptureType; + +/** + * \brief Specify what event we received from the camera. + * + * Used by gp_camera_wait_for_event() to specify what + * event happened on the camera. + * + */ +typedef enum { + GP_EVENT_UNKNOWN, /**< unknown and unhandled event. argument is a char* or NULL */ + GP_EVENT_TIMEOUT, /**< timeout, no arguments */ + GP_EVENT_FILE_ADDED, /**< CameraFilePath* = file path on camfs */ + GP_EVENT_FOLDER_ADDED, /**< CameraFilePath* = folder on camfs */ + GP_EVENT_CAPTURE_COMPLETE, /**< last capture is complete */ + GP_EVENT_FILE_CHANGED /**< CameraFilePath* = file path on camfs */ +} CameraEventType; + +/** + * \name Camera object member functions + * + * These functions must be implemented by a camlib and the camlib's + * camera_init() function will add them to a Camera object. + * + * @{ + */ +/** + * \brief The camera exit function + * + * \param camera the current camera + * \param context a #GPContext + * + * This functions is called in the camera driver for closing the camera + * connection. It should do the necessary cleanups of the internal camera + * state, free allocated private structures and similar. + * + * The driver does not need to close the #GPPort, this is done by libgphoto2 + * itself. + * + * Implement this function if you need to any of this stuff, otherwise leave + * it out. + * + * \returns a gphoto error code + */ +typedef int (*CameraExitFunc) (Camera *camera, GPContext *context); + +/** + * \brief Get a configuration tree for the camera and its driver + * + * \param camera the current camera + * \param widget pointer to store the toplevel widget of the tree + * \param context the active #GPContext + * + * A camera driver can support configuration of either its own behaviour + * or the camera device itself. To allow a flexible driver framework, + * the camera driver provides a generic configuration widget tree to the + * frontend, which then renders it, allows user input and sends it back + * via the #CameraSetConfigFunc function to have the driver configure itself + * or the camera. + * + * If you do not have configuration ability, there is no need to specify this + * function. + * + * \returns a gphoto error code + */ +typedef int (*CameraGetConfigFunc) (Camera *camera, CameraWidget **widget, + GPContext *context); +/** + * \brief Get a configuration widget for a specific configuration + * + * \param camera the current camera + * \param name the name of the widget + * \param widget pointer to store the toplevel widget of the tree + * \param context the active #GPContext + * + * A camera driver can support configuration of either its own behaviour + * or the camera device itself. To allow a flexible driver framework, + * the camera driver provides a generic configuration widget tree to the + * frontend, which then renders it, allows user input and sends it back + * via the #CameraSetConfigFunc function to have the driver configure itself + * or the camera. + * + * This specific function retrieves one specific named entry, and not the full + * tree to allow for querying specific settings faster. + * + * If you do not have configuration ability, there is no need to specify this + * function. + * + * \returns a gphoto error code + */ +typedef int (*CameraGetSingleConfigFunc) (Camera *camera, const char *name, CameraWidget **widget, + GPContext *context); +/** + * \brief List all configuration widgets for a specific configuration + * + * \param camera the current camera + * \param list the list of widgets available + * \param context the active #GPContext + * + * A camera driver can support configuration of either its own behaviour + * or the camera device itself. To allow a flexible driver framework, + * the camera driver provides a generic configuration widget tree to the + * frontend, which then renders it, allows user input and sends it back + * via the #CameraSetConfigFunc function to have the driver configure itself + * or the camera. + * + * This specific function retrieves all the available configuration values in a flat list. + * + * This is different than the GetConfigFunc, which returns a configuration tree. + * + * If you do not have configuration ability, there is no need to specify this + * function. + * + * \returns a gphoto error code + */ +typedef int (*CameraListConfigFunc) (Camera *camera, CameraList *list, GPContext *context); +/** + * \brief Set the configuration in the camera + * + * \param camera the current camera + * \param widget the configuration widget tree that was changed + * \param context the active #GPContext + * + * This function is called in the driver after the configuration is set. + * It is called directly after setting the value and might called multiple + * times (or never) after just one #CameraGetConfigFunc. + * + * \returns a gphoto error code + */ +typedef int (*CameraSetConfigFunc) (Camera *camera, CameraWidget *widget, + GPContext *context); +/** + * \brief Set a single configuration variable in the camera + * + * \param camera the current camera + * \param name the widget to set + * \param widget the configuration widget tree that was changed + * \param context the active #GPContext + * + * This function is called in the driver after the configuration value is set. + * + * \returns a gphoto error code + */ +typedef int (*CameraSetSingleConfigFunc) (Camera *camera, const char *name, CameraWidget *widget, + GPContext *context); + +typedef int (*CameraCaptureFunc) (Camera *camera, CameraCaptureType type, + CameraFilePath *path, GPContext *context); +typedef int (*CameraTriggerCaptureFunc) (Camera *camera, GPContext *context); +typedef int (*CameraCapturePreviewFunc) (Camera *camera, CameraFile *file, + GPContext *context); +typedef int (*CameraSummaryFunc) (Camera *camera, CameraText *text, + GPContext *context); +typedef int (*CameraManualFunc) (Camera *camera, CameraText *text, + GPContext *context); +typedef int (*CameraAboutFunc) (Camera *camera, CameraText *text, + GPContext *context); +typedef int (*CameraWaitForEvent) (Camera *camera, int timeout, + CameraEventType *eventtype, void **eventdata, + GPContext *context); +/**@}*/ + + +/** + * \param camera a \ref Camera object + * \param context a \ref GPContext object + * \return a gphoto2 error code + * + * Implement this function in the camera driver if the camera needs to + * be initialized before or reset the after each access from + * libgphoto2. + * + * For example, you would probably set the speed to the highest one + * right before downloading an image, and reset it to the default speed + * afterwards so that other programs will not be affected by this speed + * change. + */ +typedef int (*CameraPrePostFunc) (Camera *camera, GPContext *context); + +/** + * \brief Various camera specific functions. + * + * This structure contains various pointers to functions that apply to + * the camera itself, and not the filesystem (which is handled by the + * filesystem functions). Set the ones you want to provide, leave the rest + * unset. + * + * This structure should only used by the driver itself, the frontend + * should use the gp_camera_xxx wrapper functions for it, who handle + * opening and locking around those hooks. + */ +typedef struct _CameraFunctions { + CameraPrePostFunc pre_func; /**< \brief Function called before each camera operation. */ + CameraPrePostFunc post_func; /**< \brief Function called after each camera operation. */ + + CameraExitFunc exit; /**< \brief Function called on closing the camera. */ + + /* Configuration */ + CameraGetConfigFunc get_config; /**< \brief Called for requesting the configuration widgets. */ + CameraSetConfigFunc set_config; /**< \brief Called after a configuration was changed */ + + CameraListConfigFunc list_config; /**< \brief Called for listing the available configuration widgets. */ + CameraGetSingleConfigFunc get_single_config; /**< \brief Called for requesteing a single widget. */ + CameraSetSingleConfigFunc set_single_config; /**< \brief Called for setting a single configuration widget. */ + + /* Capturing */ + CameraCaptureFunc capture; /**< \brief Remote control the camera to capture */ + CameraTriggerCaptureFunc trigger_capture;/**< \brief Remote control the camera to trigger capture */ + CameraCapturePreviewFunc capture_preview;/**< \brief Preview viewfinder content. */ + + /* Textual information */ + CameraSummaryFunc summary; /**< \brief Give a summary about the current camera status, translated. */ + CameraManualFunc manual; /**< \brief Give a brief manual about any specific items a user has to know, translated. */ + CameraAboutFunc about; /**< \brief A little About text, including authors and credits. */ + + /* Event Interface */ + CameraWaitForEvent wait_for_event; /**< \brief Wait for a specific event from the camera */ + /* Reserved space to use in the future without changing the struct size */ + void *reserved1; /**< \brief reserved for future use */ + void *reserved2; /**< \brief reserved for future use */ + void *reserved3; /**< \brief reserved for future use */ + void *reserved4; /**< \brief reserved for future use */ + void *reserved5; /**< \brief reserved for future use */ + void *reserved6; /**< \brief reserved for future use */ + void *reserved7; /**< \brief reserved for future use */ + void *reserved8; /**< \brief reserved for future use */ +} CameraFunctions; + +typedef struct _CameraPrivateLibrary CameraPrivateLibrary; +typedef struct _CameraPrivateCore CameraPrivateCore; + +struct _Camera { + + /** \name Those should be accessed only by the camera driver. + * @{ */ + GPPort *port; + CameraFilesystem *fs; + CameraFunctions *functions; + /**@}*/ + + CameraPrivateLibrary *pl; /**< Private data of camera libraries. */ + CameraPrivateCore *pc; /**< Private data of the core of gphoto2. */ +}; + + +/** Create a new camera device. */ +int gp_camera_new (Camera **camera); + + +/** \name Preparing initialization + * @{ + */ +int gp_camera_set_abilities (Camera *camera, CameraAbilities abilities); +int gp_camera_get_abilities (Camera *camera, CameraAbilities *abilities); +int gp_camera_set_port_info (Camera *camera, GPPortInfo info); +int gp_camera_get_port_info (Camera *camera, GPPortInfo *info); + +/**@}*/ + + +/** + * \name camera speed + * + * You normally don't use that. If you do, you prevent the camera driver + * from selecting the optimal speed. + * + * @{ + */ +int gp_camera_set_port_speed (Camera *camera, int speed); +int gp_camera_get_port_speed (Camera *camera); + +/**@}*/ + + +/** \name Initialization + * @{ + */ +int gp_camera_autodetect (CameraList *list, GPContext *context); +int gp_camera_init (Camera *camera, GPContext *context); +int gp_camera_exit (Camera *camera, GPContext *context); + +/**@}*/ + + + +/** \name Operations on cameras + * @{ + */ +int gp_camera_ref (Camera *camera); +int gp_camera_unref (Camera *camera); +int gp_camera_free (Camera *camera); + +int gp_camera_get_config (Camera *camera, CameraWidget **window, + GPContext *context); +int gp_camera_list_config (Camera *camera, CameraList *list, + GPContext *context); +int gp_camera_get_single_config (Camera *camera, const char *name, CameraWidget **widget, + GPContext *context); +int gp_camera_set_config (Camera *camera, CameraWidget *window, + GPContext *context); +int gp_camera_set_single_config (Camera *camera, const char *name, CameraWidget *widget, + GPContext *context); +int gp_camera_get_summary (Camera *camera, CameraText *summary, + GPContext *context); +int gp_camera_get_manual (Camera *camera, CameraText *manual, + GPContext *context); +int gp_camera_get_about (Camera *camera, CameraText *about, + GPContext *context); +int gp_camera_capture (Camera *camera, CameraCaptureType type, + CameraFilePath *path, GPContext *context); +int gp_camera_trigger_capture (Camera *camera, GPContext *context); +int gp_camera_capture_preview (Camera *camera, CameraFile *file, + GPContext *context); +int gp_camera_wait_for_event (Camera *camera, int timeout, + CameraEventType *eventtype, void **eventdata, + GPContext *context); + +int gp_camera_get_storageinfo (Camera *camera, CameraStorageInformation**, + int *, GPContext *context); + +/**@}*/ + + +/** \name Operations on folders + * @{ + */ +int gp_camera_folder_list_files (Camera *camera, const char *folder, + CameraList *list, GPContext *context); +int gp_camera_folder_list_folders (Camera *camera, const char *folder, + CameraList *list, GPContext *context); +int gp_camera_folder_delete_all (Camera *camera, const char *folder, + GPContext *context); +int gp_camera_folder_put_file (Camera *camera, + const char *folder, const char *filename, + CameraFileType type, + CameraFile *file, GPContext *context); +int gp_camera_folder_make_dir (Camera *camera, const char *folder, + const char *name, GPContext *context); +int gp_camera_folder_remove_dir (Camera *camera, const char *folder, + const char *name, GPContext *context); +/**@}*/ + + +/** \name Operations on files + * @{ + */ +int gp_camera_file_get_info (Camera *camera, const char *folder, + const char *file, CameraFileInfo *info, + GPContext *context); +int gp_camera_file_set_info (Camera *camera, const char *folder, + const char *file, CameraFileInfo info, + GPContext *context); +int gp_camera_file_get (Camera *camera, const char *folder, + const char *file, CameraFileType type, + CameraFile *camera_file, GPContext *context); +int gp_camera_file_read (Camera *camera, const char *folder, const char *file, + CameraFileType type, + uint64_t offset, char *buf, uint64_t *size, + GPContext *context); +int gp_camera_file_delete (Camera *camera, const char *folder, + const char *file, GPContext *context); +/**@}*/ + + +/** + * \name Some cameras need 'keep-alive-messages'. + * @{ + */ +typedef int (* CameraTimeoutFunc) (Camera *camera, + GPContext *context); +typedef unsigned int (* CameraTimeoutStartFunc) (Camera *camera, + unsigned int timeout, + CameraTimeoutFunc func, + void *data); +typedef void (* CameraTimeoutStopFunc) (Camera *camera, + unsigned int id, void *data); +void gp_camera_set_timeout_funcs (Camera *camera, + CameraTimeoutStartFunc start_func, + CameraTimeoutStopFunc stop_func, + void *data); +int gp_camera_start_timeout (Camera *camera, unsigned int timeout, + CameraTimeoutFunc func); +void gp_camera_stop_timeout (Camera *camera, unsigned int id); + +/**@}*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_CAMERA_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-context.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-context.h new file mode 100644 index 00000000..f8b67c9c --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-context.h @@ -0,0 +1,138 @@ +/** \file + * \brief Context callback operation functions. + * + * \author Copyright 2001 Lutz Mueller + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_CONTEXT_H +#define LIBGPHOTO2_GPHOTO2_CONTEXT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief The gphoto context structure. + * + * This structure allows callback handling, passing error contexts back, + * progress handling and download cancellation and similar things. + * It is usually passed around the functions. + */ +typedef struct _GPContext GPContext; + +GPContext *gp_context_new (void); + +void gp_context_ref (GPContext *context); +void gp_context_unref (GPContext *context); + +/** + * \brief Return codes that can be returned by progress handling. + * + * An application can return special values back to the libgphoto2 + * progress callback handling functions. If "Cancel" is selected, + * libgphoto2 and the camera driver will try to cancel transfer. + */ +typedef enum _GPContextFeedback { + GP_CONTEXT_FEEDBACK_OK, /**< Everything ok... proceed. */ + GP_CONTEXT_FEEDBACK_CANCEL /**< Please cancel the current transfer if possible. */ +} GPContextFeedback; + +/* Functions */ +typedef void (* GPContextIdleFunc) (GPContext *context, void *data); +typedef void (* GPContextErrorFunc) (GPContext *context, const char *text, void *data); +typedef void (* GPContextStatusFunc) (GPContext *context, const char *text, void *data); +typedef void (* GPContextMessageFunc) (GPContext *context, const char *text, void *data); +typedef GPContextFeedback (* GPContextQuestionFunc) (GPContext *context, + const char *text, void *data); +typedef GPContextFeedback (* GPContextCancelFunc) (GPContext *context, + void *data); +typedef unsigned int (* GPContextProgressStartFunc) (GPContext *context, + float target, + const char *text, + void *data); +typedef void (* GPContextProgressUpdateFunc) (GPContext *context, + unsigned int id, + float current, + void *data); +typedef void (* GPContextProgressStopFunc) (GPContext *context, + unsigned int id, + void *data); + +/* Setting those functions (frontends) */ +void gp_context_set_idle_func (GPContext *context, + GPContextIdleFunc func, void *data); +void gp_context_set_progress_funcs (GPContext *context, + GPContextProgressStartFunc start_func, + GPContextProgressUpdateFunc update_func, + GPContextProgressStopFunc stop_func, + void *data); +void gp_context_set_error_func (GPContext *context, + GPContextErrorFunc func, void *data); +void gp_context_set_status_func (GPContext *context, + GPContextStatusFunc func, void *data); +void gp_context_set_question_func (GPContext *context, + GPContextQuestionFunc func, void *data); +void gp_context_set_cancel_func (GPContext *context, + GPContextCancelFunc func, void *data); +void gp_context_set_message_func (GPContext *context, + GPContextMessageFunc func, void *data); + +/* Calling those functions (backends) */ +void gp_context_idle (GPContext *context); +void gp_context_error (GPContext *context, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,2,3))) +#endif +; +void gp_context_status (GPContext *context, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,2,3))) +#endif +; +void gp_context_message (GPContext *context, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,2,3))) +#endif +; +GPContextFeedback gp_context_question (GPContext *context, const char *format, + ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,2,3))) +#endif +; +GPContextFeedback gp_context_cancel (GPContext *context); +unsigned int gp_context_progress_start (GPContext *context, float target, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,3,4))) +#endif +; +void gp_context_progress_update (GPContext *context, unsigned int id, + float current); +void gp_context_progress_stop (GPContext *context, unsigned int id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_CONTEXT_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-file.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-file.h new file mode 100644 index 00000000..53c9eab8 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-file.h @@ -0,0 +1,177 @@ +/** \file + * \brief Abstracted gphoto2 file operations. + * + * \author Copyright 2000 Scott Fritzinger + * \author Copyright 2008-2009 Marcus Meissner + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_FILE_H +#define LIBGPHOTO2_GPHOTO2_FILE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GP_MIME_TXT "text/plain" +#define GP_MIME_WAV "audio/wav" +#define GP_MIME_RAW "image/x-raw" +#define GP_MIME_PNG "image/png" +#define GP_MIME_PGM "image/x-portable-graymap" +#define GP_MIME_PPM "image/x-portable-pixmap" +#define GP_MIME_PNM "image/x-portable-anymap" +#define GP_MIME_JPEG "image/jpeg" +#define GP_MIME_TIFF "image/tiff" +#define GP_MIME_BMP "image/bmp" +#define GP_MIME_QUICKTIME "video/quicktime" +#define GP_MIME_AVI "video/x-msvideo" +#define GP_MIME_CRW "image/x-canon-raw" +#define GP_MIME_CR2 "image/x-canon-cr2" +#define GP_MIME_CR3 "image/x-canon-cr3" +#define GP_MIME_NEF "image/x-nikon-nef" +#define GP_MIME_UNKNOWN "application/octet-stream" +#define GP_MIME_EXIF "application/x-exif" +#define GP_MIME_MP3 "audio/mpeg" +#define GP_MIME_OGG "application/ogg" +#define GP_MIME_WMA "audio/x-wma" +#define GP_MIME_ASF "audio/x-asf" +#define GP_MIME_MPEG "video/mpeg" +#define GP_MIME_AVCHD "video/mp2t" +#define GP_MIME_RW2 "image/x-panasonic-raw2" +#define GP_MIME_ARW "image/x-sony-arw" + +/** + * \brief The type of view on the specified file. + * + * Specifies the file of the current file, usually passed + * to the gp_camera_file_get() and gp_camera_file_put() + * functions. This is useful for multiple views of one + * file, like that an single image file has "raw", "normal", + * "exif" and "preview" views, or a media file has "normal" + * and "metadata" file views. + */ +typedef enum { + GP_FILE_TYPE_PREVIEW, /**< A preview of an image. */ + GP_FILE_TYPE_NORMAL, /**< The regular normal data of a file. */ + GP_FILE_TYPE_RAW, /**< The raw mode of a file, for instance the raw bayer data for cameras + * where postprocessing is done in the driver. The RAW files of modern + * DSLRs are GP_FILE_TYPE_NORMAL usually. */ + GP_FILE_TYPE_AUDIO, /**< The audio view of a file. Perhaps an embedded comment or similar. */ + GP_FILE_TYPE_EXIF, /**< The embedded EXIF data of an image. */ + GP_FILE_TYPE_METADATA /**< The metadata of a file, like Metadata of files on MTP devices. */ +} CameraFileType; + +/** + * \brief File storage type. + * + * The file storage type. Only used internally for now, but might + * be exposed later on. See gp_file_new() and gp_file_new_from_fd(). + */ +typedef enum { + GP_FILE_ACCESSTYPE_MEMORY, /**< File is in system memory. */ + GP_FILE_ACCESSTYPE_FD, /**< File is associated with a UNIX filedescriptor. */ + GP_FILE_ACCESSTYPE_HANDLER /**< File is associated with a programmatic handler. */ +} CameraFileAccessType; + +/* FIXME: api might be unstable. function return gphoto results codes. */ +typedef struct _CameraFileHandler { + int (*size) (void*priv, uint64_t *size); /* only for read? */ + int (*read) (void*priv, unsigned char *data, uint64_t *len); + int (*write) (void*priv, unsigned char *data, uint64_t *len); + /* FIXME: should we have both read/write methods? */ + /* FIXME: how to finish method, due to LRU it might be longlived. */ +} CameraFileHandler; + +/*! \struct CameraFile + * \brief File structure. + * + * The internals of the CameraFile struct are private, please use + * the accessor functions. + */ +typedef struct _CameraFile CameraFile; + +int gp_file_new (CameraFile **file); +int gp_file_new_from_fd (CameraFile **file, int fd); +int gp_file_new_from_handler (CameraFile **file, CameraFileHandler *handler, void*priv); +int gp_file_ref (CameraFile *file); +int gp_file_unref (CameraFile *file); +int gp_file_free (CameraFile *file); + +int gp_file_set_name (CameraFile *file, const char *name); +int gp_file_get_name (CameraFile *file, const char **name); + +int gp_file_set_mime_type (CameraFile *file, const char *mime_type); +int gp_file_get_mime_type (CameraFile *file, const char **mime_type); + +int gp_file_set_mtime (CameraFile *file, time_t mtime); +int gp_file_get_mtime (CameraFile *file, time_t *mtime); + +int gp_file_detect_mime_type (CameraFile *file); +int gp_file_adjust_name_for_mime_type (CameraFile *file); +int gp_file_get_name_by_type (CameraFile *file, const char *basename, CameraFileType type, char **newname); + +int gp_file_set_data_and_size (CameraFile*, char *data, + unsigned long int size); +int gp_file_get_data_and_size (CameraFile*, const char **data, + unsigned long int *size); +/* "Do not use those" + * + * These functions probably were originally intended for internal use only. + * However, due to + * - the lack of good documentation + * - this being the obvious way to save a file + * - the fact that libgphoto2 has been exporting all its internal + * symbols for years (until 2005-06) + * - our in-house frontends gphoto2 and gtkam using them + * a number of external frontends started to use these functions, as + * of 2005-06: + * - digikam + * - f-spot + * - gthumb + * But a few frontends can live without it (and thus are likely to + * use the correct API): + * - flphoto + * - kamera + * + * So we're going to phase these functions out over the next year or + * so, going the GTK way of keeping the ABI but breaking the API. So + * we'll continue to export functionally equivalent functions, but the + * header files will not contain definitions for you to use any more. + */ +int gp_file_open (CameraFile *file, const char *filename); +int gp_file_save (CameraFile *file, const char *filename); +int gp_file_clean (CameraFile *file); +int gp_file_copy (CameraFile *destination, CameraFile *source); + + +/* These are for use by camera drivers only */ +int gp_file_append (CameraFile*, const char *data, + unsigned long int size); +int gp_file_slurp (CameraFile*, char *data, + size_t size, size_t *readlen); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_FILE_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-filesys.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-filesys.h new file mode 100644 index 00000000..f37378ed --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-filesys.h @@ -0,0 +1,387 @@ +/** \file + * \brief Filesystem related operations and declarations. + * + * \author Copyright 2000 Scott Fritzinger + * \author Copyright 2008-2009 Marcus Meissner + * + * \note + * Contributions: + * Lutz Mueller (2001) + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_FILESYS_H +#define LIBGPHOTO2_GPHOTO2_FILESYS_H + +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Bitmask on what fields are set in the CameraFileInfo structure. + * + * Bitmask to mark up which fields are set in the CameraFileInfo + * structure. The other fields might be uninitialized. + * If you set information via gp_camera_file_set_info() you + * need to set those flags. If you retrieve information via + * gp_camera_file_get_info() you need to check those flags. + * They are separate for both "normal" and "preview" parts + * and are mostly image related. + */ +typedef enum { + GP_FILE_INFO_NONE = 0, /**< \brief No fields set. */ + GP_FILE_INFO_TYPE = 1 << 0, /**< \brief The MIME type is set. */ + GP_FILE_INFO_SIZE = 1 << 2, /**< \brief The filesize is set. */ + GP_FILE_INFO_WIDTH = 1 << 3, /**< \brief The width is set. */ + GP_FILE_INFO_HEIGHT = 1 << 4, /**< \brief The height is set. */ + GP_FILE_INFO_PERMISSIONS = 1 << 5, /**< \brief The access permissions are set. */ + GP_FILE_INFO_STATUS = 1 << 6, /**< \brief The status is set (downloaded). */ + GP_FILE_INFO_MTIME = 1 << 7, /**< \brief The modification time is set. */ + GP_FILE_INFO_ALL = 0xFF /**< \brief All possible fields set. Internal. */ +} CameraFileInfoFields; + +/** + * \brief Bitmask containing the file permission flags. + * + * Possible flag values of the permission entry in the file information. + */ +typedef enum { + GP_FILE_PERM_NONE = 0, /**< \brief No permissions. */ + GP_FILE_PERM_READ = 1 << 0, /**< \brief Read permissions. */ + GP_FILE_PERM_DELETE = 1 << 1, /**< \brief Write permissions */ + GP_FILE_PERM_ALL = 0xFF /**< \brief Internal. */ +} CameraFilePermissions; + +/** + * \brief Possible status values. + * + * Bitmask of possible stati. Currently only download is supported. + */ +typedef enum { + GP_FILE_STATUS_NOT_DOWNLOADED, /**< File is not downloaded. */ + GP_FILE_STATUS_DOWNLOADED /**< File is already downloaded. */ +} CameraFileStatus; + +/** + * \brief File information of a regular file. + * + * Contains information a regular file with fields being + * set depending on the bitmask in the fields member. + */ +typedef struct _CameraFileInfoFile { + CameraFileInfoFields fields; /**< \brief Bitmask containing the set members. */ + CameraFileStatus status; /**< \brief Status of the file. */ + uint64_t size; /**< \brief Size of the file. */ + char type[64]; /**< \brief MIME type of the file. */ + uint32_t width; /**< \brief Height of the file. */ + uint32_t height; /**< \brief Width of the file. */ + CameraFilePermissions permissions;/**< \brief Permissions of the file. */ + time_t mtime; /**< \brief Modification time of the file. */ +} CameraFileInfoFile; + +/** + * \brief File information of a preview file. + * + * Contains information of a preview file with fields being + * set depending on the bitmask in the fields member. + */ +typedef struct _CameraFileInfoPreview { + CameraFileInfoFields fields; /**< \brief Bitmask containing the set members. */ + CameraFileStatus status; /**< \brief Status of the preview. */ + uint64_t size; /**< \brief Size of the preview. */ + char type[64]; /**< \brief MIME type of the preview. */ + + uint32_t width; /**< \brief Width of the preview. */ + uint32_t height; /**< \brief Height of the preview. */ +} CameraFileInfoPreview; + +/** + * \brief File information of an audio file. + * + * Contains information of an audio file with fields being + * set depending on the bitmask in the fields member. + */ +typedef struct _CameraFileInfoAudio { + CameraFileInfoFields fields; /**< \brief Bitmask containing the set members. */ + CameraFileStatus status; /**< \brief Status of the preview file. */ + uint64_t size; /**< \brief Size of the audio file. */ + char type[64]; /**< \brief MIME type of the audio file. */ +} CameraFileInfoAudio; + +/** + * \brief File information structure. + * + * Contains the normal, preview and audio file information structures + * for a specific file. + */ +typedef struct _CameraFileInfo { + CameraFileInfoPreview preview; + CameraFileInfoFile file; + CameraFileInfoAudio audio; +} CameraFileInfo; + +/** + * \brief Storage information flags. + * + * Bitmask to specify which entries of the filesystem + * storage information is set. + */ +typedef enum { + GP_STORAGEINFO_BASE = (1<<0), /**< \brief The base directory. + * Usually / if just 1 storage is attached. + */ + GP_STORAGEINFO_LABEL = (1<<1), /**< \brief Label of the filesystem. + * Could also be a DOS label. + */ + GP_STORAGEINFO_DESCRIPTION = (1<<2), /**< \brief More verbose description. */ + GP_STORAGEINFO_ACCESS = (1<<3), /**< \brief Access permissions. */ + GP_STORAGEINFO_STORAGETYPE = (1<<4), /**< \brief Hardware type. */ + GP_STORAGEINFO_FILESYSTEMTYPE = (1<<5), /**< \brief Filesystem type. */ + GP_STORAGEINFO_MAXCAPACITY = (1<<6), /**< \brief Maximum capacity in kbytes */ + GP_STORAGEINFO_FREESPACEKBYTES = (1<<7), /**< \brief Free space in kbytes. */ + GP_STORAGEINFO_FREESPACEIMAGES = (1<<8) /**< \brief Free space in images. */ +} CameraStorageInfoFields; + +/** + * \brief Hardware storage types. + * + * Type of hardware this storage is on. The types and values + * are the same as the PTP standard uses (PTP_ST_xxx). + */ +typedef enum { + GP_STORAGEINFO_ST_UNKNOWN = 0, /**< \brief Unknown storage type. */ + GP_STORAGEINFO_ST_FIXED_ROM = 1, /**< \brief A fixed ROM storage. */ + GP_STORAGEINFO_ST_REMOVABLE_ROM = 2, /**< \brief A removable ROM storage. */ + GP_STORAGEINFO_ST_FIXED_RAM = 3, /**< \brief A fixed RAM storage. (e.g. SDRAM) */ + GP_STORAGEINFO_ST_REMOVABLE_RAM = 4 /**< \brief A removable RAM storage. (any kind of cards etc) */ +} CameraStorageType; + +/** + * \brief Storage access modes. + * + * The modes we can access the storage with. Uses the same + * types and values as the PTP standard (PTP_AC_xxx). + */ +typedef enum { + GP_STORAGEINFO_AC_READWRITE = 0, /**< \brief Storage is Read / Write. */ + GP_STORAGEINFO_AC_READONLY = 1, /**< \brief Storage is Ready Only. */ + GP_STORAGEINFO_AC_READONLY_WITH_DELETE = 2 /**< \brief Storage is Ready Only, but allows Delete.*/ +} CameraStorageAccessType; + +/** + * \brief Filesystem hierarchy types. + * + * The type of the filesystem hierarchy the devices uses. + * Same types and values as the PTP standard defines (PTP_FST_xxx). + */ +typedef enum { + GP_STORAGEINFO_FST_UNDEFINED = 0, /**< \brief Undefined or unknown filesystem hierarchy. */ + GP_STORAGEINFO_FST_GENERICFLAT = 1, /**< \brief Generic flat storage (all in 1 directory). */ + GP_STORAGEINFO_FST_GENERICHIERARCHICAL = 2, /**< \brief Generic tree hierarchy. */ + GP_STORAGEINFO_FST_DCF = 3 /**< \brief DCIM style storage. */ +} CameraStorageFilesystemType; + +/** + * \brief Storage information structue. + * + * This structure contains the information of a specific camera storage. + * Only the members as specified by the \a fields member are valid. + */ +typedef struct _CameraStorageInformation { + CameraStorageInfoFields fields; /**< \brief Bitmask of struct members that are specified. */ + char basedir[256]; /**< \brief Basedirectory of the storage. Will be "/" if just 1 storage on the camera. */ + char label[256]; /**< \brief Label of the storage. Similar to DOS label. */ + char description[256];/**< \brief Description of the storage. */ + CameraStorageType type; /**< \brief Hardware type of the storage. */ + CameraStorageFilesystemType fstype; /**< \brief Hierarchy type of the filesystem. */ + CameraStorageAccessType access; /**< \brief Access permissions. */ + uint64_t capacitykbytes; /**< \brief Total capacity in kbytes. */ + uint64_t freekbytes; /**< \brief Free space in kbytes. */ + uint64_t freeimages; /**< \brief Free space in images (guessed by camera). */ +} CameraStorageInformation; + +/** + * \brief Filesystem structure, only exposed to camera drivers. + * + * Internal structure, contents not exposed to frontends. Camera + * drivers get these passed to filesystem related functions and + * are supposed to use it only via the accessor functions. + */ +typedef struct _CameraFilesystem CameraFilesystem; + +int gp_filesystem_new (CameraFilesystem **fs); +int gp_filesystem_free (CameraFilesystem *fs); + +/* Manual editing */ +int gp_filesystem_append (CameraFilesystem *fs, const char *folder, + const char *filename, GPContext *context); +int gp_filesystem_set_info_noop (CameraFilesystem *fs, + const char *folder, const char *filename, + CameraFileInfo info, GPContext *context); +int gp_filesystem_set_info_dirty (CameraFilesystem *fs, + const char *folder, const char *filename, + GPContext *context); +int gp_filesystem_set_file_noop (CameraFilesystem *fs, + const char *folder, const char *filename, + CameraFileType type, + CameraFile *file, GPContext *context); +int gp_filesystem_delete_file_noop (CameraFilesystem *fs, const char *folder, + const char *filename, GPContext *context); +int gp_filesystem_reset (CameraFilesystem *fs); + +/* Information retrieval */ +int gp_filesystem_count (CameraFilesystem *fs, const char *folder, + GPContext *context); +int gp_filesystem_name (CameraFilesystem *fs, const char *folder, + int filenumber, const char **filename, + GPContext *context); +int gp_filesystem_get_folder (CameraFilesystem *fs, const char *filename, + char **folder, GPContext *context); +int gp_filesystem_number (CameraFilesystem *fs, const char *folder, + const char *filename, GPContext *context); + +/* Listings */ +typedef int (*CameraFilesystemListFunc) (CameraFilesystem *fs, + const char *folder, CameraList *list, + void *data, GPContext *context); +int gp_filesystem_list_files (CameraFilesystem *fs, const char *folder, + CameraList *list, GPContext *context); +int gp_filesystem_list_folders (CameraFilesystem *fs, const char *folder, + CameraList *list, GPContext *context); + +/* File information */ +typedef int (*CameraFilesystemSetInfoFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + CameraFileInfo info, void *data, + GPContext *context); +typedef int (*CameraFilesystemGetInfoFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + CameraFileInfo *info, void *data, + GPContext *context); +int gp_filesystem_get_info (CameraFilesystem *fs, const char *folder, + const char *filename, CameraFileInfo *info, + GPContext *context); +int gp_filesystem_set_info (CameraFilesystem *fs, const char *folder, + const char *filename, CameraFileInfo info, + GPContext *context); + +/* Files */ +typedef int (*CameraFilesystemGetFileFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + CameraFileType type, + CameraFile *file, void *data, + GPContext *context); +typedef int (*CameraFilesystemReadFileFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + CameraFileType type, + uint64_t offset, + char *buf, + uint64_t *size, + void *data, + GPContext *context); +typedef int (*CameraFilesystemDeleteFileFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + void *data, GPContext *context); +int gp_filesystem_get_file (CameraFilesystem *fs, const char *folder, + const char *filename, CameraFileType type, + CameraFile *file, GPContext *context); +int gp_filesystem_read_file (CameraFilesystem *fs, const char *folder, + const char *filename, CameraFileType type, + uint64_t offset, char *buf, uint64_t *size, + GPContext *context); +int gp_filesystem_delete_file (CameraFilesystem *fs, const char *folder, + const char *filename, GPContext *context); + +/* Folders */ +typedef int (*CameraFilesystemPutFileFunc) (CameraFilesystem *fs, + const char *folder, + const char *filename, + CameraFileType type, + CameraFile *file, + void *data, + GPContext *context); +typedef int (*CameraFilesystemDeleteAllFunc) (CameraFilesystem *fs, + const char *folder, void *data, + GPContext *context); +typedef int (*CameraFilesystemDirFunc) (CameraFilesystem *fs, + const char *folder, + const char *name, void *data, + GPContext *context); + +typedef int (*CameraFilesystemStorageInfoFunc) (CameraFilesystem *fs, + CameraStorageInformation **, + int *nrofstorageinformations, + void *data, GPContext *context); + +int gp_filesystem_get_storageinfo (CameraFilesystem *fs, + CameraStorageInformation **, + int *nrofstorageinformations, + GPContext *context); + +typedef struct _CameraFilesystemFuncs CameraFilesystemFuncs; +struct _CameraFilesystemFuncs { + CameraFilesystemListFunc file_list_func; + CameraFilesystemListFunc folder_list_func; + CameraFilesystemPutFileFunc put_file_func; + CameraFilesystemDeleteAllFunc delete_all_func; + CameraFilesystemGetInfoFunc get_info_func; + CameraFilesystemSetInfoFunc set_info_func; + CameraFilesystemDirFunc make_dir_func; + CameraFilesystemDirFunc remove_dir_func; + CameraFilesystemGetFileFunc get_file_func; + CameraFilesystemReadFileFunc read_file_func; + CameraFilesystemDeleteFileFunc del_file_func; + CameraFilesystemStorageInfoFunc storage_info_func; + + /* for later use. Remove one if you add a new function */ + void *unused[31]; +}; +int gp_filesystem_set_funcs (CameraFilesystem *fs, + CameraFilesystemFuncs *funcs, + void *data); +int gp_filesystem_put_file (CameraFilesystem *fs, const char *folder, const char *filename, + CameraFileType type, CameraFile *file, GPContext *context); +int gp_filesystem_delete_all (CameraFilesystem *fs, const char *folder, + GPContext *context); +int gp_filesystem_make_dir (CameraFilesystem *fs, const char *folder, + const char *name, GPContext *context); +int gp_filesystem_remove_dir (CameraFilesystem *fs, const char *folder, + const char *name, GPContext *context); + +/* For debugging */ +int gp_filesystem_dump (CameraFilesystem *fs); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_FILESYS_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-library.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-library.h new file mode 100644 index 00000000..3c93fbbd --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-library.h @@ -0,0 +1,80 @@ +/** \file + * \brief Camery driver header. + * + * \author Copyright 2000 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_LIBRARY_H +#define LIBGPHOTO2_GPHOTO2_LIBRARY_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Returns a unique id for the camera driver. + * + * \param id a #CameraText + * \return a gphoto2 error code + * + **/ +typedef int (* CameraLibraryIdFunc) (CameraText *id); + +/** + * \brief Adds the abilities of the supported models to the supplied list. + * + * \param list a #CameraAbilitiesList + * \return a gphoto2 error code + * + **/ +typedef int (* CameraLibraryAbilitiesFunc) (CameraAbilitiesList *list); + +/** + * \brief Initializes the camera. + * + * \param camera a #Camera + * \param context a #GPContext + * \return a gphoto2 error code + * + * The camera driver will establish a first connection + * to the camera and configure the camera variable (i.e. using + * #gp_filesystem_set_list_funcs or #gp_port_get_settings). + * + **/ +typedef int (* CameraLibraryInitFunc) (Camera *camera, GPContext *context); + +/* + * If you want to write a camera library, you need to implement + * the following three functions. Everything else should be declared + * as static. + */ +int camera_id (CameraText *id); +int camera_abilities (CameraAbilitiesList *list); +int camera_init (Camera *camera, GPContext *context); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_LIBRARY_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-list.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-list.h new file mode 100644 index 00000000..f47e02f2 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-list.h @@ -0,0 +1,93 @@ +/** \file gphoto2-list.h + * + * Lists of files, folders, cameras, etc. + * + * \author Copyright 2001 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_LIST_H +#define LIBGPHOTO2_GPHOTO2_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief A generic list + * + * This structure provides a list with \a name:value pairs that is used in various + * parts of libgphoto2. Its details are internal, please use the + * gp_list_xxx accessor functions. + * + * Usage pattern for CameraList for users external of + * libgphoto2, such as libgphoto2 frontends: + * + * \code + * CameraList *list; + * gp_list_new (&list); + * init_list_somehow (list); + * for (i=0; i < gp_list_count(list); i++) { + * char *name, *value; + * gp_list_get_name (list, i, &name); + * gp_list_get_name (list, i, &value); + * do_something_with (name, value); + * } + * gp_list_free (list); + * \endcode + * + * Please do NOT directly instantiate a CameraList object like this: + * \code + * CameraList foo; // DO NOT DO THIS + * \endcode + * + * Please do NOT directly access the structure members like this: + * \code + * list->entry[i].name // DO NOT DO THIS + * \endcode + */ +typedef struct _CameraList CameraList; + +int gp_list_new (CameraList **list); +int gp_list_ref (CameraList *list); +int gp_list_unref (CameraList *list); +int gp_list_free (CameraList *list); + +int gp_list_count (CameraList *list); +int gp_list_append (CameraList *list, + const char *name, const char *value); +int gp_list_reset (CameraList *list); +int gp_list_sort (CameraList *list); + +int gp_list_find_by_name (CameraList *list, int *index, const char *name); + +int gp_list_get_name (CameraList *list, int index, const char **name); +int gp_list_get_value (CameraList *list, int index, const char **value); + +int gp_list_set_name (CameraList *list, int index, const char *name); +int gp_list_set_value (CameraList *list, int index, const char *value); + +int gp_list_populate (CameraList *list, const char *format, int count); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_LIST_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-info-list.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-info-list.h new file mode 100644 index 00000000..53f9ef39 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-info-list.h @@ -0,0 +1,116 @@ +/** \file + * + * \author Copyright 2001 Lutz Mueller + * + * \par License + * This library 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 2 of the License, or (at your option) any later version. + * + * \par + * This library 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. + * + * \par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_INFO_LIST_H +#define LIBGPHOTO2_GPHOTO2_PORT_INFO_LIST_H + +/** + * \brief The gphoto port type. + * + * Enumeration specifying the port type. + * The enum is providing bitmasks, but most code uses it as + * just the one specific values. + */ +typedef enum { + GP_PORT_NONE = 0, /**< \brief No specific type associated. */ + GP_PORT_SERIAL = 1 << 0, /**< \brief Serial port. */ + GP_PORT_USB = 1 << 2, /**< \brief USB port. */ + GP_PORT_DISK = 1 << 3, /**< \brief Disk / local mountpoint port. */ + GP_PORT_PTPIP = 1 << 4, /**< \brief PTP/IP port. */ + GP_PORT_USB_DISK_DIRECT = 1 << 5, /**< \brief Direct IO to an usb mass storage device. */ + GP_PORT_USB_SCSI = 1 << 6, /**< \brief USB Mass Storage raw SCSI port. */ + GP_PORT_IP = 1 << 7 /**< \brief generic IP address port. */ +} GPPortType; + +/** + * \brief Information about the current port. + * + * Specific information about the current port. Usually taken from the + * "--port=XXXX" setting from the frontend. + * + * This is not to be confused with the driver configurable port settings + * in \ref GPPortSettings. + */ +struct _GPPortInfo; +typedef struct _GPPortInfo *GPPortInfo; + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef _GPHOTO2_INTERNAL_CODE +#include +extern const StringFlagItem gpi_gphoto_port_type_map[]; +#endif + +int gp_port_info_new (GPPortInfo *info); +int gp_port_info_get_name (GPPortInfo info, char **name); +int gp_port_info_set_name (GPPortInfo info, const char *name); +int gp_port_info_get_path (GPPortInfo info, char **path); +int gp_port_info_set_path (GPPortInfo info, const char *path); +int gp_port_info_get_type (GPPortInfo info, GPPortType *type); +int gp_port_info_set_type (GPPortInfo info, const GPPortType type); +int gp_port_info_get_library_filename (GPPortInfo info, char **lib); +int gp_port_info_set_library_filename (GPPortInfo info, char *lib); + +/* Internals are private */ +typedef struct _GPPortInfoList GPPortInfoList; + +int gp_port_info_list_new (GPPortInfoList **list); +int gp_port_info_list_free (GPPortInfoList *list); + +int gp_port_info_list_append (GPPortInfoList *list, GPPortInfo info); + +int gp_port_info_list_load (GPPortInfoList *list); + +int gp_port_info_list_count (GPPortInfoList *list); + +int gp_port_info_list_lookup_path (GPPortInfoList *list, const char *path); +int gp_port_info_list_lookup_name (GPPortInfoList *list, const char *name); + +int gp_port_info_list_get_info (GPPortInfoList *list, int n, GPPortInfo *info); + +const char *gp_port_message_codeset (const char*); + +int gp_port_init_localedir (const char *localedir); + + +/** + * Name of the environment variable which may contain the path where + * to look for the IO libs. If this environment variable is not defined, + * use the compiled-in default constant. + * + * \internal Internal use only. + */ +#ifdef _GPHOTO2_INTERNAL_CODE +#define IOLIBDIR_ENV "IOLIBS" +#endif /* _GPHOTO2_INTERNAL_CODE */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_INFO_LIST_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-library.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-library.h new file mode 100644 index 00000000..be92ba30 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-library.h @@ -0,0 +1,103 @@ +/** \file gphoto2-port-library.h + * + * \author Copyright 2001 Lutz Mueller + * + * \par License + * This library 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 2 of the License, or (at your option) any later version. + * + * \par + * This library 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. + * + * \par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_LIBRARY_H +#define LIBGPHOTO2_GPHOTO2_PORT_LIBRARY_H + +#include +#include + +/** + * \brief The port operations + * + * These operations are to be implemented and set by the port library, + * which drives the lowlevel protocol (serial, usb, etc.). + * + * They are acessed using the accessor functions, like gp_port_open(), + * gp_port_read() and gp_port_write(). + */ +typedef struct _GPPortOperations { + int (*init) (GPPort *); + int (*exit) (GPPort *); + int (*open) (GPPort *); + int (*close) (GPPort *); + int (*read) (GPPort *, char *, int); + int (*check_int)(GPPort *, char *, int, int); + int (*write) (GPPort *, const char *, int); + int (*update) (GPPort *); + + /* Pointers to devices. Please note these are stubbed so there is + no need to #ifdef GP_PORT_* anymore. */ + + /* for serial devices */ + int (*get_pin) (GPPort *, GPPin, GPLevel*); + int (*set_pin) (GPPort *, GPPin, GPLevel); + int (*send_break)(GPPort *, int); + int (*flush) (GPPort *, int); + + /* for USB devices */ + int (*find_device)(GPPort * dev, int idvendor, int idproduct); + int (*find_device_by_class)(GPPort * dev, int class, int subclass, int protocol); + int (*clear_halt) (GPPort * dev, int ep); + int (*msg_write) (GPPort * dev, int request, int value, int index, + char *bytes, int size); + int (*msg_read) (GPPort * dev, int request, int value, int index, + char *bytes, int size); + int (*msg_interface_write) (GPPort * dev, int request, + int value, int index, char *bytes, int size); + int (*msg_interface_read) (GPPort * dev, int request, + int value, int index, char *bytes, int size); + int (*msg_class_write) (GPPort * dev, int request, + int value, int index, char *bytes, int size); + int (*msg_class_read) (GPPort * dev, int request, + int value, int index, char *bytes, int size); + + /* For USB disk direct IO devices */ + int (*seek) (GPPort * dev, int offset, int whence); + + /* For USB Mass Storage raw SCSI ports */ + int (*send_scsi_cmd) (GPPort *port, int to_dev, + char *cmd, int cmd_size, + char *sense, int sense_size, + char *data, int data_size); + + int (*reset) (GPPort *); + +} GPPortOperations; + +typedef GPPortType (* GPPortLibraryType) (void); +typedef int (* GPPortLibraryList) (GPPortInfoList *list); + +typedef GPPortOperations *(* GPPortLibraryOperations) (void); + +/* + * If you want to write an io library, you need to implement the following + * functions. Everything else in your io library should be declared static. + */ + +GPPortType gp_port_library_type (void); +int gp_port_library_list (GPPortInfoList *list); + +GPPortOperations *gp_port_library_operations (void); + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_LIBRARY_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-log.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-log.h new file mode 100644 index 00000000..217115a5 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-log.h @@ -0,0 +1,247 @@ +/** \file gphoto2-port-log.h + * + * Copyright 2001 Lutz Mueller + * + * This library 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 2 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_LOG_H +#define LIBGPHOTO2_GPHOTO2_PORT_LOG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Logging level + * Specifies the logging severity level. + */ +typedef enum { + GP_LOG_ERROR = 0, /**< \brief Log message is an error information. */ + GP_LOG_VERBOSE = 1, /**< \brief Log message is an verbose debug information. */ + GP_LOG_DEBUG = 2, /**< \brief Log message is an debug information. */ + GP_LOG_DATA = 3 /**< \brief Log message is a data hex dump. */ +} GPLogLevel; + +/** + * GP_LOG_ALL: + * + * Used by frontends if they want to be sure their + * callback function receives all messages. Defined + * as the highest debug level. Can make frontend code + * more understandable and extension of log levels + * easier. + **/ +#define GP_LOG_ALL GP_LOG_DATA + +/** + * \brief Logging function hook + * + * This is the function frontends can use to receive logging information + * from the libgphoto2 framework. It is set using gp_log_add_func() and + * removed using gp_log_remove_func() and will then receive the logging + * messages of the level specified. + * + * \param level the log level of the passed message, as set by the camera driver or libgphoto2 + * \param domain the logging domain as set by the camera driver, or libgphoto2 function + * \param str the logmessage, without linefeed + * \param data the caller private data that was passed to gp_log_add_func() + */ +typedef void (* GPLogFunc) (GPLogLevel level, const char *domain, const char *str, void *data); + +#ifndef DISABLE_DEBUGGING + +int gp_log_add_func (GPLogLevel level, GPLogFunc func, void *data); +int gp_log_remove_func (int id); + +/* Logging */ +void gp_log (GPLogLevel level, const char *domain, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,3,4))) +#endif +; +void gp_log_with_source_location( + GPLogLevel level, const char *file, int line, const char *func, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,5,6))) +#endif +; +void gp_logv (GPLogLevel level, const char *domain, const char *format, + va_list args) +#ifdef __GNUC__ + __attribute__((__format__(printf,3,0))) +#endif +; +void gp_log_data (const char *domain, const char *data, unsigned int size, + const char *format, ...) +#ifdef __GNUC__ +__attribute__((__format__(printf,4,5))) +#endif +; + +/* + * GP_DEBUG: + * msg: message to log + * params: params to message + * + * Logs message at log level #GP_LOG_DEBUG by calling #gp_log() with + * an automatically generated domain + * You have to define GP_MODULE as "mymod" for your module + * mymod before using #GP_DEBUG(). + */ + +#ifdef _GPHOTO2_INTERNAL_CODE +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || _MSC_VER +#define GP_DEBUG(...) \ + gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, __VA_ARGS__) + +/* + * GP_LOG_D/E: + * simple helper macros for convenient and consistent logging of error + * and debug messages including information about the source location. + */ +#define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__) +#define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__) + +#elif defined(__GNUC__) && __GNUC__ >= 2 +#define GP_DEBUG(msg, params...) \ + gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, msg, ##params) +/* + * GP_LOG_D/E: + * simple helper macros for convenient and consistent logging of error + * and debug messages including information about the source location. + */ +#define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__) +#define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__) + +#else +# ifdef __GNUC__ +# warning Disabling GP_DEBUG because variadic macros are not allowed +# endif +#define GP_DEBUG (void) +#define GP_LOG_D(...) /* no-op */ +#define GP_LOG_E(...) /* no-op */ +#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ +#endif +#endif /* _GPHOTO2_INTERNAL_CODE */ + +#else /* DISABLE_DEBUGGING */ + +/* Stub these functions out if debugging is disabled */ +#define gp_log_add_func(level, func, data) (0) +#define gp_log_remove_func(id) (0) +#define gp_log(level, domain, format, args...) /**/ +#define gp_log_with_source_location(level, file, line, func, format, ...) +#define gp_logv(level, domain, format, args) /**/ +#define gp_log_data(domain, data, size) /**/ + +#ifdef _GPHOTO2_INTERNAL_CODE +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define GP_DEBUG(...) /* no-op */ +#define GP_LOG_D(...) /* no-op */ +#define GP_LOG_E(...) /* no-op */ +#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ + +#elif defined(__GNUC__) +#define GP_DEBUG(msg, params...) /* no-op */ +#define GP_LOG_D(...) /* no-op */ +#define GP_LOG_E(...) /* no-op */ +#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ +#else +#define GP_DEBUG (void) +#define GP_LOG_D (void /* no-op */ +#define GP_LOG_E (void) /* no-op */ +#define GP_LOG_DATA(void) /* no-op */ +#endif +#endif /* _GPHOTO2_INTERNAL_CODE */ + +#endif /* DISABLE_DEBUGGING */ + +#ifdef _GPHOTO2_INTERNAL_CODE + + typedef struct StringFlagItem { + char *str; + unsigned int flag; + } StringFlagItem; + + typedef void (*string_item_func) (const char *str, void *data); + + const char * + gpi_enum_to_string(const unsigned int _enum, + const StringFlagItem *map); + + int + gpi_string_to_enum(const char *str, + unsigned int *result, + const StringFlagItem *map); + + void + gpi_flags_to_string_list(const unsigned int flags, + const StringFlagItem *map, + string_item_func func, void *data); + + int + gpi_string_or_to_flags(const char *str, + unsigned int *flags, + const StringFlagItem *map); + + unsigned int + gpi_string_to_flag(const char *str, + const StringFlagItem *map); + + unsigned int + gpi_string_list_to_flags(const char *str[], + const StringFlagItem *map); + + /* Allocates a sufficiently large buffer and interpolates the format + * string with the proveded va_list args. The returned memory has to + * be freed by the caller. */ + char* + gpi_vsnprintf (const char* format, va_list args); + +#define C_MEM(MEM) do {\ + if ((MEM) == NULL) {\ + GP_LOG_E ("Out of memory: '%s' failed.", #MEM);\ + return GP_ERROR_NO_MEMORY;\ + }\ +} while(0) + +#define C_PARAMS(PARAMS) do {\ + if (!(PARAMS)) {\ + GP_LOG_E ("Invalid parameters: '%s' is NULL/FALSE.", #PARAMS);\ + return GP_ERROR_BAD_PARAMETERS;\ + }\ +} while(0) + +#define C_PARAMS_MSG(PARAMS, MSG, ...) do {\ + if (!(PARAMS)) {\ + GP_LOG_E ("Invalid parameters: " #MSG " ('%s' is NULL/FALSE.)", ##__VA_ARGS__, #PARAMS);\ + return GP_ERROR_BAD_PARAMETERS;\ + }\ +} while(0) + +#endif /* _GPHOTO2_INTERNAL_CODE */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_LOG_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-portability.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-portability.h new file mode 100644 index 00000000..eda81289 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-portability.h @@ -0,0 +1,149 @@ +/** \file gphoto2-port-log.h + * + * Copyright 2001 Lutz Mueller + * + * This library 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 2 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_PORTABILITY_H +#define LIBGPHOTO2_GPHOTO2_PORT_PORTABILITY_H + +#ifdef _GPHOTO2_INTERNAL_CODE + +#if defined(WIN32) && !defined(__WINESRC__) + +/************************************************************************ + * Begin Windows definitions (but not during WINE compilation) + ************************************************************************/ + +# include +/* done by mingw/wine headers ... defined to struct ... tsaes*/ +#undef interface +# include +# include +# include +# include +# include + +# ifndef IOLIBS +# define IOLIBS "." +# endif +# define strcasecmp _stricmp +# ifndef snprintf +# define snprintf _snprintf +# endif + +#define __func__ __FUNCTION__ + +#ifndef _SSIZE_T_DEFINED +typedef SSIZE_T ssize_t; +#endif + +/* Work-around for readdir() */ +typedef struct { + HANDLE handle; + int got_first; + WIN32_FIND_DATA search; + char dir[1024]; + char drive[32][2]; + int drive_count; + int drive_index; +} GPPORTWINDIR; + + +/* Directory-oriented functions */ +# define gp_system_dir GPPORTWINDIR * +# define gp_system_dirent WIN32_FIND_DATA * +# define gp_system_dir_delim '\\' + +# define sleep(x) usleep((x) * 1000 * 1000) + + + +/************************************************************************ + * End WIN32 definitions + ************************************************************************/ + +#else + +/************************************************************************ + * Begin POSIX/XOPEN definitions + ************************************************************************/ + +/* yummy. :) */ + +/* XOPEN needed for usleep */ +#ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +#else +# if ((_XOPEN_SOURCE - 0) < 500) +# undef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif +#endif + +/* for nanosleep */ +# ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 199309 +# endif +# include + +# include +# include +# include +#ifdef HAVE_SYS_PARAM_H +# include +#endif +# include +# include + + +/* Directory-oriented functions */ +/** A system directory handle */ +# define gp_system_dir DIR * +/** A system directory entry */ +# define gp_system_dirent struct dirent * +/** The directory delimiter character on this platform. */ +# define gp_system_dir_delim '/' + +/************************************************************************ + * End POSIX/XOPEN definitions + ************************************************************************/ + +#endif /* else */ + + +/************************************************************************ + * Begin platform independent portability functions + ************************************************************************/ + +int gp_system_mkdir (const char *dirname); +int gp_system_rmdir (const char *dirname); +gp_system_dir gp_system_opendir (const char *dirname); +gp_system_dirent gp_system_readdir (gp_system_dir d); +const char* gp_system_filename (gp_system_dirent de); +int gp_system_closedir (gp_system_dir dir); +int gp_system_is_file (const char *filename); +int gp_system_is_dir (const char *dirname); + +/************************************************************************ + * End platform independent portability functions + ************************************************************************/ +#endif /* _GPHOTO2_INTERNAL_CODE */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_PORTABILITY_H) */ + +/* end of file */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-result.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-result.h new file mode 100644 index 00000000..319a73b1 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-result.h @@ -0,0 +1,133 @@ +/** \file gphoto2-port-result.h + * + * Copyright 2001 Lutz Mueller + * + * This library 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 2 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_RESULT_H +#define LIBGPHOTO2_GPHOTO2_PORT_RESULT_H + +/* Return values. gphoto2-port should only return values from 0 to -99 */ +/** + * \brief Everything is OK + * + * Note that this is also the value 0, and every error is negative (lower). + */ +#define GP_OK 0 +/** + * \brief Generic Error + */ +#define GP_ERROR -1 +/** + * \brief Bad parameters passed + */ +#define GP_ERROR_BAD_PARAMETERS -2 +/** + * \brief Out of memory + */ +#define GP_ERROR_NO_MEMORY -3 +/** + * \brief Error in the camera driver + */ +#define GP_ERROR_LIBRARY -4 +/** + * \brief Unknown libgphoto2 port passed + */ +#define GP_ERROR_UNKNOWN_PORT -5 +/** + * \brief Functionality not supported + */ +#define GP_ERROR_NOT_SUPPORTED -6 +/** + * \brief Generic I/O error + */ +#define GP_ERROR_IO -7 +/** + * \brief Buffer overflow of internal structure + */ +#define GP_ERROR_FIXED_LIMIT_EXCEEDED -8 +/** + * \brief Operation timed out + */ +#define GP_ERROR_TIMEOUT -10 + +/** + * \brief Serial ports not supported + */ +#define GP_ERROR_IO_SUPPORTED_SERIAL -20 +/** + * \brief USB ports not supported + */ +#define GP_ERROR_IO_SUPPORTED_USB -21 + +/** + * \brief Error initializing I/O + */ +#define GP_ERROR_IO_INIT -31 +/** + * \brief I/O during read + */ +#define GP_ERROR_IO_READ -34 +/** + * \brief I/O during write + */ +#define GP_ERROR_IO_WRITE -35 +/** + * \brief I/O during update of settings + */ +#define GP_ERROR_IO_UPDATE -37 + +/** + * \brief Specified serial speed not possible. + */ +#define GP_ERROR_IO_SERIAL_SPEED -41 + +/** + * \brief Error during USB Clear HALT + */ +#define GP_ERROR_IO_USB_CLEAR_HALT -51 +/** + * \brief Error when trying to find USB device + */ +#define GP_ERROR_IO_USB_FIND -52 +/** + * \brief Error when trying to claim the USB device + */ +#define GP_ERROR_IO_USB_CLAIM -53 + +/** + * \brief Error when trying to lock the device + */ +#define GP_ERROR_IO_LOCK -60 + +/** + * \brief Unspecified error when talking to HAL + */ +#define GP_ERROR_HAL -70 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +const char *gp_port_result_as_string (int result); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_RESULT_H) */ + diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-version.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-version.h new file mode 100644 index 00000000..3a11e792 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port-version.h @@ -0,0 +1,48 @@ +/** \file gphoto2-port-version.h + * + * Copyright 2002 Hans Ulrich Niedermann + * + * This library 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 2 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_VERSION_H +#define LIBGPHOTO2_GPHOTO2_PORT_VERSION_H + +typedef enum { + GP_VERSION_SHORT = 0, + GP_VERSION_VERBOSE = 1 +} GPVersionVerbosity; + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef const char **(*GPVersionFunc)(GPVersionVerbosity verbose); +const char **gp_port_library_version(GPVersionVerbosity verbose); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_VERSION_H) */ + +/* + * Local Variables: + * c-file-style:"linux" + * indent-tabs-mode:t + * End: + */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-port.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port.h new file mode 100644 index 00000000..e75d3859 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-port.h @@ -0,0 +1,256 @@ +/** \file + * + * \author Copyright 2001 Lutz Mueller + * + * \par License + * This library 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 2 of the License, or (at your option) any later version. + * + * \par + * This library 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. + * + * \par + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_PORT_H +#define LIBGPHOTO2_GPHOTO2_PORT_H + +#include + +/* For portability */ +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef TRUE +#define TRUE (0==0) +#endif + +#ifndef FALSE +#define FALSE (1==0) +#endif + +/** + * \brief Serial parity + * + * Parity of the serial port. + */ +typedef enum _GPPortSerialParity +{ + GP_PORT_SERIAL_PARITY_OFF = 0, /**< \brief Parity is off (disabled) */ + GP_PORT_SERIAL_PARITY_EVEN, /**< \brief Parity is even. */ + GP_PORT_SERIAL_PARITY_ODD /**< \brief Parity is odd. */ +} GPPortSerialParity; + +/** \brief Maximum length of receive buffer */ +#define GP_PORT_MAX_BUF_LEN 4096 + +/** + * \brief Port settings for serial ports. + */ +typedef struct _GPPortSettingsSerial { + char port[128]; /**< The portname (/dev/ttyX)*/ + int speed; /**< The baudrate of the device. */ + int bits; /**< How many bits data. */ + GPPortSerialParity parity; /**< parity data, see GP_PORT_SERIAL_PARITY_ + defines */ + int stopbits; /**< How many stop bits are used. */ +} GPPortSettingsSerial; + +/** + * \brief Port settings for USB ports. + */ +#ifdef interface +#undef interface +#define _RESTORE_INTERFACE +#endif +typedef struct _GPPortSettingsUSB { + int inep; /**< \brief Bulk IN endpoint used. */ + int outep; /**< \brief Bulk OUT endpoint used. */ + int intep; /**< \brief Interrupt endpoint used. */ + int config; /**< \brief USB bConfigurationValue used. */ + int interface; /**< \brief USB Interface number used. */ + int altsetting; /**< \brief USB Alternative Setting used. */ + + int maxpacketsize; /**< \brief Maximum USB packetsize of the IN endpoint. (r/o) */ + + /* must be last to avoid binary incompatibility. + * luckily we just need to make sure this struct does not + * get larger than _GPPortSettingsSerial. */ + char port[64]; /**< \brief USB Portname. Specific to lowlevel USB. */ +} GPPortSettingsUSB; +#ifdef _RESTORE_INTERFACE +#define interface __STRUCT__ +#undef _RESTORE_INTERFACE +#endif + +/** + * \brief Port settings for USB mass storage direct IO ports. + */ +typedef struct _GPPortSettingsUsbDiskDirect { + char path[128]; /**< /brief The ports device node path (/dev/sdX)*/ +} GPPortSettingsUsbDiskDirect; + +/** + * \brief Port settings for USB Mass Storage raw SCSI ports. + */ +typedef struct _GPPortSettingsUsbScsi { + char path[128]; /**< /brief The ports device node path (/dev/sg#)*/ +} GPPortSettingsUsbScsi; + +/** + * \brief Union of port settings. + * + * This contains a shared union of possible settings for ports needing + * them. + */ +typedef union _GPPortSettings { + GPPortSettingsSerial serial; /**< \brief Serial specific settings */ + GPPortSettingsUSB usb; /**< \brief USB specific settings */ + GPPortSettingsUsbDiskDirect usbdiskdirect; /**< \brief usb disk direct port specific settings */ + GPPortSettingsUsbScsi usbscsi; /**< \brief usb scsi port specific settings */ +} GPPortSettings; + +enum { + GP_PORT_USB_ENDPOINT_IN, /**< \brief USB bulk IN ep */ + GP_PORT_USB_ENDPOINT_OUT, /**< \brief USB bulk OUT ep */ + GP_PORT_USB_ENDPOINT_INT /**< \brief USB Interrupt ep */ +}; + +typedef struct _GPPortPrivateLibrary GPPortPrivateLibrary; +typedef struct _GPPortPrivateCore GPPortPrivateCore; + +/** + * \brief The GPhoto port structure. + * + * This structure tracks the physical connection of the device. + * It can correspond the various methods of lowlevel access, serial + * usb and others and abstracts them as much as possible. + * + * Frontends should consider this structure opaque and only use accessor + * functions. + * + * Camera drivers should only access the type and pl members directly, + * and use accessor functions for the rest. + */ +typedef struct _GPPort { + /* For your convenience */ + GPPortType type; /**< \brief Actual type of this port */ + + GPPortSettings settings; /**< \brief Current port settings. */ + GPPortSettings settings_pending;/**< \brief Settings to be committed. */ + + int timeout; /**< \brief Port timeout in milliseconds. */ + + GPPortPrivateLibrary *pl; /**< \brief Camera driver private data pointer. */ + GPPortPrivateCore *pc; /**< \brief Port library private data pointer. */ +} GPPort; + +int gp_port_new (GPPort **port); +int gp_port_free (GPPort *port); + +int gp_port_set_info (GPPort *port, GPPortInfo info); +int gp_port_get_info (GPPort *port, GPPortInfo *info); + +int gp_port_open (GPPort *port); +int gp_port_close (GPPort *port); + +int gp_port_reset (GPPort *port); + +int gp_port_write (GPPort *port, const char *data, int size); +int gp_port_read (GPPort *port, char *data, int size); +int gp_port_check_int (GPPort *port, char *data, int size); +int gp_port_check_int_fast (GPPort *port, char *data, int size); + +int gp_port_get_timeout (GPPort *port, int *timeout); +int gp_port_set_timeout (GPPort *port, int timeout); + +int gp_port_set_settings (GPPort *port, GPPortSettings settings); +int gp_port_get_settings (GPPort *port, GPPortSettings *settings); + +/** + * \brief Serial pins. + * + * A number of serial pins to trigger and pull. This is necessary + * for some devices that have more than just the regular 3 or 4 wires. + */ +typedef enum _GPPin { + GP_PIN_RTS, /**< \brief RTS line */ + GP_PIN_DTR, /**< \brief DTR line */ + GP_PIN_CTS, /**< \brief CTS line */ + GP_PIN_DSR, /**< \brief DSR line */ + GP_PIN_CD, /**< \brief Carrier Detect line */ + GP_PIN_RING /**< \brief RING (Modem) line */ +} GPPin; + +/** + * \brief Level to pull specific lines. + * + * The level on which to pull some of the serial lines. + */ +typedef enum _GPLevel { + GP_LEVEL_LOW = 0, /**< \brief Pull to low (0V) */ + GP_LEVEL_HIGH = 1 /**< \brief Pull to high (nV) */ +} GPLevel; + +int gp_port_get_pin (GPPort *port, GPPin pin, GPLevel *level); +int gp_port_set_pin (GPPort *port, GPPin pin, GPLevel level); + +int gp_port_send_break (GPPort *port, int duration); +int gp_port_flush (GPPort *port, int direction); + +int gp_port_usb_find_device (GPPort *port, int idvendor, int idproduct); +int gp_port_usb_find_device_by_class (GPPort *port, int mainclass, int subclass, int protocol); +int gp_port_usb_clear_halt (GPPort *port, int ep); +int gp_port_usb_msg_write (GPPort *port, int request, int value, + int index, char *bytes, int size); +int gp_port_usb_msg_read (GPPort *port, int request, int value, + int index, char *bytes, int size); +int gp_port_usb_msg_interface_write (GPPort *port, int request, + int value, int index, char *bytes, int size); +int gp_port_usb_msg_interface_read (GPPort *port, int request, + int value, int index, char *bytes, int size); +int gp_port_usb_msg_class_write (GPPort *port, int request, + int value, int index, char *bytes, int size); +int gp_port_usb_msg_class_read (GPPort *port, int request, + int value, int index, char *bytes, int size); + +int gp_port_seek (GPPort *port, int offset, int whence); + +int gp_port_send_scsi_cmd (GPPort *port, int to_dev, + char *cmd, int cmd_size, + char *sense, int sense_size, + char *data, int data_size); + +/* Error reporting */ +int gp_port_set_error (GPPort *port, const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,2,3))) +#endif +; +const char *gp_port_get_error (GPPort *port); + +/* DEPRECATED */ +/** \deprecated internal typedef */ +typedef GPPort gp_port; +/** \deprecated internal typedef */ +typedef GPPortSettings gp_port_settings; +/** \deprecated internal define */ +#define PIN_CTS GP_PIN_CTS + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_PORT_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-result.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-result.h new file mode 100644 index 00000000..0a669770 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-result.h @@ -0,0 +1,141 @@ +/** \file + * + * \author Copyright 2000 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_RESULT_H +#define LIBGPHOTO2_GPHOTO2_RESULT_H + +/* Additional error codes are defined here */ +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Corrupted data received + * + * Data is corrupt. This error is reported by camera drivers if corrupted + * data has been received that can not be automatically handled. Normally, + * drivers will do everything possible to automatically recover from this + * error. + **/ +#define GP_ERROR_CORRUPTED_DATA -102 /* Corrupted data */ + +/** + * \brief File already exists + * + * An operation failed because a file existed. This error is reported for + * example when the user tries to create a file that already exists. + **/ +#define GP_ERROR_FILE_EXISTS -103 + +/** + * \brief Specified camera model was not found + * + * The specified model could not be found. This error is reported when + * the user specified a model that does not seem to be supported by + * any driver. + **/ +#define GP_ERROR_MODEL_NOT_FOUND -105 + +/** + * \brief Specified directory was not found + * + * The specified directory could not be found. This error is reported when + * the user specified a directory that is non-existent. + **/ +#define GP_ERROR_DIRECTORY_NOT_FOUND -107 + +/** + * \brief Specified file was not found + * + * The specified file could not be found. This error is reported when + * the user wants to access a file that is non-existent. + **/ +#define GP_ERROR_FILE_NOT_FOUND -108 + +/** + * \brief Specified directory already exists + * + * The specified directory already exists. This error is reported for example + * when the user wants to create a directory that already exists. + **/ +#define GP_ERROR_DIRECTORY_EXISTS -109 + +/** + * \brief The camera is already busy + * + * Camera I/O or a command is in progress. + **/ +#define GP_ERROR_CAMERA_BUSY -110 + +/** + * \brief Path is not absolute + * + * The specified path is not absolute. This error is reported when the user + * specifies paths that are not absolute, i.e. paths like "path/to/directory". + * As a rule of thumb, in gphoto2, there is nothing like relative paths. + **/ +#define GP_ERROR_PATH_NOT_ABSOLUTE -111 + +/** + * \brief Cancellation successful. + * + * A cancellation requestion by the frontend via progress callback and + * GP_CONTEXT_FEEDBACK_CANCEL was successful and the transfer has been aborted. + */ +#define GP_ERROR_CANCEL -112 + +/** + * \brief Unspecified camera error + * + * The camera reported some kind of error. This can be either a + * photographic error, such as failure to autofocus, underexposure, or + * violating storage permission, anything else that stops the camera + * from performing the operation. + */ +#define GP_ERROR_CAMERA_ERROR -113 + +/** + * \brief Unspecified failure of the operating system + * + * There was some sort of OS error in communicating with the camera, + * e.g. lack of permission for an operation. + */ +#define GP_ERROR_OS_FAILURE -114 + +/** + * \brief Not enough space + * + * There was not enough free space when uploading a file. + */ +#define GP_ERROR_NO_SPACE -115 + + +const char *gp_result_as_string (int result); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_RESULT_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-setting.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-setting.h new file mode 100644 index 00000000..34c6d894 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-setting.h @@ -0,0 +1,38 @@ +/** \file + * + * \author Copyright 2000 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_SETTING_H +#define LIBGPHOTO2_GPHOTO2_SETTING_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int gp_setting_set (char *id, char *key, char *value); +int gp_setting_get (char *id, char *key, char *value); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_SETTING_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-version.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-version.h new file mode 100644 index 00000000..f13f0a93 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-version.h @@ -0,0 +1,39 @@ +/** \file + * + * \author Copyright 2002 Hans Ulrich Niedermann + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_VERSION_H +#define LIBGPHOTO2_GPHOTO2_VERSION_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const char **gp_library_version(GPVersionVerbosity verbose); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_VERSION_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2-widget.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2-widget.h new file mode 100644 index 00000000..9b200592 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2-widget.h @@ -0,0 +1,133 @@ +/** \file + * + * \author Copyright 2000 Scott Fritzinger + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_WIDGET_H +#define LIBGPHOTO2_GPHOTO2_WIDGET_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** \brief internal structure please use the accessors. */ +typedef struct _CameraWidget CameraWidget; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \brief Type of the widget to be created. + * + * The actual widget type we want to create. The type of the value + * it supports depends on this type. + */ +typedef enum { /* Value (get/set): */ + GP_WIDGET_WINDOW, /**< \brief Window widget + * This is the toplevel configuration widget. It should likely contain multiple #GP_WIDGET_SECTION entries. + */ + GP_WIDGET_SECTION, /**< \brief Section widget (think Tab) */ + GP_WIDGET_TEXT, /**< \brief Text widget. */ /* char * */ + GP_WIDGET_RANGE, /**< \brief Slider widget. */ /* float */ + GP_WIDGET_TOGGLE, /**< \brief Toggle widget (think check box) */ /* int */ + GP_WIDGET_RADIO, /**< \brief Radio button widget. */ /* char * */ + GP_WIDGET_MENU, /**< \brief Menu widget (same as RADIO). */ /* char * */ + GP_WIDGET_BUTTON, /**< \brief Button press widget. */ /* CameraWidgetCallback */ + GP_WIDGET_DATE /**< \brief Date entering widget. */ /* int */ +} CameraWidgetType; + +/** + * \brief Callback handler for Button widgets. + */ +typedef int (* CameraWidgetCallback) (Camera *, CameraWidget *, GPContext *); + +int gp_widget_new (CameraWidgetType type, const char *label, + CameraWidget **widget); +int gp_widget_free (CameraWidget *widget); +int gp_widget_ref (CameraWidget *widget); +int gp_widget_unref (CameraWidget *widget); + +int gp_widget_append (CameraWidget *widget, CameraWidget *child); +int gp_widget_prepend (CameraWidget *widget, CameraWidget *child); + +int gp_widget_count_children (CameraWidget *widget); +int gp_widget_get_child (CameraWidget *widget, int child_number, + CameraWidget **child); + +/* Retrieve Widgets */ +int gp_widget_get_child_by_label (CameraWidget *widget, + const char *label, + CameraWidget **child); +int gp_widget_get_child_by_id (CameraWidget *widget, int id, + CameraWidget **child); +int gp_widget_get_child_by_name (CameraWidget *widget, + const char *name, + CameraWidget **child); +int gp_widget_get_root (CameraWidget *widget, + CameraWidget **root); +int gp_widget_get_parent (CameraWidget *widget, + CameraWidget **parent); + +int gp_widget_set_value (CameraWidget *widget, const void *value); +int gp_widget_get_value (CameraWidget *widget, void *value); + +int gp_widget_set_name (CameraWidget *widget, const char *name); +int gp_widget_get_name (CameraWidget *widget, const char **name); + +int gp_widget_set_info (CameraWidget *widget, const char *info); +int gp_widget_get_info (CameraWidget *widget, const char **info); + +int gp_widget_get_id (CameraWidget *widget, int *id); +int gp_widget_get_type (CameraWidget *widget, CameraWidgetType *type); +int gp_widget_get_label (CameraWidget *widget, const char **label); + +int gp_widget_set_range (CameraWidget *range, + float low, float high, float increment); +int gp_widget_get_range (CameraWidget *range, + float *min, float *max, float *increment); + +int gp_widget_add_choice (CameraWidget *widget, const char *choice); +int gp_widget_count_choices (CameraWidget *widget); +int gp_widget_get_choice (CameraWidget *widget, int choice_number, + const char **choice); + +int gp_widget_changed (CameraWidget *widget); +int gp_widget_set_changed (CameraWidget *widget, int changed); + +int gp_widget_set_readonly (CameraWidget *widget, int readonly); +int gp_widget_get_readonly (CameraWidget *widget, int *readonly); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_WIDGET_H) */ diff --git a/thirdparty/libgphoto2/include/gphoto2/gphoto2.h b/thirdparty/libgphoto2/include/gphoto2/gphoto2.h new file mode 100644 index 00000000..60009682 --- /dev/null +++ b/thirdparty/libgphoto2/include/gphoto2/gphoto2.h @@ -0,0 +1,50 @@ +/** \file + * \brief Convenience header for gphoto2 + * + * \author Copyright 2001 Lutz Mueller + * + * \note + * This library 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 2 of the License, or (at your option) any later version. + * + * \note + * This library 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. + * + * \note + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LIBGPHOTO2_GPHOTO2_H +#define LIBGPHOTO2_GPHOTO2_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +#ifndef CAMLIBS +#define CAMLIBS "." +#endif +#endif + +#include +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(LIBGPHOTO2_GPHOTO2_H) */ diff --git a/thirdparty/libgphoto2/lib/compat.lib b/thirdparty/libgphoto2/lib/compat.lib new file mode 100644 index 00000000..b0406e6e --- /dev/null +++ b/thirdparty/libgphoto2/lib/compat.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5025eb63955e6e6d519201cdaed07cdd643986bb252a4def291024df0aeb18dc +size 286818 diff --git a/thirdparty/libgphoto2/lib/libgphoto2.exp b/thirdparty/libgphoto2/lib/libgphoto2.exp new file mode 100644 index 00000000..dff05b05 Binary files /dev/null and b/thirdparty/libgphoto2/lib/libgphoto2.exp differ diff --git a/thirdparty/libgphoto2/lib/libgphoto2.lib b/thirdparty/libgphoto2/lib/libgphoto2.lib new file mode 100644 index 00000000..b21cf3fc --- /dev/null +++ b/thirdparty/libgphoto2/lib/libgphoto2.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c609ae08ac863b9f2a8882d42aa909a11d3166a9a335c7195b939779846865a +size 41162 diff --git a/thirdparty/libgphoto2/lib/libgphoto2_port.exp b/thirdparty/libgphoto2/lib/libgphoto2_port.exp new file mode 100644 index 00000000..38d8c505 Binary files /dev/null and b/thirdparty/libgphoto2/lib/libgphoto2_port.exp differ diff --git a/thirdparty/libgphoto2/lib/libgphoto2_port.lib b/thirdparty/libgphoto2/lib/libgphoto2_port.lib new file mode 100644 index 00000000..cb47087a --- /dev/null +++ b/thirdparty/libgphoto2/lib/libgphoto2_port.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0037541e5c2f83f806ff5d78486262d7c1d27ffaf3515858f0e2ba292a4726d6 +size 18208 diff --git a/toonz/sources/CMakeLists.txt b/toonz/sources/CMakeLists.txt index c9adbf70..0034aa94 100644 --- a/toonz/sources/CMakeLists.txt +++ b/toonz/sources/CMakeLists.txt @@ -108,6 +108,7 @@ endif() option(WITH_SYSTEM_LZO "Use the system LZO library instead of 'thirdpary'" ${_init_SYSTEM_LZO}) option(WITH_SYSTEM_SUPERLU "Use the system SuperLU library instead of 'thirdpary'" ${_init_SYSTEM_SUPERLU}) option(WITH_CANON "Build with Canon DSLR support - Requires Canon SDK" OFF) +option(WITH_GPHOTO2 "Build with Libgphoto2" OFF) option(WITH_TRANSLATION "Generate translation projects as well" ON) option(WITH_CRASHRPT "Build CrashRpt support - Requires CrashRpt Library" OFF) option(WITH_WINTAB "(Windows only) Build with customized Qt with WinTab support. https://github.com/shun-iwasawa/qt5/releases/tag/v5.15.2_wintab" OFF) @@ -287,6 +288,12 @@ if(BUILD_ENV_MSVC) ${SDKROOT}/crashrpt/include ) endif() + + if(WITH_GPHOTO2) + include_directories( + ${SDKROOT}/libgphoto2/include + ) + endif() endif() if(BUILD_ENV_MSVC) @@ -394,6 +401,12 @@ if(BUILD_ENV_MSVC) if(WITH_CRASHRPT) set(CRASHRPT_LIB ${SDKROOT}/crashrpt/CrashRpt1500.lib) endif() + + if(WITH_GPHOTO2) + set(GPHOTO2_LIB ${SDKROOT}/libgphoto2/lib/libgphoto2.lib) + set(GPHOTO2_PORT_LIB ${SDKROOT}/libgphoto2/lib/libgphoto2_port.lib) + set(GPHOTO2_COMPAT_LIB ${SDKROOT}/libgphoto2/lib/compat.lib) + endif() elseif(BUILD_ENV_APPLE) find_library(GLUT_LIB GLUT) find_library(GL_LIB OpenGL) @@ -455,6 +468,12 @@ elseif(BUILD_ENV_APPLE) endif() endif() + if(WITH_GPHOTO2) + find_library(GPHOTO2_LIB gphoto2) + message("**************** gphoto2 lib:" ${GPHOTO2_LIB}) + find_library(GPHOTO2_PORT_LIB gphoto2_port) + message("**************** gphoto2_port lib:" ${GPHOTO2_PORT_LIB}) + endif() elseif(BUILD_ENV_UNIXLIKE) if(BUILD_TARGET_WIN) find_library(GL_LIB opengl32) @@ -521,6 +540,13 @@ elseif(BUILD_ENV_UNIXLIKE) find_library(TURBOJPEG_LIB turbojpeg) message("**************** turbojpeg lib:" ${TURBOJPEG_LIB}) + + if(WITH_GPHOTO2) + find_library(GPHOTO2_LIB gphoto2) + message("**************** gphoto2 lib:" ${GPHOTO2_LIB}) + find_library(GPHOTO2_PORT_LIB gphoto2_port) + message("**************** gphoto2_port lib:" ${GPHOTO2_PORT_LIB}) + endif() endif() diff --git a/toonz/sources/scripts/AppRun b/toonz/sources/scripts/AppRun new file mode 100644 index 00000000..b7b96066 --- /dev/null +++ b/toonz/sources/scripts/AppRun @@ -0,0 +1,14 @@ +#!/bin/bash + +DIR="`dirname \"$0\"`" +DIR="`( cd \"$DIR\" && readlink -f $(pwd) )`" +echo "DIR: $DIR" +export APPDIR=$DIR + +export CAMLIBS=`find $APPDIR/usr/lib/libgphoto2 -mindepth 1 -type d` +echo "CAMLIBS: $CAMLIBS" + +export IOLIBS=`find $APPDIR/usr/lib/libgphoto2_port -mindepth 1 -type d` +echo "IOLIBS: $IOLIBS" + +$APPDIR/usr/bin/Tahoma2D diff --git a/toonz/sources/stopmotion/canon.cpp b/toonz/sources/stopmotion/canon.cpp index 09957543..81a86cc9 100644 --- a/toonz/sources/stopmotion/canon.cpp +++ b/toonz/sources/stopmotion/canon.cpp @@ -90,6 +90,8 @@ EdsError Canon::releaseCameraList() { //----------------------------------------------------------------- int Canon::getCameraCount() { + m_count = 0; + if (m_cameraList == NULL) { getCameraList(); } @@ -102,9 +104,9 @@ int Canon::getCameraCount() { m_sessionOpen = false; } } - return m_count; - } else - return -1; + } + + return m_count; } //----------------------------------------------------------------- @@ -158,7 +160,7 @@ void Canon::resetCanon(bool liveViewOpen) { if (m_sessionOpen && getCameraCount() > 0) { if (liveViewOpen) { - endCanonLiveView(); + endLiveView(); } closeCameraSession(); } @@ -1056,7 +1058,7 @@ void Canon::extendCameraOnTime() { //----------------------------------------------------------------- -EdsError Canon::startCanonLiveView() { +EdsError Canon::startLiveView() { if (m_camera && m_sessionOpen) { EdsError err = EDS_ERR_OK; // Get the output device for the live view image @@ -1083,7 +1085,7 @@ EdsError Canon::startCanonLiveView() { //----------------------------------------------------------------- -EdsError Canon::endCanonLiveView() { +EdsError Canon::endLiveView() { EdsError err = EDS_ERR_OK; // Get the output device for the live view image EdsUInt32 device; diff --git a/toonz/sources/stopmotion/canon.h b/toonz/sources/stopmotion/canon.h index 3e3c0afc..a685c24f 100644 --- a/toonz/sources/stopmotion/canon.h +++ b/toonz/sources/stopmotion/canon.h @@ -85,7 +85,6 @@ public: EdsUInt32 m_liveViewZoom = 1; bool m_isSDKLoaded = false; bool m_sessionOpen = false; - bool m_zooming = false; std::string m_cameraName; TPoint m_liveViewZoomOffset = TPoint(0, 0); bool m_liveViewZoomReadyToPick = true; @@ -97,6 +96,7 @@ public: #endif TDimension m_proxyImageDimensions = TDimension(0, 0); bool m_converterSucceeded = false; + bool m_zooming = false; bool m_pickLiveViewZoom = false; TDimension m_fullImageDimensions = TDimension(0, 0); int m_liveViewExposureOffset = 0; @@ -104,6 +104,10 @@ public: QString m_displayedShutterSpeed; QString m_imageQuality; cv::Mat m_canonImage; + int m_canonIndex = -1; + + void setCanonIndex(int index) { m_canonIndex = index; } + int getCanonIndex() { return m_canonIndex; } bool m_useCalibration; cv::Mat m_calibrationMapX, m_calibrationMapY; @@ -135,8 +139,8 @@ public: EdsError closeCameraSession(); bool downloadImage(EdsBaseRef object); EdsError takePicture(); - EdsError startCanonLiveView(); - EdsError endCanonLiveView(); + EdsError startLiveView(); + EdsError endLiveView(); bool downloadEVFData(); QStringList getIsoOptions() { return m_isoOptions; } QStringList getShutterSpeedOptions() { return m_shutterSpeedOptions; } diff --git a/toonz/sources/stopmotion/gphotocam.cpp b/toonz/sources/stopmotion/gphotocam.cpp new file mode 100644 index 00000000..1b762cfa --- /dev/null +++ b/toonz/sources/stopmotion/gphotocam.cpp @@ -0,0 +1,1617 @@ +#include "gphotocam.h" +#include "stopmotion.h" +#include "tapp.h" + +#include "toonz/tscenehandle.h" +#include "toonz/tcamera.h" +#include "toonz/toonzscene.h" +#include "toonz/stage.h" + +#include +#include + +#if defined(_WIN32) +#include +#else +#include +#endif +#include + +#define EVENTTIMER_INTERVAL 40 +#define DOGPSLEEP_INTERVAL 100 + +void doGPSleep(int ms) { + if (ms <= 0) return; + +#ifdef Q_OS_WIN + Sleep(uint(ms)); +#else + struct timespec ts = {ms / 1000, (ms % 1000) * 1000 * 1000}; + nanosleep(&ts, NULL); +#endif +} + +#ifdef WITH_GPHOTO2 +#include + +//----------------------------------------------------------------------------- + +static void logdump(GPLogLevel level, const char *domain, const char *str, + void *data) { + if (level == GP_LOG_ERROR) + qDebug() << "[GP_ERROR] " << QString(str); + else if (level == GP_LOG_VERBOSE) { + qDebug() << "[GP_VERBOSE] " << QString(str); + } else if (level == GP_LOG_DEBUG) { + qDebug() << "[GP_DEBUG] " << QString(str); + } else if (level == GP_LOG_DATA) { + qDebug() << "[GP_DATA] " << QString(str); + } else + qDebug() << "[GP_UNKNOWN] " << QString(str); +} +#endif + +//----------------------------------------------------------------------------- + +GPhotoCam::GPhotoCam() { + m_count = 0; + m_gphotoIndex = -1; + m_sessionOpen = false; + + m_eventTimer = new QTimer(this); + m_capturePreview = false; + m_captureImage = false; + m_previewImageReady = false; + +#ifdef WITH_GPHOTO2 + m_cameraListMaster = NULL; + m_portInfoList = NULL; + m_cameraListDetected = NULL; + m_camera = NULL; + m_cameraImageFilePath = new CameraFilePath; + + m_gpContext = gp_context_new(); + gp_log_add_func(GP_LOG_ERROR, logdump, NULL); + + // Load all the camera drivers we have... + int retVal = gp_abilities_list_new(&m_cameraListMaster); + if (retVal >= GP_OK) gp_abilities_list_load(m_cameraListMaster, m_gpContext); + + // Load all the port drivers we have... + retVal = gp_port_info_list_new(&m_portInfoList); + if (retVal >= GP_OK) gp_port_info_list_load(m_portInfoList); + + gp_file_new(&m_previewFile); + connect(m_eventTimer, SIGNAL(timeout()), this, SLOT(onTimeout())); +#endif +} + +//----------------------------------------------------------------------------- + +GPhotoCam::~GPhotoCam() { +#ifdef WITH_GPHOTO2 + gp_file_unref(m_previewFile); +#endif +} + +int GPhotoCam::getCameraCount() { + m_count = 0; + +#ifdef WITH_GPHOTO2 + if (m_cameraListDetected == NULL) + gp_list_new(&m_cameraListDetected); + else + gp_list_reset(m_cameraListDetected); + + if (m_cameraListDetected != NULL) { + m_count = gp_camera_autodetect(m_cameraListDetected, m_gpContext); + if (m_count < 0) m_count = 0; + } +#endif + + return m_count; +} + +//----------------------------------------------------------------------------- + +void GPhotoCam::resetGphotocam(bool liveViewOpen) { +#ifdef WITH_GPHOTO2 + m_proxyImageDimensions = TDimension(0, 0); + + if (m_sessionOpen && getCameraCount() > 0) { + if (liveViewOpen) { + endLiveView(); + } + closeCameraSession(); + } + +#endif +} + +//----------------------------------------------------------------- + +void GPhotoCam::loadCameraConfigKeys(QString manufacturer) { + int i = sizeof(cameraConfigKeys) - 1; + + if (manufacturer.contains("Canon")) + i = 0; + else if (manufacturer.contains("Nikon")) + i = 1; + + m_configKeys.modeKey = cameraConfigKeys[i].keys.modeKey; + m_configKeys.batteryLevelKey = cameraConfigKeys[i].keys.batteryLevelKey; + m_configKeys.shutterSpeedKey = cameraConfigKeys[i].keys.shutterSpeedKey; + m_configKeys.apertureKey = cameraConfigKeys[i].keys.apertureKey; + m_configKeys.isoKey = cameraConfigKeys[i].keys.isoKey; + m_configKeys.whiteBalanceKey = cameraConfigKeys[i].keys.whiteBalanceKey; + m_configKeys.pictureStyleKey = cameraConfigKeys[i].keys.pictureStyleKey; + m_configKeys.imageQualityKey = cameraConfigKeys[i].keys.imageQualityKey; + m_configKeys.imageSizeKey = cameraConfigKeys[i].keys.imageSizeKey; + m_configKeys.exposureCompensationKey = + cameraConfigKeys[i].keys.exposureCompensationKey; + m_configKeys.colorTemperatureKey = + cameraConfigKeys[i].keys.colorTemperatureKey; + m_configKeys.manualFocusDriveKey = + cameraConfigKeys[i].keys.manualFocusDriveKey; + m_configKeys.afPositionKey = cameraConfigKeys[i].keys.afPositionKey; + m_configKeys.viewfinderKey = cameraConfigKeys[i].keys.viewfinderKey; + m_configKeys.focusPointKey = cameraConfigKeys[i].keys.focusPointKey; +} + +//----------------------------------------------------------------- + +enum EventTrigger { + NoTrigger = 0, + BatteryLevel, + ImageSize, + ImageQuality, + Whitebalance, + Aperture, + ShutterSpeed, + Mode, + ISO, + ExposureCompensation, + PictureStyle, + ColorTemperature +}; + +EventTrigger checkEventCode(QString manufacturer, char *evtdata) { + // Generic + if (strstr(evtdata, "5001")) return EventTrigger::BatteryLevel; + if (strstr(evtdata, "5003")) return EventTrigger::ImageSize; + if (strstr(evtdata, "5004")) return EventTrigger::ImageQuality; + if (strstr(evtdata, "5005")) return EventTrigger::Whitebalance; + if (strstr(evtdata, "5007")) return EventTrigger::Aperture; + if (strstr(evtdata, "500d")) return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "500e")) return EventTrigger::Mode; + if (strstr(evtdata, "500f")) return EventTrigger::ISO; + if (strstr(evtdata, "5010")) return EventTrigger::ExposureCompensation; + + if (manufacturer.contains("Canon")) { + if (strstr(evtdata, "d005") || strstr(evtdata, "d105") || + strstr(evtdata, "d138")) + return EventTrigger::Mode; + if (strstr(evtdata, "d006") || strstr(evtdata, "d120")) + return EventTrigger::ImageQuality; + if (strstr(evtdata, "d008")) return EventTrigger::ImageSize; + if (strstr(evtdata, "d013") || strstr(evtdata, "d109")) + return EventTrigger::Whitebalance; + if (strstr(evtdata, "d01c") || strstr(evtdata, "d103")) + return EventTrigger::ISO; + if (strstr(evtdata, "d01d") || strstr(evtdata, "d101")) + return EventTrigger::Aperture; + if (strstr(evtdata, "d01e") || strstr(evtdata, "d102")) + return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "d01f") || strstr(evtdata, "d104")) + return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "d10a")) return EventTrigger::ColorTemperature; + if (strstr(evtdata, "d110")) return EventTrigger::PictureStyle; + if (strstr(evtdata, "d111") || strstr(evtdata, "d1a6")) + return EventTrigger::BatteryLevel; + } else if (manufacturer.contains("Nikon")) { + if (strstr(evtdata, "d038")) return EventTrigger::Mode; + if (strstr(evtdata, "d058")) return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "f002") || strstr(evtdata, "d100")) + return EventTrigger::ISO; + if (strstr(evtdata, "f003") || strstr(evtdata, "d087")) + return EventTrigger::Aperture; + if (strstr(evtdata, "f004")) return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "f009") || strstr(evtdata, "d031")) + return EventTrigger::ImageQuality; + if (strstr(evtdata, "f00a")) return EventTrigger::ImageSize; + if (strstr(evtdata, "f00c")) return EventTrigger::Whitebalance; + } else if (manufacturer.contains("Kodak")) { + if (strstr(evtdata, "d001")) return EventTrigger::ColorTemperature; + } else if (manufacturer.contains("Fuji")) { + if (strstr(evtdata, "d218")) return EventTrigger::Aperture; + if (strstr(evtdata, "d242")) return EventTrigger::BatteryLevel; + if (strstr(evtdata, "d017")) return EventTrigger::ColorTemperature; + if (strstr(evtdata, "d018")) return EventTrigger::ImageQuality; + if (strstr(evtdata, "d219")) return EventTrigger::ShutterSpeed; + } else if (manufacturer.contains("Olympus")) { + if (strstr(evtdata, "d002")) return EventTrigger::Aperture; + if (strstr(evtdata, "d008")) return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "d00d")) return EventTrigger::ImageQuality; + if (strstr(evtdata, "d007")) return EventTrigger::ISO; + if (strstr(evtdata, "d01c")) return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "d01e")) return EventTrigger::Whitebalance; + } else if (manufacturer.contains("Panasonic")) { + if (strstr(evtdata, "02000040")) return EventTrigger::Aperture; + if (strstr(evtdata, "02000080")) return EventTrigger::Mode; + if (strstr(evtdata, "02000060")) return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "020000a2")) return EventTrigger::ImageQuality; + if (strstr(evtdata, "02000020")) return EventTrigger::ISO; + if (strstr(evtdata, "02000030")) return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "02000050")) return EventTrigger::Whitebalance; + } else if (manufacturer.contains("RICOH")) { + if (strstr(evtdata, "d00f")) return EventTrigger::ShutterSpeed; + } else if (manufacturer.contains("Sigma")) { + if (strstr(evtdata, "d002")) return EventTrigger::Aperture; + if (strstr(evtdata, "d006")) return EventTrigger::BatteryLevel; + if (strstr(evtdata, "d005")) return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "d004")) return EventTrigger::ISO; + if (strstr(evtdata, "d001")) return EventTrigger::ShutterSpeed; + } else if (manufacturer.contains("Sony")) { + if (strstr(evtdata, "d6c5")) return EventTrigger::Aperture; + if (strstr(evtdata, "d218") || strstr(evtdata, "d6f1")) + return EventTrigger::BatteryLevel; + if (strstr(evtdata, "d20f") || strstr(evtdata, "d6f0")) + return EventTrigger::ColorTemperature; + if (strstr(evtdata, "d224") || strstr(evtdata, "d6c3")) + return EventTrigger::ExposureCompensation; + if (strstr(evtdata, "d6b7")) return EventTrigger::ImageSize; + if (strstr(evtdata, "d203")) return EventTrigger::ImageQuality; + if (strstr(evtdata, "d21e") || strstr(evtdata, "d6f2")) + return EventTrigger::ISO; + if (strstr(evtdata, "d20d") || strstr(evtdata, "d6ea")) + return EventTrigger::ShutterSpeed; + if (strstr(evtdata, "d6b8")) return EventTrigger::Whitebalance; + } + + return EventTrigger::NoTrigger; +} + +//----------------------------------------------------------------- + +void GPhotoCam::onTimeout() { +#ifdef WITH_GPHOTO2 + bool debug = false; +#ifdef _MSC_VER + debug = true; +#endif + + CameraEventType evttype; + CameraFilePath *path; + void *evtdata; + int retVal; + + if (!m_gpContext || !m_camera || m_exitRequested) return; + + if (m_captureImage) { + m_captureImage = false; + + if (!isCanon() || m_cameraName.contains("450D") || + m_cameraName.contains("1000D") || m_cameraName.contains("40D")) { + // Nikon: Turn off autofocus from a libgphoto2 point of view. + // Does not work for Canon but may work for others. + retVal = gp_setting_set("ptp2", "autofocus", "off"); + retVal = gp_camera_trigger_capture(m_camera, m_gpContext); + } else { + retVal = setCameraConfigValue("eosremoterelease", "Immediate"); + if (retVal >= GP_OK) + setCameraConfigValue("eosremoterelease", "Release Full"); + } + } + + // Capture preview when enabled + if (m_capturePreview && !m_previewImageReady) { + retVal = gp_camera_capture_preview(m_camera, m_previewFile, m_gpContext); + m_previewImageReady = true; + } + + while (1) { + if (!m_gpContext || !m_camera || m_exitRequested) break; + + retVal = + gp_camera_wait_for_event(m_camera, 1, &evttype, &evtdata, m_gpContext); + if (retVal < GP_OK) break; + if (m_exitRequested) break; + + switch (evttype) { + case GP_EVENT_FILE_ADDED: + path = (CameraFilePath *)evtdata; + if (debug) + qDebug() << "[GphotoCamEventHandler] FILE ADDED ON CAMERA: " + << path->folder << "/" << path->name; + + m_cameraImageFilePath = path; + downloadImage(); + free(evtdata); + break; +#ifdef GP_EVENT_FILE_CHANGED + case GP_EVENT_FILE_CHANGED: + path = (CameraFilePath *)evtdata; + if (debug) + qDebug() << "[GphotoCamEventHandler] File CHANGED on the camera: " + << path->folder << "/" << path->name; + free(evtdata); + break; +#endif + case GP_EVENT_FOLDER_ADDED: + path = (CameraFilePath *)evtdata; + if (debug) + qDebug() << "[GphotoCamEventHandler] FOLDER ADDED ON CAMERA: " + << path->folder << "/" << path->name; + free(evtdata); + break; + case GP_EVENT_CAPTURE_COMPLETE: + if (debug) qDebug() << "[GphotoCamEventHandler] CAPTURE COMPLETE"; + break; + case GP_EVENT_TIMEOUT: + // if (debug) qDebug() << "[GphotoCamEventHandler] TIMEOUT"; + break; + case GP_EVENT_UNKNOWN: + if (evtdata) { + if (debug) + qDebug() << "[GphotoCamEventHandler] UNKNOWN EVENT: " + << (char *)evtdata; + + EventTrigger event = + checkEventCode(m_cameraManufacturer, (char *)evtdata); + + switch (event) { + case EventTrigger::BatteryLevel: { + QString value = getCameraConfigValue(m_configKeys.batteryLevelKey); + emit batteryChanged(); + break; + } + case EventTrigger::ImageSize: { + QString value = getCameraConfigValue(m_configKeys.imageQualityKey); + emit imageSizeChangedSignal(value); + break; + } + case EventTrigger::ImageQuality: { + QString value = getCameraConfigValue(m_configKeys.imageQualityKey); + emit imageQualityChangedSignal(value); + break; + } + case EventTrigger::Whitebalance: { + QString value = getCameraConfigValue(m_configKeys.whiteBalanceKey); + emit whiteBalanceChangedSignal(value); + break; + } + case EventTrigger::Aperture: { + QString value = getCameraConfigValue(m_configKeys.apertureKey); + emit apertureChangedSignal(value); + break; + } + case EventTrigger::ShutterSpeed: { + QString value = getCameraConfigValue(m_configKeys.shutterSpeedKey); + emit shutterSpeedChangedSignal(value); + break; + } + case EventTrigger::Mode: { + QString value = getCameraConfigValue(m_configKeys.modeKey); + emit modeChanged(); + break; + } + case EventTrigger::ISO: { + QString value = getCameraConfigValue(m_configKeys.isoKey); + emit isoChangedSignal(value); + break; + } + case EventTrigger::ExposureCompensation: { + QString value = + getCameraConfigValue(m_configKeys.exposureCompensationKey); + emit exposureChangedSignal(value); + break; + } + case EventTrigger::PictureStyle: { + QString value = getCameraConfigValue(m_configKeys.pictureStyleKey); + emit pictureStyleChangedSignal(value); + break; + } + case EventTrigger::ColorTemperature: { + QString value = + getCameraConfigValue(m_configKeys.colorTemperatureKey); + emit colorTemperatureChangedSignal(value); + break; + } + default: + break; + } + + free(evtdata); + } else if (debug) + qDebug() << "[GphotoCamEventHandler] UNKNOWN EVENT (no data)."; + break; + default: + if (debug) + qDebug() << "[GphotoCamEventHandler] DEFAULT EVENT - Type:" << evttype; + break; + } + if (evttype == GP_EVENT_TIMEOUT) break; + } +#endif +} + +//----------------------------------------------------------------- + +void GPhotoCam::onImageReady(const bool &status) { + m_converterSucceeded = status; +} + +//----------------------------------------------------------------- + +void GPhotoCam::onFinished() { l_quitLoop = true; } + +//----------------------------------------------------------------------------- + +#ifdef WITH_GPHOTO2 + +QString GPhotoCam::getCameraName(int index) { + if (!m_count) return 0; + + const char *name; + + gp_list_get_name(m_cameraListDetected, index, &name); + + m_cameraName = QString(name); + return m_cameraName; +} + +//----------------------------------------------------------------------------- + +bool GPhotoCam::getCamera(int index) { + if (!m_count) return false; + + int retVal = gp_camera_new(&m_camera); + + if (retVal < GP_OK) return false; + + const char *cameraName, *cameraPort; + gp_list_get_name(m_cameraListDetected, index, &cameraName); + gp_list_get_value(m_cameraListDetected, index, &cameraPort); + + // Set camera abilities + CameraAbilities abilities; + int abilityIndex = + gp_abilities_list_lookup_model(m_cameraListMaster, cameraName); + if (abilityIndex < 0) return false; + + retVal = gp_abilities_list_get_abilities(m_cameraListMaster, abilityIndex, + &abilities); + if (retVal < GP_OK) return false; + + retVal = gp_camera_set_abilities(m_camera, abilities); + if (retVal < GP_OK) { + gp_camera_unref(m_camera); + return false; + } + + // Set camera port + // Reload port list in case something changed + if (m_portInfoList) { + gp_port_info_list_free(m_portInfoList); + gp_port_info_list_new(&m_portInfoList); + } + + retVal = gp_port_info_list_load(m_portInfoList); + if (retVal < GP_OK) { + gp_camera_unref(m_camera); + return false; + } + + int portIndex = gp_port_info_list_lookup_path(m_portInfoList, cameraPort); + if (portIndex == GP_ERROR_UNKNOWN_PORT) { + gp_camera_unref(m_camera); + return false; + } + + retVal = gp_port_info_list_get_info(m_portInfoList, portIndex, &m_portInfo); + if (retVal < GP_OK) { + gp_camera_unref(m_camera); + return false; + } + + retVal = gp_camera_set_port_info(m_camera, m_portInfo); + if (retVal < GP_OK) { + gp_camera_unref(m_camera); + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- + +bool GPhotoCam::initializeCamera() { + if (!m_camera) return false; + + int retVal = gp_camera_init(m_camera, m_gpContext); + if (retVal < GP_OK) return false; + + m_cameraManufacturer = getCameraConfigValue("manufacturer"); + m_cameraModel = getCameraConfigValue("cameramodel"); + + loadCameraConfigKeys(m_cameraManufacturer); + + return true; +} + +//----------------------------------------------------------------------------- + +bool GPhotoCam::releaseCamera() { + int retVal = GP_OK; + + if (!m_camera) return retVal; + + if (m_eventTimer->isActive()) { + m_exitRequested = true; + // Give time for handler to stop + doGPSleep(DOGPSLEEP_INTERVAL); + + m_eventTimer->stop(); + } + + retVal = gp_camera_exit(m_camera, m_gpContext); + + m_exitRequested = false; + + m_camera = 0; + m_gphotoIndex = -1; + + return (retVal >= GP_OK); +} + +//----------------------------------------------------------------------------- + +bool GPhotoCam::openCameraSession() { + if (!m_camera) return false; + + m_sessionOpen = true; + + m_eventTimer->start(EVENTTIMER_INTERVAL); + + return true; +} + +//----------------------------------------------------------------------------- + +bool GPhotoCam::closeCameraSession() { + + m_sessionOpen = false; + + if (!m_camera) return true; + + if (m_liveViewExposureOffset != 0) { + setShutterSpeed(m_displayedShutterSpeed, false); + doGPSleep(DOGPSLEEP_INTERVAL); + } + + m_eventTimer->stop(); + + return true; +} + +//----------------------------------------------------------------------------- + +void GPhotoCam::closeAll() { +#ifdef WITH_GPHOTO2 + if (m_camera) releaseCamera(); +#endif +} + +//----------------------------------------------------------------- + +bool GPhotoCam::startLiveView() { + if (!m_camera || !m_sessionOpen) return false; + + int retVal = gp_camera_capture_preview(m_camera, m_previewFile, m_gpContext); + if (retVal < GP_OK) return false; + + m_capturePreview = true; + + m_previewImageReady = true; + + StopMotion::instance()->m_liveViewStatus = 1; + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::endLiveView() { + StopMotion::instance()->m_liveViewStatus = 0; + + m_capturePreview = false; + + bool status = setCameraConfigValue(m_configKeys.viewfinderKey, "0"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getGPhotocamImage() { + if (!m_camera || !m_capturePreview) return false; + + int retVal; + CameraFile *file = m_previewFile; + + if (!file || !m_previewImageReady) return false; + + const char *dataPtr; + unsigned long dataSize; + retVal = gp_file_get_data_and_size(file, &dataPtr, &dataSize); + if (retVal < GP_OK) { + m_previewImageReady = false; + return false; + } + + JpgConverter *converter = new JpgConverter; + converter->setDataPtr((unsigned char *)dataPtr, dataSize); + + connect(converter, SIGNAL(imageReady(bool)), this, SLOT(onImageReady(bool)), + Qt::QueuedConnection); + connect(converter, SIGNAL(finished()), this, SLOT(onFinished()), + Qt::QueuedConnection); + + converter->start(); + + while (!l_quitLoop) + QCoreApplication::processEvents(QEventLoop::AllEvents | + QEventLoop::WaitForMoreEvents); + + l_quitLoop = false; + StopMotion::instance()->m_liveViewImage = converter->getImage(); + StopMotion::instance()->m_hasLiveViewImage = true; + + m_previewImageReady = false; + + if (!m_converterSucceeded) return false; + + uchar *imgBuf = StopMotion::instance()->m_liveViewImage->getRawData(); + int height = StopMotion::instance()->m_liveViewImage->getLy(); + int width = StopMotion::instance()->m_liveViewImage->getLx(); + + cv::Mat imgData(height, width, CV_8UC4, (void *)imgBuf); + + // perform calibration + if (m_useCalibration) { + cv::remap(imgData, imgData, m_calibrationMapX, m_calibrationMapY, + cv::INTER_LINEAR); + } + + m_gPhotoImage = imgData; + + delete converter; + + QString focusPosition = getCameraConfigValue(m_configKeys.focusPointKey); + if (m_configKeys.focusPointKey == "focusinfo") { + int i = focusPosition.indexOf("size="); + i += 5; + int j = focusPosition.indexOf(",", i); + focusPosition = focusPosition.mid(i, (j - i)); + } + + QStringList sizeDimensions = focusPosition.split("x"); + if (sizeDimensions.size() > 1) { + m_fullImageDimensions = + TDimension(sizeDimensions.at(0).toInt(), sizeDimensions.at(1).toInt()); + m_zoomRectDimensions = + TPoint((m_fullImageDimensions.lx / 5), (m_fullImageDimensions.ly / 5)); + if (m_zoomRect == TRect(0, 0, 0, 0)) { + m_zoomRect = TRect(0, m_zoomRectDimensions.y, m_zoomRectDimensions.x, 0); + calculateZoomPoint(); + } + } + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::takePicture() { + if (m_liveViewExposureOffset != 0) { + bool status = setShutterSpeed(m_displayedShutterSpeed, false); + if (!status) { + DVGui::error(tr("An error occurred. Please try again.")); + return status; + } + doGPSleep(DOGPSLEEP_INTERVAL); + } + + m_captureImage = true; + return true; +} + +bool GPhotoCam::downloadImage() { + int fd, retVal; + CameraFile *file; + + QString imageFilename = m_cameraImageFilePath->name; + bool isRaw = (imageFilename.at(imageFilename.length() - 1) == '2'); + + QString filename = isRaw ? StopMotion::instance()->m_tempRaw + : StopMotion::instance()->m_tempFile; + + // Get image off the camera + QByteArray ba = filename.toLocal8Bit(); + const char *fn = ba.data(); +#ifdef WIN32 + fd = _open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644); +#else + fd = open(fn, O_CREAT | O_WRONLY, 0644); +#endif + + retVal = gp_file_new_from_fd(&file, fd); + if (retVal < GP_OK) return false; + + retVal = gp_camera_file_get(m_camera, m_cameraImageFilePath->folder, + m_cameraImageFilePath->name, GP_FILE_TYPE_NORMAL, + file, m_gpContext); + if (retVal < GP_OK) return false; + + retVal = gp_file_unref(file); + + retVal = gp_camera_file_delete(m_camera, m_cameraImageFilePath->folder, + m_cameraImageFilePath->name, m_gpContext); + + // Currently does not support creating images from Raw files + if (isRaw) { + return true; + } + + // Open file and process + retVal = gp_file_new(&file); + if (retVal < GP_OK) return false; + +#ifdef WIN32 + fd = _open(fn, O_RDONLY | O_BINARY); +#else + fd = open(fn, O_RDONLY); +#endif + + retVal = gp_file_new_from_fd(&file, fd); + if (retVal < GP_OK) return false; + + const char *dataPtr; + unsigned long dataSize; + + retVal = gp_file_get_data_and_size(file, &dataPtr, &dataSize); + if (retVal < GP_OK) return false; + + JpgConverter *converter = new JpgConverter; + converter->setDataPtr((unsigned char *)dataPtr, dataSize); + + connect(converter, SIGNAL(imageReady(bool)), this, SLOT(onImageReady(bool)), + Qt::QueuedConnection); + connect(converter, SIGNAL(finished()), this, SLOT(onFinished()), + Qt::QueuedConnection); + + converter->start(); + + while (!l_quitLoop) + QCoreApplication::processEvents(QEventLoop::AllEvents | + QEventLoop::WaitForMoreEvents); + + l_quitLoop = false; + TRaster32P tempImage = converter->getImage(); + + if (!m_converterSucceeded || !tempImage || tempImage->isEmpty()) return false; + + uchar *imgBuf = tempImage->getRawData(); + int height = tempImage->getLy(); + int width = tempImage->getLx(); + + // Get camera size info + TCamera *camera = + TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); + TDimension res = camera->getRes(); + if (m_proxyImageDimensions == TDimension(0, 0)) { + m_proxyImageDimensions = res; + } + + cv::Mat imgData(height, width, CV_8UC4, (void *)imgBuf); + + // perform calibration + if (m_useCalibration) { + cv::remap(imgData, imgData, m_calibrationMapX, m_calibrationMapY, + cv::INTER_LINEAR); + } + + m_gPhotoImage = imgData; + + // calculate the size of the new image + // and resize it down + double r = (double)width / (double)height; + cv::Size dim(m_proxyImageDimensions.lx, m_proxyImageDimensions.lx / r); + int newWidth = dim.width; + int newHeight = dim.height; + cv::Mat imgResized(dim, CV_8UC4); + cv::resize(imgData, imgResized, dim); + int newSize = imgResized.total() * imgResized.elemSize(); + uchar *resizedBuf = imgResized.data; + + // copy the image to m_newImage + StopMotion::instance()->m_newImage = TRaster32P(newWidth, newHeight); + StopMotion::instance()->m_newImage->lock(); + uchar *rawData = StopMotion::instance()->m_newImage->getRawData(); + memcpy(rawData, resizedBuf, newSize); + StopMotion::instance()->m_newImage->unlock(); + + gp_file_unref(file); + + emit(newGPhotocamImageReady()); + + delete converter; + + return true; +} + +//----------------------------------------------------------------- + +QStringList GPhotoCam::getCameraConfigList(const char *key) { + QStringList configList; + CameraWidget *widget = NULL, *child = NULL; + CameraWidgetType widgetType; + int retVal; + + if (!key) return configList; + + retVal = gp_camera_get_config(m_camera, &widget, m_gpContext); + if (retVal < GP_OK) return configList; + + retVal = gp_widget_get_child_by_name(widget, key, &child); + if (retVal < GP_OK) + retVal = gp_widget_get_child_by_label(widget, key, &child); + if (retVal < GP_OK) { + gp_widget_free(widget); + return configList; + } + + retVal = gp_widget_get_type(child, &widgetType); + if (retVal < GP_OK) { + gp_widget_free(widget); + return configList; + } + + switch (widgetType) { + case GP_WIDGET_MENU: + case GP_WIDGET_RADIO: { + int choices = gp_widget_count_choices(child); + for (int i = 0; i < choices; i++) { + const char *choice; + retVal = gp_widget_get_choice(child, i, &choice); + if (retVal < GP_OK) continue; + + configList.push_back(choice); + } + break; + } + case GP_WIDGET_RANGE: { + float rmin, rmax, rstep; + retVal = gp_widget_get_range(child, &rmin, &rmax, &rstep); + if (retVal < GP_OK) break; + + configList.push_back(QString::number(rmin)); + configList.push_back(QString::number(rmax)); + configList.push_back(QString::number(rstep)); + break; + } + default: + break; + } + + gp_widget_free(widget); + + return configList; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCameraConfigValue(const char *key) { + CameraWidget *widget = NULL, *child = NULL; + CameraWidgetType widgetType; + int retVal; + + QString currentValue = "-"; + + if (!key) return currentValue; + + retVal = gp_camera_get_single_config(m_camera, key, &child, m_gpContext); + if (retVal == GP_OK) + widget = child; + else { + retVal = gp_camera_get_config(m_camera, &widget, m_gpContext); + if (retVal < GP_OK) return currentValue; + + retVal = gp_widget_get_child_by_name(widget, key, &child); + if (retVal < GP_OK) + retVal = gp_widget_get_child_by_label(widget, key, &child); + if (retVal < GP_OK) { + gp_widget_free(widget); + return currentValue; + } + } + + retVal = gp_widget_get_type(child, &widgetType); + if (retVal < GP_OK) { + gp_widget_free(widget); + return currentValue; + } + + switch (widgetType) { + case GP_WIDGET_MENU: + case GP_WIDGET_RADIO: + case GP_WIDGET_TEXT: { + char *cvalue; + retVal = gp_widget_get_value(child, &cvalue); + if (retVal >= GP_OK) currentValue = cvalue; + break; + } + case GP_WIDGET_RANGE: { + float fvalue; + retVal = gp_widget_get_value(child, &fvalue); + if (retVal >= GP_OK) currentValue = QString::number(fvalue); + break; + } + case GP_WIDGET_TOGGLE: { + int ivalue; + retVal = gp_widget_get_value(child, &ivalue); + if (retVal >= GP_OK) currentValue = QString::number(ivalue); + break; + } + case GP_WIDGET_DATE: + case GP_WIDGET_BUTTON: + case GP_WIDGET_SECTION: + case GP_WIDGET_WINDOW: + default: + break; + } + + gp_widget_free(widget); + + return currentValue; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setCameraConfigValue(const char *key, QString value) { + CameraWidget *widget = NULL, *child = NULL; + CameraWidgetType widgetType; + int retVal; + + if (!key) return false; + + retVal = gp_camera_get_single_config(m_camera, key, &child, m_gpContext); + if (retVal == GP_OK) + widget = child; + else { + retVal = gp_camera_get_config(m_camera, &widget, m_gpContext); + if (retVal < GP_OK) return false; + + retVal = gp_widget_get_child_by_name(widget, key, &child); + if (retVal < GP_OK) + retVal = gp_widget_get_child_by_label(widget, key, &child); + if (retVal < GP_OK) { + gp_widget_free(widget); + return false; + } + } + + retVal = gp_widget_get_type(child, &widgetType); + if (retVal < GP_OK) { + gp_widget_free(widget); + return false; + } + + switch (widgetType) { + case GP_WIDGET_MENU: + case GP_WIDGET_RADIO: { + bool found = false; + int choices = gp_widget_count_choices(child); + for (int i = 0; i < choices; i++) { + const char *choice; + retVal = gp_widget_get_choice(child, i, &choice); + if (retVal < GP_OK) continue; + if (choice != value) continue; + found = true; + break; + } + + retVal = !found ? GP_ERROR + : gp_widget_set_value(child, value.toStdString().c_str()); + break; + } + case GP_WIDGET_TEXT: + retVal = gp_widget_set_value(child, value.toStdString().c_str()); + break; + case GP_WIDGET_RANGE: { + float fvalue = value.toFloat(); + retVal = gp_widget_set_value(child, &fvalue); + break; + } + case GP_WIDGET_TOGGLE: { + int ivalue = value.toInt(); + retVal = gp_widget_set_value(child, &ivalue); + break; + } + case GP_WIDGET_DATE: + case GP_WIDGET_BUTTON: + case GP_WIDGET_SECTION: + case GP_WIDGET_WINDOW: + default: + retVal = GP_ERROR; + break; + } + + if (retVal >= GP_OK) + retVal = gp_camera_set_single_config(m_camera, key, child, m_gpContext); + + gp_widget_free(widget); + + return (retVal >= GP_OK); +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableApertures() { + m_apertureOptions.clear(); + + m_apertureOptions = getCameraConfigList(m_configKeys.apertureKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableShutterSpeeds() { + m_shutterSpeedOptions.clear(); + + m_shutterSpeedOptions = getCameraConfigList(m_configKeys.shutterSpeedKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableIso() { + m_isoOptions.clear(); + + m_isoOptions = getCameraConfigList(m_configKeys.isoKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableExposureCompensations() { + m_exposureOptions.clear(); + + m_exposureOptions = getCameraConfigList(m_configKeys.exposureCompensationKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableWhiteBalances() { + m_whiteBalanceOptions.clear(); + + m_whiteBalanceOptions = getCameraConfigList(m_configKeys.whiteBalanceKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableImageQualities() { + m_imageQualityOptions.clear(); + + m_imageQualityOptions = getCameraConfigList(m_configKeys.imageQualityKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableImageSizes() { + m_imageSizeOptions.clear(); + + m_imageSizeOptions = getCameraConfigList(m_configKeys.imageSizeKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailablePictureStyles() { + m_pictureStyleOptions.clear(); + + m_pictureStyleOptions = getCameraConfigList(m_configKeys.pictureStyleKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getAvailableColorTemperatures() { + m_colorTempOptions.clear(); + + m_colorTempOptions = getCameraConfigList(m_configKeys.colorTemperatureKey); + + return true; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::getManualFocusRangeData() { + m_manualFocusRange.clear(); + + m_manualFocusRange = getCameraConfigList(m_configKeys.manualFocusDriveKey); + + return true; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentAperture() { + QString currentValue = getCameraConfigValue(m_configKeys.apertureKey); + + m_displayedAperture = currentValue; + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentShutterSpeed() { + QString currentValue = getCameraConfigValue(m_configKeys.shutterSpeedKey); + + m_realShutterSpeed = currentValue; + + if (m_liveViewExposureOffset == 0) { + m_displayedShutterSpeed = m_realShutterSpeed; + currentValue = m_realShutterSpeed; + } else + currentValue = m_displayedShutterSpeed; + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentIso() { + QString currentValue = getCameraConfigValue(m_configKeys.isoKey); + + m_displayedIso = currentValue; + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentExposureCompensation() { + QString currentValue = + getCameraConfigValue(m_configKeys.exposureCompensationKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentWhiteBalance() { + QString currentValue = getCameraConfigValue(m_configKeys.whiteBalanceKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentColorTemperature() { + QString currentValue = getCameraConfigValue(m_configKeys.colorTemperatureKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentImageQuality() { + QString currentValue = getCameraConfigValue(m_configKeys.imageQualityKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentImageSize() { + QString currentValue = getCameraConfigValue(m_configKeys.imageSizeKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentPictureStyle() { + QString currentValue = getCameraConfigValue(m_configKeys.pictureStyleKey); + + return currentValue; +} + +//----------------------------------------------------------------- + +int GPhotoCam::getCurrentLiveViewOffset() { return m_liveViewExposureOffset; } + +//----------------------------------------------------------------- + +QString GPhotoCam::getMode() { + QString value = getCameraConfigValue(m_configKeys.modeKey); + + return value; +} + +//----------------------------------------------------------------- + +QString GPhotoCam::getCurrentBatteryLevel() { + QString value = getCameraConfigValue(m_configKeys.batteryLevelKey); + + return value; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setAperture(QString aperture) { + bool status = setCameraConfigValue(m_configKeys.apertureKey, aperture); + + if (status) m_displayedAperture = aperture; + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setShutterSpeed(QString shutterSpeed, bool withOffset) { + if (withOffset) { + m_realShutterSpeed = shutterSpeed; + m_displayedShutterSpeed = shutterSpeed; + if (m_liveViewExposureOffset != 0) { + int index = m_shutterSpeedOptions.indexOf(shutterSpeed); + // brighter goes down in shutter speed, so subtract + + if (m_liveViewExposureOffset > 0) { + int newValue = index - m_liveViewExposureOffset; + // get brighter, go down + if (newValue >= 0) { + m_realShutterSpeed = m_shutterSpeedOptions.at(newValue); + } else + m_realShutterSpeed = m_shutterSpeedOptions.at(0); + } else { + // get darker, go up + int newValue = index - m_liveViewExposureOffset; + if (newValue < m_shutterSpeedOptions.size()) { + m_realShutterSpeed = m_shutterSpeedOptions.at(newValue); + } else + m_realShutterSpeed = + m_shutterSpeedOptions.at(m_shutterSpeedOptions.size() - 1); + } + } + } + + QString usedSpeed = withOffset ? m_realShutterSpeed : shutterSpeed; + + bool status = setCameraConfigValue(m_configKeys.shutterSpeedKey, usedSpeed); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setIso(QString iso) { + bool status = setCameraConfigValue(m_configKeys.isoKey, iso); + if (status) m_displayedIso = iso; + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setExposureCompensation(QString exposure) { + bool status = + setCameraConfigValue(m_configKeys.exposureCompensationKey, exposure); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setWhiteBalance(QString whiteBalance) { + bool status = + setCameraConfigValue(m_configKeys.whiteBalanceKey, whiteBalance); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setColorTemperature(QString colorTemp) { + bool status = + setCameraConfigValue(m_configKeys.colorTemperatureKey, colorTemp); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setImageQuality(QString imageQuality) { + bool status = + setCameraConfigValue(m_configKeys.imageQualityKey, imageQuality); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setImageSize(QString imageSize) { + bool status = setCameraConfigValue(m_configKeys.imageSizeKey, imageSize); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setPictureStyle(QString pictureStyle) { + bool status = + setCameraConfigValue(m_configKeys.pictureStyleKey, pictureStyle); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setManualFocus(int value){ + QString strvalue = QString::number(value); + + bool status = + setCameraConfigValue(m_configKeys.manualFocusDriveKey, strvalue); + + return status; +} + +//----------------------------------------------------------------- + +void GPhotoCam::setLiveViewOffset(int compensation) { + m_liveViewExposureOffset = compensation; + emit(liveViewOffsetChangedSignal(m_liveViewExposureOffset)); +} + +//----------------------------------------------------------------- + +bool GPhotoCam::zoomLiveView() { + if (!m_sessionOpen || !StopMotion::instance()->m_liveViewStatus > 0) + return false; + + if (m_pickLiveViewZoom) toggleZoomPicking(); + + if (m_liveViewZoom == 1) { + m_liveViewZoom = 5; + m_zooming = true; + StopMotion::instance()->toggleNumpadForFocusCheck(true); + } else if (m_liveViewZoom == 5) { + m_liveViewZoom = 1; + m_zooming = false; + StopMotion::instance()->toggleNumpadForFocusCheck(false); + } + + bool status = + setCameraConfigValue("eoszoom", QString::number(m_liveViewZoom)); + if (status) { + if (m_liveViewZoom == 5) setZoomPoint(); + emit(focusCheckToggled(m_liveViewZoom > 1)); + } + + return status; +} + +//----------------------------------------------------------------- + +void GPhotoCam::calculateZoomPoint() { + double minimumDpi = 0.0; + + if (m_proxyImageDimensions == TDimension(0, 0)) { + TCamera *camera = + TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); + TDimensionD size = camera->getSize(); + minimumDpi = std::min(m_fullImageDimensions.lx / size.lx, + m_fullImageDimensions.ly / size.ly); + } else { + TDimensionD size = + TDimensionD((double)m_proxyImageDimensions.lx / Stage::standardDpi, + (double)m_proxyImageDimensions.ly / Stage::standardDpi); + minimumDpi = std::min(m_fullImageDimensions.lx / size.lx, + m_fullImageDimensions.ly / size.ly); + } + TPointD fullImageDpi = TPointD(minimumDpi, minimumDpi); + + bool outOfBounds = false; + if (m_liveViewZoomPickPoint == TPointD(0.0, 0.0)) { + m_calculatedZoomPoint = + TPoint(m_fullImageDimensions.lx / 2, m_fullImageDimensions.ly / 2); + m_finalZoomPoint.x = m_calculatedZoomPoint.x - (m_zoomRectDimensions.x / 2); + m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRectDimensions.y / 2); + } else { + // get the image size in Tahoma2D dimensions + double maxFullWidth = + (double)m_fullImageDimensions.lx / fullImageDpi.x * Stage::inch; + double maxFullHeight = + (double)m_fullImageDimensions.ly / fullImageDpi.y * Stage::inch; + // Tahoma2D coordinates are based on center at 0, 0 + // convert that to top left based coordinates + double newX = m_liveViewZoomPickPoint.x + maxFullWidth / 2.0; + double newY = -m_liveViewZoomPickPoint.y + maxFullHeight / 2.0; + // convert back to the normal image dimensions to talk to the camera + m_calculatedZoomPoint.x = newX / Stage::inch * fullImageDpi.x; + m_calculatedZoomPoint.y = newY / Stage::inch * fullImageDpi.x; + // the Canon SDK wants the top left corner of the zoom rect, not the center + m_finalZoomPoint.x = m_calculatedZoomPoint.x - (m_zoomRectDimensions.x / 2); + m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRectDimensions.y / 2); + // finally make sure everything actually fits on the image + if (m_finalZoomPoint.x < 0) { + m_finalZoomPoint.x = 0; + outOfBounds = true; + } + if (m_finalZoomPoint.y < 0) { + m_finalZoomPoint.y = 0; + outOfBounds = true; + } + if (m_finalZoomPoint.x > + m_fullImageDimensions.lx - (m_zoomRectDimensions.x)) { + m_finalZoomPoint.x = m_fullImageDimensions.lx - (m_zoomRectDimensions.x); + outOfBounds = true; + } + if (m_finalZoomPoint.y > + m_fullImageDimensions.ly - (m_zoomRectDimensions.y)) { + m_finalZoomPoint.y = m_fullImageDimensions.ly - (m_zoomRectDimensions.y); + outOfBounds = true; + } + + // if out of bounds, recalculate backwards to get the correct location + if (outOfBounds) { + TPoint tempCalculated; + // recenter the point in the rect + tempCalculated.x = m_finalZoomPoint.x + (m_zoomRectDimensions.x / 2); + tempCalculated.y = m_finalZoomPoint.y + (m_zoomRectDimensions.y / 2); + // convert to Tahoma2D Dimensions + newX = tempCalculated.x / fullImageDpi.x * Stage::inch; + newY = tempCalculated.y / fullImageDpi.y * Stage::inch; + // get center based coordinates + m_liveViewZoomPickPoint.x = newX - (maxFullWidth / 2.0); + m_liveViewZoomPickPoint.y = (newY - (maxFullHeight / 2.0)) * -1; + } + } + + // calculate the zoom rectangle position on screen + + // get the image size in Tahoma2D dimensions + double maxFullWidth = + (double)m_fullImageDimensions.lx / fullImageDpi.x * Stage::inch; + double maxFullHeight = + (double)m_fullImageDimensions.ly / fullImageDpi.y * Stage::inch; + m_zoomRect = + TRect(m_finalZoomPoint.x, m_finalZoomPoint.y + m_zoomRectDimensions.y, + m_finalZoomPoint.x + m_zoomRectDimensions.x, m_finalZoomPoint.y); + TRect tempCalculated; + + // convert to Tahoma2D Dimensions + tempCalculated.x0 = m_zoomRect.x0 / fullImageDpi.x * Stage::inch; + tempCalculated.y0 = m_zoomRect.y0 / fullImageDpi.y * Stage::inch; + tempCalculated.x1 = m_zoomRect.x1 / fullImageDpi.x * Stage::inch; + tempCalculated.y1 = m_zoomRect.y1 / fullImageDpi.y * Stage::inch; + // get center based coordinates + m_zoomRect.x0 = tempCalculated.x0 - (maxFullWidth / 2.0); + m_zoomRect.y0 = (tempCalculated.y0 - (maxFullHeight / 2.0)) * -1; + m_zoomRect.x1 = tempCalculated.x1 - (maxFullWidth / 2.0); + m_zoomRect.y1 = (tempCalculated.y1 - (maxFullHeight / 2.0)) * -1; +} + +//----------------------------------------------------------------- + +void GPhotoCam::makeZoomPoint(TPointD pos) { + m_liveViewZoomPickPoint = pos; + calculateZoomPoint(); +} + +//----------------------------------------------------------------- + +void GPhotoCam::toggleZoomPicking() { + if (m_sessionOpen && StopMotion::instance()->m_liveViewStatus > 0 && + !m_zooming) { + if (m_pickLiveViewZoom) { + m_pickLiveViewZoom = false; + StopMotion::instance()->toggleNumpadForFocusCheck(false); + } else { + m_pickLiveViewZoom = true; + if (m_liveViewZoomPickPoint == TPointD(0.0, 0.0)) { + makeZoomPoint(m_liveViewZoomPickPoint); + } + StopMotion::instance()->toggleNumpadForFocusCheck(true); + } + } + emit(pickFocusCheckToggled(m_pickLiveViewZoom)); +} + +//----------------------------------------------------------------- + +bool GPhotoCam::setZoomPoint() { + // make sure this is set AFTER starting zoom + int retVal; + + m_liveViewZoomReadyToPick = false; + + calculateZoomPoint(); + + TPoint zoomPoint; + zoomPoint.x = m_finalZoomPoint.x; + zoomPoint.y = m_finalZoomPoint.y; + + QString zoomPointVal = QString("%1,%2").arg(zoomPoint.x).arg(zoomPoint.y); + + bool status = setCameraConfigValue(m_configKeys.afPositionKey, zoomPointVal); + + m_liveViewZoomReadyToPick = true; + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusNear() { + bool status = + setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Near 1"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusFar() { + bool status = setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Far 1"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusNear2() { + bool status = + setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Near 2"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusFar2() { + bool status = setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Far 2"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusNear3() { + bool status = + setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Near 3"); + + return status; +} + +//----------------------------------------------------------------- + +bool GPhotoCam::focusFar3() { + bool status = setCameraConfigValue(m_configKeys.manualFocusDriveKey, "Far 3"); + + return status; +} +#endif diff --git a/toonz/sources/stopmotion/gphotocam.h b/toonz/sources/stopmotion/gphotocam.h new file mode 100644 index 00000000..2246be0c --- /dev/null +++ b/toonz/sources/stopmotion/gphotocam.h @@ -0,0 +1,257 @@ +#pragma once + +#ifndef GPHOTOCAM_H +#define GPHOTOCAM_H + +#ifdef WITH_GPHOTO2 +#include +#endif + +#include "opencv2/opencv.hpp" + +#include "traster.h" + +#include +#include +#include + +typedef struct { + const char *modeKey; + const char *batteryLevelKey; + const char *shutterSpeedKey; + const char *apertureKey; + const char *isoKey; + const char *whiteBalanceKey; + const char *pictureStyleKey; + const char *imageQualityKey; + const char *imageSizeKey; + const char *exposureCompensationKey; + const char *colorTemperatureKey; + const char *manualFocusDriveKey; + const char *afPositionKey; + const char *viewfinderKey; + const char *focusPointKey; +} GPConfigKeys; + +const struct { + QString manufacturer; + GPConfigKeys keys; +} cameraConfigKeys[] = { + // Canon + {"Canon", + {"autoexposuremode", "batterylevel", "shutterspeed", "aperture", "iso", + "whitebalance", "picturestyle", "imageformat", 0, "exposurecompensation", + "colorTemperature", "manualfocusdrive", "eoszoomposition", "viewfinder", + "focusinfo"}}, + // Nikon + {"Nikon", + {"expprogram", "Battery Level", "shutterspeed", "f-number", "iso", + "whitebalance", 0, "imagequality", "imagesize", "exposurecompensation", 0, + "manualfocusdrive", "changeafarea", "viewfinder", "changeafarea"}}, + {0, + {"expprogram", 0, "shutterspeed", "f-number", "iso", "whitebalance", 0, + "imagequality", "imagesize", "exposurecompensation", 0, "manualfocusdrive", + 0, "viewfinder", 0}}}; + +//----------------------------------------------------------------- + +class GPhotoCam : public QObject { + Q_OBJECT + +public: + static GPhotoCam *instance() { + static GPhotoCam _instance; + return &_instance; + }; + +private: +#ifdef WITH_GPHOTO2 + GPContext *m_gpContext; +#endif + +private: + QStringList m_apertureOptions, m_shutterSpeedOptions, m_isoOptions, + m_exposureOptions, m_whiteBalanceOptions, m_colorTempOptions, + m_imageQualityOptions, m_imageSizeOptions, m_pictureStyleOptions, + m_manualFocusRange; + + GPConfigKeys m_configKeys; + +public: + GPhotoCam(); + ~GPhotoCam(); + + int m_count; + int m_gphotoIndex; + bool m_sessionOpen; + + QTimer *m_eventTimer; + bool m_capturePreview; + bool m_captureImage; + bool m_exitRequested; + bool m_previewImageReady; + + QString m_cameraName; + QString m_cameraManufacturer; + QString m_cameraModel; + +#ifdef WITH_GPHOTO2 + CameraFile *m_previewFile; + + CameraAbilitiesList *m_cameraListMaster; + GPPortInfoList *m_portInfoList; + CameraList *m_cameraListDetected; + Camera *m_camera; + GPPortInfo m_portInfo; + CameraFilePath *m_cameraImageFilePath; +#endif + + TDimension m_proxyImageDimensions = TDimension(0, 0); + TDimension m_fullImageDimensions = TDimension(0, 0); + int m_liveViewExposureOffset = 0; + QString m_realShutterSpeed; + QString m_displayedShutterSpeed; + QString m_displayedAperture; + QString m_displayedIso; + + bool m_converterSucceeded, l_quitLoop; + + cv::Mat m_gPhotoImage; + + bool m_zooming = false; + bool m_pickLiveViewZoom = false; + bool m_liveViewZoomReadyToPick = true; + int m_liveViewZoom = 1; + TPointD m_liveViewZoomPickPoint = TPointD(0.0, 0.0); + TPoint m_calculatedZoomPoint = TPoint(0, 0); + TPoint m_finalZoomPoint = TPoint(0, 0); + TPoint m_zoomRectDimensions = TPoint(0, 0); + TRect m_zoomRect = TRect(0, 0, 0, 0); + + void setGphotoIndex(int index) { m_gphotoIndex = index; } + int getGphotoIndex() { return m_gphotoIndex; } + + bool m_useCalibration; + cv::Mat m_calibrationMapX, m_calibrationMapY; + + void enableCalibration(bool useCalibration) { + m_useCalibration = useCalibration; + } + void setCalibration(cv::Mat calibrationMapX, cv::Mat calibrationMapY) { + m_calibrationMapX = calibrationMapX; + m_calibrationMapY = calibrationMapY; + }; + + cv::Mat getGPhotoImage() { return m_gPhotoImage; } + + int getCameraCount(); + + void resetGphotocam(bool liveViewOpen); + + bool isCanon() { return m_cameraManufacturer.contains("Canon"); }; + bool isNikon() { return m_cameraManufacturer.contains("Nikon"); }; + + void loadCameraConfigKeys(QString manufacturer); + +#ifdef WITH_GPHOTO2 + bool initializeCamera(); + bool getCamera(int index); + bool releaseCamera(); + QString getCameraName(int index); + bool openCameraSession(); + bool closeCameraSession(); + void closeAll(); + bool startLiveView(); + bool endLiveView(); + bool getGPhotocamImage(); + bool takePicture(); + QString getMode(); + QString getCurrentBatteryLevel(); + bool downloadImage(); + + QStringList getApertureOptions() { return m_apertureOptions; } + QStringList getShutterSpeedOptions() { return m_shutterSpeedOptions; } + QStringList getIsoOptions() { return m_isoOptions; } + QStringList getExposureOptions() { return m_exposureOptions; } + QStringList getWhiteBalanceOptions() { return m_whiteBalanceOptions; } + QStringList getColorTemperatureOptions() { return m_colorTempOptions; } + QStringList getImageQualityOptions() { return m_imageQualityOptions; } + QStringList getImageSizeOptions() { return m_imageSizeOptions; } + QStringList getPictureStyleOptions() { return m_pictureStyleOptions; } + QStringList getManualFocusRange() { return m_manualFocusRange; } + + QStringList getCameraConfigList(const char *key); + QString getCameraConfigValue(const char *key); + bool setCameraConfigValue(const char *key, QString value); + + bool getAvailableApertures(); + bool getAvailableShutterSpeeds(); + bool getAvailableIso(); + bool getAvailableExposureCompensations(); + bool getAvailableWhiteBalances(); + bool getAvailableImageQualities(); + bool getAvailableImageSizes(); + bool getAvailablePictureStyles(); + bool getAvailableColorTemperatures(); + bool getManualFocusRangeData(); + + QString getCurrentAperture(); + QString getCurrentShutterSpeed(); + QString getCurrentIso(); + QString getCurrentExposureCompensation(); + QString getCurrentWhiteBalance(); + QString getCurrentColorTemperature(); + QString getCurrentImageQuality(); + QString getCurrentImageSize(); + QString getCurrentPictureStyle(); + int getCurrentLiveViewOffset(); + + bool setAperture(QString aperture); + bool setShutterSpeed(QString shutterSpeed, bool withOffset = true); + bool setIso(QString iso); + bool setExposureCompensation(QString exposure); + bool setWhiteBalance(QString whiteBalance); + bool setColorTemperature(QString colorTemp); + bool setImageQuality(QString imageQuality); + bool setImageSize(QString imageSize); + bool setPictureStyle(QString pictureStyle); + bool setManualFocus(int value); + void setLiveViewOffset(int offset); + + bool zoomLiveView(); + void calculateZoomPoint(); + void makeZoomPoint(TPointD pos); + void toggleZoomPicking(); + bool setZoomPoint(); + bool focusNear(); + bool focusFar(); + bool focusNear2(); + bool focusFar2(); + bool focusNear3(); + bool focusFar3(); +#endif + +public slots: + void onTimeout(); + void onImageReady(const bool &); + void onFinished(); + +signals: + void newGPhotocamImageReady(); + void modeChanged(); + void batteryChanged(); + void apertureChangedSignal(QString); + void isoChangedSignal(QString); + void shutterSpeedChangedSignal(QString); + void exposureChangedSignal(QString); + void whiteBalanceChangedSignal(QString); + void imageQualityChangedSignal(QString); + void imageSizeChangedSignal(QString); + void pictureStyleChangedSignal(QString); + void colorTemperatureChangedSignal(QString); + void liveViewOffsetChangedSignal(int); + void focusCheckToggled(bool); + void pickFocusCheckToggled(bool); +}; + +#endif // GPHOTOCAM_H diff --git a/toonz/sources/stopmotion/jpgconverter.cpp b/toonz/sources/stopmotion/jpgconverter.cpp index ec785751..3b895098 100644 --- a/toonz/sources/stopmotion/jpgconverter.cpp +++ b/toonz/sources/stopmotion/jpgconverter.cpp @@ -9,26 +9,34 @@ JpgConverter::JpgConverter() {} JpgConverter::~JpgConverter() {} #ifdef WITH_CANON - void JpgConverter::setStream(EdsStreamRef stream) { m_stream = stream; } +#endif + +void JpgConverter::setDataPtr(unsigned char* dataPtr, unsigned long dataSize) { + m_dataPtr = dataPtr; + m_dataSize = dataSize; +} void JpgConverter::convertFromJpg() { -#ifdef MACOSX - UInt64 mySize = 0; -#else - unsigned __int64 mySize = 0; +#ifdef WITH_CANON + if (m_stream) { + EdsError err = EdsGetPointer(m_stream, (EdsVoid**)&m_dataPtr); + err = EdsGetLength(m_stream, &m_dataSize); + } #endif - unsigned char* data = NULL; - EdsError err = EdsGetPointer(m_stream, (EdsVoid**)&data); - err = EdsGetLength(m_stream, &mySize); + + if (!m_dataPtr) { + emit(imageReady(false)); + return; + } int width, height, pixelFormat; int inSubsamp, inColorspace; tjhandle tjInstance = NULL; unsigned char* imgBuf = NULL; tjInstance = tjInitDecompress(); - tjDecompressHeader3(tjInstance, data, mySize, &width, &height, &inSubsamp, - &inColorspace); + tjDecompressHeader3(tjInstance, m_dataPtr, m_dataSize, &width, &height, + &inSubsamp, &inColorspace); if (width < 0 || height < 0) { emit(imageReady(false)); @@ -51,7 +59,7 @@ void JpgConverter::convertFromJpg() { tempWidth = TJSCALED(width, scalingFactor); tempHeight = TJSCALED(height, scalingFactor); } - tjDecompress2(tjInstance, data, mySize, imgBuf, width, + tjDecompress2(tjInstance, m_dataPtr, m_dataSize, imgBuf, width, width * tjPixelSize[pixelFormat], height, pixelFormat, flags); m_finalImage = TRaster32P(width, height); @@ -65,18 +73,18 @@ void JpgConverter::convertFromJpg() { tjDestroy(tjInstance); tjInstance = NULL; +#ifdef WITH_CANON if (m_stream != NULL) { EdsRelease(m_stream); m_stream = NULL; } - data = NULL; +#endif + m_dataPtr = NULL; emit(imageReady(true)); } void JpgConverter::run() { convertFromJpg(); } -#endif - //----------------------------------------------------------------------------- void JpgConverter::saveJpg(TRaster32P image, TFilePath path) { diff --git a/toonz/sources/stopmotion/jpgconverter.h b/toonz/sources/stopmotion/jpgconverter.h index 168ef888..8b3fa0b5 100644 --- a/toonz/sources/stopmotion/jpgconverter.h +++ b/toonz/sources/stopmotion/jpgconverter.h @@ -32,6 +32,16 @@ class JpgConverter : public QThread { #ifdef WITH_CANON EdsStreamRef m_stream; #endif + +#ifdef MACOSX + UInt64 m_dataSize = 0; +#elif defined(LINUX) + unsigned long long m_dataSize = 0; +#else + unsigned __int64 m_dataSize = 0; +#endif + unsigned char* m_dataPtr = NULL; + TRaster32P m_finalImage; // bool m_scale = false; int m_scaleWidth = 0; @@ -43,19 +53,18 @@ public: static bool loadJpg(TFilePath path, TRaster32P& image); #ifdef WITH_CANON void setStream(EdsStreamRef stream); - // void setScale(bool scale) { m_scale = scale; } +// void setScale(bool scale) { m_scale = scale; } +#endif + void setDataPtr(unsigned char* dataPtr, unsigned long dataSize); void setScaleWidth(bool scaleWidth) { m_scaleWidth = scaleWidth; } TRaster32P getImage() { return m_finalImage; } void convertFromJpg(); protected: void run() override; -#endif signals: void imageReady(bool); }; -//#endif - #endif // JPGCONVERTER_H \ No newline at end of file diff --git a/toonz/sources/stopmotion/stopmotion.cpp b/toonz/sources/stopmotion/stopmotion.cpp index cef37fa2..6c2be860 100644 --- a/toonz/sources/stopmotion/stopmotion.cpp +++ b/toonz/sources/stopmotion/stopmotion.cpp @@ -246,10 +246,11 @@ bool FlexibleNameCreator::setCurrent(std::wstring name) { StopMotion::StopMotion() { m_opacity = StopMotionOpacity; - m_webcam = new Webcam(); - m_canon = Canon::instance(); - m_serial = new StopMotionSerial(); - m_light = new StopMotionLight(); + m_webcam = new Webcam(); + m_canon = Canon::instance(); + m_gphotocam = GPhotoCam::instance(); + m_serial = new StopMotionSerial(); + m_light = new StopMotionLight(); m_alwaysLiveView = StopMotionAlwaysLiveView; @@ -298,6 +299,8 @@ StopMotion::StopMotion() { SLOT(captureWebcamOnTimeout())); ret = ret && connect(m_canon, SIGNAL(newCanonImageReady()), this, SLOT(directDslrImage())); + ret = ret && connect(m_gphotocam, SIGNAL(newGPhotocamImageReady()), this, + SLOT(directDslrImage())); assert(ret); ret = ret && connect(m_canon, SIGNAL(canonCameraChanged(QString)), this, SLOT(onCanonCameraChanged(QString))); @@ -319,6 +322,9 @@ StopMotion::~StopMotion() { #ifdef WITH_CANON m_canon->closeAll(); #endif +#ifdef WITH_GPHOTO2 + m_gphotocam->closeAll(); +#endif } //----------------------------------------------------------------------------- @@ -355,7 +361,11 @@ void StopMotion::onSceneSwitched() { loadXmlFile(); buildLiveViewMap(sl); m_sl = sl; - getRasterLevelSize(sl, m_canon->m_proxyImageDimensions); + // Type should have been set by loadXmlFile + if (m_currentCameraType == CameraType::CanonDSLR) + getRasterLevelSize(sl, m_canon->m_proxyImageDimensions); + else if (m_currentCameraType == CameraType::GPhoto) + getRasterLevelSize(sl, m_gphotocam->m_proxyImageDimensions); found = true; break; } @@ -385,7 +395,7 @@ bool StopMotion::buildLiveViewMap(TXshSimpleLevel *sl) { return false; } - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { return false; } @@ -421,19 +431,26 @@ bool StopMotion::buildLiveViewMap(TXshSimpleLevel *sl) { //----------------------------------------------------------------- void StopMotion::disconnectAllCameras() { + if (m_currentCameraType == CameraType::Web) { + m_webcam->releaseWebcam(); + m_webcam->clearWebcam(); + } #ifdef WITH_CANON - if (m_liveViewStatus > LiveViewClosed) { - m_canon->resetCanon(true); - } else { - m_canon->resetCanon(false); + if (m_currentCameraType == CameraType::CanonDSLR) { + if (m_liveViewStatus > LiveViewClosed) { + m_canon->resetCanon(true); + } else { + m_canon->resetCanon(false); + } } #endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + m_gphotocam->resetGphotocam((m_liveViewStatus > LiveViewClosed)); +#endif - if (m_usingWebcam) { - m_webcam->releaseWebcam(); - m_usingWebcam = false; - } - m_webcam->clearWebcam(); + m_currentCameraType = CameraType::None; + m_currentCameraTypeIndex = -1; m_liveViewStatus = LiveViewClosed; setTEnvCameraName(""); @@ -449,7 +466,7 @@ void StopMotion::disconnectAllCameras() { emit(intervalToggled(false)); emit(liveViewChanged(false)); emit(liveViewStopped()); - emit(newCameraSelected(0, false)); + emit(newCameraSelected(0)); toggleNumpadShortcuts(false); } @@ -1139,7 +1156,7 @@ bool StopMotion::loadLiveViewImage(int row, TRaster32P &image) { int frameNumber = frameId.getNumber(); - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { if (frameNumber > 0) { image = sl->getFrame(frameId, false)->raster(); return true; @@ -1386,42 +1403,41 @@ void StopMotion::onTimeout() { bool calibrateImage = !m_calibration.captureCue && m_calibration.isValid && m_calibration.isEnabled; - if (!m_usingWebcam) { + bool success = false; + #ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { m_canon->enableCalibration(calibrateImage); - bool success = m_canon->downloadEVFData(); - if (success) { - // capture calibration reference - if (m_calibration.captureCue) { - m_calibration.captureCue = false; - emit(calibrationImageCaptured()); - return; - } - - setLiveViewImage(); - } else { - m_hasLiveViewImage = false; - } -#endif - } else { - m_webcam->enableCalibration(calibrateImage); - bool success = m_webcam->getWebcamImage(m_liveViewImage); - if (success) { - // capture calibration reference - if (m_calibration.captureCue) { - m_calibration.captureCue = false; - emit(calibrationImageCaptured()); - return; - } - - setLiveViewImage(); - } else { - m_hasLiveViewImage = false; - } + success = m_canon->downloadEVFData(); } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + m_gphotocam->enableCalibration(calibrateImage); + success = m_gphotocam->getGPhotocamImage(); + } +#endif + if (m_currentCameraType == CameraType::Web) { + m_webcam->enableCalibration(calibrateImage); + success = m_webcam->getWebcamImage(m_liveViewImage); + } + + if (success) { + // capture calibration reference + if (m_calibration.captureCue) { + m_calibration.captureCue = false; + emit(calibrationImageCaptured()); + return; + } + + setLiveViewImage(); + } else { + m_hasLiveViewImage = false; + } + if ((!getAlwaysLiveView() && !(currentFrame >= m_xSheetFrameNumber - 2)) || - m_canon->m_pickLiveViewZoom) { + isPickLiveViewZoom()) { m_showLineUpImage = false; } else { m_showLineUpImage = true; @@ -1446,23 +1462,31 @@ void StopMotion::setLiveViewImage() { if (m_liveViewDpi == TPointD(0.0, 0.0) || m_liveViewImageDimensions.lx == 0) { m_liveViewImageDimensions = m_liveViewImage->getSize(); - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { m_liveViewDpi = TPointD(Stage::standardDpi, Stage::standardDpi); } else { double minimumDpi; - if (m_canon->m_proxyImageDimensions == TDimension(0, 0)) { - TCamera *camera = - TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); - TDimensionD size = camera->getSize(); - minimumDpi = std::min(m_liveViewImageDimensions.lx / size.lx, - m_liveViewImageDimensions.ly / size.ly); - } else { - TDimensionD size = TDimensionD( + + TCamera *camera = + TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); + TDimensionD size = camera->getSize(); + + if (m_currentCameraType == CameraType::CanonDSLR && + m_canon->m_proxyImageDimensions != TDimension(0, 0)) { + size = TDimensionD( (double)m_canon->m_proxyImageDimensions.lx / Stage::standardDpi, (double)m_canon->m_proxyImageDimensions.ly / Stage::standardDpi); - minimumDpi = std::min(m_liveViewImageDimensions.lx / size.lx, - m_liveViewImageDimensions.ly / size.ly); } + if (m_currentCameraType == CameraType::GPhoto && + m_gphotocam->m_proxyImageDimensions != TDimension(0, 0)) { + size = TDimensionD( + (double)m_gphotocam->m_proxyImageDimensions.lx / Stage::standardDpi, + (double)m_gphotocam->m_proxyImageDimensions.ly / + Stage::standardDpi); + } + + minimumDpi = std::min(m_liveViewImageDimensions.lx / size.lx, + m_liveViewImageDimensions.ly / size.ly); m_liveViewDpi = TPointD(minimumDpi, minimumDpi); } @@ -1497,7 +1521,7 @@ bool StopMotion::importImage() { return false; } - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { m_newImage = m_liveViewImage; } @@ -1634,7 +1658,7 @@ bool StopMotion::importImage() { return false; } } - if (!m_usingWebcam) { + if (m_currentCameraType != CameraType::Web) { if (!TFileStatus(fullResFolder).doesExist()) { try { TSystem::mkDir(fullResFolder); @@ -1656,7 +1680,7 @@ bool StopMotion::importImage() { } // move the temp file - if (!m_usingWebcam) { + if (m_currentCameraType != CameraType::Web) { TSystem::copyFile(fullResFile, tempFile); TSystem::deleteFile(tempFile); @@ -1800,9 +1824,11 @@ bool StopMotion::importImage() { //----------------------------------------------------------------- void StopMotion::captureImage() { - if (m_playCaptureSound) { - m_camSnapSound->play(); + if (m_currentCameraType == CameraType::None) { + DVGui::warning(tr("No camera selected.")); + return; } + if (m_isTimeLapse && !m_intervalStarted) { startInterval(); return; @@ -1811,21 +1837,34 @@ void StopMotion::captureImage() { stopInterval(); return; } +/* if (!m_hasLiveViewImage || m_liveViewStatus != LiveViewOpen) { DVGui::warning(tr("Cannot capture image unless live view is active.")); return; } +*/ bool sessionOpen = false; #ifdef WITH_CANON - sessionOpen = m_canon->m_sessionOpen; + if (m_currentCameraType == CameraType::CanonDSLR) + sessionOpen = m_canon->m_sessionOpen; #endif - if ((!m_usingWebcam && !sessionOpen) || m_userCalledPause) { +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + sessionOpen = m_gphotocam->m_sessionOpen; +#endif + + if ((m_currentCameraType != CameraType::Web && !sessionOpen) || + m_userCalledPause) { DVGui::warning(tr("Please start live view before capturing an image.")); return; } - if (m_usingWebcam) { + if (m_playCaptureSound) { + m_camSnapSound->play(); + } + + if (m_currentCameraType == CameraType::Web) { captureWebcamImage(); } else { captureDslrImage(); @@ -1876,14 +1915,14 @@ void StopMotion::captureWebcamOnTimeout() { void StopMotion::captureDslrImage() { m_light->showOverlays(); -#ifdef WITH_CANON - if (m_canon->m_zooming) { + + if (isZooming()) { DVGui::warning( tr("Can't capture an image with focus check on.\n" "Please click the Check button in the Settings tab.")); return; } -#endif + if (getReviewTimeDSec() > 0 && !m_isTimeLapse) { m_timer->stop(); } @@ -1915,7 +1954,10 @@ void StopMotion::captureDslrImage() { m_tempRaw = tempRaw.getQString(); #ifdef WITH_CANON - m_canon->takePicture(); + if (m_currentCameraType == CameraType::CanonDSLR) m_canon->takePicture(); +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) m_gphotocam->takePicture(); #endif } @@ -1926,10 +1968,16 @@ void StopMotion::directDslrImage() { saveTestShot(); else importImage(); + #ifdef WITH_CANON - if (m_canon->m_liveViewExposureOffset != 0) { + if (m_currentCameraType == CameraType::CanonDSLR && + m_canon->m_liveViewExposureOffset != 0) m_canon->setShutterSpeed(m_canon->m_realShutterSpeed, false); - } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto && + m_gphotocam->m_liveViewExposureOffset != 0) + m_gphotocam->setShutterSpeed(m_gphotocam->m_realShutterSpeed, false); #endif } @@ -1961,23 +2009,28 @@ void StopMotion::postImportProcess() { void StopMotion::takeTestShot() { bool sessionOpen = false; #ifdef WITH_CANON - sessionOpen = m_canon->m_sessionOpen; + if (m_currentCameraType == CameraType::CanonDSLR) + sessionOpen = m_canon->m_sessionOpen; #endif - if ((!m_usingWebcam && !sessionOpen) || m_userCalledPause) { +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + sessionOpen = m_gphotocam->m_sessionOpen; +#endif + + if ((m_currentCameraType != CameraType::Web && !sessionOpen) || + m_userCalledPause) { DVGui::warning(tr("Please start live view before capturing an image.")); return; } m_isTestShot = true; - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { if (m_light->useOverlays()) { m_light->showOverlays(); m_webcamOverlayTimer->start(500); } else { saveTestShot(); } - } -#ifdef WITH_CANON - else { + } else { TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); TFilePath parentDir = scene->decodeFilePath(TFilePath(m_filePath)); @@ -1990,9 +2043,14 @@ void StopMotion::takeTestShot() { m_tempFile = tempFile.getQString(); m_tempRaw = tempRaw.getQString(); m_light->showOverlays(); - m_canon->takePicture(); - } + +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) m_gphotocam->takePicture(); #endif +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) m_canon->takePicture(); +#endif + } } //----------------------------------------------------------------------------- @@ -2010,7 +2068,7 @@ void StopMotion::saveTestShot() { return; } - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { m_newImage = m_liveViewImage; } @@ -2089,7 +2147,7 @@ void StopMotion::saveTestShot() { TFilePath tempFile = parentDir + "temp.jpg"; TFilePath tempRaw = parentDir + "temp.cr2"; - if (!m_usingWebcam) { + if (m_currentCameraType != CameraType::Web) { TSystem::copyFile(testsFile, tempFile); TSystem::deleteFile(tempFile); if (TSystem::doesExistFileOrLevel(TFilePath(tempRaw))) { @@ -2135,7 +2193,7 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { xmlWriter.writeStartElement("body"); xmlWriter.writeStartElement("Test_" + QString::number(number)); - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { xmlWriter.writeTextElement("Webcam", "yes"); xmlWriter.writeTextElement("CameraName", m_webcam->getWebcamDescription()); @@ -2143,9 +2201,10 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { QString::number(m_webcam->getWebcamWidth())); xmlWriter.writeTextElement("CameraResolutionY", QString::number(m_webcam->getWebcamHeight())); - } else { - xmlWriter.writeTextElement("Webcam", "no"); + } #ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { + xmlWriter.writeTextElement("Webcam", "no"); xmlWriter.writeTextElement("CameraName", QString::fromStdString(m_canon->m_cameraName)); xmlWriter.writeTextElement("Aperture", m_canon->getCurrentAperture()); @@ -2156,14 +2215,38 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { m_canon->getCurrentPictureStyle()); xmlWriter.writeTextElement("ImageQuality", m_canon->getCurrentImageQuality()); +// xmlWriter.writeTextElement("ImageSize", +// m_canon->getCurrentImageSize()); xmlWriter.writeTextElement("WhiteBalance", m_canon->getCurrentWhiteBalance()); xmlWriter.writeTextElement("ColorTemperature", m_canon->getCurrentColorTemperature()); xmlWriter.writeTextElement("ExposureCompensation", m_canon->getCurrentExposureCompensation()); -#endif } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + xmlWriter.writeTextElement("Webcam", "no"); + xmlWriter.writeTextElement("CameraName", m_gphotocam->m_cameraName); + xmlWriter.writeTextElement("Aperture", m_gphotocam->m_displayedAperture); + xmlWriter.writeTextElement("ShutterSpeed", + m_gphotocam->m_displayedShutterSpeed); + xmlWriter.writeTextElement("ISO", m_gphotocam->m_displayedIso); + xmlWriter.writeTextElement("PictureStyle", + m_gphotocam->getCurrentPictureStyle()); + xmlWriter.writeTextElement("ImageQuality", + m_gphotocam->getCurrentImageQuality()); + xmlWriter.writeTextElement("ImageSize", + m_gphotocam->getCurrentImageSize()); + xmlWriter.writeTextElement("WhiteBalance", + m_gphotocam->getCurrentWhiteBalance()); + xmlWriter.writeTextElement("ColorTemperature", + m_gphotocam->getCurrentColorTemperature()); + xmlWriter.writeTextElement("ExposureCompensation", + m_gphotocam->getCurrentExposureCompensation()); + } +#endif xmlWriter.writeEndElement(); xmlWriter.writeEndElement(); xmlWriter.writeEndDocument(); @@ -2187,7 +2270,7 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { QDomElement newTest = document.createElement("Test_" + QString::number(number)); - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { QDomElement webcam = document.createElement("Webcam"); newTest.appendChild(webcam); webcam.appendChild(document.createTextNode("yes")); @@ -2207,12 +2290,11 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { resolutionY.appendChild(document.createTextNode( QString::number(m_webcam->getWebcamHeight()))); } - - else { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { QDomElement webcam = document.createElement("Webcam"); newTest.appendChild(webcam); webcam.appendChild(document.createTextNode("no")); -#ifdef WITH_CANON QDomElement cameraName = document.createElement("CameraName"); newTest.appendChild(cameraName); cameraName.appendChild(document.createTextNode( @@ -2242,6 +2324,11 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { imageQuality.appendChild( document.createTextNode(m_canon->getCurrentImageQuality())); + //QDomElement imageSize = document.createElement("ImageSize"); + //newTest.appendChild(imageSize); + //imageSize.appendChild( + // document.createTextNode(m_canon->getCurrentImageSize())); + QDomElement whiteBalance = document.createElement("WhiteBalance"); newTest.appendChild(whiteBalance); whiteBalance.appendChild( @@ -2257,8 +2344,64 @@ void StopMotion::saveTestXml(TFilePath testsXml, int number) { newTest.appendChild(exposureCompensation); exposureCompensation.appendChild( document.createTextNode(m_canon->getCurrentExposureCompensation())); -#endif } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + QDomElement webcam = document.createElement("Webcam"); + newTest.appendChild(webcam); + webcam.appendChild(document.createTextNode("no")); + QDomElement cameraName = document.createElement("CameraName"); + newTest.appendChild(cameraName); + cameraName.appendChild( + document.createTextNode(m_gphotocam->m_cameraName)); + + QDomElement aperture = document.createElement("Aperture"); + newTest.appendChild(aperture); + aperture.appendChild( + document.createTextNode(m_gphotocam->m_displayedAperture)); + + QDomElement shutterSpeed = document.createElement("ShutterSpeed"); + newTest.appendChild(shutterSpeed); + shutterSpeed.appendChild( + document.createTextNode(m_gphotocam->m_displayedShutterSpeed)); + + QDomElement iso = document.createElement("ISO"); + newTest.appendChild(iso); + iso.appendChild(document.createTextNode(m_gphotocam->m_displayedIso)); + + QDomElement pictureStyle = document.createElement("PictureStyle"); + newTest.appendChild(pictureStyle); + pictureStyle.appendChild( + document.createTextNode(m_gphotocam->getCurrentPictureStyle())); + + QDomElement imageQuality = document.createElement("ImageQuality"); + newTest.appendChild(imageQuality); + imageQuality.appendChild( + document.createTextNode(m_gphotocam->getCurrentImageQuality())); + + QDomElement imageSize = document.createElement("ImageSize"); + newTest.appendChild(imageSize); + imageSize.appendChild( + document.createTextNode(m_gphotocam->getCurrentImageSize())); + + QDomElement whiteBalance = document.createElement("WhiteBalance"); + newTest.appendChild(whiteBalance); + whiteBalance.appendChild( + document.createTextNode(m_gphotocam->getCurrentWhiteBalance())); + + QDomElement colorTemperature = document.createElement("ColorTemperature"); + newTest.appendChild(colorTemperature); + colorTemperature.appendChild( + document.createTextNode(m_gphotocam->getCurrentColorTemperature())); + + QDomElement exposureCompensation = + document.createElement("ExposureCompensation"); + newTest.appendChild(exposureCompensation); + exposureCompensation.appendChild(document.createTextNode( + m_gphotocam->getCurrentExposureCompensation())); + } +#endif docEle.appendChild(newTest); file.open(QIODevice::WriteOnly); file.resize(0); @@ -2294,16 +2437,17 @@ void StopMotion::saveXmlFile() { xmlWriter.writeEndElement(); xmlWriter.writeStartElement("CameraInfo"); - if (m_usingWebcam) { + if (m_currentCameraType == CameraType::Web) { xmlWriter.writeTextElement("Webcam", "yes"); xmlWriter.writeTextElement("CameraName", m_webcam->getWebcamDescription()); xmlWriter.writeTextElement("CameraResolutionX", QString::number(m_webcam->getWebcamWidth())); xmlWriter.writeTextElement("CameraResolutionY", QString::number(m_webcam->getWebcamHeight())); - } else { - xmlWriter.writeTextElement("Webcam", "no"); + } #ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { + xmlWriter.writeTextElement("Webcam", "no"); xmlWriter.writeTextElement("CameraName", QString::fromStdString(m_canon->m_cameraName)); xmlWriter.writeTextElement("Aperture", m_canon->getCurrentAperture()); @@ -2314,6 +2458,8 @@ void StopMotion::saveXmlFile() { m_canon->getCurrentPictureStyle()); xmlWriter.writeTextElement("ImageQuality", m_canon->getCurrentImageQuality()); + //xmlWriter.writeTextElement("ImageSize", + // m_canon->getCurrentImageSize()); xmlWriter.writeTextElement("WhiteBalance", m_canon->getCurrentWhiteBalance()); xmlWriter.writeTextElement("ColorTemperature", @@ -2324,8 +2470,36 @@ void StopMotion::saveXmlFile() { QString::number(m_canon->m_finalZoomPoint.x)); xmlWriter.writeTextElement("FocusCheckLocationY", QString::number(m_canon->m_finalZoomPoint.y)); -#endif } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + xmlWriter.writeTextElement("Webcam", "no"); + xmlWriter.writeTextElement("CameraName", m_gphotocam->m_cameraName); + xmlWriter.writeTextElement("Aperture", m_gphotocam->m_displayedAperture); + xmlWriter.writeTextElement("ShutterSpeed", + m_gphotocam->m_displayedShutterSpeed); + xmlWriter.writeTextElement("ISO", m_gphotocam->m_displayedIso); + xmlWriter.writeTextElement("PictureStyle", + m_gphotocam->getCurrentPictureStyle()); + xmlWriter.writeTextElement("ImageQuality", + m_gphotocam->getCurrentImageQuality()); + xmlWriter.writeTextElement("ImageSize", + m_gphotocam->getCurrentImageSize()); + xmlWriter.writeTextElement("WhiteBalance", + m_gphotocam->getCurrentWhiteBalance()); + xmlWriter.writeTextElement("ColorTemperature", + m_gphotocam->getCurrentColorTemperature()); + xmlWriter.writeTextElement("ExposureCompensation", + m_gphotocam->getCurrentExposureCompensation()); + xmlWriter.writeTextElement( + "FocusCheckLocationX", + QString::number(m_gphotocam->m_finalZoomPoint.x)); + xmlWriter.writeTextElement( + "FocusCheckLocationY", + QString::number(m_gphotocam->m_finalZoomPoint.y)); + } +#endif xmlWriter.writeEndElement(); xmlWriter.writeStartElement("Images"); @@ -2343,8 +2517,8 @@ bool StopMotion::loadXmlFile() { ToonzScene *scene = app->getCurrentScene()->getScene(); TXsheet *xsh = scene->getXsheet(); - bool webcam = false; - bool foundCamera = false; + bool foundCamera = false; + CameraType cameraType = CameraType::None; QString text; int x; int y; @@ -2360,114 +2534,201 @@ bool StopMotion::loadXmlFile() { QXmlStreamReader xmlReader; xmlReader.setDevice(&xmlFile); xmlReader.readNext(); + QList cameras = QCameraInfo::availableCameras(); + int webCount = cameras.count(); while (!xmlReader.atEnd()) { if (xmlReader.isStartElement()) { if (xmlReader.name() == "Webcam") { - text = xmlReader.readElementText(); - if (text == "yes") webcam = true; - } - if (xmlReader.name() == "CameraName") { + text = xmlReader.readElementText(); + if (text == "yes") cameraType = CameraType::Web; + } else if (xmlReader.name() == "CameraName") { text = xmlReader.readElementText(); - if (webcam) { - QList cameras = QCameraInfo::availableCameras(); - if (cameras.size() > 0) { - for (int i = 0; i < cameras.size(); i++) { - if (cameras.at(i).description() == text) { - changeCameras(i + 1); + if (cameraType == CameraType::Web) { + for (int i = 0; i < webCount; i++) { + if (cameras.at(i).description() == text) { + changeCameras(i + 1, CameraType::Web, i); + foundCamera = true; + break; + } + } + } else { + int canonCount = 0; + int gphotoCount = 0; +#ifdef WITH_CANON + canonCount = m_canon->getCameraCount(); + for (int i = 0; i < canonCount; i++) { + m_canon->getCamera(i); + m_canon->openCameraSession(); + QString camName = QString::fromStdString(m_canon->getCameraName()); + m_canon->closeCameraSession(); + + if (camName == text) { + changeCameras((webCount + i) + 1, CameraType::CanonDSLR, i); + foundCamera = true; + cameraType = CameraType::CanonDSLR; + break; + } + } +#endif +#ifdef WITH_GPHOTO2 + // If it's a canon camera, ignore the one in the gphoto list + if (!foundCamera) { + gphotoCount = m_gphotocam->getCameraCount(); + for (int i = 0; i < gphotoCount; i++) { + if (m_gphotocam->getCameraName(i) == text) { + changeCameras((webCount + canonCount + i) + 1, + CameraType::GPhoto, i); foundCamera = true; + cameraType = CameraType::GPhoto; break; } } } - } else { -#ifdef WITH_CANON - QString camName = ""; - if (m_canon->getCameraCount() > 0) { - m_canon->openCameraSession(); - camName = QString::fromStdString(m_canon->getCameraName()); - m_canon->closeCameraSession(); - } - if (text == camName) { - changeCameras(-1); - foundCamera = true; - } #endif } - } - if (xmlReader.name() == "CameraResolutionX") { + } else if (xmlReader.name() == "CameraResolutionX") { text = xmlReader.readElementText(); x = text.toInt(); - } - if (xmlReader.name() == "CameraResolutionY") { + } else if (xmlReader.name() == "CameraResolutionY") { text = xmlReader.readElementText(); y = text.toInt(); - if (foundCamera == true && webcam == true) { + if (foundCamera == true && cameraType == CameraType::Web) { setWebcamResolution( QString(QString::number(x) + " x " + QString::number(y))); } - } + } else if (xmlReader.name() == "Aperture") { + text = xmlReader.readElementText(); + if (foundCamera == true) { #ifdef WITH_CANON - if (xmlReader.name() == "Aperture") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setAperture(text); - } - } - if (xmlReader.name() == "ShutterSpeed") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setShutterSpeed(text); - } - } - if (xmlReader.name() == "ISO") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setIso(text); - } - } - if (xmlReader.name() == "PictureStyle") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setPictureStyle(text); - } - } - if (xmlReader.name() == "ImageQuality") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setImageQuality(text); - } - } - if (xmlReader.name() == "WhiteBalance") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setWhiteBalance(text); - } - } - if (xmlReader.name() == "ColorTemperature") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setColorTemperature(text); - } - } - if (xmlReader.name() == "ExposureCompensation") { - text = xmlReader.readElementText(); - if (foundCamera == true && webcam == false) { - m_canon->setExposureCompensation(text); - } - } - if (xmlReader.name() == "FocusCheckLocationX") { - text = xmlReader.readElementText(); - m_canon->m_finalZoomPoint.x = text.toInt(); - } - if (xmlReader.name() == "FocusCheckLocationY") { - text = xmlReader.readElementText(); - m_canon->m_finalZoomPoint.y = text.toInt(); - } + if (cameraType == CameraType::CanonDSLR) m_canon->setAperture(text); #endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) m_gphotocam->setAperture(text); +#endif + } + } else if (xmlReader.name() == "ShutterSpeed") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setShutterSpeed(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setShutterSpeed(text); +#endif + } + } else if (xmlReader.name() == "ISO") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) m_canon->setIso(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) m_gphotocam->setIso(text); +#endif + } + } else if (xmlReader.name() == "PictureStyle") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setPictureStyle(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setPictureStyle(text); +#endif + } + } else if (xmlReader.name() == "ImageQuality") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setImageQuality(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setImageQuality(text); +#endif + } + } else if (xmlReader.name() == "ImageSize") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + //if (cameraType == CameraType::CanonDSLR) + // m_canon->setImageSize(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setImageSize(text); +#endif + } + } else if (xmlReader.name() == "WhiteBalance") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setWhiteBalance(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setWhiteBalance(text); +#endif + } + } else if (xmlReader.name() == "ColorTemperature") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setColorTemperature(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setColorTemperature(text); +#endif + } + } else if (xmlReader.name() == "ExposureCompensation") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->setExposureCompensation(text); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->setExposureCompensation(text); +#endif + } + } else if (xmlReader.name() == "FocusCheckLocationX") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->m_finalZoomPoint.x = text.toInt(); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->m_finalZoomPoint.x = text.toInt(); +#endif + } + } else if (xmlReader.name() == "FocusCheckLocationY") { + text = xmlReader.readElementText(); + if (foundCamera == true) { +#ifdef WITH_CANON + if (cameraType == CameraType::CanonDSLR) + m_canon->m_finalZoomPoint.y = text.toInt(); +#endif +#ifdef WITH_GPHOTO2 + if (cameraType == CameraType::GPhoto) + m_gphotocam->m_finalZoomPoint.y = text.toInt(); +#endif + } + } } xmlReader.readNext(); } - emit(updateStopMotionControls(webcam)); + emit(updateStopMotionControls()); return true; } @@ -2615,10 +2876,16 @@ void StopMotion::refreshFrameInfo() { bool sessionOpen = false; #ifdef WITH_CANON - sessionOpen = m_canon->m_sessionOpen; + if (m_currentCameraType == CameraType::CanonDSLR) + sessionOpen = m_canon->m_sessionOpen; +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + sessionOpen = m_gphotocam->m_sessionOpen; #endif - if ((!sessionOpen && m_liveViewStatus < LiveViewOpen) && !m_usingWebcam) { + if ((!sessionOpen && m_liveViewStatus < LiveViewOpen) && + m_currentCameraType != CameraType::Web) { m_frameInfoText = ""; return; } @@ -2635,18 +2902,22 @@ void StopMotion::refreshFrameInfo() { int frameNumber = m_frameNumber; TDimension stopMotionRes; - bool checkRes = true; - if (m_usingWebcam) stopMotionRes = m_liveViewImageDimensions; + bool checkRes = true; + if (m_currentCameraType == CameraType::Web) + stopMotionRes = m_liveViewImageDimensions; #ifdef WITH_CANON - - if (!m_usingWebcam) { + if (m_currentCameraType == CameraType::CanonDSLR) stopMotionRes = m_canon->m_proxyImageDimensions; - if (m_canon->m_proxyImageDimensions == TDimension(0, 0)) { - checkRes = false; - } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + stopMotionRes = m_gphotocam->m_proxyImageDimensions; +#endif + + if (stopMotionRes == TDimension(0, 0)) { + checkRes = false; } -#endif // else // stopMotionRes = m_fullImageDimensions; @@ -2963,83 +3234,85 @@ void StopMotion::setToNextNewLevel() { void StopMotion::refreshCameraList() { QString camera = ""; bool hasCamera = false; + + if (m_currentCameraType == CameraType::Web) { + QList cameras = QCameraInfo::availableCameras(); + for (int i = 0; i < cameras.size(); i++) { + if (cameras.at(i).description() == m_webcam->getWebcamDescription()) { + hasCamera = true; + camera = m_webcam->getWebcamDescription(); + break; + } + } + } #ifdef WITH_CANON - if (m_canon->m_sessionOpen && m_canon->getCameraCount() > 0 && - !m_usingWebcam && m_canon->m_cameraName == m_canon->getCameraName()) { + if (m_currentCameraType == CameraType::CanonDSLR && m_canon->m_sessionOpen && + m_canon->getCameraCount() > 0 && + m_canon->m_cameraName == m_canon->getCameraName()) { hasCamera = true; camera = QString::fromStdString(m_canon->m_cameraName); } #endif - if (m_usingWebcam) { - QList cameras = QCameraInfo::availableCameras(); - if (m_usingWebcam && cameras.size() > 0) { - for (int i = 0; i < cameras.size(); i++) { - if (cameras.at(i).description() == m_webcam->getWebcamDescription()) { - hasCamera = true; - camera = m_webcam->getWebcamDescription(); - break; - } - } - } +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto && m_gphotocam->m_sessionOpen) { + hasCamera = true; + camera = m_gphotocam->m_cameraName; } +#endif if (!hasCamera) disconnectAllCameras(); emit(updateCameraList(camera)); } //----------------------------------------------------------------- -void StopMotion::changeCameras(int index) { - // note: index is negative if this is called to load DSLR from load settings - - QList cameras = QCameraInfo::availableCameras(); +void StopMotion::changeCameras(int comboIndex, CameraType cameraType, + int cameraIndex) { + // first see if the index didn't actually change + if (cameraType == m_currentCameraType && + cameraIndex == m_currentCameraTypeIndex) + return; // if selected the non-connected state, then disconnect the current camera - if (index == 0) { + if (cameraType == CameraType::None) { disconnectAllCameras(); stopInterval(); return; } - // There is a "Select Camera" as the first index - index -= 1; - - // first see if the index didn't actually change - if (cameras.size() > 0 && index < cameras.size() && index >= 0) { - if (cameras.at(index).deviceName() == m_webcam->getWebcamDeviceName()) { - return; - } - } - -#ifdef WITH_CANON - if ((index > cameras.size() - 1) && m_canon->m_sessionOpen) return; -#endif - // close live view if open int liveViewStatus = m_liveViewStatus; if (liveViewStatus > LiveViewClosed) { toggleLiveView(); } - // Check if its a webcam or DSLR - // Webcams are listed first, so see if one of them is selected - if (index < 0 || index > cameras.size() - 1) { - m_usingWebcam = false; - } else { - m_usingWebcam = true; - m_webcam->setWebcamIndex(index); + // close current camera if open + if (m_currentCameraType == CameraType::Web) { + m_webcam->clearWebcam(); } - - // in case the camera is not changed - if (m_usingWebcam) { #ifdef WITH_CANON - if (m_canon->m_sessionOpen && m_canon->getCameraCount() > 0) { - m_canon->closeCameraSession(); - } + if (m_currentCameraType == CameraType::CanonDSLR) { + if (m_canon->m_sessionOpen) m_canon->closeCameraSession(); + m_canon->releaseCamera(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + if (m_gphotocam->m_sessionOpen) m_gphotocam->closeCameraSession(); + m_gphotocam->releaseCamera(); + } #endif - m_webcam->setWebcam(new QCamera(cameras.at(index))); - m_webcam->setWebcamDeviceName(cameras.at(index).deviceName()); - m_webcam->setWebcamDescription(cameras.at(index).description()); + m_currentCameraType = cameraType; + m_currentCameraTypeIndex = cameraIndex; + + if (m_currentCameraType == CameraType::Web) { + m_webcam->setWebcamIndex(cameraIndex); + + QList cameras = QCameraInfo::availableCameras(); + + m_webcam->setWebcam(new QCamera(cameras.at(cameraIndex))); + m_webcam->setWebcamDeviceName(cameras.at(cameraIndex).deviceName()); + m_webcam->setWebcamDescription(cameras.at(cameraIndex).description()); // loading new camera m_webcam->getWebcam()->load(); @@ -3072,24 +3345,33 @@ void StopMotion::changeCameras(int index) { setWebcamResolution( QString(QString::number(width) + " x " + QString::number(height))); setTEnvCameraName(m_webcam->getWebcamDescription().toStdString()); -// emit(newCameraSelected(index + 1, true)); - emit(changeCameraIndex(index + 1)); + // emit(newCameraSelected(index + 1, true)); + emit(changeCameraIndex(comboIndex)); emit(webcamResolutionsChanged()); emit(newWebcamResolutionSelected(sizeCount)); - - } else { + } #ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { + if (m_canon->getCanonIndex() != cameraIndex) { + if (m_canon->getCamera(cameraIndex)) m_canon->setCanonIndex(cameraIndex); + } m_canon->openCameraSession(); setTEnvCameraName(m_canon->getCameraName()); - if (index == -2) { - index = cameras.size(); - } - m_webcam->clearWebcam(); - -// emit(newCameraSelected(index + 1, false)); - emit(changeCameraIndex(index + 1)); -#endif + emit(changeCameraIndex(comboIndex)); } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + if (m_gphotocam->getGphotoIndex() != cameraIndex) { + if (m_gphotocam->getCamera(cameraIndex)) + m_gphotocam->setGphotoIndex(cameraIndex); + } + m_gphotocam->initializeCamera(); + m_gphotocam->openCameraSession(); + setTEnvCameraName(m_gphotocam->getCameraName(cameraIndex).toStdString()); + emit(changeCameraIndex(comboIndex)); + } +#endif if (m_useNumpadShortcuts) toggleNumpadShortcuts(true); m_liveViewDpi = TPointD(0.0, 0.0); m_liveViewImageDimensions = TDimension(0, 0); @@ -3149,36 +3431,51 @@ void StopMotion::setWebcamResolution(QString resolution) { //----------------------------------------------------------------- bool StopMotion::toggleLiveView() { - bool sessionOpen = false; + bool retVal = false; -#ifdef WITH_CANON - sessionOpen = m_canon->m_sessionOpen; -#endif + if (m_currentCameraType == CameraType::None) { + DVGui::warning(tr("No camera selected.")); + return false; + } - if ((sessionOpen || m_usingWebcam) && m_liveViewStatus == LiveViewClosed) { + if (m_liveViewStatus == LiveViewClosed) { m_liveViewDpi = TPointD(0.0, 0.0); m_liveViewImageDimensions = TDimension(0, 0); - if (!m_usingWebcam) { #ifdef WITH_CANON - m_canon->startCanonLiveView(); + // m_liveViewStatus is set by startLiveView if successful + if (m_currentCameraType == CameraType::CanonDSLR && + (m_canon->startLiveView() != EDS_ERR_OK)) { + DVGui::warning(tr("Unable to start Live View.")); + return false; + } #endif - } else +#ifdef WITH_GPHOTO2 + // m_liveViewStatus is set by startLiveView if successful + if (m_currentCameraType == CameraType::GPhoto && + !m_gphotocam->startLiveView()) { + DVGui::warning(tr("Unable to start Live View.")); + return false; + } +#endif + if (m_currentCameraType == CameraType::Web) m_liveViewStatus = LiveViewStarting; + loadLineUpImage(); m_timer->start(40); emit(liveViewChanged(true)); Preferences::instance()->setValue(rewindAfterPlayback, false); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); - return true; - } else if ((sessionOpen || m_usingWebcam) && - m_liveViewStatus > LiveViewClosed) { - if (!m_usingWebcam) { + retVal = true; + } else if (m_liveViewStatus > LiveViewClosed) { #ifdef WITH_CANON - m_canon->endCanonLiveView(); + if (m_currentCameraType == CameraType::CanonDSLR) + m_canon->endLiveView(); #endif - } else { - m_webcam->releaseWebcam(); - } +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + m_gphotocam->endLiveView(); +#endif + if (m_currentCameraType == CameraType::Web) m_webcam->releaseWebcam(); m_timer->stop(); emit(liveViewStopped()); @@ -3188,11 +3485,10 @@ bool StopMotion::toggleLiveView() { } TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); m_liveViewStatus = LiveViewClosed; - return false; - } else { - DVGui::warning(tr("No camera selected.")); - return false; + retVal = false; } + + return retVal; } //----------------------------------------------------------------- @@ -3239,6 +3535,133 @@ void StopMotion::setTEnvCameraResolution(std::string resolution) { StopMotionCameraResolution = resolution; } +//----------------------------------------------------------------- + +bool StopMotion::isPickLiveViewZoom() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) + return m_canon->m_pickLiveViewZoom; +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + return m_gphotocam->m_pickLiveViewZoom; +#endif + + return false; +} + +//----------------------------------------------------------------- + +bool StopMotion::isZooming() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) return m_canon->m_zooming; +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) return m_gphotocam->m_zooming; +#endif + + return false; +} + +//----------------------------------------------------------------- + +bool StopMotion::isLiveViewZoomReadyToPick() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) + return m_canon->m_liveViewZoomReadyToPick; +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + return m_gphotocam->m_liveViewZoomReadyToPick; +#endif + + return false; +} + +//----------------------------------------------------------------- + +void StopMotion::makeZoomPoint(TPointD pickPos) { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { + m_canon->makeZoomPoint(pickPos); + m_canon->setZoomPoint(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + m_gphotocam->makeZoomPoint(pickPos); + m_gphotocam->setZoomPoint(); + } +#endif +} + +//----------------------------------------------------------------- + +TRect StopMotion::getZoomRect() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) return m_canon->m_zoomRect; +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) return m_gphotocam->m_zoomRect; +#endif + + return TRect(0, 0, 0, 0); +} + +//----------------------------------------------------------------- + +void StopMotion::toggleZoomPicking() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) + m_canon->toggleZoomPicking(); +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + m_gphotocam->toggleZoomPicking(); +#endif +} + +//----------------------------------------------------------------- + +void StopMotion::calculateZoomPoint() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) + m_canon->calculateZoomPoint(); +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) + m_gphotocam->calculateZoomPoint(); +#endif +} + +//----------------------------------------------------------------- + +void StopMotion::setZoomPoint() { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) m_canon->setZoomPoint(); +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) m_gphotocam->setZoomPoint(); +#endif +} + +//----------------------------------------------------------------- + +void StopMotion::adjustLiveViewZoomPickPoint(int x, int y) { +#ifdef WITH_CANON + if (m_currentCameraType == CameraType::CanonDSLR) { + m_canon->m_liveViewZoomPickPoint.x += x; + m_canon->m_liveViewZoomPickPoint.y += y; + } +#endif +#ifdef WITH_GPHOTO2 + if (m_currentCameraType == CameraType::GPhoto) { + m_gphotocam->m_liveViewZoomPickPoint.x += x; + m_gphotocam->m_liveViewZoomPickPoint.y += y; + } +#endif +} + //============================================================================= class StopMotionCaptureCommand : public MenuItemHandler { @@ -3384,7 +3807,14 @@ public: StopMotionPickFocusCheck() : MenuItemHandler(MI_StopMotionPickFocusCheck) {} void execute() { StopMotion *sm = StopMotion::instance(); - sm->m_canon->toggleZoomPicking(); +#ifdef WITH_CANON + if (sm->m_currentCameraType == CameraType::CanonDSLR) + sm->m_canon->toggleZoomPicking(); +#endif +#ifdef WITH_GPHOTO2 + if (sm->m_currentCameraType == CameraType::GPhoto) + sm->m_gphotocam->toggleZoomPicking(); +#endif } } StopMotionPickFocusCheck; @@ -3395,7 +3825,14 @@ public: StopMotionToggleZoomCommand() : MenuItemHandler(MI_StopMotionToggleZoom) {} void execute() { StopMotion *sm = StopMotion::instance(); - sm->m_canon->zoomLiveView(); +#ifdef WITH_CANON + if (sm->m_currentCameraType == CameraType::CanonDSLR) + sm->m_canon->zoomLiveView(); +#endif +#ifdef WITH_GPHOTO2 + if (sm->m_currentCameraType == CameraType::GPhoto) + sm->m_gphotocam->zoomLiveView(); +#endif } } StopMotionToggleZoomCommand; #endif \ No newline at end of file diff --git a/toonz/sources/stopmotion/stopmotion.h b/toonz/sources/stopmotion/stopmotion.h index 213a40bb..154e227f 100644 --- a/toonz/sources/stopmotion/stopmotion.h +++ b/toonz/sources/stopmotion/stopmotion.h @@ -23,6 +23,7 @@ #include "canon.h" #include "stopmotionserial.h" #include "stopmotionlight.h" +#include "gphotocam.h" #include "toonz/namebuilder.h" #include "toonz/txshsimplelevel.h" @@ -51,6 +52,8 @@ public: enum ASPECT_RATIO { FOUR_THREE = 0, THREE_TWO, SIXTEEN_NINE, OTHER_RATIO }; +enum CameraType { None = 0, Web, CanonDSLR, GPhoto }; + class StopMotion : public QObject { // Singleton Q_OBJECT @@ -98,10 +101,13 @@ public: Webcam* m_webcam; Canon* m_canon; + GPhotoCam* m_gphotocam; StopMotionSerial* m_serial; StopMotionLight* m_light; - bool m_usingWebcam = false; + CameraType m_currentCameraType = CameraType::None; + int m_currentCameraTypeIndex = -1; + bool m_placeOnXSheet = true; bool m_alwaysLiveView = false; bool m_userCalledPause = false; @@ -175,7 +181,7 @@ public: std::string getTEnvCameraResolution(); void setTEnvCameraResolution(std::string resolution); void disconnectAllCameras(); - void changeCameras(int index); + void changeCameras(int comboIndex, CameraType cameraType, int cameraIndex); void refreshCameraList(); // commands @@ -236,6 +242,16 @@ public: void saveTestShot(); void saveTestXml(TFilePath testsXml, int number); + bool isPickLiveViewZoom(); + bool isZooming(); + bool isLiveViewZoomReadyToPick(); + void makeZoomPoint(TPointD pickPos); + TRect getZoomRect(); + void toggleZoomPicking(); + void calculateZoomPoint(); + void setZoomPoint(); + void adjustLiveViewZoomPickPoint(int x, int y); + public slots: // timers void onTimeout(); @@ -252,12 +268,12 @@ public slots: signals: // camera stuff void cameraChanged(QString); - void newCameraSelected(int, bool); + void newCameraSelected(int); void webcamResolutionsChanged(); void newWebcamResolutionSelected(int); void updateCameraList(QString); void changeCameraIndex(int); - void updateStopMotionControls(bool); + void updateStopMotionControls(); // live view and images void newLiveViewImageReady(); diff --git a/toonz/sources/stopmotion/stopmotioncontroller.cpp b/toonz/sources/stopmotion/stopmotioncontroller.cpp index fa3f5af6..c47b3eb0 100644 --- a/toonz/sources/stopmotion/stopmotioncontroller.cpp +++ b/toonz/sources/stopmotion/stopmotioncontroller.cpp @@ -672,13 +672,13 @@ void StopMotionSaveInFolderPopup::updateParentFolder() { //============================================================================= -FrameNumberLineEdit::FrameNumberLineEdit(QWidget* parent, TFrameId fId, +FrameNumberLineEdit::FrameNumberLineEdit(QWidget *parent, TFrameId fId, bool acceptLetter) : LineEdit(parent) { if (acceptLetter) { QString regExpStr = QString("^%1$").arg(TFilePath::fidRegExpStr()); m_regexpValidator = new QRegExpValidator(QRegExp(regExpStr), this); - TProjectManager* pm = TProjectManager::instance(); + TProjectManager *pm = TProjectManager::instance(); pm->addListener(this); } else m_regexpValidator = new QRegExpValidator(QRegExp("^\\d{1,4}$"), this); @@ -704,7 +704,7 @@ void FrameNumberLineEdit::updateValidator() { //----------------------------------------------------------------------------- void FrameNumberLineEdit::updateSize() { - FilePathProperties* fpProp = + FilePathProperties *fpProp = TProjectManager::instance()->getCurrentProject()->getFilePathProperties(); bool useStandard = fpProp->useStandard(); int letterCount = fpProp->letterCountForSuffix(); @@ -762,7 +762,7 @@ TFrameId FrameNumberLineEdit::getValue() { //----------------------------------------------------------------------------- void FrameNumberLineEdit::onProjectSwitched() { - QRegExpValidator* oldValidator = m_regexpValidator; + QRegExpValidator *oldValidator = m_regexpValidator; QString regExpStr = QString("^%1$").arg(TFilePath::fidRegExpStr()); m_regexpValidator = new QRegExpValidator(QRegExp(regExpStr), this); updateValidator(); @@ -981,6 +981,9 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { m_focusNear3Button->setFixedSize(32, 28); m_focusFar3Button = new QPushButton(tr(">>>"), this); m_focusFar3Button->setFixedSize(32, 28); + m_manualFocusSlider = new QSlider(Qt::Horizontal, this); + m_manualFocusSlider->setRange(0, 255); + m_manualFocusSlider->setTickInterval(5); //*****//**** QVBoxLayout *controlLayout = new QVBoxLayout(); @@ -1146,6 +1149,7 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { m_exposureCombo = new QComboBox(this); m_whiteBalanceCombo = new QComboBox(this); m_imageQualityCombo = new QComboBox(this); + m_imageSizeCombo = new QComboBox(this); m_pictureStyleCombo = new QComboBox(this); m_cameraSettingsLabel = new QLabel(tr("Camera Model"), this); m_cameraModeLabel = new QLabel(tr("Camera Mode"), this); @@ -1198,39 +1202,57 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { settingsGridLayout->addWidget(new QLabel(tr("Image Quality: ")), 15, 0, Qt::AlignRight); settingsGridLayout->addWidget(m_imageQualityCombo, 15, 1, Qt::AlignLeft); - settingsGridLayout->addWidget(new QLabel(tr("Exposure: ")), 16, 0, + settingsGridLayout->addWidget(new QLabel(tr("Image Size: ")), 16, 0, Qt::AlignRight); - settingsGridLayout->addWidget(m_exposureCombo, 16, 1, Qt::AlignLeft); - settingsGridLayout->addWidget(new QLabel(" ", this), 17, 0, 1, 2, + settingsGridLayout->addWidget(m_imageSizeCombo, 16, 1, Qt::AlignLeft); + settingsGridLayout->addWidget(new QLabel(tr("Exposure: ")), 17, 0, + Qt::AlignRight); + settingsGridLayout->addWidget(m_exposureCombo, 17, 1, Qt::AlignLeft); + settingsGridLayout->addWidget(new QLabel(" ", this), 18, 0, 1, 2, Qt::AlignCenter); - settingsGridLayout->addWidget(m_liveViewCompensationLabel, 18, 0, 1, 2, + settingsGridLayout->addWidget(m_liveViewCompensationLabel, 19, 0, 1, 2, Qt::AlignCenter); - settingsGridLayout->addWidget(m_liveViewCompensationSlider, 19, 0, 1, 2, - Qt::AlignCenter); - settingsGridLayout->addWidget(new QLabel(" ", this), 20, 0, 1, 2, + settingsGridLayout->addWidget(m_liveViewCompensationSlider, 20, 0, 1, 2, Qt::AlignCenter); settingsGridLayout->addWidget(new QLabel(" ", this), 21, 0, 1, 2, Qt::AlignCenter); + settingsGridLayout->addWidget(new QLabel(" ", this), 22, 0, 1, 2, + Qt::AlignCenter); settingsGridLayout->setColumnStretch(1, 30); } settingsLayout->addLayout(settingsGridLayout, 0); - m_focusAndZoomLayout = new QHBoxLayout; - m_focusAndZoomLayout->addStretch(); - m_focusAndZoomLayout->addWidget(m_focusNear3Button, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_focusNear2Button, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_focusNearButton, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_zoomButton, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_pickZoomButton, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_focusFarButton, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_focusFar2Button, Qt::AlignCenter); - m_focusAndZoomLayout->addWidget(m_focusFar3Button, Qt::AlignCenter); - m_focusAndZoomLayout->addStretch(); - // settingsLayout->addStretch(); - settingsLayout->addLayout(m_focusAndZoomLayout); - m_settingsTakeTestButton = new QPushButton(tr("Test Shot")); - m_settingsTakeTestButton->setFixedHeight(25); - settingsLayout->addWidget(m_settingsTakeTestButton); + + QVBoxLayout *focusTestLayout = new QVBoxLayout; + focusTestLayout->setMargin(3); + focusTestLayout->setSpacing(0); + { + focusTestLayout->addSpacing(2); + m_focusAndZoomLayout = new QHBoxLayout; + m_focusAndZoomLayout->setMargin(0); + m_focusAndZoomLayout->setSpacing(0); + { + m_focusAndZoomLayout->addWidget(m_manualFocusSlider, Qt::AlignCenter); + + m_focusAndZoomLayout->addWidget(m_focusNear3Button, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_focusNear2Button, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_focusNearButton, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_zoomButton, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_pickZoomButton, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_focusFarButton, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_focusFar2Button, Qt::AlignCenter); + m_focusAndZoomLayout->addWidget(m_focusFar3Button, Qt::AlignCenter); + } + focusTestLayout->addLayout(m_focusAndZoomLayout); + + m_settingsTakeTestButton = new QPushButton(tr("Test Shot")); + m_settingsTakeTestButton->setFixedHeight(25); + focusTestLayout->addWidget(m_settingsTakeTestButton); + focusTestLayout->addSpacing(2); + } + QGroupBox *focusTestBox = new QGroupBox(tr("Manual Focus"), this); + focusTestBox->setLayout(focusTestLayout); + settingsLayout->addWidget(focusTestBox); settingsLayout->addStretch(); m_dslrFrame = new QFrame(); m_dslrFrame->setLayout(settingsLayout); @@ -1431,10 +1453,10 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { m_cameraSettingsPage->setLayout(innerSettingsLayout); // Make Options Page - QGroupBox *webcamBox = new QGroupBox(tr("Webcam Options"), this); - QGroupBox *dslrBox = new QGroupBox(tr("DSLR Options"), this); - m_timerCB = new QGroupBox(tr("Use Time Lapse"), this); - m_timerIntervalFld = new DVGui::DoubleField(this, true, 1); + QGroupBox *webcamBox = new QGroupBox(tr("Webcam Options"), this); + QGroupBox *dslrBox = new QGroupBox(tr("DSLR Options"), this); + m_timerCB = new QGroupBox(tr("Use Time Lapse"), this); + m_timerIntervalFld = new DVGui::DoubleField(this, true, 1); m_timerCB->setCheckable(true); m_timerCB->setObjectName("CleanupSettingsFrame"); m_timerCB->setChecked(false); @@ -1875,16 +1897,16 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { SLOT(refreshCameraList(QString))); ret = ret && connect(m_stopMotion, SIGNAL(liveViewChanged(bool)), this, SLOT(onLiveViewChanged(bool))); - ret = ret && connect(m_stopMotion, SIGNAL(newCameraSelected(int, bool)), this, - SLOT(onNewCameraSelected(int, bool))); + ret = ret && connect(m_stopMotion, SIGNAL(newCameraSelected(int)), this, + SLOT(onNewCameraSelected(int))); ret = ret && connect(m_stopMotion, SIGNAL(cameraChanged(QString)), this, SLOT(refreshCameraList(QString))); ret = ret && connect(m_stopMotion, SIGNAL(optionsChanged()), this, SLOT(refreshOptionsLists())); ret = ret && connect(m_stopMotion, SIGNAL(changeCameraIndex(int)), this, SLOT(onCameraIndexChanged(int))); - ret = ret && connect(m_stopMotion, SIGNAL(updateStopMotionControls(bool)), - this, SLOT(onUpdateStopMotionControls(bool))); + ret = ret && connect(m_stopMotion, SIGNAL(updateStopMotionControls()), this, + SLOT(onUpdateStopMotionControls())); // EOS Connections ret = ret && @@ -1903,6 +1925,8 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { SLOT(onFocusNear3())); ret = ret && connect(m_focusFar3Button, SIGNAL(clicked()), this, SLOT(onFocusFar3())); + + // Canon stuff ret = ret && connect(m_stopMotion->m_canon, SIGNAL(apertureChangedSignal(QString)), this, SLOT(onApertureChangedSignal(QString))); @@ -1920,6 +1944,9 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { ret = ret && connect(m_stopMotion->m_canon, SIGNAL(imageQualityChangedSignal(QString)), this, SLOT(onImageQualityChangedSignal(QString))); + //ret = ret && connect(m_stopMotion->m_canon, + // SIGNAL(imageSizeChangedSignal(QString)), this, + // SLOT(onImageSizeChangedSignal(QString))); ret = ret && connect(m_stopMotion->m_canon, SIGNAL(pictureStyleChangedSignal(QString)), this, SLOT(onPictureStyleChangedSignal(QString))); @@ -1929,6 +1956,78 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { ret = ret && connect(m_stopMotion->m_canon, SIGNAL(liveViewOffsetChangedSignal(int)), this, SLOT(onLiveViewCompensationChangedSignal(int))); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(apertureOptionsChanged()), + this, SLOT(refreshApertureList())); + ret = ret && + connect(m_stopMotion->m_canon, SIGNAL(shutterSpeedOptionsChanged()), + this, SLOT(refreshShutterSpeedList())); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(isoOptionsChanged()), this, + SLOT(refreshIsoList())); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(exposureOptionsChanged()), + this, SLOT(refreshExposureList())); + ret = ret && + connect(m_stopMotion->m_canon, SIGNAL(whiteBalanceOptionsChanged()), + this, SLOT(refreshWhiteBalanceList())); + ret = ret && + connect(m_stopMotion->m_canon, SIGNAL(imageQualityOptionsChanged()), + this, SLOT(refreshImageQualityList())); + //ret = ret && + // connect(m_stopMotion->m_canon, SIGNAL(imageSizeOptionsChanged()), + // this, SLOT(refreshImageSizeList())); + ret = ret && + connect(m_stopMotion->m_canon, SIGNAL(pictureStyleOptionsChanged()), + this, SLOT(refreshPictureStyleList())); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(modeChanged()), this, + SLOT(refreshMode())); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(focusCheckToggled(bool)), + this, SLOT(onFocusCheckToggled(bool))); + ret = + ret && connect(m_stopMotion->m_canon, SIGNAL(pickFocusCheckToggled(bool)), + this, SLOT(onPickFocusCheckToggled(bool))); + + // GPhotocam connections + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(apertureChangedSignal(QString)), this, + SLOT(onApertureChangedSignal(QString))); + ret = ret && + connect(m_stopMotion->m_gphotocam, SIGNAL(isoChangedSignal(QString)), + this, SLOT(onIsoChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(shutterSpeedChangedSignal(QString)), this, + SLOT(onShutterSpeedChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(exposureChangedSignal(QString)), this, + SLOT(onExposureChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(whiteBalanceChangedSignal(QString)), this, + SLOT(onWhiteBalanceChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(imageQualityChangedSignal(QString)), this, + SLOT(onImageQualityChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(imageSizeChangedSignal(QString)), this, + SLOT(onImageSizeChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(pictureStyleChangedSignal(QString)), this, + SLOT(onPictureStyleChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(colorTemperatureChangedSignal(QString)), this, + SLOT(onColorTemperatureChangedSignal(QString))); + ret = ret && connect(m_stopMotion->m_gphotocam, SIGNAL(modeChanged()), this, + SLOT(refreshMode())); + ret = ret && connect(m_stopMotion->m_gphotocam, SIGNAL(modeChanged()), this, + SLOT(refreshOptionsLists())); + ret = ret && connect(m_stopMotion->m_gphotocam, SIGNAL(batteryChanged()), + this, SLOT(refreshMode())); + ret = ret && connect(m_stopMotion->m_gphotocam, + SIGNAL(liveViewOffsetChangedSignal(int)), this, + SLOT(onLiveViewCompensationChangedSignal(int))); + ret = ret && connect(m_stopMotion->m_canon, SIGNAL(focusCheckToggled(bool)), + this, SLOT(onFocusCheckToggled(bool))); + ret = ret && + connect(m_stopMotion->m_gphotocam, SIGNAL(pickFocusCheckToggled(bool)), + this, SLOT(onPickFocusCheckToggled(bool))); + ret = ret && connect(m_apertureSlider, SIGNAL(valueChanged(int)), this, SLOT(onApertureChanged(int))); ret = ret && connect(m_shutterSpeedSlider, SIGNAL(valueChanged(int)), this, @@ -1945,35 +2044,14 @@ StopMotionController::StopMotionController(QWidget *parent) : QWidget(parent) { SLOT(onColorTemperatureChanged(int))); ret = ret && connect(m_imageQualityCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onImageQualityChanged(int))); + ret = ret && connect(m_imageSizeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(onImageSizeChanged(int))); ret = ret && connect(m_pictureStyleCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onPictureStyleChanged(int))); - ret = ret && connect(m_stopMotion->m_canon, SIGNAL(apertureOptionsChanged()), - this, SLOT(refreshApertureList())); - ret = ret && - connect(m_stopMotion->m_canon, SIGNAL(shutterSpeedOptionsChanged()), - this, SLOT(refreshShutterSpeedList())); - ret = ret && connect(m_stopMotion->m_canon, SIGNAL(isoOptionsChanged()), this, - SLOT(refreshIsoList())); - ret = ret && connect(m_stopMotion->m_canon, SIGNAL(exposureOptionsChanged()), - this, SLOT(refreshExposureList())); - ret = ret && - connect(m_stopMotion->m_canon, SIGNAL(whiteBalanceOptionsChanged()), - this, SLOT(refreshWhiteBalanceList())); - ret = ret && - connect(m_stopMotion->m_canon, SIGNAL(imageQualityOptionsChanged()), - this, SLOT(refreshImageQualityList())); - ret = ret && - connect(m_stopMotion->m_canon, SIGNAL(pictureStyleOptionsChanged()), - this, SLOT(refreshPictureStyleList())); - ret = ret && connect(m_stopMotion->m_canon, SIGNAL(modeChanged()), this, - SLOT(refreshMode())); - ret = ret && connect(m_stopMotion->m_canon, SIGNAL(focusCheckToggled(bool)), - this, SLOT(onFocusCheckToggled(bool))); - ret = - ret && connect(m_stopMotion->m_canon, SIGNAL(pickFocusCheckToggled(bool)), - this, SLOT(onPickFocusCheckToggled(bool))); ret = ret && connect(m_settingsTakeTestButton, SIGNAL(clicked()), this, SLOT(onTakeTestButtonClicked())); + ret = ret && connect(m_manualFocusSlider, SIGNAL(valueChanged(int)), this, + SLOT(onManualFocusChanged(int))); // Webcam Specific Connections ret = ret && connect(m_stopMotion, SIGNAL(webcamResolutionsChanged()), this, @@ -2520,12 +2598,16 @@ void StopMotionController::refreshCameraListCalled() { void StopMotionController::refreshCameraList(QString activeCamera) { m_cameraListCombo->blockSignals(true); m_cameraListCombo->clear(); - m_cameraStatusLabel->hide(); + // m_cameraStatusLabel->hide(); QList webcams = m_stopMotion->m_webcam->getWebcams(); int count = webcams.count(); #ifdef WITH_CANON count += m_stopMotion->m_canon->getCameraCount(); #endif +#ifdef WITH_GPHOTO2 + count += m_stopMotion->m_gphotocam->getCameraCount(); +#endif + if (count < 1) { m_cameraListCombo->addItem(tr("No camera detected.")); m_cameraSettingsLabel->setText(tr("No camera detected")); @@ -2537,27 +2619,32 @@ void StopMotionController::refreshCameraList(QString activeCamera) { } else { int maxTextLength = 0; m_cameraListCombo->addItem(tr("- Select camera -")); - if (webcams.count() > 0) { - for (int c = 0; c < webcams.size(); c++) { - std::string name = webcams.at(c).deviceName().toStdString(); - QString camDesc = webcams.at(c).description(); - m_cameraListCombo->addItem(camDesc); - maxTextLength = std::max(maxTextLength, fontMetrics().width(camDesc)); - } + for (int c = 0; c < webcams.size(); c++) { + std::string name = webcams.at(c).deviceName().toStdString(); + QString camDesc = webcams.at(c).description(); + m_cameraListCombo->addItem(camDesc, QVariant::fromValue(c)); + maxTextLength = std::max(maxTextLength, fontMetrics().width(camDesc)); } #ifdef WITH_CANON - if (m_stopMotion->m_canon->getCameraCount() > 0) { + for (int c = 0; c < m_stopMotion->m_canon->getCameraCount(); c++) { QString name; - m_stopMotion->m_canon->getCamera(0); + m_stopMotion->m_canon->getCamera(c); bool open = m_stopMotion->m_canon->m_sessionOpen; if (!open) m_stopMotion->m_canon->openCameraSession(); name = QString::fromStdString(m_stopMotion->m_canon->getCameraName()); if (!open) m_stopMotion->m_canon->closeCameraSession(); - m_cameraSettingsLabel->setText(name); - m_cameraListCombo->addItem(name); + m_cameraListCombo->addItem(name, QVariant::fromValue(c)); maxTextLength = std::max(maxTextLength, fontMetrics().width(name)); } #endif +#ifdef WITH_GPHOTO2 + for (int c = 0; c < m_stopMotion->m_gphotocam->getCameraCount(); c++) { + QString name = m_stopMotion->m_gphotocam->getCameraName(c); + m_cameraListCombo->addItem(name, QVariant::fromValue(c)); + maxTextLength = std::max(maxTextLength, fontMetrics().width(name)); + } +#endif + m_cameraListCombo->setMaximumWidth(maxTextLength + 40); m_cameraListCombo->setEnabled(true); m_cameraListCombo->setCurrentIndex(0); @@ -2568,9 +2655,7 @@ void StopMotionController::refreshCameraList(QString activeCamera) { m_cameraListCombo->blockSignals(false); m_stopMotion->updateLevelNameAndFrame(m_levelNameEdit->text().toStdWString()); refreshOptionsLists(); -#ifdef WITH_CANON refreshMode(); -#endif } //----------------------------------------------------------------------------- @@ -2583,14 +2668,17 @@ void StopMotionController::refreshOptionsLists() { m_whiteBalanceCombo->blockSignals(true); m_kelvinSlider->blockSignals(true); m_imageQualityCombo->blockSignals(true); + m_imageSizeCombo->blockSignals(true); m_pictureStyleCombo->blockSignals(true); + m_manualFocusSlider->blockSignals(true); // m_isoCombo->clear(); // m_shutterSpeedCombo->clear(); // m_apertureSlider->clear(); m_exposureCombo->clear(); -#ifdef WITH_CANON - if (m_stopMotion->m_canon->getCameraCount() == 0) { + + if (m_stopMotion->m_currentCameraType == CameraType::Web || + m_stopMotion->m_currentCameraType == CameraType::None) { m_shutterSpeedSlider->setDisabled(true); m_isoSlider->setDisabled(true); m_apertureSlider->setDisabled(true); @@ -2598,7 +2686,9 @@ void StopMotionController::refreshOptionsLists() { m_whiteBalanceCombo->setDisabled(true); m_kelvinSlider->setDisabled(true); m_imageQualityCombo->setDisabled(true); + m_imageSizeCombo->setDisabled(true); m_pictureStyleCombo->setDisabled(true); + m_manualFocusSlider->setDisabled(true); return; } @@ -2608,34 +2698,68 @@ void StopMotionController::refreshOptionsLists() { refreshExposureList(); refreshWhiteBalanceList(); refreshImageQualityList(); + refreshImageSizeList(); refreshPictureStyleList(); -#endif + refreshManualFocusRange(); } //----------------------------------------------------------------------------- void StopMotionController::refreshMode() { -#ifdef WITH_CANON - if (m_stopMotion->m_canon->getCameraCount() == 0) { + QString mode = "-"; + QString battery = "-"; + + if (m_stopMotion->m_currentCameraType == CameraType::None || + m_stopMotion->m_currentCameraType == CameraType::Web) { m_cameraModeLabel->setText(""); m_cameraStatusLabel->hide(); return; } - QString mode = m_stopMotion->m_canon->getMode(); - QString battery = m_stopMotion->m_canon->getCurrentBatteryLevel(); + + m_cameraStatusLabel->show(); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + mode = m_stopMotion->m_canon->getMode(); + battery = m_stopMotion->m_canon->getCurrentBatteryLevel(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + mode = m_stopMotion->m_gphotocam->getMode(); + battery = m_stopMotion->m_gphotocam->getCurrentBatteryLevel(); + } +#endif m_cameraModeLabel->setText(tr("Mode: ") + mode); m_cameraStatusLabel->setText("Mode: " + mode + " - Battery: " + battery); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshApertureList() { -#ifdef WITH_CANON m_apertureSlider->blockSignals(true); - int count = 0; - m_stopMotion->m_canon->getAvailableApertures(); - count = m_stopMotion->m_canon->getApertureOptions().size(); + + QStringList apertureOptions; + QString currentAperture = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableApertures(); + apertureOptions = m_stopMotion->m_canon->getApertureOptions(); + + currentAperture = m_stopMotion->m_canon->getCurrentAperture(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableApertures(); + apertureOptions = m_stopMotion->m_gphotocam->getApertureOptions(); + + currentAperture = m_stopMotion->m_gphotocam->getCurrentAperture(); + } +#endif + + int count = apertureOptions.size(); if (count == 0) { m_apertureLabel->setText(tr("Aperture: Auto")); @@ -2643,25 +2767,40 @@ void StopMotionController::refreshApertureList() { m_apertureSlider->setRange(0, 0); } else { m_apertureSlider->setEnabled(true); - m_apertureLabel->setText(tr("Aperture: ") + - m_stopMotion->m_canon->getCurrentAperture()); + m_apertureLabel->setText(tr("Aperture: ") + currentAperture); m_apertureSlider->setRange(0, count - 1); - m_apertureSlider->setValue( - m_stopMotion->m_canon->getApertureOptions().lastIndexOf( - m_stopMotion->m_canon->getCurrentAperture())); + m_apertureSlider->setValue(apertureOptions.lastIndexOf(currentAperture)); } + m_apertureSlider->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshShutterSpeedList() { -#ifdef WITH_CANON m_shutterSpeedSlider->blockSignals(true); - int count = 0; - m_stopMotion->m_canon->getAvailableShutterSpeeds(); - count = m_stopMotion->m_canon->getShutterSpeedOptions().size(); + + QStringList shutterSpeedOptions; + QString currentShutterSpeed = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableShutterSpeeds(); + shutterSpeedOptions = m_stopMotion->m_canon->getShutterSpeedOptions(); + + currentShutterSpeed = m_stopMotion->m_canon->getCurrentShutterSpeed(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableShutterSpeeds(); + shutterSpeedOptions = m_stopMotion->m_gphotocam->getShutterSpeedOptions(); + + currentShutterSpeed = m_stopMotion->m_gphotocam->getCurrentShutterSpeed(); + } +#endif + + int count = shutterSpeedOptions.size(); if (count == 0) { m_shutterSpeedLabel->setText(tr("Shutter Speed: Auto")); @@ -2669,26 +2808,41 @@ void StopMotionController::refreshShutterSpeedList() { m_shutterSpeedSlider->setRange(0, 0); } else { m_shutterSpeedSlider->setEnabled(true); - m_shutterSpeedLabel->setText( - tr("Shutter Speed: ") + - m_stopMotion->m_canon->getCurrentShutterSpeed()); + m_shutterSpeedLabel->setText(tr("Shutter Speed: ") + currentShutterSpeed); m_shutterSpeedSlider->setRange(0, count - 1); m_shutterSpeedSlider->setValue( - m_stopMotion->m_canon->getShutterSpeedOptions().lastIndexOf( - m_stopMotion->m_canon->getCurrentShutterSpeed())); + shutterSpeedOptions.lastIndexOf(currentShutterSpeed)); } + m_shutterSpeedSlider->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshIsoList() { -#ifdef WITH_CANON m_isoSlider->blockSignals(true); - int count = 0; - m_stopMotion->m_canon->getAvailableIso(); - count = m_stopMotion->m_canon->getIsoOptions().size(); + + QStringList isoOptions; + QString currentIso = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableIso(); + isoOptions = m_stopMotion->m_canon->getIsoOptions(); + + currentIso = m_stopMotion->m_canon->getCurrentIso(); + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableIso(); + isoOptions = m_stopMotion->m_gphotocam->getIsoOptions(); + + currentIso = m_stopMotion->m_gphotocam->getCurrentIso(); + } +#endif + + int count = isoOptions.size(); if (count == 0) { m_isoLabel->setText(tr("Iso: ") + tr("Auto")); @@ -2696,80 +2850,176 @@ void StopMotionController::refreshIsoList() { m_isoSlider->setRange(0, 0); } else { m_isoSlider->setEnabled(true); - m_isoLabel->setText(tr("Iso: ") + m_stopMotion->m_canon->getCurrentIso()); + m_isoLabel->setText(tr("Iso: ") + currentIso); m_isoSlider->setRange(0, count - 1); - m_isoSlider->setValue(m_stopMotion->m_canon->getIsoOptions().lastIndexOf( - m_stopMotion->m_canon->getCurrentIso())); + m_isoSlider->setValue(isoOptions.lastIndexOf(currentIso)); } + m_isoSlider->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshExposureList() { -#ifdef WITH_CANON m_exposureCombo->blockSignals(true); m_exposureCombo->clear(); - m_stopMotion->m_canon->getAvailableExposureCompensations(); - QStringList options = m_stopMotion->m_canon->getExposureOptions(); - m_exposureCombo->addItems(options); - int maxTextLength = 0; - for (int i = 0; i < options.size(); i++) { - maxTextLength = std::max(maxTextLength, fontMetrics().width(options.at(i))); + + QStringList exposureOptions; + QString currentExposure = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableExposureCompensations(); + exposureOptions = m_stopMotion->m_canon->getExposureOptions(); + + currentExposure = m_stopMotion->m_canon->getCurrentExposureCompensation(); } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableExposureCompensations(); + exposureOptions = m_stopMotion->m_gphotocam->getExposureOptions(); + + currentExposure = + m_stopMotion->m_gphotocam->getCurrentExposureCompensation(); + } +#endif + + m_exposureCombo->addItems(exposureOptions); + + int maxTextLength = 0; + for (int i = 0; i < exposureOptions.size(); i++) { + maxTextLength = + std::max(maxTextLength, fontMetrics().width(exposureOptions.at(i))); + } + if (m_exposureCombo->count() == 0) { m_exposureCombo->addItem(tr("Disabled")); m_exposureCombo->setDisabled(true); m_exposureCombo->setMaximumWidth(fontMetrics().width("Disabled") + 25); } else { m_exposureCombo->setEnabled(true); - m_exposureCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentExposureCompensation()); + m_exposureCombo->setCurrentText(currentExposure); m_exposureCombo->setMaximumWidth(maxTextLength + 25); } + m_exposureCombo->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshWhiteBalanceList() { -#ifdef WITH_CANON m_whiteBalanceCombo->blockSignals(true); + m_whiteBalanceCombo->clear(); - m_stopMotion->m_canon->getAvailableWhiteBalances(); - QStringList options = m_stopMotion->m_canon->getWhiteBalanceOptions(); - m_whiteBalanceCombo->addItems(options); - int maxTextLength = 0; - for (int i = 0; i < options.size(); i++) { - maxTextLength = std::max(maxTextLength, fontMetrics().width(options.at(i))); + + QStringList whiteBalanceOptions; + QString currentWhiteBalance = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableWhiteBalances(); + whiteBalanceOptions = m_stopMotion->m_canon->getWhiteBalanceOptions(); + + currentWhiteBalance = m_stopMotion->m_canon->getCurrentWhiteBalance(); } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableWhiteBalances(); + whiteBalanceOptions = m_stopMotion->m_gphotocam->getWhiteBalanceOptions(); + + currentWhiteBalance = m_stopMotion->m_gphotocam->getCurrentWhiteBalance(); + } +#endif + + m_whiteBalanceCombo->addItems(whiteBalanceOptions); + int maxTextLength = 0; + for (int i = 0; i < whiteBalanceOptions.size(); i++) { + maxTextLength = + std::max(maxTextLength, fontMetrics().width(whiteBalanceOptions.at(i))); + } + if (m_whiteBalanceCombo->count() == 0) { m_whiteBalanceCombo->addItem(tr("Disabled")); m_whiteBalanceCombo->setDisabled(true); m_whiteBalanceCombo->setMaximumWidth(fontMetrics().width("Disabled") + 25); } else { m_whiteBalanceCombo->setEnabled(true); - m_whiteBalanceCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentWhiteBalance()); + m_whiteBalanceCombo->setCurrentText(currentWhiteBalance); m_whiteBalanceCombo->setMaximumWidth(maxTextLength + 25); } + m_whiteBalanceCombo->blockSignals(false); refreshColorTemperatureList(); +} + +//----------------------------------------------------------------------------- + +void StopMotionController::refreshManualFocusRange() { + m_manualFocusSlider->blockSignals(true); + + QStringList manualFocusRangeData; + +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto && !m_stopMotion->m_gphotocam->isCanon()) { + m_stopMotion->m_gphotocam->getManualFocusRangeData(); + + manualFocusRangeData = m_stopMotion->m_gphotocam->getManualFocusRange(); + } #endif + + if (manualFocusRangeData.count() == 0) { + m_manualFocusSlider->setDisabled(true); + } else { + m_manualFocusSlider->setEnabled(true); + float rmin, rmax, rstep; + rmin = manualFocusRangeData[0].toInt(); + rmax = manualFocusRangeData[1].toInt(); + rstep = manualFocusRangeData[2].toInt(); + m_manualFocusSlider->setRange(rmin, rmax); + m_manualFocusSlider->setSingleStep(rstep); + } + + m_manualFocusSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::refreshColorTemperatureList() { -#ifdef WITH_CANON m_kelvinSlider->blockSignals(true); - int count = 0; - count = m_stopMotion->m_canon->getColorTemperatureOptions().size(); - if (count == 0 || - m_stopMotion->m_canon->getCurrentWhiteBalance() != "Color Temperature") { + QStringList colorTempOptions; + QString currentWhiteBalance = "-"; + QString currentColorTemp = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + currentWhiteBalance = m_stopMotion->m_canon->getCurrentWhiteBalance(); + if (currentWhiteBalance == "Color Temperature") { + colorTempOptions = m_stopMotion->m_canon->getColorTemperatureOptions(); + + currentColorTemp = m_stopMotion->m_canon->getCurrentColorTemperature(); + } + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + currentWhiteBalance = m_stopMotion->m_gphotocam->getCurrentWhiteBalance(); + if (currentWhiteBalance == "Color Temperature") { + m_stopMotion->m_gphotocam->getAvailableColorTemperatures(); + colorTempOptions = + m_stopMotion->m_gphotocam->getColorTemperatureOptions(); + + currentColorTemp = + m_stopMotion->m_gphotocam->getCurrentColorTemperature(); + } + } +#endif + + int count = colorTempOptions.size(); + + if (count == 0) { // m_kelvinCombo->addItem(tr("Disabled")); m_kelvinSlider->setDisabled(true); m_kelvinSlider->hide(); @@ -2779,110 +3029,218 @@ void StopMotionController::refreshColorTemperatureList() { m_kelvinValueLabel->show(); m_kelvinSlider->setEnabled(true); m_kelvinSlider->setRange(0, count - 1); - m_kelvinValueLabel->setText( - tr("Temperature: ") + - m_stopMotion->m_canon->getCurrentColorTemperature()); + m_kelvinValueLabel->setText(tr("Temperature: ") + currentColorTemp); } + m_kelvinSlider->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::refreshImageQualityList() { -#ifdef WITH_CANON m_imageQualityCombo->blockSignals(true); + m_imageQualityCombo->clear(); - m_stopMotion->m_canon->getAvailableImageQualities(); - QStringList options = m_stopMotion->m_canon->getImageQualityOptions(); - m_imageQualityCombo->addItems(options); - int maxTextLength = 0; - for (int i = 0; i < options.size(); i++) { - maxTextLength = std::max(maxTextLength, fontMetrics().width(options.at(i))); + + QStringList imageQualityOptions; + QString currentImageQuality = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailableImageQualities(); + imageQualityOptions = m_stopMotion->m_canon->getImageQualityOptions(); + + currentImageQuality = m_stopMotion->m_canon->getCurrentImageQuality(); } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableImageQualities(); + imageQualityOptions = m_stopMotion->m_gphotocam->getImageQualityOptions(); + + currentImageQuality = m_stopMotion->m_gphotocam->getCurrentImageQuality(); + } +#endif + + m_imageQualityCombo->addItems(imageQualityOptions); + int maxTextLength = 0; + for (int i = 0; i < imageQualityOptions.size(); i++) { + maxTextLength = + std::max(maxTextLength, fontMetrics().width(imageQualityOptions.at(i))); + } + if (m_imageQualityCombo->count() == 0) { m_imageQualityCombo->addItem(tr("Disabled")); m_imageQualityCombo->setDisabled(true); m_imageQualityCombo->setMaximumWidth(fontMetrics().width("Disabled") + 25); } else { m_imageQualityCombo->setEnabled(true); - m_imageQualityCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentImageQuality()); + m_imageQualityCombo->setCurrentText(currentImageQuality); m_imageQualityCombo->setMaximumWidth(maxTextLength + 25); } + m_imageQualityCombo->blockSignals(false); +} + +//----------------------------------------------------------------------------- + +void StopMotionController::refreshImageSizeList() { + m_imageSizeCombo->blockSignals(true); + + m_imageSizeCombo->clear(); + + QStringList imageSizeOptions; + QString currentImageSize = "-"; + +#ifdef WITH_CANON + //if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + // m_stopMotion->m_canon->getAvailableImageSizes(); + // imageSizeOptions = m_stopMotion->m_canon->getImageSizeOptions(); + // + // currentImageSize = m_stopMotion->m_canon->getCurrentImageSizze(); + //} #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailableImageSizes(); + imageSizeOptions = m_stopMotion->m_gphotocam->getImageSizeOptions(); + + currentImageSize = m_stopMotion->m_gphotocam->getCurrentImageSize(); + } +#endif + + m_imageSizeCombo->addItems(imageSizeOptions); + int maxTextLength = 0; + for (int i = 0; i < imageSizeOptions.size(); i++) { + maxTextLength = + std::max(maxTextLength, fontMetrics().width(imageSizeOptions.at(i))); + } + + if (m_imageSizeCombo->count() == 0) { + m_imageSizeCombo->addItem(tr("Disabled")); + m_imageSizeCombo->setDisabled(true); + m_imageSizeCombo->setMaximumWidth(fontMetrics().width("Disabled") + 25); + } else { + m_imageSizeCombo->setEnabled(true); + m_imageSizeCombo->setCurrentText(currentImageSize); + m_imageSizeCombo->setMaximumWidth(maxTextLength + 25); + } + + m_imageSizeCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::refreshPictureStyleList() { -#ifdef WITH_CANON m_pictureStyleCombo->blockSignals(true); + m_pictureStyleCombo->clear(); - m_stopMotion->m_canon->getAvailablePictureStyles(); - QStringList options = m_stopMotion->m_canon->getPictureStyleOptions(); - m_pictureStyleCombo->addItems( - m_stopMotion->m_canon->getPictureStyleOptions()); - int maxTextLength = 0; - for (int i = 0; i < options.size(); i++) { - maxTextLength = std::max(maxTextLength, fontMetrics().width(options.at(i))); + + QStringList pictureStyleOptions; + QString currentPictureStyle = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->getAvailablePictureStyles(); + pictureStyleOptions = m_stopMotion->m_canon->getPictureStyleOptions(); + + currentPictureStyle = m_stopMotion->m_canon->getCurrentPictureStyle(); } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->getAvailablePictureStyles(); + pictureStyleOptions = m_stopMotion->m_gphotocam->getPictureStyleOptions(); + + currentPictureStyle = m_stopMotion->m_gphotocam->getCurrentPictureStyle(); + } +#endif + + m_pictureStyleCombo->addItems(pictureStyleOptions); + int maxTextLength = 0; + for (int i = 0; i < pictureStyleOptions.size(); i++) { + maxTextLength = + std::max(maxTextLength, fontMetrics().width(pictureStyleOptions.at(i))); + } + if (m_pictureStyleCombo->count() == 0) { m_pictureStyleCombo->addItem(tr("Disabled")); m_pictureStyleCombo->setDisabled(true); m_pictureStyleCombo->setMaximumWidth(fontMetrics().width("Disabled") + 25); } else { m_pictureStyleCombo->setEnabled(true); - m_pictureStyleCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentPictureStyle()); + m_pictureStyleCombo->setCurrentText(currentPictureStyle); m_pictureStyleCombo->setMaximumWidth(maxTextLength + 25); } + m_pictureStyleCombo->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::onCameraListComboActivated(int comboIndex) { QList cameras = QCameraInfo::availableCameras(); - int cameraCount = cameras.size(); + int webCount = cameras.size(); + int canonCount = 0; + int gphotoCount = 0; + #ifdef WITH_CANON - cameraCount += m_stopMotion->m_canon->getCameraCount(); + canonCount = m_stopMotion->m_canon->getCameraCount(); #endif +#ifdef WITH_GPHOTO2 + gphotoCount = m_stopMotion->m_gphotocam->getCameraCount(); +#endif + + int cameraCount = webCount + canonCount + gphotoCount; + if (cameraCount != m_cameraListCombo->count() - 1) return; - m_stopMotion->changeCameras(comboIndex); - m_stopMotion->updateStopMotionControls(m_stopMotion->m_usingWebcam); + int cameraIndex = 0; + CameraType selectedCameraType = CameraType::None; + if (comboIndex > 0) { + cameraIndex = m_cameraListCombo->itemData(comboIndex).toInt(); + int adjComboIndex = comboIndex - 1; // Adjust for "Select camera" option + if (adjComboIndex < webCount) + selectedCameraType = CameraType::Web; + else if (adjComboIndex < (webCount + canonCount)) + selectedCameraType = CameraType::CanonDSLR; + else if (adjComboIndex < (cameraCount)) + selectedCameraType = CameraType::GPhoto; + } + + m_stopMotion->changeCameras(comboIndex, selectedCameraType, cameraIndex); + + m_stopMotion->updateStopMotionControls(); if (m_calibrationUI.groupBox->isChecked() && comboIndex > 0) { m_stopMotion->m_calibration.isValid = false; m_calibrationUI.exportBtn->setEnabled(false); - if (m_stopMotion->m_usingWebcam) resetCalibSettingsFromFile(); + if (m_stopMotion->m_currentCameraType == CameraType::Web) + resetCalibSettingsFromFile(); } } //----------------------------------------------------------------------------- -void StopMotionController::onNewCameraSelected(int index, bool useWebcam) { +void StopMotionController::onNewCameraSelected(int index) { onCameraIndexChanged(index); - onUpdateStopMotionControls(useWebcam); + onUpdateStopMotionControls(); } //----------------------------------------------------------------------------- void StopMotionController::onCameraIndexChanged(int index) { - if (index < m_cameraListCombo->count()) + if (index < m_cameraListCombo->count()) { m_cameraListCombo->setCurrentIndex(index); + m_cameraSettingsLabel->setText(m_cameraListCombo->currentText()); + } } //----------------------------------------------------------------------------- -void StopMotionController::onUpdateStopMotionControls(bool useWebcam) { - int index = m_cameraListCombo->currentIndex(); - - if (index == 0) { - m_cameraListCombo->setCurrentIndex(index); +void StopMotionController::onUpdateStopMotionControls() { + if (m_stopMotion->m_currentCameraType == CameraType::None) { + m_cameraListCombo->setCurrentIndex(0); m_resolutionCombo->hide(); m_resolutionLabel->hide(); m_cameraStatusLabel->hide(); @@ -2898,7 +3256,7 @@ void StopMotionController::onUpdateStopMotionControls(bool useWebcam) { // if (m_tabBar->tabText(1) == tr("Settings")) { // m_tabBar->removeTab(1); //} - } else if (useWebcam) { + } else if (m_stopMotion->m_currentCameraType == CameraType::Web) { m_resolutionCombo->show(); m_resolutionCombo->setEnabled(true); m_resolutionLabel->show(); @@ -2927,6 +3285,31 @@ void StopMotionController::onUpdateStopMotionControls(bool useWebcam) { // if (m_tabBar->tabText(1) == tr("Options")) { // m_tabBar->insertTab(1, tr("Settings")); //} + bool showFocusButtons = true; // Default to Canon focus buttons +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto && + !m_stopMotion->m_gphotocam->isCanon()) + showFocusButtons = false; +#endif; + if (showFocusButtons) { + m_focusNearButton->show(); + m_focusNear2Button->show(); + m_focusNear3Button->show(); + m_focusFarButton->show(); + m_focusFar2Button->show(); + m_focusFar3Button->show(); + // Hide slider used by other cameras + m_manualFocusSlider->hide(); + } else { + m_manualFocusSlider->show(); + // Hide buttons used by Canon + m_focusNearButton->hide(); + m_focusNear2Button->hide(); + m_focusNear3Button->hide(); + m_focusFarButton->hide(); + m_focusFar2Button->hide(); + m_focusFar3Button->hide(); + } } } @@ -2955,7 +3338,8 @@ void StopMotionController::onResolutionComboActivated(const QString &itemText) { m_stopMotion->m_calibration.isValid = false; m_calibrationUI.exportBtn->setEnabled(false); - if (m_stopMotion->m_usingWebcam) resetCalibSettingsFromFile(); + if (m_stopMotion->m_currentCameraType == CameraType::Web) + resetCalibSettingsFromFile(); } //----------------------------------------------------------------------------- @@ -3136,243 +3520,501 @@ void StopMotionController::onFrameCaptured(QImage &image) {} //----------------------------------------------------------------------------- void StopMotionController::onApertureChanged(int index) { -#ifdef WITH_CANON m_apertureSlider->blockSignals(true); - QStringList apertureOptions = m_stopMotion->m_canon->getApertureOptions(); - m_stopMotion->m_canon->setAperture( - apertureOptions.at(m_apertureSlider->value())); - m_apertureSlider->setRange(0, apertureOptions.size() - 1); - m_apertureSlider->setValue( - apertureOptions.lastIndexOf(m_stopMotion->m_canon->getCurrentAperture())); - m_apertureLabel->setText(tr("Aperture: ") + - m_stopMotion->m_canon->getCurrentAperture()); - m_apertureSlider->blockSignals(false); + + QStringList apertureOptions; + QString currentAperture = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + apertureOptions = m_stopMotion->m_canon->getApertureOptions(); + m_stopMotion->m_canon->setAperture( + apertureOptions.at(m_apertureSlider->value())); + + currentAperture = m_stopMotion->m_canon->getCurrentAperture(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + apertureOptions = m_stopMotion->m_gphotocam->getApertureOptions(); + m_stopMotion->m_gphotocam->setAperture( + apertureOptions.at(m_apertureSlider->value())); + + currentAperture = m_stopMotion->m_gphotocam->getCurrentAperture(); + } +#endif + + m_apertureLabel->setText(tr("Aperture: ") + currentAperture); + m_apertureSlider->setRange(0, apertureOptions.size() - 1); + m_apertureSlider->setValue(apertureOptions.lastIndexOf(currentAperture)); + + m_apertureSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onApertureChangedSignal(QString text) { -#ifdef WITH_CANON m_apertureSlider->blockSignals(true); - QStringList apertureOptions = m_stopMotion->m_canon->getApertureOptions(); - m_apertureLabel->setText(tr("Aperture: ") + - m_stopMotion->m_canon->getCurrentAperture()); - m_apertureSlider->setRange(0, apertureOptions.size() - 1); - m_apertureSlider->setValue( - apertureOptions.lastIndexOf(m_stopMotion->m_canon->getCurrentAperture())); - m_apertureSlider->blockSignals(false); + + QStringList apertureOptions; + QString currentAperture = text; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + apertureOptions = m_stopMotion->m_canon->getApertureOptions(); + if (apertureOptions.lastIndexOf(currentAperture) < 0) + currentAperture = m_stopMotion->m_canon->getCurrentAperture(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + apertureOptions = m_stopMotion->m_gphotocam->getApertureOptions(); + if (apertureOptions.lastIndexOf(currentAperture) < 0) + currentAperture = m_stopMotion->m_gphotocam->getCurrentAperture(); + } +#endif + + m_apertureLabel->setText(tr("Aperture: ") + currentAperture); + m_apertureSlider->setRange(0, apertureOptions.size() - 1); + m_apertureSlider->setValue(apertureOptions.lastIndexOf(currentAperture)); + + m_apertureSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onShutterSpeedChanged(int index) { -#ifdef WITH_CANON m_shutterSpeedSlider->blockSignals(true); - QStringList shutterSpeedOptions = - m_stopMotion->m_canon->getShutterSpeedOptions(); - m_stopMotion->m_canon->setShutterSpeed( - shutterSpeedOptions.at(m_shutterSpeedSlider->value())); - m_shutterSpeedSlider->setRange(0, shutterSpeedOptions.size() - 1); - m_shutterSpeedSlider->blockSignals(false); + + QStringList shutterSpeedOptions; + QString currentShutterSpeed = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + shutterSpeedOptions = m_stopMotion->m_canon->getShutterSpeedOptions(); + m_stopMotion->m_canon->setShutterSpeed( + shutterSpeedOptions.at(m_shutterSpeedSlider->value())); + + currentShutterSpeed = m_stopMotion->m_canon->getCurrentShutterSpeed(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + shutterSpeedOptions = m_stopMotion->m_gphotocam->getShutterSpeedOptions(); + m_stopMotion->m_gphotocam->setShutterSpeed( + shutterSpeedOptions.at(m_shutterSpeedSlider->value())); + + currentShutterSpeed = m_stopMotion->m_gphotocam->getCurrentShutterSpeed(); + } +#endif + + QSlider *senderWidget = qobject_cast(sender()); + // Don't change value if LiveViewOffset slider caused this change + if (senderWidget == m_shutterSpeedSlider) { + m_shutterSpeedLabel->setText(tr("Shutter Speed: ") + currentShutterSpeed); + m_shutterSpeedSlider->setRange(0, shutterSpeedOptions.size() - 1); + m_shutterSpeedSlider->setValue(shutterSpeedOptions.lastIndexOf(currentShutterSpeed)); + } + + m_shutterSpeedSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onShutterSpeedChangedSignal(QString text) { -#ifdef WITH_CANON m_shutterSpeedSlider->blockSignals(true); - QStringList shutterSpeedOptions = - m_stopMotion->m_canon->getShutterSpeedOptions(); - m_shutterSpeedLabel->setText(tr("Shutter Speed: ") + text); - m_shutterSpeedSlider->setRange(0, shutterSpeedOptions.size() - 1); - m_shutterSpeedSlider->setValue(shutterSpeedOptions.lastIndexOf(text)); - m_shutterSpeedSlider->blockSignals(false); + + QStringList shutterSpeedOptions; + QString currentShutterSpeed = text; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + shutterSpeedOptions = m_stopMotion->m_canon->getShutterSpeedOptions(); + if (shutterSpeedOptions.lastIndexOf(currentShutterSpeed) < 0) + currentShutterSpeed = m_stopMotion->m_canon->getCurrentShutterSpeed(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + shutterSpeedOptions = m_stopMotion->m_gphotocam->getShutterSpeedOptions(); + + if (m_stopMotion->m_gphotocam->m_liveViewExposureOffset) + currentShutterSpeed = m_stopMotion->m_gphotocam->m_displayedShutterSpeed; + + if (shutterSpeedOptions.lastIndexOf(currentShutterSpeed) < 0) + currentShutterSpeed = m_stopMotion->m_gphotocam->getCurrentShutterSpeed(); + } +#endif + + m_shutterSpeedLabel->setText(tr("Shutter Speed: ") + currentShutterSpeed); + m_shutterSpeedSlider->setRange(0, shutterSpeedOptions.size() - 1); + m_shutterSpeedSlider->setValue( + shutterSpeedOptions.lastIndexOf(currentShutterSpeed)); + + m_shutterSpeedSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onIsoChanged(int index) { -#ifdef WITH_CANON m_isoSlider->blockSignals(true); - QStringList isoOptions = m_stopMotion->m_canon->getIsoOptions(); - m_stopMotion->m_canon->setIso(isoOptions.at(m_isoSlider->value())); - m_isoSlider->setRange(0, isoOptions.size() - 1); - m_isoSlider->setValue( - isoOptions.lastIndexOf(m_stopMotion->m_canon->getCurrentIso())); - m_isoLabel->setText(tr("Iso: ") + m_stopMotion->m_canon->getCurrentIso()); - m_isoSlider->blockSignals(false); + + QStringList isoOptions; + QString currentIso = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + isoOptions = m_stopMotion->m_canon->getIsoOptions(); + m_stopMotion->m_canon->setIso(isoOptions.at(m_isoSlider->value())); + + currentIso = m_stopMotion->m_canon->getCurrentIso(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + isoOptions = m_stopMotion->m_gphotocam->getIsoOptions(); + m_stopMotion->m_gphotocam->setIso(isoOptions.at(m_isoSlider->value())); + + currentIso = m_stopMotion->m_gphotocam->getCurrentIso(); + } +#endif + + m_isoLabel->setText(tr("Iso: ") + currentIso); + m_isoSlider->setRange(0, isoOptions.size() - 1); + m_isoSlider->setValue(isoOptions.lastIndexOf(currentIso)); + + m_isoSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onIsoChangedSignal(QString text) { -#ifdef WITH_CANON m_isoSlider->blockSignals(true); - QStringList isoOptions = m_stopMotion->m_canon->getIsoOptions(); - m_isoSlider->setRange(0, isoOptions.size() - 1); - m_isoSlider->setValue( - isoOptions.lastIndexOf(m_stopMotion->m_canon->getCurrentIso())); - m_isoLabel->setText(tr("Iso: ") + m_stopMotion->m_canon->getCurrentIso()); - m_isoSlider->blockSignals(false); + + QStringList isoOptions; + QString currentIso = text; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + isoOptions = m_stopMotion->m_canon->getIsoOptions(); + if (isoOptions.lastIndexOf(currentIso) < 0) + currentIso = m_stopMotion->m_canon->getCurrentIso(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + isoOptions = m_stopMotion->m_gphotocam->getIsoOptions(); + if (isoOptions.lastIndexOf(currentIso) < 0) + currentIso = m_stopMotion->m_gphotocam->getCurrentIso(); + } +#endif + + m_isoLabel->setText(tr("Iso: ") + currentIso); + m_isoSlider->setRange(0, isoOptions.size() - 1); + m_isoSlider->setValue(isoOptions.lastIndexOf(currentIso)); + + m_isoSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onExposureChanged(int index) { -#ifdef WITH_CANON m_exposureCombo->blockSignals(true); - m_stopMotion->m_canon->setExposureCompensation( - m_exposureCombo->currentText()); - m_exposureCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->setExposureCompensation( + m_exposureCombo->currentText()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setExposureCompensation( + m_exposureCombo->currentText()); +#endif + + m_exposureCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onExposureChangedSignal(QString text) { -#ifdef WITH_CANON m_exposureCombo->blockSignals(true); - m_exposureCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentExposureCompensation()); - m_exposureCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_exposureCombo->setCurrentText( + m_stopMotion->m_canon->getCurrentExposureCompensation()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_exposureCombo->setCurrentText( + m_stopMotion->m_gphotocam->getCurrentExposureCompensation()); +#endif + + m_exposureCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onWhiteBalanceChanged(int index) { -#ifdef WITH_CANON m_whiteBalanceCombo->blockSignals(true); - m_stopMotion->m_canon->setWhiteBalance(m_whiteBalanceCombo->currentText()); - m_whiteBalanceCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->setWhiteBalance(m_whiteBalanceCombo->currentText()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setWhiteBalance( + m_whiteBalanceCombo->currentText()); +#endif + + m_whiteBalanceCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onWhiteBalanceChangedSignal(QString text) { -#ifdef WITH_CANON m_whiteBalanceCombo->blockSignals(true); - m_whiteBalanceCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentWhiteBalance()); - refreshColorTemperatureList(); - m_whiteBalanceCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_whiteBalanceCombo->setCurrentText( + m_stopMotion->m_canon->getCurrentWhiteBalance()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_whiteBalanceCombo->setCurrentText( + m_stopMotion->m_gphotocam->getCurrentWhiteBalance()); +#endif + + refreshColorTemperatureList(); + + m_whiteBalanceCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onColorTemperatureChanged(int index) { -#ifdef WITH_CANON m_kelvinSlider->blockSignals(true); - QStringList kelvinOptions = - m_stopMotion->m_canon->getColorTemperatureOptions(); - m_stopMotion->m_canon->setColorTemperature( - kelvinOptions.at(m_kelvinSlider->value())); - m_kelvinSlider->setRange(0, kelvinOptions.size() - 1); - m_kelvinSlider->setValue(kelvinOptions.lastIndexOf( - m_stopMotion->m_canon->getCurrentColorTemperature())); - m_kelvinValueLabel->setText( - tr("Temperature: ") + - m_stopMotion->m_canon->getCurrentColorTemperature()); - m_kelvinSlider->blockSignals(false); + + QStringList kelvinOptions; + QString currentColorTemp = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + kelvinOptions = m_stopMotion->m_canon->getColorTemperatureOptions(); + m_stopMotion->m_canon->setColorTemperature( + kelvinOptions.at(m_kelvinSlider->value())); + + currentColorTemp = m_stopMotion->m_canon->getCurrentColorTemperature(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + kelvinOptions = m_stopMotion->m_gphotocam->getColorTemperatureOptions(); + m_stopMotion->m_gphotocam->setColorTemperature( + kelvinOptions.at(m_kelvinSlider->value())); + + currentColorTemp = m_stopMotion->m_gphotocam->getCurrentColorTemperature(); + } +#endif + + m_kelvinValueLabel->setText(tr("Temperature: ") + currentColorTemp); + m_kelvinSlider->setRange(0, kelvinOptions.size() - 1); + m_kelvinSlider->setValue(kelvinOptions.lastIndexOf(currentColorTemp)); + + m_kelvinSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onColorTemperatureChangedSignal(QString text) { -#ifdef WITH_CANON m_kelvinSlider->blockSignals(true); - QStringList kelvinOptions = - m_stopMotion->m_canon->getColorTemperatureOptions(); - m_kelvinSlider->setRange(0, kelvinOptions.size() - 1); - m_kelvinSlider->setValue(kelvinOptions.lastIndexOf( - m_stopMotion->m_canon->getCurrentColorTemperature())); - m_kelvinValueLabel->setText( - tr("Temperature: ") + - m_stopMotion->m_canon->getCurrentColorTemperature()); - m_kelvinSlider->blockSignals(false); + + QStringList kelvinOptions; + QString currentColorTemp = "-"; + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + kelvinOptions = m_stopMotion->m_canon->getColorTemperatureOptions(); + + currentColorTemp = m_stopMotion->m_canon->getCurrentColorTemperature(); + } #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + kelvinOptions = m_stopMotion->m_gphotocam->getColorTemperatureOptions(); + + currentColorTemp = m_stopMotion->m_gphotocam->getCurrentColorTemperature(); + } +#endif + + m_kelvinValueLabel->setText(tr("Temperature: ") + currentColorTemp); + m_kelvinSlider->setRange(0, kelvinOptions.size() - 1); + m_kelvinSlider->setValue(kelvinOptions.lastIndexOf(currentColorTemp)); + + m_kelvinSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onImageQualityChanged(int index) { -#ifdef WITH_CANON m_imageQualityCombo->blockSignals(true); - m_stopMotion->m_canon->setImageQuality(m_imageQualityCombo->currentText()); - m_imageQualityCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->setImageQuality(m_imageQualityCombo->currentText()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setImageQuality( + m_imageQualityCombo->currentText()); +#endif + + m_imageQualityCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onImageQualityChangedSignal(QString text) { -#ifdef WITH_CANON m_imageQualityCombo->blockSignals(true); - m_imageQualityCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentImageQuality()); - m_imageQualityCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_imageQualityCombo->setCurrentText( + m_stopMotion->m_canon->getCurrentImageQuality()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_imageQualityCombo->setCurrentText( + m_stopMotion->m_gphotocam->getCurrentImageQuality()); +#endif + + m_imageQualityCombo->blockSignals(false); +} + +//----------------------------------------------------------------------------- + +void StopMotionController::onImageSizeChanged(int index) { + m_imageSizeCombo->blockSignals(true); + +#ifdef WITH_CANON +// if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) +// m_stopMotion->m_canon->setImageSize(m_imageSizeCombo->currentText()); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setImageSize(m_imageSizeCombo->currentText()); +#endif + + m_imageSizeCombo->blockSignals(false); +} + +//----------------------------------------------------------------------------- + +void StopMotionController::onImageSizeChangedSignal(QString text) { + m_imageSizeCombo->blockSignals(true); + +#ifdef WITH_CANON + //if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + // m_imageSizeCombo->setCurrentText( + // m_stopMotion->m_canon->getCurrentImageSize()); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_imageSizeCombo->setCurrentText( + m_stopMotion->m_gphotocam->getCurrentImageSize()); +#endif + + m_imageSizeCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onPictureStyleChanged(int index) { -#ifdef WITH_CANON m_pictureStyleCombo->blockSignals(true); - m_stopMotion->m_canon->setPictureStyle(m_pictureStyleCombo->currentText()); - m_pictureStyleCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->setPictureStyle(m_pictureStyleCombo->currentText()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setPictureStyle( + m_pictureStyleCombo->currentText()); +#endif + + m_pictureStyleCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onPictureStyleChangedSignal(QString text) { -#ifdef WITH_CANON m_pictureStyleCombo->blockSignals(true); - m_pictureStyleCombo->setCurrentText( - m_stopMotion->m_canon->getCurrentPictureStyle()); - m_pictureStyleCombo->blockSignals(false); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_pictureStyleCombo->setCurrentText( + m_stopMotion->m_canon->getCurrentPictureStyle()); #endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_pictureStyleCombo->setCurrentText( + m_stopMotion->m_gphotocam->getCurrentPictureStyle()); +#endif + + m_pictureStyleCombo->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onLiveViewCompensationChanged(int index) { -#ifdef WITH_CANON m_liveViewCompensationSlider->blockSignals(true); - m_stopMotion->m_canon->setLiveViewOffset( - m_liveViewCompensationSlider->value()); + +#ifdef WITH_CANON + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->setLiveViewOffset( + m_liveViewCompensationSlider->value()); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setLiveViewOffset( + m_liveViewCompensationSlider->value()); +#endif + onShutterSpeedChanged(0); m_liveViewCompensationSlider->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::onLiveViewCompensationChangedSignal(int value) { -#ifdef WITH_CANON m_liveViewCompensationSlider->blockSignals(true); m_liveViewCompensationSlider->setValue(value); QString labelText = tr("Live View Offset: "); labelText = labelText + QString::number(value); m_liveViewCompensationLabel->setText(labelText); m_liveViewCompensationSlider->blockSignals(false); +} + + +//----------------------------------------------------------------------------- + +void StopMotionController::onManualFocusChanged(int index) { + m_manualFocusSlider->blockSignals(true); + +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto && !m_stopMotion->m_gphotocam->isCanon()) + m_stopMotion->m_gphotocam->setManualFocus(m_manualFocusSlider->value()); #endif + + m_manualFocusSlider->blockSignals(false); } //----------------------------------------------------------------------------- void StopMotionController::onFocusCheckToggled(bool on) { -#ifdef WITH_CANON if (on) { m_zoomButton->setStyleSheet("border:1px solid rgba(0, 255, 0, 255);"); } else { @@ -3381,13 +4023,11 @@ void StopMotionController::onFocusCheckToggled(bool on) { m_zoomButton->blockSignals(true); m_zoomButton->setChecked(on); m_zoomButton->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::onPickFocusCheckToggled(bool on) { -#ifdef WITH_CANON if (on) { m_pickZoomButton->setStyleSheet("border:1px solid rgba(0, 255, 0, 255);"); @@ -3397,14 +4037,18 @@ void StopMotionController::onPickFocusCheckToggled(bool on) { m_pickZoomButton->blockSignals(true); m_pickZoomButton->setChecked(on); m_pickZoomButton->blockSignals(false); -#endif } //----------------------------------------------------------------------------- void StopMotionController::onZoomPressed() { #ifdef WITH_CANON - m_stopMotion->m_canon->zoomLiveView(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->zoomLiveView(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->zoomLiveView(); #endif } @@ -3412,7 +4056,12 @@ void StopMotionController::onZoomPressed() { void StopMotionController::onPickZoomPressed() { #ifdef WITH_CANON - m_stopMotion->m_canon->toggleZoomPicking(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->toggleZoomPicking(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->toggleZoomPicking(); #endif } @@ -3420,7 +4069,12 @@ void StopMotionController::onPickZoomPressed() { void StopMotionController::onFocusNear() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusNear(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusNear(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusNear(); #endif } @@ -3428,7 +4082,12 @@ void StopMotionController::onFocusNear() { void StopMotionController::onFocusFar() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusFar(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusFar(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusFar(); #endif } @@ -3436,7 +4095,12 @@ void StopMotionController::onFocusFar() { void StopMotionController::onFocusNear2() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusNear2(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusNear2(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusNear2(); #endif } @@ -3444,7 +4108,12 @@ void StopMotionController::onFocusNear2() { void StopMotionController::onFocusFar2() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusFar2(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusFar2(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusFar2(); #endif } @@ -3452,7 +4121,12 @@ void StopMotionController::onFocusFar2() { void StopMotionController::onFocusNear3() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusNear3(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusNear3(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusNear3(); #endif } @@ -3460,30 +4134,43 @@ void StopMotionController::onFocusNear3() { void StopMotionController::onFocusFar3() { #ifdef WITH_CANON - m_stopMotion->m_canon->focusFar3(); + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + m_stopMotion->m_canon->focusFar3(); +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->focusFar3(); #endif } //----------------------------------------------------------------------------- void StopMotionController::showEvent(QShowEvent *event) { - bool hasCanon = false; - bool hasWebcam = false; + bool openSession = false; + bool hasDslr = false; + bool hasWebcam = false; + #ifdef WITH_CANON - m_stopMotion->m_canon->initializeCanonSDK(); - if (!m_stopMotion->m_canon->m_sessionOpen) { + if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + m_stopMotion->m_canon->initializeCanonSDK(); + openSession = m_stopMotion->m_canon->m_sessionOpen; + } +#endif +#ifdef WITH_GPHOTO2 + if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + openSession = m_stopMotion->m_gphotocam->m_sessionOpen; +#endif + + if (!openSession) { m_dslrFrame->hide(); m_alwaysUseLiveViewImagesButton->hide(); } else { m_dslrFrame->show(); m_alwaysUseLiveViewImagesButton->show(); - hasCanon = true; + hasDslr = true; } -#else - m_dslrFrame->hide(); - m_alwaysUseLiveViewImagesButton->hide(); -#endif - if (!m_stopMotion->m_usingWebcam) { + + if (m_stopMotion->m_currentCameraType != CameraType::Web) { m_resolutionCombo->hide(); m_resolutionLabel->hide(); m_webcamFrame->hide(); @@ -3492,7 +4179,7 @@ void StopMotionController::showEvent(QShowEvent *event) { m_webcamFrame->show(); } - if (!hasWebcam && !hasCanon) { + if (!hasWebcam && !hasDslr) { m_commonFrame->hide(); m_noCameraFrame->show(); } else { @@ -3535,38 +4222,35 @@ void StopMotionController::keyPressEvent(QKeyEvent *event) { int key = event->key(); TFrameHandle *fh = TApp::instance()->getCurrentFrame(); int origFrame = fh->getFrame(); -#ifdef WITH_CANON - if ((m_stopMotion->m_canon->m_pickLiveViewZoom || - m_stopMotion->m_canon->m_zooming) && + + if ((m_stopMotion->isPickLiveViewZoom() || m_stopMotion->isZooming()) && (key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_2 || key == Qt::Key_4 || key == Qt::Key_6 || key == Qt::Key_8)) { - if (m_stopMotion->m_canon->m_liveViewZoomReadyToPick == true) { + if (m_stopMotion->isLiveViewZoomReadyToPick() == true) { if (key == Qt::Key_Left || key == Qt::Key_4) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.x -= 10; + m_stopMotion->adjustLiveViewZoomPickPoint(-10, 0); } if (key == Qt::Key_Right || key == Qt::Key_6) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.x += 10; + m_stopMotion->adjustLiveViewZoomPickPoint(10, 0); } if (key == Qt::Key_Up || key == Qt::Key_8) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.y += 10; + m_stopMotion->adjustLiveViewZoomPickPoint(0, 10); } if (key == Qt::Key_Down || key == Qt::Key_2) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.y -= 10; + m_stopMotion->adjustLiveViewZoomPickPoint(0, -10); } - if (m_stopMotion->m_canon->m_zooming) { - m_stopMotion->m_canon->setZoomPoint(); + if (m_stopMotion->isZooming()) { + m_stopMotion->setZoomPoint(); } } - m_stopMotion->m_canon->calculateZoomPoint(); + m_stopMotion->calculateZoomPoint(); event->accept(); - } else if (m_stopMotion->m_canon->m_pickLiveViewZoom && + } else if (m_stopMotion->isPickLiveViewZoom() && (key == Qt::Key_Escape || key == Qt::Key_Enter || key == Qt::Key_Return)) { - m_stopMotion->m_canon->toggleZoomPicking(); - } else -#endif - if (key == Qt::Key_Up || key == Qt::Key_Left) { + m_stopMotion->toggleZoomPicking(); + } else if (key == Qt::Key_Up || key == Qt::Key_Left) { fh->prevFrame(); event->accept(); } else if (key == Qt::Key_Down || key == Qt::Key_Right) { @@ -3922,6 +4606,10 @@ void StopMotionController::onRefreshTests() { testInfo.firstChildElement("ImageQuality") .firstChild() .nodeValue(); + tooltipString += "\nImage Size: " + + testInfo.firstChildElement("ImageSize") + .firstChild() + .nodeValue(); QString wb = testInfo.firstChildElement("WhiteBalance") .firstChild() .nodeValue(); @@ -4071,12 +4759,18 @@ void StopMotionController::resetCalibSettingsFromFile() { fs["identifier"] >> identifierStr; if (identifierStr != "OpenToonzCameraCalibrationSettings") return; cv::Size resolution; - int camWidth = m_stopMotion->m_usingWebcam - ? m_stopMotion->m_webcam->getWebcamWidth() - : m_stopMotion->m_canon->m_fullImageDimensions.lx; - int camHeight = m_stopMotion->m_usingWebcam - ? m_stopMotion->m_webcam->getWebcamHeight() - : m_stopMotion->m_canon->m_fullImageDimensions.ly; + int camWidth, camHeight; + if (m_stopMotion->m_currentCameraType == CameraType::Web) { + camWidth = m_stopMotion->m_webcam->getWebcamWidth(); + camHeight = m_stopMotion->m_webcam->getWebcamHeight(); + } else if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + camWidth = m_stopMotion->m_canon->m_fullImageDimensions.lx; + camHeight = m_stopMotion->m_canon->m_fullImageDimensions.ly; + } else if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + camWidth = m_stopMotion->m_gphotocam->m_fullImageDimensions.lx; + camHeight = m_stopMotion->m_gphotocam->m_fullImageDimensions.ly; + } + QSize currentResolution(camWidth, camHeight); fs["resolution"] >> resolution; if (currentResolution != QSize(resolution.width, resolution.height)) @@ -4093,10 +4787,12 @@ void StopMotionController::resetCalibSettingsFromFile() { cv::Size(currentResolution.width(), currentResolution.height()), CV_32FC1, mapX, mapY); - if (m_stopMotion->m_usingWebcam) + if (m_stopMotion->m_currentCameraType == CameraType::Web) m_stopMotion->m_webcam->setCalibration(mapX, mapY); - else + else if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) m_stopMotion->m_canon->setCalibration(mapX, mapY); + else if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + m_stopMotion->m_gphotocam->setCalibration(mapX, mapY); m_stopMotion->m_calibration.isValid = true; m_stopMotion->m_calibration.filePath = calibFp; @@ -4176,14 +4872,18 @@ void StopMotionController::captureCalibrationRefImage(cv::Mat &image) { image.size(), CV_32FC1, mapX, mapY); int camWidth, camHeight; - if (m_stopMotion->m_usingWebcam) { + if (m_stopMotion->m_currentCameraType == CameraType::Web) { m_stopMotion->m_webcam->setCalibration(mapX, mapY); camWidth = m_stopMotion->m_webcam->getWebcamWidth(); camHeight = m_stopMotion->m_webcam->getWebcamHeight(); - } else { + } else if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { m_stopMotion->m_canon->setCalibration(mapX, mapY); camWidth = m_stopMotion->m_canon->m_fullImageDimensions.lx; camHeight = m_stopMotion->m_canon->m_fullImageDimensions.ly; + } else if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + m_stopMotion->m_gphotocam->setCalibration(mapX, mapY); + camWidth = m_stopMotion->m_gphotocam->m_fullImageDimensions.lx; + camHeight = m_stopMotion->m_gphotocam->m_fullImageDimensions.ly; } // save calibration settings @@ -4213,9 +4913,9 @@ void StopMotionController::captureCalibrationRefImage(cv::Mat &image) { QString StopMotionController::getCurrentCalibFilePath() { QString cameraName = m_cameraListCombo->currentText(); if (cameraName.isEmpty()) return QString(); - QString resolution = m_resolutionCombo->currentText(); - QString hostName = QHostInfo::localHostName(); - QString fileName = hostName + "_" + cameraName + "_" + resolution + ".xml"; + QString resolution = m_resolutionCombo->currentText(); + QString hostName = QHostInfo::localHostName(); + QString fileName = hostName + "_" + cameraName + "_" + resolution + ".xml"; TFilePath folderPath = ToonzFolder::getLibraryFolder() + "camera calibration" + TFilePath(fileName); return folderPath.getQString(); @@ -4238,12 +4938,17 @@ void StopMotionController::onCalibLoadBtnClicked() { if (identifierStr != "OpenToonzCameraCalibrationSettings") throw TException(fp.toStdWString() + L": Identifier does not match"); cv::Size resolution; - int camWidth = m_stopMotion->m_usingWebcam - ? m_stopMotion->m_webcam->getWebcamWidth() - : m_stopMotion->m_canon->m_fullImageDimensions.lx; - int camHeight = m_stopMotion->m_usingWebcam - ? m_stopMotion->m_webcam->getWebcamHeight() - : m_stopMotion->m_canon->m_fullImageDimensions.ly; + int camWidth, camHeight; + if (m_stopMotion->m_currentCameraType == CameraType::Web) { + camWidth = m_stopMotion->m_webcam->getWebcamWidth(); + camHeight = m_stopMotion->m_webcam->getWebcamHeight(); + } else if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) { + camWidth = m_stopMotion->m_canon->m_fullImageDimensions.lx; + camHeight = m_stopMotion->m_canon->m_fullImageDimensions.ly; + } else if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) { + camWidth = m_stopMotion->m_gphotocam->m_fullImageDimensions.lx; + camHeight = m_stopMotion->m_gphotocam->m_fullImageDimensions.ly; + } QSize currentResolution(camWidth, camHeight); fs["resolution"] >> resolution; if (currentResolution != QSize(resolution.width, resolution.height)) @@ -4312,9 +5017,17 @@ void StopMotionController::onCalibReadme() { //----------------------------------------------------------------------------- void StopMotionController::onCalibImageCaptured() { - cv::Mat camImage = m_stopMotion->m_usingWebcam - ? m_stopMotion->m_webcam->getWebcamImage() - : m_stopMotion->m_canon->getcanonImage(); + cv::Mat camImage; + + if (m_stopMotion->m_currentCameraType == CameraType::Web) + camImage = m_stopMotion->m_webcam->getWebcamImage(); + else if (m_stopMotion->m_currentCameraType == CameraType::CanonDSLR) + camImage = m_stopMotion->m_canon->getcanonImage(); + else if (m_stopMotion->m_currentCameraType == CameraType::GPhoto) + camImage = m_stopMotion->m_gphotocam->getGPhotoImage(); + else + return; + captureCalibrationRefImage(camImage); } diff --git a/toonz/sources/stopmotion/stopmotioncontroller.h b/toonz/sources/stopmotion/stopmotioncontroller.h index 19c2c72c..2cf8c06e 100644 --- a/toonz/sources/stopmotion/stopmotioncontroller.h +++ b/toonz/sources/stopmotion/stopmotioncontroller.h @@ -85,7 +85,7 @@ class FrameNumberLineEdit : public DVGui::LineEdit, QString m_textOnFocusIn; public: - FrameNumberLineEdit(QWidget* parent = 0, TFrameId fId = TFrameId(1), + FrameNumberLineEdit(QWidget *parent = 0, TFrameId fId = TFrameId(1), bool acceptLetter = true); ~FrameNumberLineEdit() {} @@ -194,18 +194,18 @@ class StopMotionController final : public QWidget { *m_focusFar3Button, *m_captureFilterSettingsBtn, *m_testLightsButton; QHBoxLayout *m_focusAndZoomLayout; QLabel *m_frameInfoLabel, *m_cameraSettingsLabel, *m_cameraModeLabel, - *m_resolutionLabel, *m_cameraStatusLabel, - *m_apertureLabel, *m_kelvinValueLabel, *m_isoLabel, *m_shutterSpeedLabel, - *m_webcamLabel, *m_liveViewCompensationLabel; + *m_resolutionLabel, *m_cameraStatusLabel, *m_apertureLabel, + *m_kelvinValueLabel, *m_isoLabel, *m_shutterSpeedLabel, *m_webcamLabel, + *m_liveViewCompensationLabel; QToolButton *m_previousLevelButton, *m_previousFrameButton, *m_previousXSheetFrameButton; QSlider *m_apertureSlider, *m_shutterSpeedSlider, *m_isoSlider, *m_kelvinSlider, *m_webcamFocusSlider, *m_webcamWhiteBalanceSlider, *m_webcamExposureSlider, *m_webcamBrightnessSlider, *m_webcamContrastSlider, *m_webcamGainSlider, *m_webcamSaturationSlider, - *m_liveViewCompensationSlider; + *m_liveViewCompensationSlider, *m_manualFocusSlider; QComboBox *m_cameraListCombo, *m_exposureCombo, *m_fileTypeCombo, - *m_whiteBalanceCombo, *m_resolutionCombo, *m_imageQualityCombo, + *m_whiteBalanceCombo, *m_resolutionCombo, *m_imageQualityCombo, *m_imageSizeCombo, *m_pictureStyleCombo, *m_controlDeviceCombo, *m_captureFramesCombo, *m_colorTypeCombo; LevelNameLineEdit *m_levelNameEdit; @@ -343,7 +343,7 @@ protected slots: void onShowSceneOn2Changed(bool); void onShowSceneOn3Changed(bool); - // canon stuff + // DSLR stuff void onApertureChanged(int index); void onShutterSpeedChanged(int index); void onIsoChanged(int index); @@ -351,8 +351,10 @@ protected slots: void onWhiteBalanceChanged(int index); void onColorTemperatureChanged(int index); void onImageQualityChanged(int index); + void onImageSizeChanged(int index); void onPictureStyleChanged(int index); void onLiveViewCompensationChanged(int index); + void onManualFocusChanged(int index); void onZoomPressed(); void onPickZoomPressed(); void onFocusNear(); @@ -368,6 +370,7 @@ protected slots: void onWhiteBalanceChangedSignal(QString); void onColorTemperatureChangedSignal(QString); void onImageQualityChangedSignal(QString); + void onImageSizeChangedSignal(QString); void onPictureStyleChangedSignal(QString); void onLiveViewCompensationChangedSignal(int); void refreshApertureList(); @@ -377,8 +380,10 @@ protected slots: void refreshWhiteBalanceList(); void refreshColorTemperatureList(); void refreshImageQualityList(); + void refreshImageSizeList(); void refreshPictureStyleList(); void refreshMode(); + void refreshManualFocusRange(); void onFocusCheckToggled(bool on); void onPickFocusCheckToggled(bool on); void onAlwaysUseLiveViewImagesButtonClicked(); @@ -406,9 +411,9 @@ protected slots: void onUseNumpadSignal(bool); void onDrawBeneathSignal(bool); void onLiveViewChanged(bool); - void onNewCameraSelected(int, bool); + void onNewCameraSelected(int); void onCameraIndexChanged(int); - void onUpdateStopMotionControls(bool); + void onUpdateStopMotionControls(); // webcam void onWebcamResolutionsChanged(); diff --git a/toonz/sources/toonz/CMakeLists.txt b/toonz/sources/toonz/CMakeLists.txt index ae0fdfbd..9e7bcb04 100644 --- a/toonz/sources/toonz/CMakeLists.txt +++ b/toonz/sources/toonz/CMakeLists.txt @@ -132,6 +132,7 @@ set(MOC_HEADERS ../stopmotion/canon.h ../stopmotion/stopmotionserial.h ../stopmotion/stopmotionlight.h + ../stopmotion/gphotocam.h cameracapturelevelcontrol.h navtageditorpopup.h ) @@ -369,6 +370,7 @@ set(SOURCES ../stopmotion/canon.cpp ../stopmotion/stopmotionserial.cpp ../stopmotion/stopmotionlight.cpp + ../stopmotion/gphotocam.cpp cameracapturelevelcontrol.cpp navtageditorpopup.cpp ) @@ -438,6 +440,10 @@ if (WITH_CRASHRPT) add_definitions(-DWITH_CRASHRPT) endif() +if (WITH_GPHOTO2) + add_definitions(-DWITH_GPHOTO2) +endif() + if (WITH_WINTAB AND BUILD_TARGET_WIN AND (PLATFORM EQUAL 64)) add_definitions(-DWITH_WINTAB) endif() @@ -468,6 +474,10 @@ if(BUILD_ENV_MSVC) set(EXTRA_LIBS ${EXTRA_LIBS} ${CRASHRPT_LIB}) endif() + if(WITH_GPHOTO2) + set(EXTRA_LIBS ${EXTRA_LIBS} ${GPHOTO2_LIB} ${GPHOTO2_PORT_LIB} ${GPHOTO2_COMPAT_LIB}) + endif() + target_link_libraries(Tahoma2D Qt5::WinMain Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Svg Qt5::Xml Qt5::Script Qt5::Widgets Qt5::PrintSupport Qt5::Multimedia Qt5::SerialPort @@ -482,6 +492,10 @@ elseif(BUILD_ENV_APPLE AND WITH_CANON) # 変なところにライブラリ生成するカスども set(EXTRA_LIBS ${EXTRA_LIBS} "$" "$") + if(WITH_GPHOTO2) + set(EXTRA_LIBS ${EXTRA_LIBS} ${GPHOTO2_LIB} ${GPHOTO2_PORT_LIB}) + endif() + add_dependencies(Tahoma2D tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm) target_link_libraries(Tahoma2D @@ -499,6 +513,10 @@ elseif(BUILD_ENV_APPLE) # 変なところにライブラリ生成するカスども set(EXTRA_LIBS ${EXTRA_LIBS} "$" "$") + if(WITH_GPHOTO2) + set(EXTRA_LIBS ${EXTRA_LIBS} ${GPHOTO2_LIB} ${GPHOTO2_PORT_LIB}) + endif() + add_dependencies(Tahoma2D tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm) target_link_libraries(Tahoma2D @@ -516,6 +534,10 @@ elseif(BUILD_ENV_UNIXLIKE) set(EXTRA_LIBS ${EXTRA_LIBS} ${Boost_LIBRARIES} ${OPENBLAS_LIB}) + if(WITH_GPHOTO2) + set(EXTRA_LIBS ${EXTRA_LIBS} ${GPHOTO2_LIB} ${GPHOTO2_PORT_LIB}) + endif() + if(BUILD_TARGET_WIN) set(EXTRA_LIBS ${EXTRA_LIBS} Qt5::WinMain -lstrmiids -mwindows) endif() diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 67af94fa..d4b78da0 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -3073,12 +3073,10 @@ void MainWindow::defineActions() { QT_TR_NOOP("Lower Stop Motion Opacity"), ""); createStopMotionAction(MI_StopMotionToggleLiveView, QT_TR_NOOP("Toggle Stop Motion Live View"), ""); -#ifdef WITH_CANON createStopMotionAction(MI_StopMotionToggleZoom, QT_TR_NOOP("Toggle Stop Motion Zoom"), ""); createStopMotionAction(MI_StopMotionPickFocusCheck, QT_TR_NOOP("Pick Focus Check Location"), ""); -#endif createStopMotionAction(MI_StopMotionLowerSubsampling, QT_TR_NOOP("Lower Stop Motion Level Subsampling"), ""); createStopMotionAction(MI_StopMotionRaiseSubsampling, diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index 57874351..b85f0c3f 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -1204,7 +1204,7 @@ void SceneViewer::onNewStopMotionImageReady() { m_stopMotionImage->setDpi(m_stopMotion->m_liveViewDpi.x, m_stopMotion->m_liveViewDpi.y); m_hasStopMotionImage = true; - if (m_stopMotion->m_canon->m_pickLiveViewZoom) { + if (m_stopMotion->isPickLiveViewZoom()) { setToolCursor(this, ToolCursor::ZoomCursor); } onSceneChanged(); @@ -1713,7 +1713,6 @@ void SceneViewer::drawOverlay() { glPopMatrix(); } -#ifdef WITH_CANON if (m_stopMotion->m_liveViewStatus == StopMotion::LiveViewOpen && app->getCurrentFrame()->getFrame() == m_stopMotion->getXSheetFrameNumber() - 1) { @@ -1726,12 +1725,11 @@ void SceneViewer::drawOverlay() { } // draw Stop Motion Zoom Box - if (m_stopMotion->m_liveViewStatus == 2 && - m_stopMotion->m_canon->m_pickLiveViewZoom) { + if (m_stopMotion->m_liveViewStatus == 2 && m_stopMotion->isPickLiveViewZoom()) { glPushMatrix(); tglMultMatrix(m_drawCameraAff); m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); - TRect rect = m_stopMotion->m_canon->m_zoomRect; + TRect rect = m_stopMotion->getZoomRect(); glColor3d(1.0, 0.0, 0.0); @@ -1747,8 +1745,6 @@ void SceneViewer::drawOverlay() { glPopMatrix(); } -#endif - // safe area if (safeAreaToggle.getStatus() && m_drawEditingLevel == false && !is3DView()) { @@ -2176,11 +2172,9 @@ void SceneViewer::drawScene() { m_stopMotionImage->getDpi(dpiX, dpiY); smPlayer.m_dpiAff = TScale(Stage::inch / dpiX, Stage::inch / dpiY); bool hide_opacity = false; -#ifdef WITH_CANON - hide_opacity = m_stopMotion->m_canon->m_zooming || - m_stopMotion->m_canon->m_pickLiveViewZoom || + hide_opacity = m_stopMotion->isZooming() || + m_stopMotion->isPickLiveViewZoom() || !m_hasStopMotionLineUpImage; -#endif smPlayer.m_opacity = hide_opacity ? 255.0 : m_stopMotion->getOpacity(); smPlayer.m_sl = m_stopMotion->m_sl; args.m_liveViewImage = m_stopMotionImage; @@ -2293,11 +2287,9 @@ void SceneViewer::drawScene() { m_stopMotionImage->getDpi(dpiX, dpiY); smPlayer.m_dpiAff = TScale(Stage::inch / dpiX, Stage::inch / dpiY); bool hide_opacity = false; -#ifdef WITH_CANON - hide_opacity = m_stopMotion->m_canon->m_zooming || - m_stopMotion->m_canon->m_pickLiveViewZoom || + hide_opacity = m_stopMotion->isZooming()|| + m_stopMotion->isPickLiveViewZoom() || !m_hasStopMotionLineUpImage; -#endif smPlayer.m_opacity = hide_opacity ? 255.0 : m_stopMotion->getOpacity(); smPlayer.m_sl = m_stopMotion->m_sl; diff --git a/toonz/sources/toonz/sceneviewerevents.cpp b/toonz/sources/toonz/sceneviewerevents.cpp index 21481ab6..80dc7aca 100644 --- a/toonz/sources/toonz/sceneviewerevents.cpp +++ b/toonz/sources/toonz/sceneviewerevents.cpp @@ -654,15 +654,13 @@ void SceneViewer::onMove(const TMouseEvent &event) { return; } -#ifdef WITH_CANON TPointD pickPos = winToWorld(curPos); // grab screen picking for stop motion live view zoom if ((event.buttons() & Qt::LeftButton) && - StopMotion::instance()->m_canon->m_pickLiveViewZoom) { - StopMotion::instance()->m_canon->makeZoomPoint(pickPos); + StopMotion::instance()->isPickLiveViewZoom()) { + StopMotion::instance()->makeZoomPoint(pickPos); return; } -#endif TTool *tool = TApp::instance()->getCurrentTool()->getTool(); if (!tool || !tool->isEnabled()) { @@ -709,10 +707,9 @@ void SceneViewer::onMove(const TMouseEvent &event) { } if (!cursorSet) setToolCursor(this, tool->getCursorId()); -#ifdef WITH_CANON - if (StopMotion::instance()->m_canon->m_pickLiveViewZoom) + if (StopMotion::instance()->isPickLiveViewZoom()) setToolCursor(this, ToolCursor::ZoomCursor); -#endif + m_pos = curPos; m_tabletMove = false; m_toolSwitched = false; @@ -840,14 +837,12 @@ void SceneViewer::onPress(const TMouseEvent &event) { if (m_freezedStatus != NO_FREEZED) return; -#ifdef WITH_CANON TPointD pickPos = winToWorld(m_pos); // grab screen picking for stop motion live view zoom - if (StopMotion::instance()->m_canon->m_pickLiveViewZoom) { - StopMotion::instance()->m_canon->makeZoomPoint(pickPos); + if (StopMotion::instance()->isPickLiveViewZoom()) { + StopMotion::instance()->makeZoomPoint(pickPos); return; } -#endif TTool *tool = TApp::instance()->getCurrentTool()->getTool(); if (!tool || !tool->isEnabled()) { @@ -961,12 +956,12 @@ void SceneViewer::onRelease(const TMouseEvent &event) { TTool *tool = TApp::instance()->getCurrentTool()->getTool(); bool canonJumpToQuit = false; -#ifdef WITH_CANON + // Stop if we're picking live view for StopMotion - if (StopMotion::instance()->m_canon->m_pickLiveViewZoom) { + if (StopMotion::instance()->isPickLiveViewZoom()) { canonJumpToQuit = true; } -#endif + if (canonJumpToQuit) { doQuit(); return; @@ -1366,41 +1361,38 @@ bool SceneViewer::event(QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(e); key = keyEvent->key(); -#ifdef WITH_CANON - if ((m_stopMotion->m_canon->m_pickLiveViewZoom || - m_stopMotion->m_canon->m_zooming) && + if ((m_stopMotion->isPickLiveViewZoom() || + m_stopMotion->isZooming()) && (key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_2 || key == Qt::Key_4 || key == Qt::Key_6 || key == Qt::Key_8)) { - if (m_stopMotion->m_canon->m_liveViewZoomReadyToPick == true) { + if (m_stopMotion->isLiveViewZoomReadyToPick()) { if (key == Qt::Key_Left || key == Qt::Key_4) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.x -= 10; + m_stopMotion->adjustLiveViewZoomPickPoint(-10, 0); } if (key == Qt::Key_Right || key == Qt::Key_6) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.x += 10; + m_stopMotion->adjustLiveViewZoomPickPoint(10, 0); } if (key == Qt::Key_Up || key == Qt::Key_8) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.y += 10; + m_stopMotion->adjustLiveViewZoomPickPoint(0, 10); } if (key == Qt::Key_Down || key == Qt::Key_2) { - m_stopMotion->m_canon->m_liveViewZoomPickPoint.y -= 10; + m_stopMotion->adjustLiveViewZoomPickPoint(0, -10); } - if (m_stopMotion->m_canon->m_zooming) { - m_stopMotion->m_canon->setZoomPoint(); + if (m_stopMotion->isZooming()) { + m_stopMotion->setZoomPoint(); } } - m_stopMotion->m_canon->calculateZoomPoint(); + m_stopMotion->calculateZoomPoint(); e->accept(); return true; - } else if (m_stopMotion->m_canon->m_pickLiveViewZoom && + } else if (m_stopMotion->isPickLiveViewZoom() && (key == Qt::Key_Escape || key == Qt::Key_Enter || key == Qt::Key_Return)) { - m_stopMotion->m_canon->toggleZoomPicking(); + m_stopMotion->toggleZoomPicking(); e->accept(); return true; - } else -#endif - if (m_stopMotion->m_liveViewStatus == 2 && + } else if (m_stopMotion->m_liveViewStatus == 2 && (key == Qt::Key_Enter || key == Qt::Key_Return)) { m_stopMotion->captureImage(); e->accept();