Skip to content

Commit

Permalink
Moved some tests from libexif-testsuite here.
Browse files Browse the repository at this point in the history
These tests are basically self-contained and don't depend on the library
of images included in libexif-testsuite, so they're appropriate for
running within the exif project. Doing so makes them much more
accessible than leaving them in a separate project.
  • Loading branch information
dfandrich committed Nov 2, 2018
1 parent 08ff692 commit 636f21e
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 0 deletions.
8 changes: 8 additions & 0 deletions test/Makefile.am
Expand Up @@ -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

Expand Down
168 changes: 168 additions & 0 deletions 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" - <<EOF
0x010e The image description
0x011a 6.0
0x013e 4.5, 6.3
0x0212 YCbCr4:2:0
0x011b 72
0x0128 Inch
0x9204 -1.50 EV
0x9286 The user comment
0xa000 Unknown FlashPix Version
0xa002 64
0xa301 Directly photographed
0xa401 2
0xa402 Manual exposure
0xa403 Manual white balance
0xa405 12345
0xa406 Night scene
0x9000 Exif Version 2.1
0xa001 Uncalibrated
EOF
check_result

rm -f "$srcimg" "$dstimg" "$tmpfile"

echo Test complete: status $error
exit "$error"
35 changes: 35 additions & 0 deletions test/check-create-tags.sh
@@ -0,0 +1,35 @@
#!/bin/sh
# Tests the creation of new EXIF data.
# Checks that the expected tags are created, and that the --no-fixup option
# creates no tags, just an empty EXIF structure.

. ./check-vars.sh

dstimg="./create-tags.out.jpg"

# Abort on any command failure
set -e

echo Create an empty EXIF tag block
$EXIFEXE --create-exif --no-fixup -o "$dstimg" "$SRCDIR/testdata/no-exif.jpg"

# Count the number of tags
numtags=`$EXIFEXE --no-fixup -m -i "$dstimg" | wc -l`

echo Must be 0 tags: $numtags
test $numtags = 0

rm -f "$dstimg"

echo Create a EXIF tag block with mandatory and default tags
$EXIFEXE --create-exif -o "$dstimg" "$SRCDIR/testdata/no-exif.jpg"

# Count the number of tags
numtags=`$EXIFEXE --no-fixup -m -i "$dstimg" | wc -l`

echo Must be 11 tags: $numtags
test $numtags = 11

rm -f "$dstimg"


102 changes: 102 additions & 0 deletions test/check-init-mandatory-tags.sh
@@ -0,0 +1,102 @@
#!/bin/sh
# Ensure that all mandatory tags can be created with --set-value

# TODO: add the other mandatory values for all image types

. ./check-vars.sh

dstimg="init.out.jpg"
srcimg="$SRCDIR/testdata/no-exif.jpg"

check_result () {
s="$?"
if test "$s" -ne 0; then
echo " FAILED (${s})."
error=1
fi
}

# IFD 0 mandatory entries

echo Create XResolution
$EXIFEXE --create-exif --no-fixup --ifd=0 --tag=XResolution --set-value=' 99 1' -o "$dstimg" "$srcimg" >/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 - - * - -
60 changes: 60 additions & 0 deletions 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" - <<EOF
Tag 'GPS Tag Version' (0x0000, 'GPSVersionID'): Indicates the version of <GPSInfoIFD>. The version is given as 2.0.0.0. This tag is mandatory when <GPSInfo> tag is present. (Note: The <GPSVersionID> tag is given in bytes, unlike the <ExifVersion> 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 <ResolutionUnit> in the <ImageWidth> direction. When the image resolution is unknown, 72 [dpi] is designated.
EOF
s="$?"

rm -f "$tmpfile"

exit "$s"

0 comments on commit 636f21e

Please sign in to comment.