Merge remote-tracking branch 'refs/remotes/brett/bug270-lazycelery-script'
[mediagoblin.git] / mediagoblin / tests / test_exif.py
CommitLineData
63bd7c04 1# GNU MediaGoblin -- federated, autonomous media hosting
cf29e8a8 2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
63bd7c04
JW
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
17import os
18import pkg_resources
19import Image
20
21from mediagoblin.tools.exif import exif_fix_image_orientation, \
22 extract_exif, clean_exif, get_gps_data, get_useful
23
ccca39f1
E
24
25def assert_in(a, b):
26 assert a in b, "%r not in %r" % (a, b)
27
28
63bd7c04
JW
29GOOD_JPG = pkg_resources.resource_filename(
30 'mediagoblin.tests',
31 os.path.join(
32 'test_exif',
33 'good.jpg'))
34EMPTY_JPG = pkg_resources.resource_filename(
35 'mediagoblin.tests',
36 os.path.join(
37 'test_exif',
38 'empty.jpg'))
39BAD_JPG = pkg_resources.resource_filename(
40 'mediagoblin.tests',
41 os.path.join(
42 'test_exif',
43 'bad.jpg'))
44GPS_JPG = pkg_resources.resource_filename(
45 'mediagoblin.tests',
46 os.path.join(
47 'test_exif',
48 'has-gps.jpg'))
49
ccca39f1 50
63bd7c04
JW
51def 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) == 108
62
63 # Do we have clean data?
64 assert len(clean) == 105
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': 'No',
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 'EXIF UserComment': {
128 'field_type': 7,
129 'printable': 'Joar Wandborg ',
130 'field_offset': 26180,
131 'tag': 37510,
132 'values': [
133 65, 83, 67, 73, 73, 0, 0, 0, 74, 111, 97, 114, 32, 87,
134 97, 110, 100, 98, 111, 114, 103, 32, 32, 32, 32, 32, 32,
135 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
136 32, 32, 32],
137 'field_length': 44}}
138
ccca39f1 139
63bd7c04
JW
140def test_exif_image_orientation():
141 '''
142 Test image reorientation based on EXIF data
143 '''
144 result = extract_exif(GOOD_JPG)
145
146 image = exif_fix_image_orientation(
147 Image.open(GOOD_JPG),
148 result)
149
150 # Are the dimensions correct?
151 assert image.size == (428, 640)
152
153 # If this pixel looks right, the rest of the image probably will too.
ccca39f1
E
154 assert_in(image.getdata()[10000],
155 ((41, 28, 11), (43, 27, 11))
156 )
157
63bd7c04
JW
158
159def test_exif_no_exif():
160 '''
161 Test an image without exif
162 '''
163 result = extract_exif(EMPTY_JPG)
164 clean = clean_exif(result)
165 useful = get_useful(clean)
166 gps = get_gps_data(result)
167
168 assert result == {}
169 assert clean == {}
170 assert gps == {}
171 assert useful == {}
172
ccca39f1 173
63bd7c04
JW
174def test_exif_bad_image():
175 '''
176 Test EXIF extraction from a faithful, but bad image
177 '''
178 result = extract_exif(BAD_JPG)
179 clean = clean_exif(result)
180 useful = get_useful(clean)
181 gps = get_gps_data(result)
182
183 assert result == {}
184 assert clean == {}
185 assert gps == {}
186 assert useful == {}
187
ccca39f1 188
63bd7c04
JW
189def test_exif_gps_data():
190 '''
191 Test extractiion of GPS data
192 '''
193 result = extract_exif(GPS_JPG)
194 gps = get_gps_data(result)
195
196 assert gps == {
197 'latitude': 59.336666666666666,
198 'direction': 25.674046740467404,
199 'altitude': 37.64365671641791,
200 'longitude': 18.016166666666667}