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_Olympus extends Horde_Image_Exif_Parser_Base
 30: {
 31:     /**
 32:      *
 33:      * @param $tag
 34:      * @return unknown_type
 35:      */
 36:     protected function _lookupTag($tag)
 37:     {
 38:         switch($tag) {
 39:         case '0200': $tag = 'SpecialMode'; break;
 40:         case '0201': $tag = 'JpegQual'; break;
 41:         case '0202': $tag = 'Macro'; break;
 42:         case '0203': $tag = 'Unknown1'; break;
 43:         case '0204': $tag = 'DigiZoom'; break;
 44:         case '0205': $tag = 'Unknown2'; break;
 45:         case '0206': $tag = 'Unknown3'; break;
 46:         case '0207': $tag = 'SoftwareRelease'; break;
 47:         case '0208': $tag = 'PictInfo'; break;
 48:         case '0209': $tag = 'CameraID'; break;
 49:         case '0f00': $tag = 'DataDump'; break;
 50:         default:     $tag = 'unknown: ' . $tag; break;
 51:         }
 52: 
 53:         return $tag;
 54:     }
 55: 
 56:     /**
 57:      *
 58:      * @param $type
 59:      * @param $tag
 60:      * @param $intel
 61:      * @param $data
 62:      * @return unknown_type
 63:      */
 64:     protected function _formatData($type, $tag, $intel, $data)
 65:     {
 66:         switch ($type) {
 67:         case 'ASCII':
 68:         case 'UNDEFINED':
 69:             break;
 70: 
 71:         case 'URATIONAL':
 72:         case 'SRATIONAL':
 73:             $data = bin2hex($data);
 74:             if ($intel) {
 75:                 $data = Horde_Image_Exif::intel2Moto($data);
 76:             }
 77:             $top = hexdec(substr($data, 8, 8));
 78:             $bottom = hexdec(substr($data, 0, 8));
 79:             if ($bottom) {
 80:                 $data = $top / $bottom;
 81:             } elseif (!$top) {
 82:                 $data = 0;
 83:             } else {
 84:                 $data = $top . '/' . $bottom;
 85:             }
 86: 
 87:             switch ($tag) {
 88:             case '0204':
 89:                 //DigitalZoom
 90:                 $data .= 'x';
 91:                 break;
 92:             case '0205':
 93:                 //Unknown2
 94:                 $data = $top . '/' . $bottom;
 95:                 break;
 96:             }
 97:             break;
 98: 
 99:         case 'USHORT':
100:         case 'SSHORT':
101:         case 'ULONG':
102:         case 'SLONG':
103:         case 'FLOAT':
104:         case 'DOUBLE':
105:             $data = bin2hex($data);
106:             if ($intel) {
107:                 $data = Horde_Image_Exif::intel2Moto($data);
108:             }
109:             $data = hexdec($data);
110: 
111:             switch ($tag) {
112:             case '0201':
113:                 //JPEGQuality
114:                 switch ($data) {
115:                 case 1:  $data = 'SQ'; break;
116:                 case 2:  $data = 'HQ'; break;
117:                 case 3:  $data = 'SHQ'; break;
118:                 default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
119:                 }
120:                 break;
121:             case '0202':
122:                 //Macro
123:                 switch ($data) {
124:                 case 0:  $data = 'Normal'; break;
125:                 case 1:  $data = 'Macro'; break;
126:                 default: $data = Horde_Image_Translation::t("Unknown") . ': ' . $data; break;
127:                 }
128:                 break;
129:             }
130:             break;
131: 
132:         default:
133:             $data = bin2hex($data);
134:             if ($intel) {
135:                 $data = Horde_Image_Exif::intel2Moto($data);
136:             }
137:             break;
138:         }
139: 
140:         return $data;
141:     }
142: 
143:     /**
144:      *
145:      * @param $block
146:      * @param $result
147:      * @param $seek
148:      * @param $globalOffset
149:      * @return unknown_type
150:      */
151:     public function parse($block, &$result, $seek, $globalOffset)
152:     {
153:         $intel = $result['Endien']=='Intel';
154:         $model = $result['IFD0']['Model'];
155: 
156:         // New header for new DSLRs - Check for it because the number of bytes
157:         // that count the IFD fields differ in each case.  Fixed by Zenphoto
158:         // 2/24/08
159:         $new = false;
160:         if (substr($block, 0, 8) == "OLYMPUS\x00") {
161:             $new = true;
162:         } elseif (substr($block, 0, 7) == "OLYMP\x00\x01" ||
163:                   substr($block, 0, 7) == "OLYMP\x00\x02") {
164:             $new = false;
165:         } else {
166:             // Header does not match known Olympus headers.
167:             // This is not a valid OLYMPUS Makernote.
168:             return false;
169:         }
170: 
171:         // Offset of IFD entry after Olympus header.
172:         $place = 8;
173:         $offset = 8;
174: 
175:         // Get number of tags (1 or 2 bytes, depending on New or Old makernote)
176:         $countfieldbits = $new ? 1 : 2;
177:         // New makernote repeats 1-byte value twice, so increment $place by 2
178:         // in either case.
179:         $num = bin2hex(substr($block, $place, $countfieldbits));
180:         $place += 2;
181:         if ($intel) {
182:             $num = Horde_Image_Exif::intel2Moto($num);
183:         }
184:         $ntags = hexdec($num);
185:         $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = $ntags;
186: 
187:         //loop thru all tags  Each field is 12 bytes
188:         for ($i = 0; $i < $ntags; $i++) {
189:             //2 byte tag
190:             $tag = bin2hex(substr($block, $place, 2));
191:             $place += 2;
192:             if ($intel) {
193:                 $tag = Horde_Image_Exif::intel2Moto($tag);
194:             }
195:             $tag_name = $this->_lookupTag($tag);
196: 
197:             //2 byte type
198:             $type = bin2hex(substr($block, $place, 2));
199:             $place += 2;
200:             if ($intel) {
201:                 $type = Horde_Image_Exif::intel2Moto($type);
202:             }
203:             $this->_lookupType($type, $size);
204: 
205:             //4 byte count of number of data units
206:             $count = bin2hex(substr($block, $place, 4));
207:             $place += 4;
208:             if ($intel) {
209:                 $count = Horde_Image_Exif::intel2Moto($count);
210:             }
211:             $bytesofdata = $size * hexdec($count);
212: 
213:             //4 byte value of data or pointer to data
214:             $value = substr($block, $place, 4);
215:             $place += 4;
216: 
217:             if ($bytesofdata <= 4) {
218:                 $data = $value;
219:             } else {
220:                 $value = bin2hex($value);
221:                 if ($intel) {
222:                     $value = Horde_Image_Exif::intel2Moto($value);
223:                 }
224:                 //offsets are from TIFF header which is 12 bytes from the start
225:                 //of the file
226:                 $v = fseek($seek, $globalOffset + hexdec($value));
227:                 $result['Errors'] = $result['Errors']++;
228:                 $data = '';
229:             }
230:             $formated_data = $this->_formatData($type, $tag, $intel, $data);
231:             $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
232:         }
233:     }
234: }
API documentation generated by ApiGen