diff options
160 files changed, 12545 insertions, 198 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b4742c8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,57 @@ +--- +Language: Cpp +# BasedOnStyle: Mozilla +AccessModifierOffset: -4 +ConstructorInitializerIndentWidth: 2 +AlignEscapedNewlinesLeft: false +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AlwaysBreakTemplateDeclarations: true +AlwaysBreakBeforeMultilineStrings: false +BreakBeforeBinaryOperators: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +DerivePointerAlignment: true +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: false +IndentWrappedFunctionNames: false +IndentFunctionDeclarationAfterType: false +MaxEmptyLinesToKeep: 1 +KeepEmptyLinesAtTheStartOfBlocks: true +NamespaceIndentation: None +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +SpacesBeforeTrailingComments: 1 +Cpp11BracedListStyle: false +Standard: Cpp11 +IndentWidth: 4 +TabWidth: 8 +UseTab: Never +BreakBeforeBraces: Stroustrup +SpacesInParentheses: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +SpaceBeforeParens: ControlStatements +DisableFormat: false +... + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41ca6de --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +Makefile +Makefile.in +GNUmakefile +GNUmakefile.in +TAGS +*~ +TAGS +config.guess +config.sub +config.log +config.status +aclocal.m4 +autogen.err +configure +depcomp +install-sh +ltmain.sh +missing +autom4te.cache +stamp-h1 +shave +shave-libtool +*.o +*.lo +*.la +.libs +.deps +.git +compile +libtool +test-driver +*.plist/ +exempi/exempi-2.0.pc +exempi/exempi +exempi/tests/test.jpg +exempi/tests/test.webp +exempi/tests/testexempicore +exempi/tests/testserialise +exempi/tests/testwritenewprop +exempi/tests/testtiffleak +exempi/tests/testxmpfiles +exempi/tests/testxmpfileswrite +exempi/tests/test2 +exempi/tests/test3 +exempi/tests/testinit +exempi/tests/testfdo18635 +exempi/tests/testfdo83313 +exempi/tests/testcpp +exempi/tests/testwebp +exempi/tests/test*.log +exempi/tests/test*.trs +exempi/doc/Doxyfile +samples/source/dumpmainxmp +samples/source/dumpxmp +samples/source/xmpcoverage +samples/source/xmpfilescoverage +samples/source/customschema +samples/source/modifyingxmp +samples/source/readingxmp +samples/source/xmpcommandtool +samples/source/xmpcoverageLog.txt diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b04c954 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,34 @@ +dist: trusty +language: cpp +matrix: + include: + - compiler: gcc + env: COMPILER=g++ + - compiler: gcc + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libboost-test-dev + - g++-5 + env: COMPILER=g++-5 + - compiler: gcc + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libboost-test-dev + - g++-6 + env: COMPILER=g++-6 + - compiler: clang + env: COMPILER=clang++ +addons: + apt: + packages: + - libboost-test-dev +script: + - ./autogen.sh + - make + - make check
\ No newline at end of file @@ -0,0 +1,14 @@ +The package is based on Adobe XMP SDK CS6 + +Maintainer: +Hubert Figuiere <hub@figuiere.net> + +Original XMP code by: +Adobe Systems Incorporated (XMP SDK) + +Contributions by: +Ian Jacobi +Jason Kivlighn +Michael Biebl <biebl@debian.org> +Tim Mooney +Misty De Meo @@ -0,0 +1,32 @@ +This package is based off Adobe XMP SDK CD6, distributed +under the BSD license reproduced thereafter for convenience +and available in BSD-License.txt + +This package is licensed under the same license. + + +The BSD License + +Copyright (c) 1999 - 2010, Adobe Systems Incorporated +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Adobe Systems Incorporated, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..047887b --- /dev/null +++ b/ChangeLog @@ -0,0 +1,339 @@ +2009-05-26 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FileHandlers/UCF_Handler.cpp (UCF_CheckFormat): + Mismatched new [] / delete. (Closes bug #21934) + +2009-05-15 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp: + Catch unhandled exceptions in xmp_files_can_put_xmp() + (Closes bug #20622) + +2009-03-11 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: + * exempi/Makefile.am: + * m4/ax_ld_check_flag.m4: + Detect proper ldflags. (Closes bug #20554) + + * configure.ac: Bump to version 2.1.1 + +2009-03-11 Lars Holm Nielsen <lnielsen@eso.org> + + * source/XMPFiles/FileHandlers/Makefile.am: + * source/XMPFiles/FormatSupport/Makefile.am: + * configure.ac: + Some files missing when building on Mac + (Closes bug #20554) + +2009-02-24 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp (xmp_set_property): + If the value is struct or array, if the property value + is the empty string pass NULL. + (Closes bug #16030) + +2009-02-22 Hubert Figuiere <hub@figuiere.net> + + * source/common/XMLParserAdapter.hpp: + Remove an annoying warning. + +2009-02-20 Hubert Figuiere <hub@figuiere.net> + + * configure.in: + * m4/shave.m4: + * shave-libtool.in: + * shave.in: + Add shave to make the build output saner. + +2008-12-28 Michael Biebl <biebl@debian.org> + + * tests/utils.cpp + * samples/source/XMPFilesCoverage.cpp + * source/common/XML_Node.cpp + Fix build on gcc 4.4 + +2008-12-24 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FileHandlers/P2_Handler.cpp (SetStartTimecodeFromLegacyXML): + Don't compare string pointers. (Closes: #19312) + +=== 2.1.0 === + +2008-12-24 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/test-bgo.cpp + * exempi/tests/test-xmpfiles.cpp + Remove serious warnings. + +2008-12-21 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/Makefile.am + * exempi/tests/test-bgo.cpp + * exempi/tests/test-exempi-core.cpp + * exempi/tests/test-serialise.cpp + * exempi/tests/test-tiff-leak.cpp + * exempi/tests/test-write-new-prop.cpp + * exempi/tests/test-xmpfiles-write.cpp + * exempi/tests/test-xmpfiles.cpp + * exempi/tests/test3.cpp + * exempi/tests/testinit.cpp + Migrated to use boost/test/minimal + + * exempi/tests/test1.cpp + * exempi/tests/test2.cpp + Split out for the above change. + +2008-12-19 Hubert Figuiere <hub@figuiere.net> + + * exempi/Makefile.am (EXTRA_DIST): Added libexempi.sym + +2008-11-26 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/Makefile.am (TESTS_ENVIRONMENT): + BOOST_TEST_CATCH_SYSTEM_ERRORS=no is set before running + the test. This avoid a failure because of system() on + boost 1.35 and later. + See https://svn.boost.org/trac/boost/ticket/1723 + +2008-11-24 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FormatSupport/ReconcileTIFF.cpp (ImportSingleTIFF_ASCII): + Re-enable the conversion for UNIX. Disabled in the original SDK. + + * exempi/tests/Makefile.am: + * exempi/tests/fdo18635.jpg: + * exempi/tests/test-bgo.cpp + Don't crash on not so valid Exif. (Closes #18635) + And test case. + +2008-11-18 Hubert Figuiere <hub@figuiere.net> + + * exempi/libexempi.sym, exempi/Makefile.am (libexempi_la_LDFLAGS): + Use symbol file. (Closes #16139) + + * samples/testfiles/BlueSquare.gif, + samples/testfiles/Makefile.am: Forgotten files. + + * NEWS, configure.ac, exempi/Makefile.am, + exempi/tests/test2.cpp, exempi/tests/testcore.sh, + samples/Makefile.am, samples/source/Makefile.am, + source/XMPFiles/FileHandlers/Makefile.am, + source/XMPFiles/FormatSupport/Makefile.am, + source/XMPCore/Makefile.am, source/common/Makefile.am: + Fix the build system. + * source/XMPFiles/FileHandlers/AVCHD_Handler.cpp + source/XMPFiles/FileHandlers/MP3_Handler.cpp, + source/XMPFiles/FileHandlers/MP3_Handler.hpp, + source/XMPFiles/FileHandlers/P2_Handler.cpp, + source/XMPFiles/FileHandlers/SonyHDV_Handler.cpp, + source/XMPFiles/FileHandlers/WAV_Handler.cpp, + source/XMPFiles/FileHandlers/WAV_Handler.hpp, + source/XMPFiles/FileHandlers/XDCAMEX_Handler.cpp, + source/XMPFiles/FileHandlers/XDCAM_Handler.cpp, + source/XMPFiles/FormatSupport/ID3_Support.cpp, + source/XMPFiles/FormatSupport/ID3_Support.hpp, + source/XMPFiles/FormatSupport/RIFF_Support.cpp, + source/XMPFiles/FormatSupport/RIFF_Support.hpp, + source/XMPFiles/FormatSupport/ReconcileTIFF.cpp, + source/XMPFiles/FormatSupport/Reconcile_Impl.cpp, + source/XMPFiles/FormatSupport/Reconcile_Impl.hpp, + source/XMPFiles/FormatSupport/TIFF_Support.hpp: + Enable all the file formats that Adobe disabled on + purpose. + * samples/source/ModifyingXMP.cpp, + source/common/EndianUtils.hpp, + source/common/LargeFileAccess.hpp, + source/common/XML_Node.cpp: + Other misc merge fixes. + + * Merge the XPM SDK 4.4.2 + +2008-05-29 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp, exempi/Makefile.am: don't define + UNIX_ENV in the source code but use the CPPFLAGS. + + * exempi/exempi.cpp (xmp_files_get_xmp): CHECK_PTR should + return false and not NULL. + +2008-04-06 Hubert Figuiere <hub@figuiere.net> + + * exempi/xmp.h, exempi/exempi.cpp: add new API + xmp_namespace_prefix(), xmp_prefix_namespace_uri(). + * exempi/tests/test1.cpp: corresponding test. + (Closes #14962) + +2008-04-04 Hubert Figuiere <hub@figuiere.net> + + * Start 2.1.0 + +=== 2.0.2 === + +2008-08-12 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp (set_error): Use pthread for the TLS + if there is no compiler support. + (Closes #16598) + + * configure.ac: + * m4/ax_tls.m4: + Check for TLS. + +=== 2.0.1 === + +2008-04-28 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/test1.cpp: Check that errors are unset. + +2008-04-24 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp: RESET_ERROR is called + upon entry of any functions. + error code is local thread storage. + +2008-04-05 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FormatSupport/Reconcile_Impl.cpp, + configure.ac: Check for iconv constness. (Closes #14613) + +2008-04-04 Hubert Figuiere <hub@figuiere.net> + + * exempi/xmp.h: no stdbool.h on Sun compilers + (Closes #14612) + +=== 2.0.0 === + +2008-04-01 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: This is really 2.0.0 + + * exempi/tests/test1.cpp, exempi/tests/test1.xmp: + Add a test on "Rating:". + +2008-03-30 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FormatSupport/EndianUtils.hpp, + configure.ac: Fix the endian detection. (Closes #15263) + +2008-02-22 Hubert Figuiere <hub@figuiere.net> + + * source/XMPCore/XMPMeta.cpp, + source/XMPFiles/FormatSupport/GIF_Support.cpp, + source/XMPFiles/FormatSupport/ID3_Support.cpp, + source/XMPFiles/FormatSupport/PNG_Support.cpp, + source/XMPFiles/FormatSupport/PSIR_FileWriter.cpp, + source/XMPFiles/FormatSupport/PSIR_MemoryReader.cpp, + source/XMPFiles/FormatSupport/ReconcileIPTC.cpp, + source/XMPFiles/FormatSupport/TIFF_Support.hpp: + Add some missing includes. (Closes #14615) + + * source/XMPFiles/FormatSupport/EndianUtils.hpp: endian + detection on Solaris. (Closes #14614) + +=== 1.99.9 === + +2008-01-30 Hubert Figuiere <hub@figuiere.net> + + * exempi/xmp.h (XMP_OPEN_OPNLYXMP): Bad API breakage fix (introduced + in 1.99.8) + +=== 1.99.8 === + +2008-01-23 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FormatSupport/GIF_Support.cpp (ReadHeader): Fix + a nasty buffer overflow. Closes Debian #454297. Closes Gnome #484105 + Patch by Michael Biebl <biebl@debian.org> + (ReadBlock): Fix another possible overflow similar to the one in + ReadHeader() + +2008-01-22 Hubert Figuiere <hub@figuiere.net> + + * exempi/xmp.h: Fix a typo. (Closes #14200) + +2008-01-18 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/Makefile.am: Disable strict aliasing. This fix + some nasty warning. + +2008-01-13 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: Allow disabling unittest if you + don't have boost (Closes #13712) + + * autogen.sh: Don't run autoheader. (Closes #14049) + + * autogen.sh: re-order commands in autogens.sh + +=== 1.99.7 === + +2008-01-12 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: Fix the soversion. A mix-up occured in the last + release. + +=== 1.99.6 === + +2008-01-11 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/test2.cpp (test_tiff_leak): Ensure that the file is + writable. + +2007-12-22 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: make boost optional as it is only for + the unit tests. (Closes #13712) + + * configure.ac, m4/boost.m4, exempi/test/Makefile.am: + Change the BOOST detection macros. + (Closes #13713) + +2007-12-20 Hubert Figuiere <hub@figuiere.net> + + * source/XMPCore/XMPUtils.cpp (ConvertFromInt64): Fix format + for long long int that was causing a failure on ppc (big endian). + +2007-12-19 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp, exempi/tests/test1.cpp, + exempi/tests/test1.xmp, exempi/xmp.h: + Add setter/getter for int32, int64, bool, float. + + * exempi/xmpconsts.h, exempi/exempi.cpp: add ACR schema namespace + + * public/include/TXMPMeta.hpp, public/include/client-glue/TXMPMeta.incl_cpp, + samples/source/XMPCoreCoverage.cpp, + source/XMPFiles/FormatSupport/ReconcileTIFF.cpp: + Some APIs use long and long long. Change that. + + * source/XMPFiles/FormatSupport/TIFF_FileWriter.cpp, exempi/tests/*: + Fix a memory leak. See http://www.adobeforums.com/webx/.3bc42b73 + And test case. + + * exempi/tests/*, configure.ac: detect valgrind. + Add leak detection support. + +2007-12-17 Hubert Figuiere <hub@figuiere.net> + + * autogen.sh: added for convenience for non-tarball builders. + (Closes #13707) + +2007-12-16 Hubert Figuiere <hub@figuiere.net> + + * exempi/*: added new API for get/set datetime. + + * exempi/tests/*: refactor the test preparation. + +2007-11-13 Hubert Figuiere <hub@figuiere.net> + + * exempi/tests/*.c: Add a bunch of include deemed necessary + by suse factory. + * Add a bunch of include deemed necessary by suse factory. + +2007-11-08 Hubert Figuiere <hub@figuiere.net> + + * source/XMPFiles/FormatSupport/Makefile.am: add + -Wno-multichar to remove warnings. + QuickTime_Support.cpp is in the dist as a noinst_HEADER + diff --git a/ChangeLog-pre.1.99.2 b/ChangeLog-pre.1.99.2 new file mode 100644 index 0000000..72d7e18 --- /dev/null +++ b/ChangeLog-pre.1.99.2 @@ -0,0 +1,22 @@ +2007-06-14 Jason Kivlighn <jkivlighn@gmail.com> + + * source/XMPFiles/FileHandlers/TIFF_Handler.cpp (UpdateFile): + Fix a bug: store the tag as BYTE and not UNDEFINED + to comply with the spec. + +2007-06-06 Hubert Figuiere <hub@figuiere.net> + + * Release 1.99.1 + + * exempi/exempi.cpp: Added more exception catching. + + * exempi/xmpconsts.h: Added NS_CC namespace + + * exempi/exempi.cpp (xmp_register_namespace): wrapped + the namespace registration. Actually needed to + set new API. + +2007-05-11 Hubert Figuiere <hub@figuiere.net> + + * Initial version of exempi 1.99.0 + diff --git a/ChangeLog-pre.1.99.3 b/ChangeLog-pre.1.99.3 new file mode 100644 index 0000000..261ea6f --- /dev/null +++ b/ChangeLog-pre.1.99.3 @@ -0,0 +1,21 @@ +2007-06-25 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp (xmp_copy): Added API. + +2007-06-24 Hubert Figuiere <hub@figuiere.net> + + * Added xmp_set_property2(), xmp_set_array_item() + and xmp_get_error() to the public API. + +2007-06-23 Hubert Figuiere <hub@figuiere.net> + + * Added xmp_get_property_and_bits() and all the + option bits for it. + +2007-06-21 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp (xmp_files_get_xmp): More + exception handling. Should be better for error + management and resource tracking: was causing XMP to + leak because the exception was not caught. + diff --git a/ChangeLog-pre.1.99.4 b/ChangeLog-pre.1.99.4 new file mode 100644 index 0000000..e4e3bdb --- /dev/null +++ b/ChangeLog-pre.1.99.4 @@ -0,0 +1,12 @@ +2007-06-29 Hubert Figuiere <hub@figuiere.net> + + * rpm/SLED10.spec: Added .spec for SLED10 packaging + (only in git) + +2007-06-28 Hubert Figuiere <hub@figuiere.net> + + * New API wrapped: xmp_serialize{,_and_format}() and the + corresponding option bits + + * New API wrapped: xmp_get_array_item() + diff --git a/ChangeLog-pre.1.99.5 b/ChangeLog-pre.1.99.5 new file mode 100644 index 0000000..f422ab3 --- /dev/null +++ b/ChangeLog-pre.1.99.5 @@ -0,0 +1,22 @@ +2007-08-14 Hubert Figuiere <hub@figuiere.net> + + * New API xmp_delete_localized_text(), by Ian Jacobi. + +2007-08-13 Hubert Figuiere <hub@figuiere.net> + + * source/XMPCore/, public/include/: new call DeleteLocalizedText() + by Ian Jacobi. + + * New API xmp_append_array_item(), xmp_delete_property(), + xmp_has_property(), xmp_get_localized_text(), + xmp_set_localized_text() by Ian Jacobi. + * exempi.cpp (xmp_files_open_new): Handle exception properly + by Ian Jacobi. + +2007-08-12 Hubert Figuiere <hub@figuiere.net> + + * Added GIF smart handler support by Ian Jacobi. + + * source/XMPCore/XMPCore_Impl.hpp (kXMPCoreName): Add Exempi + name to clearly identify when Exempi is generating. + diff --git a/ChangeLog-pre.1.99.6 b/ChangeLog-pre.1.99.6 new file mode 100644 index 0000000..8cd8d93 --- /dev/null +++ b/ChangeLog-pre.1.99.6 @@ -0,0 +1,37 @@ +2007-11-06 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: Lower requirement for libboost. + +2007-11-01 Hubert Figuiere <hub@figuiere.net> + + * exempi/doc/*, exempi/Makefile.am, configure.ac: Documentation + generation with Doxygen (manual). + +2007-10-31 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp: CHECK_PTR macro to check the input pointers + in all the API functions. + More functions return true or false (instead of void). + + * exempi/tests/*: update for new API. + +2007-10-30 Hubert Figuiere <hub@figuiere.net> + + * ABI breakage: soversion is now 3 + + * exempi/{exempi.cpp,xmp.h}: xmp_get_property_and_bits() renamed + xmp_get_property(). xmp_set_property2() renamed + xmp_set_property(). More exception handling and refactor + set_error() use. + + * exempi/tests/*: update for new API. + +2007-10-02 Hubert Figuiere <hub@figuiere.net> + + * exempi/exempi.cpp (xmp_files_new): Catch + exceptions. + +2007-08-17 Hubert Figuiere <hub@figuiere.net> + + * configure.ac: add AC_CONFIG_MACRO_DIR to configure. + @@ -0,0 +1,234 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006 Free Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..2fdee08 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,42 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = third-party source XMPCore XMPFiles samples exempi +DIST_SUBDIRS = build third-party source XMPCore XMPFiles XMPFilesPlugins samples exempi public + +EXTRA_DIST = autogen.sh @@ -0,0 +1,215 @@ +2.4.0 + +- Bug #89449: Upgrade XMPCore to Adobe XMP CC 2014.12. + - New flag to optimize layout on MPEG4 files. + - GoPro MPEG4 video files support. + - Improved JPEG support. + - iXML support in WAVE files. + - Several bugs and memory leaks fixes. + - Changes from Adobe XMP CC 2013.06. + - Pluggable file handlers (not exposed yet in Exempi) + - Support for Exif 2.3 properties + - New RIFF file handler + - Better Postscript support. + - Lot of bug fixes. +- New API: added XMP_OPEN_OPTIMIZEFILELAYOUT for new SDK. +- Now require (partial) C++11 support to compile (gcc 4.4.7 tested) +- New: WebP format handler (contributed: Frankie Dintino, The Atlantic) + +Internal: + +- Exempi is now automatically build and the test run by Travis CI. + +2.3.0 - 2016/03/15 + +- New: API xmp_datetime_compare(). +- New: API xmp_string_len() to get the length of the XmpString. +- Bug #94065: + - New: API xmp_files_can_put_xmp_xmpstring() and xmp_files_can_put_xmp_cstr() + variants. + - New: API xmp_files_put_xmp_xmpstring() and xmp_files_put_xmp_cstr() + variants. + - New: API xmp_files_get_xmp_xmpstring() variant. + - Test: check the status of the PDF handler. +- Bug #90380: Fix potential crash with corrupt TIFF file. +- Bug #14612: Better Solaris compilation fix. +- Fix header to pass -Wstrict-prototypes + +2.2.2 - 2014/08/31 + +- Public header cleanup and documentation update. +- Update Doxygen config. +- Bug #73058: Add missing include for MacOS. +- Bug #72810: Fix typo in date test in MP3 handler. +- Bug #83313: Fix crash on invalid Exif (from Samsung) +- Fix valgrind testing for xmpcore.sh +- Fix delete / delete[] mismatch in ID3_Support.hpp + +2.2.1 - 2013/06/29 + +- Bug #54011: Use POSIX API for files on MacOS. (Misty De Meo) +- Bug #58175: Replace OS X FlatCarbon headers. (Misty De Meo) +- Added a manpage for exempi(1). +- Added the -n option to the command line for arbitrary namespaces. + +2.2.0 - 2012/02/21 + +- New 'exempi' command line tool. +- Upgrade XMPCore to Adobe XMP 5.1.2 + - Quicktime support now works without Quicktime. + - Reconciliation with ID3v2. + - "Blessed" 64-bits support (we already had it in exempi). + - Slight change in the way XMP are written for MWG compliance. + - Fixed a serious bug with RIFF. + - Change in the way local text encoding is dealt with. + - Alternative languages behave slightly differently by changing + how the default language property is managed. + - Probably a bunch of bugs fixed that I don't know about. +- Update unit tests. + - Refactor the fixtures. +- Use automake silent rules instead of shave. (build only) +- "make dist" generate a bzip2 archive as well. (build only) +- Remove some obsolete warning flags. (build only) +- Build xmpcommandtool +- New: API xmp_files_get_format_info(). +- New: API xmp_files_check_file_format(). +- New: API xmp_files_get_file_info(). +- New: API XMP_PROP_ARRAY_INSERT_BEFORE, XMP_PROP_ARRAY_INSERT_AFTER array options. +- New: C++ helpers in xmp++.hpp. + +Bug fixes: + +- Bug #37747: mismatch delete/delete[] and new/new[] (from Meego + https://bugs.meego.com/show_bug.cgi?id=14661) + +2.1.1 - 2009/06/30 + +New features: + +- Added shave to the build system for sane output. (build only) + +Bug fixes: + +- Bug #16030: if the property is an array or struct allow "" to be passed + as a value. +- Bug #19312: source/XMPFiles/FileHandlers/P2_Handler.cpp was using + an improper string comparison. (made rpmlint unhappy). +- Bug #20554: Missing file on MacOS X. +- Bug #20554: Detect ldflags properly. +- Bug #20622: Catch unhandled exceptions in xmp_files_can_put_xmp(). +- Bug #21934: Mismatched new [] / delete. +- Bug #22554: Fix a SIGFPE encountered on some invalid files. (Bug GNOME #586720) + +2.1.0 + +- Upgrade XMPCore to Adobe XMP 4.4.2 + - Handlers for additional file formats, including ASF (WMA, WMV), FLV; + MPEG4; SWF; folder-based video formats AVCHD, P2, SonyHDV, and XDCAM; UCF + - Additional schemas to support document histories, composed documents, + and temporal metadata +- New: NS_PDF namespace for PDF. +- New: API xmp_prefix_namespace_uri() and xmp_namespace_prefix(). Bug #14962. +- Bug: make sure boost >1.35 does not fail test with system(). +- Bug: unit test now use boost/test/minimal.hpp to work with more boost + install. (known boost.test bug) +- Bug: fix a typo in a CHECK_PTR call causing warnings on gcc < 4. +- Bug: no longer define UNIX_ENV in exempi.cpp and let CPPFLAGS do it. +- Bug #16139: the list of exported symbols was too large. +- Bug #18635: fix crasher. + +2.0.2 + +- Bug #16598: address the lack of TLS for some platforms. + +2.0.1 + +- Bug #14612: no stdbool.h for Sun compilers. +- Bug #14613: check for iconv() const-ness. +- Make the error checking more robust. +- Make error code thread-safe (ie local to the thread). + +2.0.0 + +- Bug #14614, Bug #15263: endian detection in configure. +- Bug #14615: missing includes for Solaris. + +1.99.9 + +- Bug: fixed an API breakage introduced in 1.99.8 + +1.99.8 + +- Bug #14049: don't run autoheader. +- Bug #13712: add --enable-unittest to disable tests. +- Bug: Disable strict aliasing in XMPFiles due to bad casting. +- Bug #14200: fix a typo. +- Bug: fix a couple of buffer overflows in GIF support. Closes Debian #454297. + Closes Gnome #484105 + +1.99.7 + +- Bug: fix soversion. + +1.99.6 + +- New: API xmp_get_property_date() / xmp_set_property_date() with tests. +- New: API xmp_{get,set]_property_{float,bool,int32,int64}() with tests. +- New: API add ACR schema namespaces. +- Test: refactor a the tests preparation. +- Test: add a test for multiple initializations. +- Test: use valgrind is available. +- Bug: fix configure to allow building on MacOS X. Closes bug #13596 +- Bug #13707: add autogen.sh +- Bug #13713: fix boost macros to link boost.test statically (for 1.34). +- Bug #13712: skip tests if no boost. + +1.99.5 + +- ABI breakage: soversion is now 3 +- Change: API xmp_files_close(), xmp_files_put_xmp(), xmp_files_free(), + xmp_free(), xmp_iterator_free(), xmp_iterator_skip() now return bool. +- Change: API xmp_get_property_and_bits() renamed xmp_get_property(). +- Change: API xmp_set_property2() renamed xmp_set_property(). +- Bug: all API should check about input and return an error if + passed NULL. +- Bug: more exception handling and refactor set_error() use. +- Bug: add AC_CONFIG_MACRO_DIR to configure. +- Bug: Lower requirement for libboost to 1.33.0. +- New: Doxygen API doc generation. + +1.99.4 + +- New: GIF Files smart handlers +- New: API xmp_append_array_item(), xmp_delete_property(), + xmp_has_property(), xmp_get_localized_text(), + xmp_set_localized_text() +- New: API xmp_delete_localized_text() +- New: Exempi will be visible in the "generator" string of the XMP packet. +- Bug: xmp_files_open_new() will handle exceptions properly + +1.99.3 + +- New: API xmp_serialize{,_and_format}() and the + corresponding option bits +- New API xmp_get_array_item() + +1.99.2 + +- New: API xmp_copy() +- New: API xmp_set_property2(), xmp_set_array_item() + and xmp_get_error() +- New: API xmp_get_property_and_bits() +- Bug: xmp_files_get_xmp() handle exceptions properly. + +1.99.1 + +- Bug: store the TIFF tag as BYTE and not UNDEFINED + to comply with the spec. +- Bug: more exception catched. +- New: added NS_CC namespace +- New: API xmp_register_namespace() + +1.99.0 + +Initial release of the 2.0 series. Based on Adobe XMP SDK 4.1.1 + @@ -0,0 +1,15 @@ +exempi is a port of Adobe XMP SDK to work on UNIX and to be build with +GNU automake. + +It includes XMPCore and XMPFiles, libexempi, a C-based API and exempi +a command line tool. + +It require at least the gcc 4.4.7 C++ compiler or clang++. + +It is maintained by Hubert Figuiere <hub@figuiere.net> + +Contributors: + Frankie Dintino <fdintino@theatlantic.com> + + +Homepage: http://libopenraw.freedesktop.org/wiki/Exempi @@ -0,0 +1,9 @@ +Things to do: + +- allow providing your own IO +- add handler for Ogg (need to be defined) +- reconcile CC license from Ogg to XMP. Check for other media +format like MP3 +- add support for QuickTime without having quicktime +- bug gna #10110 +- add support for PDF (using PoDoFo?) diff --git a/XMPCore/Makefile.am b/XMPCore/Makefile.am new file mode 100644 index 0000000..525e2e5 --- /dev/null +++ b/XMPCore/Makefile.am @@ -0,0 +1,3 @@ + + +SUBDIRS=source diff --git a/XMPCore/source/ExpatAdapter.cpp b/XMPCore/source/ExpatAdapter.cpp index 5fe0181..38ad449 100644 --- a/XMPCore/source/ExpatAdapter.cpp +++ b/XMPCore/source/ExpatAdapter.cpp @@ -146,7 +146,7 @@ void ExpatAdapter::ParseBuffer ( const void * buffer, size_t length, bool last / #if BanAllEntityUsage if ( this->isAborted ) { - XMP_Error error(kXMPErr_BadXML, "DOCTYPE is not allowed" ) + XMP_Error error(kXMPErr_BadXML, "DOCTYPE is not allowed" ); this->NotifyClient ( kXMPErrSev_Recoverable, error ); } #endif diff --git a/XMPCore/source/Makefile.am b/XMPCore/source/Makefile.am new file mode 100644 index 0000000..309d255 --- /dev/null +++ b/XMPCore/source/Makefile.am @@ -0,0 +1,64 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + + +noinst_LTLIBRARIES = libXMPCore.la + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/public/include \ + -Wall @XMPCORE_CPPFLAGS@ + +noinst_HEADERS = \ + XMPCore_Impl.hpp XMPIterator.hpp \ + XMPMeta.hpp XMPUtils.hpp + + +libXMPCore_la_SOURCES = ExpatAdapter.cpp \ + WXMPIterator.cpp \ + WXMPUtils.cpp \ + XMPIterator.cpp \ + XMPMeta-GetSet.cpp \ + XMPMeta-Serialize.cpp \ + XMPUtils-FileInfo.cpp \ + ParseRDF.cpp \ + WXMPMeta.cpp \ + XMPCore_Impl.cpp \ + XMPMeta.cpp \ + XMPMeta-Parse.cpp \ + XMPUtils.cpp + diff --git a/XMPCore/source/ParseRDF.cpp b/XMPCore/source/ParseRDF.cpp index b163867..8ec0e87 100644 --- a/XMPCore/source/ParseRDF.cpp +++ b/XMPCore/source/ParseRDF.cpp @@ -315,16 +315,6 @@ GetRDFTermKind ( const XMP_VarString & name ) // ================================================================================================= static void -RemoveChild ( XMP_Node * xmpParent, size_t index ) -{ - XMP_Node * child = xmpParent->children[index]; - xmpParent->children.erase ( xmpParent->children.begin() + index ); - delete child; -} - -// ------------------------------------------------------------------------------------------------- - -static void RemoveQualifier ( XMP_Node * xmpParent, size_t index ) { XMP_Node * qualifier = xmpParent->qualifiers[index]; @@ -359,20 +349,6 @@ IsCoreSyntaxTerm ( RDFTermKind term ) } // ------------------------------------------------------------------------------------------------- -// IsSyntaxTerm -// ------------ -// -// 7.2.3 syntaxTerms -// coreSyntaxTerms | rdf:Description | rdf:li - -static bool -IsSyntaxTerm ( RDFTermKind term ) -{ - if ( (kRDFTerm_FirstSyntax <= term) && (term <= kRDFTerm_LastSyntax) ) return true; - return false; -} - -// ------------------------------------------------------------------------------------------------- // IsOldTerm // --------- // @@ -387,20 +363,6 @@ IsOldTerm ( RDFTermKind term ) } // ------------------------------------------------------------------------------------------------- -// IsNodeElementName -// ----------------- -// -// 7.2.5 nodeElementURIs -// anyURI - ( coreSyntaxTerms | rdf:li | oldTerms ) - -static bool -IsNodeElementName ( RDFTermKind term ) -{ - if ( (term == kRDFTerm_li) || IsOldTerm ( term ) ) return false; - return (! IsCoreSyntaxTerm ( term )); -} - -// ------------------------------------------------------------------------------------------------- // IsPropertyElementName // --------------------- // @@ -415,20 +377,6 @@ IsPropertyElementName ( RDFTermKind term ) } // ------------------------------------------------------------------------------------------------- -// IsPropertyAttributeName -// ----------------------- -// -// 7.2.7 propertyAttributeURIs -// anyURI - ( coreSyntaxTerms | rdf:Description | rdf:li | oldTerms ) - -static bool -IsPropertyAttributeName ( RDFTermKind term ) -{ - if ( (term == kRDFTerm_Description) || (term == kRDFTerm_li) || IsOldTerm ( term ) ) return false; - return (! IsCoreSyntaxTerm ( term )); -} - -// ------------------------------------------------------------------------------------------------- // IsNumberedArrayItemName // ----------------------- // diff --git a/XMPCore/source/XMPCore_Impl.cpp b/XMPCore/source/XMPCore_Impl.cpp index daec535..86c30bd 100644 --- a/XMPCore/source/XMPCore_Impl.cpp +++ b/XMPCore/source/XMPCore_Impl.cpp @@ -645,6 +645,7 @@ ExpandXPath ( XMP_StringPtr schemaNS, XMP_StringPtr qualName = 0 , nameEnd = 0; XMP_VarString currStep; + qualName = nameEnd = NULL; size_t resCount = 2; // Guess at the number of steps. At least 2, plus 1 for each '/' or '['. for ( stepEnd = propPath; *stepEnd != 0; ++stepEnd ) { if ( (*stepEnd == '/') || (*stepEnd == '[') ) ++resCount; diff --git a/XMPCore/source/XMPCore_Impl.hpp b/XMPCore/source/XMPCore_Impl.hpp index 52aa114..7ce2537 100644 --- a/XMPCore/source/XMPCore_Impl.hpp +++ b/XMPCore/source/XMPCore_Impl.hpp @@ -121,7 +121,7 @@ extern WXMP_Result void_wResult; (XMP_API_VERSION_MINOR << 16) | \ (XMP_API_VERSION_MICRO << 8) ) - #define kXMPCoreName "XMP Core" + #define kXMPCoreName "Exempi + XMP Core" #define kXMPCore_VersionMessage kXMPCoreName " " XMPCORE_API_VERSION_STRING // ================================================================================================= // Support for call tracing diff --git a/XMPCore/source/XMPIterator.cpp b/XMPCore/source/XMPIterator.cpp index 275e32f..80cf6ca 100644 --- a/XMPCore/source/XMPIterator.cpp +++ b/XMPCore/source/XMPIterator.cpp @@ -367,7 +367,7 @@ XMPIterator::Terminate() RELEASE_NO_THROW XMPIterator::XMPIterator ( const XMPMeta & xmpObj, XMP_StringPtr schemaNS, XMP_StringPtr propName, - XMP_OptionBits options ) : info(IterInfo(options,&xmpObj)), clientRefs(0) + XMP_OptionBits options ) : clientRefs(0), info(IterInfo(options,&xmpObj)) { if ( (options & kXMP_IterClassMask) != kXMP_IterProperties ) { XMP_Throw ( "Unsupported iteration kind", kXMPErr_BadOptions ); @@ -485,11 +485,10 @@ XMPIterator::XMPIterator ( const XMPMeta & xmpObj, // // Constructor for iterations over global tables such as registered namespaces or aliases. -XMPIterator::XMPIterator ( XMP_StringPtr schemaNS, - XMP_StringPtr propName, - XMP_OptionBits options ) : info(IterInfo(options,0)), clientRefs(0) +XMPIterator::XMPIterator ( XMP_StringPtr /*schemaNS*/, + XMP_StringPtr /*propName*/, + XMP_OptionBits options ) : clientRefs(0), info(IterInfo(options,0)) { - void * p; p = &schemaNS; p = &propName; p = &options; // Avoid unused param warnings. XMP_Throw("Unimplemented XMPIterator constructor for global tables", kXMPErr_Unimplemented); } // XMPIterator for global tables diff --git a/XMPCore/source/XMPMeta-GetSet.cpp b/XMPCore/source/XMPMeta-GetSet.cpp index 18c024c..c67965f 100644 --- a/XMPCore/source/XMPMeta-GetSet.cpp +++ b/XMPCore/source/XMPMeta-GetSet.cpp @@ -1081,7 +1081,6 @@ XMPMeta::DeleteLocalizedText ( XMP_StringPtr schemaNS, XMP_Node * assocNode = 0; size_t assocIndex; - size_t assocIsXDefault = false; if ( itemIsXDefault ) { @@ -1100,7 +1099,6 @@ XMPMeta::DeleteLocalizedText ( XMP_StringPtr schemaNS, if ( (qualNode->name == "xml:lang") && (qualNode->value == "x-default") ) { assocNode = arrayNode->children[0]; assocIndex = 0; - assocIsXDefault = true; } } diff --git a/XMPCore/source/XMPMeta-Serialize.cpp b/XMPCore/source/XMPMeta-Serialize.cpp index 39a5270..f31e65e 100644 --- a/XMPCore/source/XMPMeta-Serialize.cpp +++ b/XMPCore/source/XMPMeta-Serialize.cpp @@ -44,7 +44,7 @@ using namespace std; static const char * kPacketHeader = "<?xpacket begin=\"\xEF\xBB\xBF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>"; static const char * kPacketTrailer = "<?xpacket end=\"w\"?>"; // ! The w/r is at [size-4]. -static const char * kTXMP_SchemaGroup = "XMP_SchemaGroup"; +//static const char * kTXMP_SchemaGroup = "XMP_SchemaGroup"; static const char * kRDF_XMPMetaStart = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\""; static const char * kRDF_XMPMetaEnd = "</x:xmpmeta>"; @@ -59,19 +59,19 @@ static const char * kRDF_StructStart = "<rdf:Description>"; static const char * kRDF_StructEnd = "</rdf:Description>"; static const char * kRDF_BagStart = "<rdf:Bag>"; -static const char * kRDF_BagEnd = "</rdf:Bag>"; +//static const char * kRDF_BagEnd = "</rdf:Bag>"; -static const char * kRDF_SeqStart = "<rdf:Seq>"; -static const char * kRDF_SeqEnd = "</rdf:Seq>"; +//static const char * kRDF_SeqStart = "<rdf:Seq>"; +//static const char * kRDF_SeqEnd = "</rdf:Seq>"; -static const char * kRDF_AltStart = "<rdf:Alt>"; -static const char * kRDF_AltEnd = "</rdf:Alt>"; +//static const char * kRDF_AltStart = "<rdf:Alt>"; +//static const char * kRDF_AltEnd = "</rdf:Alt>"; static const char * kRDF_ItemStart = "<rdf:li>"; -static const char * kRDF_ItemEnd = "</rdf:li>"; +//static const char * kRDF_ItemEnd = "</rdf:li>"; static const char * kRDF_ValueStart = "<rdf:value>"; -static const char * kRDF_ValueEnd = "</rdf:value>"; +//static const char * kRDF_ValueEnd = "</rdf:value>"; // ================================================================================================= @@ -1347,11 +1347,9 @@ XMPMeta::SerializeToBuffer ( XMP_VarString * rdfString, } else { std::string padStr ( " " ); padStr[0] = padStr[1] = padStr[2] = 0; // Assume big endian. - UTF8_to_UTF32_Proc Converter = UTF8_to_UTF32BE; if ( charEncoding & _XMP_LittleEndian_Bit ) { padStr[0] = ' '; padStr[1] = padStr[2] = padStr[3] = 0; - Converter = UTF8_to_UTF32LE; } utf8Str.swap ( *rdfString ); diff --git a/XMPCore/source/XMPMeta.cpp b/XMPCore/source/XMPMeta.cpp index b2f02b6..ae31063 100644 --- a/XMPCore/source/XMPMeta.cpp +++ b/XMPCore/source/XMPMeta.cpp @@ -686,7 +686,7 @@ RegisterStandardAliases() // ============ -XMPMeta::XMPMeta() : tree(XMP_Node(0,"",0)), clientRefs(0), xmlParser(0) +XMPMeta::XMPMeta() : clientRefs(0), tree(XMP_Node(0,"",0)), xmlParser(0) { #if XMP_TraceCTorDTor printf ( "Default construct XMPMeta @ %.8X\n", this ); @@ -886,7 +886,9 @@ XMPMeta::Initialize() XMP_Assert ( sizeof(XMP_Bool) == 1 ); XMP_Assert ( sizeof(XMP_OptionBits) == 4 ); // Check that option masking work on all 32 bits. +#if XMP_DebugBuild XMP_OptionBits flag = (XMP_OptionBits) (~0UL); +#endif XMP_Assert ( flag == (XMP_OptionBits)(-1L) ); XMP_Assert ( (flag ^ kXMP_PropHasLang) == 0xFFFFFFBFUL ); XMP_Assert ( (flag & ~kXMP_PropHasLang) == 0xFFFFFFBFUL ); @@ -1030,10 +1032,9 @@ XMPMeta::GetGlobalOptions() // ---------------- /* class-static */ void -XMPMeta::SetGlobalOptions ( XMP_OptionBits options ) +XMPMeta::SetGlobalOptions ( XMP_OptionBits /*options*/ ) { - void * p; p = &options; // Avoid unused param warnings. XMP_Throw("Unimplemented method XMPMeta::SetGlobalOptions", kXMPErr_Unimplemented); } // SetGlobalOptions @@ -1267,11 +1268,9 @@ XMPMeta::GetObjectOptions() const // ---------------- void -XMPMeta::SetObjectOptions ( XMP_OptionBits options ) +XMPMeta::SetObjectOptions ( XMP_OptionBits /*options*/ ) { - void * p; p = &options; // Avoid unused param warnings. XMP_Throw ( "Unimplemented method XMPMeta::SetObjectOptions", kXMPErr_Unimplemented ); - } // SetObjectOptions diff --git a/XMPCore/source/XMPMeta.hpp b/XMPCore/source/XMPMeta.hpp index 34b71aa..a93554d 100644 --- a/XMPCore/source/XMPMeta.hpp +++ b/XMPCore/source/XMPMeta.hpp @@ -411,7 +411,7 @@ public: private: // ! These are hidden on purpose: - XMPMeta ( const XMPMeta & /* original */ ) : tree(XMP_Node(0,"",0)), clientRefs(0), xmlParser(0) + XMPMeta ( const XMPMeta & /* original */ ) : clientRefs(0), tree(XMP_Node(0,"",0)), xmlParser(0) { XMP_Throw ( "Call to hidden constructor", kXMPErr_InternalFailure ); }; void operator= ( const XMPMeta & /* rhs */ ) { XMP_Throw ( "Call to hidden operator=", kXMPErr_InternalFailure ); }; diff --git a/XMPCore/source/XMPUtils.cpp b/XMPCore/source/XMPUtils.cpp index 8a8c4fc..c075389 100644 --- a/XMPCore/source/XMPUtils.cpp +++ b/XMPCore/source/XMPUtils.cpp @@ -1890,7 +1890,10 @@ static size_t MoveLargestProperty ( XMPMeta & stdXMP, XMPMeta * extXMP, PropSize printf ( " Move %s, %d bytes\n", propName, propSize ); #endif - bool moved = MoveOneProperty ( stdXMP, extXMP, schemaURI, propName ); +#if XMP_DebugBuild + bool moved = +#endif + MoveOneProperty ( stdXMP, extXMP, schemaURI, propName ); XMP_Assert ( moved ); propSizes.erase ( lastPos ); @@ -3025,9 +3028,11 @@ XMPUtils::PackageForJPEG ( const XMPMeta & origXMP, // Adjust the standard XMP padding to be up to 2KB. +#if XMP_DebugBuild XMP_Assert ( (stdStr->size() > kTrailerLen) && (stdStr->size() <= kStdXMPLimit) ); const char * packetEnd = stdStr->c_str() + stdStr->size() - kTrailerLen; XMP_Assert ( XMP_LitMatch ( packetEnd, kPacketTrailer ) ); +#endif size_t extraPadding = kStdXMPLimit - stdStr->size(); // ! Do this before erasing the trailer. if ( extraPadding > 2047 ) extraPadding = 2047; diff --git a/XMPFiles/Makefile.am b/XMPFiles/Makefile.am new file mode 100644 index 0000000..525e2e5 --- /dev/null +++ b/XMPFiles/Makefile.am @@ -0,0 +1,3 @@ + + +SUBDIRS=source diff --git a/XMPFiles/source/FileHandlers/AIFF_Handler.cpp b/XMPFiles/source/FileHandlers/AIFF_Handler.cpp index 8c9d604..6331a0b 100644 --- a/XMPFiles/source/FileHandlers/AIFF_Handler.cpp +++ b/XMPFiles/source/FileHandlers/AIFF_Handler.cpp @@ -132,7 +132,7 @@ const ChunkIdentifier AIFF_MetaHandler::kAIFCAnno[2] = { { kChunk_FORM, kType_AI // ================================ AIFF_MetaHandler::AIFF_MetaHandler ( XMPFiles * _parent ) - : mChunkBehavior(NULL), mChunkController(NULL), + : mChunkController(NULL), mChunkBehavior(NULL), mAiffMeta(), mXMPChunk(NULL), mNameChunk(NULL), mAuthChunk(NULL), mCprChunk(NULL), mAnnoChunk(NULL) diff --git a/XMPFiles/source/FileHandlers/MP3_Handler.cpp b/XMPFiles/source/FileHandlers/MP3_Handler.cpp index e9520f3..9295a2e 100644 --- a/XMPFiles/source/FileHandlers/MP3_Handler.cpp +++ b/XMPFiles/source/FileHandlers/MP3_Handler.cpp @@ -130,8 +130,8 @@ MP3_MetaHandler::MP3_MetaHandler ( XMPFiles * _parent ) this->newFramesSize = 0; this->tagIsDirty = false; this->mustShift = false; - this->majorVersion = 2.3; - this->minorVersion = 2.3; + this->majorVersion = 2; + this->minorVersion = 3; this->hasID3Tag = false; this->hasFooter = false; this->extHeaderSize = 0; diff --git a/XMPFiles/source/FileHandlers/Makefile.am b/XMPFiles/source/FileHandlers/Makefile.am new file mode 100644 index 0000000..1198856 --- /dev/null +++ b/XMPFiles/source/FileHandlers/Makefile.am @@ -0,0 +1,73 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + + +noinst_LTLIBRARIES = libxmpfilehandlers.la + +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/public/include \ + -Wall @XMPCORE_CPPFLAGS@ + + +libxmpfilehandlers_la_SOURCES = \ +AIFF_Handler.cpp AIFF_Handler.hpp\ +ASF_Handler.cpp ASF_Handler.hpp\ +AVCHD_Handler.cpp AVCHD_Handler.hpp\ +Basic_Handler.cpp Basic_Handler.hpp\ +FLV_Handler.cpp FLV_Handler.hpp\ +InDesign_Handler.cpp InDesign_Handler.hpp\ +JPEG_Handler.cpp JPEG_Handler.hpp\ +MP3_Handler.cpp MP3_Handler.hpp\ +MPEG2_Handler.cpp MPEG2_Handler.hpp \ +MPEG4_Handler.cpp MPEG4_Handler.hpp \ +P2_Handler.cpp P2_Handler.hpp\ +PNG_Handler.cpp PNG_Handler.hpp\ +PostScript_Handler.cpp PostScript_Handler.hpp\ +PSD_Handler.cpp PSD_Handler.hpp\ +RIFF_Handler.cpp RIFF_Handler.hpp \ +Scanner_Handler.cpp Scanner_Handler.hpp\ +SonyHDV_Handler.cpp SonyHDV_Handler.hpp\ +SWF_Handler.cpp SWF_Handler.hpp\ +TIFF_Handler.cpp TIFF_Handler.hpp\ +Trivial_Handler.cpp Trivial_Handler.hpp\ +UCF_Handler.cpp UCF_Handler.hpp\ +XDCAMEX_Handler.cpp XDCAMEX_Handler.hpp\ +XDCAM_Handler.cpp XDCAM_Handler.hpp\ +WAVE_Handler.cpp WAVE_Handler.hpp \ +GIF_Handler.cpp GIF_Handler.hpp \ +WEBP_Handler.cpp WEB_Handler.hpp +$(NULL) + diff --git a/XMPFiles/source/FileHandlers/P2_Handler.cpp b/XMPFiles/source/FileHandlers/P2_Handler.cpp index 982744d..1b7ad09 100644 --- a/XMPFiles/source/FileHandlers/P2_Handler.cpp +++ b/XMPFiles/source/FileHandlers/P2_Handler.cpp @@ -720,7 +720,7 @@ void P2_MetaHandler::SetStartTimecodeFromLegacyXML ( XML_NodePtr legacyVideoCont dmTimeFormat = "50Timecode"; this->AdjustTimeCode( p2StartTimecode, false ); - } else if ( p2FrameRate == "59.94p" ) { + } else if ( ( p2FrameRate == "59.94p" ) && ( p2DropFrameFlag != 0 ) ) { if ( XMP_LitMatch ( p2DropFrameFlag, "true" ) ) { dmTimeFormat = "5994DropTimecode"; diff --git a/XMPFiles/source/FileHandlers/PSD_Handler.cpp b/XMPFiles/source/FileHandlers/PSD_Handler.cpp index cbcf4df..312e855 100644 --- a/XMPFiles/source/FileHandlers/PSD_Handler.cpp +++ b/XMPFiles/source/FileHandlers/PSD_Handler.cpp @@ -81,7 +81,7 @@ XMPFileHandler * PSD_MetaHandlerCTor ( XMPFiles * parent ) // PSD_MetaHandler::PSD_MetaHandler // ================================ -PSD_MetaHandler::PSD_MetaHandler ( XMPFiles * _parent ) : iptcMgr(0), exifMgr(0), skipReconcile(false),imageWidth(0),imageHeight(0) +PSD_MetaHandler::PSD_MetaHandler ( XMPFiles * _parent ) : skipReconcile(false), iptcMgr(0), exifMgr(0),imageWidth(0),imageHeight(0) { this->parent = _parent; this->handlerFlags = kPSD_HandlerFlags; diff --git a/XMPFiles/source/FileHandlers/PSD_Handler.hpp b/XMPFiles/source/FileHandlers/PSD_Handler.hpp index 51dd4b9..4caec1b 100644 --- a/XMPFiles/source/FileHandlers/PSD_Handler.hpp +++ b/XMPFiles/source/FileHandlers/PSD_Handler.hpp @@ -58,7 +58,7 @@ public: private: - PSD_MetaHandler() : iptcMgr(0), exifMgr(0), skipReconcile(false) {}; // Hidden on purpose. + PSD_MetaHandler() : skipReconcile(false), iptcMgr(0), exifMgr(0) {} // Hidden on purpose. PSIR_FileWriter psirMgr; // Don't need a pointer, the PSIR part is always file-based. IPTC_Manager * iptcMgr; // Need to use pointers so we can properly select between read-only diff --git a/XMPFiles/source/FileHandlers/UCF_Handler.hpp b/XMPFiles/source/FileHandlers/UCF_Handler.hpp index 3140c23..eee46ef 100644 --- a/XMPFiles/source/FileHandlers/UCF_Handler.hpp +++ b/XMPFiles/source/FileHandlers/UCF_Handler.hpp @@ -237,8 +237,8 @@ private: //TODO intergrate in clear() void release() // avoid terminus free() since subject to a #define (mem-leak-check) { - if (filename) delete filename; - if (extraField) delete extraField; + if (filename) delete [] filename; + if (extraField) delete [] extraField; filename=0; extraField=0; } @@ -277,10 +277,10 @@ private: PutUns16LE(0x14, &fields[FileHeader::o_extractVersion] ); } - FileHeader() : filename(0),filenameLen(0),extraField(0),extraFieldLen(0) + FileHeader() : filename(0),extraField(0),filenameLen(0),extraFieldLen(0) { clear(); - }; + } // reads entire *FileHeader* structure from file (starting at current position) void read(XMP_IO* file) @@ -379,9 +379,9 @@ private: private: void release() //*** needed or can go? { - if (filename) delete filename; - if (extraField) delete extraField; - if (comment) delete comment; + if (filename) delete [] filename; + if (extraField) delete [] extraField; + if (comment) delete [] comment; filename=0; filenameLen=0; extraField=0; extraFieldLen=0; comment=0; commentLen=0; @@ -547,7 +547,7 @@ private: { //// WRITE BACK REAL 64 BIT VALUES, CREATE EXTRA FIELD /////////////// //may only wipe extra field after obtaining all Info from it - if (extraField) delete extraField; + if (extraField) delete [] extraField; extraFieldLen=0; if ( ( sizeUncompressed > 0xffffffff ) || @@ -598,7 +598,7 @@ private: void setXMPFilename() { - if (filename) delete filename; + if (filename) delete [] filename; filenameLen = xmpFilenameLen; filename = new char[xmpFilenameLen]; PutUns16LE(filenameLen, &fields[CDFileHeader::o_fileNameLength] ); @@ -630,8 +630,9 @@ private: const static XMP_Uns32 SIG = 0x06054b50; void UCFECD_Free() { - if(commentLen) delete comment; + if(commentLen) delete [] comment; commentLen = 0; + comment = 0; } public: const static XMP_Int32 o_Sig = 0; @@ -678,7 +679,7 @@ private: ~EndOfCD() { - if (comment) delete comment; + if (comment) delete [] comment; }; }; //class EndOfCD diff --git a/XMPFiles/source/FileHandlers/WAVE_Handler.cpp b/XMPFiles/source/FileHandlers/WAVE_Handler.cpp index 1695013..6f7f287 100644 --- a/XMPFiles/source/FileHandlers/WAVE_Handler.cpp +++ b/XMPFiles/source/FileHandlers/WAVE_Handler.cpp @@ -140,7 +140,7 @@ const ChunkIdentifier WAVE_MetaHandler::kRF64iXML[2] = { { kChunk_RF64, kType_WA // ================================ WAVE_MetaHandler::WAVE_MetaHandler ( XMPFiles * _parent ) - : mChunkBehavior(NULL), mChunkController(NULL), + : mChunkController(NULL), mChunkBehavior(NULL), mINFOMeta(), mBEXTMeta(), mCartMeta(), mDISPMeta(), miXMLMeta(), mXMPChunk(NULL), mINFOChunk(NULL), mBEXTChunk(NULL), mCartChunk(NULL), mDISPChunk(NULL), miXMLChunk(NULL) diff --git a/XMPFiles/source/FileHandlers/WEBP_Handler.cpp b/XMPFiles/source/FileHandlers/WEBP_Handler.cpp new file mode 100644 index 0000000..c0b1f09 --- /dev/null +++ b/XMPFiles/source/FileHandlers/WEBP_Handler.cpp @@ -0,0 +1,197 @@ +#include "public/include/XMP_Const.h" +#include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. + +#include "XMPFiles/source/FileHandlers/WEBP_Handler.hpp" + +#include "XMPFiles/source/FormatSupport/IPTC_Support.hpp" +#include "XMPFiles/source/FormatSupport/PSIR_Support.hpp" +#include "XMPFiles/source/FormatSupport/ReconcileLegacy.hpp" +#include "XMPFiles/source/FormatSupport/Reconcile_Impl.hpp" +#include "XMPFiles/source/FormatSupport/TIFF_Support.hpp" +#include "XMPFiles/source/FormatSupport/WEBP_Support.hpp" +#include "source/XIO.hpp" + +using namespace std; + +/// File format handler for WEBP. + +XMPFileHandler* WEBP_MetaHandlerCTor(XMPFiles* parent) +{ + return new WEBP_MetaHandler(parent); +} + +// Check that the file begins with "RIFF", a 4 byte length, then the chunkType +// (WEBP). +bool WEBP_CheckFormat(XMP_FileFormat format, XMP_StringPtr filePath, + XMP_IO* file, XMPFiles* parent) +{ + IgnoreParam(format); + IgnoreParam(parent); + XMP_Assert(format == kXMP_WEBPFile); + + if (file->Length() < 12) + return false; + file->Rewind(); + + XMP_Uns8 chunkID[12]; + file->ReadAll(chunkID, 12); + if (!CheckBytes(&chunkID[0], "RIFF", 4)) { + return false; + } + if (CheckBytes(&chunkID[8], "WEBP", 4) && format == kXMP_WEBPFile) { + return true; + } + return false; +} + +WEBP_MetaHandler::WEBP_MetaHandler(XMPFiles* parent) + : exifMgr(0) +{ + this->parent = parent; + this->handlerFlags = kWEBP_HandlerFlags; + this->stdCharForm = kXMP_Char8Bit; + + this->initialFileSize = 0; + this->mainChunk = 0; +} + +WEBP_MetaHandler::~WEBP_MetaHandler() +{ + if (this->mainChunk) { + delete this->mainChunk; + } + if (this->exifMgr) { + delete this->exifMgr; + } + if (this->iptcMgr) { + delete this->iptcMgr; + } + if (this->psirMgr) { + delete this->psirMgr; + } +} + +void WEBP_MetaHandler::CacheFileData() +{ + this->containsXMP = false; // assume for now + + XMP_IO* file = this->parent->ioRef; + this->initialFileSize = file->Length(); + + file->Rewind(); + + XMP_Int64 filePos = 0; + while (filePos < this->initialFileSize) { + this->mainChunk = new WEBP::Container(this); + filePos = file->Offset(); + } + + // covered before => internal error if it occurs + XMP_Validate(file->Offset() == this->initialFileSize, + "WEBP_MetaHandler::CacheFileData: unknown data at end of file", + kXMPErr_InternalFailure); +} + +void WEBP_MetaHandler::ProcessXMP() +{ + SXMPUtils::RemoveProperties(&this->xmpObj, 0, 0, kXMPUtil_DoAllProperties); + + bool readOnly = false; + bool xmpOnly = false; + bool haveExif = false; + if (this->parent) { + readOnly = + !XMP_OptionIsSet(this->parent->openFlags, kXMPFiles_OpenForUpdate); + xmpOnly = + XMP_OptionIsSet(this->parent->openFlags, kXMPFiles_OpenOnlyXMP); + } + if (!xmpOnly) { + if (readOnly) { + this->exifMgr = new TIFF_MemoryReader(); + } + else { + this->exifMgr = new TIFF_FileWriter(); + } + this->psirMgr = new PSIR_MemoryReader(); + this->iptcMgr = new IPTC_Reader(); + if (this->parent) { + exifMgr->SetErrorCallback(&this->parent->errorCallback); + } + if (this->mainChunk) { + WEBP::Chunk* exifChunk = this->mainChunk->getExifChunk(); + if (exifChunk != NULL) { + haveExif = true; + this->exifMgr->ParseMemoryStream(exifChunk->data.data() + 6, + exifChunk->data.size() - 6); + } + } + } + + if (this->containsXMP) { + this->xmpObj.ParseFromBuffer(this->xmpPacket.c_str(), + (XMP_StringLen) this->xmpPacket.size()); + } + if (haveExif) { + XMP_OptionBits options = k2XMP_FileHadExif; + if (this->containsXMP) { + options |= k2XMP_FileHadXMP; + } + TIFF_Manager& exif = *this->exifMgr; + PSIR_Manager& psir = *this->psirMgr; + IPTC_Manager& iptc = *this->iptcMgr; + ImportPhotoData(exif, iptc, psir, kDigestMatches, &this->xmpObj, + options); + // Assume that, since the file had EXIF data, some of it was mapped to + // XMP + this->containsXMP = true; + } + this->processedXMP = true; +} + +void WEBP_MetaHandler::UpdateFile(bool doSafeUpdate) +{ + XMP_Validate(this->needsUpdate, "nothing to update", + kXMPErr_InternalFailure); + + bool xmpOnly = false; + if (this->parent) { + xmpOnly = + XMP_OptionIsSet(this->parent->openFlags, kXMPFiles_OpenOnlyXMP); + } + + if (!xmpOnly && this->exifMgr) { + WEBP::Chunk* exifChunk = this->mainChunk->getExifChunk(); + if (exifChunk != NULL) { + ExportPhotoData(kXMP_TIFFFile, &this->xmpObj, this->exifMgr, 0, 0); + if (this->exifMgr->IsLegacyChanged()) { + XMP_Uns8* exifPtr; + XMP_Uns32 exifLen = + this->exifMgr->UpdateMemoryStream((void**)&exifPtr); + RawDataBlock exifData(&exifChunk->data[0], &exifChunk->data[6]); + exifData.insert(exifData.begin() + 6, &exifPtr[0], + &exifPtr[exifLen]); + exifChunk->data = exifData; + exifChunk->size = exifLen + 6; + exifChunk->needsRewrite = true; + } + } + } + + this->packetInfo.charForm = stdCharForm; + this->packetInfo.writeable = true; + this->packetInfo.offset = kXMPFiles_UnknownOffset; + this->packetInfo.length = kXMPFiles_UnknownLength; + + this->xmpObj.SerializeToBuffer(&this->xmpPacket, kXMP_OmitPacketWrapper); + + this->mainChunk->write(this); + this->needsUpdate = false; // do last for safety +} + +void WEBP_MetaHandler::WriteTempFile(XMP_IO* tempRef) +{ + IgnoreParam(tempRef); + XMP_Throw("WEBP_MetaHandler::WriteTempFile: Not supported (must go through " + "UpdateFile)", + kXMPErr_Unavailable); +} diff --git a/XMPFiles/source/FileHandlers/WEBP_Handler.hpp b/XMPFiles/source/FileHandlers/WEBP_Handler.hpp new file mode 100644 index 0000000..c5041ea --- /dev/null +++ b/XMPFiles/source/FileHandlers/WEBP_Handler.hpp @@ -0,0 +1,48 @@ +#ifndef __WEBP_Handler_hpp__ +#define __WEBP_Handler_hpp__ 1 + +#include "public/include/XMP_Const.h" +#include "public/include/XMP_Environment.h" + +#include "XMPFiles/source/FormatSupport/WEBP_Support.hpp" +#include "XMPFiles/source/FormatSupport/TIFF_Support.hpp" +#include "XMPFiles/source/FormatSupport/IPTC_Support.hpp" +#include "XMPFiles/source/FormatSupport/PSIR_Support.hpp" + +#include "source/XIO.hpp" + +// File format handler for WEBP + +extern XMPFileHandler* WEBP_MetaHandlerCTor(XMPFiles* parent); + +extern bool WEBP_CheckFormat(XMP_FileFormat format, XMP_StringPtr filePath, + XMP_IO* fileRef, XMPFiles* parent); + +static const XMP_OptionBits kWEBP_HandlerFlags = + (kXMPFiles_CanInjectXMP | kXMPFiles_CanExpand | kXMPFiles_PrefersInPlace | + kXMPFiles_AllowsOnlyXMP | kXMPFiles_ReturnsRawPacket | + kXMPFiles_CanReconcile); + +class WEBP_MetaHandler + : public XMPFileHandler { +public: + WEBP_MetaHandler(XMPFiles* parent); + ~WEBP_MetaHandler(); + + void CacheFileData(); + void ProcessXMP(); + void UpdateFile(bool doSafeUpdate); + void WriteTempFile(XMP_IO* tempRef); + + WEBP::Container* mainChunk; + WEBP::XMPChunk* xmpChunk; + XMP_Int64 initialFileSize; + TIFF_Manager* exifMgr; + // The PSIR_Manager and IPTC_Manager aren't actually used, but they need + // to be instantiated and passed to the function that reconciles EXIF and + // XMP data. + PSIR_Manager* psirMgr; + IPTC_Manager* iptcMgr; +}; + +#endif /* __WEBP_Handler_hpp__ */ diff --git a/XMPFiles/source/FormatSupport/GIF_Support.cpp b/XMPFiles/source/FormatSupport/GIF_Support.cpp new file mode 100644 index 0000000..4f2ac6c --- /dev/null +++ b/XMPFiles/source/FormatSupport/GIF_Support.cpp @@ -0,0 +1,352 @@ +// ================================================================================================= +// ADOBE SYSTEMS INCORPORATED +// Copyright 2002-2007 Adobe Systems Incorporated +// All Rights Reserved +// +// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms +// of the Adobe license agreement accompanying it. +// +// Derived from PNG_Support.cpp by Ian Jacobi +// Ported to the CS6 version by Hubert Figuiere +// ================================================================================================= + +#include "GIF_Support.hpp" +#include <string.h> + +#include "source/XIO.hpp" + +typedef std::basic_string<unsigned char> filebuffer; + +// Don't need CRC. + +namespace GIF_Support +{ + // This only really counts for extension blocks. + enum blockType { + bGraphicControl = 0xF9, + bComment = 0xFE, + bPlainText = 0x01, + bApplication = 0xFF, + // Hacky. Don't like the following, but there's no easy way. + bImage = 0x2C, + bExtension = 0x21, + bTerminator = 0x3B, + bHeader = 0x47 + }; + + // ============================================================================================= + + long OpenGIF ( XMP_IO* fileRef, BlockState & inOutBlockState ) + { + XMP_Uns64 pos = 0; + unsigned char name; + XMP_Uns32 len; + BlockData newBlock; + + pos = fileRef->Seek ( 0, kXMP_SeekFromStart ); + // header needs to be a block, mostly for our safe write. + pos = ReadHeader ( fileRef ); + if (pos < 13) + return 0; + + newBlock.pos = 0; + newBlock.len = pos; + newBlock.type = bHeader; + inOutBlockState.blocks.push_back(newBlock); + + // read first and following blocks + while ( ReadBlock ( fileRef, inOutBlockState, &name, &len, pos) ) {} + + return inOutBlockState.blocks.size(); + + } + + // ============================================================================================= + + long ReadHeader ( XMP_IO* fileRef ) + { + long bytesRead; + long headerSize; + long tableSize = 0; + long bytesPerColor = 0; + unsigned char buffer[768]; + + headerSize = 0; + bytesRead = fileRef->Read ( buffer, GIF_SIGNATURE_LEN ); + if ( bytesRead != GIF_SIGNATURE_LEN ) return 0; + if ( memcmp ( buffer, GIF_SIGNATURE_DATA, GIF_SIGNATURE_LEN) != 0 ) return 0; + headerSize += bytesRead; + bytesRead = fileRef->Read ( buffer, 3 ); + if ( bytesRead != 3 ) return 0; + if ( memcmp ( buffer, "87a", 3 ) != 0 && memcmp ( buffer, "89a", 3 ) != 0 ) return 0; + headerSize += bytesRead; + bytesRead = fileRef->Read ( buffer, 4 ); + if ( bytesRead != 4 ) return 0; + headerSize += bytesRead; + bytesRead = fileRef->Read ( buffer, 3 ); + if ( bytesRead != 3 ) return 0; + headerSize += bytesRead; + if ( buffer[0] & 0x80 ) tableSize = (1 << ((buffer[0] & 0x07) + 1)) * 3; + bytesRead = fileRef->Read ( buffer, tableSize ); + if ( bytesRead != tableSize ) return 0; + headerSize += bytesRead; + + return headerSize; + } + + // ============================================================================================= + + bool ReadBlock ( XMP_IO* fileRef, BlockState & inOutBlockState, unsigned char * blockType, XMP_Uns32 * blockLength, XMP_Uns64 & inOutPosition ) + { + try + { + XMP_Uns64 startPosition = inOutPosition; + long bytesRead; + long blockSize; + unsigned char buffer[768]; + + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + if ( buffer[0] == bImage ) + { + // Image is a special case. + long tableSize = 0; + bytesRead = fileRef->Read ( buffer, 4 ); + if ( bytesRead != 4 ) return false; + inOutPosition += 4; + bytesRead = fileRef->Read ( buffer, 4 ); + if ( bytesRead != 4 ) return false; + inOutPosition += 4; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + if ( buffer[0] & 0x80 ) tableSize = (1 << ((buffer[0] & 0x07) + 1)) * 3; + bytesRead = fileRef->Read ( buffer, tableSize ); + if ( bytesRead != tableSize ) return 0; + inOutPosition += tableSize; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + tableSize = buffer[0]; + while ( tableSize != 0x00 ) + { + bytesRead = fileRef->Read ( buffer, tableSize ); + if ( bytesRead != tableSize ) return false; + inOutPosition += tableSize; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + tableSize = buffer[0]; + } + + BlockData newBlock; + + newBlock.pos = startPosition; + newBlock.len = inOutPosition - startPosition; + newBlock.type = bImage; + + inOutBlockState.blocks.push_back ( newBlock ); + } + else if ( buffer[0] == bExtension ) + { + unsigned char type; + long tableSize = 0; + + BlockData newBlock; + + newBlock.pos = startPosition; + + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + type = buffer[0]; + newBlock.type = type; + + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + tableSize = buffer[0]; + while ( tableSize != 0x00 ) + { + bytesRead = fileRef->Read ( buffer, tableSize ); + if ( bytesRead != tableSize ) return false; + inOutPosition += tableSize; + if ( inOutPosition - startPosition == 14 && type == bApplication ) + { + // Check for XMP identifier... + CheckApplicationBlockHeader ( fileRef, inOutBlockState, newBlock, inOutPosition ); + + if ( newBlock.xmp == true ) + { + newBlock.len = inOutPosition - startPosition; + + inOutBlockState.blocks.push_back ( newBlock ); + + return true; + } + } + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + tableSize = buffer[0]; + } + + newBlock.len = inOutPosition - startPosition; + + inOutBlockState.blocks.push_back ( newBlock ); + } + else if ( buffer[0] == bTerminator ) + { + BlockData newBlock; + + newBlock.pos = startPosition; + newBlock.len = 1; + newBlock.type = buffer[0]; + + inOutBlockState.blocks.push_back ( newBlock ); + } + + } catch ( ... ) { + + return false; + + } + + return true; + + } + + // ============================================================================================= + + bool WriteXMPBlock ( XMP_IO* fileRef, XMP_Uns32 len, const char* inBuffer ) + { + bool ret = false; + unsigned long datalen = (APPLICATION_HEADER_LEN + len + MAGIC_TRAILER_LEN); + unsigned char* buffer = new unsigned char[datalen]; + + try + { + size_t pos = 0; + memcpy(&buffer[pos], APPLICATION_HEADER_DATA, APPLICATION_HEADER_LEN); + pos += APPLICATION_HEADER_LEN; + memcpy(&buffer[pos], inBuffer, len); + pos += len; + memcpy(&buffer[pos], MAGIC_TRAILER_DATA, MAGIC_TRAILER_LEN); + + fileRef->Write(buffer, datalen); + + ret = true; + } + catch ( ... ) {} + + delete [] buffer; + + return ret; + } + + // ============================================================================================= + + bool CopyBlock ( XMP_IO* sourceRef, XMP_IO* destRef, BlockData& block ) + { + try + { + sourceRef->Seek ( block.pos, kXMP_SeekFromStart ); + XIO::Copy (sourceRef, destRef, (block.len)); + + } catch ( ... ) { + + return false; + + } + + return true; + } + + // ============================================================================================= + + // Don't need CRC. + + // ============================================================================================= + + unsigned long CheckApplicationBlockHeader ( XMP_IO* fileRef, BlockState& inOutBlockState, BlockData& inOutBlockData, XMP_Uns64& inOutPosition ) + { + try + { + fileRef->Seek((inOutBlockData.pos), kXMP_SeekFromStart); + + unsigned char buffer[256]; + long bytesRead = fileRef->Read ( buffer, APPLICATION_HEADER_LEN ); + + if (bytesRead == APPLICATION_HEADER_LEN) + { + if (memcmp(buffer, APPLICATION_HEADER_DATA, APPLICATION_HEADER_LEN) == 0) + { + // We still have to go through all of the data... + long tableSize = 0; + long xmpSize; + + inOutPosition = inOutBlockData.pos + APPLICATION_HEADER_LEN; + inOutBlockState.xmpPos = inOutPosition; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return 0; + inOutPosition += 1; + tableSize = buffer[0]; + while ( tableSize != 0x00 ) + { + bytesRead = fileRef->Read ( buffer, tableSize ); + if ( bytesRead != tableSize ) return false; + inOutPosition += tableSize; + bytesRead = fileRef->Read ( buffer, 1 ); + if ( bytesRead != 1 ) return false; + inOutPosition += 1; + tableSize = buffer[0]; + } + inOutBlockState.xmpLen = inOutPosition - inOutBlockData.pos - APPLICATION_HEADER_LEN - MAGIC_TRAILER_LEN; + inOutBlockState.xmpBlock = inOutBlockData; + inOutBlockData.xmp = true; + } + } + } + catch ( ... ) {} + + return 0; + } + + bool ReadBuffer ( XMP_IO* fileRef, XMP_Uns64 & pos, XMP_Uns32 len, char * outBuffer ) + { + try + { + if ( (fileRef == 0) || (outBuffer == 0) ) return false; + + fileRef->Seek ( pos, kXMP_SeekFromStart ); + long bytesRead = fileRef->Read ( outBuffer, len ); + if ( XMP_Uns32(bytesRead) != len ) return false; + + return true; + } + catch ( ... ) {} + + return false; + } + + bool WriteBuffer ( XMP_IO* fileRef, XMP_Uns64 & pos, XMP_Uns32 len, const char * inBuffer ) + { + try + { + if ( (fileRef == 0) || (inBuffer == 0) ) return false; + + fileRef->Seek ( pos, kXMP_SeekFromStart ); + fileRef->Write( inBuffer, len ); + + return true; + } + catch ( ... ) {} + + return false; + } + +} // namespace GIF_Support diff --git a/XMPFiles/source/FormatSupport/GIF_Support.hpp b/XMPFiles/source/FormatSupport/GIF_Support.hpp new file mode 100644 index 0000000..aa81b8a --- /dev/null +++ b/XMPFiles/source/FormatSupport/GIF_Support.hpp @@ -0,0 +1,71 @@ +#ifndef __GIF_Support_hpp__ +#define __GIF_Support_hpp__ 1 + +// ================================================================================================= +// ADOBE SYSTEMS INCORPORATED +// Copyright 2002-2007 Adobe Systems Incorporated +// All Rights Reserved +// +// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms +// of the Adobe license agreement accompanying it +// +// Derived from PNG_Support.hpp by Ian Jacobi +// ================================================================================================= + +#include "XMP_Environment.h" // ! This must be the first include. + +#include "XMPFiles/source/XMPFiles_Impl.hpp" + +#define GIF_SIGNATURE_LEN 3 +#define GIF_SIGNATURE_DATA "\x47\x49\x46" + +#define APPLICATION_HEADER_LEN 14 +#define APPLICATION_HEADER_DATA "\x21\xFF\x0B\x58\x4D\x50\x20\x44\x61\x74\x61\x58\x4D\x50" + +#define MAGIC_TRAILER_LEN 258 +#define MAGIC_TRAILER_DATA "\x01\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8\xF7\xF6\xF5\xF4\xF3\xF2\xF1\xF0\xEF\xEE\xED\xEC\xEB\xEA\xE9\xE8\xE7\xE6\xE5\xE4\xE3\xE2\xE1\xE0\xDF\xDE\xDD\xDC\xDB\xDA\xD9\xD8\xD7\xD6\xD5\xD4\xD3\xD2\xD1\xD0\xCF\xCE\xCD\xCC\xCB\xCA\xC9\xC8\xC7\xC6\xC5\xC4\xC3\xC2\xC1\xC0\xBF\xBE\xBD\xBC\xBB\xBA\xB9\xB8\xB7\xB6\xB5\xB4\xB3\xB2\xB1\xB0\xAF\xAE\xAD\xAC\xAB\xAA\xA9\xA8\xA7\xA6\xA5\xA4\xA3\xA2\xA1\xA0\x9F\x9E\x9D\x9C\x9B\x9A\x99\x98\x97\x96\x95\x94\x93\x92\x91\x90\x8F\x8E\x8D\x8C\x8B\x8A\x89\x88\x87\x86\x85\x84\x83\x82\x81\x80\x7F\x7E\x7D\x7C\x7B\x7A\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70\x6F\x6E\x6D\x6C\x6B\x6A\x69\x68\x67\x66\x65\x64\x63\x62\x61\x60\x5F\x5E\x5D\x5C\x5B\x5A\x59\x58\x57\x56\x55\x54\x53\x52\x51\x50\x4F\x4E\x4D\x4C\x4B\x4A\x49\x48\x47\x46\x45\x44\x43\x42\x41\x40\x3F\x3E\x3D\x3C\x3B\x3A\x39\x38\x37\x36\x35\x34\x33\x32\x31\x30\x2F\x2E\x2D\x2C\x2B\x2A\x29\x28\x27\x26\x25\x24\x23\x22\x21\x20\x1F\x1E\x1D\x1C\x1B\x1A\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00" + +namespace GIF_Support +{ + class BlockData + { + public: + BlockData() : pos(0), len(0), type(0), xmp(false) {} + virtual ~BlockData() {} + + XMP_Uns64 pos; // file offset of block + XMP_Uns32 len; // length of block data, including extension introducer and label + char type; // name/type of block + bool xmp; // application extension block with XMP ? + }; + + typedef std::vector<BlockData> BlockVector; + typedef BlockVector::iterator BlockIterator; + + class BlockState + { + public: + BlockState() : xmpPos(0), xmpLen(0) {} + virtual ~BlockState() {} + + XMP_Uns64 xmpPos; + XMP_Uns32 xmpLen; + BlockData xmpBlock; + BlockVector blocks; /* vector of blocks */ + }; + + long OpenGIF ( XMP_IO* fileRef, BlockState& inOutBlockState ); + + long ReadHeader ( XMP_IO* fileRef ); + bool ReadBlock ( XMP_IO* fileRef, BlockState& inOutBlockState, unsigned char* blockType, XMP_Uns32* blockLength, XMP_Uns64& inOutPosition ); + bool WriteXMPBlock ( XMP_IO* fileRef, XMP_Uns32 len, const char* inBuffer ); + bool CopyBlock ( XMP_IO* sourceRef, XMP_IO* destRef, BlockData& block ); + + unsigned long CheckApplicationBlockHeader ( XMP_IO* fileRef, BlockState& inOutBlockState, BlockData& inOutBlockData, XMP_Uns64& inOutPosition ); + + bool ReadBuffer ( XMP_IO* fileRef, XMP_Uns64& pos, XMP_Uns32 len, char* outBuffer ); + bool WriteBuffer ( XMP_IO* fileRef, XMP_Uns64& pos, XMP_Uns32 len, const char* inBuffer ); + +} // namespace GIF_Support + +#endif // __GIF_Support_hpp__ diff --git a/XMPFiles/source/FormatSupport/ID3_Support.cpp b/XMPFiles/source/FormatSupport/ID3_Support.cpp index abe0923..528609c 100644 --- a/XMPFiles/source/FormatSupport/ID3_Support.cpp +++ b/XMPFiles/source/FormatSupport/ID3_Support.cpp @@ -20,6 +20,27 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) +#if !XMP_WinBuild + int stricmp ( const char * left, const char * right ) // Case insensitive ASCII compare. + { + char chL = *left; // ! Allow for 0 passes in the loop (one string is empty). + char chR = *right; // ! Return -1 for stricmp ( "a", "Z" ). + + for ( ; (*left != 0) && (*right != 0); ++left, ++right ) { + chL = *left; + chR = *right; + if ( chL == chR ) continue; + if ( ('A' <= chL) && (chL <= 'Z') ) chL |= 0x20; + if ( ('A' <= chR) && (chR <= 'Z') ) chR |= 0x20; + if ( chL != chR ) break; + } + + if ( chL == chR ) return 0; + if ( chL < chR ) return -1; + return 1; + } +#endif + namespace ID3_Support { // ================================================================================================= @@ -440,7 +461,7 @@ ID3v2Frame::ID3v2Frame ( XMP_Uns32 id ) : frameDefaults void ID3v2Frame::release() { - if ( this->content != 0 ) delete this->content; + if ( this->content != 0 ) delete [] this->content; this->content = 0; this->contentSize = 0; } diff --git a/XMPFiles/source/FormatSupport/ID3_Support.hpp b/XMPFiles/source/FormatSupport/ID3_Support.hpp index 299c27c..dda6bfc 100644 --- a/XMPFiles/source/FormatSupport/ID3_Support.hpp +++ b/XMPFiles/source/FormatSupport/ID3_Support.hpp @@ -18,24 +18,7 @@ #if XMP_WinBuild #define stricmp _stricmp #else - static int stricmp ( const char * left, const char * right ) // Case insensitive ASCII compare. - { - char chL = *left; // ! Allow for 0 passes in the loop (one string is empty). - char chR = *right; // ! Return -1 for stricmp ( "a", "Z" ). - - for ( ; (*left != 0) && (*right != 0); ++left, ++right ) { - chL = *left; - chR = *right; - if ( chL == chR ) continue; - if ( ('A' <= chL) && (chL <= 'Z') ) chL |= 0x20; - if ( ('A' <= chR) && (chR <= 'Z') ) chR |= 0x20; - if ( chL != chR ) break; - } - - if ( chL == chR ) return 0; - if ( chL < chR ) return -1; - return 1; - } + int stricmp ( const char * left, const char * right ); // Case insensitive ASCII compare. #endif // ================================================================================================= diff --git a/XMPFiles/source/FormatSupport/IFF/Chunk.cpp b/XMPFiles/source/FormatSupport/IFF/Chunk.cpp index 9e1407f..e8acc9f 100644 --- a/XMPFiles/source/FormatSupport/IFF/Chunk.cpp +++ b/XMPFiles/source/FormatSupport/IFF/Chunk.cpp @@ -15,6 +15,7 @@ #include "source/XIO.hpp" #include <cstdio> +#include <cstdlib> #include <typeinfo> using namespace IFF_RIFF; @@ -1207,7 +1208,7 @@ void Chunk::adjustSize( XMP_Int64 sizeChange ) mSize = mBufferSize; // if the difference is odd, the corrected even size has be incremented by 1 - sizeChange += abs(sizeChange % 2); + sizeChange += std::abs(sizeChange % 2); } else // mChunkMode == CHUNK_NODE/CHUNK_UNKNOWN { diff --git a/XMPFiles/source/FormatSupport/IFF/ChunkController.cpp b/XMPFiles/source/FormatSupport/IFF/ChunkController.cpp index fc7c2c6..29dec94 100644 --- a/XMPFiles/source/FormatSupport/IFF/ChunkController.cpp +++ b/XMPFiles/source/FormatSupport/IFF/ChunkController.cpp @@ -31,8 +31,8 @@ ChunkController::ChunkController( IChunkBehavior* chunkBehavior, XMP_Bool bigEnd mChunkBehavior (chunkBehavior), mFileSize (0), mRoot (NULL), - mTrailingGarbageSize (0), - mTrailingGarbageOffset (0) + mTrailingGarbageOffset (0), + mTrailingGarbageSize (0) { if (bigEndian) { diff --git a/XMPFiles/source/FormatSupport/IPTC_Support.cpp b/XMPFiles/source/FormatSupport/IPTC_Support.cpp index 3a3421c..3df7726 100644 --- a/XMPFiles/source/FormatSupport/IPTC_Support.cpp +++ b/XMPFiles/source/FormatSupport/IPTC_Support.cpp @@ -525,7 +525,7 @@ void IPTC_Writer::SetDataSet_UTF8 ( XMP_Uns8 dsNum, const void* utf8Ptr, XMP_Uns } } - XMP_Uns8 * dataPtr = (XMP_Uns8*) malloc ( dataLen ); + XMP_Uns8 * dataPtr = dataLen ? (XMP_Uns8*) malloc ( dataLen ) : NULL; if ( dataPtr == 0 ) XMP_Throw ( "Out of memory", kXMPErr_NoMemory ); memcpy ( dataPtr, tempPtr, dataLen ); // AUDIT: Safe, malloc'ed dataLen bytes above. diff --git a/XMPFiles/source/FormatSupport/Makefile.am b/XMPFiles/source/FormatSupport/Makefile.am new file mode 100644 index 0000000..8916332 --- /dev/null +++ b/XMPFiles/source/FormatSupport/Makefile.am @@ -0,0 +1,82 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +noinst_LTLIBRARIES = libformatsupport.la +noinst_HEADERS = IPTC_Support.hpp PSIR_Support.hpp\ + Reconcile_Impl.hpp RIFF_Support.hpp XMPScanner.hpp\ + ID3_Support.hpp PNG_Support.hpp QuickTime_Support.hpp\ + ReconcileLegacy.hpp TIFF_Support.hpp GIF_Support.hpp + + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions +AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(top_srcdir)/public/include/ \ + -Wall @XMPCORE_CPPFLAGS@ + +libformatsupport_la_SOURCES = \ + PackageFormat_Support.cpp PackageFormat_Support.hpp \ + PostScript_Support.cpp PostScript_Support.hpp \ + PSIR_FileWriter.cpp Reconcile_Impl.cpp \ + ReconcileTIFF.cpp TIFF_MemoryReader.cpp \ + IPTC_Support.cpp PSIR_MemoryReader.cpp ReconcileIPTC.cpp \ + RIFF.cpp RIFF.hpp ID3_Support.cpp ID3_Support.hpp\ + RIFF_Support.cpp TIFF_Support.cpp \ + ISOBaseMedia_Support.hpp ISOBaseMedia_Support.cpp \ + PNG_Support.cpp ReconcileLegacy.cpp \ + GIF_Support.cpp \ + SWF_Support.hpp SWF_Support.cpp\ + XDCAM_Support.hpp XDCAM_Support.cpp\ + TIFF_FileWriter.cpp XMPScanner.cpp \ + MOOV_Support.cpp MOOV_Support.hpp \ + QuickTime_Support.cpp \ + ASF_Support.hpp ASF_Support.cpp \ + MacScriptExtracts.h \ + TimeConversionUtils.cpp TimeConversionUtils.hpp \ + AIFF/AIFFBehavior.cpp AIFF/AIFFBehavior.h \ + AIFF/AIFFMetadata.cpp AIFF/AIFFMetadata.h \ + AIFF/AIFFReconcile.cpp AIFF/AIFFReconcile.h \ + IFF/ChunkController.cpp IFF/Chunk.cpp IFF/ChunkPath.cpp IFF/IChunkBehavior.cpp IFF/IChunkContainer.h \ + IFF/ChunkController.h IFF/Chunk.h IFF/ChunkPath.h IFF/IChunkBehavior.h IFF/IChunkData.h \ + WAVE/BEXTMetadata.cpp WAVE/CartMetadata.h WAVE/DISPMetadata.cpp WAVE/INFOMetadata.h WAVE/WAVEBehavior.cpp WAVE/WAVEReconcile.h \ + WAVE/BEXTMetadata.h WAVE/Cr8rMetadata.cpp WAVE/DISPMetadata.h WAVE/PrmLMetadata.cpp WAVE/WAVEBehavior.h \ + WAVE/CartMetadata.cpp WAVE/Cr8rMetadata.h WAVE/INFOMetadata.cpp WAVE/PrmLMetadata.h WAVE/WAVEReconcile.cpp \ + WAVE/iXMLMetadata.h WAVE/iXMLMetadata.cpp \ + P2_Support.hpp P2_Support.cpp \ + WEBP_Support.hpp WEBP_Support.cpp \ + $(NULL) + + diff --git a/XMPFiles/source/FormatSupport/P2_Support.cpp b/XMPFiles/source/FormatSupport/P2_Support.cpp index a5336d5..fc5a334 100644 --- a/XMPFiles/source/FormatSupport/P2_Support.cpp +++ b/XMPFiles/source/FormatSupport/P2_Support.cpp @@ -25,7 +25,7 @@ #include <sstream> P2_Clip::P2_Clip(const std::string & p2ClipMetadataFilePath) - try :p2XMLParser(0),p2Root(0),headContentCached(false) + try :headContentCached(false),p2XMLParser(0),p2Root(0) ,p2ClipContent(0),filePath(p2ClipMetadataFilePath) { Host_IO::FileRef hostRef = Host_IO::Open ( p2ClipMetadataFilePath.c_str(), Host_IO::openReadOnly ); diff --git a/XMPFiles/source/FormatSupport/P2_Support.hpp b/XMPFiles/source/FormatSupport/P2_Support.hpp index e16faea..8375d32 100644 --- a/XMPFiles/source/FormatSupport/P2_Support.hpp +++ b/XMPFiles/source/FormatSupport/P2_Support.hpp @@ -47,9 +47,9 @@ protected: class ClipContent { public: - ClipContent():clipId(0),scaleUnit(0), + ClipContent():clipTitle(0),clipId(0),scaleUnit(0), duration(0),OffsetInShot(0),topClipId(0),nextClipId(0), - prevClipId(0),shotId(0),clipMetadata(0),essenceList(0),clipTitle(0){} + prevClipId(0),shotId(0),clipMetadata(0),essenceList(0){} std::string* clipTitle; std::string* clipId; std::string* scaleUnit; diff --git a/XMPFiles/source/FormatSupport/PSIR_FileWriter.cpp b/XMPFiles/source/FormatSupport/PSIR_FileWriter.cpp index 5d06220..12adc58 100644 --- a/XMPFiles/source/FormatSupport/PSIR_FileWriter.cpp +++ b/XMPFiles/source/FormatSupport/PSIR_FileWriter.cpp @@ -409,7 +409,7 @@ XMP_Uns32 PSIR_FileWriter::UpdateMemoryResources ( void** dataPtr ) newLength += this->otherRsrcs[i].rsrcLength; } - XMP_Uns8* newContent = (XMP_Uns8*) malloc ( newLength ); + XMP_Uns8* newContent = newLength ? (XMP_Uns8*) malloc ( newLength ) : NULL; if ( newContent == 0 ) XMP_Throw ( "Out of memory", kXMPErr_NoMemory ); // Fill in the new image resource block. diff --git a/XMPFiles/source/FormatSupport/ReconcileTIFF.cpp b/XMPFiles/source/FormatSupport/ReconcileTIFF.cpp index f9e1165..ee58379 100644 --- a/XMPFiles/source/FormatSupport/ReconcileTIFF.cpp +++ b/XMPFiles/source/FormatSupport/ReconcileTIFF.cpp @@ -506,7 +506,7 @@ ImportSingleTIFF_ASCII ( const TIFF_Manager::TagInfo & tagInfo, if ( tagInfo.dataLen == 0 ) return; // Ignore empty tags. const char * chPtr = (const char *)tagInfo.dataPtr; - const bool hasNul = (chPtr[tagInfo.dataLen-1] == 0); + const bool hasNul = !tagInfo.dataLen || !chPtr || (chPtr[tagInfo.dataLen-1] == 0); const bool isUTF8 = ReconcileUtils::IsUTF8 ( chPtr, tagInfo.dataLen ); if ( isUTF8 && hasNul ) { diff --git a/XMPFiles/source/FormatSupport/Reconcile_Impl.cpp b/XMPFiles/source/FormatSupport/Reconcile_Impl.cpp index ca0e1a0..7ff57c2 100644 --- a/XMPFiles/source/FormatSupport/Reconcile_Impl.cpp +++ b/XMPFiles/source/FormatSupport/Reconcile_Impl.cpp @@ -21,6 +21,8 @@ #include <CoreFoundation/CoreFoundation.h> #endif +const char * ReconcileUtils::kHexDigits = "0123456789ABCDEF"; + // ================================================================================================= /// \file Reconcile_Impl.cpp /// \brief Implementation utilities for the photo metadata reconciliation support. diff --git a/XMPFiles/source/FormatSupport/Reconcile_Impl.hpp b/XMPFiles/source/FormatSupport/Reconcile_Impl.hpp index 4efcb3f..6fc357d 100644 --- a/XMPFiles/source/FormatSupport/Reconcile_Impl.hpp +++ b/XMPFiles/source/FormatSupport/Reconcile_Impl.hpp @@ -33,7 +33,7 @@ namespace ReconcileUtils { // *** These ought to be with the Unicode conversions. - static const char * kHexDigits = "0123456789ABCDEF"; + extern const char * kHexDigits; bool IsASCII ( const void * _textPtr, size_t textLen ); bool IsUTF8 ( const void * _textPtr, size_t textLen ); diff --git a/XMPFiles/source/FormatSupport/TIFF_FileWriter.cpp b/XMPFiles/source/FormatSupport/TIFF_FileWriter.cpp index 20c6012..ec92c8e 100644 --- a/XMPFiles/source/FormatSupport/TIFF_FileWriter.cpp +++ b/XMPFiles/source/FormatSupport/TIFF_FileWriter.cpp @@ -585,6 +585,7 @@ void TIFF_FileWriter::ParseMemoryStream ( const void* data, XMP_Uns32 length, bo } else { if ( length > 100*1024*1024 ) XMP_Throw ( "Outrageous length for memory-based TIFF", kXMPErr_BadTIFF ); this->memStream = (XMP_Uns8*) malloc(length); + this->ownedStream = true; if ( this->memStream == 0 ) XMP_Throw ( "Out of memory", kXMPErr_NoMemory ); memcpy ( this->memStream, data, length ); // AUDIT: Safe, malloc'ed length bytes above. this->ownedStream = true; diff --git a/XMPFiles/source/FormatSupport/TIFF_MemoryReader.cpp b/XMPFiles/source/FormatSupport/TIFF_MemoryReader.cpp index 31192c7..c1a0d44 100644 --- a/XMPFiles/source/FormatSupport/TIFF_MemoryReader.cpp +++ b/XMPFiles/source/FormatSupport/TIFF_MemoryReader.cpp @@ -96,14 +96,14 @@ void TIFF_MemoryReader::SortIFD ( TweakedIFDInfo* thisIFD ) #if ! (SUNOS_SPARC || XMP_IOS_ARM) TweakedIFDEntry temp = ifdEntries[i]; ++j; // ! So the insertion index becomes j. - memcpy ( &ifdEntries[j+1], &ifdEntries[j], 12*(i-j) ); // AUDIT: Safe, moving less than i entries to a location before i. + memmove ( &ifdEntries[j+1], &ifdEntries[j], 12*(i-j) ); // FAILED -- AUDIT: Safe, moving less than i entries to a location before i. ifdEntries[j] = temp; #else void * tempifdEntries = &ifdEntries[i]; TweakedIFDEntry temp; memcpy ( &temp, tempifdEntries, sizeof(TweakedIFDEntry) ); ++j; // ! So the insertion index becomes j. - memcpy ( &ifdEntries[j+1], &ifdEntries[j], 12*(i-j) ); // AUDIT: Safe, moving less than i entries to a location before i. + memmove ( &ifdEntries[j+1], &ifdEntries[j], 12*(i-j) ); // FAILED -- AUDIT: Safe, moving less than i entries to a location before i. tempifdEntries = &ifdEntries[j]; memcpy ( tempifdEntries, &temp, sizeof(TweakedIFDEntry) ); #endif diff --git a/XMPFiles/source/FormatSupport/TIFF_Support.cpp b/XMPFiles/source/FormatSupport/TIFF_Support.cpp index da2f9b6..08b0bc6 100644 --- a/XMPFiles/source/FormatSupport/TIFF_Support.cpp +++ b/XMPFiles/source/FormatSupport/TIFF_Support.cpp @@ -16,6 +16,10 @@ #include "source/UnicodeConversions.hpp" +static const char * kTIFF_TypeNames[] = { "ShortOrLong", "BYTE", "ASCII", "SHORT", "LONG", "RATIONAL", + "SBYTE", "UNDEFINED", "SSHORT", "SLONG", "SRATIONAL", + "FLOAT", "DOUBLE" }; + // ================================================================================================= /// \file TIFF_Support.cpp /// \brief Manager for parsing and serializing TIFF streams. @@ -29,9 +33,9 @@ static bool sFirstCTor = true; TIFF_Manager::TIFF_Manager() - : bigEndian(false), nativeEndian(false), errorCallbackPtr( NULL ), - GetUns16(0), GetUns32(0), GetFloat(0), GetDouble(0), - PutUns16(0), PutUns32(0), PutFloat(0), PutDouble(0) + : GetUns16(0), GetUns32(0), GetFloat(0), GetDouble(0), + PutUns16(0), PutUns32(0), PutFloat(0), PutDouble(0), + bigEndian(false), nativeEndian(false), errorCallbackPtr( NULL ) { if ( sFirstCTor ) { diff --git a/XMPFiles/source/FormatSupport/TIFF_Support.hpp b/XMPFiles/source/FormatSupport/TIFF_Support.hpp index 6d4860b..5ed5965 100644 --- a/XMPFiles/source/FormatSupport/TIFF_Support.hpp +++ b/XMPFiles/source/FormatSupport/TIFF_Support.hpp @@ -101,10 +101,6 @@ static const bool kTIFF_IsIntegerType[] = { 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, static const bool kTIFF_IsRationalType[] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }; static const bool kTIFF_IsFloatType[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; -static const char * kTIFF_TypeNames[] = { "ShortOrLong", "BYTE", "ASCII", "SHORT", "LONG", "RATIONAL", - "SBYTE", "UNDEFINED", "SSHORT", "SLONG", "SRATIONAL", - "FLOAT", "DOUBLE" }; - enum { // Encodings for SetTag_EncodedString. kTIFF_EncodeUndefined = 0, kTIFF_EncodeASCII = 1, diff --git a/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp b/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp index 9b52c79..a153bc7 100644 --- a/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp +++ b/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp @@ -58,8 +58,8 @@ namespace IFF_RIFF { static const char * trackFunctionTagName = "FUNCTION"; iXMLMetadata::iXMLMetadata() - : mRootNode( NULL ) - , mExpatAdapter( NULL ) + : mExpatAdapter( NULL ) + , mRootNode( NULL ) , mErrorCallback( NULL ) , mExtraSpaceSize( 1024 ) {} diff --git a/XMPFiles/source/FormatSupport/WEBP_Support.cpp b/XMPFiles/source/FormatSupport/WEBP_Support.cpp new file mode 100644 index 0000000..2b007de --- /dev/null +++ b/XMPFiles/source/FormatSupport/WEBP_Support.cpp @@ -0,0 +1,273 @@ +#include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. + +#include "public/include/XMP_Const.h" +#include "public/include/XMP_IO.hpp" + +#include "XMPFiles/source/XMPFiles_Impl.hpp" +#include "source/XIO.hpp" +#include "source/XMPFiles_IO.hpp" + +#include "XMPFiles/source/FileHandlers/WEBP_Handler.hpp" +#include "XMPFiles/source/FormatSupport/WEBP_Support.hpp" + +#include <stdexcept> // std::out_of_range +#include <vector> + +using namespace WEBP; + +namespace WEBP { + +// Constructor for reading an existing chunk +Chunk::Chunk(Container* parent, WEBP_MetaHandler* handler) +{ + this->needsRewrite = (parent) ? parent->needsRewrite : false; + this->parent = parent; + + XMP_IO* file = handler->parent->ioRef; + this->pos = file->Offset(); + + this->tag = XIO::ReadUns32_LE(file); + + this->size = XIO::ReadUns32_LE(file); + + // Make sure the size is within expected bounds. + if ((this->pos + this->size + 8) > handler->initialFileSize) { + XMP_Throw("Bad RIFF chunk size", kXMPErr_BadFileFormat); + } + + this->data.reserve((XMP_Int32) this->size); + this->data.assign((XMP_Int32) this->size, '\0'); + file->ReadAll((void*)this->data.data(), (XMP_Int32) this->size); + + // Account for padding + if (this->size & 1) { + file->Seek(1, kXMP_SeekFromCurrent); + } +} + +// Constructor for creating a new chunk +Chunk::Chunk(Container* parent, XMP_Uns32 tag) + : parent(parent), tag(tag) +{ + this->needsRewrite = true; +} + +void Chunk::write(WEBP_MetaHandler* handler) +{ + XMP_IO* file = handler->parent->ioRef; + if (this->needsRewrite) { + this->pos = file->Offset(); + XIO::WriteUns32_LE(file, this->tag); + XIO::WriteUns32_LE(file, (XMP_Uns32) this->size); + file->Write(this->data.data(), (XMP_Int32) this->size); + } + else { + file->Seek(this->pos + this->size + 8, kXMP_SeekFromStart); + } + if (this->size & 1) { + const XMP_Uns8 zero = 0; + file->Write(&zero, 1); + } +} + +Chunk::~Chunk() +{ + // Do nothing +} + +XMPChunk::XMPChunk(Container* parent) + : Chunk(parent, kChunk_XMP_) +{ + this->size = 0; +} + +XMPChunk::XMPChunk(Container* parent, WEBP_MetaHandler* handler) + : Chunk(parent, handler) +{ + handler->packetInfo.offset = this->pos + 8; + handler->packetInfo.length = (XMP_Int32) this->data.size(); + + handler->xmpPacket.reserve(handler->packetInfo.length); + handler->xmpPacket.assign(handler->packetInfo.length, '\0'); + handler->xmpPacket.insert(handler->xmpPacket.begin(), this->data.begin(), + this->data.end()); + + handler->containsXMP = true; // last, after all possible failure + + // pointer for later processing + handler->xmpChunk = this; +} + +void XMPChunk::write(WEBP_MetaHandler* handler) +{ + XMP_IO* file = handler->parent->ioRef; + this->size = handler->xmpPacket.size(); + XIO::WriteUns32_LE(file, this->tag); + XIO::WriteUns32_LE(file, (XMP_Uns32) this->size); + file->Write(handler->xmpPacket.data(), (XMP_Int32) this->size); + if (this->size & 1) { + const XMP_Uns8 zero = 0; + file->Write(&zero, 1); + } +} + +VP8XChunk::VP8XChunk(Container* parent) + : Chunk(parent, kChunk_VP8X) +{ + this->needsRewrite = true; + this->size = 10; + this->data.resize(this->size); + this->data.assign(this->size, 0); + XMP_Uns8* bitstream = + (XMP_Uns8*)parent->chunks[WEBP_CHUNK_IMAGE][0]->data.data(); + XMP_Uns32 width = ((bitstream[7] << 8) | bitstream[6]) & 0x3fff; + XMP_Uns32 height = ((bitstream[9] << 8) | bitstream[8]) & 0x3fff; + this->width(width); + this->height(height); + parent->vp8x = this; +} + +VP8XChunk::VP8XChunk(Container* parent, WEBP_MetaHandler* handler) + : Chunk(parent, handler) +{ + this->size = 10; + this->needsRewrite = true; + parent->vp8x = this; +} + +XMP_Uns32 VP8XChunk::width() +{ + return GetLE24(&this->data[4]) + 1; +} +void VP8XChunk::width(XMP_Uns32 val) +{ + PutLE24(&this->data[4], val - 1); +} +XMP_Uns32 VP8XChunk::height() +{ + return GetLE24(&this->data[7]) + 1; +} +void VP8XChunk::height(XMP_Uns32 val) +{ + PutLE24(&this->data[7], val - 1); +} +bool VP8XChunk::xmp() +{ + XMP_Uns32 flags = GetLE32(&this->data[0]); + return (bool)((flags >> XMP_FLAG_BIT) & 1); +} +void VP8XChunk::xmp(bool hasXMP) +{ + XMP_Uns32 flags = GetLE32(&this->data[0]); + flags ^= (-hasXMP ^ flags) & (1 << XMP_FLAG_BIT); + PutLE32(&this->data[0], flags); +} + +Container::Container(WEBP_MetaHandler* handler) : Chunk(NULL, handler) +{ + this->needsRewrite = false; + + XMP_IO* file = handler->parent->ioRef; + + file->Seek(12, kXMP_SeekFromStart); + + XMP_Int64 size = handler->initialFileSize; + + XMP_Uns32 peek = 0; + + while (file->Offset() < size) { + peek = XIO::PeekUns32_LE(file); + switch (peek) { + case kChunk_XMP_: + this->addChunk(new XMPChunk(this, handler)); + break; + case kChunk_VP8X: + this->addChunk(new VP8XChunk(this, handler)); + break; + default: + this->addChunk(new Chunk(this, handler)); + break; + } + } + + if (this->chunks[WEBP_CHUNK_IMAGE].size() == 0) { + XMP_Throw("File has no image bitstream", kXMPErr_BadFileFormat); + } + + if (this->chunks[WEBP_CHUNK_VP8X].size() == 0) { + // The file is either in Lossy or Lossless Simple File Format. + // For simplicity we will always convert it to the Extended File Format. + this->needsRewrite = true; + this->addChunk(new VP8XChunk(this)); + } + + if (this->chunks[WEBP_CHUNK_XMP].size() == 0) { + XMPChunk* xmpChunk = new XMPChunk(this); + this->addChunk(xmpChunk); + handler->xmpChunk = xmpChunk; + this->vp8x->xmp(true); + } +} + +Chunk* Container::getExifChunk() +{ + if (this->chunks[WEBP::WEBP_CHUNK_EXIF].size() == 0) { + return NULL; + } + return this->chunks[WEBP::WEBP_CHUNK_EXIF][0]; +} + +void Container::addChunk(Chunk* chunk) +{ + ChunkId idx; + + try { + idx = chunkMap.at(chunk->tag); + } + catch (const std::out_of_range& e) { + idx = WEBP_CHUNK_UNKNOWN; + } + this->chunks[idx].push_back(chunk); +} + +void Container::write(WEBP_MetaHandler* handler) +{ + XMP_IO* file = handler->parent->ioRef; + file->Rewind(); + XIO::WriteUns32_LE(file, this->tag); + XIO::WriteUns32_LE(file, (XMP_Uns32) this->size); + XIO::WriteUns32_LE(file, kChunk_WEBP); + + size_t i, j; + std::vector<Chunk*> chunkVect; + for (i = 0; i < WEBP_CHUNK_NIL; i++) { + chunkVect = this->chunks[i]; + for (j = 0; j < chunkVect.size(); j++) { + chunkVect.at(j)->write(handler); + } + } + XMP_Int64 lastOffset = file->Offset(); + this->size = lastOffset - 8; + file->Seek(this->pos + 4, kXMP_SeekFromStart); + XIO::WriteUns32_LE(file, (XMP_Uns32) this->size); + file->Seek(lastOffset, kXMP_SeekFromStart); + if (lastOffset < handler->initialFileSize) { + file->Truncate(lastOffset); + } +} + +Container::~Container() +{ + Chunk* chunk; + size_t i; + std::vector<Chunk*> chunkVect; + for (i = 0; i < WEBP_CHUNK_NIL; i++) { + chunkVect = this->chunks[i]; + while (!chunkVect.empty()) { + chunk = chunkVect.back(); + delete chunk; + chunkVect.pop_back(); + } + } +} +} diff --git a/XMPFiles/source/FormatSupport/WEBP_Support.hpp b/XMPFiles/source/FormatSupport/WEBP_Support.hpp new file mode 100644 index 0000000..aebe781 --- /dev/null +++ b/XMPFiles/source/FormatSupport/WEBP_Support.hpp @@ -0,0 +1,174 @@ +#ifndef __WEBP_Support_hpp__ +#define __WEBP_Support_hpp__ 1 + +#include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. + +#include "public/include/XMP_Const.h" +#include "public/include/XMP_IO.hpp" + +#include "XMPFiles/source/XMPFiles_Impl.hpp" +#include "source/Endian.h" +#include "source/XMPFiles_IO.hpp" + +#include <array> +#include <map> +#include <vector> + +// forward declaration: +class WEBP_MetaHandler; + +namespace WEBP { + +// Read 16, 24 or 32 bits stored in little-endian order. +// +// The inline functions provided in EndianUtils.hpp and XIO.hpp operate on +// pointers to XMP_Uns32, and then flip the bytes if the desired endianness +// differs from the host's. It seems to me that it is much simpler to read +// the data into XMP_Uns8 (i.e. unsigned char) arrays and just use shift +// operators (which operate on values rather than their representation +// in memory) to convert between values and the bytes read from or written to +// a file in a platform-independent way. And besides, WEBP stores dimensions +// in 24 bit LE, and converting that to and from a 32 bit pointer, having to +// account for the platform's endianness, would be a nightmare. +static inline XMP_Uns32 GetLE16(const XMP_Uns8* const data) +{ + return (XMP_Uns32)(data[0] << 0) | (data[1] << 8); +} + +static inline XMP_Uns32 GetLE24(const XMP_Uns8* const data) +{ + return GetLE16(data) | (data[2] << 16); +} + +static inline XMP_Uns32 GetLE32(const XMP_Uns8* const data) +{ + return (XMP_Uns32)GetLE16(data) | (GetLE16(data + 2) << 16); +} + +// Store 16, 24 or 32 bits in little-endian order. +static inline void PutLE16(XMP_Uns8* const data, XMP_Uns32 val) +{ + assert(val < (1 << 16)); + data[0] = (val >> 0); + data[1] = (val >> 8); +} + +static inline void PutLE24(XMP_Uns8* const buf, XMP_Uns32 val) +{ + assert(val < (1 << 24)); + PutLE16(buf, val & 0xffff); + buf[2] = (val >> 16); +} + +static inline void PutLE32(XMP_Uns8* const data, XMP_Uns32 val) +{ + PutLE16(data, (XMP_Uns32)(val & 0xffff)); + PutLE16(data + 2, (XMP_Uns32)(val >> 16)); +} + +#define WEBP_MKFOURCC(a, b, c, d) \ + ((XMP_Uns32)(a) | (b) << 8 | (c) << 16 | (d) << 24) + +// VP8X Feature Flags. +typedef enum FeatureFlagBits { + FRAGMENTS_FLAG_BIT, // Experimental, not enabled by default + ANIMATION_FLAG_BIT, + XMP_FLAG_BIT, + EXIF_FLAG_BIT, + ALPHA_FLAG_BIT, + ICCP_FLAG_BIT +} FeatureFlagBits; + +typedef enum ChunkId { + WEBP_CHUNK_VP8X, // VP8X + WEBP_CHUNK_ICCP, // ICCP + WEBP_CHUNK_ANIM, // ANIM + WEBP_CHUNK_ANMF, // ANMF + WEBP_CHUNK_FRGM, // FRGM + WEBP_CHUNK_ALPHA, // ALPH + WEBP_CHUNK_IMAGE, // VP8/VP8L + WEBP_CHUNK_EXIF, // EXIF + WEBP_CHUNK_XMP, // XMP + WEBP_CHUNK_UNKNOWN, // Other chunks. + WEBP_CHUNK_NIL +} ChunkId; + +const XMP_Uns32 kChunk_RIFF = WEBP_MKFOURCC('R', 'I', 'F', 'F'); +const XMP_Uns32 kChunk_WEBP = WEBP_MKFOURCC('W', 'E', 'B', 'P'); +const XMP_Uns32 kChunk_VP8_ = WEBP_MKFOURCC('V', 'P', '8', ' '); +const XMP_Uns32 kChunk_VP8L = WEBP_MKFOURCC('V', 'P', '8', 'L'); +const XMP_Uns32 kChunk_VP8X = WEBP_MKFOURCC('V', 'P', '8', 'X'); +const XMP_Uns32 kChunk_XMP_ = WEBP_MKFOURCC('X', 'M', 'P', ' '); +const XMP_Uns32 kChunk_ANIM = WEBP_MKFOURCC('A', 'N', 'I', 'M'); +const XMP_Uns32 kChunk_ICCP = WEBP_MKFOURCC('I', 'C', 'C', 'P'); +const XMP_Uns32 kChunk_EXIF = WEBP_MKFOURCC('E', 'X', 'I', 'F'); +const XMP_Uns32 kChunk_ANMF = WEBP_MKFOURCC('A', 'N', 'M', 'F'); +const XMP_Uns32 kChunk_FRGM = WEBP_MKFOURCC('F', 'R', 'G', 'M'); +const XMP_Uns32 kChunk_ALPH = WEBP_MKFOURCC('A', 'L', 'P', 'H'); + +static std::map<XMP_Uns32, ChunkId> chunkMap = { + { kChunk_VP8X, WEBP_CHUNK_VP8X }, { kChunk_ICCP, WEBP_CHUNK_ICCP }, + { kChunk_ANIM, WEBP_CHUNK_ANIM }, { kChunk_ANMF, WEBP_CHUNK_ANMF }, + { kChunk_FRGM, WEBP_CHUNK_FRGM }, { kChunk_ALPH, WEBP_CHUNK_ALPHA }, + { kChunk_VP8_, WEBP_CHUNK_IMAGE }, { kChunk_VP8L, WEBP_CHUNK_IMAGE }, + { kChunk_EXIF, WEBP_CHUNK_EXIF }, { kChunk_XMP_, WEBP_CHUNK_XMP } +}; + +class Container; + +class Chunk { +public: + Chunk(Container* parent, WEBP_MetaHandler* handler); + Chunk(Container* parent, XMP_Uns32 tag); + virtual ~Chunk(); + + virtual void write(WEBP_MetaHandler* handler); + + Container* parent; + XMP_Uns32 tag; + RawDataBlock data; + XMP_Int64 pos; + XMP_Int64 size; + bool needsRewrite; +}; + +class XMPChunk + : public Chunk { +public: + XMPChunk(Container* parent, WEBP_MetaHandler* handler); + XMPChunk(Container* parent); + void write(WEBP_MetaHandler* handler); +}; + +class VP8XChunk + : public Chunk { +public: + VP8XChunk(Container* parent, WEBP_MetaHandler* handler); + VP8XChunk(Container* parent); + bool xmp(); + void xmp(bool); + XMP_Uns32 width(); + XMP_Uns32 height(); + void width(XMP_Uns32); + void height(XMP_Uns32); +}; + +typedef std::array<std::vector<Chunk*>, WEBP_CHUNK_NIL> Chunks; + +class Container + : public Chunk { +public: + Container(WEBP_MetaHandler* handler); + ~Container(); + + void write(WEBP_MetaHandler* handler); + void addChunk(Chunk*); + Chunk* getExifChunk(); + + Chunks chunks; + VP8XChunk* vp8x; +}; + +} // namespace WEBP + +#endif // __WEBP_Support_hpp__ diff --git a/XMPFiles/source/FormatSupport/XMPScanner.cpp b/XMPFiles/source/FormatSupport/XMPScanner.cpp index 14552de..22726d0 100644 --- a/XMPFiles/source/FormatSupport/XMPScanner.cpp +++ b/XMPFiles/source/FormatSupport/XMPScanner.cpp @@ -989,7 +989,7 @@ XMPScanner::InternalSnip::InternalSnip ( XMP_Int64 offset, XMP_Int64 length ) XMPScanner::InternalSnip::InternalSnip ( const InternalSnip & rhs ) : fInfo ( rhs.fInfo ), - fMachine ( NULL ) + fMachine () { assert ( rhs.fMachine.get() == NULL ); // Don't copy a snip with a machine. @@ -1257,13 +1257,13 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 } else { // *** snipPos->fMachine.reset ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); VC++ lacks reset #if 0 - snipPos->fMachine = auto_ptr<PacketMachine> ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); + snipPos->fMachine = unique_ptr<PacketMachine> ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. PacketMachine * pm = new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ); - auto_ptr<PacketMachine> ap ( pm ); - snipPos->fMachine = ap; + unique_ptr<PacketMachine> ap ( pm ); + snipPos->fMachine = std::move(ap); } #endif thisMachine = snipPos->fMachine.get(); @@ -1282,12 +1282,12 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 snipPos->fInfo.fState = eRawInputSnip; #if 0 - snipPos->fMachine = auto_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset + snipPos->fMachine = unique_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. - auto_ptr<PacketMachine> ap ( 0 ); - snipPos->fMachine = ap; + unique_ptr<PacketMachine> ap; + snipPos->fMachine = std::move(ap); } #endif bufferDone = true; @@ -1375,12 +1375,12 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 // This packet ends exactly at the end of the current snip. #if 0 - snipPos->fMachine = auto_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset + snipPos->fMachine = unique_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. - auto_ptr<PacketMachine> ap ( 0 ); - snipPos->fMachine = ap; + unique_ptr<PacketMachine> ap; + snipPos->fMachine = std::move(ap); } #endif bufferDone = true; @@ -1392,7 +1392,7 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 InternalSnipIterator tailPos = NextSnip ( snipPos ); - tailPos->fMachine = snipPos->fMachine; // auto_ptr assignment - taking ownership + tailPos->fMachine = std::move(snipPos->fMachine); // unique_ptr assignment - taking ownership thisMachine->ResetMachine (); snipPos = tailPos; diff --git a/XMPFiles/source/FormatSupport/XMPScanner.hpp b/XMPFiles/source/FormatSupport/XMPScanner.hpp index 1648692..841f2ec 100644 --- a/XMPFiles/source/FormatSupport/XMPScanner.hpp +++ b/XMPFiles/source/FormatSupport/XMPScanner.hpp @@ -156,7 +156,7 @@ private: // XMPScanner public: SnipInfo fInfo; // The public info about this snip. - std::auto_ptr<PacketMachine> fMachine; // The state machine for "active" snips. + std::unique_ptr<PacketMachine> fMachine; // The state machine for "active" snips. InternalSnip ( XMP_Int64 offset, XMP_Int64 length ); InternalSnip ( const InternalSnip & ); diff --git a/XMPFiles/source/HandlerRegistry.cpp b/XMPFiles/source/HandlerRegistry.cpp index cc58d34..60547fc 100644 --- a/XMPFiles/source/HandlerRegistry.cpp +++ b/XMPFiles/source/HandlerRegistry.cpp @@ -40,6 +40,7 @@ #include "XMPFiles/source/FileHandlers/XDCAMEX_Handler.hpp" #include "XMPFiles/source/FileHandlers/XDCAMFAM_Handler.hpp" #include "XMPFiles/source/FileHandlers/XDCAMSAM_Handler.hpp" + #include "XMPFiles/source/FileHandlers/WEBP_Handler.hpp" #endif #if EnableMiscHandlers @@ -144,6 +145,7 @@ void HandlerRegistry::initialize() allOK &= this->registerNormalHandler ( kXMP_MP3File, kMP3_HandlerFlags, MP3_CheckFormat, MP3_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_WAVFile, kWAVE_HandlerFlags, WAVE_CheckFormat, WAVE_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_AVIFile, kRIFF_HandlerFlags, RIFF_CheckFormat, RIFF_MetaHandlerCTor ); + allOK &= this->registerNormalHandler ( kXMP_WEBPFile, kWEBP_HandlerFlags, WEBP_CheckFormat, WEBP_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_SWFFile, kSWF_HandlerFlags, SWF_CheckFormat, SWF_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_MPEG4File, kMPEG4_HandlerFlags, MPEG4_CheckFormat, MPEG4_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_MOVFile, kMPEG4_HandlerFlags, MPEG4_CheckFormat, MPEG4_MetaHandlerCTor ); // ! Yes, MPEG-4 includes MOV. @@ -155,6 +157,7 @@ void HandlerRegistry::initialize() allOK &= this->registerNormalHandler ( kXMP_InDesignFile, kInDesign_HandlerFlags, InDesign_CheckFormat, InDesign_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_PNGFile, kPNG_HandlerFlags, PNG_CheckFormat, PNG_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_UCFFile, kUCF_HandlerFlags, UCF_CheckFormat, UCF_MetaHandlerCTor ); + allOK &= this->registerNormalHandler ( kXMP_GIFFile, kGIF_HandlerFlags, GIF_CheckFormat, GIF_MetaHandlerCTor ); // ! EPS and PostScript have the same handler, EPS is a proper subset of PostScript. allOK &= this->registerNormalHandler ( kXMP_EPSFile, kPostScript_HandlerFlags, PostScript_CheckFormat, PostScript_MetaHandlerCTor ); allOK &= this->registerNormalHandler ( kXMP_PostScriptFile, kPostScript_HandlerFlags, PostScript_CheckFormat, PostScript_MetaHandlerCTor ); diff --git a/XMPFiles/source/Makefile.am b/XMPFiles/source/Makefile.am new file mode 100644 index 0000000..6d1a1d3 --- /dev/null +++ b/XMPFiles/source/Makefile.am @@ -0,0 +1,57 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +SUBDIRS = FileHandlers FormatSupport NativeMetadataSupport PluginHandler + +noinst_LTLIBRARIES = libXMPFiles.la + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions -fno-strict-aliasing +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/public/include \ + -I$(top_srcdir)/XMPFilesPlugins/api/source/ \ + -Wall @XMPCORE_CPPFLAGS@ + +noinst_HEADERS = XMPFiles.hpp XMPFiles_Impl.hpp HandlerRegistry.h + +libXMPFiles_la_SOURCES = WXMPFiles.cpp XMPFiles.cpp \ + XMPFiles_Impl.cpp HandlerRegistry.cpp + + +libXMPFiles_la_LIBADD = ./FileHandlers/libxmpfilehandlers.la \ + ./FormatSupport/libformatsupport.la \ + ./PluginHandler/libpluginhandler.la \ + ./NativeMetadataSupport/libnativemetadata.la +#libXMPFiles_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@ diff --git a/XMPFiles/source/NativeMetadataSupport/Makefile.am b/XMPFiles/source/NativeMetadataSupport/Makefile.am new file mode 100644 index 0000000..2606720 --- /dev/null +++ b/XMPFiles/source/NativeMetadataSupport/Makefile.am @@ -0,0 +1,51 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +noinst_LTLIBRARIES = libnativemetadata.la + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions -fno-strict-aliasing +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/public/include \ + -I$(top_srcdir)/XMPFilesPlugins/api/source/ \ + -Wall @XMPCORE_CPPFLAGS@ + +libnativemetadata_la_SOURCES = \ + IMetadata.cpp IMetadata.h \ + IReconcile.cpp IReconcile.h \ + MetadataSet.cpp MetadataSet.h \ + ValueObject.h \ + $(NULL) diff --git a/XMPFiles/source/NativeMetadataSupport/ValueObject.h b/XMPFiles/source/NativeMetadataSupport/ValueObject.h index cd4b6d9..4ef2f50 100644 --- a/XMPFiles/source/NativeMetadataSupport/ValueObject.h +++ b/XMPFiles/source/NativeMetadataSupport/ValueObject.h @@ -10,6 +10,8 @@ #ifndef _ValueObject_h_ #define _ValueObject_h_ +#include <string.h> + #include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. #include "public/include/XMP_Const.h" diff --git a/XMPFiles/source/PluginHandler/FileHandler.h b/XMPFiles/source/PluginHandler/FileHandler.h index ca43ced..96c344b 100644 --- a/XMPFiles/source/PluginHandler/FileHandler.h +++ b/XMPFiles/source/PluginHandler/FileHandler.h @@ -51,7 +51,7 @@ class FileHandler public: FileHandler(std::string & uid, XMP_OptionBits handlerFlags, FileHandlerType type, ModuleSharedPtr module): - mVersion(0), mUID(uid), mHandlerFlags(handlerFlags), mOverwrite(false), mType(type), mModule(module),mSerializeOption(0) {} + mVersion(0), mUID(uid), mHandlerFlags(handlerFlags), mSerializeOption(0), mOverwrite(false), mType(type), mModule(module) {} virtual ~FileHandler(){} diff --git a/XMPFiles/source/PluginHandler/Makefile.am b/XMPFiles/source/PluginHandler/Makefile.am new file mode 100644 index 0000000..0c0a6f6 --- /dev/null +++ b/XMPFiles/source/PluginHandler/Makefile.am @@ -0,0 +1,61 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +noinst_LTLIBRARIES = libpluginhandler.la + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions -fno-strict-aliasing +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/public/include \ + -I$(top_srcdir)/XMPFilesPlugins/api/source/ \ + -Wall @XMPCORE_CPPFLAGS@ + +if MAC_ENV +PLATFORM_UTILS=OS_Utils_Mac.cpp +else +PLATFORM_UTILS=OS_Utils_Linux.cpp +endif + +libpluginhandler_la_SOURCES = FileHandler.h \ + FileHandlerInstance.cpp FileHandlerInstance.h \ + HostAPIImpl.cpp \ + Module.cpp Module.h ModuleUtils.h \ + PluginManager.cpp PluginManager.h \ + XMPAtoms.cpp XMPAtoms.h \ + $(PLATFORM_UTILS) \ + $(NULL) + +EXTRA_DIST=OS_Utils_Linux.cpp OS_Utils_WIN.cpp OS_Utils_Mac.cpp diff --git a/XMPFiles/source/PluginHandler/XMPAtoms.h b/XMPFiles/source/PluginHandler/XMPAtoms.h index 4cacef0..3daad38 100644 --- a/XMPFiles/source/PluginHandler/XMPAtoms.h +++ b/XMPFiles/source/PluginHandler/XMPAtoms.h @@ -100,7 +100,7 @@ class ResourceParser { public: ResourceParser(ModuleSharedPtr module) - : mModule(module), mFlags(0), mSerializeOption(0), mType(0), mVersion(0.0), mOverwriteHandler(false) {} + : mModule(module), mType(0), mFlags(0), mSerializeOption(0), mVersion(0.0), mOverwriteHandler(false) {} /** * Initialize the XMPAtoms which will be used in parsing resource files. diff --git a/XMPFiles/source/XMPFiles_Impl.cpp b/XMPFiles/source/XMPFiles_Impl.cpp index 5914560..febb790 100644 --- a/XMPFiles/source/XMPFiles_Impl.cpp +++ b/XMPFiles/source/XMPFiles_Impl.cpp @@ -92,6 +92,7 @@ const FileExtMapping kFileExtMap[] = { "avi", kXMP_AVIFile }, { "cin", kXMP_CINFile }, { "wav", kXMP_WAVFile }, + { "webp", kXMP_WEBPFile }, { "mp3", kXMP_MP3File }, { "mp4", kXMP_MPEG4File }, { "m4v", kXMP_MPEG4File }, @@ -517,4 +518,4 @@ void XMPFileHandler::NotifyClient(GenericErrorCallback * errCBptr, XMP_ErrorSeve throw error; } } -// =================================================================================================
\ No newline at end of file +// ================================================================================================= diff --git a/XMPFiles/source/XMPFiles_Impl.hpp b/XMPFiles/source/XMPFiles_Impl.hpp index b70d88c..f8bc5ac 100644 --- a/XMPFiles/source/XMPFiles_Impl.hpp +++ b/XMPFiles/source/XMPFiles_Impl.hpp @@ -149,11 +149,11 @@ extern XMP_StringPtr voidStringPtr; extern XMP_StringLen voidStringLen; extern XMP_OptionBits voidOptionBits; -static const XMP_Uns8 * kUTF8_PacketStart = (const XMP_Uns8 *) "<?xpacket begin="; -static const XMP_Uns8 * kUTF8_PacketID = (const XMP_Uns8 *) "W5M0MpCehiHzreSzNTczkc9d"; +#define kUTF8_PacketStart (const XMP_Uns8 *)"<?xpacket begin=" +#define kUTF8_PacketID (const XMP_Uns8 *)"W5M0MpCehiHzreSzNTczkc9d" static const size_t kUTF8_PacketHeaderLen = 51; // ! strlen ( "<?xpacket begin='xxx' id='W5M0MpCehiHzreSzNTczkc9d'" ) -static const XMP_Uns8 * kUTF8_PacketTrailer = (const XMP_Uns8 *) "<?xpacket end=\"w\"?>"; +#define kUTF8_PacketTrailer (const XMP_Uns8 *)"<?xpacket end=\"w\"?>" static const size_t kUTF8_PacketTrailerLen = 19; // ! strlen ( kUTF8_PacketTrailer ) struct FileExtMapping { diff --git a/XMPFilesPlugins/Makefile.am b/XMPFilesPlugins/Makefile.am new file mode 100644 index 0000000..24fd3a6 --- /dev/null +++ b/XMPFilesPlugins/Makefile.am @@ -0,0 +1,4 @@ + + + +SUBDIRS=api PDF_Handler diff --git a/XMPFilesPlugins/PDF_Handler/Makefile.am b/XMPFilesPlugins/PDF_Handler/Makefile.am new file mode 100644 index 0000000..310146c --- /dev/null +++ b/XMPFilesPlugins/PDF_Handler/Makefile.am @@ -0,0 +1,3 @@ + + +EXTRA_DIST = README.exempi diff --git a/XMPFilesPlugins/PDF_Handler/README.exempi b/XMPFilesPlugins/PDF_Handler/README.exempi new file mode 100644 index 0000000..f5fceac --- /dev/null +++ b/XMPFilesPlugins/PDF_Handler/README.exempi @@ -0,0 +1,6 @@ +This directory usually contains a proprietary PDF Handler +written by Adobe. There is no source code. + +It has been omitted from the Exempi tarball. + +Check the source code repository.
\ No newline at end of file diff --git a/XMPFilesPlugins/api/Makefile.am b/XMPFilesPlugins/api/Makefile.am new file mode 100644 index 0000000..57fb028 --- /dev/null +++ b/XMPFilesPlugins/api/Makefile.am @@ -0,0 +1,2 @@ + +SUBDIRS=source diff --git a/XMPFilesPlugins/api/source/Makefile.am b/XMPFilesPlugins/api/source/Makefile.am new file mode 100644 index 0000000..ece8912 --- /dev/null +++ b/XMPFilesPlugins/api/source/Makefile.am @@ -0,0 +1,13 @@ + + +EXTRA_DIST = HostAPIAccess.cpp \ + HostAPIAccess.h\ + HostAPI.h\ + PluginAPIImpl.cpp\ + PluginBase.cpp\ + PluginBase.h\ + PluginConst.h\ + PluginHandler.h\ + PluginRegistry.cpp\ + PluginRegistry.h\ + $(NULL) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..9bb10bc --- /dev/null +++ b/autogen.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# part of libopenraw +# + + +topsrcdir=`dirname $0` +if test x$topsrcdir = x ; then + topsrcdir=. +fi + +builddir=`pwd` + +AUTOCONF=autoconf + +LIBTOOL=$(command -v glibtool) +if [ -z "$LIBTOOL" ]; then + LIBTOOL=libtool +fi + +LIBTOOLIZE=$(command -v glibtoolize) +if [ -z "$LIBTOOLIZE" ]; then + LIBTOOLIZE=libtoolize +fi + + +AUTOMAKE=automake +ACLOCAL=aclocal + +cd $topsrcdir + +rm -f autogen.err +$LIBTOOLIZE --force +$ACLOCAL -I m4 >> autogen.err 2>&1 + +#autoheader --force +$AUTOMAKE --add-missing --copy --foreign +$AUTOCONF + +cd $builddir + + +if [ "$NOCONFIGURE" = "" ]; then + if test -z "$*"; then + echo "I am going to run ./configure with --enable-maintainer-mode" + echo "If you wish to pass any to it, please specify them on " + echo "the $0 command line." + fi + echo "Running configure..." + $topsrcdir/configure --enable-maintainer-mode "$@" +fi diff --git a/build/GNUmakefile.am b/build/GNUmakefile.am new file mode 100644 index 0000000..1cdb0f1 --- /dev/null +++ b/build/GNUmakefile.am @@ -0,0 +1,37 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +noinst_HEADERS=XMP_BuildInfo.h
\ No newline at end of file diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..6f67259 --- /dev/null +++ b/configure.ac @@ -0,0 +1,268 @@ +dnl Copyright (C) 2007-2010 Hubert Figuiere +dnl Small portions are: +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +AC_PREREQ(2.50) +AC_INIT(exempi,2.4.0) +AM_INIT_AUTOMAKE([foreign dist-bzip2 subdir-objects]) +AM_MAINTAINER_MODE +m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])]) +AM_SILENT_RULES([yes]) + +dnl --------------------------------------------------------------------------- +dnl Advanced information about versioning: +dnl * "Writing shared libraries" by Mike Hearn +dnl http://plan99.net/~mike/writing-shared-libraries.html +dnl * libtool.info chapter "Versioning" +dnl * libtool.info chapter "Updating library version information" +dnl --------------------------------------------------------------------------- +dnl Versioning: +dnl - CURRENT (Major): Increment if the interface has changes. AGE is always +dnl *changed* at the same time. +dnl - AGE (Micro): Increment if any interfaces have been added; set to 0 +dnl if any interfaces have been removed. Removal has +dnl precedence over adding, so set to 0 if both happened. +dnl It denotes upward compatibility. +dnl - REVISION (Minor): Increment any time the source changes; set to +dnl 0 if you incremented CURRENT. +dnl +dnl To summarize. Any interface *change* increment CURRENT. If that interface +dnl change does not break upward compatibility (ie it is an addition), +dnl increment AGE, Otherwise AGE is reset to 0. If CURRENT has changed, +dnl REVISION is set to 0, otherwise REVISION is incremented. +dnl --------------------------------------------------------------------------- +dnl 1.99.0 is the revision 2 0 0 +dnl 1.99.1 is the revision 3 1 0 +dnl 1.99.2 is the revision 4 2 0 +dnl 1.99.3 is the revision 5 3 0 +dnl 1.99.4 is the revision 6 4 0 +dnl ABI breakage reset major to 3 +dnl 1.99.5 is the revision 3.0.0 +dnl 1.99.6 is the revision 3.1.0 WHICH IS WRONG!!! +dnl 1.99.7 is the revision 4.1.0 +dnl 1.99.8 is the revision 4.1.1 +dnl 1.99.9 is the revision 4.1.1 (no library change have been made) +dnl 2.0.0 is the revision 4.1.2 +dnl 2.0.1 is the revision 4.1.3 +dnl 2.0.2 is the revision 4.1.4 +dnl 2.1.0 is the revision 5.2.0 +dnl 2.1.1 is the revision 5.2.1 +dnl 2.2.0 is the revision 5.2.2 -- no public API change +dnl 2.2.1 is the revision 5.2.3 -- no public API change +dnl 2.2.2 is the revision 5.2.4 -- no public API change +dnl 2.2.3 is the revision 5.2.5 -- no public API change +dnl 2.3.0 is the revision 6.3.0 +dnl 2.4.0 is the revision 7.4.0 +AC_SUBST([EXEMPI_REVISION], [0]) +AC_SUBST([EXEMPI_AGE], [4]) +AC_SUBST([EXEMPI_CURRENT], [7]) +AC_SUBST([EXEMPI_CURRENT_MIN], + [`expr $EXEMPI_CURRENT - $EXEMPI_AGE`]) +AC_SUBST([EXEMPI_VERSION_INFO], + [$EXEMPI_CURRENT:$EXEMPI_REVISION:$EXEMPI_AGE]) + +dnl the major version. used for package names, etc +EXEMPI_MAJOR_VERSION=2.0 +AC_SUBST(EXEMPI_MAJOR_VERSION) + +dnl the path where includes are installed +EXEMPI_INCLUDE_BASE=exempi-$EXEMPI_MAJOR_VERSION +AC_SUBST(EXEMPI_INCLUDE_BASE) + +dnl -------------------------------------------------------------------- +dnl guess directory to install *.pc into +dnl -------------------------------------------------------------------- +pkgconfigdir='${libdir}/pkgconfig' +AC_SUBST(pkgconfigdir) + +AC_CONFIG_MACRO_DIR([m4]) + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_LIBTOOL +AX_CXX_COMPILE_STDCXX_11(noext,mandatory) + +AC_C_BIGENDIAN +AC_DEFINE(CHECKED_ENDIANNESS) +AC_LANG(C++) + +AC_ARG_WITH(darwinports,[ --with-darwinports add /opt/local/... to CPP/LDFLAGS (Mac OSX)],[ + if test "x$withval" != "xno"; then + CPPFLAGS="$CPPFLAGS -I/opt/local/include" + LDFLAGS="$LDFLAGS -L/opt/local/lib" + CC=g++ + fi +]) +AC_ARG_WITH(fink,[ --with-fink add /sw/... to CPP/LDFLAGS (Mac OSX)],[ + if test "x$withval" != "xno"; then + CPPFLAGS="$CPPFLAGS -I/sw/include" + LDFLAGS="$LDFLAGS -L/sw/lib" + CC=g++ + fi +]) + + +AC_CHECK_HEADER(expat.h, , + AC_MSG_ERROR([expat headers missing])) +AC_CHECK_HEADER(iconv.h, , + AC_MSG_ERROR([iconv headers missing])) +AC_CHECK_HEADER(zlib.h, , + AC_MSG_ERROR([zlib headers missing])) + +dnl Blatently copied from iconv.m4 to remove the crack about libtool +dnl But check for constness of the iconv parameters. +AC_MSG_CHECKING([for iconv declaration]) +AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` +AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) +AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) +dnl end iconv checks + + +dnl TLS. +AX_TLS +if test "$ac_cv_tls" != "none"; then + AC_DEFINE(HAVE_NATIVE_TLS, [1], [Define if compiler has native TLS.]) +fi +dnl end TLS + +dnl check LD Flags +dnl we need a valid symfile. Make one. +cat >> _ac_foo.sym << _ACEOF +foo +_ACEOF +AX_LD_CHECK_FLAG([-Wl,--retain-symbols-file=_ac_foo.sym],[],[],[ +dnl success +cv_support_symfile=yes +],[ +dnl fail +cv_support_symfile=no +]) +rm -f _ac_foo.sym +AM_CONDITIONAL(HAVE_SYMBOLS_FILE, test x$cv_support_symfile = "xyes") + + +AC_ARG_ENABLE(unittest, + AC_HELP_STRING([--enable-unittest=yes|no], + [enable the unittest. requires boost (default is yes)]), + ENABLE_UNITTEST=$enableval, + ENABLE_UNITTEST=yes) +if test x$ENABLE_UNITTEST = xyes ; then + BOOST_REQUIRE([1.48.0]) + BOOST_TEST([mt-s]) +else + ENABLE_UNITTEST=no +fi + + +case $build_vendor in + apple) + EXEMPI_PLATFORM_DEF=MAC_ENV + LDFLAGS="$LDFLAGS -framework CoreServices -stdlib=libc++" + CPPFLAGS="$CPPFLAGS -std=c++11 -stdlib=libc++" + ;; + *) + EXEMPI_PLATFORM_DEF=UNIX_ENV + ;; +esac + +AC_SUBST(EXEMPI_PLATFORM_DEF) +AM_CONDITIONAL(MAC_ENV, test x$EXEMPI_PLATFORM_DEF = xMAC_ENV) +AM_CONDITIONAL(UNIX_ENV, test x$EXEMPI_PLATFORM_DEF = xUNIX_ENV) + +AM_CONDITIONAL(WITH_UNIT_TEST, test x$ENABLE_UNITTEST = xyes) + +dnl Check for valgrind (optional) for make check. +dnl AC_CHECK_PROG(VALGRIND, valgrind, valgrind) +AC_CHECK_HEADERS(valgrind/memcheck.h) +if test "$VALGRIND" = ""; then + AC_MSG_WARN([Valgrind is missing. checks will run without]) +fi +if test "$VALGRIND" != ""; then +dnl due to stupid m4 I had to double the [ and ] in the regexp + vg_ver=`valgrind --version | sed -e 's/.*-\([[0-9]]\)\.[[0-9]].*/\1/'` + VALGRIND="$VALGRIND --tool=memcheck --leak-check=yes --num-callers=10 --error-exitcode=100" + if test "$vg_ver" != "3" ; then + VALGRIND="$VALGRIND --logfile-fd=-1" + fi +fi +AC_SUBST(VALGRIND) + +AC_ARG_ENABLE(asan,[ --enable-asan Turn on address sanitizer],[ + AX_APPEND_COMPILE_FLAGS([-fsanitize=address -fno-omit-frame-pointer]) +] +, +[ + +]) + +XMPCORE_CPPFLAGS="-D$EXEMPI_PLATFORM_DEF=1 -DXMP_IMPL=1 -DXMP_ClientBuild=0 \ + -DXMP_StaticBuild=1 -DBanAllEntityUsage \ + -D_FILE_OFFSET_BITS=64 -DHAVE_EXPAT_CONFIG_H=1 -DXML_STATIC=1 \ + -DDISABLE_QUICKTIME" +AC_SUBST(XMPCORE_CPPFLAGS) + +AC_OUTPUT([ +Makefile +third-party/Makefile +third-party/zuid/interfaces/Makefile +third-party/zlib/Makefile +third-party/expat/Makefile +source/Makefile +XMPCore/Makefile +XMPCore/source/Makefile +XMPFiles/Makefile +XMPFiles/source/Makefile +XMPFiles/source/FileHandlers/Makefile +XMPFiles/source/FormatSupport/Makefile +XMPFiles/source/NativeMetadataSupport/Makefile +XMPFiles/source/PluginHandler/Makefile +XMPFilesPlugins/Makefile +XMPFilesPlugins/api/Makefile +XMPFilesPlugins/api/source/Makefile +XMPFilesPlugins/PDF_Handler/Makefile +samples/Makefile +samples/source/Makefile +samples/testfiles/Makefile +build/GNUmakefile +public/Makefile +public/include/Makefile +public/include/client-glue/Makefile +exempi/Makefile +exempi/doc/Makefile +exempi/doc/Doxyfile +exempi/tests/Makefile +exempi/exempi-2.0.pc +]) + + +echo " +Defines: + + EXEMPI_PLATFORM_DEF = $EXEMPI_PLATFORM_DEF + CPPFLAGS = $CPPFLAGS + LDFLAGS = $LDFLAGS + Thread Local Storage = $ac_cv_tls + Run unit test = $ENABLE_UNITTEST +" diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..4f68d4d --- /dev/null +++ b/debian/changelog @@ -0,0 +1,12 @@ +exempi (1.99.2+git20070625) unstable; urgency=low + + * New upstream version + + -- Hubert Figuiere <hub@figuiere.net> Wed, 6 Jun 2007 22:15:52 -0400 + +exempi (1.99.0+git20070526) unstable; urgency=low + + * Initial release + + -- Hubert Figuiere <hub@figuiere.net> Sat, 26 May 2007 16:35:34 -0400 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..d0bf923 --- /dev/null +++ b/debian/control @@ -0,0 +1,32 @@ +Source: exempi +Section: libs +Priority: extra +Maintainer: Hubert Figuiere <hub@figuiere.net> +Build-Depends: debhelper (>> 5.0.0), cdbs (>= 0.4.30), libboost-dev (>= 1.33), libexpat1-dev +Standards-Version: 3.7.2 + + +Package: libexempi-dev +Section: libdevel +Depends: libexempi3 (= ${Source-Version}) +Architecture: any +Description: A library to parse XMP metadata (Development files) + Exempi is a library to parse XMP metadata as defined by the + specification. + + +Package: libexempi3-dbg +Architecture: any +Depends: libexempi3 (= ${Source-Version}) +Description: A library to parse XMP metadata (Debug files) + Exempi is a library to parse XMP metadata as defined by the + specification. + + +Package: libexempi3 +Section: libs +Architecture: any +Depends: ${shlibs:Depends} +Description: A library to parse XMP metadata (Library) + Exempi is a library to parse XMP metadata as defined by the + specification. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..4c8eaba --- /dev/null +++ b/debian/copyright @@ -0,0 +1,36 @@ +This package was debianized by Hubert Figuiere <hub@figuiere.net> on +Mon Mar 12 22:22:41 EDT 2007 + +It was downloaded from Git + +Copyright: + Copyright (C) 2007 Hubert Figuiere <hub@figuiere.net> + Copyright (c) 1999 - 2007, Adobe Systems Incorporated + +License: + +Copyright (c) 1999 - 2007, Adobe Systems Incorporated +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +* Neither the name of Adobe Systems Incorporated, nor the names of its contributors may be used to endorse or promote products derived from this software wit +hout specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/debian/libexempi-dev.install b/debian/libexempi-dev.install new file mode 100644 index 0000000..c7dd91c --- /dev/null +++ b/debian/libexempi-dev.install @@ -0,0 +1,3 @@ +usr/include +usr/lib/pkgconfig +usr/lib/libexempi.{so,la,a}
\ No newline at end of file diff --git a/debian/libexempi2.install b/debian/libexempi2.install new file mode 100644 index 0000000..5f36ae7 --- /dev/null +++ b/debian/libexempi2.install @@ -0,0 +1 @@ +usr/lib/libexempi.so.2* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..726c479 --- /dev/null +++ b/debian/rules @@ -0,0 +1,7 @@ +#!/usr/bin/make -f + +DEB_DH_INSTALL_SOURCEDIR=debian/tmp + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/autotools.mk + diff --git a/exempi/Makefile.am b/exempi/Makefile.am new file mode 100644 index 0000000..4a65f91 --- /dev/null +++ b/exempi/Makefile.am @@ -0,0 +1,79 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +SUBDIRS = tests +DIST_SUBDIRS = tests doc + +exempidir = $(includedir)/@EXEMPI_INCLUDE_BASE@/exempi +exempi_HEADERS = xmp.h xmpconsts.h xmperrors.h xmp++.hpp + +bin_PROGRAMS = exempi + +exempi_SOURCES = main.cpp +exempi_CPPFLAGS = -I$(srcdir)/.. +exempi_LDADD = libexempi.la + +AM_CPPFLAGS = -I$(top_srcdir)/public/include -I$(top_srcdir)/XMPCore/source \ + -I$(top_srcdir)/build/ -I$(top_srcdir) \ + -I$(top_srcdir)/source/common/ \ + -Wall -D@EXEMPI_PLATFORM_DEF@=1 + +lib_LTLIBRARIES = libexempi.la + +pkgconfig_DATA = exempi-@EXEMPI_MAJOR_VERSION@.pc + +libexempi_la_SOURCES = exempi.cpp + +libexempi_la_LIBADD = $(top_builddir)/source/libxmpcommon.la \ + $(top_builddir)/XMPCore/source/libXMPCore.la \ + $(top_builddir)/XMPFiles/source/libXMPFiles.la \ + $(top_builddir)/third-party/zuid/interfaces/libmd5.la \ + -lexpat -lz -ldl + +if UNIX_ENV +libexempi_la_LIBADD += -lrt +endif + +libexempi_la_LDFLAGS = -version-info @EXEMPI_VERSION_INFO@ + +if HAVE_SYMBOLS_FILE +libexempi_la_LDFLAGS += -Wl,--retain-symbols-file=$(srcdir)/libexempi.sym +endif + +dist_man1_MANS = exempi.1 + +EXTRA_DIST = libexempi.sym + diff --git a/exempi/doc/Doxyfile.in b/exempi/doc/Doxyfile.in new file mode 100644 index 0000000..21033dc --- /dev/null +++ b/exempi/doc/Doxyfile.in @@ -0,0 +1,1869 @@ +# Doxyfile 1.8.3.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = @PACKAGE@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = .. + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page (index.html). +# This can be useful if you have a project on for instance GitHub and want reuse +# the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search engine +# library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = *.h + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/exempi/doc/Makefile.am b/exempi/doc/Makefile.am new file mode 100644 index 0000000..012eac6 --- /dev/null +++ b/exempi/doc/Makefile.am @@ -0,0 +1,38 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + +EXTRA_DIST = Doxyfile.in + diff --git a/exempi/exempi-2.0.pc.in b/exempi/exempi-2.0.pc.in new file mode 100644 index 0000000..e8d6745 --- /dev/null +++ b/exempi/exempi-2.0.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +VERSION=@VERSION@ + +Name: exempi +Description: Library for easy parsing of XMP metadata. +Requires: +Version: @VERSION@ +Libs: -L${libdir} -lexempi +Cflags: -I${includedir}/@EXEMPI_INCLUDE_BASE@ -I${includedir} diff --git a/exempi/exempi.1 b/exempi/exempi.1 new file mode 100644 index 0000000..01bb741 --- /dev/null +++ b/exempi/exempi.1 @@ -0,0 +1,40 @@ +.TH exempi 1 "February 10 2013" + +.SH NAME + +exempi - command line tool to manipulate XMP metadata + +.SH SYNTAX + +exempi { -h | [ -R ] [ -x ] [ { -w | -o <file> } ] [ { -g <prop_name> | -s <prop_name> -v <value> } ] } <files> + +.SH OPTIONS + +.IP "-h: show this help" +.IP "-R: don't reconcile" +.IP "-x: dump XML" +.IP "-X: file(s) is XMP" +.IP "-w: write in place. Only for -s. Not compatible with -o." +.IP "-o <file>: file to write the output to." +.IP "-n <ns> <prefix>: set the prefix for a namespace." +.IP "-g <prop_name>: retrieve the value with prop_name." +.IP "-s <prop_name> -v <value>: retrieve or get the value." +.IP "<files> the files to read from." + +.SH SECURITY + +The source code hasn't been audited for security. The command line tool doesn't have a strong input sanity checking easier. +.P +Be careful not to run the tool as super-user. Be careful if you decide to use it in an online (web) application. +.P +Patches and suggestions welcome. + +.SH AUHTORS + +Exempi is written by Hubert Figuiere +.P +It contains the XMP SDK written by Adobe Systems Inc. + +.SH LICENSE + +Exempi is licensed under the BSD license. diff --git a/exempi/exempi.cpp b/exempi/exempi.cpp new file mode 100644 index 0000000..5392047 --- /dev/null +++ b/exempi/exempi.cpp @@ -0,0 +1,1170 @@ +/* + * exempi - exempi.cpp + * + * Copyright (C) 2007-2016 Hubert Figuière + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** @brief this file implement the glue for XMP API + */ + +#include "xmpconsts.h" +#include "xmp.h" +#include "xmperrors.h" + +#include <string> +#include <iostream> +#include <memory> + +#define XMP_INCLUDE_XMPFILES 1 +#define TXMP_STRING_TYPE std::string +#include "XMP.hpp" +#include "XMP.incl_cpp" +#include "XMPUtils.hpp" + +#if HAVE_NATIVE_TLS + +static TLS int g_error = 0; + +static void set_error(int err) +{ + g_error = err; +} + +#else + +#include <pthread.h> + +/* Portable thread local storage using pthreads */ +static pthread_key_t key = NULL; +static pthread_once_t key_once = PTHREAD_ONCE_INIT; + +/* Destructor called when a thread exits - ensure to delete allocated int + * pointer */ +static void destroy_tls_key(void *ptr) +{ + int *err_ptr = static_cast<int *>(ptr); + delete err_ptr; +} + +/* Create a key for use with pthreads local storage */ +static void create_tls_key() +{ + (void)pthread_key_create(&key, destroy_tls_key); +} + +/* Obtain the latest xmp error for this specific thread - defaults to 0 */ +static int get_error_for_thread() +{ + int *err_ptr; + + pthread_once(&key_once, create_tls_key); + err_ptr = (int *)pthread_getspecific(key); + + if (err_ptr == NULL) { + return 0; + } + + return *err_ptr; +} + +/* set the current xmp error for this specific thread */ +static void set_error(int err) +{ + int *err_ptr; + + // Ensure that create_thread_local_storage_key is only called + // once, by the first thread, to create the key. + pthread_once(&key_once, create_tls_key); + + // Retrieve pointer to int for this thread. + err_ptr = (int *)pthread_getspecific(key); + + // Allocate it, if it does not exists. + if (err_ptr == NULL) { + err_ptr = new int; + pthread_setspecific(key, err_ptr); + } + + // Save the error for this thread. + *err_ptr = err; +} + +#endif + +static void set_error(const XMP_Error &e) +{ + set_error(-e.GetID()); + std::cerr << e.GetErrMsg() << std::endl; +} + +#define RESET_ERROR set_error(0) + +// Hack: assign between XMP_DateTime and XmpDateTime +#define ASSIGN(dst, src) \ + (dst).year = (src).year; \ + (dst).month = (src).month; \ + (dst).day = (src).day; \ + (dst).hour = (src).hour; \ + (dst).minute = (src).minute; \ + (dst).second = (src).second; \ + (dst).tzSign = (src).tzSign; \ + (dst).tzHour = (src).tzHour; \ + (dst).tzMinute = (src).tzMinute; \ + (dst).nanoSecond = (src).nanoSecond; + +#ifdef __cplusplus +extern "C" { +#endif + +const char NS_XMP_META[] = "adobe:ns:meta/"; +const char NS_RDF[] = kXMP_NS_RDF; +const char NS_EXIF[] = kXMP_NS_EXIF; +const char NS_TIFF[] = kXMP_NS_TIFF; +const char NS_XAP[] = kXMP_NS_XMP; +const char NS_XAP_RIGHTS[] = kXMP_NS_XMP_Rights; +const char NS_DC[] = kXMP_NS_DC; +const char NS_EXIF_AUX[] = kXMP_NS_EXIF_Aux; +const char NS_CRS[] = kXMP_NS_CameraRaw; +const char NS_LIGHTROOM[] = "http://ns.adobe.com/lightroom/1.0/"; +const char NS_CAMERA_RAW_SETTINGS[] = kXMP_NS_CameraRaw; +const char NS_CAMERA_RAW_SAVED_SETTINGS[] = + "http://ns.adobe.com/camera-raw-saved-settings/1.0/"; +const char NS_PHOTOSHOP[] = kXMP_NS_Photoshop; +const char NS_IPTC4XMP[] = kXMP_NS_IPTCCore; +const char NS_TPG[] = kXMP_NS_XMP_PagedFile; +const char NS_DIMENSIONS_TYPE[] = kXMP_NS_XMP_Dimensions; +const char NS_CC[] = "http://creativecommons.org/ns#"; +const char NS_PDF[] = kXMP_NS_PDF; + +#define STRING(x) reinterpret_cast<std::string *>(x) + +#define CHECK_PTR(p, r) \ + if (p == NULL) { \ + set_error(XMPErr_BadObject); \ + return r; \ + } + +int xmp_get_error() +{ +#if HAVE_NATIVE_TLS + return g_error; +#else + return get_error_for_thread(); +#endif +} + +bool xmp_init() +{ + RESET_ERROR; + try { + // no need to initialize anything else. + // XMP SDK 5.1.2 needs this because it has been lobotomized of local + // text + // conversion + // the one that was done in Exempi with libiconv. + return SXMPFiles::Initialize(kXMPFiles_IgnoreLocalText); + } + catch (const XMP_Error &e) { + set_error(e); + } + return false; +} + +void xmp_terminate() +{ + RESET_ERROR; + SXMPFiles::Terminate(); +} + +bool xmp_register_namespace(const char *namespaceURI, + const char *suggestedPrefix, + XmpStringPtr registeredPrefix) +{ + RESET_ERROR; + try { + return SXMPMeta::RegisterNamespace(namespaceURI, suggestedPrefix, + STRING(registeredPrefix)); + } + catch (const XMP_Error &e) { + set_error(e); + } + return false; +} + +bool xmp_namespace_prefix(const char *ns, XmpStringPtr prefix) +{ + CHECK_PTR(ns, false); + RESET_ERROR; + try { + return SXMPMeta::GetNamespacePrefix(ns, STRING(prefix)); + } + catch (const XMP_Error &e) { + set_error(e); + } + return false; +} + +bool xmp_prefix_namespace_uri(const char *prefix, XmpStringPtr ns) +{ + CHECK_PTR(prefix, false); + RESET_ERROR; + try { + return SXMPMeta::GetNamespaceURI(prefix, STRING(ns)); + } + catch (const XMP_Error &e) { + set_error(e); + } + return false; +} + +XmpFilePtr xmp_files_new() +{ + RESET_ERROR; + + try { + auto txf = std::unique_ptr<SXMPFiles>(new SXMPFiles()); + + return reinterpret_cast<XmpFilePtr>(txf.release()); + } + catch (const XMP_Error &e) { + set_error(e); + } + return NULL; +} + +XmpFilePtr xmp_files_open_new(const char *path, XmpOpenFileOptions options) +{ + CHECK_PTR(path, NULL); + RESET_ERROR; + + try { + auto txf = std::unique_ptr<SXMPFiles>(new SXMPFiles); + + txf->OpenFile(path, XMP_FT_UNKNOWN, options); + + return reinterpret_cast<XmpFilePtr>(txf.release()); + } + catch (const XMP_Error &e) { + set_error(e); + } + + return NULL; +} + +bool xmp_files_open(XmpFilePtr xf, const char *path, XmpOpenFileOptions options) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + try { + return txf->OpenFile(path, XMP_FT_UNKNOWN, options); + } + catch (const XMP_Error &e) { + set_error(e); + } + return false; +} + +bool xmp_files_close(XmpFilePtr xf, XmpCloseFileOptions options) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + try { + auto txf = reinterpret_cast<SXMPFiles *>(xf); + txf->CloseFile(options); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return true; +} + +XmpPtr xmp_files_get_new_xmp(XmpFilePtr xf) +{ + CHECK_PTR(xf, NULL); + RESET_ERROR; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + + bool result = false; + try { + auto xmp = std::unique_ptr<SXMPMeta>(new SXMPMeta); + result = txf->GetXMP(xmp.get()); + if (result) { + return reinterpret_cast<XmpPtr>(xmp.release()); + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return NULL; +} + +bool xmp_files_get_xmp(XmpFilePtr xf, XmpPtr xmp) +{ + CHECK_PTR(xf, false); + CHECK_PTR(xmp, false); + RESET_ERROR; + bool result = false; + try { + auto txf = reinterpret_cast<SXMPFiles *>(xf); + + result = txf->GetXMP(reinterpret_cast<SXMPMeta *>(xmp)); + } + catch (const XMP_Error &e) { + set_error(e); + } + return result; +} + +bool xmp_files_get_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet, + XmpPacketInfo* packet_info) +{ + CHECK_PTR(xf, false); + CHECK_PTR(xmp_packet, false); + RESET_ERROR; + bool result = false; + try { + SXMPFiles *txf = reinterpret_cast<SXMPFiles*>(xf); + + XMP_PacketInfo xmp_packet_info; + result = txf->GetXMP(NULL, + reinterpret_cast<std::string*>(xmp_packet), + &xmp_packet_info); + if (packet_info) { + packet_info->offset = xmp_packet_info.offset; + packet_info->length = xmp_packet_info.length; + packet_info->padSize = xmp_packet_info.padSize; + packet_info->charForm = xmp_packet_info.charForm; + packet_info->writeable = xmp_packet_info.writeable; + packet_info->hasWrapper = xmp_packet_info.hasWrapper; + packet_info->pad = xmp_packet_info.pad; + } + } + catch(const XMP_Error & e) { + set_error(e); + } + return result; +} + + +bool xmp_files_can_put_xmp(XmpFilePtr xf, XmpPtr xmp) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + bool result = false; + + try { + result = txf->CanPutXMP(*reinterpret_cast<const SXMPMeta *>(xmp)); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return result; +} + +bool xmp_files_can_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + SXMPFiles *txf = reinterpret_cast<SXMPFiles*>(xf); + bool result = false; + + try { + result = txf->CanPutXMP(*reinterpret_cast<const std::string*>(xmp_packet)); + } + catch(const XMP_Error & e) { + set_error(e); + return false; + } + return result; +} + +bool xmp_files_can_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet, size_t len) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + SXMPFiles *txf = reinterpret_cast<SXMPFiles*>(xf); + bool result = false; + + try { + result = txf->CanPutXMP(xmp_packet, len); + } + catch(const XMP_Error & e) { + set_error(e); + return false; + } + return result; +} + +bool xmp_files_put_xmp(XmpFilePtr xf, XmpPtr xmp) +{ + CHECK_PTR(xf, false); + CHECK_PTR(xmp, false); + RESET_ERROR; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + + try { + txf->PutXMP(*reinterpret_cast<const SXMPMeta *>(xmp)); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_files_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet) +{ + CHECK_PTR(xf, false); + CHECK_PTR(xmp_packet, false); + RESET_ERROR; + SXMPFiles *txf = reinterpret_cast<SXMPFiles*>(xf); + + try { + txf->PutXMP(*reinterpret_cast<const std::string*>(xmp_packet)); + } + catch(const XMP_Error & e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_files_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet, size_t len) +{ + CHECK_PTR(xf, false); + CHECK_PTR(xmp_packet, false); + RESET_ERROR; + SXMPFiles *txf = reinterpret_cast<SXMPFiles*>(xf); + + try { + txf->PutXMP(xmp_packet, len); + } + catch(const XMP_Error & e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_files_get_file_info(XmpFilePtr xf, XmpStringPtr filePath, + XmpOpenFileOptions *options, + XmpFileType *file_format, + XmpFileFormatOptions *handler_flags) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + + bool result = false; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + try { + result = txf->GetFileInfo(STRING(filePath), (XMP_OptionBits *)options, + (XMP_FileFormat *)file_format, + (XMP_OptionBits *)handler_flags); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + + return result; +} + +bool xmp_files_free(XmpFilePtr xf) +{ + CHECK_PTR(xf, false); + RESET_ERROR; + auto txf = reinterpret_cast<SXMPFiles *>(xf); + try { + delete txf; + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_files_get_format_info(XmpFileType format, + XmpFileFormatOptions *options) +{ + RESET_ERROR; + + bool result = false; + try { + result = SXMPFiles::GetFormatInfo(format, (XMP_OptionBits *)options); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return result; +} + +XmpFileType xmp_files_check_file_format(const char *filePath) +{ + CHECK_PTR(filePath, XMP_FT_UNKNOWN); + RESET_ERROR; + + XmpFileType file_type = XMP_FT_UNKNOWN; + try { + file_type = (XmpFileType)SXMPFiles::CheckFileFormat(filePath); + } + catch (const XMP_Error &e) { + set_error(e); + return XMP_FT_UNKNOWN; + } + return file_type; +} + +XmpPtr xmp_new_empty() +{ + RESET_ERROR; + SXMPMeta *txmp = new SXMPMeta; + return (XmpPtr)txmp; +} + +XmpPtr xmp_new(const char *buffer, size_t len) +{ + CHECK_PTR(buffer, NULL); + RESET_ERROR; + + try { + auto txmp = std::unique_ptr<SXMPMeta>(new SXMPMeta(buffer, len)); + return reinterpret_cast<XmpPtr>(txmp.release()); + } + catch (const XMP_Error &e) { + set_error(e); + } + return NULL; +} + +XmpPtr xmp_copy(XmpPtr xmp) +{ + CHECK_PTR(xmp, NULL); + RESET_ERROR; + + try { + auto txmp = std::unique_ptr<SXMPMeta>(new SXMPMeta(*(SXMPMeta *)xmp)); + return reinterpret_cast<XmpPtr>(txmp.release()); + } + catch (const XMP_Error &e) { + set_error(e); + } + return NULL; +} + +bool xmp_parse(XmpPtr xmp, const char *buffer, size_t len) +{ + CHECK_PTR(xmp, false); + CHECK_PTR(buffer, false); + + SXMPMeta *txmp = (SXMPMeta *)xmp; + try { + txmp->ParseFromBuffer(buffer, len, kXMP_RequireXMPMeta); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_serialize(XmpPtr xmp, XmpStringPtr buffer, uint32_t options, + uint32_t padding) +{ + RESET_ERROR; + return xmp_serialize_and_format(xmp, buffer, options, padding, "\n", " ", + 0); +} + +bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer, uint32_t options, + uint32_t padding, const char *newline, + const char *tab, int32_t indent) +{ + CHECK_PTR(xmp, false); + CHECK_PTR(buffer, false); + RESET_ERROR; + + SXMPMeta *txmp = (SXMPMeta *)xmp; + try { + txmp->SerializeToBuffer(STRING(buffer), options, padding, newline, tab, + indent); + } + catch (const XMP_Error &e) { + set_error(e); + return false; + } + return true; +} + +bool xmp_free(XmpPtr xmp) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + SXMPMeta *txmp = (SXMPMeta *)xmp; + delete txmp; + return true; +} + +bool xmp_get_property(XmpPtr xmp, const char *schema, const char *name, + XmpStringPtr property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetProperty(schema, name, STRING(property), &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_property_date(XmpPtr xmp, const char *schema, const char *name, + XmpDateTime *property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + XMP_DateTime dt; + // memset((void*)&dt, 1, sizeof(XMP_DateTime)); + ret = txmp->GetProperty_Date(schema, name, &dt, &optionBits); + ASSIGN((*property), dt); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_property_float(XmpPtr xmp, const char *schema, const char *name, + double *property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetProperty_Float(schema, name, property, &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_property_bool(XmpPtr xmp, const char *schema, const char *name, + bool *property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetProperty_Bool(schema, name, property, &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_property_int32(XmpPtr xmp, const char *schema, const char *name, + int32_t *property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + // the long converstion is needed until XMPCore is fixed it use proper + // types. + ret = txmp->GetProperty_Int(schema, name, property, &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_property_int64(XmpPtr xmp, const char *schema, const char *name, + int64_t *property, uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetProperty_Int64(schema, name, property, &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_get_array_item(XmpPtr xmp, const char *schema, const char *name, + int32_t index, XmpStringPtr property, + uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetArrayItem(schema, name, index, STRING(property), + &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + } + return ret; +} + +bool xmp_set_property(XmpPtr xmp, const char *schema, const char *name, + const char *value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + // see bug #16030 + // when it is a struct or an array, get prop return an empty string + // but it fail if passed an empty string + if ((optionBits & (XMP_PROP_VALUE_IS_STRUCT | XMP_PROP_VALUE_IS_ARRAY)) && + (*value == 0)) { + value = NULL; + } + try { + txmp->SetProperty(schema, name, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_property_date(XmpPtr xmp, const char *schema, const char *name, + const XmpDateTime *value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + XMP_DateTime dt; + ASSIGN(dt, (*value)); + txmp->SetProperty_Date(schema, name, dt, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_property_float(XmpPtr xmp, const char *schema, const char *name, + double value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetProperty_Float(schema, name, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_property_bool(XmpPtr xmp, const char *schema, const char *name, + bool value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetProperty_Bool(schema, name, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_property_int32(XmpPtr xmp, const char *schema, const char *name, + int32_t value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetProperty_Int(schema, name, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_property_int64(XmpPtr xmp, const char *schema, const char *name, + int64_t value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetProperty_Int64(schema, name, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_set_array_item(XmpPtr xmp, const char *schema, const char *name, + int32_t index, const char *value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetArrayItem(schema, name, index, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_append_array_item(XmpPtr xmp, const char *schema, const char *name, + uint32_t arrayOptions, const char *value, + uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->AppendArrayItem(schema, name, arrayOptions, value, optionBits); + ret = true; + } + catch (const XMP_Error &e) { + set_error(e); + } + catch (...) { + } + return ret; +} + +bool xmp_delete_property(XmpPtr xmp, const char *schema, const char *name) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = true; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->DeleteProperty(schema, name); + } + catch (const XMP_Error &e) { + set_error(e); + ret = false; + } + catch (...) { + ret = false; + } + return ret; +} + +bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = true; + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + try { + ret = txmp->DoesPropertyExist(schema, name); + } + catch (const XMP_Error &e) { + set_error(e); + ret = false; + } + catch (...) { + ret = false; + } + return ret; +} + +bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, const char *specificLang, + XmpStringPtr actualLang, XmpStringPtr itemValue, + uint32_t *propsBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = false; + try { + auto txmp = reinterpret_cast<const SXMPMeta *>(xmp); + XMP_OptionBits optionBits; + ret = txmp->GetLocalizedText(schema, name, genericLang, specificLang, + STRING(actualLang), STRING(itemValue), + &optionBits); + if (propsBits) { + *propsBits = optionBits; + } + } + catch (const XMP_Error &e) { + set_error(e); + ret = false; + } + return ret; +} + +bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, const char *specificLang, + const char *value, uint32_t optionBits) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = true; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->SetLocalizedText(schema, name, genericLang, specificLang, value, + optionBits); + } + catch (const XMP_Error &e) { + set_error(e); + ret = false; + } + catch (...) { + ret = false; + } + return ret; +} + +bool xmp_delete_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, + const char *specificLang) +{ + CHECK_PTR(xmp, false); + RESET_ERROR; + + bool ret = true; + auto txmp = reinterpret_cast<SXMPMeta *>(xmp); + try { + txmp->DeleteLocalizedText(schema, name, genericLang, specificLang); + } + catch (const XMP_Error &e) { + set_error(e); + ret = false; + } + catch (...) { + ret = false; + } + return ret; +} + +XmpStringPtr xmp_string_new() +{ + return (XmpStringPtr) new std::string; +} + +void xmp_string_free(XmpStringPtr s) +{ + auto str = reinterpret_cast<std::string *>(s); + delete str; +} + +const char *xmp_string_cstr(XmpStringPtr s) +{ + CHECK_PTR(s, NULL); + return reinterpret_cast<const std::string *>(s)->c_str(); +} + +size_t xmp_string_len(XmpStringPtr s) +{ + CHECK_PTR(s, 0); + return reinterpret_cast<const std::string *>(s)->size(); +} + +XmpIteratorPtr xmp_iterator_new(XmpPtr xmp, const char *schema, + const char *propName, XmpIterOptions options) +{ + CHECK_PTR(xmp, NULL); + RESET_ERROR; + + try { + auto xiter = std::unique_ptr<SXMPIterator>( + new SXMPIterator(*(SXMPMeta *)xmp, schema, propName, options)); + + return reinterpret_cast<XmpIteratorPtr>(xiter.release()); + } + catch (const XMP_Error &e) { + set_error(e); + } + + return NULL; +} + +bool xmp_iterator_free(XmpIteratorPtr iter) +{ + CHECK_PTR(iter, false); + RESET_ERROR; + auto titer = reinterpret_cast<SXMPIterator *>(iter); + delete titer; + return true; +} + +bool xmp_iterator_next(XmpIteratorPtr iter, XmpStringPtr schema, + XmpStringPtr propName, XmpStringPtr propValue, + uint32_t *options) +{ + CHECK_PTR(iter, false); + RESET_ERROR; + auto titer = reinterpret_cast<SXMPIterator *>(iter); + return titer->Next(reinterpret_cast<std::string *>(schema), + reinterpret_cast<std::string *>(propName), + reinterpret_cast<std::string *>(propValue), options); +} + +bool xmp_iterator_skip(XmpIteratorPtr iter, XmpIterSkipOptions options) +{ + CHECK_PTR(iter, false); + RESET_ERROR; + auto titer = reinterpret_cast<SXMPIterator *>(iter); + titer->Skip(options); + return true; +} + +int xmp_datetime_compare(XmpDateTime *left, XmpDateTime *right) +{ + if (!left && !right) { + return 0; + } + if (!left) { + return -1; + } + if (!right) { + return 1; + } + XMP_DateTime _left; + ASSIGN(_left, *left); + XMP_DateTime _right; + ASSIGN(_right, *right); + return XMPUtils::CompareDateTime(_left, _right); +} + +#ifdef __cplusplus +} +#endif diff --git a/exempi/libexempi.sym b/exempi/libexempi.sym new file mode 100644 index 0000000..d75d5c0 --- /dev/null +++ b/exempi/libexempi.sym @@ -0,0 +1,67 @@ +xmp_append_array_item +xmp_copy +xmp_delete_localized_text +xmp_delete_property +xmp_files_can_put_xmp +xmp_files_close +xmp_files_free +xmp_files_get_new_xmp +xmp_files_get_xmp +xmp_files_new +xmp_files_open +xmp_files_open_new +xmp_files_put_xmp +xmp_free +xmp_get_array_item +xmp_get_error +xmp_get_localized_text +xmp_get_property +xmp_get_property_bool +xmp_get_property_date +xmp_get_property_float +xmp_get_property_int32 +xmp_get_property_int64 +xmp_has_property +xmp_init +xmp_iterator_free +xmp_iterator_new +xmp_iterator_next +xmp_iterator_skip +xmp_namespace_prefix +xmp_new +xmp_new_empty +xmp_parse +xmp_prefix_namespace_uri +xmp_register_namespace +xmp_serialize +xmp_serialize_and_format +xmp_set_array_item +xmp_set_localized_text +xmp_set_property +xmp_set_property_bool +xmp_set_property_date +xmp_set_property_float +xmp_set_property_int32 +xmp_set_property_int64 +xmp_string_cstr +xmp_string_free +xmp_string_new +xmp_terminate +NS_CAMERA_RAW_SAVED_SETTINGS +NS_CAMERA_RAW_SETTINGS +NS_CC +NS_CRS +NS_DC +NS_DIMENSIONS_TYPE +NS_EXIF +NS_EXIF_AUX +NS_IPTC4XMP +NS_LIGHTROOM +NS_PDF +NS_PHOTOSHOP +NS_RDF +NS_TIFF +NS_TPG +NS_XAP +NS_XAP_RIGHTS +NS_XMP_META diff --git a/exempi/main.cpp b/exempi/main.cpp new file mode 100644 index 0000000..4cca1ca --- /dev/null +++ b/exempi/main.cpp @@ -0,0 +1,357 @@ +/* -*- tab-width:4; c-basic-offset:4; indent-tabs-mode:nil; + * c-file-style:"stroustrup" -*- */ +/* + * exempi - exempi.cpp + * + * Copyright (C) 2011-2013 Hubert Figuiere + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#include <string> +#include <vector> + +#include <exempi/xmp.h> +#include <exempi/xmp++.hpp> + +enum { ACTION_NONE = 0, ACTION_SET, ACTION_GET }; + +static void process_file(const char *filename, bool no_reconcile, + bool is_an_xmp, bool dump_xml, bool write_in_place, + int action, const std::string &value_name, + const std::string &prop_value, + const std::string &output); + +/** fatal error in argument. Display and quit. */ +static void fatal_error(const char *error) +{ + fprintf(stderr, "ERROR: %s\n", error); + exit(128); +} + +/** Print the usage, and quit. Exit code is 255. + */ +static void usage() +{ + fprintf(stderr, "Exempi version %s\n", VERSION); + fprintf(stderr, "exempi { -h | [ -R ] [ -x ] [ { -w | -o <file> } ] [ { -g " + "<prop_name> | -s <prop_name> -v <value> } ] } <files>\n"); + fprintf(stderr, "\t-h: show this help\n"); + fprintf(stderr, "\t-R: don't reconcile\n"); + fprintf(stderr, "\t-x: dump XML packet.\n"); + fprintf(stderr, "\t-X: file(s) is XMP\n"); + fprintf(stderr, + "\t-w: write in place. Only for -s. Not compatible with -o.\n"); + fprintf(stderr, "\t-o <file>: file to write the output to.\n"); + fprintf(stderr, "\t-n <uri> <prefix>: create a new namespace.\n"); + fprintf(stderr, "\t-g <prop_name>: retrieve the value with prop_name.\n"); + fprintf(stderr, + "\t-s <prop_name> -v <value>: retrieve or get the value.\n"); + fprintf(stderr, "\t<files> the files to read from.\n"); + + exit(255); +} + +int main(int argc, char **argv) +{ + int ch; + + int action = ACTION_NONE; + bool dont_reconcile = false; + bool write_in_place = false; + bool dump_xml = false; + bool is_an_xmp = false; + std::string output_file; + std::string value_name; + std::string prop_value; + std::vector<std::pair<std::string, std::string>> namespaces; + + while ((ch = getopt(argc, argv, "hRo:wxXn:g:s:v:")) != -1) { + switch (ch) { + + case 'R': + dont_reconcile = true; + break; + case 'o': + output_file = optarg; + break; + case 'w': + write_in_place = true; + break; + case 'x': + dump_xml = true; + break; + case 'X': + is_an_xmp = true; + break; + case 'g': + if (!value_name.empty()) { + usage(); + } + action = ACTION_GET; + value_name = optarg; + break; + case 'n': { + std::string ns = optarg; + std::string prefix = argv[optind]; + if (prefix[0] && prefix[0] != '-') { + namespaces.push_back(make_pair(ns, prefix)); + optind++; + } + break; + } + case 's': + if (!value_name.empty()) { + usage(); + } + action = ACTION_SET; + value_name = optarg; + break; + case 'v': + if (action != ACTION_SET || value_name.empty()) { + fatal_error("-v needs to come after -s"); + } + prop_value = optarg; + break; + case 'h': + case '?': + usage(); + break; + } + } + + argc -= optind; + argv += optind; + + if (optind == 1 || argc == 0) { + fatal_error("Missing input."); + return 1; + } + + if (write_in_place && (!output_file.empty() || action != ACTION_SET)) { + fatal_error( + "Need to write in place and output file are mutually exclusive."); + return 1; + } + + if (action == ACTION_SET && (!write_in_place && argc > 1)) { + fatal_error("Need to write in place for more than one file."); + return 1; + } + + xmp_init(); + if (!namespaces.empty()) { + for (std::vector<std::pair<std::string, std::string>>::const_iterator + iter = namespaces.begin(); + iter != namespaces.end(); ++iter) { + xmp_register_namespace(iter->first.c_str(), iter->second.c_str(), + NULL); + } + } + while (argc) { + + process_file(*argv, dont_reconcile, is_an_xmp, write_in_place, dump_xml, + action, value_name, prop_value, output_file); + argc--; + argv++; + } + + xmp_terminate(); + return 0; +} + +static XmpPtr get_xmp_from_sidecar(const char *filename, bool is_an_xmp) +{ + struct stat s; + + if (stat(filename, &s) == -1) { + perror("exempi:"); + return NULL; + } + + off_t size = s.st_size; + FILE *file = fopen(filename, "r"); + if (!file) { + perror("exempi:"); + return NULL; + } + + char *buffer = (char *)malloc(size); + size_t len = fread(buffer, 1, size, file); + + XmpPtr xmp = xmp_new_empty(); + if (!xmp_parse(xmp, buffer, len)) { + xmp_free(xmp); + xmp = NULL; + } + free(buffer); + fclose(file); + return xmp; +} + +/** Helper to get the XMP for the file */ +static XmpPtr get_xmp_from_file(const char *filename, bool no_reconcile, + bool is_an_xmp) +{ + if (is_an_xmp) { + return get_xmp_from_sidecar(filename, is_an_xmp); + } + + xmp::ScopedPtr<XmpFilePtr> f(xmp_files_open_new( + filename, (XmpOpenFileOptions)(XMP_OPEN_READ | + (no_reconcile ? XMP_OPEN_ONLYXMP : 0)))); + if (f) { + XmpPtr xmp = xmp_files_get_new_xmp(f); + xmp_files_close(f, XMP_CLOSE_NOOPTION); + return xmp; + } + return NULL; +} + +/** dump the XMP xml to the output IO */ +static void dump_xmp(const char *filename, bool no_reconcile, bool is_an_xmp, + FILE *outio) +{ + printf("dump_xmp for file %s\n", filename); + xmp::ScopedPtr<XmpPtr> xmp( + get_xmp_from_file(filename, no_reconcile, is_an_xmp)); + + xmp::ScopedPtr<XmpStringPtr> output(xmp_string_new()); + + xmp_serialize_and_format(xmp, output, XMP_SERIAL_OMITPACKETWRAPPER, 0, "\n", + " ", 0); + + fprintf(outio, "%s", xmp_string_cstr(output)); +} + +/** get an xmp prop and dump it to the output IO */ +static void get_xmp_prop(const char *filename, const std::string &value_name, + bool no_reconcile, bool is_an_xmp, FILE *outio) +{ + xmp::ScopedPtr<XmpPtr> xmp( + get_xmp_from_file(filename, no_reconcile, is_an_xmp)); + + std::string prefix; + size_t idx = value_name.find(':'); + if (idx != std::string::npos) { + prefix = std::string(value_name, 0, idx); + } + + xmp::ScopedPtr<XmpStringPtr> property(xmp_string_new()); + xmp::ScopedPtr<XmpStringPtr> ns(xmp_string_new()); + xmp_prefix_namespace_uri(prefix.c_str(), ns); + xmp_get_property(xmp, xmp_string_cstr(ns), value_name.c_str(), property, + NULL); + fprintf(outio, "%s\n", xmp_string_cstr(property)); +} + +static void set_xmp_prop(const char *filename, const std::string &value_name, + const std::string &prop_value, bool no_reconcile, + bool is_an_xmp, bool write_in_place, FILE *outio) +{ + xmp::ScopedPtr<XmpPtr> xmp( + get_xmp_from_file(filename, no_reconcile, is_an_xmp)); + + std::string prefix; + size_t idx = value_name.find(':'); + if (idx != std::string::npos) { + prefix = std::string(value_name, 0, idx); + } + + xmp::ScopedPtr<XmpStringPtr> ns(xmp_string_new()); + xmp_prefix_namespace_uri(prefix.c_str(), ns); + if (!xmp_set_property(xmp, xmp_string_cstr(ns), + value_name.c_str() + idx + 1, prop_value.c_str(), + 0)) { + fprintf(stderr, "set error = %d\n", xmp_get_error()); + } + + if (write_in_place) { + xmp::ScopedPtr<XmpFilePtr> f(xmp_files_open_new( + filename, + (XmpOpenFileOptions)(XMP_OPEN_FORUPDATE | + (no_reconcile ? XMP_OPEN_ONLYXMP : 0)))); + + if (!xmp_files_can_put_xmp(f, xmp)) { + fprintf(stderr, "can put xmp error = %d\n", xmp_get_error()); + } + if (!xmp_files_put_xmp(f, xmp)) { + fprintf(stderr, "put xmp error = %d\n", xmp_get_error()); + } + if (!xmp_files_close(f, XMP_CLOSE_SAFEUPDATE)) { + fprintf(stderr, "close error = %d\n", xmp_get_error()); + } + } +} + +/** process a file with all the options */ +static void process_file(const char *filename, bool no_reconcile, + bool is_an_xmp, bool write_in_place, bool dump_xml, + int action, const std::string &value_name, + const std::string &prop_value, + const std::string &output) +{ + printf("processing file %s\n", filename); + + FILE *outio = stdout; + + bool needclose = false; + if (!output.empty()) { + outio = fopen(output.c_str(), "a+"); + needclose = true; + } + + switch (action) { + case ACTION_NONE: + if (dump_xml) { + dump_xmp(filename, no_reconcile, is_an_xmp, outio); + } + break; + case ACTION_SET: + set_xmp_prop(filename, value_name, prop_value, no_reconcile, is_an_xmp, + write_in_place, outio); + break; + case ACTION_GET: + get_xmp_prop(filename, value_name, no_reconcile, is_an_xmp, outio); + break; + default: + break; + } + + if (needclose) { + fclose(outio); + } +} diff --git a/exempi/tests/Makefile.am b/exempi/tests/Makefile.am new file mode 100644 index 0000000..92c94e9 --- /dev/null +++ b/exempi/tests/Makefile.am @@ -0,0 +1,110 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2011 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + + +AUTOMAKE_OPTIONS = parallel-tests +TEST_EXTENSIONS = .sh + +if WITH_UNIT_TEST +check_PROGRAMS = testexempicore testserialise testwritenewprop \ + testtiffleak testxmpfiles testxmpfileswrite \ + test3 testinit testfdo18635 testfdo83313 testcpp testwebp +TESTS = testcore.sh testinit testexempicore testserialise testwritenewprop \ + testtiffleak testxmpfiles testxmpfileswrite \ + test3 testfdo18635 testfdo83313 testcpp testwebp +TESTS_ENVIRONMENT = TEST_DIR=$(srcdir) BOOST_TEST_CATCH_SYSTEM_ERRORS=no VALGRIND="$(VALGRIND)" +LOG_COMPILER = $(VALGRIND) +endif +check_SCRIPTS = testcore.sh + +check_DATA = test1.xmp fdo18635.jpg fdo83313.jpg + +noinst_HEADERS = utils.h + +EXTRA_DIST = $(check_DATA) $(check_SCRIPTS) +CLEANFILES = test.jpg + +AM_CXXFLAGS = @BOOST_CPPFLAGS@ +AM_CPPFLAGS = -I$(srcdir)/.. -I$(top_srcdir)/public/include -I$(top_srcdir) + +testinit_SOURCES = testinit.cpp utils.cpp +testinit_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testinit_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testexempicore_SOURCES = test-exempi-core.cpp utils.cpp +testexempicore_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testexempicore_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testserialise_SOURCES = test-serialise.cpp utils.cpp +testserialise_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testserialise_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testwritenewprop_SOURCES = test-write-new-prop.cpp utils.cpp +testwritenewprop_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testwritenewprop_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testtiffleak_SOURCES = test-tiff-leak.cpp utils.cpp +testtiffleak_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testtiffleak_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testxmpfiles_SOURCES = test-xmpfiles.cpp utils.cpp +testxmpfiles_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testxmpfiles_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testxmpfileswrite_SOURCES = test-xmpfiles-write.cpp utils.cpp +testxmpfileswrite_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testxmpfileswrite_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +test3_SOURCES = test3.cpp utils.cpp +test3_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +test3_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testfdo18635_SOURCES = test-bgo.cpp utils.cpp +testfdo18635_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testfdo18635_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testfdo83313_SOURCES = test-fdo83313.cpp utils.cpp +testfdo83313_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testfdo83313_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testcpp_SOURCES = testcpp.cpp utils.cpp +testcpp_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testcpp_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ + +testwebp_SOURCES = test-webp.cpp utils.cpp +testwebp_LDADD = ../libexempi.la @BOOST_UNIT_TEST_FRAMEWORK_LIBS@ +testwebp_LDFLAGS = -static @BOOST_UNIT_TEST_FRAMEWORK_LDFLAGS@ diff --git a/exempi/tests/fdo18635.jpg b/exempi/tests/fdo18635.jpg Binary files differnew file mode 100644 index 0000000..0f8f38f --- /dev/null +++ b/exempi/tests/fdo18635.jpg diff --git a/exempi/tests/fdo83313.jpg b/exempi/tests/fdo83313.jpg Binary files differnew file mode 100644 index 0000000..59c5c43 --- /dev/null +++ b/exempi/tests/fdo83313.jpg diff --git a/exempi/tests/test-bgo.cpp b/exempi/tests/test-bgo.cpp new file mode 100644 index 0000000..1919780 --- /dev/null +++ b/exempi/tests/test-bgo.cpp @@ -0,0 +1,74 @@ +/* + * exempi - test-bgo.cpp + * + * Copyright (C) 2007-2008 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +int test_main(int argc, char* argv[]) +{ + prepare_test(argc, argv, "fdo18635.jpg"); + + BOOST_CHECK(xmp_init()); + + XmpFilePtr xf = xmp_files_open_new(g_testfile.c_str(), XMP_OPEN_READ); + + BOOST_CHECK(xf != NULL); + if (xf == NULL) { + return 1; + } + + XmpPtr xmp = xmp_files_get_new_xmp(xf); + + BOOST_CHECK(xmp != NULL); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_free(xf)); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-exempi-core.cpp b/exempi/tests/test-exempi-core.cpp new file mode 100644 index 0000000..c71f1b2 --- /dev/null +++ b/exempi/tests/test-exempi-core.cpp @@ -0,0 +1,231 @@ +/* + * exempi - test-exempi-core.cpp + * + * Copyright (C) 2007-2013 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +using boost::unit_test::test_suite; + +// void test_exempi() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "test1.xmp"); + + size_t len; + char *buffer; + + FILE *f = fopen(g_testfile.c_str(), "rb"); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + exit(128); + } + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + buffer = (char *)malloc(len + 1); + size_t rlen = fread(buffer, 1, len, f); + + BOOST_CHECK(rlen == len); + BOOST_CHECK(len != 0); + + BOOST_CHECK(xmp_init()); + + XmpPtr xmp = xmp_new_empty(); + + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + + BOOST_CHECK(xmp != NULL); + + XmpStringPtr the_prop = xmp_string_new(); + BOOST_CHECK(xmp_string_len(the_prop) == 0); + + BOOST_CHECK(xmp_has_property(xmp, NS_TIFF, "Make")); + BOOST_CHECK(!xmp_has_property(xmp, NS_TIFF, "Foo")); + + BOOST_CHECK(xmp_get_property(xmp, NS_TIFF, "Make", the_prop, NULL)); + BOOST_CHECK(strcmp("Canon", xmp_string_cstr(the_prop)) == 0); + BOOST_CHECK(xmp_string_len(the_prop) == 5); + + BOOST_CHECK(xmp_set_property(xmp, NS_TIFF, "Make", "Leica", 0)); + BOOST_CHECK(xmp_get_property(xmp, NS_TIFF, "Make", the_prop, NULL)); + BOOST_CHECK(strcmp("Leica", xmp_string_cstr(the_prop)) == 0); + BOOST_CHECK(xmp_string_len(the_prop) == 5); + + uint32_t bits; + BOOST_CHECK( + xmp_get_property(xmp, NS_DC, "rights[1]/?xml:lang", the_prop, &bits)); + BOOST_CHECK(bits == 0x20); + BOOST_CHECK(XMP_IS_PROP_QUALIFIER(bits)); + + BOOST_CHECK(xmp_get_property(xmp, NS_DC, "rights[1]", the_prop, &bits)); + BOOST_CHECK(bits == 0x50); + BOOST_CHECK(XMP_HAS_PROP_QUALIFIERS(bits)); + + XmpStringPtr the_lang = xmp_string_new(); + BOOST_CHECK(xmp_get_localized_text(xmp, NS_DC, "rights", NULL, "x-default", + the_lang, the_prop, &bits)); + BOOST_CHECK(strcmp("x-default", xmp_string_cstr(the_lang)) == 0); + BOOST_CHECK(strcmp("2006, Hubert Figuiere", xmp_string_cstr(the_prop)) == 0); + + // This will modify the default property. + BOOST_CHECK( + xmp_set_localized_text(xmp, NS_DC, "rights", "en", "en-CA", "Foo Bar", 0)); + // Ask for the en_US alternative. + BOOST_CHECK(xmp_get_localized_text(xmp, NS_DC, "rights", "en", "en-US", + the_lang, the_prop, &bits)); + // And we only got the "en-CA" as the only "en" + BOOST_CHECK(strcmp("en-US", xmp_string_cstr(the_lang)) != 0); + BOOST_CHECK(strcmp("en-CA", xmp_string_cstr(the_lang)) == 0); + // Check its value + BOOST_CHECK(strcmp("Foo Bar", xmp_string_cstr(the_prop)) == 0); + // The default property is supposed to have been changed too. + BOOST_CHECK(xmp_get_localized_text(xmp, NS_DC, "rights", NULL, "x-default", + the_lang, the_prop, &bits)); + BOOST_CHECK(strcmp("Foo Bar", xmp_string_cstr(the_prop)) == 0); + + // This should also remove the property x-default. (SDK 5.2.2) + BOOST_CHECK(xmp_delete_localized_text(xmp, NS_DC, "rights", "en", "en-CA")); + + BOOST_CHECK(!xmp_has_property(xmp, NS_DC, "rights[1]")); + BOOST_CHECK(!xmp_has_property(xmp, NS_DC, "rights[2]")); + + xmp_string_free(the_lang); + + BOOST_CHECK(xmp_set_array_item(xmp, NS_DC, "creator", 2, "foo", 0)); + BOOST_CHECK(xmp_get_array_item(xmp, NS_DC, "creator", 2, the_prop, &bits)); + BOOST_CHECK(XMP_IS_PROP_SIMPLE(bits)); + BOOST_CHECK(strcmp("foo", xmp_string_cstr(the_prop)) == 0); + BOOST_CHECK(xmp_append_array_item(xmp, NS_DC, "creator", 0, "bar", 0)); + + BOOST_CHECK(xmp_get_array_item(xmp, NS_DC, "creator", 3, the_prop, &bits)); + BOOST_CHECK(XMP_IS_PROP_SIMPLE(bits)); + BOOST_CHECK(strcmp("bar", xmp_string_cstr(the_prop)) == 0); + + BOOST_CHECK(xmp_delete_property(xmp, NS_DC, "creator[3]")); + BOOST_CHECK(!xmp_has_property(xmp, NS_DC, "creator[3]")); + + BOOST_CHECK( + xmp_get_property(xmp, NS_EXIF, "DateTimeOriginal", the_prop, NULL)); + BOOST_CHECK(strcmp("2006-12-07T23:20:43-05:00", xmp_string_cstr(the_prop)) == + 0); + + BOOST_CHECK(xmp_get_property(xmp, NS_XAP, "Rating", the_prop, NULL)); + BOOST_CHECK(strcmp("3", xmp_string_cstr(the_prop)) == 0); + + xmp_string_free(the_prop); + + // testing date time get + XmpDateTime the_dt; + bool ret; + BOOST_CHECK(ret = xmp_get_property_date(xmp, NS_EXIF, "DateTimeOriginal", + &the_dt, NULL)); + BOOST_CHECK(the_dt.year == 2006); + BOOST_CHECK(the_dt.minute == 20); + BOOST_CHECK(the_dt.tzSign == XMP_TZ_WEST); + + // testing compare + XmpDateTime the_other_dt; + BOOST_CHECK(ret = xmp_get_property_date(xmp, NS_EXIF, "DateTimeOriginal", + &the_other_dt, NULL)); + BOOST_CHECK(xmp_datetime_compare(&the_dt, &the_other_dt) == 0); + the_other_dt.year++; + BOOST_CHECK(xmp_datetime_compare(&the_dt, &the_other_dt) < 0); + BOOST_CHECK(xmp_datetime_compare(&the_other_dt, &the_dt) > 0); + // NULL checks - this is Exempi API + BOOST_CHECK(xmp_datetime_compare(NULL, NULL) == 0); + BOOST_CHECK(xmp_datetime_compare(NULL, &the_other_dt) < 0); + BOOST_CHECK(xmp_datetime_compare(&the_other_dt, NULL) > 0); + + // testing float get set + double float_value = 0.0; + BOOST_CHECK(xmp_get_property_float(xmp, NS_CAMERA_RAW_SETTINGS, + "SharpenRadius", &float_value, NULL)); + BOOST_CHECK(float_value == 1.0); + BOOST_CHECK(xmp_set_property_float(xmp, NS_CAMERA_RAW_SETTINGS, + "SharpenRadius", 2.5, 0)); + BOOST_CHECK(xmp_get_property_float(xmp, NS_CAMERA_RAW_SETTINGS, + "SharpenRadius", &float_value, NULL)); + BOOST_CHECK(float_value == 2.5); + + // testing bool get set + bool bool_value = true; + BOOST_CHECK(xmp_get_property_bool(xmp, NS_CAMERA_RAW_SETTINGS, + "AlreadyApplied", &bool_value, NULL)); + BOOST_CHECK(!bool_value); + BOOST_CHECK(xmp_set_property_bool(xmp, NS_CAMERA_RAW_SETTINGS, + "AlreadyApplied", true, 0)); + BOOST_CHECK(xmp_get_property_bool(xmp, NS_CAMERA_RAW_SETTINGS, + "AlreadyApplied", &bool_value, NULL)); + BOOST_CHECK(bool_value); + + // testing int get set + int32_t value = 0; + BOOST_CHECK( + xmp_get_property_int32(xmp, NS_EXIF, "MeteringMode", &value, NULL)); + BOOST_CHECK(value == 5); + BOOST_CHECK(xmp_set_property_int32(xmp, NS_EXIF, "MeteringMode", 10, 0)); + int64_t valuelarge = 0; + BOOST_CHECK( + xmp_get_property_int64(xmp, NS_EXIF, "MeteringMode", &valuelarge, NULL)); + BOOST_CHECK(valuelarge == 10); + BOOST_CHECK(xmp_set_property_int64(xmp, NS_EXIF, "MeteringMode", 32, 0)); + + BOOST_CHECK( + xmp_get_property_int32(xmp, NS_EXIF, "MeteringMode", &value, NULL)); + BOOST_CHECK(value == 32); + + BOOST_CHECK(xmp_free(xmp)); + + free(buffer); + fclose(f); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-fdo83313.cpp b/exempi/tests/test-fdo83313.cpp new file mode 100644 index 0000000..38ff771 --- /dev/null +++ b/exempi/tests/test-fdo83313.cpp @@ -0,0 +1,74 @@ +/* + * exempi - test-bgo.cpp + * + * Copyright (C) 2007-2008 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +int test_main(int argc, char* argv[]) +{ + prepare_test(argc, argv, "fdo83313.jpg"); + + BOOST_CHECK(xmp_init()); + + XmpFilePtr xf = xmp_files_open_new(g_testfile.c_str(), XMP_OPEN_READ); + + BOOST_CHECK(xf != NULL); + if (xf == NULL) { + return 1; + } + + XmpPtr xmp = xmp_files_get_new_xmp(xf); + + BOOST_CHECK(xmp != NULL); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_free(xf)); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-serialise.cpp b/exempi/tests/test-serialise.cpp new file mode 100644 index 0000000..6175a16 --- /dev/null +++ b/exempi/tests/test-serialise.cpp @@ -0,0 +1,102 @@ +/* + * exempi - test-serialise.cpp + * + * Copyright (C) 2007-2008 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +using boost::unit_test::test_suite; + +// void test_serialize() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "test1.xmp"); + + size_t len; + char *buffer; + FILE *f = fopen(g_testfile.c_str(), "rb"); + + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + buffer = (char *)malloc(len + 1); + size_t rlen = fread(buffer, 1, len, f); + + BOOST_CHECK(rlen == len); + BOOST_CHECK(len != 0); + buffer[rlen] = 0; + + BOOST_CHECK(xmp_init()); + BOOST_CHECK(xmp_get_error() == 0); + + XmpPtr xmp = xmp_new_empty(); + BOOST_CHECK(xmp_get_error() == 0); + + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + BOOST_CHECK(xmp_get_error() == 0); + + std::string b1(buffer); + std::string b2; + XmpStringPtr output = xmp_string_new(); + + BOOST_CHECK(xmp_serialize_and_format( + xmp, output, XMP_SERIAL_OMITPACKETWRAPPER, 0, "\n", " ", 0)); + BOOST_CHECK(xmp_get_error() == 0); + b2 = xmp_string_cstr(output); + // find a way to compare that. + // BOOST_CHECK_EQUAL(b1, b2); + + xmp_string_free(output); + BOOST_CHECK(xmp_free(xmp)); + + free(buffer); + fclose(f); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-tiff-leak.cpp b/exempi/tests/test-tiff-leak.cpp new file mode 100644 index 0000000..729cced --- /dev/null +++ b/exempi/tests/test-tiff-leak.cpp @@ -0,0 +1,86 @@ +/* + * exempi - test-tiff-leak.cpp + * + * Copyright (C) 2007-2008,2010 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" + +/** See http://www.adobeforums.com/webx/.3bc42b73 for the orignal + * test case */ +// void test_tiff_leak() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "../../samples/testfiles/BlueSquare.jpg"); + + std::string orig_tiff_file = + g_src_testdir + "../../samples/testfiles/BlueSquare.tif"; + BOOST_CHECK(copy_file(orig_tiff_file, "test.tif")); + BOOST_CHECK(chmod("test.tif", S_IRUSR | S_IWUSR) == 0); + BOOST_CHECK(xmp_init()); + + XmpFilePtr f = xmp_files_open_new("test.tif", XMP_OPEN_FORUPDATE); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 1; + } + + XmpPtr xmp; + + BOOST_CHECK(xmp = xmp_files_get_new_xmp(f)); + BOOST_CHECK(xmp != NULL); + + xmp_set_localized_text(xmp, NS_DC, "description", "en", "en-US", "foo", 0); + BOOST_CHECK(xmp_files_put_xmp(f, xmp)); + BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_NOOPTION)); + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_free(f)); + xmp_terminate(); + + BOOST_CHECK(unlink("test.tif") == 0); + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-webp.cpp b/exempi/tests/test-webp.cpp new file mode 100644 index 0000000..47aa7dc --- /dev/null +++ b/exempi/tests/test-webp.cpp @@ -0,0 +1,119 @@ +/* + * exempi - test-webp.cpp + * + * Copyright (C) 2007-2016 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" + +using boost::unit_test::test_suite; + + +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "../../samples/testfiles/BlueSquare.webp"); + + BOOST_CHECK(xmp_init()); + + BOOST_CHECK(xmp_files_check_file_format(g_testfile.c_str()) == XMP_FT_WEBP); + XmpFilePtr f = xmp_files_open_new(g_testfile.c_str(), XMP_OPEN_READ); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 1; + } + + XmpPtr xmp = xmp_files_get_new_xmp(f); + BOOST_CHECK(xmp != NULL); + + BOOST_CHECK(xmp_files_free(f)); + + BOOST_CHECK(copy_file(g_testfile, "test.webp")); + BOOST_CHECK(chmod("test.webp", S_IRUSR | S_IWUSR) == 0); + + BOOST_CHECK(xmp_files_check_file_format("test.webp") == XMP_FT_WEBP); + + f = xmp_files_open_new("test.webp", XMP_OPEN_FORUPDATE); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 2; + } + + BOOST_CHECK(xmp_set_property(xmp, NS_PHOTOSHOP, "ICCProfile", "foo", 0)); + + BOOST_CHECK(xmp_files_can_put_xmp(f, xmp)); + BOOST_CHECK(xmp_files_put_xmp(f, xmp)); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_SAFEUPDATE)); + BOOST_CHECK(xmp_files_free(f)); + + f = xmp_files_open_new("test.webp", XMP_OPEN_READ); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 3; + } + xmp = xmp_files_get_new_xmp(f); + BOOST_CHECK(xmp != NULL); + + XmpStringPtr the_prop = xmp_string_new(); + BOOST_CHECK( + xmp_get_property(xmp, NS_PHOTOSHOP, "ICCProfile", the_prop, NULL)); + BOOST_CHECK(strcmp("foo", xmp_string_cstr(the_prop)) == 0); + + xmp_string_free(the_prop); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_NOOPTION)); + BOOST_CHECK(xmp_files_free(f)); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + + return 0; +} diff --git a/exempi/tests/test-write-new-prop.cpp b/exempi/tests/test-write-new-prop.cpp new file mode 100644 index 0000000..524376e --- /dev/null +++ b/exempi/tests/test-write-new-prop.cpp @@ -0,0 +1,150 @@ +/* + * exempi - test1.cpp + * + * Copyright (C) 2007-2008 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +using boost::unit_test::test_suite; + +// void test_write_new_property() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "test1.xmp"); + + size_t len; + char *buffer; + + FILE *f = fopen(g_testfile.c_str(), "rb"); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + exit(128); + } + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + buffer = (char *)malloc(len + 1); + size_t rlen = fread(buffer, 1, len, f); + + BOOST_CHECK(rlen == len); + BOOST_CHECK(len != 0); + + BOOST_CHECK(xmp_init()); + BOOST_CHECK(xmp_get_error() == 0); + + XmpPtr xmp = xmp_new_empty(); + BOOST_CHECK(xmp_get_error() == 0); + + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + BOOST_CHECK(xmp_get_error() == 0); + + BOOST_CHECK(xmp != NULL); + + XmpStringPtr reg_prefix = xmp_string_new(); + BOOST_CHECK(xmp_register_namespace(NS_CC, "cc", reg_prefix)); + BOOST_CHECK(xmp_get_error() == 0); + BOOST_CHECK(strcmp("cc:", xmp_string_cstr(reg_prefix)) == 0); + + BOOST_CHECK(xmp_prefix_namespace_uri("cc", reg_prefix)); + BOOST_CHECK(xmp_get_error() == 0); + BOOST_CHECK(strcmp(NS_CC, xmp_string_cstr(reg_prefix)) == 0); + + BOOST_CHECK(xmp_namespace_prefix(NS_CC, reg_prefix)); + BOOST_CHECK(xmp_get_error() == 0); + BOOST_CHECK(strcmp("cc:", xmp_string_cstr(reg_prefix)) == 0); + + xmp_string_free(reg_prefix); + + BOOST_CHECK(xmp_set_property(xmp, NS_CC, "License", "Foo", 0)); + BOOST_CHECK(xmp_get_error() == 0); + + XmpStringPtr the_prop = xmp_string_new(); + BOOST_CHECK(xmp_get_property(xmp, NS_CC, "License", the_prop, NULL)); + BOOST_CHECK(xmp_get_error() == 0); + BOOST_CHECK(strcmp("Foo", xmp_string_cstr(the_prop)) == 0); + + XmpDateTime the_dt; + the_dt.year = 2005; + the_dt.month = 12; + the_dt.day = 25; + the_dt.hour = 12; + the_dt.minute = 42; + the_dt.second = 42; + the_dt.tzSign = XMP_TZ_UTC; + the_dt.tzHour = 0; + the_dt.tzMinute = 0; + the_dt.nanoSecond = 0; + BOOST_CHECK( + xmp_set_property_date(xmp, NS_EXIF, "DateTimeOriginal", &the_dt, 0)); + BOOST_CHECK(xmp_get_error() == 0); + + BOOST_CHECK( + xmp_get_property(xmp, NS_EXIF, "DateTimeOriginal", the_prop, NULL)); + BOOST_CHECK(xmp_get_error() == 0); + BOOST_CHECK(strcmp("2005-12-25T12:42:42", xmp_string_cstr(the_prop)) == 0); + + XmpDateTime the_dt2; + BOOST_CHECK( + xmp_get_property_date(xmp, NS_EXIF, "DateTimeOriginal", &the_dt2, NULL)); + BOOST_CHECK(xmp_get_error() == 0); + + BOOST_CHECK(the_dt2.year == 2005); + BOOST_CHECK(the_dt2.minute == 42); + BOOST_CHECK(the_dt2.tzSign == XMP_TZ_UTC); + + xmp_string_free(the_prop); + + BOOST_CHECK(xmp_free(xmp)); + + free(buffer); + fclose(f); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test-xmpfiles-write.cpp b/exempi/tests/test-xmpfiles-write.cpp new file mode 100644 index 0000000..e44e242 --- /dev/null +++ b/exempi/tests/test-xmpfiles-write.cpp @@ -0,0 +1,120 @@ +/* + * exempi - test-xmpfile-write.cpp + * + * Copyright (C) 2007-2008,2010 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" + +using boost::unit_test::test_suite; + +// void test_xmpfiles_write() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "../../samples/testfiles/BlueSquare.jpg"); + + BOOST_CHECK(xmp_init()); + + BOOST_CHECK(xmp_files_check_file_format(g_testfile.c_str()) == XMP_FT_JPEG); + XmpFilePtr f = xmp_files_open_new(g_testfile.c_str(), XMP_OPEN_READ); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 1; + } + + XmpPtr xmp = xmp_files_get_new_xmp(f); + BOOST_CHECK(xmp != NULL); + + BOOST_CHECK(xmp_files_free(f)); + + BOOST_CHECK(copy_file(g_testfile, "test.jpg")); + BOOST_CHECK(chmod("test.jpg", S_IRUSR | S_IWUSR) == 0); + + BOOST_CHECK(xmp_files_check_file_format("test.jpg") == XMP_FT_JPEG); + + f = xmp_files_open_new("test.jpg", XMP_OPEN_FORUPDATE); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 2; + } + + BOOST_CHECK(xmp_set_property(xmp, NS_PHOTOSHOP, "ICCProfile", "foo", 0)); + + BOOST_CHECK(xmp_files_can_put_xmp(f, xmp)); + BOOST_CHECK(xmp_files_put_xmp(f, xmp)); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_SAFEUPDATE)); + BOOST_CHECK(xmp_files_free(f)); + + f = xmp_files_open_new("test.jpg", XMP_OPEN_READ); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + return 3; + } + xmp = xmp_files_get_new_xmp(f); + BOOST_CHECK(xmp != NULL); + + XmpStringPtr the_prop = xmp_string_new(); + BOOST_CHECK( + xmp_get_property(xmp, NS_PHOTOSHOP, "ICCProfile", the_prop, NULL)); + BOOST_CHECK(strcmp("foo", xmp_string_cstr(the_prop)) == 0); + + xmp_string_free(the_prop); + + BOOST_CHECK(xmp_free(xmp)); + BOOST_CHECK(xmp_files_close(f, XMP_CLOSE_NOOPTION)); + BOOST_CHECK(xmp_files_free(f)); + + // unlink("test.jpg"); + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + + return 0; +} diff --git a/exempi/tests/test-xmpfiles.cpp b/exempi/tests/test-xmpfiles.cpp new file mode 100644 index 0000000..9a2bfca --- /dev/null +++ b/exempi/tests/test-xmpfiles.cpp @@ -0,0 +1,129 @@ +/* + * exempi - test-xmpfiles.cpp + * + * Copyright (C) 2007-2016 Hubert Figuière + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" + +using boost::unit_test::test_suite; + +// void test_xmpfiles() +int test_main(int argc, char* argv[]) +{ + prepare_test(argc, argv, "../../samples/testfiles/BlueSquare.jpg"); + + BOOST_CHECK(xmp_init()); + + XmpFilePtr f = xmp_files_open_new(g_testfile.c_str(), XMP_OPEN_READ); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + exit(128); + } + + BOOST_CHECK(xmp_files_check_file_format(g_testfile.c_str()) == XMP_FT_JPEG); + + XmpStringPtr file_path = xmp_string_new(); + XmpOpenFileOptions options; + XmpFileType file_format; + XmpFileFormatOptions handler_flags; + BOOST_CHECK(xmp_files_get_file_info(f, file_path, &options, &file_format, + &handler_flags)); + BOOST_CHECK(options == XMP_OPEN_READ); + BOOST_CHECK(file_format == XMP_FT_JPEG); + // the value check might break at each SDK update. You have been warned. + BOOST_CHECK(handler_flags == 0x27f); + BOOST_CHECK(g_testfile == xmp_string_cstr(file_path)); + xmp_string_free(file_path); + + XmpPtr xmp = xmp_new_empty(); + + BOOST_CHECK(xmp != NULL); + + BOOST_CHECK(xmp_files_get_xmp(f, xmp)); + + { + XmpStringPtr thestring = xmp_string_new(); + XmpPacketInfo packet_info; + BOOST_CHECK(xmp_files_get_xmp_xmpstring(f, thestring, &packet_info)); + BOOST_CHECK(packet_info.offset == 2189); + BOOST_CHECK(packet_info.length == 4782); + BOOST_CHECK(packet_info.padSize == 2049); + BOOST_CHECK(packet_info.hasWrapper); + + const char *xmp_str = xmp_string_cstr(thestring); + BOOST_CHECK(xmp_str); + xmp_string_free(thestring); + } + + XmpStringPtr the_prop = xmp_string_new(); + + BOOST_CHECK( + xmp_get_property(xmp, NS_PHOTOSHOP, "ICCProfile", the_prop, NULL)); + BOOST_CHECK(strcmp("sRGB IEC61966-2.1", xmp_string_cstr(the_prop)) == 0); + + xmp_string_free(the_prop); + BOOST_CHECK(xmp_free(xmp)); + + BOOST_CHECK(xmp_files_free(f)); + + XmpFileFormatOptions formatOptions; + + // the value check might break at each SDK update. You have been warned. + BOOST_CHECK(xmp_files_get_format_info(XMP_FT_JPEG, &formatOptions)); + BOOST_CHECK(formatOptions == 0x27f); + BOOST_CHECK(xmp_files_get_format_info(XMP_FT_GIF, &formatOptions)); + BOOST_CHECK(formatOptions == 0x46b); + BOOST_CHECK(xmp_files_get_format_info(XMP_FT_PNG, &formatOptions)); + BOOST_CHECK(formatOptions == 0x46b); + // PDF doesn't have a smart handler. + BOOST_CHECK(!xmp_files_get_format_info(XMP_FT_PDF, &formatOptions)); + + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/test1.xmp b/exempi/tests/test1.xmp new file mode 100644 index 0000000..281f936 --- /dev/null +++ b/exempi/tests/test1.xmp @@ -0,0 +1,255 @@ +<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Public XMP Toolkit Core 3.5"> + <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="" + xmlns:tiff="http://ns.adobe.com/tiff/1.0/"> + <tiff:Make>Canon</tiff:Make> + <tiff:Model>Canon EOS 20D</tiff:Model> + <tiff:Orientation>1</tiff:Orientation> + <tiff:ImageWidth>3504</tiff:ImageWidth> + <tiff:ImageLength>2336</tiff:ImageLength> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:exif="http://ns.adobe.com/exif/1.0/"> + <exif:ExifVersion>0221</exif:ExifVersion> + <exif:ExposureTime>15/1</exif:ExposureTime> + <exif:ShutterSpeedValue>-3906891/1000000</exif:ShutterSpeedValue> + <exif:FNumber>8/1</exif:FNumber> + <exif:ApertureValue>6/1</exif:ApertureValue> + <exif:ExposureProgram>1</exif:ExposureProgram> + <exif:DateTimeOriginal>2006-12-07T23:20:43-05:00</exif:DateTimeOriginal> + <exif:DateTimeDigitized>2006-12-07T23:20:43-05:00</exif:DateTimeDigitized> + <exif:ExposureBiasValue>0/2</exif:ExposureBiasValue> + <exif:MaxApertureValue>3625/1000</exif:MaxApertureValue> + <exif:MeteringMode>5</exif:MeteringMode> + <exif:FocalLength>32/1</exif:FocalLength> + <exif:CustomRendered>0</exif:CustomRendered> + <exif:ExposureMode>1</exif:ExposureMode> + <exif:WhiteBalance>0</exif:WhiteBalance> + <exif:SceneCaptureType>0</exif:SceneCaptureType> + <exif:FocalPlaneXResolution>3504000/885</exif:FocalPlaneXResolution> + <exif:FocalPlaneYResolution>2336000/590</exif:FocalPlaneYResolution> + <exif:FocalPlaneResolutionUnit>2</exif:FocalPlaneResolutionUnit> + <exif:ISOSpeedRatings> + <rdf:Seq> + <rdf:li>100</rdf:li> + </rdf:Seq> + </exif:ISOSpeedRatings> + <exif:Flash rdf:parseType="Resource"> + <exif:Fired>False</exif:Fired> + <exif:Return>0</exif:Return> + <exif:Mode>2</exif:Mode> + <exif:Function>False</exif:Function> + <exif:RedEyeMode>False</exif:RedEyeMode> + </exif:Flash> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:xap="http://ns.adobe.com/xap/1.0/"> + <xap:ModifyDate>2006-12-07T23:20:43-05:00</xap:ModifyDate> + <xap:Rating>3</xap:Rating> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <dc:creator> + <rdf:Seq> + <rdf:li>unknown</rdf:li> + </rdf:Seq> + </dc:creator> + <dc:rights> + <rdf:Alt> + <rdf:li xml:lang="x-default">2006, Hubert Figuiere</rdf:li> + </rdf:Alt> + </dc:rights> + <dc:subject> + <rdf:Bag> + <rdf:li>night</rdf:li> + <rdf:li>ontario</rdf:li> + <rdf:li>ottawa</rdf:li> + <rdf:li>parliament of canada</rdf:li> + </rdf:Bag> + </dc:subject> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"> + <aux:SerialNumber>420103070</aux:SerialNumber> + <aux:LensInfo>24/1 85/1 0/0 0/0</aux:LensInfo> + <aux:Lens>24.0-85.0 mm</aux:Lens> + <aux:ImageNumber>176</aux:ImageNumber> + <aux:FlashCompensation>-2/1</aux:FlashCompensation> + <aux:OwnerName>unknown</aux:OwnerName> + <aux:Firmware>1.1.0</aux:Firmware> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"> + <crs:AlreadyApplied>False</crs:AlreadyApplied> + <crs:WhiteBalance>As Shot</crs:WhiteBalance> + <crs:Exposure>0.00</crs:Exposure> + <crs:Shadows>5</crs:Shadows> + <crs:Brightness>+50</crs:Brightness> + <crs:Contrast>+25</crs:Contrast> + <crs:Saturation>0</crs:Saturation> + <crs:Sharpness>25</crs:Sharpness> + <crs:LuminanceSmoothing>0</crs:LuminanceSmoothing> + <crs:ColorNoiseReduction>25</crs:ColorNoiseReduction> + <crs:ChromaticAberrationR>0</crs:ChromaticAberrationR> + <crs:ChromaticAberrationB>0</crs:ChromaticAberrationB> + <crs:VignetteAmount>0</crs:VignetteAmount> + <crs:ShadowTint>0</crs:ShadowTint> + <crs:RedHue>0</crs:RedHue> + <crs:RedSaturation>0</crs:RedSaturation> + <crs:GreenHue>0</crs:GreenHue> + <crs:GreenSaturation>0</crs:GreenSaturation> + <crs:BlueHue>0</crs:BlueHue> + <crs:BlueSaturation>0</crs:BlueSaturation> + <crs:FillLight>0</crs:FillLight> + <crs:Vibrance>0</crs:Vibrance> + <crs:HighlightRecovery>0</crs:HighlightRecovery> + <crs:Clarity>0</crs:Clarity> + <crs:Defringe>0</crs:Defringe> + <crs:HueAdjustmentRed>0</crs:HueAdjustmentRed> + <crs:HueAdjustmentOrange>0</crs:HueAdjustmentOrange> + <crs:HueAdjustmentYellow>0</crs:HueAdjustmentYellow> + <crs:HueAdjustmentGreen>0</crs:HueAdjustmentGreen> + <crs:HueAdjustmentAqua>0</crs:HueAdjustmentAqua> + <crs:HueAdjustmentBlue>0</crs:HueAdjustmentBlue> + <crs:HueAdjustmentPurple>0</crs:HueAdjustmentPurple> + <crs:HueAdjustmentMagenta>0</crs:HueAdjustmentMagenta> + <crs:SaturationAdjustmentRed>0</crs:SaturationAdjustmentRed> + <crs:SaturationAdjustmentOrange>0</crs:SaturationAdjustmentOrange> + <crs:SaturationAdjustmentYellow>0</crs:SaturationAdjustmentYellow> + <crs:SaturationAdjustmentGreen>0</crs:SaturationAdjustmentGreen> + <crs:SaturationAdjustmentAqua>0</crs:SaturationAdjustmentAqua> + <crs:SaturationAdjustmentBlue>0</crs:SaturationAdjustmentBlue> + <crs:SaturationAdjustmentPurple>0</crs:SaturationAdjustmentPurple> + <crs:SaturationAdjustmentMagenta>0</crs:SaturationAdjustmentMagenta> + <crs:LuminanceAdjustmentRed>0</crs:LuminanceAdjustmentRed> + <crs:LuminanceAdjustmentOrange>0</crs:LuminanceAdjustmentOrange> + <crs:LuminanceAdjustmentYellow>0</crs:LuminanceAdjustmentYellow> + <crs:LuminanceAdjustmentGreen>0</crs:LuminanceAdjustmentGreen> + <crs:LuminanceAdjustmentAqua>0</crs:LuminanceAdjustmentAqua> + <crs:LuminanceAdjustmentBlue>0</crs:LuminanceAdjustmentBlue> + <crs:LuminanceAdjustmentPurple>0</crs:LuminanceAdjustmentPurple> + <crs:LuminanceAdjustmentMagenta>0</crs:LuminanceAdjustmentMagenta> + <crs:SplitToningShadowHue>0</crs:SplitToningShadowHue> + <crs:SplitToningShadowSaturation>0</crs:SplitToningShadowSaturation> + <crs:SplitToningHighlightHue>0</crs:SplitToningHighlightHue> + <crs:SplitToningHighlightSaturation>0</crs:SplitToningHighlightSaturation> + <crs:SplitToningBalance>0</crs:SplitToningBalance> + <crs:ParametricShadows>0</crs:ParametricShadows> + <crs:ParametricDarks>0</crs:ParametricDarks> + <crs:ParametricLights>0</crs:ParametricLights> + <crs:ParametricHighlights>0</crs:ParametricHighlights> + <crs:ParametricShadowSplit>25</crs:ParametricShadowSplit> + <crs:ParametricMidtoneSplit>50</crs:ParametricMidtoneSplit> + <crs:ParametricHighlightSplit>75</crs:ParametricHighlightSplit> + <crs:SharpenRadius>+1.0</crs:SharpenRadius> + <crs:SharpenDetail>25</crs:SharpenDetail> + <crs:SharpenEdgeMasking>0</crs:SharpenEdgeMasking> + <crs:ConvertToGrayscale>False</crs:ConvertToGrayscale> + <crs:ToneCurveName>Medium Contrast</crs:ToneCurveName> + <crs:ToneCurve> + <rdf:Seq> + <rdf:li>0, 0</rdf:li> + <rdf:li>32, 22</rdf:li> + <rdf:li>64, 56</rdf:li> + <rdf:li>128, 128</rdf:li> + <rdf:li>192, 196</rdf:li> + <rdf:li>255, 255</rdf:li> + </rdf:Seq> + </crs:ToneCurve> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:crx="http://ns.adobe.com/lightroom-settings-experimental/1.0/"> + <crx:ConvertToGrayscale>false</crx:ConvertToGrayscale> + <crx:SplitToningHighlightHue>0</crx:SplitToningHighlightHue> + <crx:Sharpness>25</crx:Sharpness> + <crx:CropBottom>1</crx:CropBottom> + <crx:GreenSaturation>0</crx:GreenSaturation> + <crx:Exposure>0</crx:Exposure> + <crx:LuminanceAdjustmentGreens>0</crx:LuminanceAdjustmentGreens> + <crx:SplitToningShadowHue>0</crx:SplitToningShadowHue> + <crx:BlueHue>0</crx:BlueHue> + <crx:GreenHue>0</crx:GreenHue> + <crx:FillLight>0</crx:FillLight> + <crx:HueAdjustmentCyans>0</crx:HueAdjustmentCyans> + <crx:SaturationAdjustmentGreens>0</crx:SaturationAdjustmentGreens> + <crx:Saturation>0</crx:Saturation> + <crx:SaturationAdjustmentBlues>0</crx:SaturationAdjustmentBlues> + <crx:VignetteMidpoint>50</crx:VignetteMidpoint> + <crx:ToneHighlightSplit>75</crx:ToneHighlightSplit> + <crx:ToneShadowSplit>25</crx:ToneShadowSplit> + <crx:Contrast>25</crx:Contrast> + <crx:WhiteBalance>As Shot</crx:WhiteBalance> + <crx:HueAdjustmentMagentas>0</crx:HueAdjustmentMagentas> + <crx:HighlightRecovery>0</crx:HighlightRecovery> + <crx:SaturationAdjustmentCyans>0</crx:SaturationAdjustmentCyans> + <crx:GrayMixerYellows>100</crx:GrayMixerYellows> + <crx:HueAdjustmentGreens>0</crx:HueAdjustmentGreens> + <crx:ToneShadows>0</crx:ToneShadows> + <crx:GrayMixerGreens>71</crx:GrayMixerGreens> + <crx:GrayMixerBlues>0</crx:GrayMixerBlues> + <crx:ColorNoiseReduction>25</crx:ColorNoiseReduction> + <crx:ShadowTint>0</crx:ShadowTint> + <crx:Shadows>5</crx:Shadows> + <crx:RedHue>0</crx:RedHue> + <crx:Brightness>50</crx:Brightness> + <crx:BlueSaturation>0</crx:BlueSaturation> + <crx:CropTop>0</crx:CropTop> + <crx:SaturationAdjustmentMagentas>0</crx:SaturationAdjustmentMagentas> + <crx:GrayMixerReds>29</crx:GrayMixerReds> + <crx:AutoBrightness>false</crx:AutoBrightness> + <crx:AutoTonality>false</crx:AutoTonality> + <crx:AutoExposure>false</crx:AutoExposure> + <crx:RedSaturation>0</crx:RedSaturation> + <crx:LuminanceAdjustmentMagentas>0</crx:LuminanceAdjustmentMagentas> + <crx:LuminanceAdjustmentBlues>0</crx:LuminanceAdjustmentBlues> + <crx:HueAdjustmentBlues>0</crx:HueAdjustmentBlues> + <crx:SaturationAdjustmentReds>0</crx:SaturationAdjustmentReds> + <crx:LuminanceAdjustmentYellows>0</crx:LuminanceAdjustmentYellows> + <crx:SplitToningShadowSaturation>0</crx:SplitToningShadowSaturation> + <crx:ChromaticAberrationR>0</crx:ChromaticAberrationR> + <crx:LuminanceAdjustmentCyans>0</crx:LuminanceAdjustmentCyans> + <crx:CropAngle>0</crx:CropAngle> + <crx:ChromaticAberrationB>0</crx:ChromaticAberrationB> + <crx:AutoShadows>false</crx:AutoShadows> + <crx:CropRight>1</crx:CropRight> + <crx:ToneLights>0</crx:ToneLights> + <crx:HueAdjustmentReds>0</crx:HueAdjustmentReds> + <crx:Vibrance>0</crx:Vibrance> + <crx:ToneDarks>0</crx:ToneDarks> + <crx:GrayMixerMagentas>29</crx:GrayMixerMagentas> + <crx:LuminanceSmoothing>0</crx:LuminanceSmoothing> + <crx:SplitToningHighlightSaturation>0</crx:SplitToningHighlightSaturation> + <crx:HueAdjustmentYellows>0</crx:HueAdjustmentYellows> + <crx:GrayMixerCyans>71</crx:GrayMixerCyans> + <crx:ToneMidtoneSplit>50</crx:ToneMidtoneSplit> + <crx:VignetteAmount>0</crx:VignetteAmount> + <crx:AutoContrast>false</crx:AutoContrast> + <crx:CropLeft>0</crx:CropLeft> + <crx:ToneHighlights>0</crx:ToneHighlights> + <crx:AutoGrayscaleWeights>true</crx:AutoGrayscaleWeights> + <crx:SaturationAdjustmentYellows>0</crx:SaturationAdjustmentYellows> + <crx:LuminanceAdjustmentReds>0</crx:LuminanceAdjustmentReds> + <crx:Tint>1</crx:Tint> + <crx:Temperature>4350</crx:Temperature> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:lr="http://ns.adobe.com/lightroom/1.0/"> + <lr:hierarchicalKeywords>aGllcmFyY2hpY2FsS2V5d29yZHMgPSB7Cgl7CgkJZmxhdCA9IHsKCQkJIm5pZ2h0IiwKCQl9LAoJCXBhdGggPSB7CgkJCSJuaWdodCIsCgkJfSwKCQlwcmltYXJ5ID0gIm5pZ2h0IiwKCQl1dWlkID0gIkU1RDEwQTFELTU3QUYtMTFEQi04RTMzLTAwMEQ5MzVDODY5QSIsCgl9LAoJewoJCWZsYXQgPSB7CgkJCSJvbnRhcmlvIiwKCQkJIm90dGF3YSIsCgkJfSwKCQlwYXRoID0gewoJCQkib250YXJpbyIsCgkJCSJvdHRhd2EiLAoJCX0sCgkJcHJpbWFyeSA9ICJvdHRhd2EiLAoJCXV1aWQgPSAiQjgzMTc4RkItNTdBRi0xMURCLThFMzMtMDAwRDkzNUM4NjlBIiwKCX0sCgl7CgkJZmxhdCA9IHsKCQkJInBhcmxpYW1lbnQgb2YgY2FuYWRhIiwKCQkJIm9udGFyaW8iLAoJCQkib3R0YXdhIiwKCQl9LAoJCXBhdGggPSB7CgkJCSJvbnRhcmlvIiwKCQkJIm90dGF3YSIsCgkJCSJwYXJsaWFtZW50IG9mIGNhbmFkYSIsCgkJfSwKCQlwcmltYXJ5ID0gInBhcmxpYW1lbnQgb2YgY2FuYWRhIiwKCQl1dWlkID0gIkU1RDMzMEZDLTU3QUYtMTFEQi04RTMzLTAwMEQ5MzVDODY5QSIsCgl9LAp9Cg==</lr:hierarchicalKeywords> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"> + <xmpTPg:MaxPageSize> + <rdf:Description + xmlns:stDim="http:ns.adobe.com/xap/1.0/sType/Dimensions#"> + <stDim:w>4</stDim:w> + <stDim:h>3</stDim:h> + <stDim:unit>inches</stDim:unit> + </rdf:Description> + </xmpTPg:MaxPageSize> + </rdf:Description> + <rdf:Description rdf:about="" + xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"> + <Iptc4xmpCore:Location>Parliament Hill, Ottawa, Ontario, Canada</Iptc4xmpCore:Location> + </rdf:Description> + </rdf:RDF> +</x:xmpmeta> diff --git a/exempi/tests/test3.cpp b/exempi/tests/test3.cpp new file mode 100644 index 0000000..90f84a3 --- /dev/null +++ b/exempi/tests/test3.cpp @@ -0,0 +1,115 @@ +/* + * exempi - test3.cpp + * + * Copyright (C) 2007-2008 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> +#include <iostream> + +#include <boost/test/minimal.hpp> +#include <boost/format.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" + +using boost::unit_test::test_suite; + +// void test_exempi_iterate() +int test_main(int argc, char *argv[]) +{ + prepare_test(argc, argv, "test1.xmp"); + + size_t len; + char *buffer; + + FILE *f = fopen(g_testfile.c_str(), "rb"); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + exit(128); + } + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + buffer = (char *)malloc(len + 1); + size_t rlen = fread(buffer, 1, len, f); + + BOOST_CHECK(rlen == len); + BOOST_CHECK(len != 0); + BOOST_CHECK(xmp_init()); + + XmpPtr xmp = xmp_new_empty(); + + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + + BOOST_CHECK(xmp != NULL); + + XmpIteratorPtr iter = + xmp_iterator_new(xmp, NULL, NULL, XMP_ITER_JUSTLEAFNODES); + + XmpStringPtr the_schema = xmp_string_new(); + XmpStringPtr the_path = xmp_string_new(); + XmpStringPtr the_prop = xmp_string_new(); + uint32_t options; + + while (xmp_iterator_next(iter, the_schema, the_path, the_prop, &options)) { + std::cout << xmp_string_cstr(the_schema) << " / " + << xmp_string_cstr(the_path) << " = " + << xmp_string_cstr(the_prop); + if (options) { + std::cout << boost::format(" options = 0x%1$x") % options; + } + std::cout << std::endl; + } + + xmp_string_free(the_prop); + xmp_string_free(the_path); + xmp_string_free(the_schema); + BOOST_CHECK(xmp_iterator_free(iter)); + BOOST_CHECK(xmp_free(xmp)); + + free(buffer); + fclose(f); + xmp_terminate(); + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/testcore.sh b/exempi/tests/testcore.sh new file mode 100755 index 0000000..94c67b4 --- /dev/null +++ b/exempi/tests/testcore.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Test script. +# Currently only make sure dumpmainxmp does not crash +# Written by Hubert Figuiere <hub@figuiere.net> + +if [ -z $srcdir ] ; then + echo "$srcdir srcdir not defined." + exit 255 +fi + +SAMPLES="BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif BlueSquare.avi BlueSquare.indd BlueSquare.pdf BlueSquare.psd BlueSquare.wav" +SAMPLES_DIR=$srcdir/../../samples/testfiles +DUMPMAINXMP_PROG=../../samples/source/dumpmainxmp + +if [ ! -x $DUMPMAINXMP_PROG ] ; then + echo "$DUMPMAINXMP_PROG not executable." + exit 255 +fi + +for i in $SAMPLES +do + echo "Running $DUMPMAINXMP_PROG $SAMPLES_DIR/$i" + $VALGRIND $DUMPMAINXMP_PROG $SAMPLES_DIR/$i > /dev/null + if [ $? -ne 0 ] ; then + echo "Failed" + exit 255 + fi +done diff --git a/exempi/tests/testcpp.cpp b/exempi/tests/testcpp.cpp new file mode 100644 index 0000000..13f944f --- /dev/null +++ b/exempi/tests/testcpp.cpp @@ -0,0 +1,69 @@ +/* + * exempi - testcpp.cpp + * + * Copyright (C) 2011 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmp.h" +#include "xmpconsts.h" +#include "xmp++.hpp" + +using boost::unit_test::test_suite; + +int test_main(int argc, char* argv[]) +{ + // this test is totally useless without leak checking. + // but for compiling. + { + xmp::ScopedPtr<XmpStringPtr> ptr(xmp_string_new()); + } + + { + xmp::ScopedPtr<XmpFilePtr> ptr(xmp_files_new()); + } + + { + xmp::ScopedPtr<XmpPtr> ptr(xmp_new_empty()); + { + xmp::ScopedPtr<XmpIteratorPtr> iterptr( + xmp_iterator_new(ptr, NS_EXIF, NULL, XMP_ITER_JUSTLEAFNODES)); + } + } + + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/testinit.cpp b/exempi/tests/testinit.cpp new file mode 100644 index 0000000..0ce70aa --- /dev/null +++ b/exempi/tests/testinit.cpp @@ -0,0 +1,94 @@ +/* + * exempi - testinit.cpp + * + * Copyright (C) 2007 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +#include <boost/test/minimal.hpp> + +#include "utils.h" +#include "xmpconsts.h" +#include "xmp.h" + +// void test_exempi_init() +int test_main(int argc, char* argv[]) +{ + prepare_test(argc, argv, "test1.xmp"); + + size_t len; + char* buffer; + + FILE* f = fopen(g_testfile.c_str(), "rb"); + + BOOST_CHECK(f != NULL); + if (f == NULL) { + exit(128); + } + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + buffer = (char*)malloc(len + 1); + size_t rlen = fread(buffer, 1, len, f); + + BOOST_CHECK(rlen == len); + BOOST_CHECK(len != 0); + + BOOST_CHECK(xmp_init()); + BOOST_CHECK(xmp_init()); + + XmpPtr xmp = xmp_new_empty(); + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + BOOST_CHECK(xmp != NULL); + BOOST_CHECK(xmp_free(xmp)); + + xmp_terminate(); + + xmp = xmp_new_empty(); + BOOST_CHECK(xmp_parse(xmp, buffer, len)); + BOOST_CHECK(xmp != NULL); + BOOST_CHECK(xmp_free(xmp)); + + xmp_terminate(); + + free(buffer); + BOOST_CHECK(!g_lt->check_leaks()); + BOOST_CHECK(!g_lt->check_errors()); + return 0; +} diff --git a/exempi/tests/utils.cpp b/exempi/tests/utils.cpp new file mode 100644 index 0000000..1620597 --- /dev/null +++ b/exempi/tests/utils.cpp @@ -0,0 +1,119 @@ +/* + * exempi - utils.cpp + * + * Copyright (C) 2007-2016 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <cstdio> +#include <cstdlib> +#include <memory> + +#include <boost/test/unit_test.hpp> + +#include "utils.h" + +std::string g_testfile; +std::string g_src_testdir; +std::unique_ptr<LeakTracker> g_lt(new LeakTracker) ; + +void prepare_test(int argc, char *argv[], const char *filename) +{ + if (argc == 1) { + // no argument, lets run like we are in "check" + const char *srcdir = getenv("TEST_DIR"); + + BOOST_ASSERT(srcdir != NULL); + g_src_testdir = std::string(srcdir) + "/"; + g_testfile = g_src_testdir + filename; + } else { + g_src_testdir = "./"; + g_testfile = argv[1]; + } +} + +bool copy_file(const std::string &source, const std::string &dest) +{ + std::string command = "cp "; + command += source + " " + dest; + return (system(command.c_str()) >= 0); +} + +#ifdef HAVE_VALGRIND_MEMCHECK_H +#include <valgrind/memcheck.h> +#include <valgrind/valgrind.h> +#define CC_EXTENSION __extension__ +#else +#define VALGRIND_COUNT_ERRORS 0 +#define VALGRIND_DO_LEAK_CHECK +#define VALGRIND_COUNT_LEAKS(a, b, c, d) (a = b = c = d = 0) +#define CC_EXTENSION +#endif + +LeakTracker::LeakTracker() + : m_leaks(0), m_dubious(0), m_reachable(0), m_suppressed(0), m_errors(0) +{ +} + +LeakTracker::~LeakTracker() +{ + printf("LeakTracker: leaked = %d, errors = %d\n", m_leaks, m_errors); +} + +int LeakTracker::check_leaks() +{ + int leaked = 0; + int dubious = 0; + int reachable = 0; + int suppressed = 0; + + VALGRIND_DO_LEAK_CHECK; + VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed); + printf("memleaks: sure:%d dubious:%d reachable:%d suppress:%d\n", leaked, + dubious, reachable, suppressed); + bool has_leaks = (m_leaks != leaked); + + m_leaks = leaked; + m_dubious = dubious; + m_reachable = reachable; + m_suppressed = suppressed; + + return has_leaks; +} + +int LeakTracker::check_errors() +{ + int errors = (int)(CC_EXTENSION VALGRIND_COUNT_ERRORS); + bool has_new_errors = (m_errors != errors); + m_errors = errors; + return has_new_errors; +} diff --git a/exempi/tests/utils.h b/exempi/tests/utils.h new file mode 100644 index 0000000..a26ccd2 --- /dev/null +++ b/exempi/tests/utils.h @@ -0,0 +1,69 @@ +/* + * exempi - utils.h + * + * Copyright (C) 2007,2010 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TEST_UTILS_H__ +#define __TEST_UTILS_H__ + +#include <string> + +#include <memory> + +extern std::string g_testfile; +extern std::string g_src_testdir; + +void prepare_test(int argc, char* argv[], const char* filename); + +bool copy_file(const std::string& source, const std::string& dest); + +class LeakTracker { +public: + LeakTracker(); + ~LeakTracker(); + /** return false if there is NO leak. Will print on stdout */ + int check_leaks(); + int check_errors(); + +private: + int m_leaks; + int m_dubious; + int m_reachable; + int m_suppressed; + int m_errors; +}; + +extern std::unique_ptr<LeakTracker> g_lt; + +#endif diff --git a/exempi/xmp++.hpp b/exempi/xmp++.hpp new file mode 100644 index 0000000..15b7351 --- /dev/null +++ b/exempi/xmp++.hpp @@ -0,0 +1,61 @@ +/* + * + * Copyright (C) 2011 Hubert Figuiere + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef __XMP_PLUSPLUS_H__ +#define __XMP_PLUSPLUS_H__ + +#include <exempi/xmp.h> + +namespace xmp { + +inline void release(XmpIteratorPtr ptr) +{ + xmp_iterator_free(ptr); +} + +inline void release(XmpStringPtr ptr) +{ + xmp_string_free(ptr); +} + +inline void release(XmpFilePtr ptr) +{ + xmp_files_free(ptr); +} + +inline void release(XmpPtr ptr) +{ + xmp_free(ptr); +} + +/** + * @brief a scoped pointer for Xmp opaque types + */ +template <class T> +class ScopedPtr { +public: + ScopedPtr(T p) : _p(p) {} + ~ScopedPtr() + { + if (_p) + release(_p); + } + operator T() const { return _p; } + +private: + T _p; + + // private copy constructor and assignment + // to make the class non copiable + ScopedPtr(const ScopedPtr<T> &); + ScopedPtr &operator=(const ScopedPtr<T> &); +}; +} + +#endif diff --git a/exempi/xmp.h b/exempi/xmp.h new file mode 100644 index 0000000..c3cfea9 --- /dev/null +++ b/exempi/xmp.h @@ -0,0 +1,742 @@ +/* + * exempi - xmp.h + * + * Copyright (C) 2007-2016 Hubert Figuiere + * Copyright 2002-2007 Adobe Systems Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __EXEMPI_XMP_H_ +#define __EXEMPI_XMP_H_ + +#include <stdlib.h> +/* stdbool choke on Sun (bug #14612) */ +#if !(defined(__sun) && defined(__cplusplus)) +#include <stdbool.h> +#endif +#include <stdint.h> + +#include <time.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* enums grafted from XMP_Const.h */ + +/** Option bits for xmp_files_open() */ +typedef enum { + XMP_OPEN_NOOPTION = 0x00000000, /**< No open option */ + XMP_OPEN_READ = 0x00000001, /**< Open for read-only access. */ + XMP_OPEN_FORUPDATE = 0x00000002, /**< Open for reading and writing. */ + XMP_OPEN_ONLYXMP = 0x00000004, /**< Only the XMP is wanted, + * allows space/time optimizations. */ + XMP_OPEN_CACHETNAIL = 0x00000008, /**< Cache thumbnail if possible, + * GetThumbnail will be called. */ + XMP_OPEN_STRICTLY = 0x00000010, /**< Be strict about locating XMP + * and reconciling with other forms. */ + XMP_OPEN_USESMARTHANDLER = 0x00000020, /**< Require the use of a smart + * handler. */ + XMP_OPEN_USEPACKETSCANNING = 0x00000040, /**< Force packet scanning, + * don't use a smart handler. */ + XMP_OPEN_LIMITSCANNING = 0x00000080, /**< Only packet scan files "known" + * to need scanning. */ + XMP_OPEN_REPAIR_FILE = + 0x00000100, /**< Attempt to repair a file opened for update, + * default is to not open (throw an exception). */ + XMP_OPEN_OPTIMIZEFILELAYOUT = + 0x00000200, /**< Optimize MPEG4 to support stream when updating + * This can take some time */ + XMP_OPEN_INBACKGROUND = 0x10000000 /**< Set if calling from background + * thread. */ +} XmpOpenFileOptions; + +/** Option bits for xmp_files_close() */ +typedef enum { + XMP_CLOSE_NOOPTION = 0x0000, /**< No close option */ + XMP_CLOSE_SAFEUPDATE = 0x0001 /**< Write into a temporary file and + * swap for crash safety. */ +} XmpCloseFileOptions; + +typedef enum { + + /* Public file formats. Hex used to avoid gcc warnings. */ + /* ! Leave them as big endian. There seems to be no decent way on UNIX to + determine the target */ + /* ! endianness at compile time. Forcing it on the client isn't acceptable. + */ + + XMP_FT_PDF = 0x50444620UL, /* 'PDF ' */ + XMP_FT_PS = 0x50532020UL, /* 'PS ', general PostScript following DSC + conventions. */ + XMP_FT_EPS = 0x45505320UL, /* 'EPS ', encapsulated PostScript. */ + + XMP_FT_JPEG = 0x4A504547UL, /* 'JPEG' */ + XMP_FT_JPEG2K = 0x4A505820UL, /* 'JPX ', ISO 15444-1 */ + XMP_FT_TIFF = 0x54494646UL, /* 'TIFF' */ + XMP_FT_GIF = 0x47494620UL, /* 'GIF ' */ + XMP_FT_PNG = 0x504E4720UL, /* 'PNG ' */ + XMP_FT_WEBP = 0x57454250UL, /* 'WEBP' */ + + XMP_FT_SWF = 0x53574620UL, /* 'SWF ' */ + XMP_FT_FLA = 0x464C4120UL, /* 'FLA ' */ + XMP_FT_FLV = 0x464C5620UL, /* 'FLV ' */ + + XMP_FT_MOV = 0x4D4F5620UL, /* 'MOV ', Quicktime */ + XMP_FT_AVI = 0x41564920UL, /* 'AVI ' */ + XMP_FT_CIN = 0x43494E20UL, /* 'CIN ', Cineon */ + XMP_FT_WAV = 0x57415620UL, /* 'WAV ' */ + XMP_FT_MP3 = 0x4D503320UL, /* 'MP3 ' */ + XMP_FT_SES = 0x53455320UL, /* 'SES ', Audition session */ + XMP_FT_CEL = 0x43454C20UL, /* 'CEL ', Audition loop */ + XMP_FT_MPEG = 0x4D504547UL, /* 'MPEG' */ + XMP_FT_MPEG2 = 0x4D503220UL, /* 'MP2 ' */ + XMP_FT_MPEG4 = 0x4D503420UL, /* 'MP4 ', ISO 14494-12 and -14 */ + XMP_FT_WMAV = 0x574D4156UL, /* 'WMAV', Windows Media Audio and Video */ + XMP_FT_AIFF = 0x41494646UL, /* 'AIFF' */ + + XMP_FT_HTML = 0x48544D4CUL, /* 'HTML' */ + XMP_FT_XML = 0x584D4C20UL, /* 'XML ' */ + XMP_FT_TEXT = 0x74657874UL, /* 'text' */ + + /* Adobe application file formats. */ + XMP_FT_PHOTOSHOP = 0x50534420UL, /* 'PSD ' */ + XMP_FT_ILLUSTRATOR = 0x41492020UL, /* 'AI ' */ + XMP_FT_INDESIGN = 0x494E4444UL, /* 'INDD' */ + XMP_FT_AEPROJECT = 0x41455020UL, /* 'AEP ' */ + XMP_FT_AEPROJTEMPLATE = + 0x41455420UL, /* 'AET ', After Effects Project Template */ + XMP_FT_AEFILTERPRESET = 0x46465820UL, /* 'FFX ' */ + XMP_FT_ENCOREPROJECT = 0x4E434F52UL, /* 'NCOR' */ + XMP_FT_PREMIEREPROJECT = 0x5052504AUL, /* 'PRPJ' */ + XMP_FT_PREMIERETITLE = 0x5052544CUL, /* 'PRTL' */ + + /* Catch all. */ + XMP_FT_UNKNOWN = 0x20202020UL /* ' ' */ +} XmpFileType; + +typedef enum { + + XMP_FMT_CAN_INJECT_XMP = 0x00000001, + XMP_FMT_CAN_EXPAND = 0x00000002, + XMP_FMT_CAN_REWRITE = 0x00000004, + XMP_FMT_PREFERS_IN_PLACE = 0x00000008, + XMP_FMT_CAN_RECONCILE = 0x00000010, + XMP_FMT_ALLOWS_ONLY_XMP = 0x00000020, + XMP_FMT_RETURNS_RAW_PACKET = 0x00000040, + XMP_FMT_HANDLER_OWNS_FILE = 0x00000100, + XMP_FMT_ALLOW_SAFE_UPDATE = 0x00000200, + XMP_FMT_NEEDS_READONLY_PACKET = 0x00000400, + XMP_FMT_USE_SIDECAR_XMP = 0x00000800, + XMP_FMT_FOLDER_BASED_FORMAT = 0x00001000, + + _XMP_FMT_LAST +} XmpFileFormatOptions; + +typedef enum { + XMP_ITER_CLASSMASK = 0x00FFUL, /**< The low 8 bits are an enum of + * what data structure to iterate. */ + XMP_ITER_PROPERTIES = 0x0000UL, /**< Iterate the property tree of + * a TXMPMeta object. */ + XMP_ITER_ALIASES = 0x0001UL, /**< Iterate the global alias table. */ + XMP_ITER_NAMESPACES = 0x0002UL, /**< Iterate the global namespace table. */ + XMP_ITER_JUSTCHILDREN = 0x0100UL, /**< Just do the immediate children + * of the root, default is subtree. */ + XMP_ITER_JUSTLEAFNODES = 0x0200UL, /**< Just do the leaf nodes, default + * is all nodes in the subtree. */ + XMP_ITER_JUSTLEAFNAME = 0x0400UL, /**< Return just the leaf part of the + * path, default is the full path. */ + XMP_ITER_INCLUDEALIASES = 0x0800UL, /**< Include aliases, default is just + * actual properties. */ + XMP_ITER_OMITQUALIFIERS = 0x1000UL /* Omit all qualifiers. */ +} XmpIterOptions; + +typedef enum { + XMP_ITER_SKIPSUBTREE = 0x0001UL, /**< Skip the subtree below the + * current node. */ + XMP_ITER_SKIPSIBLINGS = + 0x0002UL /**< Skip the subtree below and remaining + * siblings of the current + * node. */ +} XmpIterSkipOptions; + +typedef enum { + /** Options relating to the XML string form of the property value. */ + XMP_PROP_VALUE_IS_URI = 0x00000002UL, /**< The value is a URI, use + * rdf:resource attribute. + * DISCOURAGED */ + /** Options relating to qualifiers attached to a property. */ + XMP_PROP_HAS_QUALIFIERS = 0x00000010UL, /**< The property has qualifiers, + * includes rdf:type and + * xml:lang. */ + XMP_PROP_IS_QUALIFIER = 0x00000020UL, /**< This is a qualifier, + * includes rdf:type and + * xml:lang. */ + XMP_PROP_HAS_LANG = 0x00000040UL, /**< Implies XMP_PropHasQualifiers, + * property has xml:lang. */ + XMP_PROP_HAS_TYPE = 0x00000080UL, /**< Implies XMP_PropHasQualifiers, + * property has rdf:type. */ + + /* Options relating to the data structure form. */ + XMP_PROP_VALUE_IS_STRUCT = 0x00000100UL, /**< The value is a structure + * with nested fields. */ + XMP_PROP_VALUE_IS_ARRAY = 0x00000200UL, /**< The value is an array + * (RDF alt/bag/seq). */ + XMP_PROP_ARRAY_IS_UNORDERED = XMP_PROP_VALUE_IS_ARRAY, /**< The item order + * does not matter.*/ + XMP_PROP_ARRAY_IS_ORDERED = 0x00000400UL, /**< Implies XMP_PropValueIsArray, + * item order matters. */ + XMP_PROP_ARRAY_IS_ALT = 0x00000800UL, /**< Implies XMP_PropArrayIsOrdered, + * items are alternates. */ + + /** Additional struct and array options. */ + XMP_PROP_ARRAY_IS_ALTTEXT = + 0x00001000UL, /**< Implies kXMP_PropArrayIsAlternate, + * items are localized text. */ + XMP_PROP_ARRAY_INSERT_BEFORE = + 0x00004000UL, /**< Used by array functions. */ + XMP_PROP_ARRAY_INSERT_AFTER = 0x00008000UL, /**< Used by array functions. */ + + /* Other miscellaneous options. */ + XMP_PROP_IS_ALIAS = 0x00010000UL, /**< This property is an alias name for + another property. */ + XMP_PROP_HAS_ALIASES = 0x00020000UL, /**< This property is the base value + for a set of aliases. */ + XMP_PROP_IS_INTERNAL = 0x00040000UL, /**< This property is an "internal" + property, owned by applications. */ + XMP_PROP_IS_STABLE = 0x00100000UL, /**< This property is not derived from + * the document content. + */ + XMP_PROP_IS_DERIVED = 0x00200000UL, /**< This property is derived from the + document content. */ + /* kXMPUtil_AllowCommas = 0x10000000UL, ! Used by + TXMPUtils::CatenateArrayItems and ::SeparateArrayItems. */ + /* kXMP_DeleteExisting = 0x20000000UL, ! Used by TXMPMeta::SetXyz + functions to delete any pre-existing property. */ + /* kXMP_SchemaNode = 0x80000000UL, ! Returned by iterators - #define + to avoid warnings */ + + /* Masks that are multiple flags. */ + XMP_PROP_ARRAY_FORM_MASK = XMP_PROP_VALUE_IS_ARRAY | + XMP_PROP_ARRAY_IS_ORDERED | + XMP_PROP_ARRAY_IS_ALT | + XMP_PROP_ARRAY_IS_ALTTEXT, + XMP_PROP_COMPOSITE_MASK = XMP_PROP_VALUE_IS_STRUCT | + XMP_PROP_ARRAY_FORM_MASK, /* Is it simple or + composite (array or + struct)? */ + XMP_IMPL_RESERVED_MASK = + 0x70000000L /**< Reserved for transient use by the implementation. */ +} XmpPropsBits; + +/* convenience macros */ + +/** set option bits */ +#define XMP_SET_OPTION(var, opt) var |= (opt) +/** clear option bits */ +#define XMP_CLEAR_OPTION(var, opt) var &= ~(opt) +/** test if option is set */ +#define XMP_TEST_OPTION_SET(var, opt) (((var) & (opt)) != 0) +/** test if option is clear */ +#define XMP_TEST_OPTION_CLEAR(var, opt) (((var) & (opt)) == 0) + +#define XMP_IS_PROP_SIMPLE(opt) (((opt)&XMP_PROP_COMPOSITE_MASK) == 0) +#define XMP_IS_PROP_STRUCT(opt) (((opt)&XMP_PROP_VALUE_IS_STRUCT) != 0) +#define XMP_IS_PROP_ARRAY(opt) (((opt)&XMP_PROP_VALUE_IS_ARRAY) != 0) +#define XMP_IS_ARRAY_UNORDERED(opt) (((opt)&XMP_PROP_ARRAY_IS_ORDERED) == 0) +#define XMP_IS_ARRAY_ORDERED(opt) (((opt)&XMP_PROP_ARRAY_IS_ORDERED) != 0) +#define XMP_IS_ARRAY_ALT(opt) (((opt)&XMP_PROP_ARRAY_IS_ALT) != 0) +#define XMP_IS_ARRAY_ALTTEXT(opt) (((opt)&XMP_PROP_ARRAY_IS_ALTTEXT) != 0) + +#define XMP_HAS_PROP_QUALIFIERS(opt) (((opt)&XMP_PROP_HAS_QUALIFIERS) != 0) +#define XMP_IS_PROP_QUALIFIER(opt) (((opt)&XMP_PROP_IS_QUALIFIER) != 0) +#define XMP_HAS_PROP_LANG(opt) (((opt)&XMP_PROP_HAS_LANG) != 0) + +#define XMP_IS_NODE_SCHEMA(opt) (((opt)&XMP_SCHEMA_NODE) != 0) +#define XMP_IS_PROP_ALIAS(opt) (((opt)&XMP_PROP_IS_ALIAS) != 0) + +enum { /* Options for xmp_serialize */ + XMP_SERIAL_OMITPACKETWRAPPER = 0x0010UL, /**< Omit the XML packet + * wrapper. */ + XMP_SERIAL_READONLYPACKET = 0x0020UL, /**< Default is a writeable + * packet. */ + XMP_SERIAL_USECOMPACTFORMAT = 0x0040UL, /**< Use a compact form of + * RDF. */ + + XMP_SERIAL_INCLUDETHUMBNAILPAD = + 0x0100UL, /**< Include a padding allowance + * for a thumbnail image. */ + XMP_SERIAL_EXACTPACKETLENGTH = 0x0200UL, /**< The padding parameter is + * the overall packet length. */ + XMP_SERIAL_WRITEALIASCOMMENTS = 0x0400UL, /**< Show aliases as XML + * comments. */ + XMP_SERIAL_OMITALLFORMATTING = 0x0800UL, /**< Omit all formatting + * whitespace. */ + + _XMP_LITTLEENDIAN_BIT = + 0x0001UL, /* ! Don't use directly, see the combined values below! */ + _XMP_UTF16_BIT = 0x0002UL, + _XMP_UTF32_BIT = 0x0004UL, + + XMP_SERIAL_ENCODINGMASK = 0x0007UL, + XMP_SERIAL_ENCODEUTF8 = 0UL, + XMP_SERIAL_ENCODEUTF16BIG = _XMP_UTF16_BIT, + XMP_SERIAL_ENCODEUTF16LITTLE = _XMP_UTF16_BIT | _XMP_LITTLEENDIAN_BIT, + XMP_SERIAL_ENCODEUTF32BIG = _XMP_UTF32_BIT, + XMP_SERIAL_ENCODEUTF32LITTLE = _XMP_UTF32_BIT | _XMP_LITTLEENDIAN_BIT +}; + +/** pointer to XMP packet. Opaque. */ +typedef struct _Xmp *XmpPtr; +typedef struct _XmpFile *XmpFilePtr; +typedef struct _XmpString *XmpStringPtr; +typedef struct _XmpIterator *XmpIteratorPtr; + +typedef struct _XmpDateTime { + int32_t year; + int32_t month; /* 1..12 */ + int32_t day; /* 1..31 */ + int32_t hour; /* 0..23 */ + int32_t minute; /* 0..59 */ + int32_t second; /* 0..59 */ + int32_t tzSign; /* -1..+1, 0 means UTC, -1 is west, +1 is east. */ + int32_t tzHour; /* 0..23 */ + int32_t tzMinute; /* 0..59 */ + int32_t nanoSecond; +} XmpDateTime; + +typedef struct _XmpPacketInfo { + /// Packet offset in the file in bytes, -1 if unknown. + int64_t offset; + /// Packet length in the file in bytes, -1 if unknown. + int32_t length; + /// Packet padding size in bytes, zero if unknown. + int32_t padSize; + + /// Character format using the values \c kXMP_Char8Bit, + /// \c kXMP_Char16BitBig, etc. + uint8_t charForm; + /// True if there is a packet wrapper and the trailer says writeable + /// by dumb packet scanners. + bool writeable; + /// True if there is a packet wrapper, the "<?xpacket...>" + /// XML processing instructions. + bool hasWrapper; + + /// Padding to make the struct's size be a multiple 4. + uint8_t pad; +} XmpPacketInfo; + +/** Values used for tzSign field. */ +enum { + XMP_TZ_WEST = -1, /**< West of UTC */ + XMP_TZ_UTC = 0, /**< UTC */ + XMP_TZ_EAST = +1 /**< East of UTC */ +}; + +/** Init the library. Must be called before anything else */ +bool xmp_init(void); +void xmp_terminate(void); + +/** get the error code that last occurred. + * @todo make this thread-safe. Getting the error code + * from another thread than the on it occurred in is undefined. + */ +int xmp_get_error(void); + +XmpFilePtr xmp_files_new(void); +XmpFilePtr xmp_files_open_new(const char *, XmpOpenFileOptions options); + +bool xmp_files_open(XmpFilePtr xf, const char *, XmpOpenFileOptions options); + +/** Close an XMP file. Will flush the changes + * @param xf the file object + * @param options the options to close. + * @return true on succes, false on error + * xmp_get_error() will give the error code. + */ +bool xmp_files_close(XmpFilePtr xf, XmpCloseFileOptions options); + +/** Get the XMP packet from the file + * @param xf the %XmpFilePtr to get the XMP packet from + * @return a newly allocated XmpPtr. Use %xmp_free to release it. + */ +XmpPtr xmp_files_get_new_xmp(XmpFilePtr xf); + +/** File the XMP packet from the file + * @param xf the %XmpFilePtr to get the XMP packet from + * @param xmp the XMP Packet to fill. Must be valid. + */ +bool xmp_files_get_xmp(XmpFilePtr xf, XmpPtr xmp); +bool xmp_files_get_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet, + XmpPacketInfo* packet_info); + +bool xmp_files_can_put_xmp(XmpFilePtr xf, XmpPtr xmp); +bool xmp_files_can_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet); +bool xmp_files_can_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet, + size_t len); + +bool xmp_files_put_xmp(XmpFilePtr xf, XmpPtr xmp); +bool xmp_files_put_xmp_xmpstring(XmpFilePtr xf, XmpStringPtr xmp_packet); +bool xmp_files_put_xmp_cstr(XmpFilePtr xf, const char* xmp_packet, size_t len); + +/** Get the file info from the open file + * @param xf the file object + * @param[out] filePath the file path object to store the path in. Pass NULL if + * not needed. + * @param[out] options the options for open. Pass NULL if not needed. + * @param[out] file_format the detected file format. Pass NULL if not needed. + * @param[out] handler_flags the format options like from + * %xmp_files_get_format_info. + * @return false in case of error. + */ +bool xmp_files_get_file_info(XmpFilePtr xf, XmpStringPtr filePath, + XmpOpenFileOptions *options, + XmpFileType *file_format, + XmpFileFormatOptions *handler_flags); + +/** Free a XmpFilePtr + * @param xf the file ptr. Cannot be NULL + * @return false on error. + * Calll %xmp_get_error to retrieve the error code. + */ +bool xmp_files_free(XmpFilePtr xf); + +/** Get the format info + * @param format type identifier + * @param options the options for the file format handler + * @return false on error + */ +bool xmp_files_get_format_info(XmpFileType format, + XmpFileFormatOptions *options); + +/** Check the file format of a file. Use the same logic as in xmp_files_open() + * @param filePath the path to the file + * @return XMP_FT_UNKNOWN on error or if the file type is unknown + */ +XmpFileType xmp_files_check_file_format(const char *filePath); + +/** Register a new namespace to add properties to + * This is done automatically when reading the metadata block + * @param namespaceURI the namespace URI to register + * @param suggestedPrefix the suggested prefix + * @param registeredPrefix the really registered prefix. Not necessarily + * %suggestedPrefix. + * @return true if success, false otherwise. + */ +bool xmp_register_namespace(const char *namespaceURI, + const char *suggestedPrefix, + XmpStringPtr registeredPrefix); + +/** Check is a namespace is registered + * @param ns the namespace to check. + * @param prefix The prefix associated if registered. Pass NULL + * if not interested. + * @return true if registered. + * NEW in 2.1 + */ +bool xmp_namespace_prefix(const char *ns, XmpStringPtr prefix); + +/** Check if a ns prefix is registered. + * @param prefix the prefix to check. + * @param ns the namespace associated if registered. Pass NULL + * if not interested. + * @return true if registered. + * NEW in 2.1 + */ +bool xmp_prefix_namespace_uri(const char *prefix, XmpStringPtr ns); + +/** Create a new empty XMP packet + * @return the packet pointer. Must be free with xmp_free() + */ +XmpPtr xmp_new_empty(void); + +/** Create a new XMP packet + * @param buffer the buffer to load data from. UTF-8 encoded. + * @param len the buffer length in byte + * @return the packet pointer. Must be free with xmp_free() + */ +XmpPtr xmp_new(const char *buffer, size_t len); + +/** Create a new XMP packet from the one passed. + * @param xmp the instance to copy. Can be NULL. + * @return the packet pointer. NULL is failer (or NULL is passed). + */ +XmpPtr xmp_copy(XmpPtr xmp); + +/** Free the xmp packet + * @param xmp the xmp packet to free + */ +bool xmp_free(XmpPtr xmp); + +/** Parse the XML passed through the buffer and load it. + * @param xmp the XMP packet. + * @param buffer the buffer. + * @param len the length of the buffer. + */ +bool xmp_parse(XmpPtr xmp, const char *buffer, size_t len); + +/** Serialize the XMP Packet to the given buffer + * @param xmp the XMP Packet + * @param buffer the buffer to write the XMP to + * @param options options on how to write the XMP. See XMP_SERIAL_* + * @param padding number of bytes of padding, useful for modifying + * embedded XMP in place. + * @return TRUE if success. + */ +bool xmp_serialize(XmpPtr xmp, XmpStringPtr buffer, uint32_t options, + uint32_t padding); + +/** Serialize the XMP Packet to the given buffer with formatting + * @param xmp the XMP Packet + * @param buffer the buffer to write the XMP to + * @param options options on how to write the XMP. See XMP_SERIAL_* + * @param padding number of bytes of padding, useful for modifying + * embedded XMP in place. + * @param newline the new line character to use + * @param tab the indentation character to use + * @param indent the initial indentation level + * @return TRUE if success. + */ +bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer, uint32_t options, + uint32_t padding, const char *newline, + const char *tab, int32_t indent); + +/** Get an XMP property and it option bits from the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @param property the allocated XmpStringPtr + * @param propsBits pointer to the option bits. Pass NULL if not needed + * @return true if found + */ +bool xmp_get_property(XmpPtr xmp, const char *schema, const char *name, + XmpStringPtr property, uint32_t *propsBits); + +bool xmp_get_property_date(XmpPtr xmp, const char *schema, const char *name, + XmpDateTime *property, uint32_t *propsBits); +bool xmp_get_property_float(XmpPtr xmp, const char *schema, const char *name, + double *property, uint32_t *propsBits); +bool xmp_get_property_bool(XmpPtr xmp, const char *schema, const char *name, + bool *property, uint32_t *propsBits); +bool xmp_get_property_int32(XmpPtr xmp, const char *schema, const char *name, + int32_t *property, uint32_t *propsBits); +bool xmp_get_property_int64(XmpPtr xmp, const char *schema, const char *name, + int64_t *property, uint32_t *propsBits); + +/** Get an item frpm an array property + * @param xmp the xmp meta + * @param schema the schema + * @param name the property name + * @param index the index in the array + * @param property the property value + * @param propsBits the property bits. Pass NULL is unwanted. + * @return TRUE if success. + */ +bool xmp_get_array_item(XmpPtr xmp, const char *schema, const char *name, + int32_t index, XmpStringPtr property, + uint32_t *propsBits); + +/** Set an XMP property in the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @param value 0 terminated string + * @param optionBits + * @return false if failure + */ +bool xmp_set_property(XmpPtr xmp, const char *schema, const char *name, + const char *value, uint32_t optionBits); + +/** Set a date XMP property in the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @param value the date-time struct + * @param optionBits + * @return false if failure + */ +bool xmp_set_property_date(XmpPtr xmp, const char *schema, const char *name, + const XmpDateTime *value, uint32_t optionBits); + +/** Set a float XMP property in the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @param value the float value + * @param optionBits + * @return false if failure + */ +bool xmp_set_property_float(XmpPtr xmp, const char *schema, const char *name, + double value, uint32_t optionBits); +bool xmp_set_property_bool(XmpPtr xmp, const char *schema, const char *name, + bool value, uint32_t optionBits); +bool xmp_set_property_int32(XmpPtr xmp, const char *schema, const char *name, + int32_t value, uint32_t optionBits); +bool xmp_set_property_int64(XmpPtr xmp, const char *schema, const char *name, + int64_t value, uint32_t optionBits); + +bool xmp_set_array_item(XmpPtr xmp, const char *schema, const char *name, + int32_t index, const char *value, uint32_t optionBits); + +/** Append a value to the XMP Property array in the XMP Packet provided + * @param xmp the XMP packet + * @param schema the schema of the property + * @param name the name of the property + * @param arrayOptions option bits of the parent array + * @param value null-terminated string + * @param optionBits option bits of the value itself. + */ +bool xmp_append_array_item(XmpPtr xmp, const char *schema, const char *name, + uint32_t arrayOptions, const char *value, + uint32_t optionBits); + +/** Delete a property from the XMP Packet provided + * @param xmp the XMP packet + * @param schema the schema of the property + * @param name the name of the property + */ +bool xmp_delete_property(XmpPtr xmp, const char *schema, const char *name); + +/** Determines if a property exists in the XMP Packet provided + * @param xmp the XMP packet + * @param schema the schema of the property. Can't be NULL or empty. + * @param name the name of the property. Can't be NULL or empty. + * @return true is the property exists + */ +bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name); + +/** Get a localised text from a localisable property. + * @param xmp the XMP packet + * @param schema the schema + * @param name the property name. + * @param genericLang the generic language you may want as a fall back. + * Can be NULL or empty. + * @param specificLang the specific language you want. Can't be NULL or empty. + * @param actualLang the actual language of the value. Can be NULL if + * not wanted. + * @param itemValue the localized value. Can be NULL if not wanted. + * @param propBits the options flags describing the property. Can be NULL. + * @return true if found, false otherwise. + */ +bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, const char *specificLang, + XmpStringPtr actualLang, XmpStringPtr itemValue, + uint32_t *propBits); + +/** Set a localised text in a localisable property. + * @param xmp the XMP packet + * @param schema the schema + * @param name the property name. + * @param genericLang the generic language you may want to set too. + * Can be NULL or empty. + * @param specificLang the specific language you want. Can't be NULL or empty. + * @param value the localized value. Cannot be NULL. + * @param optionBits the options flags describing the property. + * @return true if set, false otherwise. + */ +bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, const char *specificLang, + const char *value, uint32_t optionBits); + +bool xmp_delete_localized_text(XmpPtr xmp, const char *schema, const char *name, + const char *genericLang, + const char *specificLang); + +/** Instanciate a new string + * @return the new instance. Must be freed with + * xmp_string_free() + */ +XmpStringPtr xmp_string_new(void); + +/** Free a XmpStringPtr + * @param s the string to free + */ +void xmp_string_free(XmpStringPtr s); + +/** Get the C string from the XmpStringPtr + * @param s the string object + * @return the const char * for the XmpStringPtr. It + * belong to the object. + */ +const char * xmp_string_cstr(XmpStringPtr s); + +/** Get the string length from the XmpStringPtr + * @param s the string object + * @return the string length. The unerlying implementation has it. + */ +size_t xmp_string_len(XmpStringPtr s); + +/** Create a new iterator. + * @param xmp the packet + * @param schema the property schema + * @param propName the property name + * @param options + * @return an iterator must be freed with % xmp_iterator_free + */ +XmpIteratorPtr xmp_iterator_new(XmpPtr xmp, const char *schema, + const char *propName, XmpIterOptions options); + +/** Free an iterator. + * @param iter the iterator to free. + */ +bool xmp_iterator_free(XmpIteratorPtr iter); + +/** Iterate to the next value + * @param iter the iterator + * @param schema the schema name. Pass NULL if not wanted + * @param propName the property path. Pass NULL if not wanted + * @param propValue the value of the property. Pass NULL if not wanted. + * @param options the options for the property. Pass NULL if not wanted. + * @return true if still something, false if none + */ +bool xmp_iterator_next(XmpIteratorPtr iter, XmpStringPtr schema, + XmpStringPtr propName, XmpStringPtr propValue, + uint32_t *options); + +/** + */ +bool xmp_iterator_skip(XmpIteratorPtr iter, XmpIterSkipOptions options); + +/** Compare two XmpDateTime + * @param left value + * @param right value + * @return if left < right, return < 0. If left > right, return > 0. + * if left == right, return 0. + */ +int xmp_datetime_compare(XmpDateTime *left, XmpDateTime *right); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exempi/xmpconsts.h b/exempi/xmpconsts.h new file mode 100644 index 0000000..c985d42 --- /dev/null +++ b/exempi/xmpconsts.h @@ -0,0 +1,69 @@ +/* + * exempi - xmpconsts.h + * + * Copyright (C) 2007 Hubert Figuiere + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _EXEMPI_XMP_CONSTS_H_ +#define _EXEMPI_XMP_CONSTS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern const char NS_XMP_META[]; +extern const char NS_RDF[]; +extern const char NS_EXIF[]; +extern const char NS_TIFF[]; +extern const char NS_XAP[]; +extern const char NS_XAP_RIGHTS[]; +extern const char NS_DC[]; +extern const char NS_EXIF_AUX[]; +extern const char NS_CRS[]; +extern const char NS_LIGHTROOM[]; +extern const char NS_PHOTOSHOP[]; +extern const char NS_CAMERA_RAW_SETTINGS[]; +extern const char NS_CAMERA_RAW_SAVED_SETTINGS[]; +extern const char NS_IPTC4XMP[]; +extern const char NS_TPG[]; +extern const char NS_DIMENSIONS_TYPE[]; +/** Creative Commons namespace */ +extern const char NS_CC[]; +/* Added in Exempi 2.1 */ +extern const char NS_PDF[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/exempi/xmperrors.h b/exempi/xmperrors.h new file mode 100644 index 0000000..438294e --- /dev/null +++ b/exempi/xmperrors.h @@ -0,0 +1,86 @@ +/* + * exempi - xmperror.h + * + * Copyright (C) 2007 Hubert Figuiere + * Copyright 2002-2007 Adobe Systems Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1 Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2 Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * 3 Neither the name of the Authors, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software wit hout specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __EXEMPI_XMPERROR_H_ +#define __EXEMPI_XMPERROR_H_ + +enum { + /* More or less generic error codes. */ + XMPErr_Unknown = 0, + XMPErr_TBD = -1, + XMPErr_Unavailable = -2, + XMPErr_BadObject = -3, + XMPErr_BadParam = -4, + XMPErr_BadValue = -5, + XMPErr_AssertFailure = -6, + XMPErr_EnforceFailure = -7, + XMPErr_Unimplemented = -8, + XMPErr_InternalFailure = -9, + XMPErr_Deprecated = -10, + XMPErr_ExternalFailure = -11, + XMPErr_UserAbort = -12, + XMPErr_StdException = -13, + XMPErr_UnknownException = -14, + XMPErr_NoMemory = -15, + + /* More specific parameter error codes. */ + XMPErr_BadSchema = -101, + XMPErr_BadXPath = -102, + XMPErr_BadOptions = -103, + XMPErr_BadIndex = -104, + XMPErr_BadIterPosition = -105, + XMPErr_BadParse = -106, + XMPErr_BadSerialize = -107, + XMPErr_BadFileFormat = -108, + XMPErr_NoFileHandler = -109, + XMPErr_TooLargeForJPEG = -110, + + /* File format and internal structure error codes. */ + XMPErr_BadXML = -201, + XMPErr_BadRDF = -202, + XMPErr_BadXMP = -203, + XMPErr_EmptyIterator = -204, + XMPErr_BadUnicode = -205, + XMPErr_BadTIFF = -206, + XMPErr_BadJPEG = -207, + XMPErr_BadPSD = -208, + XMPErr_BadPSIR = -209, + XMPErr_BadIPTC = -210, + XMPErr_BadMPEG = -211 +}; + +#endif diff --git a/m4/ax_cflags_gcc_option.m4 b/m4/ax_cflags_gcc_option.m4 new file mode 100644 index 0000000..9a4d62a --- /dev/null +++ b/m4/ax_cflags_gcc_option.m4 @@ -0,0 +1,230 @@ +##### http://autoconf-archive.cryp.to/ax_cflags_gcc_option.html +# +# SYNOPSIS +# +# AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) +# +# DESCRIPTION +# +# AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like +# "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the +# optionflag to CFLAGS if it is understood. You can override the +# shellvar-default of CFLAGS of course. The order of arguments stems +# from the explicit macros like AX_CFLAGS_WARN_ALL. +# +# The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add +# to CXXFLAGS - and it uses the autoconf setup for C++ instead of C +# (since it is possible to use different compilers for C and C++). +# +# The macro is a lot simpler than any special AX_CFLAGS_* macro (or +# ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. +# However, if you use this macro in a few places, it would be great +# if you would make up a new function-macro and submit it to the +# ac-archive. +# +# - $1 option-to-check-for : required ("-option" as non-value) +# - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) +# - $3 action-if-found : add value to shellvariable +# - $4 action-if-not-found : nothing +# +# note: in earlier versions, $1-$2 were swapped. We try to detect the +# situation and accept a $2=~/-/ as being the old +# option-to-check-for. +# +# also: there are other variants that emerged from the original macro +# variant which did just test an option to be possibly added. +# However, some compilers accept an option silently, or possibly for +# just another option that was not intended. Therefore, we have to do +# a generic test for a compiler family. For gcc we check "-pedantic" +# being accepted which is also understood by compilers who just want +# to be compatible with gcc even when not being made from gcc +# sources. +# +# see also: +# +# AX_CFLAGS_SUN_OPTION AX_CFLAGS_HPUX_OPTION +# AX_CFLAGS_AIX_OPTION AX_CFLAGS_IRIX_OPTION +# +# LAST MODIFICATION +# +# 2006-12-12 +# +# COPYLEFT +# +# Copyright (c) 2006 Guido U. Draheim <guidod@gmx.de> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# +# As a special exception, the respective Autoconf Macro's copyright +# owner gives unlimited permission to copy, distribute and modify the +# configure scripts that are the output of Autoconf when processing +# the Macro. You need not follow the terms of the GNU General Public +# License when using or distributing such scripts, even though +# portions of the text of the Macro appear in them. The GNU General +# Public License (GPL) does govern all other use of the material that +# constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the +# Autoconf Macro released by the Autoconf Macro Archive. When you +# make and distribute a modified version of the Autoconf Macro, you +# may extend this special exception to the GPL to apply to your +# modified version as well. + +AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$2])dnl +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC + "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +dnl ------------------------------------------------------------------------- + +AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_C + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + + +dnl the only difference - the LANG selection... and the default FLAGS + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl +AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$1])dnl +AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], +VAR,[VAR="no, unknown" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_[]FLAGS="$[]FLAGS" +for ac_arg dnl +in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC + "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC + # +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + AC_TRY_COMPILE([],[return 0;], + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) +done + FLAGS="$ac_save_[]FLAGS" + AC_LANG_RESTORE +]) +case ".$VAR" in + .ok|.ok,*) m4_ifvaln($3,$3) ;; + .|.no|.no,*) m4_ifvaln($4,$4) ;; + *) m4_ifvaln($3,$3,[ + if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null + then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) + else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) + m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" + fi ]) ;; +esac +AS_VAR_POPDEF([VAR])dnl +AS_VAR_POPDEF([FLAGS])dnl +]) + +AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) + +AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, +[AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 0000000..af37acd --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,133 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXXFLAGS to enable support. +# +# The first argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The second argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline C++11 support is required and that the macro +# should error out if no mode with that support is found. If specified +# 'optional', then configuration proceeds regardless, after defining +# HAVE_CXX11 if and only if a supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +# Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c); + + auto d = a; +]) + +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl + m4_if([$1], [], [], + [$1], [ext], [], + [$1], [noext], [], + [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl + m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], + [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], + [$2], [optional], [ax_cxx_compile_cxx11_required=false], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++11 features by default, + ax_cv_cxx_compile_cxx11, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [ax_cv_cxx_compile_cxx11=yes], + [ax_cv_cxx_compile_cxx11=no])]) + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + m4_if([$1], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$1], [ext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=c++11 -std=c++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX11=0 + AC_MSG_NOTICE([No compiler with C++11 support was found]) + else + HAVE_CXX11=1 + AC_DEFINE(HAVE_CXX11,1, + [define if the compiler supports basic C++11 syntax]) + fi + + AC_SUBST(HAVE_CXX11) + fi +]) diff --git a/m4/ax_ld_check_flag.m4 b/m4/ax_ld_check_flag.m4 new file mode 100644 index 0000000..2339657 --- /dev/null +++ b/m4/ax_ld_check_flag.m4 @@ -0,0 +1,96 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ax_ld_check_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_LD_CHECK_FLAG(FLAG-TO-CHECK,[PROLOGUE],[BODY],[ACTION-IF-SUCCESS],[ACTION-IF-FAILURE]) +# +# DESCRIPTION +# +# This macro tests if the C++ compiler supports the flag FLAG-TO-CHECK. If +# successfull execute ACTION-IF-SUCCESS otherwise ACTION-IF-FAILURE. +# PROLOGUE and BODY are optional and should be used as in AC_LANG_PROGRAM +# macro. +# +# Example: +# +# AX_LD_CHECK_FLAG([-Wl,-L/usr/lib],[],[],[ +# ... +# ],[ +# ... +# ]) +# +# This code is inspired from KDE_CHECK_COMPILER_FLAG macro. Thanks to +# Bogdan Drozdowski <bogdandr@op.pl> for testing and bug fixes. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Francesco Salvestrini <salvestrini@users.sourceforge.net> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AX_LD_CHECK_FLAG],[ + AC_PREREQ([2.61]) + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PROG_SED]) + + flag=`echo "$1" | $SED 'y% .=/+-(){}<>:*,%_______________%'` + + AC_CACHE_CHECK([whether the linker accepts the $1 flag], + [ax_cv_ld_check_flag_$flag],[ + + #AC_LANG_PUSH([C]) + + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([$2],[$3]) + ],[ + eval "ax_cv_ld_check_flag_$flag=yes" + ],[ + eval "ax_cv_ld_check_flag_$flag=no" + ]) + + LDFLAGS="$save_LDFLAGS" + + #AC_LANG_POP + + ]) + + AS_IF([eval "test \"`echo '$ax_cv_ld_check_flag_'$flag`\" = yes"],[ + : + $4 + ],[ + : + $5 + ]) +]) diff --git a/m4/ax_tls.m4 b/m4/ax_tls.m4 new file mode 100644 index 0000000..41620a7 --- /dev/null +++ b/m4/ax_tls.m4 @@ -0,0 +1,78 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ax_tls.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_TLS +# +# DESCRIPTION +# +# Provides a test for the compiler support of thread local storage (TLS) +# extensions. Defines TLS if it is found. Currently only knows about GCC +# and MSVC. I think SunPro uses the same as GCC, and Borland apparently +# supports either. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AX_TLS], [ + AC_MSG_CHECKING(for thread local storage (TLS) class) + AC_CACHE_VAL(ac_cv_tls, [ + ax_tls_keywords="__thread __declspec(thread) none" + for ax_tls_keyword in $ax_tls_keywords; do + case $ax_tls_keyword in + none) ac_cv_tls=none ; break ;; + *) + AC_TRY_COMPILE( + [#include <stdlib.h> + static void + foo(void) { + static ] $ax_tls_keyword [ int bar; + exit(1); + }], + [], + [ac_cv_tls=$ax_tls_keyword ; break], + ac_cv_tls=none + ) + esac + done +]) + + if test "$ac_cv_tls" != "none"; then + dnl AC_DEFINE([TLS], [], [If the compiler supports a TLS storage class define it to that here]) + AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here]) + fi + AC_MSG_RESULT($ac_cv_tls) +]) diff --git a/m4/boost.m4 b/m4/boost.m4 new file mode 100644 index 0000000..27d063f --- /dev/null +++ b/m4/boost.m4 @@ -0,0 +1,1560 @@ +# boost.m4: Locate Boost headers and libraries for autoconf-based projects. +# Copyright (C) 2007-2011, 2014 Benoit Sigoure <tsuna@lrde.epita.fr> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Additional permission under section 7 of the GNU General Public +# License, version 3 ("GPLv3"): +# +# If you convey this file as part of a work that contains a +# configuration script generated by Autoconf, you may do so under +# terms of your choice. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +m4_define([_BOOST_SERIAL], [m4_translit([ +# serial 25 +], [# +], [])]) + +# Original sources can be found at http://github.com/tsuna/boost.m4 +# You can fetch the latest version of the script by doing: +# wget http://github.com/tsuna/boost.m4/raw/master/build-aux/boost.m4 + +# ------ # +# README # +# ------ # + +# This file provides several macros to use the various Boost libraries. +# The first macro is BOOST_REQUIRE. It will simply check if it's possible to +# find the Boost headers of a given (optional) minimum version and it will +# define BOOST_CPPFLAGS accordingly. It will add an option --with-boost to +# your configure so that users can specify non standard locations. +# If the user's environment contains BOOST_ROOT and --with-boost was not +# specified, --with-boost=$BOOST_ROOT is implicitly used. +# For more README and documentation, go to http://github.com/tsuna/boost.m4 +# Note: THESE MACROS ASSUME THAT YOU USE LIBTOOL. If you don't, don't worry, +# simply read the README, it will show you what to do step by step. + +m4_pattern_forbid([^_?(BOOST|Boost)_]) + + +# _BOOST_SED_CPP(SED-PROGRAM, PROGRAM, +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# -------------------------------------------------------- +# Same as AC_EGREP_CPP, but leave the result in conftest.i. +# +# SED-PROGRAM is *not* overquoted, as in AC_EGREP_CPP. It is expanded +# in double-quotes, so escape your double quotes. +# +# It could be useful to turn this into a macro which extracts the +# value of any macro. +m4_define([_BOOST_SED_CPP], +[AC_LANG_PUSH([C++])dnl +AC_LANG_PREPROC_REQUIRE()dnl +AC_REQUIRE([AC_PROG_SED])dnl +AC_LANG_CONFTEST([AC_LANG_SOURCE([[$2]])]) +AS_IF([dnl eval is necessary to expand ac_cpp. +dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. +dnl Beware of Windows end-of-lines, for instance if we are running +dnl some Windows programs under Wine. In that case, boost/version.hpp +dnl is certainly using "\r\n", but the regular Unix shell will only +dnl strip `\n' with backquotes, not the `\r'. This results in +dnl boost_cv_lib_version='1_37\r' for instance, which breaks +dnl everything else. +dnl Cannot use 'dnl' after [$4] because a trailing dnl may break AC_CACHE_CHECK +dnl +dnl Beware that GCC 5, when expanding macros, may embed # line directives +dnl a within single line: +dnl +dnl # 1 "conftest.cc" +dnl # 1 "<built-in>" +dnl # 1 "<command-line>" +dnl # 1 "conftest.cc" +dnl # 1 "/opt/local/include/boost/version.hpp" 1 3 +dnl # 2 "conftest.cc" 2 +dnl boost-lib-version = +dnl # 2 "conftest.cc" 3 +dnl "1_56" +dnl +dnl So get rid of the # lines, and glue the remaining ones together. +(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | + grep -v '#' | + tr -d '\r' | + tr -s '\n' ' ' | + $SED -n -e "$1" >conftest.i 2>&1], + [$3], + [$4]) +rm -rf conftest* +AC_LANG_POP([C++])dnl +])# _BOOST_SED_CPP + + + +# BOOST_REQUIRE([VERSION], [ACTION-IF-NOT-FOUND]) +# ----------------------------------------------- +# Look for Boost. If version is given, it must either be a literal of the form +# "X.Y.Z" where X, Y and Z are integers (the ".Z" part being optional) or a +# variable "$var". +# Defines the value BOOST_CPPFLAGS. This macro only checks for headers with +# the required version, it does not check for any of the Boost libraries. +# On # success, defines HAVE_BOOST. On failure, calls the optional +# ACTION-IF-NOT-FOUND action if one was supplied. +# Otherwise aborts with an error message. +AC_DEFUN_ONCE([BOOST_REQUIRE], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_PROG_GREP])dnl +echo "$as_me: this is boost.m4[]_BOOST_SERIAL" >&AS_MESSAGE_LOG_FD +boost_save_IFS=$IFS +boost_version_req=$1 +IFS=. +set x $boost_version_req 0 0 0 +IFS=$boost_save_IFS +shift +boost_version_req=`expr "$[1]" '*' 100000 + "$[2]" '*' 100 + "$[3]"` +boost_version_req_string=$[1].$[2].$[3] +AC_ARG_WITH([boost], + [AS_HELP_STRING([--with-boost=DIR], + [prefix of Boost $1 @<:@guess@:>@])])dnl +AC_ARG_VAR([BOOST_ROOT],[Location of Boost installation])dnl +# If BOOST_ROOT is set and the user has not provided a value to +# --with-boost, then treat BOOST_ROOT as if it the user supplied it. +if test x"$BOOST_ROOT" != x; then + if test x"$with_boost" = x; then + AC_MSG_NOTICE([Detected BOOST_ROOT; continuing with --with-boost=$BOOST_ROOT]) + with_boost=$BOOST_ROOT + else + AC_MSG_NOTICE([Detected BOOST_ROOT=$BOOST_ROOT, but overridden by --with-boost=$with_boost]) + fi +fi +AC_SUBST([DISTCHECK_CONFIGURE_FLAGS], + ["$DISTCHECK_CONFIGURE_FLAGS '--with-boost=$with_boost'"])dnl +boost_save_CPPFLAGS=$CPPFLAGS + AC_CACHE_CHECK([for Boost headers version >= $boost_version_req_string], + [boost_cv_inc_path], + [boost_cv_inc_path=no +AC_LANG_PUSH([C++])dnl +m4_pattern_allow([^BOOST_VERSION$])dnl + AC_LANG_CONFTEST([AC_LANG_PROGRAM([[#include <boost/version.hpp> +#if !defined BOOST_VERSION +# error BOOST_VERSION is not defined +#elif BOOST_VERSION < $boost_version_req +# error Boost headers version < $boost_version_req +#endif +]])]) + # If the user provided a value to --with-boost, use it and only it. + case $with_boost in #( + ''|yes) set x '' /opt/local/include /usr/local/include /opt/include \ + /usr/include C:/Boost/include;; #( + *) set x "$with_boost/include" "$with_boost";; + esac + shift + for boost_dir + do + # Without --layout=system, Boost (or at least some versions) installs + # itself in <prefix>/include/boost-<version>. This inner loop helps to + # find headers in such directories. + # + # Any ${boost_dir}/boost-x_xx directories are searched in reverse version + # order followed by ${boost_dir}. The final '.' is a sentinel for + # searching $boost_dir" itself. Entries are whitespace separated. + # + # I didn't indent this loop on purpose (to avoid over-indented code) + boost_layout_system_search_list=`cd "$boost_dir" 2>/dev/null \ + && ls -1 | "${GREP}" '^boost-' | sort -rn -t- -k2 \ + && echo .` + for boost_inc in $boost_layout_system_search_list + do + if test x"$boost_inc" != x.; then + boost_inc="$boost_dir/$boost_inc" + else + boost_inc="$boost_dir" # Uses sentinel in boost_layout_system_search_list + fi + if test x"$boost_inc" != x; then + # We are going to check whether the version of Boost installed + # in $boost_inc is usable by running a compilation that + # #includes it. But if we pass a -I/some/path in which Boost + # is not installed, the compiler will just skip this -I and + # use other locations (either from CPPFLAGS, or from its list + # of system include directories). As a result we would use + # header installed on the machine instead of the /some/path + # specified by the user. So in that precise case (trying + # $boost_inc), make sure the version.hpp exists. + # + # Use test -e as there can be symlinks. + test -e "$boost_inc/boost/version.hpp" || continue + CPPFLAGS="$CPPFLAGS -I$boost_inc" + fi + AC_COMPILE_IFELSE([], [boost_cv_inc_path=yes], [boost_cv_version=no]) + if test x"$boost_cv_inc_path" = xyes; then + if test x"$boost_inc" != x; then + boost_cv_inc_path=$boost_inc + fi + break 2 + fi + done + done +AC_LANG_POP([C++])dnl + ]) + case $boost_cv_inc_path in #( + no) + boost_errmsg="cannot find Boost headers version >= $boost_version_req_string" + m4_if([$2], [], [AC_MSG_ERROR([$boost_errmsg])], + [AC_MSG_NOTICE([$boost_errmsg])]) + $2 + ;;#( + yes) + BOOST_CPPFLAGS= + ;;#( + *) + AC_SUBST([BOOST_CPPFLAGS], ["-I$boost_cv_inc_path"])dnl + ;; + esac + if test x"$boost_cv_inc_path" != xno; then + AC_DEFINE([HAVE_BOOST], [1], + [Defined if the requested minimum BOOST version is satisfied]) + AC_CACHE_CHECK([for Boost's header version], + [boost_cv_lib_version], + [m4_pattern_allow([^BOOST_LIB_VERSION$])dnl + _BOOST_SED_CPP([[/^boost-lib-version = /{s///;s/[\" ]//g;p;q;}]], + [#include <boost/version.hpp> +boost-lib-version = BOOST_LIB_VERSION], + [boost_cv_lib_version=`cat conftest.i`])]) + # e.g. "134" for 1_34_1 or "135" for 1_35 + boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'` + case $boost_major_version in #( + '' | *[[!0-9]]*) + AC_MSG_ERROR([invalid value: boost_major_version='$boost_major_version']) + ;; + esac +fi +CPPFLAGS=$boost_save_CPPFLAGS +])# BOOST_REQUIRE + + +# BOOST_STATIC() +# -------------- +# Add the "--enable-static-boost" configure argument. If this argument is given +# on the command line, static versions of the libraries will be looked up. +AC_DEFUN([BOOST_STATIC], + [AC_ARG_ENABLE([static-boost], + [AS_HELP_STRING([--enable-static-boost], + [Prefer the static boost libraries over the shared ones [no]])], + [enable_static_boost=yes], + [enable_static_boost=no])])# BOOST_STATIC + + +# BOOST_FIND_HEADER([HEADER-NAME], [ACTION-IF-NOT-FOUND], [ACTION-IF-FOUND]) +# -------------------------------------------------------------------------- +# Wrapper around AC_CHECK_HEADER for Boost headers. Useful to check for +# some parts of the Boost library which are only made of headers and don't +# require linking (such as Boost.Foreach). +# +# Default ACTION-IF-NOT-FOUND: Fail with a fatal error unless Boost couldn't be +# found in the first place, in which case by default a notice is issued to the +# user. Presumably if we haven't died already it's because it's OK to not have +# Boost, which is why only a notice is issued instead of a hard error. +# +# Default ACTION-IF-FOUND: define the preprocessor symbol HAVE_<HEADER-NAME> in +# case of success # (where HEADER-NAME is written LIKE_THIS, e.g., +# HAVE_BOOST_FOREACH_HPP). +AC_DEFUN([BOOST_FIND_HEADER], +[AC_REQUIRE([BOOST_REQUIRE])dnl +if test x"$boost_cv_inc_path" = xno; then + m4_default([$2], [AC_MSG_NOTICE([Boost not available, not searching for $1])]) +else +AC_LANG_PUSH([C++])dnl +boost_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +AC_CHECK_HEADER([$1], + [m4_default([$3], [AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1], + [Define to 1 if you have <$1>])])], + [m4_default([$2], [AC_MSG_ERROR([cannot find $1])])]) +CPPFLAGS=$boost_save_CPPFLAGS +AC_LANG_POP([C++])dnl +fi +])# BOOST_FIND_HEADER + + +# BOOST_FIND_LIBS([COMPONENT-NAME], [CANDIDATE-LIB-NAMES], +# [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], +# [CXX-PROLOGUE]) +# -------------------------------------------------------------- +# Look for the Boost library COMPONENT-NAME (e.g., `thread', for +# libboost_thread) under the possible CANDIDATE-LIB-NAMES (e.g., +# "thread_win32 thread"). Check that HEADER-NAME works and check that +# libboost_LIB-NAME can link with the code CXX-TEST. The optional +# argument CXX-PROLOGUE can be used to include some C++ code before +# the `main' function. +# +# Invokes BOOST_FIND_HEADER([HEADER-NAME]) (see above). +# +# Boost libraries typically come compiled with several flavors (with different +# runtime options) so PREFERRED-RT-OPT is the preferred suffix. A suffix is one +# or more of the following letters: sgdpn (in that order). s = static +# runtime, d = debug build, g = debug/diagnostic runtime, p = STLPort build, +# n = (unsure) STLPort build without iostreams from STLPort (it looks like `n' +# must always be used along with `p'). Additionally, PREFERRED-RT-OPT can +# start with `mt-' to indicate that there is a preference for multi-thread +# builds. Some sample values for PREFERRED-RT-OPT: (nothing), mt, d, mt-d, gdp +# ... If you want to make sure you have a specific version of Boost +# (eg, >= 1.33) you *must* invoke BOOST_REQUIRE before this macro. +AC_DEFUN([BOOST_FIND_LIBS], +[AC_REQUIRE([BOOST_REQUIRE])dnl +AC_REQUIRE([_BOOST_FIND_COMPILER_TAG])dnl +AC_REQUIRE([BOOST_STATIC])dnl +AC_REQUIRE([_BOOST_GUESS_WHETHER_TO_USE_MT])dnl +if test x"$boost_cv_inc_path" = xno; then + AC_MSG_NOTICE([Boost not available, not searching for the Boost $1 library]) +else +dnl The else branch is huge and wasn't intended on purpose. +AC_LANG_PUSH([C++])dnl +AS_VAR_PUSHDEF([Boost_lib], [boost_cv_lib_$1])dnl +AS_VAR_PUSHDEF([Boost_lib_LDFLAGS], [boost_cv_lib_$1_LDFLAGS])dnl +AS_VAR_PUSHDEF([Boost_lib_LDPATH], [boost_cv_lib_$1_LDPATH])dnl +AS_VAR_PUSHDEF([Boost_lib_LIBS], [boost_cv_lib_$1_LIBS])dnl +BOOST_FIND_HEADER([$4]) +boost_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +AC_CACHE_CHECK([for the Boost $1 library], [Boost_lib], + [_BOOST_FIND_LIBS($@)]) +case $Boost_lib in #( + (no) _AC_MSG_LOG_CONFTEST + AC_MSG_ERROR([cannot find the flags to link with Boost $1]) + ;; +esac +AC_SUBST(AS_TR_CPP([BOOST_$1_LDFLAGS]), [$Boost_lib_LDFLAGS])dnl +AC_SUBST(AS_TR_CPP([BOOST_$1_LDPATH]), [$Boost_lib_LDPATH])dnl +AC_SUBST([BOOST_LDPATH], [$Boost_lib_LDPATH])dnl +AC_SUBST(AS_TR_CPP([BOOST_$1_LIBS]), [$Boost_lib_LIBS])dnl +CPPFLAGS=$boost_save_CPPFLAGS +AS_VAR_POPDEF([Boost_lib])dnl +AS_VAR_POPDEF([Boost_lib_LDFLAGS])dnl +AS_VAR_POPDEF([Boost_lib_LDPATH])dnl +AS_VAR_POPDEF([Boost_lib_LIBS])dnl +AC_LANG_POP([C++])dnl +fi +]) + + +# BOOST_FIND_LIB([LIB-NAME], +# [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], +# [CXX-PROLOGUE]) +# -------------------------------------------------------------- +# Backward compatibility wrapper for BOOST_FIND_LIBS. +AC_DEFUN([BOOST_FIND_LIB], +[BOOST_FIND_LIBS([$1], $@)]) + + +# _BOOST_FIND_LIBS([LIB-NAME], [CANDIDATE-LIB-NAMES], +# [PREFERRED-RT-OPT], [HEADER-NAME], [CXX-TEST], +# [CXX-PROLOGUE]) +# -------------------------------------------------------------- +# Real implementation of BOOST_FIND_LIBS: rely on these local macros: +# Boost_lib, Boost_lib_LDFLAGS, Boost_lib_LDPATH, Boost_lib_LIBS +# +# The algorithm is as follows: first look for a given library name +# according to the user's PREFERRED-RT-OPT. For each library name, we +# prefer to use the ones that carry the tag (toolset name). Each +# library is searched through the various standard paths were Boost is +# usually installed. If we can't find the standard variants, we try +# to enforce -mt (for instance on MacOSX, libboost_thread.dylib +# doesn't exist but there's -obviously- libboost_thread-mt.dylib). +AC_DEFUN([_BOOST_FIND_LIBS], +[Boost_lib=no + case "$3" in #( + (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( + (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X$3" : 'Xmt-*\(.*\)'`;; #( + (*) boost_mt=; boost_rtopt=$3;; + esac + if test $enable_static_boost = yes; then + boost_rtopt="s$boost_rtopt" + fi + # Find the proper debug variant depending on what we've been asked to find. + case $boost_rtopt in #( + (*d*) boost_rt_d=$boost_rtopt;; #( + (*[[sgpn]]*) # Insert the `d' at the right place (in between `sg' and `pn') + boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( + (*) boost_rt_d='-d';; + esac + # If the PREFERRED-RT-OPT are not empty, prepend a `-'. + test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" + $boost_guess_use_mt && boost_mt=-mt + # Look for the abs path the static archive. + # $libext is computed by Libtool but let's make sure it's non empty. + test -z "$libext" && + AC_MSG_ERROR([the libext variable is empty, did you invoke Libtool?]) + boost_save_ac_objext=$ac_objext + # Generate the test file. + AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include <$4> +$6], [$5])]) +dnl Optimization hacks: compiling C++ is slow, especially with Boost. What +dnl we're trying to do here is guess the right combination of link flags +dnl (LIBS / LDFLAGS) to use a given library. This can take several +dnl iterations before it succeeds and is thus *very* slow. So what we do +dnl instead is that we compile the code first (and thus get an object file, +dnl typically conftest.o). Then we try various combinations of link flags +dnl until we succeed to link conftest.o in an executable. The problem is +dnl that the various TRY_LINK / COMPILE_IFELSE macros of Autoconf always +dnl remove all the temporary files including conftest.o. So the trick here +dnl is to temporarily change the value of ac_objext so that conftest.o is +dnl preserved accross tests. This is obviously fragile and I will burn in +dnl hell for not respecting Autoconf's documented interfaces, but in the +dnl mean time, it optimizes the macro by a factor of 5 to 30. +dnl Another small optimization: the first argument of AC_COMPILE_IFELSE left +dnl empty because the test file is generated only once above (before we +dnl start the for loops). + AC_COMPILE_IFELSE([], + [ac_objext=do_not_rm_me_plz], + [AC_MSG_ERROR([cannot compile a test that uses Boost $1])]) + ac_objext=$boost_save_ac_objext + boost_failed_libs= +# Don't bother to ident the following nested for loops, only the 2 +# innermost ones matter. +for boost_lib_ in $2; do +for boost_tag_ in -$boost_cv_lib_tag ''; do +for boost_ver_ in -$boost_cv_lib_version ''; do +for boost_mt_ in $boost_mt -mt ''; do +for boost_rtopt_ in $boost_rtopt '' -d; do + for boost_lib in \ + boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ + boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ + boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ + boost_$boost_lib_$boost_tag_$boost_ver_ + do + # Avoid testing twice the same lib + case $boost_failed_libs in #( + (*@$boost_lib@*) continue;; + esac + # If with_boost is empty, we'll search in /lib first, which is not quite + # right so instead we'll try to a location based on where the headers are. + boost_tmp_lib=$with_boost + test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} + for boost_ldpath in "$boost_tmp_lib/lib" '' \ + /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ + "$with_boost" C:/Boost/lib /lib* + do + # Don't waste time with directories that don't exist. + if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then + continue + fi + boost_save_LDFLAGS=$LDFLAGS + # Are we looking for a static library? + case $boost_ldpath:$boost_rtopt_ in #( + (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) + Boost_lib_LIBS="$boost_ldpath/lib$boost_lib.$libext" + test -e "$Boost_lib_LIBS" || continue;; #( + (*) # No: use -lboost_foo to find the shared library. + Boost_lib_LIBS="-l$boost_lib";; + esac + boost_save_LIBS=$LIBS + LIBS="$Boost_lib_LIBS $LIBS" + test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" +dnl First argument of AC_LINK_IFELSE left empty because the test file is +dnl generated only once above (before we start the for loops). + _BOOST_AC_LINK_IFELSE([], + [Boost_lib=yes], [Boost_lib=no]) + ac_objext=$boost_save_ac_objext + LDFLAGS=$boost_save_LDFLAGS + LIBS=$boost_save_LIBS + if test x"$Boost_lib" = xyes; then + # Check or used cached result of whether or not using -R or + # -rpath makes sense. Some implementations of ld, such as for + # Mac OSX, require -rpath but -R is the flag known to work on + # other systems. https://github.com/tsuna/boost.m4/issues/19 + AC_CACHE_VAL([boost_cv_rpath_link_ldflag], + [case $boost_ldpath in + '') # Nothing to do. + boost_cv_rpath_link_ldflag= + boost_rpath_link_ldflag_found=yes;; + *) + for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do + LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" + LIBS="$boost_save_LIBS $Boost_lib_LIBS" + _BOOST_AC_LINK_IFELSE([], + [boost_rpath_link_ldflag_found=yes + break], + [boost_rpath_link_ldflag_found=no]) + done + ;; + esac + AS_IF([test "x$boost_rpath_link_ldflag_found" != "xyes"], + [AC_MSG_ERROR([Unable to determine whether to use -R or -rpath])]) + LDFLAGS=$boost_save_LDFLAGS + LIBS=$boost_save_LIBS + ]) + test x"$boost_ldpath" != x && + Boost_lib_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" + Boost_lib_LDPATH="$boost_ldpath" + break 7 + else + boost_failed_libs="$boost_failed_libs@$boost_lib@" + fi + done + done +done +done +done +done +done # boost_lib_ +rm -f conftest.$ac_objext +]) + + + +# --------------------------------------- # +# Checks for the various Boost libraries. # +# --------------------------------------- # + +# List of boost libraries: http://www.boost.org/libs/libraries.htm +# The page http://beta.boost.org/doc/libs is useful: it gives the first release +# version of each library (among other things). + +# BOOST_DEFUN(LIBRARY, CODE) +# -------------------------- +# Define BOOST_<LIBRARY-UPPERCASE> as a macro that runs CODE. +# +# Use indir to avoid the warning on underquoted macro name given to AC_DEFUN. +m4_define([BOOST_DEFUN], +[m4_indir([AC_DEFUN], + m4_toupper([BOOST_$1]), +[m4_pushdef([BOOST_Library], [$1])dnl +$2 +m4_popdef([BOOST_Library])dnl +]) +]) + +# BOOST_ARRAY() +# ------------- +# Look for Boost.Array +BOOST_DEFUN([Array], +[BOOST_FIND_HEADER([boost/array.hpp])]) + + +# BOOST_ASIO() +# ------------ +# Look for Boost.Asio (new in Boost 1.35). +BOOST_DEFUN([Asio], +[AC_REQUIRE([BOOST_SYSTEM])dnl +BOOST_FIND_HEADER([boost/asio.hpp])]) + + +# BOOST_BIND() +# ------------ +# Look for Boost.Bind. +BOOST_DEFUN([Bind], +[BOOST_FIND_HEADER([boost/bind.hpp])]) + + +# BOOST_CHRONO() +# -------------- +# Look for Boost.Chrono. +BOOST_DEFUN([Chrono], +[# Do we have to check for Boost.System? This link-time dependency was +# added as of 1.35.0. If we have a version <1.35, we must not attempt to +# find Boost.System as it didn't exist by then. +if test $boost_major_version -ge 135; then + BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +boost_filesystem_save_LIBS=$LIBS +boost_filesystem_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +BOOST_FIND_LIB([chrono], [$1], + [boost/chrono.hpp], + [boost::chrono::thread_clock d;]) +if test $enable_static_boost = yes && test $boost_major_version -ge 135; then + BOOST_CHRONO_LIBS="$BOOST_CHRONO_LIBS $BOOST_SYSTEM_LIBS" +fi +LIBS=$boost_filesystem_save_LIBS +LDFLAGS=$boost_filesystem_save_LDFLAGS +])# BOOST_CHRONO + + +# BOOST_CONTEXT([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Context. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +# +# * This library was introduced in Boost 1.51.0 +# * The signatures of make_fcontext() and jump_fcontext were changed in 1.56.0 +# * A dependency on boost_thread appears in 1.57.0 +BOOST_DEFUN([Context], +[boost_context_save_LIBS=$LIBS + boost_context_save_LDFLAGS=$LDFLAGS +if test $boost_major_version -ge 157; then + BOOST_THREAD([$1]) + m4_pattern_allow([^BOOST_THREAD_(LIBS|LDFLAGS)$])dnl + LIBS="$LIBS $BOOST_THREAD_LIBS" + LDFLAGS="$LDFLAGS $BOOST_THREAD_LDFLAGS" +fi +BOOST_FIND_LIB([context], [$1], + [boost/context/all.hpp],[[ + +// creates a stack +void * stack_pointer = new void*[4096]; +std::size_t const size = sizeof(void*[4096]); + +#if BOOST_VERSION <= 105100 +ctx::make_fcontext(&fc, f); +return ctx::jump_fcontext(&fcm, &fc, 3) == 6; + +#else + +fc = ctx::make_fcontext(stack_pointer, size, f); +return ctx::jump_fcontext(&fcm, fc, 3) == 6; + +#endif + + +]],[dnl + +#include <boost/version.hpp> +#if BOOST_VERSION <= 105100 + +namespace ctx = boost::ctx; + +static ctx::fcontext_t fcm, fc; + +static void f(intptr_t i) { + ctx::jump_fcontext(&fc, &fcm, i * 2); +} + +#elif BOOST_VERSION <= 105500 + +namespace ctx = boost::context; + +// context +static ctx::fcontext_t fcm, *fc; + +// context-function +static void f(intptr_t i) { + ctx::jump_fcontext(fc, &fcm, i * 2); +} + +#else + +namespace ctx = boost::context; + +// context +static ctx::fcontext_t fcm, fc; + +// context-function +static void f(intptr_t i) { + ctx::jump_fcontext(&fc, fcm, i * 2); +} +#endif +]) +LIBS=$boost_context_save_LIBS +LDFLAGS=$boost_context_save_LDFLAGS +])# BOOST_CONTEXT + + +# BOOST_CONVERSION() +# ------------------ +# Look for Boost.Conversion (cast / lexical_cast) +BOOST_DEFUN([Conversion], +[BOOST_FIND_HEADER([boost/cast.hpp]) +BOOST_FIND_HEADER([boost/lexical_cast.hpp]) +])# BOOST_CONVERSION + + +# BOOST_COROUTINE([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Coroutine. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. This library was introduced in Boost +# 1.53.0 +BOOST_DEFUN([Coroutine], +[ +boost_coroutine_save_LIBS=$LIBS +boost_coroutine_save_LDFLAGS=$LDFLAGS +# Link-time dependency from coroutine to context +BOOST_CONTEXT([$1]) +# Starting from Boost 1.55 a dependency on Boost.System is added +if test $boost_major_version -ge 155; then + BOOST_SYSTEM([$1]) +fi +m4_pattern_allow([^BOOST_(CONTEXT|SYSTEM)_(LIBS|LDFLAGS)]) +LIBS="$LIBS $BOOST_CONTEXT_LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_CONTEXT_LDFLAGS" + +# in 1.53 coroutine was a header only library +if test $boost_major_version -eq 153; then + BOOST_FIND_HEADER([boost/coroutine/coroutine.hpp]) +else + BOOST_FIND_LIB([coroutine], [$1], + [boost/coroutine/coroutine.hpp], + [ + #include <boost/version.hpp> + #if BOOST_VERSION <= 105500 + boost::coroutines::coroutine<int(int)> coro; coro.get(); + #else + boost::coroutines::asymmetric_coroutine<int>::pull_type coro; coro.get(); + #endif + ]) +fi +# Link-time dependency from coroutine to context, existed only in 1.53, in 1.54 +# coroutine doesn't use context from its headers but from its library. +if test $boost_major_version -eq 153 || test $enable_static_boost = yes && test $boost_major_version -ge 154; then + BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_CONTEXT_LIBS" + BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_CONTEXT_LDFLAGS" +fi +if test $enable_static_boost = yes && test $boost_major_version -ge 155; then + BOOST_COROUTINE_LIBS="$BOOST_COROUTINE_LIBS $BOOST_SYSTEM_LIBS" + BOOST_COROUTINE_LDFLAGS="$BOOST_COROUTINE_LDFLAGS $BOOST_SYSTEM_LDFLAGS" +fi +LIBS=$boost_coroutine_save_LIBS +LDFLAGS=$boost_coroutine_save_LDFLAGS +])# BOOST_COROUTINE + + +# BOOST_CRC() +# ----------- +# Look for Boost.CRC +BOOST_DEFUN([CRC], +[BOOST_FIND_HEADER([boost/crc.hpp]) +])# BOOST_CRC + + +# BOOST_DATE_TIME([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Date_Time. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Date_Time], +[BOOST_FIND_LIB([date_time], [$1], + [boost/date_time/posix_time/posix_time.hpp], + [boost::posix_time::ptime t;]) +])# BOOST_DATE_TIME + + +# BOOST_FILESYSTEM([PREFERRED-RT-OPT]) +# ------------------------------------ +# Look for Boost.Filesystem. For the documentation of PREFERRED-RT-OPT, see +# the documentation of BOOST_FIND_LIB above. +# Do not check for boost/filesystem.hpp because this file was introduced in +# 1.34. +BOOST_DEFUN([Filesystem], +[# Do we have to check for Boost.System? This link-time dependency was +# added as of 1.35.0. If we have a version <1.35, we must not attempt to +# find Boost.System as it didn't exist by then. +if test $boost_major_version -ge 135; then + BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +boost_filesystem_save_LIBS=$LIBS +boost_filesystem_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +BOOST_FIND_LIB([filesystem], [$1], + [boost/filesystem/path.hpp], [boost::filesystem::path p;]) +if test $enable_static_boost = yes && test $boost_major_version -ge 135; then + BOOST_FILESYSTEM_LIBS="$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" +fi +LIBS=$boost_filesystem_save_LIBS +LDFLAGS=$boost_filesystem_save_LDFLAGS +])# BOOST_FILESYSTEM + + +# BOOST_FLYWEIGHT() +# ----------------- +# Look for Boost.Flyweight. +BOOST_DEFUN([Flyweight], +[dnl There's a hidden dependency on pthreads. +AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl +BOOST_FIND_HEADER([boost/flyweight.hpp]) +AC_SUBST([BOOST_FLYWEIGHT_LIBS], [$boost_cv_pthread_flag]) +]) + + +# BOOST_FOREACH() +# --------------- +# Look for Boost.Foreach. +BOOST_DEFUN([Foreach], +[BOOST_FIND_HEADER([boost/foreach.hpp])]) + + +# BOOST_FORMAT() +# -------------- +# Look for Boost.Format. +# Note: we can't check for boost/format/format_fwd.hpp because the header isn't +# standalone. It can't be compiled because it triggers the following error: +# boost/format/detail/config_macros.hpp:88: error: 'locale' in namespace 'std' +# does not name a type +BOOST_DEFUN([Format], +[BOOST_FIND_HEADER([boost/format.hpp])]) + + +# BOOST_FUNCTION() +# ---------------- +# Look for Boost.Function +BOOST_DEFUN([Function], +[BOOST_FIND_HEADER([boost/function.hpp])]) + + +# BOOST_GEOMETRY() +# ---------------- +# Look for Boost.Geometry (new since 1.47.0). +BOOST_DEFUN([Geometry], +[BOOST_FIND_HEADER([boost/geometry.hpp]) +])# BOOST_GEOMETRY + + +# BOOST_GRAPH([PREFERRED-RT-OPT]) +# ------------------------------- +# Look for Boost.Graphs. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Graph], +[boost_graph_save_LIBS=$LIBS +boost_graph_save_LDFLAGS=$LDFLAGS +# Link-time dependency from graph to regex was added as of 1.40.0. +if test $boost_major_version -ge 140; then + BOOST_REGEX([$1]) + m4_pattern_allow([^BOOST_REGEX_(LIBS|LDFLAGS)$])dnl + LIBS="$LIBS $BOOST_REGEX_LIBS" + LDFLAGS="$LDFLAGS $BOOST_REGEX_LDFLAGS" +fi +BOOST_FIND_LIB([graph], [$1], + [boost/graph/adjacency_list.hpp], [boost::adjacency_list<> g;]) +LIBS=$boost_graph_save_LIBS +LDFLAGS=$boost_graph_save_LDFLAGS +])# BOOST_GRAPH + + +# BOOST_IOSTREAMS([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.IOStreams. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([IOStreams], +[BOOST_FIND_LIB([iostreams], [$1], + [boost/iostreams/device/file_descriptor.hpp], + [boost::iostreams::file_descriptor fd; fd.close();]) +])# BOOST_IOSTREAMS + + +# BOOST_HASH() +# ------------ +# Look for Boost.Functional/Hash +BOOST_DEFUN([Hash], +[BOOST_FIND_HEADER([boost/functional/hash.hpp])]) + + +# BOOST_LAMBDA() +# -------------- +# Look for Boost.Lambda +BOOST_DEFUN([Lambda], +[BOOST_FIND_HEADER([boost/lambda/lambda.hpp])]) + + +# BOOST_LOCALE() +# -------------- +# Look for Boost.Locale +BOOST_DEFUN([Locale], +[ +boost_locale_save_LIBS=$LIBS +boost_locale_save_LDFLAGS=$LDFLAGS +# require SYSTEM for boost-1.50.0 and up +if test $boost_major_version -ge 150; then + BOOST_SYSTEM([$1]) + m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl + LIBS="$LIBS $BOOST_SYSTEM_LIBS" + LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +fi # end of the Boost.System check. +BOOST_FIND_LIB([locale], [$1], + [boost/locale.hpp], + [[boost::locale::generator gen; std::locale::global(gen(""));]]) +LIBS=$boost_locale_save_LIBS +LDFLAGS=$boost_locale_save_LDFLAGS +])# BOOST_LOCALE + +# BOOST_LOG([PREFERRED-RT-OPT]) +# ----------------------------- +# Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Log], +[boost_log_save_LIBS=$LIBS +boost_log_save_LDFLAGS=$LDFLAGS +BOOST_SYSTEM([$1]) +BOOST_FILESYSTEM([$1]) +BOOST_DATE_TIME([$1]) +m4_pattern_allow([^BOOST_(SYSTEM|FILESYSTEM|DATE_TIME)_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_DATE_TIME_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" +LDFLAGS="$LDFLAGS $BOOST_DATE_TIME_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS $BOOST_SYSTEM_LDFLAGS" +BOOST_FIND_LIB([log], [$1], + [boost/log/core/core.hpp], + [boost::log::attribute a; a.get_value();]) +LIBS=$boost_log_save_LIBS +LDFLAGS=$boost_log_save_LDFLAGS +])# BOOST_LOG + + +# BOOST_LOG_SETUP([PREFERRED-RT-OPT]) +# ----------------------------------- +# Look for Boost.Log. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Log_Setup], +[boost_log_setup_save_LIBS=$LIBS +boost_log_setup_save_LDFLAGS=$LDFLAGS +BOOST_LOG([$1]) +m4_pattern_allow([^BOOST_LOG_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_LOG_LIBS" +LDFLAGS="$LDFLAGS $BOOST_LOG_LDFLAGS" +BOOST_FIND_LIB([log_setup], [$1], + [boost/log/utility/setup/from_settings.hpp], + [boost::log::basic_settings<char> bs; bs.empty();]) +LIBS=$boost_log_setup_save_LIBS +LDFLAGS=$boost_log_setup_save_LDFLAGS +])# BOOST_LOG_SETUP + + +# BOOST_MATH() +# ------------ +# Look for Boost.Math +# TODO: This library isn't header-only but it comes in multiple different +# flavors that don't play well with BOOST_FIND_LIB (e.g, libboost_math_c99, +# libboost_math_c99f, libboost_math_c99l, libboost_math_tr1, +# libboost_math_tr1f, libboost_math_tr1l). This macro must be fixed to do the +# right thing anyway. +BOOST_DEFUN([Math], +[BOOST_FIND_HEADER([boost/math/special_functions.hpp])]) + + +# BOOST_MPI([PREFERRED-RT-OPT]) +# ------------------------------- +# Look for Boost MPI. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. Uses MPICXX variable if it is +# set, otherwise tries CXX +# +BOOST_DEFUN([MPI], +[boost_save_CXX=${CXX} +boost_save_CXXCPP=${CXXCPP} +if test x"${MPICXX}" != x; then + CXX=${MPICXX} + CXXCPP="${MPICXX} -E" +fi +BOOST_FIND_LIB([mpi], [$1], + [boost/mpi.hpp], + [int argc = 0; + char **argv = 0; + boost::mpi::environment env(argc,argv);]) +CXX=${boost_save_CXX} +CXXCPP=${boost_save_CXXCPP} +])# BOOST_MPI + + +# BOOST_MULTIARRAY() +# ------------------ +# Look for Boost.MultiArray +BOOST_DEFUN([MultiArray], +[BOOST_FIND_HEADER([boost/multi_array.hpp])]) + + +# BOOST_NUMERIC_UBLAS() +# -------------------------- +# Look for Boost.NumericUblas (Basic Linear Algebra) +BOOST_DEFUN([Numeric_Ublas], +[BOOST_FIND_HEADER([boost/numeric/ublas/vector.hpp]) +])# BOOST_NUMERIC_UBLAS + + +# BOOST_NUMERIC_CONVERSION() +# -------------------------- +# Look for Boost.NumericConversion (policy-based numeric conversion) +BOOST_DEFUN([Numeric_Conversion], +[BOOST_FIND_HEADER([boost/numeric/conversion/converter.hpp]) +])# BOOST_NUMERIC_CONVERSION + + +# BOOST_OPTIONAL() +# ---------------- +# Look for Boost.Optional +BOOST_DEFUN([Optional], +[BOOST_FIND_HEADER([boost/optional.hpp])]) + + +# BOOST_PREPROCESSOR() +# -------------------- +# Look for Boost.Preprocessor +BOOST_DEFUN([Preprocessor], +[BOOST_FIND_HEADER([boost/preprocessor/repeat.hpp])]) + + +# BOOST_RANGE() +# -------------------- +# Look for Boost.Range +BOOST_DEFUN([Range], +[BOOST_FIND_HEADER([boost/range/adaptors.hpp])]) + +# BOOST_UNORDERED() +# ----------------- +# Look for Boost.Unordered +BOOST_DEFUN([Unordered], +[BOOST_FIND_HEADER([boost/unordered_map.hpp])]) + + +# BOOST_UUID() +# ------------ +# Look for Boost.Uuid +BOOST_DEFUN([Uuid], +[BOOST_FIND_HEADER([boost/uuid/uuid.hpp])]) + + +# BOOST_PROGRAM_OPTIONS([PREFERRED-RT-OPT]) +# ----------------------------------------- +# Look for Boost.Program_options. For the documentation of PREFERRED-RT-OPT, +# see the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Program_Options], +[BOOST_FIND_LIB([program_options], [$1], + [boost/program_options.hpp], + [boost::program_options::options_description d("test");]) +])# BOOST_PROGRAM_OPTIONS + + + +# _BOOST_PYTHON_CONFIG(VARIABLE, FLAG) +# ------------------------------------ +# Save VARIABLE, and define it via `python-config --FLAG`. +# Substitute BOOST_PYTHON_VARIABLE. +m4_define([_BOOST_PYTHON_CONFIG], +[AC_SUBST([BOOST_PYTHON_$1], + [`python-config --$2 2>/dev/null`])dnl +boost_python_save_$1=$$1 +$1="$$1 $BOOST_PYTHON_$1"]) + + +# BOOST_PYTHON([PREFERRED-RT-OPT]) +# -------------------------------- +# Look for Boost.Python. For the documentation of PREFERRED-RT-OPT, +# see the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Python], +[_BOOST_PYTHON_CONFIG([CPPFLAGS], [includes]) +_BOOST_PYTHON_CONFIG([LDFLAGS], [ldflags]) +_BOOST_PYTHON_CONFIG([LIBS], [libs]) +m4_pattern_allow([^BOOST_PYTHON_MODULE$])dnl +BOOST_FIND_LIBS([python], [python python3], [$1], + [boost/python.hpp], + [], [BOOST_PYTHON_MODULE(empty) {}]) +CPPFLAGS=$boost_python_save_CPPFLAGS +LDFLAGS=$boost_python_save_LDFLAGS +LIBS=$boost_python_save_LIBS +])# BOOST_PYTHON + + +# BOOST_REF() +# ----------- +# Look for Boost.Ref +BOOST_DEFUN([Ref], +[BOOST_FIND_HEADER([boost/ref.hpp])]) + + +# BOOST_REGEX([PREFERRED-RT-OPT]) +# ------------------------------- +# Look for Boost.Regex. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Regex], +[BOOST_FIND_LIB([regex], [$1], + [boost/regex.hpp], + [boost::regex exp("*"); boost::regex_match("foo", exp);]) +])# BOOST_REGEX + + +# BOOST_SERIALIZATION([PREFERRED-RT-OPT]) +# --------------------------------------- +# Look for Boost.Serialization. For the documentation of PREFERRED-RT-OPT, see +# the documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Serialization], +[BOOST_FIND_LIB([serialization], [$1], + [boost/archive/text_oarchive.hpp], + [std::ostream* o = 0; // Cheap way to get an ostream... + boost::archive::text_oarchive t(*o);]) +])# BOOST_SERIALIZATION + + +# BOOST_SIGNALS([PREFERRED-RT-OPT]) +# --------------------------------- +# Look for Boost.Signals. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Signals], +[BOOST_FIND_LIB([signals], [$1], + [boost/signal.hpp], + [boost::signal<void ()> s;]) +])# BOOST_SIGNALS + + +# BOOST_SIGNALS2() +# ---------------- +# Look for Boost.Signals2 (new since 1.39.0). +BOOST_DEFUN([Signals2], +[BOOST_FIND_HEADER([boost/signals2.hpp]) +])# BOOST_SIGNALS2 + + +# BOOST_SMART_PTR() +# ----------------- +# Look for Boost.SmartPtr +BOOST_DEFUN([Smart_Ptr], +[BOOST_FIND_HEADER([boost/scoped_ptr.hpp]) +BOOST_FIND_HEADER([boost/shared_ptr.hpp]) +]) + + +# BOOST_STATICASSERT() +# -------------------- +# Look for Boost.StaticAssert +BOOST_DEFUN([StaticAssert], +[BOOST_FIND_HEADER([boost/static_assert.hpp])]) + + +# BOOST_STRING_ALGO() +# ------------------- +# Look for Boost.StringAlgo +BOOST_DEFUN([String_Algo], +[BOOST_FIND_HEADER([boost/algorithm/string.hpp]) +]) + + +# BOOST_SYSTEM([PREFERRED-RT-OPT]) +# -------------------------------- +# Look for Boost.System. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. This library was introduced in Boost +# 1.35.0. +BOOST_DEFUN([System], +[BOOST_FIND_LIB([system], [$1], + [boost/system/error_code.hpp], + [boost::system::error_code e; e.clear();]) +])# BOOST_SYSTEM + + +# BOOST_TEST([PREFERRED-RT-OPT]) +# ------------------------------ +# Look for Boost.Test. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Test], +[m4_pattern_allow([^BOOST_CHECK$])dnl +BOOST_FIND_LIB([unit_test_framework], [$1], + [boost/test/unit_test.hpp], [BOOST_CHECK(2 == 2);], + [using boost::unit_test::test_suite; + test_suite* init_unit_test_suite(int argc, char ** argv) + { return NULL; }]) +])# BOOST_TEST + + +# BOOST_THREAD([PREFERRED-RT-OPT]) +# --------------------------------- +# Look for Boost.Thread. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Thread], +[dnl Having the pthread flag is required at least on GCC3 where +dnl boost/thread.hpp would complain if we try to compile without +dnl -pthread on GNU/Linux. +AC_REQUIRE([_BOOST_PTHREAD_FLAG])dnl +boost_thread_save_LIBS=$LIBS +boost_thread_save_LDFLAGS=$LDFLAGS +boost_thread_save_CPPFLAGS=$CPPFLAGS +# Link-time dependency from thread to system was added as of 1.49.0. +if test $boost_major_version -ge 149; then +BOOST_SYSTEM([$1]) +fi # end of the Boost.System check. +m4_pattern_allow([^BOOST_SYSTEM_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +CPPFLAGS="$CPPFLAGS $boost_cv_pthread_flag" + +# When compiling for the Windows platform, the threads library is named +# differently. This suffix doesn't exist in new versions of Boost, or +# possibly new versions of GCC on mingw I am assuming it's Boost's change for +# now and I am setting version to 1.48, for lack of knowledge as to when this +# change occurred. +if test $boost_major_version -lt 148; then + case $host_os in + (*mingw*) boost_thread_lib_ext=_win32;; + esac +fi +BOOST_FIND_LIBS([thread], [thread$boost_thread_lib_ext], + [$1], + [boost/thread.hpp], [boost::thread t; boost::mutex m;]) + +case $host_os in + (*mingw*) boost_thread_w32_socket_link=-lws2_32;; +esac + +BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS $BOOST_SYSTEM_LIBS $boost_cv_pthread_flag $boost_thread_w32_socket_link" +BOOST_THREAD_LDFLAGS="$BOOST_SYSTEM_LDFLAGS" +BOOST_CPPFLAGS="$BOOST_CPPFLAGS $boost_cv_pthread_flag" +LIBS=$boost_thread_save_LIBS +LDFLAGS=$boost_thread_save_LDFLAGS +CPPFLAGS=$boost_thread_save_CPPFLAGS +])# BOOST_THREAD + +AU_ALIAS([BOOST_THREADS], [BOOST_THREAD]) + + +# BOOST_TOKENIZER() +# ----------------- +# Look for Boost.Tokenizer +BOOST_DEFUN([Tokenizer], +[BOOST_FIND_HEADER([boost/tokenizer.hpp])]) + + +# BOOST_TRIBOOL() +# --------------- +# Look for Boost.Tribool +BOOST_DEFUN([Tribool], +[BOOST_FIND_HEADER([boost/logic/tribool_fwd.hpp]) +BOOST_FIND_HEADER([boost/logic/tribool.hpp]) +]) + + +# BOOST_TUPLE() +# ------------- +# Look for Boost.Tuple +BOOST_DEFUN([Tuple], +[BOOST_FIND_HEADER([boost/tuple/tuple.hpp])]) + + +# BOOST_TYPETRAITS() +# -------------------- +# Look for Boost.TypeTraits +BOOST_DEFUN([TypeTraits], +[BOOST_FIND_HEADER([boost/type_traits.hpp])]) + + +# BOOST_UTILITY() +# --------------- +# Look for Boost.Utility (noncopyable, result_of, base-from-member idiom, +# etc.) +BOOST_DEFUN([Utility], +[BOOST_FIND_HEADER([boost/utility.hpp])]) + + +# BOOST_VARIANT() +# --------------- +# Look for Boost.Variant. +BOOST_DEFUN([Variant], +[BOOST_FIND_HEADER([boost/variant/variant_fwd.hpp]) +BOOST_FIND_HEADER([boost/variant.hpp])]) + + +# BOOST_POINTER_CONTAINER() +# ------------------------ +# Look for Boost.PointerContainer +BOOST_DEFUN([Pointer_Container], +[BOOST_FIND_HEADER([boost/ptr_container/ptr_deque.hpp]) +BOOST_FIND_HEADER([boost/ptr_container/ptr_list.hpp]) +BOOST_FIND_HEADER([boost/ptr_container/ptr_vector.hpp]) +BOOST_FIND_HEADER([boost/ptr_container/ptr_array.hpp]) +BOOST_FIND_HEADER([boost/ptr_container/ptr_set.hpp]) +BOOST_FIND_HEADER([boost/ptr_container/ptr_map.hpp]) +])# BOOST_POINTER_CONTAINER + + +# BOOST_WAVE([PREFERRED-RT-OPT]) +# ------------------------------ +# NOTE: If you intend to use Wave/Spirit with thread support, make sure you +# call BOOST_THREAD first. +# Look for Boost.Wave. For the documentation of PREFERRED-RT-OPT, see the +# documentation of BOOST_FIND_LIB above. +BOOST_DEFUN([Wave], +[AC_REQUIRE([BOOST_FILESYSTEM])dnl +AC_REQUIRE([BOOST_DATE_TIME])dnl +boost_wave_save_LIBS=$LIBS +boost_wave_save_LDFLAGS=$LDFLAGS +m4_pattern_allow([^BOOST_((FILE)?SYSTEM|DATE_TIME|THREAD)_(LIBS|LDFLAGS)$])dnl +LIBS="$LIBS $BOOST_SYSTEM_LIBS $BOOST_FILESYSTEM_LIBS $BOOST_DATE_TIME_LIBS \ +$BOOST_THREAD_LIBS" +LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS $BOOST_FILESYSTEM_LDFLAGS \ +$BOOST_DATE_TIME_LDFLAGS $BOOST_THREAD_LDFLAGS" +BOOST_FIND_LIB([wave], [$1], + [boost/wave.hpp], + [boost::wave::token_id id; get_token_name(id);]) +LIBS=$boost_wave_save_LIBS +LDFLAGS=$boost_wave_save_LDFLAGS +])# BOOST_WAVE + + +# BOOST_XPRESSIVE() +# ----------------- +# Look for Boost.Xpressive (new since 1.36.0). +BOOST_DEFUN([Xpressive], +[BOOST_FIND_HEADER([boost/xpressive/xpressive.hpp])]) + + +# ----------------- # +# Internal helpers. # +# ----------------- # + + +# _BOOST_PTHREAD_FLAG() +# --------------------- +# Internal helper for BOOST_THREAD. Computes boost_cv_pthread_flag +# which must be used in CPPFLAGS and LIBS. +# +# Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, +# boost/thread.hpp will trigger a #error if -pthread isn't used: +# boost/config/requires_threads.hpp:47:5: #error "Compiler threading support +# is not turned on. Please set the correct command line options for +# threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" +# +# Based on ACX_PTHREAD: http://autoconf-archive.cryp.to/acx_pthread.html +AC_DEFUN([_BOOST_PTHREAD_FLAG], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_LANG_PUSH([C++])dnl +AC_CACHE_CHECK([for the flags needed to use pthreads], [boost_cv_pthread_flag], +[ boost_cv_pthread_flag= + # The ordering *is* (sometimes) important. Some notes on the + # individual items follow: + # (none): in case threads are in libc; should be tried before -Kthread and + # other compiler flags to prevent continual compiler warnings + # -lpthreads: AIX (must check this before -lpthread) + # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) + # -pthreads: Solaris/GCC + # -mthreads: MinGW32/GCC, Lynx/GCC + # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it + # doesn't hurt to check since this sometimes defines pthreads too; + # also defines -D_REENTRANT) + # ... -mt is also the pthreads flag for HP/aCC + # -lpthread: GNU Linux, etc. + # --thread-safe: KAI C++ + case $host_os in #( + *solaris*) + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + boost_pthread_flags="-pthreads -lpthread -mt -pthread";; #( + *) + boost_pthread_flags="-lpthreads -Kthread -kthread -llthread -pthread \ + -pthreads -mthreads -lpthread --thread-safe -mt";; + esac + # Generate the test file. + AC_LANG_CONFTEST([AC_LANG_PROGRAM([#include <pthread.h>], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0);])]) + for boost_pthread_flag in '' $boost_pthread_flags; do + boost_pthread_ok=false +dnl Re-use the test file already generated. + boost_pthreads__save_LIBS=$LIBS + LIBS="$LIBS $boost_pthread_flag" + AC_LINK_IFELSE([], + [if grep ".*$boost_pthread_flag" conftest.err; then + echo "This flag seems to have triggered warnings" >&AS_MESSAGE_LOG_FD + else + boost_pthread_ok=:; boost_cv_pthread_flag=$boost_pthread_flag + fi]) + LIBS=$boost_pthreads__save_LIBS + $boost_pthread_ok && break + done +]) +AC_LANG_POP([C++])dnl +])# _BOOST_PTHREAD_FLAG + + +# _BOOST_gcc_test(MAJOR, MINOR) +# ----------------------------- +# Internal helper for _BOOST_FIND_COMPILER_TAG. +m4_define([_BOOST_gcc_test], +["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC @ gcc$1$2"])dnl + +# _BOOST_mingw_test(MAJOR, MINOR) +# ----------------------------- +# Internal helper for _BOOST_FIND_COMPILER_TAG. +m4_define([_BOOST_mingw_test], +["defined __GNUC__ && __GNUC__ == $1 && __GNUC_MINOR__ == $2 && !defined __ICC && \ + (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ + || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw$1$2"])dnl + + +# _BOOST_FIND_COMPILER_TAG() +# -------------------------- +# Internal. When Boost is installed without --layout=system, each library +# filename will hold a suffix that encodes the compiler used during the +# build. The Boost build system seems to call this a `tag'. +AC_DEFUN([_BOOST_FIND_COMPILER_TAG], +[AC_REQUIRE([AC_PROG_CXX])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_CACHE_CHECK([for the toolset name used by Boost for $CXX], + [boost_cv_lib_tag], +[boost_cv_lib_tag=unknown +if test x$boost_cv_inc_path != xno; then + AC_LANG_PUSH([C++])dnl + # The following tests are mostly inspired by boost/config/auto_link.hpp + # The list is sorted to most recent/common to oldest compiler (in order + # to increase the likelihood of finding the right compiler with the + # least number of compilation attempt). + # Beware that some tests are sensible to the order (for instance, we must + # look for MinGW before looking for GCC3). + # I used one compilation test per compiler with a #error to recognize + # each compiler so that it works even when cross-compiling (let me know + # if you know a better approach). + # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): + # como, edg, kcc, bck, mp, sw, tru, xlc + # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines + # the same defines as GCC's). + for i in \ + _BOOST_mingw_test(5, 3) \ + _BOOST_gcc_test(5, 3) \ + _BOOST_mingw_test(5, 2) \ + _BOOST_gcc_test(5, 2) \ + _BOOST_mingw_test(5, 1) \ + _BOOST_gcc_test(5, 1) \ + _BOOST_mingw_test(5, 0) \ + _BOOST_gcc_test(5, 0) \ + _BOOST_mingw_test(4, 10) \ + _BOOST_gcc_test(4, 10) \ + _BOOST_mingw_test(4, 9) \ + _BOOST_gcc_test(4, 9) \ + _BOOST_mingw_test(4, 8) \ + _BOOST_gcc_test(4, 8) \ + _BOOST_mingw_test(4, 7) \ + _BOOST_gcc_test(4, 7) \ + _BOOST_mingw_test(4, 6) \ + _BOOST_gcc_test(4, 6) \ + _BOOST_mingw_test(4, 5) \ + _BOOST_gcc_test(4, 5) \ + _BOOST_mingw_test(4, 4) \ + _BOOST_gcc_test(4, 4) \ + _BOOST_mingw_test(4, 3) \ + _BOOST_gcc_test(4, 3) \ + _BOOST_mingw_test(4, 2) \ + _BOOST_gcc_test(4, 2) \ + _BOOST_mingw_test(4, 1) \ + _BOOST_gcc_test(4, 1) \ + _BOOST_mingw_test(4, 0) \ + _BOOST_gcc_test(4, 0) \ + "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ + && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ + || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ + _BOOST_gcc_test(3, 4) \ + _BOOST_gcc_test(3, 3) \ + "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ + "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ + _BOOST_gcc_test(3, 2) \ + "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ + _BOOST_gcc_test(3, 1) \ + _BOOST_gcc_test(3, 0) \ + "defined __BORLANDC__ @ bcb" \ + "defined __ICC && (defined __unix || defined __unix__) @ il" \ + "defined __ICL @ iw" \ + "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ + _BOOST_gcc_test(2, 95) \ + "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ + "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ + "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ + "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" + do + boost_tag_test=`expr "X$i" : 'X\([[^@]]*\) @ '` + boost_tag=`expr "X$i" : 'X[[^@]]* @ \(.*\)'` + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if $boost_tag_test +/* OK */ +#else +# error $boost_tag_test +#endif +]])], [boost_cv_lib_tag=$boost_tag; break], []) + done +AC_LANG_POP([C++])dnl + case $boost_cv_lib_tag in #( + # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed + # to "gcc41" for instance. + *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. + gcc*) + boost_tag_x= + case $host_os in #( + darwin*) + if test $boost_major_version -ge 136; then + # The `x' added in r46793 of Boost. + boost_tag_x=x + fi;; + esac + # We can specify multiple tags in this variable because it's used by + # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... + boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" + ;; #( + unknown) + AC_MSG_WARN([[could not figure out which toolset name to use for $CXX]]) + boost_cv_lib_tag= + ;; + esac +fi])dnl end of AC_CACHE_CHECK +])# _BOOST_FIND_COMPILER_TAG + + +# _BOOST_GUESS_WHETHER_TO_USE_MT() +# -------------------------------- +# Compile a small test to try to guess whether we should favor MT (Multi +# Thread) flavors of Boost. Sets boost_guess_use_mt accordingly. +AC_DEFUN([_BOOST_GUESS_WHETHER_TO_USE_MT], +[# Check whether we do better use `mt' even though we weren't ask to. +AC_LANG_PUSH([C++])dnl +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined _REENTRANT || defined _MT || defined __MT__ +/* use -mt */ +#else +# error MT not needed +#endif +]])], [boost_guess_use_mt=:], [boost_guess_use_mt=false]) +AC_LANG_POP([C++])dnl +]) + +# _BOOST_AC_LINK_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# ------------------------------------------------------------------- +# Fork of _AC_LINK_IFELSE that preserves conftest.o across calls. Fragile, +# will break when Autoconf changes its internals. Requires that you manually +# rm -f conftest.$ac_objext in between to really different tests, otherwise +# you will try to link a conftest.o left behind by a previous test. +# Used to aggressively optimize BOOST_FIND_LIB (see the big comment in this +# macro). +# +# Don't use "break" in the actions, as it would short-circuit some code +# this macro runs after the actions. +m4_define([_BOOST_AC_LINK_IFELSE], +[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl +rm -f conftest$ac_exeext +boost_save_ac_ext=$ac_ext +boost_use_source=: +# If we already have a .o, re-use it. We change $ac_ext so that $ac_link +# tries to link the existing object file instead of compiling from source. +test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && + _AS_ECHO_LOG([re-using the existing conftest.$ac_objext]) +AS_IF([_AC_DO_STDERR($ac_link) && { + test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_executable_p conftest$ac_exeext +dnl FIXME: use AS_TEST_X instead when 2.61 is widespread enough. + }], + [$2], + [if $boost_use_source; then + _AC_MSG_LOG_CONFTEST + fi + $3]) +ac_objext=$boost_save_ac_objext +ac_ext=$boost_save_ac_ext +dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization) +dnl information created by the PGI compiler (conftest_ipa8_conftest.oo), +dnl as it would interfere with the next link command. +rm -f core conftest.err conftest_ipa8_conftest.oo \ + conftest$ac_exeext m4_ifval([$1], [conftest.$ac_ext])[]dnl +])# _BOOST_AC_LINK_IFELSE + +# Local Variables: +# mode: autoconf +# End: diff --git a/m4/shave.m4 b/m4/shave.m4 new file mode 100644 index 0000000..5b1f675 --- /dev/null +++ b/m4/shave.m4 @@ -0,0 +1,40 @@ +dnl Make automake/libtool output more friendly to humans +dnl +dnl SHAVE_INIT([shavedir]) +dnl +dnl shavedir: the directory where the shave script is, it defaults to +dnl $(top_builddir) +dnl +dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just +dnl before AC_CONFIG_FILE/AC_OUTPUT is perfect. This macro rewrite CC and +dnl LIBTOOL, you don't want the configure tests to have these variables +dnl re-defined. +dnl * This macro requires GNU make's -s option. + +AC_DEFUN([SHAVE_INIT], [ +dnl where can we find the shave scripts? +m4_if([$1],, + [shavedir='$(top_builddir)'], + [shavedir='$(top_builddir)'/$1]) +AC_SUBST(shavedir) +dnl make is now quiet +AC_SUBST([MAKEFLAGS], [-s]) +AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`']) +dnl we need sed +AC_CHECK_PROG(SED,sed,sed,false) +dnl substitute libtool +SHAVE_SAVED_LIBTOOL=$LIBTOOL +AC_SUBST(SHAVE_SAVED_LIBTOOL) +LIBTOOL="\$(SHELL) \$(shavedir)/shave-libtool '\$(SHAVE_SAVED_LIBTOOL)'" +AC_SUBST(LIBTOOL) +dnl substitute cc +SHAVE_SAVED_CC=$CC +SHAVE_SAVED_CXX=$CXX +AC_SUBST(SHAVE_SAVED_CC) +AC_SUBST(SHAVE_SAVED_CXX) +CC="\$(SHELL) \$(shavedir)/shave cc '\$(SHAVE_SAVED_CC)'" +CXX="\$(SHELL) \$(shavedir)/shave cxx '\$(SHAVE_SAVED_CXX)'" +AC_SUBST(CC) +AC_SUBST(CXX) +]) + diff --git a/public/Makefile.am b/public/Makefile.am new file mode 100644 index 0000000..bb4f0aa --- /dev/null +++ b/public/Makefile.am @@ -0,0 +1,38 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +DIST_SUBDIRS = include
\ No newline at end of file diff --git a/public/include/Makefile.am b/public/include/Makefile.am new file mode 100644 index 0000000..866c7f9 --- /dev/null +++ b/public/include/Makefile.am @@ -0,0 +1,50 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +DIST_SUBDIRS = client-glue + +xmpdir = $(includedir)/@EXEMPI_INCLUDE_BASE@ +xmp_HEADERS = + +noinst_HEADERS = TXMPFiles.hpp TXMPIterator.hpp \ + TXMPMeta.hpp TXMPUtils.hpp \ + XMP.hpp XMP_Version.h\ + XMP.incl_cpp\ + XMP_Const.h XMP_Environment.h \ + XMP_IO.hpp \ + XMP_UnixEndian.h \ + $(NULL) diff --git a/public/include/XMP_Const.h b/public/include/XMP_Const.h index 144baec..b8b904f 100644 --- a/public/include/XMP_Const.h +++ b/public/include/XMP_Const.h @@ -41,7 +41,7 @@ extern "C" { // case only the declarations of the XMP_... types needs to change, not all of the uses. These // types are used where fixed sizes are required in order to have a known ABI for a DLL build. -#if XMP_MacBuild | XMP_iOSBuild +#if XMP_MacBuild || XMP_iOSBuild || defined(HAVE_STDINT_H) typedef int8_t XMP_Int8; typedef int16_t XMP_Int16; @@ -893,6 +893,8 @@ enum { kXMP_GIFFile = 0x47494620UL, /// Public file format constant: 'PNG ' kXMP_PNGFile = 0x504E4720UL, + /// Public file format constant: 'WEBP ' + kXMP_WEBPFile = 0x57454250UL, /// Public file format constant: 'SWF ' kXMP_SWFFile = 0x53574620UL, diff --git a/public/include/XMP_IO.hpp b/public/include/XMP_IO.hpp index d485392..3664e3b 100644 --- a/public/include/XMP_IO.hpp +++ b/public/include/XMP_IO.hpp @@ -164,7 +164,7 @@ private: /// share state across multiple XMP_IO objects. XMP_IO ( const XMP_IO & original ); - void operator= ( const XMP_IO& in ) { *this = in; /* Avoid Win compile warnings. */ }; + XMP_IO& operator= ( const XMP_IO& in ); }; diff --git a/public/include/XMP_UnixEndian.h b/public/include/XMP_UnixEndian.h new file mode 100644 index 0000000..ff1699e --- /dev/null +++ b/public/include/XMP_UnixEndian.h @@ -0,0 +1,32 @@ +// Endian check for Unix, refactored because examples needs it. +// + +#ifdef CHECKED_ENDIANNESS + +# if defined(WORDS_BIGENDIAN) +# define kBigEndianHost 1 +# else +# define kBigEndianHost 0 +# endif + +#else + +# if __sun +# include <sys/isa_defs.h> +# ifdef _LITTLE_ENDIAN +# define kBigEndianHost 0 +# else +# define kBigEndianHost 1 +# endif +# else +# include <endian.h> +# if BYTE_ORDER == BIG_ENDIAN +# define kBigEndianHost 1 +# elif BYTE_ORDER == LITTLE_ENDIAN +# define kBigEndianHost 0 +# else +# error "Neither BIG_ENDIAN nor LITTLE_ENDIAN is set" +# endif +# endif + +#endif // CHECKED_ENDIANNESS diff --git a/public/include/client-glue/Makefile.am b/public/include/client-glue/Makefile.am new file mode 100644 index 0000000..30e58b2 --- /dev/null +++ b/public/include/client-glue/Makefile.am @@ -0,0 +1,40 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +noinst_HEADERS=TXMPFiles.incl_cpp TXMPMeta.incl_cpp WXMP_Common.hpp \ + WXMPIterator.hpp WXMPUtils.hpp\ + TXMPIterator.incl_cpp TXMPUtils.incl_cpp WXMPFiles.hpp WXMPMeta.hpp
\ No newline at end of file diff --git a/public/include/client-glue/WXMPFiles.hpp b/public/include/client-glue/WXMPFiles.hpp index 2f8bb9a..fc16bb7 100644 --- a/public/include/client-glue/WXMPFiles.hpp +++ b/public/include/client-glue/WXMPFiles.hpp @@ -36,7 +36,7 @@ extern "C" { PropagateException ( wResult ); \ XMPFilesRef result = XMPFilesRef(wResult.ptrResult) -static XMP_Bool WrapProgressReport ( XMP_ProgressReportProc proc, void * context, +inline XMP_Bool WrapProgressReport ( XMP_ProgressReportProc proc, void * context, float elapsedTime, float fractionDone, float secondsToGo ) { bool ok; @@ -50,7 +50,7 @@ static XMP_Bool WrapProgressReport ( XMP_ProgressReportProc proc, void * context // ================================================================================================= -static XMP_Bool WrapFilesErrorNotify ( XMPFiles_ErrorCallbackProc proc, void * context, +inline XMP_Bool WrapFilesErrorNotify ( XMPFiles_ErrorCallbackProc proc, void * context, XMP_StringPtr filePath, XMP_ErrorSeverity severity, XMP_Int32 cause, XMP_StringPtr message ) { bool ok; diff --git a/public/include/client-glue/WXMPMeta.hpp b/public/include/client-glue/WXMPMeta.hpp index af5a11e..28a8cdd 100644 --- a/public/include/client-glue/WXMPMeta.hpp +++ b/public/include/client-glue/WXMPMeta.hpp @@ -17,7 +17,7 @@ extern "C" { // ================================================================================================= -static XMP_Bool WrapErrorNotify ( XMPMeta_ErrorCallbackProc proc, void * context, +inline XMP_Bool WrapErrorNotify ( XMPMeta_ErrorCallbackProc proc, void * context, XMP_ErrorSeverity severity, XMP_Int32 cause, XMP_StringPtr message ) { bool ok; diff --git a/rpm/SLED10.spec b/rpm/SLED10.spec new file mode 100644 index 0000000..1dbae86 --- /dev/null +++ b/rpm/SLED10.spec @@ -0,0 +1,54 @@ +# +# spec file for package exempi +# +# Copyright (c) 2007 Novell Inc. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# + +# norootforbuild + + +Summary: XMP support library +Name: exempi +Version: 1.99.5 +Release: 1 +License: BSD +Group: System/Libraries +Source0: http://libopenraw.freedesktop.org/download/%name-%{version}.tar.gz +BuildRoot: /var/tmp/%{name}-buildroot +BuildRequires: boost-devel, expat +%define prefix /usr + +%description +XMP parsing and IO library + +%prep +%setup -q + + +%build +CFLAGS="$RPM_OPT_FLAGS" \ + ./configure --prefix=%prefix \ + --libdir=/usr/%_lib +make + +%install +rm -rf $RPM_BUILD_ROOT +DESTDIR=$RPM_BUILD_ROOT make install + +%post +%run_ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc README COPYING ChangeLog + +%{prefix}/%{_lib}/libexempi.* +%{prefix}/include/exempi-2.0/* +%{prefix}/%{_lib}/pkgconfig/*.pc + +%changelog diff --git a/samples/BlueSquares/BlueSquare.gif b/samples/BlueSquares/BlueSquare.gif Binary files differnew file mode 100644 index 0000000..7dcc9e7 --- /dev/null +++ b/samples/BlueSquares/BlueSquare.gif diff --git a/samples/BlueSquares/Makefile.am b/samples/BlueSquares/Makefile.am new file mode 100644 index 0000000..1aa0f57 --- /dev/null +++ b/samples/BlueSquares/Makefile.am @@ -0,0 +1,39 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +EXTRA_DIST=BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\ +BlueSquare.avi BlueSquare.indd BlueSquare.mov BlueSquare.pdf BlueSquare.psd BlueSquare.wav diff --git a/samples/Makefile.am b/samples/Makefile.am new file mode 100644 index 0000000..5f583f5 --- /dev/null +++ b/samples/Makefile.am @@ -0,0 +1,39 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +SUBDIRS = source +DIST_SUBDIRS = source testfiles diff --git a/samples/source/Makefile.am b/samples/source/Makefile.am new file mode 100644 index 0000000..5ebc13d --- /dev/null +++ b/samples/source/Makefile.am @@ -0,0 +1,94 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +noinst_PROGRAMS = xmpcoverage xmpfilescoverage dumpxmp dumpmainxmp\ + customschema \ + modifyingxmp \ + readingxmp \ + xmpcommandtool \ + $(NULL) + +AM_CXXFLAGS = -fexceptions -funsigned-char -fPIC \ + -Wno-multichar -Wno-ctor-dtor-privacy +AM_CPPFLAGS = -I$(top_srcdir)/public/include -I$(top_srcdir) \ + -D@EXEMPI_PLATFORM_DEF@=1 -D_FILE_OFFSET_BITS=64 + +XMPLIBS = $(top_builddir)/XMPCore/source/libXMPCore.la \ + $(top_builddir)/XMPFiles/source/libXMPFiles.la \ + $(top_builddir)/source/libxmpcommon.la -lexpat -lz \ + $(top_builddir)/third-party/zuid/interfaces/libmd5.la \ + -ldl + +if UNIX_ENV +XMPLIBS += -lrt +endif + +noinst_LTLIBRARIES = libsamplescommon.la +libsamplescommon_la_SOURCES = common/DumpFile.cpp common/DumpFile.h \ + common/Log.cpp common/Log.h \ + common/TagTree.cpp common/TagTree.h \ + common/LargeFileAccess.hpp \ + common/XMPScanner.hpp \ + common/globals.h \ + $(NULL) + +customschema_SOURCES = CustomSchema.cpp +customschema_LDADD = $(XMPLIBS) + +modifyingxmp_SOURCES = ModifyingXMP.cpp +modifyingxmp_LDADD = $(XMPLIBS) + +readingxmp_SOURCES = ReadingXMP.cpp +readingxmp_LDADD = $(XMPLIBS) + +xmpcoverage_SOURCES = XMPCoreCoverage.cpp +xmpcoverage_LDADD = $(XMPLIBS) + +xmpfilescoverage_SOURCES = XMPFilesCoverage.cpp +xmpfilescoverage_LDADD = $(XMPLIBS) + +dumpxmp_SOURCES = DumpScannedXMP.cpp +dumpxmp_LDADD = $(XMPLIBS) + +dumpmainxmp_SOURCES = DumpMainXMP.cpp +dumpmainxmp_LDADD = $(XMPLIBS) + +xmpcommandtool_SOURCES = xmpcommand/Actions.cpp xmpcommand/Actions.h \ + xmpcommand/PrintUsage.cpp xmpcommand/PrintUsage.h \ + xmpcommand/XMPCommand.cpp \ + $(NULL) +xmpcommandtool_LDADD = $(XMPLIBS) libsamplescommon.la diff --git a/samples/source/ModifyingXMP.cpp b/samples/source/ModifyingXMP.cpp index b334e70..13e687b 100644 --- a/samples/source/ModifyingXMP.cpp +++ b/samples/source/ModifyingXMP.cpp @@ -32,6 +32,7 @@ #include <iostream> #include <fstream> +#include <string.h> using namespace std; diff --git a/samples/source/common/TagTree.cpp b/samples/source/common/TagTree.cpp index 761ab22..6d0ae97 100644 --- a/samples/source/common/TagTree.cpp +++ b/samples/source/common/TagTree.cpp @@ -180,8 +180,8 @@ void TagTree::digest(LFA_FileRef file,const std::string key /*=NULL*/, } #endif - delete out; - if (!returnValue) delete value; //if we own it, we delete it + delete [] out; + if (!returnValue) delete [] value; //if we own it, we delete it } //////////////////////////////////////////////////////////////////////////////////// diff --git a/samples/source/common/XMPScanner.cpp b/samples/source/common/XMPScanner.cpp index 5678571..762638e 100644 --- a/samples/source/common/XMPScanner.cpp +++ b/samples/source/common/XMPScanner.cpp @@ -1246,13 +1246,13 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 } else { // *** snipPos->fMachine.reset ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); VC++ lacks reset #if 0 - snipPos->fMachine = auto_ptr<PacketMachine> ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); + snipPos->fMachine = unique_ptr<PacketMachine> ( new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ) ); #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. PacketMachine * pm = new PacketMachine ( bufferOffset, bufferOrigin, bufferLength ); - auto_ptr<PacketMachine> ap ( pm ); - snipPos->fMachine = ap; + unique_ptr<PacketMachine> ap ( pm ); + snipPos->fMachine = std::move(ap); } #endif thisMachine = snipPos->fMachine.get(); @@ -1271,11 +1271,11 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 snipPos->fInfo.fState = eRawInputSnip; #if 0 - snipPos->fMachine = auto_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset + snipPos->fMachine = unique_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. - auto_ptr<PacketMachine> ap ( 0 ); + unique_ptr<PacketMachine> ap ( 0 ); snipPos->fMachine = ap; } #endif @@ -1364,12 +1364,12 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 // This packet ends exactly at the end of the current snip. #if 0 - snipPos->fMachine = auto_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset + snipPos->fMachine = unique_ptr<PacketMachine>(); // *** snipPos->fMachine.reset(); VC++ lacks reset #else { // Some versions of gcc complain about the assignment operator above. This avoids the gcc bug. - auto_ptr<PacketMachine> ap ( 0 ); - snipPos->fMachine = ap; + unique_ptr<PacketMachine> ap ( 0 ); + snipPos->fMachine = std::move(ap); } #endif bufferDone = true; @@ -1381,7 +1381,7 @@ XMPScanner::Scan ( const void * bufferOrigin, XMP_Int64 bufferOffset, XMP_Int64 InternalSnipIterator tailPos = NextSnip ( snipPos ); - tailPos->fMachine = snipPos->fMachine; // auto_ptr assignment - taking ownership + tailPos->fMachine = std::move(snipPos->fMachine); // unique_ptr assignment - taking ownership thisMachine->ResetMachine (); snipPos = tailPos; diff --git a/samples/source/common/XMPScanner.hpp b/samples/source/common/XMPScanner.hpp index 1479d2d..2d2d166 100644 --- a/samples/source/common/XMPScanner.hpp +++ b/samples/source/common/XMPScanner.hpp @@ -155,7 +155,7 @@ private: // XMPScanner public: SnipInfo fInfo; // The public info about this snip. - std::auto_ptr<PacketMachine> fMachine; // The state machine for "active" snips. + std::unique_ptr<PacketMachine> fMachine; // The state machine for "active" snips. InternalSnip ( XMP_Int64 offset, XMP_Int64 length ); InternalSnip ( const InternalSnip & ); diff --git a/samples/source/common/globals.h b/samples/source/common/globals.h index 3998476..32c6a91 100644 --- a/samples/source/common/globals.h +++ b/samples/source/common/globals.h @@ -23,7 +23,7 @@ #ifdef WIN_ENV #define XMPQE_LITTLE_ENDIAN 1 - #elif (defined(MAC_ENV) || defined(UNIX_ENV) || defined(IOS_ENV)) + #elif (defined(MAC_ENV) || defined(IOS_ENV)) #if __BIG_ENDIAN__ #define XMPQE_BIG_ENDIAN 1 #elif __LITTLE_ENDIAN__ @@ -31,6 +31,13 @@ #else #error "Neither __BIG_ENDIAN__ nor __LITTLE_ENDIAN__ is set" #endif + #elif defined(UNIX_ENV) + #include "XMP_UnixEndian.h" + #if kBigEndianHost + #define XMPQE_BIG_ENDIAN 1 + #else + #define XMPQE_BIG_ENDIAN 0 + #endif #else #error "Unknown build environment, neither WIN_ENV nor MAC_ENV nor UNIX_ENV" #endif diff --git a/samples/source/xmpcommand/Actions.h b/samples/source/xmpcommand/Actions.h index f43afbc..471daba 100644 --- a/samples/source/xmpcommand/Actions.h +++ b/samples/source/xmpcommand/Actions.h @@ -9,6 +9,11 @@ #ifndef __ACTIONS_h__ #define __ACTIONS_h__ 1 +// Hack because of the defines. +#ifdef VERSION +#undef VERSION +#endif + class Actions { public: enum ACTION_TYPE { NONE, VERSION, INFO, PUT, GET, DUMP }; diff --git a/samples/source/xmpcommand/PrintUsage.cpp b/samples/source/xmpcommand/PrintUsage.cpp index 957caff..8f0fee1 100644 --- a/samples/source/xmpcommand/PrintUsage.cpp +++ b/samples/source/xmpcommand/PrintUsage.cpp @@ -14,7 +14,7 @@ using namespace std; namespace XMPQE { - void PrintUsageShort(char* exename) { + void PrintUsageShort(const char* exename) { Log::info("%s -version",exename); Log::info(" Print version information for this utility"); Log::info(""); @@ -28,7 +28,7 @@ namespace XMPQE { Log::info(""); } - void PrintUsageLong(char* exename) { + void PrintUsageLong(const char* exename) { Log::info("%s -version",exename); Log::info(" Print version information for this utility"); Log::info("%s -help",exename); @@ -64,7 +64,7 @@ namespace XMPQE { Log::info(" into the specified mediafile."); Log::info(" get <mediafile> Retrieves the XMP Packet contained in the specified mediafile."); Log::info(" dump <mediafile> Prints the XMP Packet contained in the specified mediafile to standard output. "); - Log::info(" <<??>> USE dump ONLY for known-good-output tests, do not use get. <<??>> "); + Log::info(" << ?? >> USE dump ONLY for known-good-output tests, do not use get. << ?? >> "); Log::info(""); Log::info("Examples:"); Log::info("%s info Sample.jpg",exename); diff --git a/samples/source/xmpcommand/PrintUsage.h b/samples/source/xmpcommand/PrintUsage.h index 982fe41..b8d467b 100644 --- a/samples/source/xmpcommand/PrintUsage.h +++ b/samples/source/xmpcommand/PrintUsage.h @@ -10,8 +10,8 @@ #define __XMPQE_PRINT_USAGE_h__ 1 namespace XMPQE { - void PrintUsageShort(char* exename); - void PrintUsageLong(char* exename); + void PrintUsageShort(const char* exename); + void PrintUsageLong(const char* exename); } #endif diff --git a/samples/testfiles/BlueSquare.gif b/samples/testfiles/BlueSquare.gif Binary files differnew file mode 100644 index 0000000..7dcc9e7 --- /dev/null +++ b/samples/testfiles/BlueSquare.gif diff --git a/samples/testfiles/BlueSquare.webp b/samples/testfiles/BlueSquare.webp Binary files differnew file mode 100644 index 0000000..d68328e --- /dev/null +++ b/samples/testfiles/BlueSquare.webp diff --git a/samples/testfiles/Makefile.am b/samples/testfiles/Makefile.am new file mode 100644 index 0000000..791f4be --- /dev/null +++ b/samples/testfiles/Makefile.am @@ -0,0 +1,39 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +EXTRA_DIST=BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\ +BlueSquare.avi BlueSquare.indd BlueSquare.mov BlueSquare.pdf BlueSquare.psd BlueSquare.wav BlueSquare.webp diff --git a/source/EndianUtils.hpp b/source/EndianUtils.hpp index 1ad23d6..6581f18 100644 --- a/source/EndianUtils.hpp +++ b/source/EndianUtils.hpp @@ -35,16 +35,7 @@ #error "Neither __BIG_ENDIAN__ nor __LITTLE_ENDIAN__ is set" #endif #elif XMP_UNIXBuild - #ifndef kBigEndianHost // Typically in the makefile for generic UNIX. - #if __GNUC__ && (__i386__ || __x86_64__) - #define kBigEndianHost 0 - #elif __GNUC__ && (__sparc__) - #define kBigEndianHost 1 - #define kLittleEndianHost 0 - #else - #error "Must define kBigEndianHost as 0 or 1 in the makefile." - #endif - #endif + #include "public/include/XMP_UnixEndian.h" #else #error "Unknown build environment" #endif diff --git a/source/Host_IO-POSIX.cpp b/source/Host_IO-POSIX.cpp index 5f71a28..09ec1d7 100644 --- a/source/Host_IO-POSIX.cpp +++ b/source/Host_IO-POSIX.cpp @@ -39,7 +39,7 @@ // ================================================================================================= // Make sure off_t is 64 bits and signed. -static char check_off_t_size [ (sizeof(off_t) == 8) ? 1 : -1 ]; +// static char check_off_t_size [ (sizeof(off_t) == 8) ? 1 : -1 ]; // *** No std::numeric_limits? static char check_off_t_sign [ std::numeric_limits<off_t>::is_signed ? -1 : 1 ]; static bool HaveWriteAccess( const std::string & path ); @@ -372,7 +372,7 @@ void Host_IO::Write ( Host_IO::FileRef refNum, const void * buffer, XMP_Uns32 co ssize_t bytesWritten = write ( refNum, buffer, count ); if ( bytesWritten != (ssize_t)count ) { int osCode = errno; // Capture ASAP and once, might not be thread safe. - if ( errno == ENOSPC ) { + if ( osCode == ENOSPC ) { XMP_Throw ( "Host_IO::Write, disk full", kXMPErr_DiskSpace ); } else { XMP_Throw ( "Host_IO::Write, write failure", kXMPErr_WriteError ); diff --git a/source/Makefile.am b/source/Makefile.am new file mode 100644 index 0000000..681f98f --- /dev/null +++ b/source/Makefile.am @@ -0,0 +1,60 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +noinst_LTLIBRARIES = libxmpcommon.la + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions +AM_CPPFLAGS = -I$(top_srcdir) \ + -Wall @XMPCORE_CPPFLAGS@ + +noinst_HEADERS = UnicodeConversions.hpp ExpatAdapter.hpp EndianUtils.hpp\ + XMLParserAdapter.hpp XMPFiles_IO.hpp Endian.h Host_IO.hpp XIO.hpp + + +libxmpcommon_la_SOURCES = UnicodeInlines.incl_cpp UnicodeConversions.cpp\ + XML_Node.cpp XMPFiles_IO.cpp \ + XMP_LibUtils.hpp XMP_LibUtils.cpp \ + XIO.cpp Host_IO-POSIX.cpp \ + XMP_ProgressTracker.hpp XMP_ProgressTracker.cpp \ + PerfUtils.hpp PerfUtils.cpp \ + IOUtils.hpp IOUtils.cpp \ + SafeStringAPIs.h SuppressSAL.h SafeTypes.h \ + $(NULL) + + +EXTRA_DIST = Host_IO-POSIX.cpp Host_IO-Win.cpp diff --git a/source/XIO.cpp b/source/XIO.cpp index d05180e..83c5bfd 100644 --- a/source/XIO.cpp +++ b/source/XIO.cpp @@ -37,8 +37,12 @@ static inline void MakeLowerCase ( std::string * str ) void XIO::SplitLeafName ( std::string * path, std::string * leafName ) { size_t dirPos = path->size(); - // Return if path is empty or just the slash - if ( dirPos == 0 || (dirPos == 1 && (*path)[dirPos-1] == kDirChar) ) + // Return if path is empty or just the slash or DOT + if ( dirPos == 0 || (dirPos == 1 && + ((*path)[dirPos-1] == kDirChar + || (*path)[dirPos-1] == '.') + ) + ) { leafName->erase(); path->erase(); diff --git a/source/XMLParserAdapter.hpp b/source/XMLParserAdapter.hpp index b337cb6..2527862 100644 --- a/source/XMLParserAdapter.hpp +++ b/source/XMLParserAdapter.hpp @@ -90,10 +90,10 @@ public: void ClearNode(); XML_Node ( XML_NodePtr _parent, XMP_StringPtr _name, XMP_Uns8 _kind ) - : kind(_kind), name(_name), parent(_parent), nsPrefixLen(0) {}; + : kind(_kind), name(_name), nsPrefixLen(0), parent(_parent) {}; XML_Node ( XML_NodePtr _parent, const std::string & _name, XMP_Uns8 _kind ) - : kind(_kind), name(_name), parent(_parent), nsPrefixLen(0) {}; + : kind(_kind), name(_name), nsPrefixLen(0), parent(_parent) {}; virtual ~XML_Node() { RemoveAttrs(); RemoveContent(); }; diff --git a/source/XMPFiles_IO.cpp b/source/XMPFiles_IO.cpp index 3d3c45e..b613dbd 100644 --- a/source/XMPFiles_IO.cpp +++ b/source/XMPFiles_IO.cpp @@ -98,8 +98,8 @@ XMPFiles_IO::XMPFiles_IO ( , currOffset(0) , isTemp(false) , derivedTemp(0) - , errorCallback(_errorCallback) , progressTracker(_progressTracker) + , errorCallback(_errorCallback) { XMP_FILESIO_START XMP_Assert ( this->fileRef != Host_IO::noFileRef ); diff --git a/source/XMP_LibUtils.hpp b/source/XMP_LibUtils.hpp index e4477fa..aa937b6 100644 --- a/source/XMP_LibUtils.hpp +++ b/source/XMP_LibUtils.hpp @@ -85,7 +85,7 @@ public: mutable XMP_Uns32 notifications; mutable XMP_ErrorSeverity topSeverity; - GenericErrorCallback() : notifications(0), limit(1), topSeverity(kXMPErrSev_Recoverable) {}; + GenericErrorCallback() : limit(1), notifications(0), topSeverity(kXMPErrSev_Recoverable) {}; virtual ~GenericErrorCallback() {}; void Clear() { this->notifications = 0; this->limit = 1; this->topSeverity = kXMPErrSev_Recoverable; }; @@ -554,7 +554,7 @@ private: #define IsHexDigit(ch) ( (('0' <= (ch)) && ((ch) <= '9')) || (('A' <= (ch)) && ((ch) <= 'F')) ) #define HexDigitValue(ch) ( (((ch) - '0') < 10) ? ((ch) - '0') : ((ch) - 'A' + 10) ) -static const char * kTenSpaces = " "; +#define kTenSpaces " " #define OutProcPadding(pad) { size_t padLen = (pad); \ for ( ; padLen >= 10; padLen -= 10 ) OutProcNChars ( kTenSpaces, 10 ); \ for ( ; padLen > 0; padLen -= 1 ) OutProcNChars ( " ", 1 ); } @@ -579,7 +579,7 @@ static const char * kTenSpaces = " "; #define OutProcHexByte(num) { snprintf ( buffer, sizeof(buffer), "%.2X", (unsigned char)(num) ); /* AUDIT: Using sizeof for snprintf length is safe */ \ XMP_Status _status = (*outProc) ( refCon, buffer, (XMP_StringLen)strlen(buffer) ); if ( _status != 0 ) return; } -static const char * kIndent = " "; +#define kIndent " " #define OutProcIndent(lev) { for ( size_t i = 0; i < (lev); ++i ) OutProcNChars ( kIndent, 3 ); } void DumpClearString ( const XMP_VarString & value, XMP_TextOutputProc outProc, void * refCon ); diff --git a/third-party/Makefile.am b/third-party/Makefile.am new file mode 100644 index 0000000..211ebcf --- /dev/null +++ b/third-party/Makefile.am @@ -0,0 +1,4 @@ + +SUBDIRS = zuid/interfaces + +DIST_SUBDIRS = zuid/interfaces zlib expat diff --git a/third-party/expat/Makefile.am b/third-party/expat/Makefile.am new file mode 100644 index 0000000..c6f44fb --- /dev/null +++ b/third-party/expat/Makefile.am @@ -0,0 +1,3 @@ + + +EXTRA_DIST=ReadMe.txt lib/expat.h diff --git a/third-party/expat/lib/expat.h b/third-party/expat/lib/expat.h new file mode 100644 index 0000000..cca1bc6 --- /dev/null +++ b/third-party/expat/lib/expat.h @@ -0,0 +1,3 @@ +// Exempi: use a system header instead +#include <expat.h> + diff --git a/third-party/zlib/Makefile.am b/third-party/zlib/Makefile.am new file mode 100644 index 0000000..3e40bb2 --- /dev/null +++ b/third-party/zlib/Makefile.am @@ -0,0 +1,3 @@ + + +EXTRA_DIST=ReadMe.txt zlib.h diff --git a/third-party/zlib/zlib.h b/third-party/zlib/zlib.h new file mode 100644 index 0000000..f4615cd --- /dev/null +++ b/third-party/zlib/zlib.h @@ -0,0 +1,2 @@ +// Proxy. Use system zlib. +#include <zlib.h> diff --git a/third-party/zuid/interfaces/Makefile.am b/third-party/zuid/interfaces/Makefile.am new file mode 100644 index 0000000..2a602a1 --- /dev/null +++ b/third-party/zuid/interfaces/Makefile.am @@ -0,0 +1,50 @@ +# +# exempi - Makefile.am +# +# Copyright (C) 2007-2013 Hubert Figuiere +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1 Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2 Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the +# distribution. +# +# 3 Neither the name of the Authors, nor the names of its +# contributors may be used to endorse or promote products derived +# from this software wit hout specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# + + +AM_CXXFLAGS = -Wno-multichar -Wno-ctor-dtor-privacy \ + -funsigned-char -fexceptions +AM_CPPFLAGS = -I$(top_srcdir)/public/include \ + -I$(top_srcdir)/public/include/client-glue \ + -I$(top_srcdir)/build/ \ + -I$(top_srcdir) \ + -Wall @XMPCORE_CPPFLAGS@ + +noinst_LTLIBRARIES = libmd5.la + + + +libmd5_la_SOURCES = MD5.cpp MD5.h |