diff --git a/test/Makefile.am b/test/Makefile.am index 45023ef..e99d75e 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,19 +4,27 @@ # check-vars.sh.in is automatically included EXTRA_DIST = \ + check-add-tags.sh \ + check-create-tags.sh \ check-help.sh \ + check-init-mandatory-tags.sh \ check-param-validity.sh \ check-show-description.sh \ check-show-tag.sh \ + check-tag-description.sh \ check-thumbnail.sh \ check-version.sh \ testdata/no-exif.jpg check_SCRIPTS = \ + check-add-tags.sh \ + check-create-tags.sh \ check-help.sh \ + check-init-mandatory-tags.sh \ check-param-validity.sh \ check-show-description.sh \ check-show-tag.sh \ + check-tag-description.sh \ check-thumbnail.sh \ check-version.sh diff --git a/test/check-add-tags.sh b/test/check-add-tags.sh new file mode 100755 index 0000000..e2797ad --- /dev/null +++ b/test/check-add-tags.sh @@ -0,0 +1,168 @@ +#!/bin/sh +# Adds tags to an exiting EXIF file. Checks that the tag data is interpreted +# correctly from the command line. Tags representative of as many different +# data types as possible are included. Data inputs with extra spaces, +# plus and minus signs are tested. + +. ./check-vars.sh + +srcimg="add-tag-src.out.jpg" +dstimg="add-tag.out.jpg" +tmpfile="output.tmp" + +error=0 + +check_result () { + s="$?" + if test "$s" -ne 0; then + echo " FAILED (${s})." + error=1 + fi +} + +append_image () { + if [ -e "$dstimg" ] ; then + mv -f "$dstimg" "$srcimg" + fi +} + +echo Create an empty EXIF tag block +$EXIFEXE --create-exif --no-fixup -o "$srcimg" "$SRCDIR/testdata/no-exif.jpg" +check_result + +echo Create SHORT value +$EXIFEXE --no-fixup --ifd=EXIF --tag=FocalLengthIn35mmFilm --set-value='12345' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create SHORT value array +$EXIFEXE --no-fixup --ifd=0 --tag=YCbCrSubSampling --set-value='2 2' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo 'Create SHORT value (enum)' +$EXIFEXE --no-fixup --ifd=EXIF --tag=SceneCaptureType --set-value='3' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo 'Create SHORT value (hex tag)' +$EXIFEXE --no-fixup --ifd=EXIF --tag=0xa401 --set-value='2' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo 'Create SHORT value (decimal tag)' +$EXIFEXE --no-fixup --ifd=EXIF --tag=41986 --set-value=1 -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo 'Create SHORT value (tag title)' +$EXIFEXE --no-fixup --ifd=EXIF --tag='White Balance' --set-value=1 -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create LONG value +$EXIFEXE --no-fixup --ifd=EXIF --tag=PixelXDimension --set-value=64 -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create RATIONAL value +$EXIFEXE --no-fixup --ifd=0 --tag=XResolution --set-value=' 99 1' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create RATIONAL value array +$EXIFEXE --no-fixup --ifd=0 --tag=WhitePoint --set-value='+9 2 19 3 ' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create SRATIONAL value +$EXIFEXE --no-fixup --ifd=EXIF --tag=ExposureBiasValue --set-value='-3 2' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create UNDEFINED value +$EXIFEXE --no-fixup --ifd=EXIF --tag=SceneType --set-value=1 -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create UNDEFINED value array +$EXIFEXE --no-fixup --ifd=EXIF --tag=FlashPixVersion --set-value='49 50 51 52' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo Create ASCII value +$EXIFEXE --no-fixup --ifd=0 --tag=ImageDescription --set-value='The image description' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +echo 'Create ASCII value (User Comment)' +$EXIFEXE --no-fixup --ifd=EXIF --tag=UserComment --set-value='The user comment' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +# Count the number of tags +numtags=`$EXIFEXE --no-fixup -m -i "$srcimg" | wc -l` +echo Must be 14 tags: $numtags +test "$numtags" -eq 14 +check_result + +# The remaining tests are failure mode tests + +echo Test invalid RATIONAL--not enough components +$EXIFEXE --no-fixup --ifd=0 --tag=XResolution --set-value=99 -o "$dstimg" "$srcimg" >/dev/null || +test "$?" -eq 1 +check_result +append_image + +echo Test invalid RATIONAL--not digits +$EXIFEXE --no-fixup --ifd=0 --tag=YResolution --set-value='9 b' -o "$dstimg" "$srcimg" >/dev/null +test "$?" -eq 1 +check_result +append_image + +echo Test invalid SHORT--no value +$EXIFEXE --no-fixup --ifd=0 --tag=FocalLengthIn35mmFilm --set-value='' -o "$dstimg" "$srcimg" >/dev/null +test "$?" -eq 1 +check_result +append_image + +echo Test invalid SHORT--invalid tag +$EXIFEXE --no-fixup --ifd=0 --tag=0xbbbb --set-value=1 -o "$dstimg" "$srcimg" >/dev/null +test "$?" -eq 1 +check_result +append_image + +echo Test invalid RATIONAL--too many components +# exif treats this as a warning and doesn't report an error code +$EXIFEXE --no-fixup --ifd=0 --tag=XResolution --set-value='12 2 3' -o "$dstimg" "$srcimg" >/dev/null +check_result +append_image + +# Check the resulting EXIF file +env LANG=C LANGUAGE=C $EXIFEXE -m -i "$srcimg" >"$tmpfile" +"$DIFFEXE" "$tmpfile" - </dev/null +check_result + +echo Create YResolution +$EXIFEXE --create-exif --no-fixup --ifd=0 --tag=YResolution --set-value='123 2' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create ResolutionUnit +$EXIFEXE --create-exif --no-fixup --ifd=0 --tag=ResolutionUnit --set-value='3' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create DateTime +$EXIFEXE --create-exif --no-fixup --ifd=0 --tag=DateTime --set-value='2010:01:22 03:44:55' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create YCbCrPositioning +$EXIFEXE --create-exif --no-fixup --ifd=0 --tag=YCbCrPositioning --set-value='2' -o "$dstimg" "$srcimg" >/dev/null +check_result + +# IFD EXIF mandatory entries + +echo Create ExifVersion +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=ExifVersion --set-value='48 50 50 49' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create ComponentsConfiguration +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=ComponentsConfiguration --set-value='2 3 1 0' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create FlashPixVersion +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=FlashPixVersion --set-value='48 49 48 48' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create ColorSpace +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=ColorSpace --set-value='2' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create PixelXDimension +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=PixelXDimension --set-value='64' -o "$dstimg" "$srcimg" >/dev/null +check_result + +echo Create PixelYDimension +$EXIFEXE --create-exif --no-fixup --ifd=EXIF --tag=PixelYDimension --set-value='32' -o "$dstimg" "$srcimg" >/dev/null +check_result + +rm -f "$dstimg" + +exit 0 + + +Here are the default values created by exif for the mandatory tags which +for which it is able to create default values. + +EXIF tags in '(EXIF)' ('Motorola' byte order): +------+------------------------------------------------------------------------ +Tag |Value +------+------------------------------------------------------------------------ +0x011a|72.00 +0x011b|72.00 +0x0128|Inch +0x0213|Centred +0x0132|2010:09:25 23:58:21 +0x9000|Exif Version 2.1 +0x9101|Y Cb Cr - +0xa000|FlashPix Version 1.0 +0xa001|Uncalibrated +0xa002|0 +0xa003|0 +------+------------------------------------------------------------------------ +EXIF tags in '(EXIF)': 0 1 EXIF GPS Interop +0x011a X-Resolution * - - - - +0x011b Y-Resolution * - - - - +0x0128 Resolution Unit * - - - - +0x0132 Date and Time * - - - - +0x0213 YCbCr Positioning * - - - - +0x9000 Exif Version - - * - - +0x9101 Components Configuration - - * - - +0xa000 FlashPixVersion - - * - - +0xa001 Colour Space - - * - - +0xa002 Pixel X Dimension - - * - - +0xa003 Pixel Y Dimension - - * - - diff --git a/test/check-tag-description.sh b/test/check-tag-description.sh new file mode 100755 index 0000000..5dd21ae --- /dev/null +++ b/test/check-tag-description.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Checks tag description lookup. Only tests a representative sample of +# tags, especially those that test some potential boundary conditions +# of the lookup routines. + +. ./check-vars.sh +tmpfile="./output.tmp" + +# clear out the output file +rm -f "$tmpfile" + +# List the tags to test +TESTTAGS_GPS="0" # first in table +TESTTAGS_GPS=$TESTTAGS_GPS" 1" # same number as in Interoperability IFD + +TESTTAGS_Interoperability="1" # same number as in GPS IFD + +TESTTAGS_0="1" # doesn't exist in this IFD +TESTTAGS_0=$TESTTAGS_0" 0x100" # first in table for this IFD +TESTTAGS_0=$TESTTAGS_0" 0xfe" # exists in table, but not marked as usable in any IFD +TESTTAGS_0=$TESTTAGS_0" 0x8769" # entry for a sub-IFD + # This currently prints an empty description, + # which is really a bug in libexif. + +TESTTAGS_0=$TESTTAGS_0" 0xbbbb" # not in table, but between two that are +TESTTAGS_0=$TESTTAGS_0" 0xfffe" # second-largest possible number (not in table) + +TESTTAGS_1="0x0201" # only exists in IFD 1 + +TESTTAGS_EXIF=$TESTTAGS_EXIF" 0x0201" # only exists in IFD 1, not EXIF IFD +TESTTAGS_EXIF=$TESTTAGS_EXIF" 0xa420" # last in table associated with an IFD +TESTTAGS_EXIF=$TESTTAGS_EXIF" 0xea1c" # last in table (not associated with IFD) + +for ifd in GPS Interoperability 0 1 EXIF; do + TESTTAGS=`eval echo \\$TESTTAGS_${ifd}` + for tag in $TESTTAGS; do + echo Testing IFD $ifd tag $tag + env LANG=C LANGUAGE=C $EXIFEXE --tag=$tag --ifd=$ifd -s >>"$tmpfile" + done +done + +# Test --machine-readable, using first mandatory tag +env LANG=C LANGUAGE=C $EXIFEXE --tag=0x11a --ifd=0 -m -s >>"$tmpfile" + +"$DIFFEXE" "$tmpfile" - <. The version is given as 2.0.0.0. This tag is mandatory when tag is present. (Note: The tag is given in bytes, unlike the tag. When the version is 2.0.0.0, the tag value is 02000000.H). +Tag 'North or South Latitude' (0x0001, 'GPSLatitudeRef'): Indicates whether the latitude is north or south latitude. The ASCII value 'N' indicates north latitude, and 'S' is south latitude. +Tag 'Interoperability Index' (0x0001, 'InteroperabilityIndex'): Indicates the identification of the Interoperability rule. Use "R98" for stating ExifR98 Rules. Four bytes used including the termination code (NULL). see the separate volume of Recommended Exif Interoperability Rules (ExifR98) for other tags used for ExifR98. +Tag 'Image Width' (0x0100, 'ImageWidth'): The number of columns of image data, equal to the number of pixels per row. In JPEG compressed data a JPEG marker is used instead of this tag. +Tag 'New Subfile Type' (0x00fe, 'NewSubfileType'): A general indication of the kind of data contained in this subfile. +Tag 'JPEG Interchange Format' (0x0201, 'JPEGInterchangeFormat'): The offset to the start byte (SOI) of JPEG compressed thumbnail data. This is not used for primary image JPEG data. +Tag 'Image Unique ID' (0xa420, 'ImageUniqueID'): This tag indicates an identifier assigned uniquely to each image. It is recorded as an ASCII string equivalent to hexadecimal notation and 128-bit fixed length. +Tag 'Padding' (0xea1c, 'Padding'): This tag reserves space that can be reclaimed later when additional metadata are added. New metadata can be written in place by replacing this tag with a smaller data element and using the reclaimed space to store the new or expanded metadata tags. +0x011a XResolution X-Resolution The number of pixels per in the direction. When the image resolution is unknown, 72 [dpi] is designated. +EOF +s="$?" + +rm -f "$tmpfile" + +exit "$s"