Overview

Packages

  • Image
  • None

Classes

  • Horde_Image_Exif_Parser_Canon
  • Horde_Image_Exif_Parser_Fujifilm
  • Horde_Image_Exif_Parser_Gps
  • Horde_Image_Exif_Parser_Nikon
  • Horde_Image_Exif_Parser_Olympus
  • Horde_Image_Exif_Parser_Panasonic
  • Horde_Image_Exif_Parser_Sanyo
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * @author   Michael J. Rubinsky <mrubinsk@horde.org>
  4:  * @author   Jan Schneider <jan@horde.org>
  5:  * @category Horde
  6:  * @package  Image
  7:  */
  8: 
  9: /**
 10:  * Exifer
 11:  * Extracts EXIF information from digital photos.
 12:  *
 13:  * Copyright © 2003 Jake Olefsky
 14:  * http://www.offsky.com/software/exif/index.php
 15:  * jake@olefsky.com
 16:  *
 17:  * ------------
 18:  *
 19:  * This program is free software; you can redistribute it and/or modify it
 20:  * under the terms of the GNU General Public License as published by the Free
 21:  * Software Foundation; either version 2 of the License, or (at your option)
 22:  * any later version.
 23:  *
 24:  * This program is distributed in the hope that it will be useful, but WITHOUT
 25:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 26:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 27:  * more details. http://www.horde.org/licenses/gpl
 28:  */
 29: class Horde_Image_Exif_Parser_Panasonic extends Horde_Image_Exif_Parser_Base
 30: {
 31:     /**
 32:      * Looks up the name of the tag for the MakerNote (Depends on Manufacturer)
 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:      * Formats Data for the data type
 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:                 //AFMode
 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:                 //Image Quality
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:                 //White Balance
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:                 //Focus Mode
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:                 //Image Stabilizer
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:                 //Macro mode
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:                 //Shooting Mode
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:                 //Audio
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:                 //White Balance Bias
333:                 $data = $data . ' EV';
334:                 break;
335: 
336:             case '0024':
337:                 //Flash Bias
338:                 $data = $data;
339:                 break;
340: 
341:             case '0028':
342:                 //Colour Effect
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:                 //Burst Mode
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:                 //Contrast
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:                 //Noise Reduction
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:                 //Self Timer
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:                 //Rotation
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:                 //Color Mode
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:                 //Travel Day
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:      * Panasonic Special data section
493:      */
494:      public function parse($block, &$result)
495:      {
496:         $intel = true;
497:         $model = $result['IFD0']['Model'];
498:         //current place
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:         //Get number of tags (2 bytes)
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:         //loop thru all tags  Each field is 12 bytes
520:         for ($i = 0; $i < hexdec($num); $i++) {
521:             //2 byte tag
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:             //2 byte type
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:             //4 byte count of number of data units
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:             //4 byte value of data or pointer to data
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: }
API documentation generated by ApiGen