2

I am building an iOS app that takes picture, modify the picture, and embed XMP metadata to the picture. The problem lies in writing the XMP part. After the picture is saved in JPEG, I re-open the picture using Exiv2, write XMP, and re-save the JPEG. Here is my sample code:

Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(jpegUrl);
image->readMetadata();
Exiv2::XmpData &xmpData = image->xmpData();
if (xmpData.empty()) {
    cout<<"file XMP empty."<<endl;
}
else{
    cout<<"file XMP not empty."<<endl;
}

xmpData["Xmp.GPano.mycustomtag"] = "customString";

image->setXmpData(xmpData);
image->writeMetadata(); //Never crashes until here.

std::string xmpPacket;
if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) //Here is the problem!
{
    throw Exiv2::Error(1, "Failed to serialize XMP data");
    return;
}

Breakpoint

In my PC it works well, and using XCode and iOS simulator it also works well. The XMP is written properly to the JPEG file. However, when I tested on iPhone, it throws

Warning: XMP toolkit support not compiled in.

and the XMP is not there. I suspect that the Exiv2 didn't link properly while I was building it for iOS. Here is how I did it:

  1. Download and build Expat for all archs (i386 x86_64 armv7 armv7s arm64). I used this script to build and after a bit of adjustments it worked fine. I checked the generated libexpat.a with lipo and all archs are there. Note that Expat is required by Exiv2 if XMP is enabled.
  2. Build Exiv2 for iPhoneSimulator (i368 and x86_64) using this script with some adjustments. While building, there were no errors and as I said, everything worked fine. The configure command looks like this: ./configure --host=x86_64-apple-darwin --prefix=$PREFIXDIR/iphonesim-build --disable-dependency-tracking --enable-static=yes --enable-shared=no --disable-dependency-tracking --enable-commercial --disable-nls --disable-lensdata --without-libiconv-prefix --without-zlib --with-expat=/Users/kevin/Downloads/expat-ios
  3. However, when building for iPhoneOS (armv7, armv7s, and arm64) there was errors:

libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch armv7 -arch armv7s -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk -mios-version-min=10.2 -o ../bin/exiv2 exiv2.o actions.o utils.o -Wl,-bind_at_load -L/Users/kevin/Downloads/expat-ios/lib -L/Users/kevin/Downloads/exiv2-ios/src/exiv2-0.25/xmpsdk/src ./.libs/libexiv2.a -liconv -lexpat -ldl Undefined symbols for architecture armv7: "_WXMPIterator_DecrementRefCount_1", referenced from: TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator=(TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&) in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) Exiv2::XmpParser::decode(Exiv2::XmpData&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libexiv2.a(xmp.o)

and after long list of errors:

"MD5Init(MD5_CTX*)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) "MD5Final(unsigned char*, MD5_CTX*)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) "MD5Update(MD5_CTX*, unsigned char const*, unsigned int)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[1]: *** [exiv2] Error 1 make: *** [install] Error 2

So even though the compiler builds and the library for iPhoneOS is created, Exiv2 could not call XmpParser::encode properly and crashes. If I remove that part, it doesn't crash but the XMP is not written.

My questions are:

  1. How to make Exiv2 built properly for iPhoneOS archs?
  2. Is there any other possible causes that makes writing XMP to JPEG file in iOS not working?
Kevin
  • 311
  • 1
  • 7

0 Answers0