From fe6ee8bc05f9ad497b216ce19dc30a4541631d3f Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Tue, 9 Mar 2004 08:20:36 +0000 Subject: [PATCH] Added simple unit tests and expected output --- src/Makefile | 5 +- src/makernote-test.cpp | 48 +++++++++ src/makernote-test.out | 20 ++++ src/write-test.cpp | 232 +++++++++++++++++++++++++++++++++++++++++ src/write-test.out | 104 ++++++++++++++++++ src/write-test.sh | 62 +++++++++++ 6 files changed, 469 insertions(+), 2 deletions(-) create mode 100644 src/makernote-test.cpp create mode 100644 src/makernote-test.out create mode 100644 src/write-test.cpp create mode 100644 src/write-test.out create mode 100755 src/write-test.sh diff --git a/src/Makefile b/src/Makefile index 9f61f785..f09fce25 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ # 02111-1307, USA. # # File: Makefile -# Version: $Name: $ $Revision: 1.14 $ +# Version: $Name: $ $Revision: 1.15 $ # Author(s): Andreas Huggel (ahu) # History: 10-Dec-03, ahu: created # @@ -55,7 +55,8 @@ CCSRC = canonmn.cpp exif.cpp ifd.cpp image.cpp makernote.cpp tags.cpp \ types.cpp value.cpp # Add source files of simple applications to this list -BINSRC = example1.cpp taglist.cpp exifprint.cpp exiftest.cpp makernote-test.cpp +BINSRC = example1.cpp taglist.cpp exifprint.cpp exiftest.cpp makernote-test.cpp \ + write-test.cpp # State the main source file of the Exiv2 application here EXIV2MAIN = exiv2.cpp diff --git a/src/makernote-test.cpp b/src/makernote-test.cpp new file mode 100644 index 00000000..65b4cd8e --- /dev/null +++ b/src/makernote-test.cpp @@ -0,0 +1,48 @@ +#include "makernote.hpp" + +#include +#include +#include + +void testMatch(const std::string& reg, const std::string& key); + +int main() +{ + testMatch("Canon", "Canon"); + testMatch("Canon*", "Canon"); + testMatch("Canon*", "Canon Corp."); + testMatch("*foo*bar*", "foobar"); + testMatch("*foo*bar*", "barfoofoobarbar"); + testMatch("foo*bar", "foo"); + testMatch("foo*bar", "bar"); + testMatch("foo*bar", "foobar"); + testMatch("foo*bar", "fooYAHOObar"); + testMatch("foo*bar", "Thefoobar"); + testMatch("foo*bar", "foobarTrick"); + testMatch("foo*bar", "ThefoobarTrick"); + testMatch("foo*bar", "ThefooYAHOObarTrick"); + + testMatch("*", "anything"); + testMatch("**", "anything times two"); + + testMatch("*bar", "bar"); + testMatch("b*bar", "bar"); + testMatch("b*bar", "bbar"); + testMatch("*foobar", "bar"); + testMatch("*bar", "foobar"); + + return 0; +} + +void testMatch(const std::string& reg, const std::string& key) +{ + std::pair rc = Exif::MakerNoteFactory::match(reg, key); + + if (rc.first) { + std::cout << "Key '" << key << "' matches '" << reg << "' in " + << rc.second << " characters.\n"; + } + else { + std::cout << "Key '" << key << "' does not match '" << reg << "'.\n"; + } +} diff --git a/src/makernote-test.out b/src/makernote-test.out new file mode 100644 index 00000000..8622d164 --- /dev/null +++ b/src/makernote-test.out @@ -0,0 +1,20 @@ +Key 'Canon' matches 'Canon' in 5 characters. +Key 'Canon' matches 'Canon*' in 5 characters. +Key 'Canon Corp.' matches 'Canon*' in 5 characters. +Key 'foobar' matches '*foo*bar*' in 6 characters. +Key 'barfoofoobarbar' matches '*foo*bar*' in 6 characters. +Key 'foo' does not match 'foo*bar'. +Key 'bar' does not match 'foo*bar'. +Key 'foobar' matches 'foo*bar' in 6 characters. +Key 'fooYAHOObar' matches 'foo*bar' in 6 characters. +Key 'Thefoobar' does not match 'foo*bar'. +Key 'foobarTrick' does not match 'foo*bar'. +Key 'ThefoobarTrick' does not match 'foo*bar'. +Key 'ThefooYAHOObarTrick' does not match 'foo*bar'. +Key 'anything' matches '*' in 0 characters. +Key 'anything times two' matches '**' in 0 characters. +Key 'bar' matches '*bar' in 3 characters. +Key 'bar' does not match 'b*bar'. +Key 'bbar' matches 'b*bar' in 4 characters. +Key 'bar' does not match '*foobar'. +Key 'foobar' matches '*bar' in 3 characters. diff --git a/src/write-test.cpp b/src/write-test.cpp new file mode 100644 index 00000000..91715802 --- /dev/null +++ b/src/write-test.cpp @@ -0,0 +1,232 @@ +// ***************************************************************** -*- C++ -*- +/* + Abstract : ExifData write unit tests + + Author(s): Andreas Huggel (ahu) + Version : $Name: $ $Revision: 1.1 $ + + Test procedure: + $ rm -f test.jpg thumb.jpg iii ttt; + $ ./exifprint ../test/img_1771.jpg > iii; + $ cp ../test/img_1771.jpg ./test.jpg; + $ ./makernote-test2 ../test/img_1771.jpg > ttt; + $ diff iii ttt + + */ +// ***************************************************************************** +// included header files +#include "exif.hpp" +#include "makernote.hpp" + +#include +#include +#include +#include +#include + +// ***************************************************************************** +// local declarations + +using namespace Exif; + +void testCase(const std::string& file1, + const std::string& file2, + const std::string& thumb, + const std::string& key, + const std::string& value); +void exifPrint(const ExifData& exifData); +std::string readError(int rc, const char* file); +std::string writeError(int rc, const char* file); + +// ***************************************************************************** +// Main +int main(int argc, char* const argv[]) +try { + + if (argc != 3) { + std::cout << "Usage: write-test file case\n\n" + << "where case is an integer between 1 and 6\n"; + return 1; + } + + std::string testFile = argv[1]; + std::istringstream iss(argv[2]); + int testNo; + iss >> testNo; + + int rc = 0; + switch (testNo) { + case 1: + std::cerr << "Case 1: "; + std::cerr << "Non-intrusive change to the standard Exif metadata\n"; + testCase(testFile, "test1.jpg", "thumb1", + "Image.DateTime.DateTimeOriginal", + "1999:11:22 00:11:22"); + break; + case 2: + std::cerr << "Case 2: "; + std::cerr << "Non-intrusive change to the makernote metadata\n"; + testCase(testFile, "test2.jpg", "thumb2", + "Makernote.Canon.OwnerName", + "Chan YeeSend"); + break; + case 3: + std::cerr << "Case 3: "; + std::cerr << "Non-intrusive change to the Exif metadata (w/o makernote)\n"; + testCase(testFile, "test3.jpg", "thumb3", + "Image.DateTime.DateTimeOriginal", + "1999:11:22 00:11:22"); + break; + case 4: + std::cerr << "Case 4: "; + std::cerr << "Intrusive change to the standard Exif metadata\n"; + testCase(testFile, "test4.jpg", "thumb4", + "Image.DateTime.DateTimeOriginal", + "1999:11:22 00:11:22 and twenty seconds"); + break; + case 5: + std::cerr << "Case 5: "; + std::cerr << "Intrusive change to the makernote metadata\n"; + testCase(testFile, "test5.jpg", "thumb5", + "Makernote.Canon.OwnerName", + "Frau Chan YeeSend und Herr Andreas Huggel"); + break; + case 6: + std::cerr << "Case 6: "; + std::cerr << "Intrusive change to the Exif metadata (w/o makernote)\n"; + testCase(testFile, "test6.jpg", "thumb6", + "Image.DateTime.DateTimeOriginal", + "1999:11:22 00:11:22 and twenty seconds"); + break; + default: + std::cout << "Usage: exiftest file case\n\n" + << "where case is an integer between 1 and 6\n"; + rc = 1; + break; + } + + return rc; +} +catch (Error& e) { + std::cerr << "Caught Exif exception '" << e << "'\n"; + return 1; +} + +// ***************************************************************************** +void testCase(const std::string& file1, + const std::string& file2, + const std::string& thumb, + const std::string& key, + const std::string& value) +{ + ExifData ed1; + + std::cerr << "---> Reading file " << file1 << "\n"; + int rc = ed1.read(file1); + if (rc) { + std::string error = readError(rc, file1.c_str()); + throw Error(error); + } + + std::cerr << "---> Modifying Exif data\n"; + Exif::ExifData::iterator pos = ed1.findKey(key); + if (pos == ed1.end()) { + throw Error("Metadatum with key = " + key + " not found"); + } + pos->setValue(value); + + std::cerr << "---> Writing Exif data to file " << file2 << "\n"; + rc = ed1.write(file2); + if (rc) { + std::string error = writeError(rc, file2.c_str()); + throw Error(error); + } + + ExifData ed2; + + std::cerr << "---> Reading file " << file2 << "\n"; + rc = ed2.read(file2); + if (rc) { + std::string error = readError(rc, file2.c_str()); + throw Error(error); + } + + exifPrint(ed2); + + std::cerr << "---> Writing Exif thumbnail to file " << thumb << ".*\n"; + ed2.writeThumbnail(thumb); + +} + +// ***************************************************************************** + +void exifPrint(const ExifData& exifData) +{ + ExifData::const_iterator i = exifData.begin(); + for (; i != exifData.end(); ++i) { + std::cout << std::setw(53) << std::setfill(' ') << std::left + << i->key() << " " + << "0x" << std::setw(4) << std::setfill('0') << std::right + << std::hex << i->tag() << " " + << std::dec << i->value() + << "\n"; + } +} + +std::string readError(int rc, const char* file) +{ + std::string error; + switch (rc) { + case -1: + error = "Couldn't open file `" + std::string(file) + "'"; + break; + case 1: + error = "Couldn't read from the input stream"; + break; + case 2: + error = "This does not look like a JPEG image"; + break; + case 3: + error = "No Exif data found in the file"; + break; + case -99: + error = "Unsupported Exif or GPS data found in IFD 1"; + break; + default: + error = "Reading Exif data failed, rc = " + toString(rc); + break; + } + return error; +} + +std::string writeError(int rc, const char* file) +{ + std::string error; + switch (rc) { + case -1: + error = "Couldn't open file `" + std::string(file) + "'"; + break; + case -2: + error = "Couldn't open temporary file"; + break; + case -3: + error = "Renaming temporary file failed"; + break; + case 1: + error = "Couldn't read from the input stream"; + break; + case 2: + error = "This does not look like a JPEG image"; + break; + case 3: + error = "No JFIF APP0 or Exif APP1 segment found in the file"; + break; + case 4: + error = "Writing to the output stream failed"; + break; + default: + error = "Reading Exif data failed, rc = " + toString(rc); + break; + } + return error; +} diff --git a/src/write-test.out b/src/write-test.out new file mode 100644 index 00000000..a107265f --- /dev/null +++ b/src/write-test.out @@ -0,0 +1,104 @@ +------------------------------------------------------------ +Case 1: Non-intrusive change to the standard Exif metadata +---> Reading file ../test/img_1771.jpg +---> Modifying Exif data +---> Writing Exif data to file test1.jpg +->>>>>> using non-intrusive writing <<<<<<- +---> Reading file test1.jpg +---> Writing Exif thumbnail to file thumb1.* +13c13 +< Image.DateTime.DateTimeOriginal 0x9003 2003:12:14 12:01:44 +--- +> Image.DateTime.DateTimeOriginal 0x9003 1999:11:22 00:11:22 +------------------------------------------------------------ +Case 2: Non-intrusive change to the makernote metadata +---> Reading file ../test/img_1771.jpg +---> Modifying Exif data +---> Writing Exif data to file test2.jpg +->>>>>> using non-intrusive writing <<<<<<- +---> Reading file test2.jpg +---> Writing Exif thumbnail to file thumb2.* +49c49 +< Makernote.Canon.OwnerName 0x0009 Andreas Huggel +--- +> Makernote.Canon.OwnerName 0x0009 Chan YeeSend +------------------------------------------------------------ +Case 3: Non-intrusive change to the Exif metadata (w/o makernote) +---> Reading file ../test/kodak-dc210.jpg +---> Modifying Exif data +---> Writing Exif data to file test3.jpg +->>>>>> using non-intrusive writing <<<<<<- +---> Reading file test3.jpg +---> Writing Exif thumbnail to file thumb3.* +14c14 +< Image.DateTime.DateTimeOriginal 0x9003 2000:10:26 16:46:51 +--- +> Image.DateTime.DateTimeOriginal 0x9003 1999:11:22 00:11:22 +------------------------------------------------------------ +Case 4: Intrusive change to the standard Exif metadata +---> Reading file ../test/img_1771.jpg +---> Modifying Exif data +---> Writing Exif data to file test4.jpg +->>>>>> writing from metadata <<<<<<- +---> Reading file test4.jpg +---> Writing Exif thumbnail to file thumb4.* +9c9 +< Image.ExifFormat.ExifTag 0x8769 196 +--- +> Image.ExifFormat.ExifTag 0x8769 184 +13c13 +< Image.DateTime.DateTimeOriginal 0x9003 2003:12:14 12:01:44 +--- +> Image.DateTime.DateTimeOriginal 0x9003 1999:11:22 00:11:22 and twenty seconds +29c29 +< Image.ExifFormat.InteroperabilityTag 0xa005 1416 +--- +> Image.ExifFormat.InteroperabilityTag 0xa005 1423 +60c60 +< Thumbnail.RecordingOffset.JPEGInterchangeFormat 0x0201 2036 +--- +> Thumbnail.RecordingOffset.JPEGInterchangeFormat 0x0201 1571 +------------------------------------------------------------ +Case 5: Intrusive change to the makernote metadata +---> Reading file ../test/img_1771.jpg +---> Modifying Exif data +---> Writing Exif data to file test5.jpg +->>>>>> writing from metadata <<<<<<- +---> Reading file test5.jpg +---> Writing Exif thumbnail to file thumb5.* +9c9 +< Image.ExifFormat.ExifTag 0x8769 196 +--- +> Image.ExifFormat.ExifTag 0x8769 184 +29c29 +< Image.ExifFormat.InteroperabilityTag 0xa005 1416 +--- +> Image.ExifFormat.InteroperabilityTag 0xa005 1414 +49c49 +< Makernote.Canon.OwnerName 0x0009 Andreas Huggel +--- +> Makernote.Canon.OwnerName 0x0009 Frau Chan YeeSend und Herr Andreas Huggel +60c60 +< Thumbnail.RecordingOffset.JPEGInterchangeFormat 0x0201 2036 +--- +> Thumbnail.RecordingOffset.JPEGInterchangeFormat 0x0201 1562 +------------------------------------------------------------ +Case 6: Intrusive change to the Exif metadata (w/o makernote) +---> Reading file ../test/kodak-dc210.jpg +---> Modifying Exif data +---> Writing Exif data to file test6.jpg +->>>>>> writing from metadata <<<<<<- +---> Reading file test6.jpg +---> Writing Exif thumbnail to file thumb6.* +10c10 +< Image.ExifFormat.ExifTag 0x8769 374 +--- +> Image.ExifFormat.ExifTag 0x8769 192 +14c14 +< Image.DateTime.DateTimeOriginal 0x9003 2000:10:26 16:46:51 +--- +> Image.DateTime.DateTimeOriginal 0x9003 1999:11:22 00:11:22 and twenty seconds +33c33 +< Thumbnail.RecordingOffset.StripOffsets 0x0111 928 +--- +> Thumbnail.RecordingOffset.StripOffsets 0x0111 765 diff --git a/src/write-test.sh b/src/write-test.sh new file mode 100755 index 00000000..af92c7a5 --- /dev/null +++ b/src/write-test.sh @@ -0,0 +1,62 @@ +#! /bin/sh +# Test driver for the write unit tests + +# Case 1 +echo "------------------------------------------------------------" +testFile="../test/img_1771.jpg" +rm -f test1.jpg thumb1.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test1.jpg; +./write-test $testFile 1 > ttt; +diff iii ttt + +# Case 2 +echo "------------------------------------------------------------" +testFile="../test/img_1771.jpg" +rm -f test2.jpg thumb2.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test2.jpg; +./write-test $testFile 2 > ttt; +diff iii ttt + +# Case 3 +echo "------------------------------------------------------------" +testFile="../test/kodak-dc210.jpg" +rm -f test3.jpg thumb3.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test3.jpg; +./write-test $testFile 3 > ttt; +diff iii ttt + +# Case 4 +echo "------------------------------------------------------------" +testFile="../test/img_1771.jpg" +rm -f test4.jpg thumb4.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test4.jpg; +./write-test $testFile 4 > ttt; +diff iii ttt + +# Case 5 +echo "------------------------------------------------------------" +testFile="../test/img_1771.jpg" +rm -f test5.jpg thumb5.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test5.jpg; +./write-test $testFile 5 > ttt; +diff iii ttt + +# Case 6 +echo "------------------------------------------------------------" +testFile="../test/kodak-dc210.jpg" +rm -f test6.jpg thumb6.jpg +rm -f iii ttt; +./exifprint $testFile > iii; +cp $testFile ./test6.jpg; +./write-test $testFile 6 > ttt; +diff iii ttt