diff options
author | Hubert Figuiere <hub@figuiere.net> | 2007-05-14 20:38:53 -0400 |
---|---|---|
committer | Hubert Figuiere <hub@figuiere.net> | 2007-05-14 20:38:53 -0400 |
commit | 4dc06db1fe5f0239151f975e178a82aab0fa4f53 (patch) | |
tree | d6afcbdb49aba2a5a25a7049fde21ec7762abe6c | |
parent | aec572f746dac209241adf8f717d066d70061756 (diff) |
firs try at the API + basic make check.
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | openxmp/Makefile.am | 18 | ||||
-rw-r--r-- | openxmp/openxmp.cpp | 132 | ||||
-rw-r--r-- | openxmp/tests/Makefile.am | 16 | ||||
-rw-r--r-- | openxmp/tests/test1.cpp | 181 | ||||
-rw-r--r-- | openxmp/tests/test1.xmp | 179 | ||||
-rwxr-xr-x | openxmp/tests/testcore.sh | 29 | ||||
-rw-r--r-- | openxmp/xmp.h | 189 | ||||
-rw-r--r-- | samples/source/Makefile.am | 12 | ||||
-rw-r--r-- | source/XMPCore/Makefile.am | 8 | ||||
-rw-r--r-- | source/XMPFiles/Makefile.am | 8 |
12 files changed, 760 insertions, 18 deletions
diff --git a/Makefile.am b/Makefile.am index 187e73b..0310cc5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,3 @@ -SUBDIRS = third-party source samples -DIST_SUBDIRS = public build source samples
\ No newline at end of file +SUBDIRS = third-party source samples openxmp +DIST_SUBDIRS = public build third-party source samples openxmp docs
\ No newline at end of file diff --git a/configure.ac b/configure.ac index 4946bf4..26049f1 100644 --- a/configure.ac +++ b/configure.ac @@ -57,4 +57,6 @@ source/XMPFiles/FileHandlers/Makefile source/XMPFiles/FormatSupport/Makefile samples/Makefile samples/source/Makefile +openxmp/Makefile +openxmp/tests/Makefile ]) diff --git a/openxmp/Makefile.am b/openxmp/Makefile.am new file mode 100644 index 0000000..779d806 --- /dev/null +++ b/openxmp/Makefile.am @@ -0,0 +1,18 @@ + +SUBDIRS = tests + +openxmpdir = $(includedir)/@OPENXMP_INCLUDE_BASE@/openxmp +openxmp_HEADERS = xmp.h + +INCLUDES = -I$(top_srcdir)/public/include + +AM_CPPFLAGS = -Wall +lib_LTLIBRARIES = libopenxmp.la + +libopenxmp_la_SOURCES = openxmp.cpp + +libopenxmp_la_LIBADD = $(top_builddir)/source/common/libxmpcommon.la \ + $(top_builddir)/source/XMPCore/libXMPCore.la \ + $(top_builddir)/source/XMPFiles/libXMPFiles.la \ + $(top_builddir)/third-party/MD5/libmd5.la +libopenxmp_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@
\ No newline at end of file diff --git a/openxmp/openxmp.cpp b/openxmp/openxmp.cpp new file mode 100644 index 0000000..2d0a50e --- /dev/null +++ b/openxmp/openxmp.cpp @@ -0,0 +1,132 @@ +/* + * openxmp - openxmp.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. + */ + +/** @brief this file implement the glue for XMP API + */ + +#include "xmp.h" + +#include <string> + +#define XMP_INCLUDE_XMPFILES 1 +#define UNIX_ENV 1 +#define TXMP_STRING_TYPE std::string +#include "XMP.hpp" + + +#ifdef __cplusplus +extern "C" { +#endif + + +XmpFilePtr xmp_files_new() +{ + SXMPFiles *txf = new SXMPFiles(); + return (XmpFilePtr)txf; +} + +XmpFilePtr xmp_files_open_new(const char *path) +{ + SXMPFiles *txf = new SXMPFiles(path); + + return (XmpFilePtr)txf; +} + + +bool xmp_files_open(XmpFilePtr xf, const char *path) +{ + SXMPFiles *txf = (SXMPFiles*)xf; + return txf->OpenFile(path); +} + + +void xmp_files_close(XmpFilePtr xf) +{ + SXMPFiles *txf = (SXMPFiles*)xf; + txf->CloseFile(); +} + + +XmpPtr xmp_files_get_new_xmp(XmpFilePtr xf) +{ + SXMPMeta *xmp = new SXMPMeta(); + SXMPFiles *txf = (SXMPFiles*)xf; + + bool result = txf->GetXMP(xmp); + if(!result) { + delete xmp; + return NULL; + } + return (XmpPtr)xmp; +} + + +bool xmp_files_get_xmp(XmpFilePtr xf, XmpPtr xmp) +{ + SXMPFiles *txf = (SXMPFiles*)xf; + + return txf->GetXMP((SXMPMeta*)xmp); +} + + +void xmp_files_free(XmpFilePtr xf) +{ + SXMPFiles *txf = (SXMPFiles*)xf; + try { + delete txf; + } + catch(...) { + } +} + + +XmpPtr xmp_new(const char *buffer, size_t len) +{ + SXMPMeta *txmp = new SXMPMeta(buffer, len); + return (XmpPtr)txmp; +} + + +void xmp_free(XmpPtr xmp) +{ + SXMPMeta *txmp = (SXMPMeta *)xmp; + delete txmp; +} + + +#ifdef __cplusplus +} +#endif diff --git a/openxmp/tests/Makefile.am b/openxmp/tests/Makefile.am new file mode 100644 index 0000000..9688148 --- /dev/null +++ b/openxmp/tests/Makefile.am @@ -0,0 +1,16 @@ + + +INCLUDES = -I$(top_srcdir)/include + +check_PROGRAMS = + +check_SCRIPTS = testcore.sh + +check_DATA = test1.xmp + +EXTRA_DIST = $(check_DATA) + +TESTS = testcore.sh + +#test1_SOURCES = test1.cpp +#test1_LDADD = -L../lib -lexempi @LIBXML2_LIBS@ @BOOST_UNIT_TEST_FRAMEWORK_LIB@
\ No newline at end of file diff --git a/openxmp/tests/test1.cpp b/openxmp/tests/test1.cpp new file mode 100644 index 0000000..eb801d3 --- /dev/null +++ b/openxmp/tests/test1.cpp @@ -0,0 +1,181 @@ +/* + * exempi - test1.cpp + * + * Copyright (C) 2007 Hubert Figuiere + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + */ + +#include <stdlib.h> +#include <stdio.h> + +#include <string> + +#include <exempi/xmp.h> +#include <exempi/xmpconsts.h> + +#include <boost/static_assert.hpp> +#include <boost/test/auto_unit_test.hpp> + + +using boost::unit_test::test_suite; + +std::string g_testfile; + + +void test_exempi() +{ + 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); + + XmpPtr xmp = xmp_new(buffer, len); + + BOOST_CHECK(xmp != NULL); + + XmpTreePtr tree = xmp_get_tree(xmp); + + BOOST_CHECK(tree != NULL); + + XmpSchemaIterator iter = xmp_tree_get_schema_iter(tree); + BOOST_CHECK(iter != NULL); + int i = 0; + while (xmp_schema_iter_is_valid(iter)) { + i++; + xmp_schema_iter_next(iter); + } + BOOST_CHECK_EQUAL(i, 10); + xmp_schema_iter_free(iter); + + iter = xmp_tree_get_schema_iter(tree); + while(xmp_schema_iter_is_valid(iter)) { + if (strcmp(NS_TIFF, xmp_schema_iter_name(iter)) == 0) { + break; + } + xmp_schema_iter_next(iter); + } + BOOST_CHECK_EQUAL(xmp_schema_iter_is_valid(iter), true); + XmpSchemaPtr schema = xmp_schema_iter_value(iter); + BOOST_CHECK(schema != NULL); + + XmpPropertyIterator iter2 = xmp_schema_get_property_iter(schema); + i = 0; + while(xmp_property_iter_is_valid(iter2)) { + i++; + xmp_property_iter_next(iter2); + } + BOOST_CHECK_EQUAL(i, 5); + xmp_property_iter_free(iter2); + + iter2 = xmp_schema_get_property_iter(schema); + while(xmp_property_iter_is_valid(iter2)) { + if (strcmp(xmp_property_iter_name(iter2), "Make") == 0) { + break; + } + xmp_property_iter_next(iter2); + } + + XmpValuePtr value = xmp_property_iter_value(iter2); + const char* make = xmp_value_get_string(value); + BOOST_CHECK(make != NULL); + BOOST_CHECK_EQUAL(strcmp(make, "Canon"), 0); + + BOOST_CHECK_EQUAL(strcmp(make, xmp_get_property(xmp, NS_TIFF, "Make")), + 0); + + xmp_property_iter_free(iter2); + + xmp_schema_iter_free(iter); + + iter = xmp_tree_get_schema_iter(tree); + while(xmp_schema_iter_is_valid(iter)) { + if (strcmp(NS_TPG, xmp_schema_iter_name(iter)) == 0) { + break; + } + xmp_schema_iter_next(iter); + } + + BOOST_CHECK_EQUAL(xmp_schema_iter_is_valid(iter), true); + schema = xmp_schema_iter_value(iter); + iter2 = xmp_schema_get_property_iter(schema); + while(xmp_property_iter_is_valid(iter2)) { + if (strcmp(xmp_property_iter_name(iter2), "MaxPageSize") == 0) { + break; + } + xmp_property_iter_next(iter2); + } + BOOST_CHECK_EQUAL(xmp_property_iter_is_valid(iter2), true); + if (xmp_property_iter_is_valid(iter2)) { + value = xmp_property_iter_value(iter2); + const char *field = xmp_value_get_field(value, "unit"); + BOOST_CHECK(field != NULL); + BOOST_CHECK_EQUAL(strcmp(field, "inches"), 0); + } + xmp_property_iter_free(iter2); + + xmp_schema_iter_free(iter); + + + // lets pretend the fantastic shot taken with a Canon has been + // with a Nikon + BOOST_CHECK_EQUAL(xmp_set_property(xmp, NS_TIFF, "Make", "Nikon"), 0); + // and make sure it is really done + BOOST_CHECK_EQUAL(strcmp("Nikon", xmp_get_property(xmp, NS_TIFF, "Make")), + 0); + + + xmp_free(xmp); + + free(buffer); + fclose(f); +} + + + +test_suite* +init_unit_test_suite( int argc, char * argv[] ) +{ + test_suite* test = BOOST_TEST_SUITE("test exempi"); + + if (argc == 1) { + // no argument, lets run like we are in "check" + const char * srcdir = getenv("srcdir"); + + BOOST_ASSERT(srcdir != NULL); + g_testfile = std::string(srcdir); + g_testfile += "/test1.xmp"; + } + else { + g_testfile = argv[1]; + } + + test->add(BOOST_TEST_CASE(&test_exempi)); + + return test; +} + diff --git a/openxmp/tests/test1.xmp b/openxmp/tests/test1.xmp new file mode 100644 index 0000000..3774193 --- /dev/null +++ b/openxmp/tests/test1.xmp @@ -0,0 +1,179 @@ +<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> + </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> + </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/openxmp/tests/testcore.sh b/openxmp/tests/testcore.sh new file mode 100755 index 0000000..27b8295 --- /dev/null +++ b/openxmp/tests/testcore.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Test script. +# Currently only make sure dumpmainxmp does not crash +# Write by Hubert Figuiere <hub@figuiere.net> + +if [ -z $srcdir ] ; then + echo "$srcdir srcdir not defined." + return 255 +fi + +SAMPLES="BlueSquare.ai BlueSquare.eps BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif BlueSquare.avi BlueSquare.indd BlueSquare.pdf BlueSquare.psd BlueSquare.wav" +SAMPLES_DIR=$srcdir/../../samples/BlueSquares +DUMPMAINXMP_PROG=../../samples/source/dumpmainxmp + +if [ ! -x $DUMPMAINXMP_PROG ] ; then + echo "$DUMPMAINXMP_PROG not executable." + return 255 +fi + +for i in $SAMPLES +do + echo "Running $DUMPMAINXMP_PROG $SAMPLES_DIR/$i" + $DUMPMAINXMP_PROG $SAMPLES_DIR/$i > /dev/null + if [ $? -ne 0 ] ; then + echo "Failed" + return 255 + fi +done
\ No newline at end of file diff --git a/openxmp/xmp.h b/openxmp/xmp.h new file mode 100644 index 0000000..32cd3e8 --- /dev/null +++ b/openxmp/xmp.h @@ -0,0 +1,189 @@ +/* + * openxmp - xmp.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 __OPENXMP_XMP_H_ +#define __OPENXMP_XMP_H_ + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** pointer to XMP packet. Opaque. */ +typedef struct _Xmp *XmpPtr; +typedef struct _XmpFile *XmpFilePtr; + +XmpFilePtr xmp_files_new(); +XmpFilePtr xmp_files_open_new(const char *); + +bool xmp_files_open(XmpFilePtr xf, const char *); +void xmp_files_close(XmpFilePtr xf); + +XmpPtr xmp_files_get_new_xmp(XmpFilePtr xf); +bool xmp_files_get_xmp(XmpFilePtr xf, XmpPtr xmp); +void xmp_files_free(XmpFilePtr xf); + + +/** 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 point. Must be free with xmp_free() + */ +XmpPtr xmp_new(const char *buffer, size_t len); + +/** Free the xmp packet + * @param xmp the xmp packet to free + */ +void xmp_free(XmpPtr xmp); + + +////////////////////////////////////////////////////// + +typedef struct _XmpTree *XmpTreePtr; +typedef struct _XmpSchema *XmpSchemaPtr; +typedef struct _XmpValue *XmpValuePtr; +typedef struct _XmpSchemaIterator *XmpSchemaIterator; +typedef struct _XmpPropertyIterator *XmpPropertyIterator; + + +/** Get an XMP property from the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @return a constant pointer on the property string. + */ +const char * xmp_get_property(XmpPtr xmp, const char *schema, + const char *name); + +/** Set an XMP property from the XMP packet + * @param xmp the XMP packet + * @param schema + * @param name + * @param value 0 terminated string + * @return -1 in case of failure, 0 otherwise + */ +int xmp_set_property(XmpPtr xmp, const char *schema, + const char *name, const char *value); + + + + +/** Return an xmp tree + * @param xmp the xmp packet + * @return a pointer to the xmp tree + * The returned point belong to the xmp packet. + */ +XmpTreePtr xmp_get_tree(XmpPtr xmp); + +/** Get the iterator to walk through schemas + * @param tree the XMP tree to walk in + * @return an iterator positionned to the first item. + * The iterator must be freed by the caller using + * xmp_schema_iter_free() + */ +XmpSchemaIterator xmp_tree_get_schema_iter(XmpTreePtr tree); +/** Move to the next element + * @return 1 if still valid, 0 if reached the end. + */ +int xmp_schema_iter_next(XmpSchemaIterator iter); +/** Test if the schema iterator is valid + */ +int xmp_schema_iter_is_valid(XmpSchemaIterator iter); +/** Get the schema name at the current iterator position + * @return the name of the schema. The pointer belongs + * to the schema and can be invalidated if the XMP data + * change. + */ +const char* xmp_schema_iter_name(XmpSchemaIterator iter); +/** Get the schema out of the iterator position + * @return the schema at the iterator position. The pointer + * belongs to the tree and can be invalidated if the XMP data + * change. + */ +XmpSchemaPtr xmp_schema_iter_value(XmpSchemaIterator iter); +/** Free a schema iterator. + * @param iter the iterator to free + */ +void xmp_schema_iter_free(XmpSchemaIterator iter); + + +/** Get the iterator to go through properties + * @param schema the schema to walk through + * @return the allocated iterator, positionned to the first item. + * The iteraotor must be freed by xmp_property_iter_free() + */ +XmpPropertyIterator xmp_schema_get_property_iter(XmpSchemaPtr schema); +/** Move the iterator to the next element + * @return 1 if the iterator is still valid. 0 if the end + * is reached. + */ +int xmp_property_iter_next(XmpPropertyIterator iter); +/** Test if the iterator is valid. + */ +int xmp_property_iter_is_valid(XmpPropertyIterator iter); +/** Get the property name at the iterator location + */ +const char* xmp_property_iter_name(XmpPropertyIterator iter); +/** Get the property value at the iterator location + */ +XmpValuePtr xmp_property_iter_value(XmpPropertyIterator iter); +/** Free the iterator + */ +void xmp_property_iter_free(XmpPropertyIterator iter); + + +/** Get the string value. If it is not a string, return NULL + * @param value the value to retrieve the string from + * @return a zero terminated C string, or NULL. String belong + * to the XMP value + */ +const char* xmp_value_get_string(XmpValuePtr value); + +/** Get a struct field. + * @param value the value to retrieve the string from + * @param field the field from the structure + * @return the field value, or NULL if the value is not struct or + * the field does not exist + */ +const char* xmp_value_get_field(XmpValuePtr value, const char *field); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/samples/source/Makefile.am b/samples/source/Makefile.am index 1e67c8d..72b5bbc 100644 --- a/samples/source/Makefile.am +++ b/samples/source/Makefile.am @@ -6,20 +6,16 @@ AM_CXXFLAGS = -fexceptions -funsigned-char -fPIC \ -Wno-multichar -Wno-implicit -Wno-ctor-dtor-privacy AM_CPPFLAGS = -DUNIX_ENV=1 -D_FILE_OFFSET_BITS=64 -AM_LDFLAGS = $(top_builddir)/source/XMPCore/libXMPCore.la -static +AM_LDFLAGS = $(top_builddir)/source/XMPCore/libXMPCore.la \ + $(top_builddir)/source/XMPFiles/libXMPFiles.la \ + $(top_builddir)/source/common/libxmpcommon.la -lexpat \ + $(top_builddir)/third-party/MD5/libmd5.la INCLUDES = -I$(top_srcdir)/public/include noinst_HEADERS = XMPScanner.hpp xmpcoverage_SOURCES = XMPCoreCoverage.cpp XMPScanner.cpp - xmpfilescoverage_SOURCES = XMPFilesCoverage.cpp -xmpfilescoverage_LDFLAGS = $(top_builddir)/source/XMPCore/libXMPCore.la \ - $(top_builddir)/source/XMPFiles/libXMPFiles.la -static - dumpxmp_SOURCES = DumpScannedXMP.cpp XMPScanner.cpp - dumpmainxmp_SOURCES = DumpMainXMP.cpp -dumpmainxmp_LDFLAGS = $(top_builddir)/source/XMPCore/libXMPCore.la \ - $(top_builddir)/source/XMPFiles/libXMPFiles.la -static diff --git a/source/XMPCore/Makefile.am b/source/XMPCore/Makefile.am index d73dc34..9124aee 100644 --- a/source/XMPCore/Makefile.am +++ b/source/XMPCore/Makefile.am @@ -1,7 +1,7 @@ -lib_LTLIBRARIES = libXMPCore.la +noinst_LTLIBRARIES = libXMPCore.la INCLUDES = -I$(top_srcdir)/public/include \ -I$(top_srcdir)/public/include/client-glue \ @@ -11,7 +11,7 @@ INCLUDES = -I$(top_srcdir)/public/include \ AM_CXXFLAGS = -Wno-multichar -Wno-implicit -Wno-ctor-dtor-privacy \ -funsigned-char -fexceptions -AM_CPPFLAGS = \ +AM_CPPFLAGS = -Wall \ -DUNIX_ENV=1 -DXMP_IMPL=1 -DXMP_ClientBuild=0 \ -D_FILE_OFFSET_BITS=64 -DHAVE_EXPAT_CONFIG_H=1 -DXML_STATIC=1 @@ -36,6 +36,6 @@ libXMPCore_la_SOURCES = ExpatAdapter.cpp \ XMPMeta-Parse.cpp \ XMPUtils.cpp -libXMPCore_la_LIBADD = -lexpat $(top_builddir)/third-party/MD5/libmd5.la \ +#libXMPCore_la_LIBADD = -lexpat $(top_builddir)/third-party/MD5/libmd5.la \ ../common/libxmpcommon.la -libXMPCore_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@ +#libXMPCore_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@ diff --git a/source/XMPFiles/Makefile.am b/source/XMPFiles/Makefile.am index 61081b6..3f4448f 100644 --- a/source/XMPFiles/Makefile.am +++ b/source/XMPFiles/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = FileHandlers FormatSupport -lib_LTLIBRARIES = libXMPFiles.la +noinst_LTLIBRARIES = libXMPFiles.la INCLUDES = -I$(top_srcdir)/public/include \ -I$(top_srcdir)/public/include/client-glue \ @@ -13,7 +13,7 @@ INCLUDES = -I$(top_srcdir)/public/include \ AM_CXXFLAGS = -Wno-multichar -Wno-implicit -Wno-ctor-dtor-privacy \ -funsigned-char -fexceptions -AM_CPPFLAGS = \ +AM_CPPFLAGS = -Wall\ -DUNIX_ENV=1 -DXMP_IMPL=1 -DXMP_ClientBuild=0 \ -D_FILE_OFFSET_BITS=64 -DHAVE_EXPAT_CONFIG_H=1 -DXML_STATIC=1 \ -DDISABLE_QUICKTIME @@ -26,6 +26,6 @@ libXMPFiles_la_SOURCES = WXMPFiles.cpp XMPFiles.cpp \ XMPFiles_Impl.cpp -libXMPFiles_la_LIBADD = -lexpat ./FileHandlers/libxmpfilehandlers.la \ +libXMPFiles_la_LIBADD = ./FileHandlers/libxmpfilehandlers.la \ ./FormatSupport/libformatsupport.la -libXMPFiles_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@ +#libXMPFiles_la_LDFLAGS = -version-info @LIBXMPCORE_VERSION_INFO@ |