Update extlib/EXIF
[mediagoblin.git] / mediagoblin / tests / test_exif.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 import os
18 import pkg_resources
19 import Image
20
21 from mediagoblin.tools.exif import exif_fix_image_orientation, \
22 extract_exif, clean_exif, get_gps_data, get_useful
23
24
25 def assert_in(a, b):
26 assert a in b, "%r not in %r" % (a, b)
27
28
29 GOOD_JPG = pkg_resources.resource_filename(
30 'mediagoblin.tests',
31 os.path.join(
32 'test_exif',
33 'good.jpg'))
34 EMPTY_JPG = pkg_resources.resource_filename(
35 'mediagoblin.tests',
36 os.path.join(
37 'test_exif',
38 'empty.jpg'))
39 BAD_JPG = pkg_resources.resource_filename(
40 'mediagoblin.tests',
41 os.path.join(
42 'test_exif',
43 'bad.jpg'))
44 GPS_JPG = pkg_resources.resource_filename(
45 'mediagoblin.tests',
46 os.path.join(
47 'test_exif',
48 'has-gps.jpg'))
49
50
51 def test_exif_extraction():
52 '''
53 Test EXIF extraction from a good image
54 '''
55 result = extract_exif(GOOD_JPG)
56 clean = clean_exif(result)
57 useful = get_useful(clean)
58 gps = get_gps_data(result)
59
60 # Do we have the result?
61 assert len(result) == 56
62
63 # Do we have clean data?
64 assert len(clean) == 53
65
66 # GPS data?
67 assert gps == {}
68
69 # Do we have the "useful" tags?
70 assert useful == {
71 'EXIF Flash': {
72 'field_type': 3,
73 'printable': u'Flash did not fire',
74 'field_offset': 380,
75 'tag': 37385,
76 'values': [0],
77 'field_length': 2},
78 'EXIF ExposureTime': {
79 'field_type': 5,
80 'printable': '1/125',
81 'field_offset': 700,
82 'tag': 33434,
83 'values': [[1, 125]],
84 'field_length': 8},
85 'EXIF FocalLength': {
86 'field_type': 5,
87 'printable': '18',
88 'field_offset': 780,
89 'tag': 37386,
90 'values': [[18, 1]],
91 'field_length': 8},
92 'Image Model': {
93 'field_type': 2,
94 'printable': 'NIKON D80',
95 'field_offset': 152,
96 'tag': 272,
97 'values': 'NIKON D80',
98 'field_length': 10},
99 'Image Make': {
100 'field_type': 2,
101 'printable': 'NIKON CORPORATION',
102 'field_offset': 134,
103 'tag': 271,
104 'values': 'NIKON CORPORATION',
105 'field_length': 18},
106 'EXIF ExposureMode': {
107 'field_type': 3,
108 'printable': 'Manual Exposure',
109 'field_offset': 584,
110 'tag': 41986,
111 'values': [1],
112 'field_length': 2},
113 'EXIF ISOSpeedRatings': {
114 'field_type': 3,
115 'printable': '100',
116 'field_offset': 260,
117 'tag': 34855,
118 'values': [100],
119 'field_length': 2},
120 'EXIF FNumber': {
121 'field_type': 5,
122 'printable': '10',
123 'field_offset': 708,
124 'tag': 33437,
125 'values': [[10, 1]],
126 'field_length': 8}}
127
128
129 def test_exif_image_orientation():
130 '''
131 Test image reorientation based on EXIF data
132 '''
133 result = extract_exif(GOOD_JPG)
134
135 image = exif_fix_image_orientation(
136 Image.open(GOOD_JPG),
137 result)
138
139 # Are the dimensions correct?
140 assert image.size == (428, 640)
141
142 # If this pixel looks right, the rest of the image probably will too.
143 assert_in(image.getdata()[10000],
144 ((41, 28, 11), (43, 27, 11))
145 )
146
147
148 def test_exif_no_exif():
149 '''
150 Test an image without exif
151 '''
152 result = extract_exif(EMPTY_JPG)
153 clean = clean_exif(result)
154 useful = get_useful(clean)
155 gps = get_gps_data(result)
156
157 assert result == {}
158 assert clean == {}
159 assert gps == {}
160 assert useful == {}
161
162
163 def test_exif_bad_image():
164 '''
165 Test EXIF extraction from a faithful, but bad image
166 '''
167 result = extract_exif(BAD_JPG)
168 clean = clean_exif(result)
169 useful = get_useful(clean)
170 gps = get_gps_data(result)
171
172 assert result == {}
173 assert clean == {}
174 assert gps == {}
175 assert useful == {}
176
177
178 def test_exif_gps_data():
179 '''
180 Test extractiion of GPS data
181 '''
182 result = extract_exif(GPS_JPG)
183 gps = get_gps_data(result)
184
185 assert gps == {
186 'latitude': 59.336666666666666,
187 'direction': 25.674046740467404,
188 'altitude': 37.64365671641791,
189 'longitude': 18.016166666666667}