Merge remote-tracking branch 'joar/exif-rebase'
[mediagoblin.git] / mediagoblin / tests / test_exif.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 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 GOOD_JPG = pkg_resources.resource_filename(
25 'mediagoblin.tests',
26 os.path.join(
27 'test_exif',
28 'good.jpg'))
29 EMPTY_JPG = pkg_resources.resource_filename(
30 'mediagoblin.tests',
31 os.path.join(
32 'test_exif',
33 'empty.jpg'))
34 BAD_JPG = pkg_resources.resource_filename(
35 'mediagoblin.tests',
36 os.path.join(
37 'test_exif',
38 'bad.jpg'))
39 GPS_JPG = pkg_resources.resource_filename(
40 'mediagoblin.tests',
41 os.path.join(
42 'test_exif',
43 'has-gps.jpg'))
44
45 def test_exif_extraction():
46 '''
47 Test EXIF extraction from a good image
48 '''
49 result = extract_exif(GOOD_JPG)
50 clean = clean_exif(result)
51 useful = get_useful(clean)
52 gps = get_gps_data(result)
53
54 # Do we have the result?
55 assert len(result) == 108
56
57 # Do we have clean data?
58 assert len(clean) == 105
59
60 # GPS data?
61 assert gps == {}
62
63 # Do we have the "useful" tags?
64 assert useful == {
65 'EXIF Flash': {
66 'field_type': 3,
67 'printable': 'No',
68 'field_offset': 380,
69 'tag': 37385,
70 'values': [0],
71 'field_length': 2},
72 'EXIF ExposureTime': {
73 'field_type': 5,
74 'printable': '1/125',
75 'field_offset': 700,
76 'tag': 33434,
77 'values': [[1, 125]],
78 'field_length': 8},
79 'EXIF FocalLength': {
80 'field_type': 5,
81 'printable': '18',
82 'field_offset': 780,
83 'tag': 37386,
84 'values': [[18, 1]],
85 'field_length': 8},
86 'Image Model': {
87 'field_type': 2,
88 'printable': 'NIKON D80',
89 'field_offset': 152,
90 'tag': 272,
91 'values': 'NIKON D80',
92 'field_length': 10},
93 'Image Make': {
94 'field_type': 2,
95 'printable': 'NIKON CORPORATION',
96 'field_offset': 134,
97 'tag': 271,
98 'values': 'NIKON CORPORATION',
99 'field_length': 18},
100 'EXIF ExposureMode': {
101 'field_type': 3,
102 'printable': 'Manual Exposure',
103 'field_offset': 584,
104 'tag': 41986,
105 'values': [1],
106 'field_length': 2},
107 'EXIF ISOSpeedRatings': {
108 'field_type': 3,
109 'printable': '100',
110 'field_offset': 260,
111 'tag': 34855,
112 'values': [100],
113 'field_length': 2},
114 'EXIF FNumber': {
115 'field_type': 5,
116 'printable': '10',
117 'field_offset': 708,
118 'tag': 33437,
119 'values': [[10, 1]],
120 'field_length': 8},
121 'EXIF UserComment': {
122 'field_type': 7,
123 'printable': 'Joar Wandborg ',
124 'field_offset': 26180,
125 'tag': 37510,
126 'values': [
127 65, 83, 67, 73, 73, 0, 0, 0, 74, 111, 97, 114, 32, 87,
128 97, 110, 100, 98, 111, 114, 103, 32, 32, 32, 32, 32, 32,
129 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
130 32, 32, 32],
131 'field_length': 44}}
132
133 def test_exif_image_orientation():
134 '''
135 Test image reorientation based on EXIF data
136 '''
137 result = extract_exif(GOOD_JPG)
138
139 image = exif_fix_image_orientation(
140 Image.open(GOOD_JPG),
141 result)
142
143 # Are the dimensions correct?
144 assert image.size == (428, 640)
145
146 # If this pixel looks right, the rest of the image probably will too.
147 assert image.getdata()[10000] == (41, 28, 11)
148
149 def test_exif_no_exif():
150 '''
151 Test an image without exif
152 '''
153 result = extract_exif(EMPTY_JPG)
154 clean = clean_exif(result)
155 useful = get_useful(clean)
156 gps = get_gps_data(result)
157
158 assert result == {}
159 assert clean == {}
160 assert gps == {}
161 assert useful == {}
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 def test_exif_gps_data():
178 '''
179 Test extractiion of GPS data
180 '''
181 result = extract_exif(GPS_JPG)
182 gps = get_gps_data(result)
183
184 assert gps == {
185 'latitude': 59.336666666666666,
186 'direction': 25.674046740467404,
187 'altitude': 37.64365671641791,
188 'longitude': 18.016166666666667}
189