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_Panasonic extends Horde_Image_Exif_Parser_Base
30: {
31: 32: 33:
34: protected function _lookupTag($tag)
35: {
36: switch ($tag) {
37: case '0001': $tag = 'Quality'; break;
38: case '0002': $tag = 'FirmwareVersion'; break;
39: case '0003': $tag = 'WhiteBalance'; break;
40: case '0007': $tag = 'FocusMode'; break;
41: case '000f': $tag = 'AFMode'; break;
42: case '001a': $tag = 'ImageStabilizer'; break;
43: case '001c': $tag = 'MacroMode'; break;
44: case '001f': $tag = 'ShootingMode'; break;
45: case '0020': $tag = 'Audio'; break;
46: case '0021': $tag = 'DataDump'; break;
47: case '0023': $tag = 'WhiteBalanceBias'; break;
48: case '0024': $tag = 'FlashBias'; break;
49: case '0025': $tag = 'SerialNumber'; break;
50: case '0028': $tag = 'ColourEffect'; break;
51: case '002a': $tag = 'BurstMode'; break;
52: case '002b': $tag = 'SequenceNumber'; break;
53: case '002c': $tag = 'Contrast'; break;
54: case '002d': $tag = 'NoiseReduction'; break;
55: case '002e': $tag = 'SelfTimer'; break;
56: case '0030': $tag = 'Rotation'; break;
57: case '0032': $tag = 'ColorMode'; break;
58: case '0036': $tag = 'TravelDay'; break;
59: default: $tag = 'unknown:' . $tag; break;
60: }
61:
62: return $tag;
63: }
64:
65: 66: 67:
68: protected function _formatData($type, $tag, $intel, $data)
69: {
70: switch ($type) {
71: case 'UBYTE':
72: case 'SBYTE':
73: $data = bin2hex($data);
74: if ($intel) {
75: $data = Horde_Image_Exif::intel2Moto($data);
76: }
77: $data = hexdec($data);
78: if ($tag == '000f') {
79:
80: switch ($data) {
81: case 256:
82: $data = Horde_Image_Translation::t("9-area-focusing");
83: break;
84: case 16:
85: $data = Horde_Image_Translation::t("1-area-focusing");
86: break;
87: case 4096:
88: $data = Horde_Image_Translation::t("3-area-focusing (High speed)");
89: break;
90: case 4112:
91: $data = Horde_Image_Translation::t("1-area-focusing (High speed)");
92: break;
93: case 16:
94: $data = Horde_Image_Translation::t("1-area-focusing");
95: break;
96: case 1:
97: $data = Horde_Image_Translation::t("Spot-focusing");
98: break;
99: default:
100: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
101: break;
102: }
103: }
104: break;
105:
106: case 'URATIONAL':
107: case 'SRATIONAL':
108: $data = bin2hex($data);
109: if ($intel) {
110: $data = Horde_Image_Exif::intel2Moto($data);
111: }
112: $top = hexdec(substr($data, 8, 8));
113: $bottom = hexdec(substr($data, 0, 8));
114: if ($bottom != 0) {
115: $data = $top / $bottom;
116: } elseif ($top == 0) {
117: $data = 0;
118: } else {
119: $data = $top . '/' . $bottom;
120: }
121: break;
122:
123: case 'USHORT':
124: case 'SSHORT':
125: case 'ULONG':
126: case 'SLONG':
127: case 'FLOAT':
128: case 'DOUBLE':
129: $data = bin2hex($data);
130: if ($intel) {
131: $data = Horde_Image_Exif::intel2Moto($data);
132: }
133:
134: $data = hexdec($data);
135: switch ($tag) {
136: case '0001':
137:
138: switch ($data) {
139: case 2:
140: $data = Horde_Image_Translation::t("High");
141: break;
142: case 3:
143: $data = Horde_Image_Translation::t("Standard");
144: break;
145: case 6:
146: $data = Horde_Image_Translation::t("Very High");
147: break;
148: case 7:
149: $data = Horde_Image_Translation::t("RAW");
150: break;
151: default:
152: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
153: break;
154: }
155: break;
156:
157: case '0003':
158:
159: switch ($data) {
160: case 1:
161: $data = Horde_Image_Translation::t("Auto");
162: break;
163: case 2:
164: $data = Horde_Image_Translation::t("Daylight");
165: break;
166: case 3:
167: $data = Horde_Image_Translation::t("Cloudy");
168: break;
169: case 4:
170: $data = Horde_Image_Translation::t("Halogen");
171: break;
172: case 5:
173: $data = Horde_Image_Translation::t("Manual");
174: break;
175: case 8:
176: $data = Horde_Image_Translation::t("Flash");
177: break;
178: case 10:
179: $data = Horde_Image_Translation::t("Black and White");
180: break;
181: case 11:
182: $data = Horde_Image_Translation::t("Manual");
183: break;
184: default:
185: $data = sprintf(Horde_Image_Translation::t("Unknown(%s)"), $data);
186: break;
187: }
188: break;
189:
190: case '0007':
191:
192: switch ($data) {
193: case 1:
194: $data = Horde_Image_Translation::t("Auto");
195: break;
196: case 2:
197: $data = Horde_Image_Translation::t("Manual");
198: break;
199: case 4:
200: $data = Horde_Image_Translation::t("Auto, Focus button");
201: break;
202: case 5:
203: $data = Horde_Image_Translation::t("Auto, Continuous");
204: break;
205: default:
206: $data = sprintf(Horde_Image_Translation::t("Unknown(%s)"), $data);
207: break;
208: }
209: break;
210:
211: case '001a':
212:
213: switch ($data) {
214: case 2:
215: $data = Horde_Image_Translation::t("Mode 1");
216: break;
217: case 3:
218: $data = Horde_Image_Translation::t("Off");
219: break;
220: case 4:
221: $data = Horde_Image_Translation::t("Mode 2");
222: break;
223: default:
224: $data = sprintf(Horde_Image_Translation::t("Unknown(%s)"), $data);
225: break;
226: }
227: break;
228:
229: case '001c':
230:
231: switch ($data) {
232: case 1:
233: $data = Horde_Image_Translation::t("On");
234: break;
235: case 2:
236: $data = Horde_Image_Translation::t("Off");
237: break;
238: default:
239: $data = sprintf(Horde_Image_Translation::t("Unknown(%s)"), $data);
240: break;
241: }
242: break;
243:
244: case '001f':
245:
246: switch ($data) {
247: case 1:
248: $data = Horde_Image_Translation::t("Normal");
249: break;
250: case 2:
251: $data = Horde_Image_Translation::t("Portrait");
252: break;
253: case 3:
254: $data = Horde_Image_Translation::t("Scenery");
255: break;
256: case 4:
257: $data = Horde_Image_Translation::t("Sports");
258: break;
259: case 5:
260: $data = Horde_Image_Translation::t("Night Portrait");
261: break;
262: case 6:
263: $data = Horde_Image_Translation::t("Program");
264: break;
265: case 7:
266: $data = Horde_Image_Translation::t("Aperture Priority");
267: break;
268: case 8:
269: $data = Horde_Image_Translation::t("Shutter Priority");
270: break;
271: case 9:
272: $data = Horde_Image_Translation::t("Macro");
273: break;
274: case 11:
275: $data = Horde_Image_Translation::t("Manual");
276: break;
277: case 13:
278: $data = Horde_Image_Translation::t("Panning");
279: break;
280: case 14:
281: $data = Horde_Image_Translation::t("Simple");
282: break;
283: case 18:
284: $data = Horde_Image_Translation::t("Fireworks");
285: break;
286: case 19:
287: $data = Horde_Image_Translation::t("Party");
288: break;
289: case 20:
290: $data = Horde_Image_Translation::t("Snow");
291: break;
292: case 21:
293: $data = Horde_Image_Translation::t("Night Scenery");
294: break;
295: case 22:
296: $data = Horde_Image_Translation::t("Food");
297: break;
298: case 23:
299: $data = Horde_Image_Translation::t("Baby");
300: break;
301: case 27:
302: $data = Horde_Image_Translation::t("High Sensitivity");
303: break;
304: case 29:
305: $data = Horde_Image_Translation::t("Underwater");
306: break;
307: case 33:
308: $data = Horde_Image_Translation::t("Pet");
309: break;
310: default:
311: $data = sprintf(Horde_Image_Translation::t("Unknown(%s)"), $data);
312: break;
313: }
314: break;
315:
316: case '0020':
317:
318: switch ($data) {
319: case 1:
320: $data = Horde_Image_Translation::t("Yes");
321: break;
322: case 2:
323: $data = Horde_Image_Translation::t("No");
324: break;
325: default:
326: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
327: break;
328: }
329: break;
330:
331: case '0023':
332:
333: $data = $data . ' EV';
334: break;
335:
336: case '0024':
337:
338: $data = $data;
339: break;
340:
341: case '0028':
342:
343: switch ($data) {
344: case 1:
345: $data = Horde_Image_Translation::t("Off");
346: break;
347: case 2:
348: $data = Horde_Image_Translation::t("Warm");
349: break;
350: case 3:
351: $data = Horde_Image_Translation::t("Cool");
352: break;
353: case 4:
354: $data = Horde_Image_Translation::t("Black and White");
355: break;
356: case 5:
357: $data = Horde_Image_Translation::t("Sepia");
358: break;
359: default:
360: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
361: break;
362: }
363: break;
364:
365: case '002a':
366:
367: switch ($data) {
368: case 0:
369: $data = Horde_Image_Translation::t("Off");
370: break;
371: case 1:
372: $data = Horde_Image_Translation::t("Low/High Quality");
373: break;
374: case 2:
375: $data = Horde_Image_Translation::t("Infinite");
376: break;
377: default:
378: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
379: break;
380: }
381: break;
382:
383: case '002c':
384:
385: switch ($data) {
386: case 0:
387: $data = Horde_Image_Translation::t("Standard");
388: break;
389: case 1:
390: $data = Horde_Image_Translation::t("Low");
391: break;
392: case 2:
393: $data = Horde_Image_Translation::t("High");
394: break;
395: default:
396: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
397: break;
398: }
399: break;
400:
401: case '002d':
402:
403: switch ($data) {
404: case 0:
405: $data = Horde_Image_Translation::t("Standard");
406: break;
407: case 1:
408: $data = Horde_Image_Translation::t("Low");
409: break;
410: case 2:
411: $data = Horde_Image_Translation::t("High");
412: break;
413: default:
414: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
415: break;
416: }
417: break;
418:
419: case '002e':
420:
421: switch ($data) {
422: case 1:
423: $data = Horde_Image_Translation::t("Off");
424: break;
425: case 2:
426: $data = Horde_Image_Translation::t("10s");
427: break;
428: case 3:
429: $data = Horde_Image_Translation::t("2s");
430: break;
431: default:
432: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
433: break;
434: }
435: break;
436:
437: case '0030':
438:
439: switch ($data) {
440: case 1:
441: $data = Horde_Image_Translation::t("Horizontal (normal)");
442: break;
443: case 6:
444: $data = Horde_Image_Translation::t("Rotate 90 CW");
445: break;
446: case 8:
447: $data = Horde_Image_Translation::t("Rotate 270 CW");
448: break;
449: default:
450: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
451: break;
452: }
453: break;
454:
455: case '0032':
456:
457: switch ($data) {
458: case 0:
459: $data = Horde_Image_Translation::t("Normal");
460: break;
461: case 1:
462: $data = Horde_Image_Translation::t("Natural");
463: break;
464: default:
465: $data = sprintf(Horde_Image_Translation::t("Unknown (%s)"), $data);
466: break;
467: }
468: break;
469:
470: case '0036':
471:
472: $data = $data;
473: break;
474: }
475: break;
476:
477: case 'UNDEFINED':
478: break;
479:
480: default:
481: $data = bin2hex($data);
482: if ($intel) {
483: $data = Horde_Image_Exif::intel2Moto($data);
484: }
485: break;
486: }
487:
488: return $data;
489: }
490:
491: 492: 493:
494: public function parse($block, &$result)
495: {
496: $intel = true;
497: $model = $result['IFD0']['Model'];
498:
499: $place = 8;
500: $offset = 8;
501:
502: $num = bin2hex(substr($block, $place, 4));
503: $place += 4;
504:
505: if ($intel) {
506: $num = Horde_Image_Exif::intel2Moto($num);
507: }
508: $result['SubIFD']['MakerNote']['Offset'] = hexdec($num);
509:
510:
511: $num = bin2hex(substr($block, $place, 2));
512: $place += 2;
513:
514: if ($intel) {
515: $num = Horde_Image_Exif::intel2Moto($num);
516: }
517: $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
518:
519:
520: for ($i = 0; $i < hexdec($num); $i++) {
521:
522: $tag = bin2hex(substr($block, $place, 2));
523: $place += 2;
524: if ($intel) {
525: $tag = Horde_Image_Exif::intel2Moto($tag);
526: }
527: $tag_name = $this->_lookupTag($tag);
528:
529:
530: $type = bin2hex(substr($block, $place, 2));
531: $place += 2;
532: if ($intel) {
533: $type = Horde_Image_Exif::intel2Moto($type);
534: }
535: $this->_lookupType($type, $size);
536:
537:
538: $count = bin2hex(substr($block, $place, 4));
539: $place += 4;
540: if ($intel) {
541: $count = Horde_Image_Exif::intel2Moto($count);
542: }
543: $bytesofdata = $size * hexdec($count);
544:
545:
546: $value = substr($block, $place, 4);
547: $place += 4;
548:
549: if ($bytesofdata <= 4) {
550: $data = $value;
551: } else {
552: $value = bin2hex($value);
553: if ($intel) {
554: $value = Horde_Image_Exif::intel2Moto($value);
555: }
556: $data = substr($block, hexdec($value) - $offset, $bytesofdata * 2);
557: }
558: $formated_data = $this->_formatData($type, $tag, $intel, $data);
559: $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
560: }
561: }
562: }