1: <?php
2: 3: 4: 5: 6: 7:
8:
9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
29: class Horde_Image_Exif_Parser_Nikon extends Horde_Image_Exif_Parser_Base
30: {
31: 32: 33: 34: 35: 36:
37: protected function _lookupTag($tag, $model)
38: {
39: switch ($model) {
40: case 0:
41: switch($tag) {
42: case '0003': $tag = 'Quality'; break;
43: case '0004': $tag = 'ColorMode'; break;
44: case '0005': $tag = 'ImageAdjustment'; break;
45: case '0006': $tag = 'CCDSensitivity'; break;
46: case '0007': $tag = 'WhiteBalance'; break;
47: case '0008': $tag = 'Focus'; break;
48: case '0009': $tag = 'Unknown2'; break;
49: case '000a': $tag = 'DigitalZoom'; break;
50: case '000b': $tag = 'Converter'; break;
51: default: $tag = 'unknown: ' . $tag; break;
52: }
53: break;
54:
55: case 1:
56: switch($tag) {
57: case '0002': $tag = 'ISOSetting'; break;
58: case '0003': $tag = 'ColorMode'; break;
59: case '0004': $tag = 'Quality'; break;
60: case '0005': $tag = 'Whitebalance'; break;
61: case '0006': $tag = 'ImageSharpening'; break;
62: case '0007': $tag = 'FocusMode'; break;
63: case '0008': $tag = 'FlashSetting'; break;
64: case '0009': $tag = 'FlashMode'; break;
65: case '000b': $tag = 'WhiteBalanceFine'; break;
66: case '000f': $tag = 'ISOSelection'; break;
67: case '0013': $tag = 'ISOSelection2'; break;
68: case '0080': $tag = 'ImageAdjustment'; break;
69: case '0081': $tag = 'ToneCompensation'; break;
70: case '0082': $tag = 'Adapter'; break;
71: case '0083': $tag = 'LensType'; break;
72: case '0084': $tag = 'LensInfo'; break;
73: case '0085': $tag = 'ManualFocusDistance'; break;
74: case '0086': $tag = 'DigitalZoom'; break;
75: case '0087': $tag = 'FlashUsed'; break;
76: case '0088': $tag = 'AFFocusPosition'; break;
77: case '008d': $tag = 'ColorMode'; break;
78: case '0090': $tag = 'LightType'; break;
79: case '0094': $tag = 'Saturation'; break;
80: case '0095': $tag = 'NoiseReduction'; break;
81: case '0010': $tag = 'DataDump'; break;
82: default: $tag = 'unknown: ' . $tag; break;
83: }
84: break;
85: }
86:
87: return $tag;
88: }
89:
90: 91: 92: 93: 94: 95: 96: 97: 98:
99: protected function _formatData($type, $tag, $intel, $model, $data)
100: {
101: switch ($type) {
102: case 'URATIONAL':
103: case 'SRATIONAL':
104: $data = bin2hex($data);
105: if ($intel) {
106: $data = Horde_Image_Exif::intel2Moto($data);
107: }
108: $top = hexdec(substr($data, 8, 8));
109: $bottom = hexdec(substr($data, 0, 8));
110: if ($bottom != 0) {
111: $data = $top / $bottom;
112: } elseif ($top == 0) {
113: $data = 0;
114: } else {
115: $data = $top . '/' . $bottom;
116: }
117:
118: if ($tag == '0085' && $model == 1) {
119:
120: $data = $data . ' m';
121: }
122: if ($tag == '0086' && $model == 1) {
123:
124: $data = $data . 'x';
125: }
126: if ($tag == '000a' && $model == 0) {
127:
128: $data = $data . 'x';
129: }
130: break;
131:
132: case 'USHORT':
133: case 'SSHORT':
134: case 'ULONG':
135: case 'SLONG':
136: case 'FLOAT':
137: case 'DOUBLE':
138: $data = bin2hex($data);
139: if ($intel) {
140: $data = Horde_Image_Exif::intel2Moto($data);
141: }
142: $data = hexdec($data);
143: if ($model != 0) {
144: break;
145: }
146:
147: switch ($tag) {
148: case '0003':
149:
150: switch ($data) {
151: case 1: $data = Horde_Image_Translation::t("VGA Basic"); break;
152: case 2: $data = Horde_Image_Translation::t("VGA Normal"); break;
153: case 3: $data = Horde_Image_Translation::t("VGA Fine"); break;
154: case 4: $data = Horde_Image_Translation::t("SXGA Basic"); break;
155: case 5: $data = Horde_Image_Translation::t("SXGA Normal"); break;
156: case 6: $data = Horde_Image_Translation::t("SXGA Fine"); break;
157: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
158: }
159: break;
160:
161: case '0004':
162:
163: switch ($data) {
164: case 1: $data = Horde_Image_Translation::t("Color"); break;
165: case 2: $data = Horde_Image_Translation::t("Monochrome"); break;
166: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
167: }
168: break;
169:
170: case '0005':
171:
172: switch ($data) {
173: case 0: $data = Horde_Image_Translation::t("Normal"); break;
174: case 1: $data = Horde_Image_Translation::t("Bright+"); break;
175: case 2: $data = Horde_Image_Translation::t("Bright-"); break;
176: case 3: $data = Horde_Image_Translation::t("Contrast+"); break;
177: case 4: $data = Horde_Image_Translation::t("Contrast-"); break;
178: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
179: }
180: break;
181:
182: case '0006':
183:
184: switch ($data) {
185: case 0: $data = 'ISO-80'; break;
186: case 2: $data = 'ISO-160'; break;
187: case 4: $data = 'ISO-320'; break;
188: case 5: $data = 'ISO-100'; break;
189: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
190: }
191: break;
192:
193: case '0007':
194:
195: switch ($data) {
196: case 0: $data = Horde_Image_Translation::t("Auto"); break;
197: case 1: $data = Horde_Image_Translation::t("Preset"); break;
198: case 2: $data = Horde_Image_Translation::t("Daylight"); break;
199: case 3: $data = Horde_Image_Translation::t("Incandescense"); break;
200: case 4: $data = Horde_Image_Translation::t("Flourescence"); break;
201: case 5: $data = Horde_Image_Translation::t("Cloudy"); break;
202: case 6: $data = Horde_Image_Translation::t("SpeedLight"); break;
203: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
204: }
205: break;
206:
207: case '000b':
208:
209: switch ($data) {
210: case 0: $data = Horde_Image_Translation::t("None"); break;
211: case 1: $data = Horde_Image_Translation::t("Fisheye"); break;
212: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
213: }
214: break;
215: }
216:
217: case 'UNDEFINED':
218: if ($model != 1) {
219: break;
220: }
221:
222: switch ($tag) {
223: case '0001':
224: $data = $data/100;
225: break;
226: case '0088':
227:
228: $temp = Horde_Image_Translation::t("Center");
229: $data = bin2hex($data);
230: $data = str_replace('01', 'Top', $data);
231: $data = str_replace('02', 'Bottom', $data);
232: $data = str_replace('03', 'Left', $data);
233: $data = str_replace('04', 'Right', $data);
234: $data = str_replace('00', '', $data);
235: if (!strlen($data)) {
236: $data = $temp;
237: }
238: break;
239: }
240: break;
241:
242: default:
243: $data = bin2hex($data);
244: if ($intel) {
245: $data = Horde_Image_Exif::intel2Moto($data);
246: }
247: if ($model != 1) {
248: break;
249: }
250:
251: switch ($tag) {
252: case '0083':
253:
254: $data = hexdec(substr($data, 0, 2));
255: switch ($data) {
256: case 0: $data = Horde_Image_Translation::t("AF non D"); break;
257: case 1: $data = Horde_Image_Translation::t("Manual"); break;
258: case 2: $data = 'AF-D or AF-S'; break;
259: case 6: $data = 'AF-D G'; break;
260: case 10: $data = 'AF-D VR'; break;
261: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
262: }
263: break;
264:
265: case '0087':
266:
267: $data = hexdec(substr($data,0,2));
268: switch ($data) {
269: case 0: $data = Horde_Image_Translation::t("Did Not Fire"); break;
270: case 4: $data = Horde_Image_Translation::t("Unknown"); break;
271: case 7: $data = Horde_Image_Translation::t("External"); break;
272: case 9: $data = Horde_Image_Translation::t("On Camera"); break;
273: default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
274: }
275: break;
276: }
277:
278: break;
279: }
280:
281: return $data;
282: }
283:
284: 285: 286: 287: 288: 289:
290: public function parse($block, &$result)
291: {
292: $intel = $result['Endien'] == 'Intel';
293: $model = $result['IFD0']['Model'];
294:
295:
296: if ($model == "E700\0" ||
297: $model == "E800\0" ||
298: $model == "E900\0" ||
299: $model == "E900S\0" ||
300: $model == "E910\0" ||
301: $model == "E950\0") {
302:
303: $place = 8;
304: $model = 0;
305:
306:
307: $num = bin2hex(substr($block, $place, 2));
308: $place += 2;
309: if ($intel) {
310: $num = Horde_Image_Exif::intel2Moto($num);
311: }
312: $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
313:
314:
315: for ($i = 0; $i < hexdec($num); $i++) {
316:
317: $tag = bin2hex(substr($block, $place, 2));
318: $place += 2;
319: if ($intel) {
320: $tag = Horde_Image_Exif::intel2Moto($tag);
321: }
322: $tag_name = $this->_lookupTag($tag, $model);
323:
324:
325: $type = bin2hex(substr($block, $place, 2));
326: $place += 2;
327: if ($intel) {
328: $type = Horde_Image_Exif::intel2Moto($type);
329: }
330: $this->_lookupType($type, $size);
331:
332:
333: $count = bin2hex(substr($block, $place, 4));
334: $place += 4;
335: if ($intel) {
336: $count = Horde_Image_Exif::intel2Moto($count);
337: }
338: $bytesofdata = $size * hexdec($count);
339:
340:
341: $value = substr($block, $place, 4);
342: $place += 4;
343:
344:
345:
346: if ($tag == '0002') {
347: $offset = hexdec($value) - 140;
348: }
349: if ($bytesofdata <= 4) {
350: $data = $value;
351: } else {
352: $value = bin2hex($value);
353: if ($intel) {
354: $value = Horde_Image_Exif::intel2Moto($value);
355: }
356: $data = substr($block, hexdec($value) - $offset, $bytesofdata * 2);
357: }
358: $formated_data = $this->_formatData($type, $tag, $intel, $model, $data);
359: $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
360: }
361: } else {
362:
363: $place = 0;
364: $model = 1;
365:
366: $nikon = substr($block, $place, 8);
367: $place += 8;
368: $endien = substr($block, $place, 4);
369: $place += 4;
370:
371:
372: $tag = bin2hex(substr($block, $place, 2));
373: $place += 2;
374:
375:
376:
377: $offset = bin2hex(substr($block, $place, 4));
378: $place += 4;
379: if ($intel) {
380: $offset = Horde_Image_Exif::intel2Moto($offset);
381: }
382: if (hexdec($offset) > 8) {
383: $place += $offset - 8;
384: }
385:
386:
387: $num = bin2hex(substr($block, $place, 2));
388: $place += 2;
389: if ($intel) {
390: $num = Horde_Image_Exif::intel2Moto($num);
391: }
392:
393:
394: for ($i = 0; $i < hexdec($num); $i++) {
395:
396: $tag = bin2hex(substr($block, $place, 2));
397: $place += 2;
398: if ($intel) {
399: $tag = Horde_Image_Exif::intel2Moto($tag);
400: }
401: $tag_name = $this->_lookupTag($tag, $model);
402:
403:
404: $type = bin2hex(substr($block, $place, 2));
405: $place += 2;
406: if ($intel) {
407: $type = Horde_Image_Exif::intel2Moto($type);
408: }
409: $this->_lookupType($type, $size);
410:
411:
412: $count = bin2hex(substr($block, $place, 4));
413: $place += 4;
414: if ($intel) {
415: $count = Horde_Image_Exif::intel2Moto($count);
416: }
417: $bytesofdata = $size * hexdec($count);
418:
419:
420: $value = substr($block, $place, 4);
421: $place += 4;
422:
423: if ($bytesofdata <= 4) {
424: $data = $value;
425: } else {
426: $value = bin2hex($value);
427: if ($intel) {
428: $value = Horde_Image_Exif::intel2Moto($value);
429: }
430: $data = substr($block, hexdec($value) + hexdec($offset) + 2, $bytesofdata);
431: }
432: $formated_data = $this->_formatData($type, $tag, $intel, $model, $data);
433: $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
434: }
435: }
436: }
437: }