Merge pull request #1475 from 1div0/BMFF

Base Media File Format
main
Robin Mills 4 years ago committed by GitHub
commit 9e2ac47cf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1
.gitignore vendored

@ -15,6 +15,7 @@ xcode_build*
msvc_build*
cygwin_build*
mingw_build*
linux_build*
po/POTFILES
po/remove-potcdate.sed
po/stamp-po

@ -6,7 +6,7 @@ git:
env:
global:
- COMMON_CMAKE_OPTIONS="-DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install"
- COMMON_CMAKE_OPTIONS="-DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_ENABLE_CURL=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_TEAM_WARNINGS_AS_ERRORS=ON -DCMAKE_INSTALL_PREFIX=install"
matrix:
include:

@ -25,6 +25,7 @@ option( EXIV2_ENABLE_WIN_UNICODE "Use Unicode paths (wstring) on Windows"
option( EXIV2_ENABLE_WEBREADY "Build webready support into library" OFF )
option( EXIV2_ENABLE_CURL "USE Libcurl for HttpIo (WEBREADY)" OFF )
option( EXIV2_ENABLE_SSH "USE Libssh for SshIo (WEBREADY)" OFF )
option( EXIV2_ENABLE_BMFF "Build with BMFF support" OFF )
option( EXIV2_BUILD_SAMPLES "Build sample applications" ON )
option( EXIV2_BUILD_EXIV2_COMMAND "Build exiv2 command-line executable" ON )

@ -41,6 +41,7 @@ The file ReadMe.txt in a build bundle describes how to install the library on th
16. [Cross Platform Build and Test on Linux for MinGW](#2-16)
17. [Building with C++11 and other compilers](#2-17)
18. [Static and Shared Libraries](#2-18)
19. [Support for bmff files (CR3, HEIF and AVIF)](#2-19)
3. [License and Support](#3)
1. [License](#3-1)
2. [Support](#3-2)
@ -127,6 +128,7 @@ option( EXIV2_ENABLE_XMP "Build with XMP metadata support" ON
option( EXIV2_ENABLE_EXTERNAL_XMP "Use external version of XMP" OFF )
option( EXIV2_ENABLE_PNG "Build with png support (requires libz)" ON )
...
option( EXIV2_ENABLE_BMFF "Build with BMFF support" OFF )
577 rmills@rmillsmm:~/gnu/github/exiv2/exiv2 $
```
@ -581,13 +583,18 @@ The level of thread safety within Exiv2 varies depending on the type of metadata
Therefore, multi-threaded applications need to ensure that these two XMP functions are serialized, e.g., by calling them from an initialization section which is run before any threads are started. All exiv2 sample applications begin with:
```cpp
#include <exiv2/exiv2.hpp>
int main(int argc, const char* argv[])
{
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
#if EXIV2_TEST_VERSION(0,27,4)
Exiv2::enableBMFF(true);
#endif
...
}
```
The use of the _**thread unsafe function**_ Exiv2::enableBMFF(true) is discussed in [2.19 Support for bmff files](#2-19)
[TOC](#TOC)
@ -604,6 +611,7 @@ The exiv2 command-line program and sample applications call the following at the
```cpp
Exiv2::XmpParser::initialize();
::atexit(Exiv2::XmpParser::terminate);
Exiv2::enableBMFF(true);
```
[TOC](#TOC)
@ -773,6 +781,26 @@ This is discussed: [https://github.com/Exiv2/exiv2/issues/1230](https://github.c
[TOC](#TOC)
<div id="2-19">
2.19 Support for bmff files (CR3, HEIF and AVIF)
**Attention is drawn to the possibility that bmff support may be the subject of patent rights. _Exiv2 shall not be held responsible for identifying any or all such patent rights. Exiv2 shall not be held responsible for the legal consequences of the use of this code_.**
Access to the bmff code is guarded in two ways. Firstly, you have to build the library with the cmake option: `-DEXIV2_ENABLE_BMFF=On`. Secondly, the application must enable bmff support at run-time by calling the following function.
```cpp
EXIV2API bool enableBMFF(bool enable);
```
The return value of `enableBMFF()` reports the build status of bmff support. A return value of true indicates that the library has been built with bmff support.
Applications may wish the provide a preference setting to enable bmff support and thereby place the responsibility for the use of this code with the user of the application.
It is recommended that you enclose the call to `enableBMFF()` with the compile time macro EXIV2\_TEST\_VERSION to ensure that your code builds cleanly on earlier versions of Exiv2. It is recommended that you call enableBMFF() at process start-up as it is not threadsafe. A code snippet is provided in [2.14 Thread Safety](#2-14).
[TOC](#TOC)
<div id="3">
## 3 License and Support
@ -784,7 +812,7 @@ All project resources are accessible from the project website.
### 3.1 License
Copyright (C) 2004-2019 Exiv2 authors.
Copyright (C) 2004-2021 Exiv2 authors.
You should have received a copy of the file [COPYING](COPYING) which details the GPLv2 license.
Exiv2 is free software; you can redistribute it and/or modify
@ -1092,6 +1120,8 @@ Please note that the platform MinGW/msys2 32 is obsolete and superceded by MinGW
#### MinGW/msys2 64 bit
Install: [https://repo.msys2.org/distrib/x86\_64/msys2-x86\_64-20200903.exe](https://repo.msys2.org/distrib/x86_64/msys2-x86_64-20200903.exe)
The file `appveyor_mingw_cygwin.yml` has instructions to configure the AppVeyor CI to configures itself to build Exiv2 on MinGW/msys2 and Cygwin/64.
I use the following batch file to start the MinGW/msys2 64 bit bash shell from the Dos Command Prompt (cmd.exe)
```bat
@ -1154,7 +1184,9 @@ Please note that the platform Cygwin/32 is obsolete and superceded by Cygwin/64.
Download: [https://cygwin.com/install.html](https://cygwin.com/install.html) and run setup-x86_64.exe. I install into c:\\cygwin64
You need:
make, cmake, curl, gcc, gettext-devel pkg-config, dos2unix, tar, zlib-devel, libexpat1-devel, git, python3-interpreter, libiconv, libxml2-utils, libncurses
make, cmake, curl, gcc, gettext-devel pkg-config, dos2unix, tar, zlib-devel, libexpat1-devel, git, libxml2-devel python3-interpreter, libiconv, libxml2-utils, libncurses, libxml2-devel libxslt-devel python38 python38-pip python38-libxml2
The file `appveyor_mingw_cygwin.yml` has instructions to configure the AppVeyor CI to configures itself to build Exiv2 on MinGW/msys2 and Cygwin/64.
To build unit tests, you should install googletest-release-1.8.0 as discussed [4.3 Unit tests](#4-3)
@ -1304,5 +1336,5 @@ $ sudo pkg install developer/gcc-7
[TOC](#TOC)
Written by Robin Mills<br>robin@clanmills.com<br>Updated: 2020-11-20
Written by Robin Mills<br>robin@clanmills.com<br>Updated: 2021-03-05

@ -74,7 +74,7 @@ build_script:
- cmd: conan --version
- cmd: conan install .. -o webready=%WEBREADY% --build missing
- cmd: echo %CMAKE_GENERATOR%
- cmd: cmake -G "%CMAKE_GENERATOR%" -DEXIV2_TEAM_WARNINGS_AS_ERRORS=%WARNINGS_AS_ERRORS% -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_NLS=OFF -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_WEBREADY=%WEBREADY% -DEXIV2_BUILD_UNIT_TESTS=%UNIT_TESTS% -DCMAKE_INSTALL_PREFIX=install ..
- cmd: cmake -G "%CMAKE_GENERATOR%" -DEXIV2_TEAM_WARNINGS_AS_ERRORS=%WARNINGS_AS_ERRORS% -DCMAKE_BUILD_TYPE=Release -DEXIV2_ENABLE_NLS=OFF -DEXIV2_ENABLE_PNG=ON -DEXIV2_ENABLE_BMFF=ON -DEXIV2_ENABLE_WEBREADY=%WEBREADY% -DEXIV2_BUILD_UNIT_TESTS=%UNIT_TESTS% -DCMAKE_INSTALL_PREFIX=install ..
- cmd: cmake --build . --config Release
- cmd: cmake --build . --config Release --target install
- cmd: cd bin

@ -10,11 +10,12 @@ python3 --version
if [[ "$(uname -s)" == 'Linux' ]]; then
sudo apt-get update
sudo apt-get install cmake
if [[ "$(lsb_release -cs)" == 'focal' ]]; then
# In Ubuntu 20.04 python-pip does not exist. Furthermore we need to have the alias python for python3
sudo apt-get install cmake zlib1g-dev libssh-dev python3-pip python-is-python3 libxml2-utils
sudo apt-get install zlib1g-dev libssh-dev python3-pip python-is-python3 libxml2-utils
else
sudo apt-get install cmake zlib1g-dev libssh-dev python-pip libxml2-utils
sudo apt-get install zlib1g-dev libssh-dev python-pip libxml2-utils
fi
if [ -n "$WITH_VALGRIND" ]; then

@ -117,7 +117,7 @@ if __name__ == '__main__':
type=str,
nargs='?',
default="-DEXIV2_TEAM_EXTRA_WARNINGS=ON -DEXIV2_ENABLE_VIDEO=ON "
"-DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_BUILD_UNIT_TESTS=ON "
"-DEXIV2_ENABLE_WEBREADY=ON -DEXIV2_BUILD_UNIT_TESTS=ON -DEXIV2_ENABLE_BMFF=ON "
"-DBUILD_WITH_CCACHE=ON -DEXIV2_ENABLE_CURL=ON"
)

@ -1,8 +1,14 @@
# These flags only applies to exiv2lib, and the applications, but not to the xmp code
include(CheckCXXCompilerFlag)
if (COMPILER_IS_GCC OR COMPILER_IS_CLANG) # MINGW, Linux, APPLE, CYGWIN
if ( EXIV2_TEAM_WARNINGS_AS_ERRORS )
add_compile_options(-Werror -Wno-error=deprecated-declarations)
check_cxx_compiler_flag(-Wno-error=deprecated-copy DEPRECATED_COPY)
if ( DEPRECATED_COPY)
add_compile_options(-Wno-error=deprecated-copy)
endif ()
endif ()
if ( EXIV2_TEAM_EXTRA_WARNINGS )

@ -18,6 +18,9 @@
// Define if you want translation of program messages to the user's native language
#cmakedefine EXV_ENABLE_NLS
// Define if you want BMFF support.
#cmakedefine EXV_ENABLE_BMFF
// Define if you want video support.
#cmakedefine EXV_ENABLE_VIDEO

@ -7,6 +7,7 @@ if (${EXIV2_ENABLE_WEBREADY})
set(EXV_USE_SSH ${EXIV2_ENABLE_SSH})
set(EXV_USE_CURL ${EXIV2_ENABLE_CURL})
endif()
set(EXV_ENABLE_BMFF ${EXIV2_ENABLE_BMFF})
set(EXV_ENABLE_VIDEO ${EXIV2_ENABLE_VIDEO})
set(EXV_ENABLE_WEBREADY ${EXIV2_ENABLE_WEBREADY})
set(EXV_HAVE_LENSDATA ${EXIV2_ENABLE_LENSDATA})

@ -50,6 +50,7 @@ if ( EXIV2_ENABLE_EXTERNAL_XMP )
else()
OptionOutput( "XMP metadata support: " EXIV2_ENABLE_XMP )
endif()
OptionOutput( "Building BMFF support: " EXIV2_ENABLE_BMFF )
OptionOutput( "Native language support: " EXIV2_ENABLE_NLS )
OptionOutput( "Conversion of Windows XP tags: " EXIV2_ENABLE_PRINTUCS2 )
OptionOutput( "Nikon lens database: " EXIV2_ENABLE_LENSDATA )

@ -1,6 +1,7 @@
install(FILES
asfvideo.hpp
basicio.hpp
bmffimage.hpp
bmpimage.hpp
config.h
convert.hpp

@ -0,0 +1,170 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2021 Exiv2 authors
* This program is part of the Exiv2 distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
// *****************************************************************************
#include "exiv2lib_export.h"
// included header files
#include "image.hpp"
#include "iostream"
// *****************************************************************************
// namespace extensions
namespace Exiv2
{
EXIV2API bool enableBMFF(bool enable = true);
struct Iloc
{
Iloc(uint32_t ID = 0, uint32_t start = 0, uint32_t length = 0) : ID_(ID), start_(start), length_(length){};
virtual ~Iloc(){};
uint32_t ID_;
uint32_t start_;
uint32_t length_;
std::string toString() const;
}; // class Iloc
// *****************************************************************************
// class definitions
// Add Base Media File Format to the supported image formats
namespace ImageType
{
const int bmff = 19; //!< BMFF (bmff) image type (see class BMFF)
}
/*!
@brief Class to access BMFF images.
*/
class EXIV2API BmffImage : public Image
{
public:
//! @name Creators
//@{
/*!
@brief Constructor to open a BMFF image. Since the
constructor can not return a result, callers should check the
good() method after object construction to determine success
or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
@param create Specifies if an existing image should be read (false)
or if a new file should be created (true).
*/
BmffImage(BasicIo::AutoPtr io, bool create);
//@}
//@{
/*!
@brief parse embedded tiff file (Exif metadata)
@param root_tag root of parse tree Tag::root, Tag::cmt2 etc.
@param length tiff block length
@param start offset in file (default, io_->tell())
@
*/
void parseTiff(uint32_t root_tag, uint32_t length);
void parseTiff(uint32_t root_tag, uint32_t length,uint32_t start);
//@}
//@{
/*!
@brief parse embedded xmp/xml
@param length xmp block length
@param start offset in file
@
*/
void parseXmp(uint32_t length,uint32_t start);
//@}
//! @name Manipulators
//@{
void readMetadata() /* override */;
void writeMetadata() /* override */;
void setComment(const std::string& comment) /* override */;
void printStructure(std::ostream& out, Exiv2::PrintStructureOption option,int depth);
//@}
//! @name Accessors
//@{
std::string mimeType() const /* override */;
int pixelWidth() const;
int pixelHeight() const;
//@}
Exiv2::ByteOrder endian_ ;
private:
void openOrThrow();
/*!
@brief recursiveBoxHandler
@throw Error if we visit a box more than once
@return address of next box
@warning This function should only be called by readMetadata()
*/
long boxHandler(std::ostream& out=std::cout, Exiv2::PrintStructureOption option=kpsNone,int depth = 0);
std::string indent(int i)
{
return std::string(2*i,' ');
}
uint32_t fileType_;
std::set<uint64_t> visits_;
uint64_t visits_max_;
uint16_t unknownID_; // 0xffff
uint16_t exifID_;
uint16_t xmpID_;
std::map<uint32_t, Iloc> ilocs_;
bool bReadMetadata_;
//@}
/*!
@brief box utilities
*/
std::string toAscii(long n);
std::string boxName(uint32_t box);
bool superBox(uint32_t box);
bool fullBox(uint32_t box);
std::string uuidName(Exiv2::DataBuf& uuid);
}; // class BmffImage
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new BMFF instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::AutoPtr newBmffInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a BMFF image.
EXIV2API bool isBmffType(BasicIo& iIo, bool advance);
} // namespace Exiv2

@ -1,6 +1,6 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2018 Exiv2 authors
* Copyright (C) 2004-2021 Exiv2 authors
* This program is part of the Exiv2 distribution.
*
* This program is free software; you can redistribute it and/or
@ -17,13 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
/*!
@file exiv2.hpp
@brief Include all Exiv2 header files.
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 21-Jun-10, ahu: created
*/
#ifndef EXIV2_HPP_
#define EXIV2_HPP_
@ -52,8 +45,11 @@
#include "exiv2/mrwimage.hpp"
#include "exiv2/orfimage.hpp"
#include "exiv2/pgfimage.hpp"
#ifdef EXV_ENABLE_BMFF
#include "bmffimage.hpp"
#endif
#ifdef EXV_HAVE_LIBZ
#ifdef EXV_HAVE_LIBZ
#include "exiv2/pngimage.hpp"
#endif
@ -76,4 +72,4 @@
#include "exiv2/xmp_exiv2.hpp"
#include "exiv2/xmpsidecar.hpp"
#endif // #ifndef EXIV2_HPP_
#endif//ifndef EXIV2_HPP_

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH EXIV2 1 "Nov 6, 2020"
.TH EXIV2 1 "Mar 8, 2021"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -39,31 +39,34 @@ lB lB lB lB lB lB
_ _ _ _ _ _
l l l l l l.
Type Exif IPTC XMP Image Comments ICC Profile
JPEG Read/Write Read/Write Read/Write Read/Write Read/Write
EXV Read/Write Read/Write Read/Write Read/Write Read/Write
ARW Read Read Read - -
AVIF Read Read Read - -
BMP - - - - -
CR2 Read/Write Read/Write Read/Write - Read/Write
CR3 Read Read Read - Read
CRW Read/Write - - Read/Write -
MRW Read Read Read - -
TIFF Read/Write Read/Write Read/Write - Read/Write
WEBP Read/Write - Read/Write - Read/Write
DNG Read/Write Read/Write Read/Write - Read/Write
EPS - - Read/Write - -
EXV Read/Write Read/Write Read/Write Read/Write Read/Write
GIF - - - - -
HEIF Read Read Read - -
JP2 Read/Write Read/Write Read/Write - Read/Write
JPEG Read/Write Read/Write Read/Write Read/Write Read/Write
MRW Read Read Read - -
NEF Read/Write Read/Write Read/Write - Read/Write
ORF Read/Write Read/Write Read/Write - -
PEF Read/Write Read/Write Read/Write - Read/Write
ARW Read Read Read - -
PGF Read/Write Read/Write Read/Write Read/Write Read/Write
PNG Read/Write Read/Write Read/Write Read/Write Read/Write
PSD Read/Write Read/Write Read/Write - -
RAF Read Read Read - -
RW2 Read Read Read - -
SR2 Read Read Read - -
SRW Read/Write Read/Write Read/Write - -
ORF Read/Write Read/Write Read/Write - -
PNG Read/Write Read/Write Read/Write Read/Write Read/Write
PGF Read/Write Read/Write Read/Write Read/Write Read/Write
RAF Read Read Read - -
EPS - - Read/Write - -
XMP - - Read/Write - -
GIF - - - - -
PSD Read/Write Read/Write Read/Write - -
TGA - - - - -
BMP - - - - -
JP2 Read/Write Read/Write Read/Write - Read/Write
TIFF Read/Write Read/Write Read/Write - Read/Write
WEBP Read/Write - Read/Write - Read/Write
XMP - - Read/Write - -
.TE
.IP \(bu 2
Support for GIF, TGA and BMP images is minimal: the image format is
@ -132,7 +135,7 @@ exiv2 [ opt [arg] ]+ [ act ] file ...
.sp 1
option [arg] long option description
-a tim --adjust Modify time stamps. [+|-]HH[:MM[:SS[.mmm]]]
-b --binary This option is obsolete and does nothing.
-b --binary This option is obsolete and should not be used. Reserved for test suite (with option -pC)
-c txt --comment JPEG comment string to set in the image ('modify' action). ...
-d tgt --delete Delete target(s) for the 'delete' action. ...
-D +-n --days Time adjustment by a positive or negative number of days ...

@ -118,6 +118,12 @@ if( EXIV2_ENABLE_VIDEO )
)
endif()
if( EXIV2_ENABLE_BMFF )
target_sources(exiv2lib PRIVATE
bmffimage.cpp ../include/exiv2/bmffimage.hpp
)
endif()
# Other library target properties
# ---------------------------------------------------------

@ -230,10 +230,34 @@ namespace Action {
{
}
int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::string& path)
{
_setmode(_fileno(stdout),O_BINARY);
return printStructure(std::cout, option, path);
int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::string& path,bool binary)
{
int result = 0 ;
if ( binary && option == Exiv2::kpsIccProfile ) {
std::stringstream output(std::stringstream::out|std::stringstream::binary);
result = printStructure(output, option, path);
if ( result == 0 ) {
size_t size = (long) output.str().size();
Exiv2::DataBuf iccProfile((long)size);
Exiv2::DataBuf ascii((long)(size * 3 + 1));
ascii.pData_[size * 3] = 0;
::memcpy(iccProfile.pData_,output.str().c_str(),size);
if ( Exiv2::base64encode(iccProfile.pData_,size,(char*)ascii.pData_,size*3) ) {
long chunk = 60 ;
std::string code = std::string("data:") + std::string((char*)ascii.pData_);
long length = (long) code.size() ;
for ( long start = 0 ; start < length ; start += chunk ) {
long count = (start+chunk) < length ? chunk : length - start ;
std::cout << code.substr(start,count) << std::endl;
}
}
}
} else {
_setmode(_fileno(stdout),O_BINARY);
result = printStructure(std::cout, option, path);
}
return result;
}
int Print::run(const std::string& path)
@ -252,12 +276,12 @@ namespace Action {
case Params::pmXMP:
if (option == Exiv2::kpsNone)
option = Exiv2::kpsXMP;
rc = setModeAndPrintStructure(option, path_);
rc = setModeAndPrintStructure(option, path_,binary());
break;
case Params::pmIccProfile:
if (option == Exiv2::kpsNone)
option = Exiv2::kpsIccProfile;
rc = setModeAndPrintStructure(option, path_);
rc = setModeAndPrintStructure(option, path_,binary());
break;
}
return rc;

@ -78,10 +78,22 @@ namespace Action {
*/
virtual int run(const std::string& path) =0;
/*!
@brief Application interface to perform a task.
@param path Path of the file to process.
@return 0 if successful.
*/
bool setBinary(bool b) { bool bResult = binary_ ; binary_ = b ; return bResult ;}
bool binary() { return binary_ ; }
private:
//! Internal virtual copy constructor.
virtual Task* clone_() const =0;
//! copy binary_ from command-line params to task
bool binary_ ;
}; // class Task
/*!

@ -0,0 +1,608 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2021 Exiv2 authors
* This program is part of the Exiv2 distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
// *****************************************************************************
// #define EXIV2_DEBUG_MESSAGES
// included header files
#include "bmffimage.hpp"
#include "basicio.hpp"
#include "config.h"
#include "error.hpp"
#include "futils.hpp"
#include "image.hpp"
#include "image_int.hpp"
#include "safe_op.hpp"
#include "tiffimage.hpp"
#include "tiffimage_int.hpp"
#include "types.hpp"
#include "unused.h"
// + standard includes
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
struct BmffBoxHeader
{
uint32_t length;
uint32_t type;
};
#define TAG_ftyp 0x66747970 /**< "ftyp" File type box */
#define TAG_avif 0x61766966 /**< "avif" AVIF */
#define TAG_heic 0x68656963 /**< "heic" HEIC */
#define TAG_heif 0x68656966 /**< "heif" HEIF */
#define TAG_crx 0x63727820 /**< "crx " Canon CR3 */
#define TAG_moov 0x6d6f6f76 /**< "moov" Movie */
#define TAG_meta 0x6d657461 /**< "meta" Metadata */
#define TAG_mdat 0x6d646174 /**< "mdat" Media data */
#define TAG_uuid 0x75756964 /**< "uuid" UUID */
#define TAG_dinf 0x64696e66 /**< "dinf" Data information */
#define TAG_iprp 0x69707270 /**< "iprp" Item properties */
#define TAG_ipco 0x6970636f /**< "ipco" Item property container */
#define TAG_iinf 0x69696e66 /**< "iinf" Item info */
#define TAG_iloc 0x696c6f63 /**< "iloc" Item location */
#define TAG_ispe 0x69737065 /**< "ispe" Image spatial extents */
#define TAG_infe 0x696e6665 /**< "infe" Item Info Extention */
#define TAG_ipma 0x69706d61 /**< "ipma" Item Property Association */
#define TAG_cmt1 0x434d5431 /**< "CMT1" ifd0Id */
#define TAG_cmt2 0x434D5432 /**< "CMD2" exifID */
#define TAG_cmt3 0x434D5433 /**< "CMT3" canonID */
#define TAG_cmt4 0x434D5434 /**< "CMT4" gpsID */
#define TAG_colr 0x636f6c72 /**< "colr" */
// *****************************************************************************
// class member definitions
namespace Exiv2
{
static bool enabled = false;
EXIV2API bool enableBMFF(bool enable)
{
#ifdef EXV_ENABLE_BMFF
enabled = enable;
return true;
#else
UNUSED(enable);
return false;
#endif // EXV_ENABLE_BMFF
}
std::string Iloc::toString() const
{
return Internal::stringFormat("ID = %u from,length = %u,%u", ID_, start_, length_);
}
BmffImage::BmffImage(BasicIo::AutoPtr io, bool /* create */)
: Image(ImageType::bmff, mdExif | mdIptc | mdXmp, io)
, endian_(Exiv2::bigEndian)
{
pixelWidth_ = 0;
pixelHeight_ = 0;
bReadMetadata_ = false;
} // BmffImage::BmffImage
std::string BmffImage::toAscii(long n)
{
const char* p = (const char*)&n;
std::string result;
for (int i = 0; i < 4; i++) {
char c = p[isBigEndianPlatform() ? i : (3 - i)];
result += (32<=c && c<127) ? c // only allow 7-bit printable ascii
: c==0 ? '_' // show 0 as _
: '.' ; // others .
}
return result;
}
bool BmffImage::superBox(uint32_t box)
{
return box == TAG_moov || box == TAG_dinf || box == TAG_iprp || box == TAG_ipco || box == TAG_meta ||
box == TAG_iinf || box == TAG_iloc;
}
bool BmffImage::fullBox(uint32_t box)
{
return box == TAG_meta || box == TAG_iinf || box == TAG_iloc;
}
std::string BmffImage::mimeType() const
{
switch (fileType_) {
case TAG_avif:
return "image/avif";
case TAG_heic:
case TAG_heif:
return "image/heif";
case TAG_crx:
return "image/x-canon-cr3";
default:
return "image/generic";
}
}
int BmffImage::pixelWidth() const
{
ExifData::const_iterator imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
return imageWidth->toLong();
}
return 0;
}
int BmffImage::pixelHeight() const
{
ExifData::const_iterator imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
return imageHeight->toLong();
}
return 0;
}
std::string BmffImage::uuidName(Exiv2::DataBuf& uuid)
{
const char* uuidCano = "\x85\xC0\xB6\x87\x82\xF\x11\xE0\x81\x11\xF4\xCE\x46\x2B\x6A\x48";
const char* uuidXmp = "\xBE\x7A\xCF\xCB\x97\xA9\x42\xE8\x9C\x71\x99\x94\x91\xE3\xAF\xAC";
const char* uuidCanp = "\xEA\xF4\x2B\x5E\x1C\x98\x4B\x88\xB9\xFB\xB7\xDC\x40\x6E\x4D\x16";
const char* result = std::memcmp(uuid.pData_, uuidCano, 16) == 0 ? "cano"
: std::memcmp(uuid.pData_, uuidXmp, 16) == 0 ? "xmp"
: std::memcmp(uuid.pData_, uuidCanp, 16) == 0 ? "canp"
: "";
return result;
}
long BmffImage::boxHandler(std::ostream& out /* = std::cout*/ , Exiv2::PrintStructureOption option /* = kpsNone */,int depth /* =0 */)
{
long result = (long)io_->size();
long address = (long)io_->tell();
// never visit a box twice!
if ( depth == 0 ) visits_.clear();
if (visits_.find(address) != visits_.end() || visits_.size() > visits_max_) {
throw Error(kerCorruptedMetadata);
}
visits_.insert(address);
bool bTrace = option == kpsBasic || option == kpsRecursive ;
#ifdef EXIV2_DEBUG_MESSAGES
bTrace = true ;
#endif
BmffBoxHeader box = {0, 0};
if (io_->read((byte*)&box, sizeof(box)) != sizeof(box))
return result;
box.length = getLong((byte*)&box.length, endian_);
box.type = getLong((byte*)&box.type, endian_);
bool bLF = true;
if ( bTrace ) {
bLF = true;
out << indent(depth) << "Exiv2::BmffImage::boxHandler: " << toAscii(box.type)
<< Internal::stringFormat(" %8ld->%u ", address, box.length);
}
if (box.length == 1) {
DataBuf data(8);
io_->read(data.pData_, data.size_);
result = (long) getULongLong(data.pData_, endian_);
// sanity check
if (result < 8 || result+address > (long)io_->size()) {
result = (long)io_->size();
box.length = result;
} else {
box.length = (long) (io_->size() - address);
}
}
// read data in box and restore file position
long restore = io_->tell();
DataBuf data(box.length - 8);
io_->read(data.pData_, data.size_);
io_->seek(restore, BasicIo::beg);
uint32_t skip = 0; // read position in data.pData_
uint8_t version = 0;
uint32_t flags = 0;
if (fullBox(box.type)) {
flags = getLong(data.pData_ + skip, endian_); // version/flags
version = (int8_t)flags >> 24;
version &= 0x00ffffff;
skip += 4;
}
switch (box.type) {
case TAG_ftyp: {
fileType_ = getLong(data.pData_, endian_);
if ( bTrace ) {
out << "brand: " << toAscii(fileType_);
}
} break;
// 8.11.6.1
case TAG_iinf: {
if ( bTrace ) {
out << std::endl;
bLF = false;
}
int n = getShort(data.pData_ + skip, endian_);
skip += 2;
io_->seek(skip, BasicIo::cur);
while (n-- > 0) {
io_->seek(boxHandler(out,option,depth + 1), BasicIo::beg);
}
} break;
// 8.11.6.2
case TAG_infe: { // .__._.__hvc1_ 2 0 0 1 0 1 0 0 104 118 99 49 0
/* getLong (data.pData_+skip,endian_) ; */ skip += 4;
uint16_t ID = getShort(data.pData_ + skip, endian_);
skip += 2;
/* getShort(data.pData_+skip,endian_) ; */ skip += 2; // protection
std::string id;
std::string name((const char*)data.pData_ + skip);
if ( !name.find("Exif") ) { // "Exif" or "ExifExif"
exifID_ = ID;
id=" *** Exif ***";
} else if ( !name.find("mime\0xmp") || !name.find("mime\0application/rdf+xml") ) {
xmpID_ = ID;
id=" *** XMP ***";
}
if ( bTrace ) {
out << Internal::stringFormat("ID = %3d ", ID) << name << " " << id;
}
} break;
case TAG_moov:
case TAG_iprp:
case TAG_ipco:
case TAG_meta: {
if ( bTrace ) {
out << std::endl;
bLF = false;
}
io_->seek(skip, BasicIo::cur);
while ((long)io_->tell() < (long)(address + box.length)) {
io_->seek(boxHandler(out,option,depth + 1), BasicIo::beg);
}
// post-process meta box to recover Exif and XMP
if (box.type == TAG_meta) {
if ( ilocs_.find(exifID_) != ilocs_.end()) {
const Iloc& iloc = ilocs_.find(exifID_)->second;
if ( bTrace ) {
out << indent(depth) << "Exiv2::BMFF Exif: " << iloc.toString() << std::endl;
}
parseTiff(Internal::Tag::root,iloc.length_,iloc.start_);
}
if ( ilocs_.find(xmpID_) != ilocs_.end()) {
const Iloc& iloc = ilocs_.find(xmpID_)->second;
if ( bTrace ) {
out << indent(depth) << "Exiv2::BMFF XMP: " << iloc.toString() << std::endl;
}
parseXmp(iloc.length_,iloc.start_);
}
ilocs_.clear() ;
}
} break;
// 8.11.3.1
case TAG_iloc: {
uint8_t u = data.pData_[skip++];
uint16_t offsetSize = u >> 4;
uint16_t lengthSize = u & 0xF;
#if 0
uint16_t indexSize = 0 ;
u = data.pData_[skip++];
if ( version == 1 || version == 2 ) {
indexSize = u & 0xF ;
}
#else
skip++;
#endif
uint32_t itemCount = version < 2 ? getShort(data.pData_ + skip, endian_)
: getLong(data.pData_ + skip, endian_);
skip += version < 2 ? 2 : 4;
if (itemCount && itemCount < box.length / 14 && offsetSize == 4 && lengthSize == 4 &&
((box.length - 16) % itemCount) == 0) {
if ( bTrace ) {
out << std::endl;
bLF = false;
}
uint32_t step = (box.length - 16) / itemCount; // length of data per item.
uint32_t base = skip;
for (uint32_t i = 0; i < itemCount; i++) {
skip = base + i * step; // move in 14, 16 or 18 byte steps
uint32_t ID = version > 2 ? getLong(data.pData_ + skip, endian_)
: getShort(data.pData_ + skip, endian_);
uint32_t offset = step==14 || step==16 ? getLong(data.pData_ + skip + step - 8, endian_)
: step== 18 ? getLong(data.pData_ + skip + 4, endian_)
: 0 ;
uint32_t ldata = getLong(data.pData_ + skip + step - 4, endian_);
if ( bTrace ) {
out << indent(depth)
<< Internal::stringFormat("%8ld | %8u | ID | %4u | %6u,%6u", address + skip, step,
ID, offset, ldata)
<< std::endl;
}
// save data for post-processing in meta box
if ( offset && ldata && ID != unknownID_ ) {
ilocs_[ID] = Iloc(ID, offset, ldata);
}
}
}
} break;
case TAG_ispe: {
skip += 4;
int width = (int)getLong(data.pData_ + skip, endian_);
skip += 4;
int height = (int)getLong(data.pData_ + skip, endian_);
skip += 4;
if ( bTrace ) {
out << "pixelWidth_, pixelHeight_ = " << Internal::stringFormat("%d, %d", width, height);
}
// HEIC files can have multiple ispe records
// Store largest width/height
if (width > pixelWidth_ && height > pixelHeight_) {
pixelWidth_ = width;
pixelHeight_ = height;
}
} break;
// 12.1.5.2
case TAG_colr: {
if ( data.size_ >= (long) (skip+4+sizeof(box)) ) { // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ...
// https://www.ics.uci.edu/~dan/class/267/papers/jpeg2000.pdf
uint8_t meth = data.pData_[skip+0];
uint8_t prec = data.pData_[skip+1];
uint8_t approx = data.pData_[skip+2];
std::string colour_type = std::string((char*)data.pData_,4) ;
skip+=4;
if ( colour_type == "rICC" || colour_type == "prof" ) {
DataBuf profile(data.pData_+skip,data.size_-skip);
setIccProfile(profile);
} else if ( meth == 2 && prec == 0 && approx == 0 ) {
// JP2000 files have a 3 byte head // 2 0 0 icc......
skip -= 1 ;
DataBuf profile(data.pData_+skip,data.size_-skip);
setIccProfile(profile);
}
}
} break;
case TAG_uuid: {
DataBuf uuid(16);
io_->read(uuid.pData_, uuid.size_);
std::string name = uuidName(uuid);
if ( bTrace ) {
out << " uuidName " << name << std::endl;
bLF = false;
}
if (name == "cano") {
while ((long)io_->tell() < (long)(address + box.length)) {
io_->seek(boxHandler(out,option,depth + 1), BasicIo::beg);
}
} else if ( name == "xmp" ) {
parseXmp(box.length,io_->tell());
}
} break;
case TAG_cmt1:
parseTiff(Internal::Tag::root, box.length);
break;
case TAG_cmt2:
parseTiff(Internal::Tag::cmt2, box.length);
break;
case TAG_cmt3:
parseTiff(Internal::Tag::cmt3, box.length);
break;
case TAG_cmt4:
parseTiff(Internal::Tag::cmt4, box.length);
break;
default: break ; /* do nothing */
}
if ( bLF&& bTrace) out << std::endl;
// return address of next box
result = static_cast<long>(address + box.length);
return result;
}
void BmffImage::parseTiff(uint32_t root_tag, uint32_t length,uint32_t start)
{
// read and parse exif data
long restore = io_->tell();
DataBuf exif(length);
io_->seek(start,BasicIo::beg);
if ( exif.size_ > 8 && io_->read(exif.pData_,exif.size_) == exif.size_ ) {
// hunt for "II" or "MM"
long eof = 0xffffffff; // impossible value for punt
long punt = eof;
for ( long i = 0 ; i < exif.size_ -8 && punt==eof ; i+=2) {
if ( exif.pData_[i] == exif.pData_[i+1] )
if ( exif.pData_[i] == 'I' || exif.pData_[i] == 'M' )
punt = i;
}
if ( punt != eof ) {
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(),
exif.pData_+punt, exif.size_-punt, root_tag,
Internal::TiffMapping::findDecoder);
}
}
io_->seek(restore,BasicIo::beg);
}
void BmffImage::parseTiff(uint32_t root_tag, uint32_t length)
{
if (length > 8) {
DataBuf data(length - 8);
long bufRead = io_->read(data.pData_, data.size_);
if (io_->error())
throw Error(kerFailedToReadImageData);
if (bufRead != data.size_)
throw Error(kerInputDataReadFailed);
Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(),
data.pData_, data.size_, root_tag,
Internal::TiffMapping::findDecoder);
}
}
void BmffImage::parseXmp(uint32_t length,uint32_t start)
{
if (length > 8) {
long restore = io_->tell() ;
io_->seek(start,BasicIo::beg);
DataBuf xmp(length+1);
xmp.pData_[length]=0 ; // ensure xmp is null terminated!
if ( io_->read(xmp.pData_, length) != length )
throw Error(kerInputDataReadFailed);
if ( io_->error() )
throw Error(kerFailedToReadImageData);
try {
Exiv2::XmpParser::decode(xmpData(),std::string((char*)xmp.pData_));
} catch (...) {
throw Error(kerFailedToReadImageData);
}
io_->seek(restore,BasicIo::beg);
}
}
void BmffImage::setComment(const std::string& /*comment*/)
{
// bmff files are read-only
throw(Error(kerInvalidSettingForImage, "Image comment", "BMFF"));
} // BmffImage::setComment
void BmffImage::openOrThrow()
{
if (io_->open() != 0) {
throw Error(kerDataSourceOpenFailed, io_->path(), strError());
}
// Ensure that this is the correct image type
if (!isBmffType(*io_, false)) {
if (io_->error() || io_->eof())
throw Error(kerFailedToReadImageData);
throw Error(kerNotAnImage, "BMFF");
}
} // Bmff::openOrThrow();
void BmffImage::readMetadata()
{
openOrThrow();
IoCloser closer(*io_);
clearMetadata();
ilocs_.clear();
visits_max_ = io_->size() / 16;
unknownID_ = 0xffff;
exifID_ = unknownID_;
long address = 0;
while (address < (long)io_->size()) {
io_->seek(address, BasicIo::beg);
address = boxHandler(std::cout,kpsNone);
}
bReadMetadata_ = true;
} // BmffImage::readMetadata
void BmffImage::printStructure(std::ostream& out, Exiv2::PrintStructureOption option,int depth)
{
if ( !bReadMetadata_ ) readMetadata();
switch (option) {
default: break; // do nothing
case kpsIccProfile : {
out.write((const char*)iccProfile_.pData_,iccProfile_.size_);
} break;
#ifdef EXV_HAVE_XMP_TOOLKIT
case kpsXMP : {
std::string xmp;
if ( Exiv2::XmpParser::encode(xmp, xmpData()) ) {
throw Exiv2::Error(Exiv2::kerErrorMessage, "Failed to serialize XMP data");
}
out << xmp;
} break;
#endif
case kpsBasic : // drop
case kpsRecursive : {
openOrThrow();
IoCloser closer(*io_);
long address = 0;
while (address < (long)io_->size()) {
io_->seek(address, BasicIo::beg);
address = boxHandler(out,option,depth);
}
}; break;
}
}
void BmffImage::writeMetadata()
{
// bmff files are read-only
throw(Error(kerInvalidSettingForImage, "Image comment", "BMFF"));
} // BmffImage::writeMetadata
// *************************************************************************
// free functions
Image::AutoPtr newBmffInstance(BasicIo::AutoPtr io, bool create)
{
Image::AutoPtr image(new BmffImage(io, create));
if (!image->good()) {
image.reset();
}
return image;
}
bool isBmffType(BasicIo& iIo, bool advance)
{
if (!enabled) {
return false;
}
const int32_t len = 12;
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof()) {
return false;
}
bool matched = buf[4] == 'f' && buf[5] == 't' && buf[6] == 'y' && buf[7] == 'p';
if (!advance || !matched) {
iIo.seek(static_cast<long>(0), BasicIo::beg);
}
return matched;
}
} // namespace Exiv2

@ -49,7 +49,6 @@
#include <regex.h>
#endif
// *****************************************************************************
// local declarations
namespace {
@ -137,6 +136,10 @@ int main(int argc, char* const argv[])
textdomain(EXV_PACKAGE_NAME);
#endif
#ifdef EXV_ENABLE_BMFF
Exiv2::enableBMFF();
#endif
// Handle command line arguments
Params& params = Params::instance();
if (params.getopt(argc, argv)) {
@ -169,6 +172,7 @@ int main(int argc, char* const argv[])
std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": " << *i
<< std::endl;
}
task->setBinary(params.binary_);
int ret = task->run(*i);
if (rc == 0)
rc = ret;
@ -385,7 +389,7 @@ int Params::option(int opt, const std::string& optarg, int optopt)
case 'q': Exiv2::LogMsg::setLevel(Exiv2::LogMsg::mute); break;
case 'Q': rc = setLogLevel(optarg); break;
case 'k': preserve_ = true; break;
case 'b': binary_ = false; break;
case 'b': binary_ = true; break;
case 'u': unknown_ = false; break;
case 'f': force_ = true; fileExistsPolicy_ = overwritePolicy; break;
case 'F': force_ = true; fileExistsPolicy_ = renamePolicy; break;

@ -271,7 +271,7 @@ private:
version_(false),
verbose_(false),
force_(false),
binary_(true),
binary_(false),
unknown_(true),
preserve_(false),
timestamp_(false),

@ -139,123 +139,83 @@ namespace Exiv2 {
delete [] decodeStr;
}
// https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
static char base64_encode[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) {
const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const uint8_t* data = (const uint8_t*)data_buf;
size_t resultIndex = 0;
size_t x;
uint32_t n = 0;
size_t padCount = dataLength % 3;
uint8_t n0, n1, n2, n3;
/* increment over the length of the string, three characters at a time */
for (x = 0; x < dataLength; x += 3)
{
/* these three 8-bit (ASCII) characters become one 24-bit number */
n = data[x] << 16;
if((x+1) < dataLength)
n += data[x+1] << 8;
if((x+2) < dataLength)
n += data[x+2];
/* this 24-bit number gets separated into four 6-bit numbers */
n0 = (uint8_t)(n >> 18) & 63;
n1 = (uint8_t)(n >> 12) & 63;
n2 = (uint8_t)(n >> 6) & 63;
n3 = (uint8_t)n & 63;
/*
* if we have one byte available, then its encoding is spread
* out over two characters
*/
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex++] = base64chars[n0];
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex++] = base64chars[n1];
/*
* if we have only two bytes available, then their encoding is
* spread out over three chars
*/
if((x+1) < dataLength)
{
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex++] = base64chars[n2];
}
char* encoding_table = (char*)base64_encode;
size_t mod_table[] = {0, 2, 1};
/*
* if we have all three bytes available, then their encoding is spread
* out over four characters
*/
if((x+2) < dataLength)
{
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex++] = base64chars[n3];
}
}
size_t output_length = 4 * ((dataLength + 2) / 3);
int rc = result && data_buf && output_length < resultSize ? 1 : 0;
if ( rc ) {
const unsigned char* data = (const unsigned char*) data_buf ;
for (size_t i = 0, j = 0 ; i < dataLength;) {
/*
* create and add padding that is required if we did not have a multiple of 3
* number of characters available
*/
if (padCount > 0)
{
for (; padCount < 3; padCount++)
{
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex++] = '=';
uint32_t octet_a = i < dataLength ? data[i++] : 0 ;
uint32_t octet_b = i < dataLength ? data[i++] : 0 ;
uint32_t octet_c = i < dataLength ? data[i++] : 0 ;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
result[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
result[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
result[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
result[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
}
for (size_t i = 0; i < mod_table[dataLength % 3]; i++)
result[output_length - 1 - i] = '=';
result[output_length]=0;
}
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
result[resultIndex] = 0;
return 1; /* indicate success */
return rc;
} // base64encode
long base64decode(const char *in, char *out, size_t out_size) {
static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW"
"$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
long len;
long i;
long done = 0;
unsigned char v;
unsigned char quad[4];
while (*in) {
len = 0;
for (i = 0; i < 4 && *in; i++) {
v = 0;
while (*in && !v) {
v = *in++;
v = (v < 43 || v > 122) ? 0 : decode[v - 43];
if (v)
v = (v == '$') ? 0 : v - 61;
if (*in) {
len++;
if (v)
quad[i] = v - 1;
} else
quad[i] = 0;
}
long base64decode(const char* in,char* out,size_t out_size) {
long result = 0;
size_t input_length = in ? ::strlen(in) : 0;
if (!in || input_length % 4 != 0) return result;
unsigned char* encoding_table = (unsigned char*)base64_encode;
unsigned char decoding_table[256];
for (unsigned char i = 0; i < 64; i++)
decoding_table[encoding_table[i]] = i;
size_t output_length = input_length / 4 * 3;
const unsigned char* buff = (const unsigned char*) in;
if (buff[input_length - 1] == '=') (output_length)--;
if (buff[input_length - 2] == '=') (output_length)--;
if ( output_length+1 < out_size ) {
for (size_t i = 0, j = 0; i < input_length;) {
uint32_t sextet_a = buff[i] == '=' ? 0 & i++ : decoding_table[buff[i++]];
uint32_t sextet_b = buff[i] == '=' ? 0 & i++ : decoding_table[buff[i++]];
uint32_t sextet_c = buff[i] == '=' ? 0 & i++ : decoding_table[buff[i++]];
uint32_t sextet_d = buff[i] == '=' ? 0 & i++ : decoding_table[buff[i++]];
uint32_t triple = (sextet_a << 3 * 6)
+ (sextet_b << 2 * 6)
+ (sextet_c << 1 * 6)
+ (sextet_d << 0 * 6);
if (j < output_length) out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < output_length) out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < output_length) out[j++] = (triple >> 0 * 8) & 0xFF;
}
if (!len)
continue;
if (out_size < (size_t) (done + len - 1))
/* out buffer is too small */
return -1;
if (len >= 2)
*out++ = quad[0] << 2 | quad[1] >> 4;
if (len >= 3)
*out++ = quad[1] << 4 | quad[2] >> 2;
if (len >= 4)
*out++ = ((quad[2] << 6) & 0xc0) | quad[3];
done += len - 1;
out[output_length]=0;
result = (long) output_length;
}
if ((size_t)(done + 1) >= out_size)
return -1;
*out++ = '\0';
return done;
return result;
} // base64decode
Protocol fileProtocol(const std::string& path) {

@ -31,14 +31,17 @@
#include "safe_op.hpp"
#include "slice.hpp"
#ifdef EXV_ENABLE_BMFF
#include "bmffimage.hpp"
#endif// EXV_ENABLE_BMFF
#include "cr2image.hpp"
#include "crwimage.hpp"
#include "epsimage.hpp"
#include "jpgimage.hpp"
#include "mrwimage.hpp"
#ifdef EXV_HAVE_LIBZ
#ifdef EXV_HAVE_LIBZ
# include "pngimage.hpp"
#endif // EXV_HAVE_LIBZ
#endif// EXV_HAVE_LIBZ
#include "rafimage.hpp"
#include "tiffimage.hpp"
#include "tiffimage_int.hpp"
@ -53,12 +56,12 @@
#include "jp2image.hpp"
#include "nikonmn_int.hpp"
#ifdef EXV_ENABLE_VIDEO
#ifdef EXV_ENABLE_VIDEO
#include "matroskavideo.hpp"
#include "quicktimevideo.hpp"
#include "riffvideo.hpp"
#include "asfvideo.hpp"
#endif // EXV_ENABLE_VIDEO
#endif// EXV_ENABLE_VIDEO
#include "rw2image.hpp"
#include "pgfimage.hpp"
#include "xmpsidecar.hpp"
@ -131,6 +134,9 @@ namespace {
{ ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone },
{ ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone },
{ ImageType::jp2, newJp2Instance, isJp2Type, amReadWrite, amReadWrite, amReadWrite, amNone },
#ifdef EXV_ENABLE_BMFF
{ ImageType::bmff, newBmffInstance, isBmffType, amRead, amRead, amRead, amNone },
#endif // EXV_ENABLE_BMFF
#ifdef EXV_ENABLE_VIDEO
{ ImageType::qtime,newQTimeInstance,isQTimeType,amRead, amNone, amRead, amNone },
{ ImageType::riff, newRiffInstance, isRiffType, amRead, amNone, amRead, amNone },

@ -76,12 +76,15 @@ namespace Exiv2 {
Special TIFF tags for the use in TIFF structures only
*/
namespace Tag {
const uint32_t none = 0x10000; //!< Dummy tag
const uint32_t root = 0x20000; //!< Special tag: root IFD
const uint32_t next = 0x30000; //!< Special tag: next IFD
const uint32_t all = 0x40000; //!< Special tag: all tags in a group
const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images
const uint32_t fuji = 0x100000; //!< Special tag: root IFD of Fujifilm RAF images
const uint32_t none = 0x10000; //!< Dummy tag
const uint32_t root = 0x20000; //!< Special tag: root IFD
const uint32_t next = 0x30000; //!< Special tag: next IFD
const uint32_t all = 0x40000; //!< Special tag: all tags in a group
const uint32_t pana = 0x80000; //!< Special tag: root IFD of Panasonic RAW images
const uint32_t fuji = 0x100000; //!< Special tag: root IFD of Fujifilm RAF images
const uint32_t cmt2 = 0x110000; //!< Special tag: root IFD of CR3 images
const uint32_t cmt3 = 0x120000; //!< Special tag: root IFD of CR3 images
const uint32_t cmt4 = 0x130000; //!< Special tag: root IFD of CR3 images
}
/*!

@ -3,6 +3,7 @@
#include "error.hpp"
#include "makernote_int.hpp"
#include "sonymn_int.hpp"
#include "tags_int.hpp"
#include "tiffvisitor_int.hpp"
#include "i18n.h" // NLS support.
@ -1125,6 +1126,11 @@ namespace Exiv2 {
{ Tag::fuji, ifdIdNotSet, newTiffDirectory<fujiId> },
{ 0xf000, fujiId, newTiffSubIfd<fujiId> },
// CR3 images #1475
{ Tag::cmt2, ifdIdNotSet, newTiffDirectory<exifId> },
{ Tag::cmt3, ifdIdNotSet, newTiffDirectory<canonId> },
{ Tag::cmt4, ifdIdNotSet, newTiffDirectory<gpsId> },
// IFD0
{ 0x8769, ifd0Id, newTiffSubIfd<exifId> },
{ 0x8825, ifd0Id, newTiffSubIfd<gpsId> },

@ -345,6 +345,7 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
int have_unistd =0;
int have_unicode_path=0;
int enable_bmff =0;
int enable_video =0;
int enable_webready =0;
int enable_nls =0;
@ -461,6 +462,10 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
have_unicode_path=1;
#endif
#ifdef EXV_ENABLE_BMFF
enable_bmff=1;
#endif
#ifdef EXV_ENABLE_VIDEO
enable_video=1;
#endif
@ -544,6 +549,7 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const exv_grep_keys_t& keys)
output(os,keys,"have_sys_types" ,have_sys_types );
output(os,keys,"have_unistd" ,have_unistd );
output(os,keys,"have_unicode_path" ,have_unicode_path);
output(os,keys,"enable_bmff" ,enable_bmff );
output(os,keys,"enable_video" ,enable_video );
output(os,keys,"enable_webready" ,enable_webready );
output(os,keys,"enable_nls" ,enable_nls );

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

@ -9,8 +9,10 @@ import shlex
import shutil
import subprocess
import time
from http import server
from urllib import request
import sys
from http import server
from urllib import request
import system_tests
"""
@ -685,3 +687,66 @@ def runTestCase(num, img):
out += diff('iii', 'ttt')
return str(out)
def runTest(cmd):
"""
Executes a command in the shell.
Add this function at PR <https://github.com/Exiv2/exiv2/pull/1475> .
"""
exiv2=system_tests.exiv2
if sys.platform == 'win32':
args = cmd
else:
args = shlex.split(cmd)
# Updat PATH, LD_LIBRARY_PATH and DYLD_LIBRARY_PATH
key = "PATH"
bin_dir = os.path.dirname(exiv2)
if key in os.environ:
os.environ[key] = os.path.join(bin_dir, os.environ[key])
else:
os.environ[key] = bin_dir
for key in ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]:
lib_dir = os.path.join(os.path.dirname(os.path.dirname(exiv2)), 'lib')
if key in os.environ:
os.environ[key] = os.path.join(lib_dir, os.environ[key])
else:
os.environ[key] = lib_dir
# Execute the command
try:
p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False)
stdout, stderr = p.communicate()
if p.returncode != 0:
print('{} returncode = {}'.format(cmd, p.returncode))
# Split the output by newline
out = stdout.decode('utf-8').replace('\r', '').rstrip('\n').split('\n')
except:
print('** {} died **'.format(cmd))
return out
def verbose_version(verbose=False):
""" Get the key-value pairs of Exiv2 verbose version """
vv = {}
exiv2=system_tests.exiv2
lines = runTest(exiv2 + ' --verbose --version')
for line in lines:
kv = line.rstrip().split('=')
if len(kv) == 2:
key, val = kv
if not key in vv:
vv[key] = val
elif isinstance(vv[key], list):
vv[key].append(val)
else:
vv[key] = [vv[key]]
if verbose:
for key in vv:
val = vv[key]
if isinstance(val, list):
val = '[ {} +{} ]'.format(val[0], len(val) - 1)
print(key.ljust(20), val)
return vv

@ -0,0 +1,423 @@
# -*- coding: utf-8 -*-
import system_tests
# test needs system_tests.BT.vv.enable_bmff=1
enable_bmff = 'enable_bmff'
vv=system_tests.BT.verbose_version()
bSkip = not (enable_bmff in vv and vv[enable_bmff] == '1')
class pr_1475_avif_avif(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/avif.avif"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -pa $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.ExifTag Long 1 26
Exif.Photo.DateTimeOriginal Ascii 20 2018:08:15 11:37:35
Exif.Photo.SubSecTimeOriginal Ascii 3 59
""","""Exiv2::BmffImage::boxHandler: ftyp 0->32 brand: avif
Exiv2::BmffImage::boxHandler: meta 32->304
Exiv2::BmffImage::boxHandler: hdlr 44->33
Exiv2::BmffImage::boxHandler: pitm 77->14
Exiv2::BmffImage::boxHandler: iinf 91->56
Exiv2::BmffImage::boxHandler: infe 105->21 ID = 1 av01
Exiv2::BmffImage::boxHandler: infe 126->21 ID = 2 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: iloc 147->44
155 | 14 | ID | 1 | 408,218726
169 | 14 | ID | 2 | 219134, 82
Exiv2::BmffImage::boxHandler: iprp 191->119
Exiv2::BmffImage::boxHandler: ipco 199->88
Exiv2::BmffImage::boxHandler: ispe 207->20 pixelWidth_, pixelHeight_ = 1920, 1080
Exiv2::BmffImage::boxHandler: colr 227->19
Exiv2::BmffImage::boxHandler: av1C 246->25
Exiv2::BmffImage::boxHandler: pixi 271->16
Exiv2::BmffImage::boxHandler: ipma 287->23
Exiv2::BmffImage::boxHandler: iref 310->26
Exiv2::BMFF Exif: ID = 2 from,length = 219134,82
Exiv2::BmffImage::boxHandler: free 336->64
Exiv2::BmffImage::boxHandler: mdat 400->218816
""","",""]
class pr_1475_exif_xmp_avif(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/avif_exif_xmp.avif"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.DateTime Ascii 20 2021:02:13 21:19:50
Xmp.iptcExt.DigitalSourceType XmpText 61 http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture
Xmp.iptcExt.LocationCreated XmpBag 0
Xmp.iptcExt.LocationShown XmpBag 0
Xmp.iptcExt.ArtworkOrObject XmpBag 0
Xmp.iptcExt.RegistryId XmpBag 0
Xmp.xmpMM.DocumentID XmpText 52 gimp:docid:gimp:8cf1b29a-9b12-4dec-9930-f2c608b298de
Xmp.xmpMM.InstanceID XmpText 44 xmp.iid:33e259b4-7237-4b2a-87bf-4609986012a8
Xmp.xmpMM.OriginalDocumentID XmpText 44 xmp.did:02dfa8e8-ce11-4de7-971d-566a5bba5edb
Xmp.xmpMM.History XmpText 0 type="Seq"
Xmp.xmpMM.History[1] XmpText 0 type="Struct"
Xmp.xmpMM.History[1]/stEvt:action XmpText 5 saved
Xmp.xmpMM.History[1]/stEvt:changed XmpText 9 /metadata
Xmp.xmpMM.History[1]/stEvt:instanceID XmpText 44 xmp.iid:446f9de2-f964-4680-8461-ddf05bfcc53e
Xmp.xmpMM.History[1]/stEvt:softwareAgent XmpText 19 GIMP 2.99.5 (Linux)
Xmp.xmpMM.History[1]/stEvt:when XmpText 25 2021-02-13T21:19:04+01:00
Xmp.xmpMM.History[2] XmpText 0 type="Struct"
Xmp.xmpMM.History[2]/stEvt:action XmpText 5 saved
Xmp.xmpMM.History[2]/stEvt:changed XmpText 1 /
Xmp.xmpMM.History[2]/stEvt:instanceID XmpText 44 xmp.iid:017dc808-2418-4f70-99f3-aa05905adb88
Xmp.xmpMM.History[2]/stEvt:softwareAgent XmpText 19 GIMP 2.99.5 (Linux)
Xmp.xmpMM.History[2]/stEvt:when XmpText 25 2021-02-13T21:20:14+01:00
Xmp.plus.ModelReleaseStatus XmpText 38 None
Xmp.plus.ImageSupplier XmpSeq 0
Xmp.plus.ImageCreator XmpSeq 0
Xmp.plus.CopyrightOwner XmpSeq 0
Xmp.plus.Licensor XmpSeq 0
Xmp.GIMP.API XmpText 3 3.0
Xmp.GIMP.Platform XmpText 5 Linux
Xmp.GIMP.TimeStamp XmpText 16 1613247614397805
Xmp.GIMP.Version XmpText 6 2.99.5
Xmp.dc.Format XmpText 10 image/avif
Xmp.dc.creator XmpSeq 1 type="Seq" Developer
Xmp.dc.description LangAlt 1 lang="x-default" This is a testfile
Xmp.dc.rights LangAlt 1 lang="x-default" It is forbidden to use for evil purposes
Xmp.dc.title LangAlt 1 lang="x-default" Personal photo
Xmp.photoshop.AuthorsPosition XmpText 18 Computer Scientist
Xmp.xmp.CreatorTool XmpText 4 GIMP
Xmp.xmp.Rating XmpText 1 5
Xmp.xmpRights.Marked XmpText 4 True
""","""Exiv2::BmffImage::boxHandler: ftyp 0->32 brand: avif
Exiv2::BmffImage::boxHandler: meta 32->379
Exiv2::BmffImage::boxHandler: hdlr 44->40
Exiv2::BmffImage::boxHandler: pitm 84->14
Exiv2::BmffImage::boxHandler: iloc 98->58
106 | 14 | ID | 1 | 5418, 5445
120 | 14 | ID | 2 | 419, 316
134 | 14 | ID | 3 | 735, 4683
Exiv2::BmffImage::boxHandler: iinf 156->109
Exiv2::BmffImage::boxHandler: infe 170->26 ID = 1 av01Color
Exiv2::BmffImage::boxHandler: infe 196->25 ID = 2 ExifExif *** Exif ***
Exiv2::BmffImage::boxHandler: infe 221->44 ID = 3 mimeXMP *** XMP ***
Exiv2::BmffImage::boxHandler: iref 265->40
Exiv2::BmffImage::boxHandler: iprp 305->106
Exiv2::BmffImage::boxHandler: ipco 313->75
Exiv2::BmffImage::boxHandler: ispe 321->20 pixelWidth_, pixelHeight_ = 120, 120
Exiv2::BmffImage::boxHandler: pixi 341->16
Exiv2::BmffImage::boxHandler: av1C 357->12
Exiv2::BmffImage::boxHandler: colr 369->19
Exiv2::BmffImage::boxHandler: ipma 388->23
Exiv2::BMFF Exif: ID = 2 from,length = 419,316
Exiv2::BMFF XMP: ID = 3 from,length = 735,4683
Exiv2::BmffImage::boxHandler: mdat 411->10452
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:iptcExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/"
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
xmlns:plus="http://ns.useplus.org/ldf/xmp/1.0/"
xmlns:GIMP="http://www.gimp.org/xmp/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:xmpRights="http://ns.adobe.com/xap/1.0/rights/"
iptcExt:DigitalSourceType="http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture"
xmpMM:DocumentID="gimp:docid:gimp:8cf1b29a-9b12-4dec-9930-f2c608b298de"
xmpMM:InstanceID="xmp.iid:33e259b4-7237-4b2a-87bf-4609986012a8"
xmpMM:OriginalDocumentID="xmp.did:02dfa8e8-ce11-4de7-971d-566a5bba5edb"
plus:ModelReleaseStatus="http://ns.useplus.org/ldf/vocab/MR-NON"
GIMP:API="3.0"
GIMP:Platform="Linux"
GIMP:TimeStamp="1613247614397805"
GIMP:Version="2.99.5"
dc:Format="image/avif"
photoshop:AuthorsPosition="Computer Scientist"
xmp:CreatorTool="GIMP"
xmp:Rating="5"
xmpRights:Marked="True">
<iptcExt:LocationCreated>
<rdf:Bag/>
</iptcExt:LocationCreated>
<iptcExt:LocationShown>
<rdf:Bag/>
</iptcExt:LocationShown>
<iptcExt:ArtworkOrObject>
<rdf:Bag/>
</iptcExt:ArtworkOrObject>
<iptcExt:RegistryId>
<rdf:Bag/>
</iptcExt:RegistryId>
<xmpMM:History>
<rdf:Seq>
<rdf:li
stEvt:action="saved"
stEvt:changed="/metadata"
stEvt:instanceID="xmp.iid:446f9de2-f964-4680-8461-ddf05bfcc53e"
stEvt:softwareAgent="GIMP 2.99.5 (Linux)"
stEvt:when="2021-02-13T21:19:04+01:00"/>
<rdf:li
stEvt:action="saved"
stEvt:changed="/"
stEvt:instanceID="xmp.iid:017dc808-2418-4f70-99f3-aa05905adb88"
stEvt:softwareAgent="GIMP 2.99.5 (Linux)"
stEvt:when="2021-02-13T21:20:14+01:00"/>
</rdf:Seq>
</xmpMM:History>
<plus:ImageSupplier>
<rdf:Seq/>
</plus:ImageSupplier>
<plus:ImageCreator>
<rdf:Seq/>
</plus:ImageCreator>
<plus:CopyrightOwner>
<rdf:Seq/>
</plus:CopyrightOwner>
<plus:Licensor>
<rdf:Seq/>
</plus:Licensor>
<dc:creator>
<rdf:Seq>
<rdf:li>type="Seq" Developer</rdf:li>
</rdf:Seq>
</dc:creator>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">This is a testfile</rdf:li>
</rdf:Alt>
</dc:description>
<dc:rights>
<rdf:Alt>
<rdf:li xml:lang="x-default">It is forbidden to use for evil purposes</rdf:li>
</rdf:Alt>
</dc:rights>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang="x-default">Personal photo</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>""",""]
class pr_1475_metadata2_avif(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/avif_metadata2.avif"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.DateTime Ascii 20 2021:02:13 21:25:32
Xmp.iptcExt.DigitalSourceType XmpText 61 http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture
Xmp.iptcExt.LocationCreated XmpBag 0
Xmp.iptcExt.LocationShown XmpBag 0
Xmp.iptcExt.ArtworkOrObject XmpBag 0
Xmp.iptcExt.RegistryId XmpBag 0
Xmp.xmpMM.DocumentID XmpText 52 gimp:docid:gimp:e38231ee-2d28-42e6-b17e-6fa80c9fd85b
Xmp.xmpMM.InstanceID XmpText 44 xmp.iid:34774f89-42e3-4411-a691-f8cdb5b11def
Xmp.xmpMM.OriginalDocumentID XmpText 44 xmp.did:e2129b55-045f-4085-bbd2-e11d11edfa0c
Xmp.xmpMM.History XmpText 0 type="Seq"
Xmp.xmpMM.History[1] XmpText 0 type="Struct"
Xmp.xmpMM.History[1]/stEvt:action XmpText 5 saved
Xmp.xmpMM.History[1]/stEvt:changed XmpText 9 /metadata
Xmp.xmpMM.History[1]/stEvt:instanceID XmpText 44 xmp.iid:928b36e2-0239-4616-847a-eff7a31816e3
Xmp.xmpMM.History[1]/stEvt:softwareAgent XmpText 19 GIMP 2.99.5 (Linux)
Xmp.xmpMM.History[1]/stEvt:when XmpText 25 2021-02-13T21:24:26+01:00
Xmp.xmpMM.History[2] XmpText 0 type="Struct"
Xmp.xmpMM.History[2]/stEvt:action XmpText 5 saved
Xmp.xmpMM.History[2]/stEvt:changed XmpText 1 /
Xmp.xmpMM.History[2]/stEvt:instanceID XmpText 44 xmp.iid:23f267c5-c40a-45c8-947d-11313b4881c1
Xmp.xmpMM.History[2]/stEvt:softwareAgent XmpText 19 GIMP 2.99.5 (Linux)
Xmp.xmpMM.History[2]/stEvt:when XmpText 25 2021-02-13T21:25:41+01:00
Xmp.plus.ModelReleaseStatus XmpText 38 None
Xmp.plus.ImageSupplier XmpSeq 0
Xmp.plus.ImageCreator XmpSeq 0
Xmp.plus.CopyrightOwner XmpSeq 0
Xmp.plus.Licensor XmpSeq 0
Xmp.GIMP.API XmpText 3 3.0
Xmp.GIMP.Platform XmpText 5 Linux
Xmp.GIMP.TimeStamp XmpText 16 1613247941462908
Xmp.GIMP.Version XmpText 6 2.99.5
Xmp.dc.Format XmpText 10 image/avif
Xmp.dc.creator XmpSeq 1 type="Seq" me
Xmp.dc.description LangAlt 1 lang="x-default" bla bla bla
Xmp.xmp.CreatorTool XmpText 4 GIMP
""","""Exiv2::BmffImage::boxHandler: ftyp 0->24 brand: avif
Exiv2::BmffImage::boxHandler: meta 24->356
Exiv2::BmffImage::boxHandler: hdlr 36->33
Exiv2::BmffImage::boxHandler: pitm 69->14
Exiv2::BmffImage::boxHandler: iloc 83->70
91 | 18 | ID | 1 | 388, 4730
109 | 18 | ID | 2 | 5118, 412
127 | 18 | ID | 3 | 5530, 4254
Exiv2::BmffImage::boxHandler: iinf 153->98
Exiv2::BmffImage::boxHandler: infe 167->21 ID = 1 av01
Exiv2::BmffImage::boxHandler: infe 188->21 ID = 2 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: infe 209->42 ID = 3 mime *** XMP ***
Exiv2::BmffImage::boxHandler: iprp 251->89
Exiv2::BmffImage::boxHandler: ipco 259->59
Exiv2::BmffImage::boxHandler: colr 267->19
Exiv2::BmffImage::boxHandler: av1C 286->12
Exiv2::BmffImage::boxHandler: ispe 298->20 pixelWidth_, pixelHeight_ = 120, 120
Exiv2::BmffImage::boxHandler: ipma 318->22
Exiv2::BmffImage::boxHandler: iref 340->40
Exiv2::BMFF Exif: ID = 2 from,length = 5118,412
Exiv2::BMFF XMP: ID = 3 from,length = 5530,4254
Exiv2::BmffImage::boxHandler: mdat 380->9404
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:iptcExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/"
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
xmlns:plus="http://ns.useplus.org/ldf/xmp/1.0/"
xmlns:GIMP="http://www.gimp.org/xmp/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
iptcExt:DigitalSourceType="http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture"
xmpMM:DocumentID="gimp:docid:gimp:e38231ee-2d28-42e6-b17e-6fa80c9fd85b"
xmpMM:InstanceID="xmp.iid:34774f89-42e3-4411-a691-f8cdb5b11def"
xmpMM:OriginalDocumentID="xmp.did:e2129b55-045f-4085-bbd2-e11d11edfa0c"
plus:ModelReleaseStatus="http://ns.useplus.org/ldf/vocab/MR-NON"
GIMP:API="3.0"
GIMP:Platform="Linux"
GIMP:TimeStamp="1613247941462908"
GIMP:Version="2.99.5"
dc:Format="image/avif"
xmp:CreatorTool="GIMP">
<iptcExt:LocationCreated>
<rdf:Bag/>
</iptcExt:LocationCreated>
<iptcExt:LocationShown>
<rdf:Bag/>
</iptcExt:LocationShown>
<iptcExt:ArtworkOrObject>
<rdf:Bag/>
</iptcExt:ArtworkOrObject>
<iptcExt:RegistryId>
<rdf:Bag/>
</iptcExt:RegistryId>
<xmpMM:History>
<rdf:Seq>
<rdf:li
stEvt:action="saved"
stEvt:changed="/metadata"
stEvt:instanceID="xmp.iid:928b36e2-0239-4616-847a-eff7a31816e3"
stEvt:softwareAgent="GIMP 2.99.5 (Linux)"
stEvt:when="2021-02-13T21:24:26+01:00"/>
<rdf:li
stEvt:action="saved"
stEvt:changed="/"
stEvt:instanceID="xmp.iid:23f267c5-c40a-45c8-947d-11313b4881c1"
stEvt:softwareAgent="GIMP 2.99.5 (Linux)"
stEvt:when="2021-02-13T21:25:41+01:00"/>
</rdf:Seq>
</xmpMM:History>
<plus:ImageSupplier>
<rdf:Seq/>
</plus:ImageSupplier>
<plus:ImageCreator>
<rdf:Seq/>
</plus:ImageCreator>
<plus:CopyrightOwner>
<rdf:Seq/>
</plus:CopyrightOwner>
<plus:Licensor>
<rdf:Seq/>
</plus:Licensor>
<dc:creator>
<rdf:Seq>
<rdf:li>type="Seq" me</rdf:li>
</rdf:Seq>
</dc:creator>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">bla bla bla</rdf:li>
</rdf:Alt>
</dc:description>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>""",""]

@ -0,0 +1,521 @@
# -*- coding: utf-8 -*-
import system_tests
# test needs system_tests.BT.vv.enable_bmff=1
vv=system_tests.BT.verbose_version()
enable_bmff = 'enable_bmff'
bSkip = not (enable_bmff in vv and vv[enable_bmff] == '1')
class pr_1475_2021_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/2021-02-13-1929.heic"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.Make Ascii 6 Apple
Exif.Image.DateTime Ascii 20 2021:02:13 11:03:31
Exif.Photo.ExposureTime Rational 1 1/30 s
Exif.Photo.ExposureProgram Short 1 Auto
Exif.Photo.DateTimeOriginal Ascii 20 2021:02:13 11:03:31
Exif.Photo.DateTimeDigitized Ascii 20 2021:02:13 11:03:31
Exif.Photo.ExposureBiasValue SRational 1 0 EV
Exif.Photo.Flash Short 1 No, compulsory
Exif.Photo.FlashpixVersion Undefined 4 1.00
Exif.Photo.ExposureMode Short 1 Auto
Exif.GPSInfo.GPSDateStamp Ascii 11 2021:02:13
""","""Exiv2::BmffImage::boxHandler: ftyp 0->36 brand: heic
Exiv2::BmffImage::boxHandler: meta 36->3380
Exiv2::BmffImage::boxHandler: hdlr 48->34
Exiv2::BmffImage::boxHandler: dinf 82->36
Exiv2::BmffImage::boxHandler: pitm 118->14
Exiv2::BmffImage::boxHandler: iinf 132->1085
Exiv2::BmffImage::boxHandler: infe 146->21 ID = 1 hvc1
Exiv2::BmffImage::boxHandler: infe 167->21 ID = 2 hvc1
Exiv2::BmffImage::boxHandler: infe 188->21 ID = 3 hvc1
Exiv2::BmffImage::boxHandler: infe 209->21 ID = 4 hvc1
Exiv2::BmffImage::boxHandler: infe 230->21 ID = 5 hvc1
Exiv2::BmffImage::boxHandler: infe 251->21 ID = 6 hvc1
Exiv2::BmffImage::boxHandler: infe 272->21 ID = 7 hvc1
Exiv2::BmffImage::boxHandler: infe 293->21 ID = 8 hvc1
Exiv2::BmffImage::boxHandler: infe 314->21 ID = 9 hvc1
Exiv2::BmffImage::boxHandler: infe 335->21 ID = 10 hvc1
Exiv2::BmffImage::boxHandler: infe 356->21 ID = 11 hvc1
Exiv2::BmffImage::boxHandler: infe 377->21 ID = 12 hvc1
Exiv2::BmffImage::boxHandler: infe 398->21 ID = 13 hvc1
Exiv2::BmffImage::boxHandler: infe 419->21 ID = 14 hvc1
Exiv2::BmffImage::boxHandler: infe 440->21 ID = 15 hvc1
Exiv2::BmffImage::boxHandler: infe 461->21 ID = 16 hvc1
Exiv2::BmffImage::boxHandler: infe 482->21 ID = 17 hvc1
Exiv2::BmffImage::boxHandler: infe 503->21 ID = 18 hvc1
Exiv2::BmffImage::boxHandler: infe 524->21 ID = 19 hvc1
Exiv2::BmffImage::boxHandler: infe 545->21 ID = 20 hvc1
Exiv2::BmffImage::boxHandler: infe 566->21 ID = 21 hvc1
Exiv2::BmffImage::boxHandler: infe 587->21 ID = 22 hvc1
Exiv2::BmffImage::boxHandler: infe 608->21 ID = 23 hvc1
Exiv2::BmffImage::boxHandler: infe 629->21 ID = 24 hvc1
Exiv2::BmffImage::boxHandler: infe 650->21 ID = 25 hvc1
Exiv2::BmffImage::boxHandler: infe 671->21 ID = 26 hvc1
Exiv2::BmffImage::boxHandler: infe 692->21 ID = 27 hvc1
Exiv2::BmffImage::boxHandler: infe 713->21 ID = 28 hvc1
Exiv2::BmffImage::boxHandler: infe 734->21 ID = 29 hvc1
Exiv2::BmffImage::boxHandler: infe 755->21 ID = 30 hvc1
Exiv2::BmffImage::boxHandler: infe 776->21 ID = 31 hvc1
Exiv2::BmffImage::boxHandler: infe 797->21 ID = 32 hvc1
Exiv2::BmffImage::boxHandler: infe 818->21 ID = 33 hvc1
Exiv2::BmffImage::boxHandler: infe 839->21 ID = 34 hvc1
Exiv2::BmffImage::boxHandler: infe 860->21 ID = 35 hvc1
Exiv2::BmffImage::boxHandler: infe 881->21 ID = 36 hvc1
Exiv2::BmffImage::boxHandler: infe 902->21 ID = 37 hvc1
Exiv2::BmffImage::boxHandler: infe 923->21 ID = 38 hvc1
Exiv2::BmffImage::boxHandler: infe 944->21 ID = 39 hvc1
Exiv2::BmffImage::boxHandler: infe 965->21 ID = 40 hvc1
Exiv2::BmffImage::boxHandler: infe 986->21 ID = 41 hvc1
Exiv2::BmffImage::boxHandler: infe 1007->21 ID = 42 hvc1
Exiv2::BmffImage::boxHandler: infe 1028->21 ID = 43 hvc1
Exiv2::BmffImage::boxHandler: infe 1049->21 ID = 44 hvc1
Exiv2::BmffImage::boxHandler: infe 1070->21 ID = 45 hvc1
Exiv2::BmffImage::boxHandler: infe 1091->21 ID = 46 hvc1
Exiv2::BmffImage::boxHandler: infe 1112->21 ID = 47 hvc1
Exiv2::BmffImage::boxHandler: infe 1133->21 ID = 48 hvc1
Exiv2::BmffImage::boxHandler: infe 1154->21 ID = 49 grid
Exiv2::BmffImage::boxHandler: infe 1175->21 ID = 50 hvc1
Exiv2::BmffImage::boxHandler: infe 1196->21 ID = 51 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: iref 1217->148
Exiv2::BmffImage::boxHandler: iprp 1365->1203
Exiv2::BmffImage::boxHandler: ipco 1373->876
Exiv2::BmffImage::boxHandler: colr 1381->560
Exiv2::BmffImage::boxHandler: hvcC 1941->112
Exiv2::BmffImage::boxHandler: ispe 2053->20 pixelWidth_, pixelHeight_ = 512, 512
Exiv2::BmffImage::boxHandler: ispe 2073->20 pixelWidth_, pixelHeight_ = 4032, 3024
Exiv2::BmffImage::boxHandler: irot 2093->9
Exiv2::BmffImage::boxHandler: pixi 2102->16
Exiv2::BmffImage::boxHandler: hvcC 2118->111
Exiv2::BmffImage::boxHandler: ispe 2229->20 pixelWidth_, pixelHeight_ = 320, 240
Exiv2::BmffImage::boxHandler: ipma 2249->319
Exiv2::BmffImage::boxHandler: idat 2568->16
Exiv2::BmffImage::boxHandler: iloc 2584->832
2592 | 16 | ID | 1 | 23265, 15453
2608 | 16 | ID | 2 | 38718, 21882
2624 | 16 | ID | 3 | 60600, 20196
2640 | 16 | ID | 4 | 80796, 22234
2656 | 16 | ID | 5 | 103030, 41489
2672 | 16 | ID | 6 | 144519, 40845
2688 | 16 | ID | 7 | 185364, 34948
2704 | 16 | ID | 8 | 220312, 17650
2720 | 16 | ID | 9 | 237962, 15024
2736 | 16 | ID | 10 | 252986, 44647
2752 | 16 | ID | 11 | 297633, 38092
2768 | 16 | ID | 12 | 335725, 43666
2784 | 16 | ID | 13 | 379391, 48523
2800 | 16 | ID | 14 | 427914, 46992
2816 | 16 | ID | 15 | 474906, 36063
2832 | 16 | ID | 16 | 510969, 20737
2848 | 16 | ID | 17 | 531706, 25756
2864 | 16 | ID | 18 | 557462, 58455
2880 | 16 | ID | 19 | 615917, 44896
2896 | 16 | ID | 20 | 660813, 39730
2912 | 16 | ID | 21 | 700543, 38596
2928 | 16 | ID | 22 | 739139, 31795
2944 | 16 | ID | 23 | 770934, 33214
2960 | 16 | ID | 24 | 804148, 18858
2976 | 16 | ID | 25 | 823006, 35122
2992 | 16 | ID | 26 | 858128, 41015
3008 | 16 | ID | 27 | 899143, 40362
3024 | 16 | ID | 28 | 939505, 38288
3040 | 16 | ID | 29 | 977793, 34497
3056 | 16 | ID | 30 | 1012290, 31806
3072 | 16 | ID | 31 | 1044096, 25360
3088 | 16 | ID | 32 | 1069456, 19672
3104 | 16 | ID | 33 | 1089128, 25400
3120 | 16 | ID | 34 | 1114528, 34515
3136 | 16 | ID | 35 | 1149043, 20863
3152 | 16 | ID | 36 | 1169906, 25975
3168 | 16 | ID | 37 | 1195881, 33532
3184 | 16 | ID | 38 | 1229413, 31296
3200 | 16 | ID | 39 | 1260709, 29869
3216 | 16 | ID | 40 | 1290578, 16479
3232 | 16 | ID | 41 | 1307057, 17323
3248 | 16 | ID | 42 | 1324380, 17331
3264 | 16 | ID | 43 | 1341711, 13357
3280 | 16 | ID | 44 | 1355068, 22206
3296 | 16 | ID | 45 | 1377274, 31859
3312 | 16 | ID | 46 | 1409133, 26694
3328 | 16 | ID | 47 | 1435827, 23620
3344 | 16 | ID | 48 | 1459447, 15007
3360 | 16 | ID | 49 | 0, 8
3376 | 16 | ID | 50 | 3432, 17469
3392 | 16 | ID | 51 | 20901, 2364
Exiv2::BMFF Exif: ID = 51 from,length = 20901,2364
Exiv2::BmffImage::boxHandler: mdat 3416->1
""","","""data:AAACJGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNzcEF
QUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsyhq
VgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
KZGVzYwAAAPwAAABlY3BydAAAAWQAAAAjd3RwdAAAAYgAAAAUclhZWgAAAZw
AAAAUZ1hZWgAAAbAAAAAUYlhZWgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAA
AAfgAAAAsYlRSQwAAAdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGl
zcGxheSBQMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3AABYWVogAAAAAAA
A81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb////+7WFlaIAAAAAAAAEq/AAC
xNwAACrlYWVogAAAAAAAAKDgAABELAADIuXBhcmEAAAAAAAMAAAACZmYAAPK
nAAANWQAAE9AAAApbc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L
///2jAAAD3AAAwG4=
"""]
class pr_1475_IMG_3578_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/IMG_3578.heic"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.Make Ascii 6 Apple
Exif.Image.DateTime Ascii 20 2020:04:17 10:03:40
Exif.Photo.ExposureTime Rational 1 1/60 s
Exif.Photo.ExposureProgram Short 1 Auto
Exif.Photo.DateTimeOriginal Ascii 20 2020:04:17 10:03:40
Exif.Photo.DateTimeDigitized Ascii 20 2020:04:17 10:03:40
Exif.Photo.ExposureBiasValue SRational 1 0 EV
Exif.Photo.Flash Short 1 No, compulsory
Exif.Photo.FlashpixVersion Undefined 4 1.00
Exif.Photo.ExposureMode Short 1 Auto
""","""Exiv2::BmffImage::boxHandler: ftyp 0->32 brand: heic
Exiv2::BmffImage::boxHandler: meta 32->3380
Exiv2::BmffImage::boxHandler: hdlr 44->34
Exiv2::BmffImage::boxHandler: dinf 78->36
Exiv2::BmffImage::boxHandler: pitm 114->14
Exiv2::BmffImage::boxHandler: iinf 128->1085
Exiv2::BmffImage::boxHandler: infe 142->21 ID = 1 hvc1
Exiv2::BmffImage::boxHandler: infe 163->21 ID = 2 hvc1
Exiv2::BmffImage::boxHandler: infe 184->21 ID = 3 hvc1
Exiv2::BmffImage::boxHandler: infe 205->21 ID = 4 hvc1
Exiv2::BmffImage::boxHandler: infe 226->21 ID = 5 hvc1
Exiv2::BmffImage::boxHandler: infe 247->21 ID = 6 hvc1
Exiv2::BmffImage::boxHandler: infe 268->21 ID = 7 hvc1
Exiv2::BmffImage::boxHandler: infe 289->21 ID = 8 hvc1
Exiv2::BmffImage::boxHandler: infe 310->21 ID = 9 hvc1
Exiv2::BmffImage::boxHandler: infe 331->21 ID = 10 hvc1
Exiv2::BmffImage::boxHandler: infe 352->21 ID = 11 hvc1
Exiv2::BmffImage::boxHandler: infe 373->21 ID = 12 hvc1
Exiv2::BmffImage::boxHandler: infe 394->21 ID = 13 hvc1
Exiv2::BmffImage::boxHandler: infe 415->21 ID = 14 hvc1
Exiv2::BmffImage::boxHandler: infe 436->21 ID = 15 hvc1
Exiv2::BmffImage::boxHandler: infe 457->21 ID = 16 hvc1
Exiv2::BmffImage::boxHandler: infe 478->21 ID = 17 hvc1
Exiv2::BmffImage::boxHandler: infe 499->21 ID = 18 hvc1
Exiv2::BmffImage::boxHandler: infe 520->21 ID = 19 hvc1
Exiv2::BmffImage::boxHandler: infe 541->21 ID = 20 hvc1
Exiv2::BmffImage::boxHandler: infe 562->21 ID = 21 hvc1
Exiv2::BmffImage::boxHandler: infe 583->21 ID = 22 hvc1
Exiv2::BmffImage::boxHandler: infe 604->21 ID = 23 hvc1
Exiv2::BmffImage::boxHandler: infe 625->21 ID = 24 hvc1
Exiv2::BmffImage::boxHandler: infe 646->21 ID = 25 hvc1
Exiv2::BmffImage::boxHandler: infe 667->21 ID = 26 hvc1
Exiv2::BmffImage::boxHandler: infe 688->21 ID = 27 hvc1
Exiv2::BmffImage::boxHandler: infe 709->21 ID = 28 hvc1
Exiv2::BmffImage::boxHandler: infe 730->21 ID = 29 hvc1
Exiv2::BmffImage::boxHandler: infe 751->21 ID = 30 hvc1
Exiv2::BmffImage::boxHandler: infe 772->21 ID = 31 hvc1
Exiv2::BmffImage::boxHandler: infe 793->21 ID = 32 hvc1
Exiv2::BmffImage::boxHandler: infe 814->21 ID = 33 hvc1
Exiv2::BmffImage::boxHandler: infe 835->21 ID = 34 hvc1
Exiv2::BmffImage::boxHandler: infe 856->21 ID = 35 hvc1
Exiv2::BmffImage::boxHandler: infe 877->21 ID = 36 hvc1
Exiv2::BmffImage::boxHandler: infe 898->21 ID = 37 hvc1
Exiv2::BmffImage::boxHandler: infe 919->21 ID = 38 hvc1
Exiv2::BmffImage::boxHandler: infe 940->21 ID = 39 hvc1
Exiv2::BmffImage::boxHandler: infe 961->21 ID = 40 hvc1
Exiv2::BmffImage::boxHandler: infe 982->21 ID = 41 hvc1
Exiv2::BmffImage::boxHandler: infe 1003->21 ID = 42 hvc1
Exiv2::BmffImage::boxHandler: infe 1024->21 ID = 43 hvc1
Exiv2::BmffImage::boxHandler: infe 1045->21 ID = 44 hvc1
Exiv2::BmffImage::boxHandler: infe 1066->21 ID = 45 hvc1
Exiv2::BmffImage::boxHandler: infe 1087->21 ID = 46 hvc1
Exiv2::BmffImage::boxHandler: infe 1108->21 ID = 47 hvc1
Exiv2::BmffImage::boxHandler: infe 1129->21 ID = 48 hvc1
Exiv2::BmffImage::boxHandler: infe 1150->21 ID = 49 grid
Exiv2::BmffImage::boxHandler: infe 1171->21 ID = 50 hvc1
Exiv2::BmffImage::boxHandler: infe 1192->21 ID = 51 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: iref 1213->148
Exiv2::BmffImage::boxHandler: iprp 1361->1203
Exiv2::BmffImage::boxHandler: ipco 1369->876
Exiv2::BmffImage::boxHandler: colr 1377->560
Exiv2::BmffImage::boxHandler: hvcC 1937->112
Exiv2::BmffImage::boxHandler: ispe 2049->20 pixelWidth_, pixelHeight_ = 512, 512
Exiv2::BmffImage::boxHandler: ispe 2069->20 pixelWidth_, pixelHeight_ = 4032, 3024
Exiv2::BmffImage::boxHandler: irot 2089->9
Exiv2::BmffImage::boxHandler: pixi 2098->16
Exiv2::BmffImage::boxHandler: hvcC 2114->111
Exiv2::BmffImage::boxHandler: ispe 2225->20 pixelWidth_, pixelHeight_ = 320, 240
Exiv2::BmffImage::boxHandler: ipma 2245->319
Exiv2::BmffImage::boxHandler: idat 2564->16
Exiv2::BmffImage::boxHandler: iloc 2580->832
2588 | 16 | ID | 1 | 10931, 11943
2604 | 16 | ID | 2 | 22874, 24817
2620 | 16 | ID | 3 | 47691, 20110
2636 | 16 | ID | 4 | 67801, 19449
2652 | 16 | ID | 5 | 87250, 19714
2668 | 16 | ID | 6 | 106964, 20223
2684 | 16 | ID | 7 | 127187, 18124
2700 | 16 | ID | 8 | 145311, 8745
2716 | 16 | ID | 9 | 154056, 21761
2732 | 16 | ID | 10 | 175817, 25378
2748 | 16 | ID | 11 | 201195, 16664
2764 | 16 | ID | 12 | 217859, 18638
2780 | 16 | ID | 13 | 236497, 22750
2796 | 16 | ID | 14 | 259247, 15801
2812 | 16 | ID | 15 | 275048, 15063
2828 | 16 | ID | 16 | 290111, 15671
2844 | 16 | ID | 17 | 305782, 19360
2860 | 16 | ID | 18 | 325142, 19415
2876 | 16 | ID | 19 | 344557, 29895
2892 | 16 | ID | 20 | 374452, 21193
2908 | 16 | ID | 21 | 395645, 46228
2924 | 16 | ID | 22 | 441873, 9356
2940 | 16 | ID | 23 | 451229, 14175
2956 | 16 | ID | 24 | 465404, 16734
2972 | 16 | ID | 25 | 482138, 32304
2988 | 16 | ID | 26 | 514442, 44251
3004 | 16 | ID | 27 | 558693, 21635
3020 | 16 | ID | 28 | 580328, 27907
3036 | 16 | ID | 29 | 608235, 8462
3052 | 16 | ID | 30 | 616697, 17997
3068 | 16 | ID | 31 | 634694, 22077
3084 | 16 | ID | 32 | 656771, 17266
3100 | 16 | ID | 33 | 674037, 19623
3116 | 16 | ID | 34 | 693660, 22028
3132 | 16 | ID | 35 | 715688, 22078
3148 | 16 | ID | 36 | 737766, 21911
3164 | 16 | ID | 37 | 759677, 20937
3180 | 16 | ID | 38 | 780614, 35413
3196 | 16 | ID | 39 | 816027, 53869
3212 | 16 | ID | 40 | 869896, 33923
3228 | 16 | ID | 41 | 903819, 18130
3244 | 16 | ID | 42 | 921949, 16268
3260 | 16 | ID | 43 | 938217, 23620
3276 | 16 | ID | 44 | 961837, 31499
3292 | 16 | ID | 45 | 993336, 33513
3308 | 16 | ID | 46 | 1026849, 37642
3324 | 16 | ID | 47 | 1064491, 37734
3340 | 16 | ID | 48 | 1102225, 20085
3356 | 16 | ID | 49 | 0, 8
3372 | 16 | ID | 50 | 3428, 5479
3388 | 16 | ID | 51 | 8907, 2024
Exiv2::BMFF Exif: ID = 51 from,length = 8907,2024
Exiv2::BmffImage::boxHandler: mdat 3412->1
""","","""data:AAACJGFwcGwEAAAAbW50clJHQiBYWVogB+EABwAHAA0AFgAgYWNzcEF
QUEwAAAAAQVBQTAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsyhq
VgiV/EE04mRPV0eoVggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
KZGVzYwAAAPwAAABlY3BydAAAAWQAAAAjd3RwdAAAAYgAAAAUclhZWgAAAZw
AAAAUZ1hZWgAAAbAAAAAUYlhZWgAAAcQAAAAUclRSQwAAAdgAAAAgY2hhZAA
AAfgAAAAsYlRSQwAAAdgAAAAgZ1RSQwAAAdgAAAAgZGVzYwAAAAAAAAALRGl
zcGxheSBQMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDE3AABYWVogAAAAAAA
A81EAAQAAAAEWzFhZWiAAAAAAAACD3wAAPb////+7WFlaIAAAAAAAAEq/AAC
xNwAACrlYWVogAAAAAAAAKDgAABELAADIuXBhcmEAAAAAAAMAAAACZmYAAPK
nAAANWQAAE9AAAApbc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeTAAD9kP//+6L
///2jAAAD3AAAwG4=
"""]
class pr_1475_Stonehenge_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/Stonehenge.heic"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.Make Ascii 18 NIKON CORPORATION
Exif.Image.DateTime Ascii 20 2015:07:16 20:25:28
Exif.Photo.ExposureTime Rational 1 1/400 s
Exif.Photo.ExposureProgram Short 1 Not defined
Exif.Photo.DateTimeOriginal Ascii 20 2015:07:16 15:38:54
Exif.Photo.DateTimeDigitized Ascii 20 2015:07:16 15:38:54
Exif.Photo.ExposureBiasValue SRational 1 0 EV
Exif.Photo.Flash Short 1 No, compulsory
Exif.Photo.FlashpixVersion Undefined 4 1.00
Exif.Photo.ExposureMode Short 1 Auto
Xmp.aux.SerialNumber XmpText 7 2567806
Xmp.aux.FlashCompensation XmpText 3 0/1
Xmp.aux.LensInfo XmpText 20 18/1 250/1 7/2 63/10
Xmp.aux.Lens XmpText 23 18.0-250.0 mm f/3.5-6.3
Xmp.aux.ImageNumber XmpText 4 9608
Xmp.aux.LensID XmpText 20 -7910804157571773682
Xmp.xmp.Rating XmpText 1 0
Xmp.xmp.CreatorTool XmpText 9 Ver.1.00
Xmp.xmp.CreateDate XmpText 22 2015-07-16T15:38:54.00
Xmp.xmp.ModifyDate XmpText 28 2015-07-16T20:25:28.00+01:00
Xmp.cm2e.Father XmpText 11 Robin Mills
Xmp.cm2e.Family XmpBag 0
Xmp.photoshop.DateCreated XmpText 22 2015-07-16T15:38:54.00
Xmp.dc.description LangAlt 1 lang="x-default" Classic View
Xmp.dc.Family XmpBag 1 Robin
""","""Exiv2::BmffImage::boxHandler: ftyp 0->24 brand: heic
Exiv2::BmffImage::boxHandler: meta 24->508
Exiv2::BmffImage::boxHandler: hdlr 36->34
Exiv2::BmffImage::boxHandler: dinf 70->36
Exiv2::BmffImage::boxHandler: pitm 106->14
Exiv2::BmffImage::boxHandler: iinf 120->97
Exiv2::BmffImage::boxHandler: infe 134->21 ID = 1 hvc1
Exiv2::BmffImage::boxHandler: infe 155->21 ID = 2 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: infe 176->41 ID = 3 mime *** XMP ***
Exiv2::BmffImage::boxHandler: iref 217->40
Exiv2::BmffImage::boxHandler: iprp 257->217
Exiv2::BmffImage::boxHandler: ipco 265->185
Exiv2::BmffImage::boxHandler: colr 273->19
Exiv2::BmffImage::boxHandler: hvcC 292->113
Exiv2::BmffImage::boxHandler: ispe 405->20 pixelWidth_, pixelHeight_ = 300, 200
Exiv2::BmffImage::boxHandler: irot 425->9
Exiv2::BmffImage::boxHandler: pixi 434->16
Exiv2::BmffImage::boxHandler: ipma 450->24
Exiv2::BmffImage::boxHandler: iloc 474->58
482 | 14 | ID | 1 | 4780, 13461
496 | 14 | ID | 2 | 548, 1082
510 | 14 | ID | 3 | 1630, 3150
Exiv2::BMFF Exif: ID = 2 from,length = 548,1082
Exiv2::BMFF XMP: ID = 3 from,length = 1630,3150
Exiv2::BmffImage::boxHandler: mdat 532->1
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:cm2e="http://clanmills.com/exiv2/"
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
aux:SerialNumber="2567806"
aux:FlashCompensation="0/1"
aux:LensInfo="18/1 250/1 7/2 63/10"
aux:Lens="18.0-250.0 mm f/3.5-6.3"
aux:ImageNumber="9608"
aux:LensID="-7910804157571773682"
xmp:Rating="0"
xmp:CreatorTool="Ver.1.00 "
xmp:CreateDate="2015-07-16T15:38:54.00"
xmp:ModifyDate="2015-07-16T20:25:28.00+01:00"
cm2e:Father="Robin Mills"
photoshop:DateCreated="2015-07-16T15:38:54.00">
<cm2e:Family>
<rdf:Bag/>
</cm2e:Family>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">Classic View</rdf:li>
</rdf:Alt>
</dc:description>
<dc:Family>
<rdf:Bag>
<rdf:li>Robin</rdf:li>
</rdf:Bag>
</dc:Family>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>""",""]
class pr_1475_heic_heic(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/heic.heic"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -pa $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC --binary $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["","""Exiv2::BmffImage::boxHandler: ftyp 0->28 brand: mif1
Exiv2::BmffImage::boxHandler: meta 28->921
Exiv2::BmffImage::boxHandler: hdlr 40->33
Exiv2::BmffImage::boxHandler: pitm 73->14
Exiv2::BmffImage::boxHandler: iloc 87->88
95 | 18 | ID | 20004 | 957,333704
113 | 18 | ID | 20005 | 334669, 24523
131 | 18 | ID | 20006 | 359200,330132
149 | 18 | ID | 20007 | 689340, 28758
Exiv2::BmffImage::boxHandler: iinf 175->140
Exiv2::BmffImage::boxHandler: iref 315->40
Exiv2::BmffImage::boxHandler: iprp 355->594
Exiv2::BmffImage::boxHandler: ipco 363->550
Exiv2::BmffImage::boxHandler: hvcC 371->126
Exiv2::BmffImage::boxHandler: ispe 497->20 pixelWidth_, pixelHeight_ = 1280, 854
Exiv2::BmffImage::boxHandler: hvcC 517->125
Exiv2::BmffImage::boxHandler: ispe 642->20 pixelWidth_, pixelHeight_ = 320, 212
Exiv2::BmffImage::boxHandler: hvcC 662->126
Exiv2::BmffImage::boxHandler: hvcC 788->125
Exiv2::BmffImage::boxHandler: ipma 913->36
Exiv2::BmffImage::boxHandler: mdat 949->333712
Exiv2::BmffImage::boxHandler: mdat 334661->24531
Exiv2::BmffImage::boxHandler: mdat 359192->330140
Exiv2::BmffImage::boxHandler: mdat 689332->28766
Exiv2::BmffImage::boxHandler: mdat 718098->16
""","",""]

@ -0,0 +1,246 @@
# -*- coding: utf-8 -*-
import system_tests
# test needs system_tests.BT.vv.enable_bmff=1
vv=system_tests.BT.verbose_version()
enable_bmff = 'enable_bmff'
bSkip = not (enable_bmff in vv and vv[enable_bmff] == '1')
class pr_1475_Sony_hif(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/Sony.HIF"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdout=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.Make Ascii 5 SONY
Exif.Image.DateTime Ascii 20 2021:02:18 19:55:41
Exif.Photo.ExposureTime Rational 1 1/1000 s
Exif.Photo.ExposureProgram Short 1 Manual
Exif.Photo.RecommendedExposureIndex Long 1 100
Exif.Photo.DateTimeOriginal Ascii 20 2021:02:18 19:55:41
Exif.Photo.DateTimeDigitized Ascii 20 2021:02:18 19:55:41
Exif.Photo.ExposureBiasValue SRational 1 0 EV
Exif.Photo.Flash Short 1 No, compulsory
Exif.Sony1.FlashExposureComp SRational 1 0 EV
Exif.Sony1.ExposureMode Short 1 Manual
Exif.Sony1.FlashLevel SShort 1 Normal
Exif.Photo.FlashpixVersion Undefined 4 1.00
Exif.Photo.ExposureMode Short 1 Manual
Xmp.xmp.Rating XmpText 1 0
""","""Exiv2::BmffImage::boxHandler: ftyp 0->40 brand: heix
Exiv2::BmffImage::boxHandler: meta 40->2081
Exiv2::BmffImage::boxHandler: hdlr 52->33
Exiv2::BmffImage::boxHandler: pitm 85->14
Exiv2::BmffImage::boxHandler: iinf 99->350
Exiv2::BmffImage::boxHandler: infe 113->21 ID = 1 hvc1
Exiv2::BmffImage::boxHandler: infe 134->21 ID = 2 hvc1
Exiv2::BmffImage::boxHandler: infe 155->21 ID = 3 hvc1
Exiv2::BmffImage::boxHandler: infe 176->21 ID = 4 hvc1
Exiv2::BmffImage::boxHandler: infe 197->21 ID = 5 hvc1
Exiv2::BmffImage::boxHandler: infe 218->21 ID = 6 hvc1
Exiv2::BmffImage::boxHandler: infe 239->21 ID = 7 hvc1
Exiv2::BmffImage::boxHandler: infe 260->21 ID = 8 hvc1
Exiv2::BmffImage::boxHandler: infe 281->21 ID = 9 hvc1
Exiv2::BmffImage::boxHandler: infe 302->21 ID = 10 grid
Exiv2::BmffImage::boxHandler: infe 323->21 ID = 11 hvc1
Exiv2::BmffImage::boxHandler: infe 344->21 ID = 12 hvc1
Exiv2::BmffImage::boxHandler: infe 365->21 ID = 13 jpeg
Exiv2::BmffImage::boxHandler: infe 386->21 ID = 14 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: infe 407->42 ID = 15 mime *** XMP ***
Exiv2::BmffImage::boxHandler: iref 449->112
Exiv2::BmffImage::boxHandler: iprp 561->1288
Exiv2::BmffImage::boxHandler: ipco 569->1184
Exiv2::BmffImage::boxHandler: irot 577->9
Exiv2::BmffImage::boxHandler: colr 586->19
Exiv2::BmffImage::boxHandler: pixi 605->16
Exiv2::BmffImage::boxHandler: hvcC 621->345
Exiv2::BmffImage::boxHandler: ispe 966->20 pixelWidth_, pixelHeight_ = 2880, 1920
Exiv2::BmffImage::boxHandler: ispe 986->20 pixelWidth_, pixelHeight_ = 8640, 5760
Exiv2::BmffImage::boxHandler: hvcC 1006->344
Exiv2::BmffImage::boxHandler: ispe 1350->20 pixelWidth_, pixelHeight_ = 1616, 1080
Exiv2::BmffImage::boxHandler: hvcC 1370->343
Exiv2::BmffImage::boxHandler: ispe 1713->20 pixelWidth_, pixelHeight_ = 320, 212
Exiv2::BmffImage::boxHandler: ispe 1733->20 pixelWidth_, pixelHeight_ = 160, 120
Exiv2::BmffImage::boxHandler: ipma 1753->96
Exiv2::BmffImage::boxHandler: idat 1849->16
Exiv2::BmffImage::boxHandler: iloc 1865->256
1873 | 16 | ID | 15 | 4096, 57344
1889 | 16 | ID | 14 | 61440, 40960
1905 | 16 | ID | 13 | 102400, 4096
1921 | 16 | ID | 12 | 106496, 4096
1937 | 16 | ID | 1 | 110592, 4562
1953 | 16 | ID | 2 | 115154, 2802
1969 | 16 | ID | 3 | 117956, 4344
1985 | 16 | ID | 4 | 122300, 3772
2001 | 16 | ID | 5 | 126072, 2227
2017 | 16 | ID | 6 | 128299, 3668
2033 | 16 | ID | 7 | 131967, 4518
2049 | 16 | ID | 8 | 136485, 2840
2065 | 16 | ID | 9 | 139325, 8131
2081 | 16 | ID | 10 | 0, 8
2097 | 16 | ID | 11 | 147456, 4096
Exiv2::BMFF Exif: ID = 14 from,length = 61440,40960
Exiv2::BMFF XMP: ID = 15 from,length = 4096,57344
Exiv2::BmffImage::boxHandler: free 2121->1967
Exiv2::BmffImage::boxHandler: mdat 4088->147464
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmp:Rating="0"/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>""",""]
class pr_1475_Canon_hif(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/pull/1475"
filename = "$data_path/Canon.HIF"
if bSkip:
commands=[]
retval=[]
stdin=[]
stderr=[]
stdin=[]
print("*** test skipped. requires enable_bmff=1***")
else:
commands = ["$exiv2 -g Image.Make -g Date -g Xm -g Expo -g Flash $filename"
,"$exiv2 -pS $filename"
,"$exiv2 -pX $filename"
,"$exiv2 -pC $filename"
]
retval = [ 0 ] * len(commands)
stderr = [ "" ] * len(commands)
stdin = [ "" ] * len(commands)
stdout = ["""Exif.Image.Make Ascii 6 Canon
Exif.Image.DateTime Ascii 20 2021:02:18 19:54:47
Exif.Photo.ExposureTime Rational 1 1/1000 s
Exif.Photo.ExposureProgram Short 1 Manual
Exif.Photo.RecommendedExposureIndex Long 1 100
Exif.Photo.DateTimeOriginal Ascii 20 2021:02:18 19:54:47
Exif.Photo.DateTimeDigitized Ascii 20 2021:02:18 19:54:47
Exif.Photo.ExposureBiasValue SRational 1 0 EV
Exif.Photo.Flash Short 1 No flash
Exif.CanonCs.FlashMode Short 1 Off
Exif.CanonCs.ExposureProgram Short 1 Manual (M)
Exif.CanonCs.FlashActivity Short 1 Did not fire
Exif.CanonCs.FlashDetails Short 1 E-TTL
Exif.CanonCs.ManualFlashOutput Short 1 n/a
Exif.CanonSi.FlashGuideNumber Short 1 0
Exif.CanonSi.FlashBias Short 1 0 EV
Exif.CanonSi.AutoExposureBracketing Short 1 Off
Exif.CanonFi.FlashExposureLock SShort 1 Off
Exif.Photo.FlashpixVersion Undefined 4 1.00
Exif.Photo.ExposureMode Short 1 Manual
Xmp.xmp.Rating XmpText 1 0
""","""Exiv2::BmffImage::boxHandler: ftyp 0->32 brand: heix
Exiv2::BmffImage::boxHandler: meta 32->1163
Exiv2::BmffImage::boxHandler: hdlr 44->33
Exiv2::BmffImage::boxHandler: uuid 77->62 uuidName cano
Exiv2::BmffImage::boxHandler: CNCV 101->38
Exiv2::BmffImage::boxHandler: dinf 139->36
Exiv2::BmffImage::boxHandler: pitm 175->14
Exiv2::BmffImage::boxHandler: iinf 189->203
Exiv2::BmffImage::boxHandler: infe 203->21 ID = 1 grid
Exiv2::BmffImage::boxHandler: infe 224->21 ID = 256 hvc1
Exiv2::BmffImage::boxHandler: infe 245->21 ID = 257 hvc1
Exiv2::BmffImage::boxHandler: infe 266->21 ID = 258 hvc1
Exiv2::BmffImage::boxHandler: infe 287->21 ID = 259 hvc1
Exiv2::BmffImage::boxHandler: infe 308->21 ID = 512 hvc1
Exiv2::BmffImage::boxHandler: infe 329->21 ID = 768 Exif *** Exif ***
Exiv2::BmffImage::boxHandler: infe 350->42 ID = 769 mime *** XMP ***
Exiv2::BmffImage::boxHandler: iref 392->74
Exiv2::BmffImage::boxHandler: iprp 466->569
Exiv2::BmffImage::boxHandler: ipco 474->507
Exiv2::BmffImage::boxHandler: hvcC 482->176
Exiv2::BmffImage::boxHandler: ispe 658->20 pixelWidth_, pixelHeight_ = 1216, 832
Exiv2::BmffImage::boxHandler: colr 678->19
Exiv2::BmffImage::boxHandler: pixi 697->16
Exiv2::BmffImage::boxHandler: ispe 713->20 pixelWidth_, pixelHeight_ = 2400, 1600
Exiv2::BmffImage::boxHandler: irot 733->9
Exiv2::BmffImage::boxHandler: hvcC 742->175
Exiv2::BmffImage::boxHandler: ispe 917->20 pixelWidth_, pixelHeight_ = 320, 214
Exiv2::BmffImage::boxHandler: colr 937->19
Exiv2::BmffImage::boxHandler: pixi 956->16
Exiv2::BmffImage::boxHandler: irot 972->9
Exiv2::BmffImage::boxHandler: ipma 981->54
Exiv2::BmffImage::boxHandler: idat 1035->16
Exiv2::BmffImage::boxHandler: iloc 1051->144
1059 | 16 | ID | 1 | 0, 8
1075 | 16 | ID | 256 | 46080,344284
1091 | 16 | ID | 257 | 390364,340989
1107 | 16 | ID | 258 | 731353,257177
1123 | 16 | ID | 259 | 988530,264862
1139 | 16 | ID | 512 | 32256, 10284
1155 | 16 | ID | 768 | 1536, 30463
1171 | 16 | ID | 769 | 43008, 3072
Exiv2::BMFF Exif: ID = 768 from,length = 1536,30463
Exiv2::BMFF XMP: ID = 769 from,length = 43008,3072
Exiv2::BmffImage::boxHandler: mdat 1195->1252197
""","""<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmp:Rating="0"/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>""",""]

@ -147,7 +147,7 @@ TEST(base64decode, decodesValidString)
const std::string original ("VGhpcyBpcyBhIHVuaXQgdGVzdA==");
const std::string expected ("This is a unit test");
char * result = new char [original.size()];
ASSERT_EQ(static_cast<long>(expected.size()+1),
ASSERT_EQ(static_cast<long>(expected.size()),
base64decode(original.c_str(), result, original.size()));
ASSERT_STREQ(expected.c_str(), result);
delete [] result;

Loading…
Cancel
Save