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
 25:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 26:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 27:  * for more details. http://www.horde.org/licenses/gpl
 28:  */
 29: class Horde_Image_Exif_Parser_Canon 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 = 'Settings 1'; break;
 38:         case '0004': $tag = 'Settings 4'; break;
 39:         case '0006': $tag = 'ImageType'; break;
 40:         case '0007': $tag = 'FirmwareVersion'; break;
 41:         case '0008': $tag = 'ImageNumber'; break;
 42:         case '0009': $tag = 'OwnerName'; break;
 43:         case '000c': $tag = 'CameraSerialNumber'; break;
 44:         case '000f': $tag = 'CustomFunctions'; break;
 45:         default:     $tag = sprintf(Horde_Image_Translation::t("Unknown: (%s)"), $tag); break;
 46:         }
 47: 
 48:         return $tag;
 49:     }
 50: 
 51:     /**
 52:      * Formats Data for the data type
 53:      */
 54:     protected function _formatData($type, $tag, $intel, $data, $exif, &$result)
 55:     {
 56:         $place = 0;
 57: 
 58:         switch ($type) {
 59:         case 'ASCII':
 60:             $result = $data = str_replace('\0', '', $data);
 61:             break;
 62: 
 63:         case 'URATIONAL':
 64:         case 'SRATIONAL':
 65:             $data = bin2hex($data);
 66:             if ($intel == 1) {
 67:                 $data = Horde_Image_Exif::intel2Moto($data);
 68:             }
 69:             $top = hexdec(substr($data, 8, 8));
 70:             $bottom = hexdec(substr($data, 0, 8));
 71:             if ($bottom != 0) {
 72:                 $data = $top / $bottom;
 73:             } elseif ($top == 0) {
 74:                 $data = 0;
 75:             } else {
 76:                 $data = $top . '/' . $bottom;
 77:             }
 78: 
 79:             if ($tag == '0204') {
 80:                 //DigitalZoom
 81:                 $data = $data . 'x';
 82:             }
 83:         case 'USHORT':
 84:         case 'SSHORT':
 85:         case 'ULONG':
 86:         case 'SLONG':
 87:         case 'FLOAT':
 88:         case 'DOUBLE':
 89:             $data = bin2hex($data);
 90:             $result['RAWDATA'] = $data;
 91: 
 92:             // TODO: split this code up
 93:             switch ($tag) {
 94:             case '0001':
 95:                 //first chunk
 96:                 $result['Bytes'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
 97:                 $place += 4;
 98:                 if ($result['Bytes'] != strlen($data) / 2) {
 99:                     //Bad chunk
100:                     return $result;
101:                 }
102:                 $result['Macro'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
103:                 $place += 4;//1
104:                 switch($result['Macro']) {
105:                 case 1: $result['Macro'] = Horde_Image_Translation::t("Macro"); break;
106:                 case 2: $result['Macro'] = Horde_Image_Translation::t("Normal"); break;
107:                 default: $result['Macro'] = Horde_Image_Translation::t("Unknown");
108:                 }
109:                 $result['SelfTimer'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
110:                 $place += 4;//2
111:                 switch($result['SelfTimer']) {
112:                 case 0: $result['SelfTimer'] = Horde_Image_Translation::t("Off"); break;
113:                 default: $result['SelfTimer'] .= Horde_Image_Translation::t("/10s");
114:                 }
115:                 $result['Quality'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
116:                 $place += 4;//3
117:                 switch($result['Quality']) {
118:                 case 2: $result['Quality'] = Horde_Image_Translation::t("Normal"); break;
119:                 case 3: $result['Quality'] = Horde_Image_Translation::t("Fine"); break;
120:                 case 5: $result['Quality'] = Horde_Image_Translation::t("Superfine"); break;
121:                 default: $result['Quality'] = Horde_Image_Translation::t("Unknown");
122:                 }
123:                 $result['Flash'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
124:                 $place += 4;//4
125:                 switch($result['Flash']) {
126:                 case 0: $result['Flash'] = Horde_Image_Translation::t("Off"); break;
127:                 case 1: $result['Flash'] = Horde_Image_Translation::t("Auto"); break;
128:                 case 2: $result['Flash'] = Horde_Image_Translation::t("On"); break;
129:                 case 3: $result['Flash'] = Horde_Image_Translation::t("Red Eye Reduction"); break;
130:                 case 4: $result['Flash'] = Horde_Image_Translation::t("Slow Synchro"); break;
131:                 case 5: $result['Flash'] = Horde_Image_Translation::t("Auto + Red Eye Reduction"); break;
132:                 case 6: $result['Flash'] = Horde_Image_Translation::t("On + Red Eye Reduction"); break;
133:                 case 16: $result['Flash'] = Horde_Image_Translation::t("External Flash"); break;
134:                 default: $result['Flash'] = Horde_Image_Translation::t("Unknown");
135:                 }
136:                 $result['DriveMode'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
137:                 $place += 4;//5
138:                 switch($result['DriveMode']) {
139:                 case 0: $result['DriveMode'] = Horde_Image_Translation::t("Single/Timer"); break;
140:                 case 1: $result['DriveMode'] = Horde_Image_Translation::t("Continuous"); break;
141:                 default: $result['DriveMode'] = Horde_Image_Translation::t("Unknown");
142:                 }
143:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
144:                 $place += 4;//6
145:                 $result['FocusMode'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
146:                 $place += 4;//7
147:                 switch($result['FocusMode']) {
148:                 case 0: $result['FocusMode'] = Horde_Image_Translation::t("One-Shot"); break;
149:                 case 1: $result['FocusMode'] = Horde_Image_Translation::t("AI Servo"); break;
150:                 case 2: $result['FocusMode'] = Horde_Image_Translation::t("AI Focus"); break;
151:                 case 3: $result['FocusMode'] = Horde_Image_Translation::t("Manual Focus"); break;
152:                 case 4: $result['FocusMode'] = Horde_Image_Translation::t("Single"); break;
153:                 case 5: $result['FocusMode'] = Horde_Image_Translation::t("Continuous"); break;
154:                 case 6: $result['FocusMode'] = Horde_Image_Translation::t("Manual Focus"); break;
155:                 default: $result['FocusMode'] = Horde_Image_Translation::t("Unknown");
156:                 }
157:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
158:                 $place += 4;//8
159:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place,4 )));
160:                 $place+=4;//9
161:                 $result['ImageSize'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
162:                 $place += 4;//10
163:                 switch($result['ImageSize']) {
164:                 case 0: $result['ImageSize'] = Horde_Image_Translation::t("Large"); break;
165:                 case 1: $result['ImageSize'] = Horde_Image_Translation::t("Medium"); break;
166:                 case 2: $result['ImageSize'] = Horde_Image_Translation::t("Small"); break;
167:                 default: $result['ImageSize'] = Horde_Image_Translation::t("Unknown");
168:                 }
169:                 $result['EasyShooting'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
170:                 $place += 4;//11
171:                 switch($result['EasyShooting']) {
172:                 case 0: $result['EasyShooting'] = Horde_Image_Translation::t("Full Auto"); break;
173:                 case 1: $result['EasyShooting'] = Horde_Image_Translation::t("Manual"); break;
174:                 case 2: $result['EasyShooting'] = Horde_Image_Translation::t("Landscape"); break;
175:                 case 3: $result['EasyShooting'] = Horde_Image_Translation::t("Fast Shutter"); break;
176:                 case 4: $result['EasyShooting'] = Horde_Image_Translation::t("Slow Shutter"); break;
177:                 case 5: $result['EasyShooting'] = Horde_Image_Translation::t("Night"); break;
178:                 case 6: $result['EasyShooting'] = Horde_Image_Translation::t("Black & White"); break;
179:                 case 7: $result['EasyShooting'] = Horde_Image_Translation::t("Sepia"); break;
180:                 case 8: $result['EasyShooting'] = Horde_Image_Translation::t("Portrait"); break;
181:                 case 9: $result['EasyShooting'] = Horde_Image_Translation::t("Sport"); break;
182:                 case 10: $result['EasyShooting'] = Horde_Image_Translation::t("Macro/Close-Up"); break;
183:                 case 11: $result['EasyShooting'] = Horde_Image_Translation::t("Pan Focus"); break;
184:                 default: $result['EasyShooting'] = Horde_Image_Translation::t("Unknown");
185:                 }
186:                 $result['DigitalZoom'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
187:                 $place += 4;//12
188:                 switch($result['DigitalZoom']) {
189:                 case 0:
190:                 case 65535: $result['DigitalZoom'] = Horde_Image_Translation::t("None"); break;
191:                 case 1: $result['DigitalZoom'] = Horde_Image_Translation::t("2x"); break;
192:                 case 2: $result['DigitalZoom'] = Horde_Image_Translation::t("4x"); break;
193:                 default: $result['DigitalZoom'] = Horde_Image_Translation::t("Unknown");
194:                 }
195:                 $result['Contrast'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
196:                 $place += 4;//13
197:                 switch($result['Contrast']) {
198:                 case 0: $result['Contrast'] = Horde_Image_Translation::t("Normal"); break;
199:                 case 1: $result['Contrast'] = Horde_Image_Translation::t("High"); break;
200:                 case 65535: $result['Contrast'] = Horde_Image_Translation::t("Low"); break;
201:                 default: $result['Contrast'] = Horde_Image_Translation::t("Unknown");
202:                 }
203:                 $result['Saturation'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
204:                 $place += 4;//14
205:                 switch($result['Saturation']) {
206:                    case 0: $result['Saturation'] = Horde_Image_Translation::t("Normal"); break;
207:                     case 1: $result['Saturation'] = Horde_Image_Translation::t("High"); break;
208:                     case 65535: $result['Saturation'] = Horde_Image_Translation::t("Low"); break;
209:                     default: $result['Saturation'] = Horde_Image_Translation::t("Unknown");
210:                 }
211:                 $result['Sharpness'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
212:                 $place += 4;//15
213:                 switch($result['Sharpness']) {
214:                 case 0: $result['Sharpness'] = Horde_Image_Translation::t("Normal"); break;
215:                 case 1: $result['Sharpness'] = Horde_Image_Translation::t("High"); break;
216:                 case 65535: $result['Sharpness'] = Horde_Image_Translation::t("Low"); break;
217:                 default: $result['Sharpness'] = Horde_Image_Translation::t("Unknown");
218:                 }
219:                 $result['ISO'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
220:                 $place += 4;//16
221:                 switch($result['ISO']) {
222:                 case 32767:
223:                 case 0:
224:                     $result['ISO'] = isset($exif['SubIFD']['ISOSpeedRatings']) ?
225:                         $exif['SubIFD']['ISOSpeedRatings'] :
226:                         'Unknown';
227:                      break;
228:                 case 15:
229:                     $result['ISO'] = Horde_Image_Translation::t("Auto");
230:                     break;
231:                 case 16:
232:                     $result['ISO'] = 50;
233:                      break;
234:                 case 17:
235:                     $result['ISO'] = 100;
236:                      break;
237:                 case 18:
238:                     $result['ISO'] = 200;
239:                      break;
240:                 case 19:
241:                     $result['ISO'] = 400;
242:                      break;
243:                 default:
244:                     $result['ISO'] = Horde_Image_Translation::t("Unknown");
245:                 }
246:                 $result['MeteringMode'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
247:                 $place += 4;//17
248:                 switch($result['MeteringMode']) {
249:                 case 3: $result['MeteringMode'] = Horde_Image_Translation::t("Evaluative"); break;
250:                 case 4: $result['MeteringMode'] = Horde_Image_Translation::t("Partial"); break;
251:                 case 5: $result['MeteringMode'] = Horde_Image_Translation::t("Center-weighted"); break;
252:                 default: $result['MeteringMode'] = Horde_Image_Translation::t("Unknown");
253:                 }
254:                 $result['FocusType'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
255:                 $place += 4;//18
256:                 switch($result['FocusType']) {
257:                 case 0: $result['FocusType'] = Horde_Image_Translation::t("Manual"); break;
258:                 case 1: $result['FocusType'] = Horde_Image_Translation::t("Auto"); break;
259:                 case 3: $result['FocusType'] = Horde_Image_Translation::t("Close-up (Macro)"); break;
260:                 case 8: $result['FocusType'] = Horde_Image_Translation::t("Locked (Pan Mode)"); break;
261:                 default: $result['FocusType'] = Horde_Image_Translation::t("Unknown");
262:                 }
263:                 $result['AFPointSelected'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
264:                 $place += 4;//19
265:                 switch($result['AFPointSelected']) {
266:                 case 12288: $result['AFPointSelected'] = Horde_Image_Translation::t("Manual Focus"); break;
267:                 case 12289: $result['AFPointSelected'] = Horde_Image_Translation::t("Auto Selected"); break;
268:                 case 12290: $result['AFPointSelected'] = Horde_Image_Translation::t("Right"); break;
269:                 case 12291: $result['AFPointSelected'] = Horde_Image_Translation::t("Center"); break;
270:                 case 12292: $result['AFPointSelected'] = Horde_Image_Translation::t("Left"); break;
271:                 default: $result['AFPointSelected'] = Horde_Image_Translation::t("Unknown");
272:                 }
273:                 $result['ExposureMode'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
274:                 $place += 4;//20
275:                 switch($result['ExposureMode']) {
276:                 case 0: $result['ExposureMode'] = Horde_Image_Translation::t("EasyShoot"); break;
277:                 case 1: $result['ExposureMode'] = Horde_Image_Translation::t("Program"); break;
278:                 case 2: $result['ExposureMode'] = Horde_Image_Translation::t("Tv"); break;
279:                 case 3: $result['ExposureMode'] = Horde_Image_Translation::t("Av"); break;
280:                 case 4: $result['ExposureMode'] = Horde_Image_Translation::t("Manual"); break;
281:                 case 5: $result['ExposureMode'] = Horde_Image_Translation::t("Auto-DEP"); break;
282:                 default: $result['ExposureMode'] = Horde_Image_Translation::t("Unknown");
283:                 }
284:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
285:                 $place += 4;//21
286:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
287:                 $place += 4;//22
288:                 $result['LongFocalLength'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
289:                 $place += 4;//23
290:                 $result['LongFocalLength'] .=  'focal units';
291:                 $result['ShortFocalLength'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
292:                 $place += 4;//24
293:                 $result['ShortFocalLength'] .= ' focal units';
294:                 $result['FocalUnits'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
295:                 $place += 4;//25
296:                  $result['FocalUnits'] .= ' per mm';
297:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
298:                 $place += 4;//26
299:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
300:                 $place += 4;//27
301:                 $result['FlashActivity'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
302:                 $place += 4;//28
303:                 switch($result['FlashActivity']) {
304:                 case 0: $result['FlashActivity'] = Horde_Image_Translation::t("Flash Did Not Fire"); break;
305:                 case 1: $result['FlashActivity'] = Horde_Image_Translation::t("Flash Fired"); break;
306:                 default: $result['FlashActivity'] = Horde_Image_Translation::t("Unknown");
307:                 }
308:                 $result['FlashDetails'] = str_pad(base_convert(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)), 16, 2), 16, '0', STR_PAD_LEFT);
309:                 $place += 4;//29
310:                 $flashDetails = array();
311:                 if (substr($result['FlashDetails'], 1, 1) == 1) {
312:                     $flashDetails[] = Horde_Image_Translation::t("External E-TTL");
313:                 }
314:                 if (substr($result['FlashDetails'], 2, 1) == 1) {
315:                     $flashDetails[] = Horde_Image_Translation::t("Internal Flash");
316:                 }
317:                 if (substr($result['FlashDetails'], 4, 1) == 1) {
318:                     $flashDetails[] = Horde_Image_Translation::t("FP sync used");
319:                 }
320:                 if (substr($result['FlashDetails'], 8, 1) == 1) {
321:                     $flashDetails[] = Horde_Image_Translation::t("2nd(rear)-curtain sync used");
322:                  }
323:                 if (substr($result['FlashDetails'], 12, 1) == 1) {
324:                     $flashDetails[] = Horde_Image_Translation::t("1st curtain sync");
325:                 }
326:                 $result['FlashDetails'] = implode(',', $flashDetails);
327:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
328:                 $place += 4;//30
329:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
330:                 $place += 4;//31
331:                 $anotherFocusMode = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
332:                 $place += 4;//32
333:                 if (strpos(strtoupper($exif['IFD0']['Model']), 'G1') !== false) {
334:                     switch($anotherFocusMode) {
335:                     case 0: $result['FocusMode'] = Horde_Image_Translation::t("Single"); break;
336:                     case 1: $result['FocusMode'] = Horde_Image_Translation::t("Continuous"); break;
337:                     default: $result['FocusMode'] = Horde_Image_Translation::t("Unknown");
338:                     }
339:                 }
340:                 break;
341: 
342:             case '0004':
343:                 //second chunk
344:                 $result['Bytes']=hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
345:                 $place += 4;//0
346:                 if ($result['Bytes'] != strlen($data) / 2) {
347:                     return $result; //Bad chunk
348:                 }
349:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
350:                 $place += 4;//1
351:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
352:                 $place += 4;//2
353:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
354:                 $place += 4;//3
355:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
356:                 $place += 4;//4
357:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
358:                 $place += 4;//5
359:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
360:                 $place += 4;//6
361:                 $result['WhiteBalance'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
362:                 $place += 4;//7
363:                 switch($result['WhiteBalance']) {
364:                 case 0: $result['WhiteBalance'] = Horde_Image_Translation::t("Auto"); break;
365:                 case 1: $result['WhiteBalance'] = Horde_Image_Translation::t("Sunny"); break;
366:                 case 2: $result['WhiteBalance'] = Horde_Image_Translation::t("Cloudy"); break;
367:                 case 3: $result['WhiteBalance'] = Horde_Image_Translation::t("Tungsten"); break;
368:                 case 4: $result['WhiteBalance'] = Horde_Image_Translation::t("Fluorescent"); break;
369:                 case 5: $result['WhiteBalance'] = Horde_Image_Translation::t("Flash"); break;
370:                 case 6: $result['WhiteBalance'] = Horde_Image_Translation::t("Custom"); break;
371:                 default: $result['WhiteBalance'] = Horde_Image_Translation::t("Unknown");
372:                 }
373:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
374:                 $place += 4;//8
375:                 $result['SequenceNumber'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
376:                 $place += 4;//9
377:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
378:                 $place += 4;//10
379:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
380:                 $place += 4;//11
381:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data ,$place, 4)));
382:                 $place += 4;//12
383:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
384:                 $place += 4;//13
385:                 $result['AFPointUsed']=hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
386:                 $place += 4;//14
387:                 $afPointUsed = array();
388:                 if ($result['AFPointUsed'] & 0x0001) {
389:                     $afPointUsed[] = Horde_Image_Translation::t("Right"); //bit 0
390:                 }
391:                 if ($result['AFPointUsed'] & 0x0002) {
392:                     $afPointUsed[] = Horde_Image_Translation::t("Center"); //bit 1
393:                 }
394:                 if ($result['AFPointUsed'] & 0x0004) {
395:                     $afPointUsed[] = Horde_Image_Translation::t("Left"); //bit 2
396:                 }
397:                 if ($result['AFPointUsed'] & 0x0800) {
398:                     $afPointUsed[] = 12; //bit 12
399:                 }
400:                 if ($result['AFPointUsed'] & 0x1000) {
401:                     $afPointUsed[] = 13; //bit 13
402:                 }
403:                 if ($result['AFPointUsed'] & 0x2000) {
404:                     $afPointUsed[] = 14; //bit 14
405:                 }
406:                 if ($result['AFPointUsed'] & 0x4000) {
407:                     $afPointUsed[] = 15; //bit 15
408:                 }
409:                 $result['AFPointUsed'] = implode(',', $afPointUsed);
410:                 $result['FlashBias'] = Horde_Image_Exif::intel2Moto(substr($data, $place, 4));
411:                 $place += 4;//15
412:                 switch($result['FlashBias']) {
413:                 case 'ffc0': $result['FlashBias'] = '-2 EV'; break;
414:                 case 'ffcc': $result['FlashBias'] = '-1.67 EV'; break;
415:                 case 'ffd0': $result['FlashBias'] = '-1.5 EV'; break;
416:                 case 'ffd4': $result['FlashBias'] = '-1.33 EV'; break;
417:                 case 'ffe0': $result['FlashBias'] = '-1 EV'; break;
418:                 case 'ffec': $result['FlashBias'] = '-0.67 EV'; break;
419:                 case 'fff0': $result['FlashBias'] = '-0.5 EV'; break;
420:                 case 'fff4': $result['FlashBias'] = '-0.33 EV'; break;
421:                 case '0000': $result['FlashBias'] = '0 EV'; break;
422:                 case '000c': $result['FlashBias'] = '0.33 EV'; break;
423:                 case '0010': $result['FlashBias'] = '0.5 EV'; break;
424:                 case '0014': $result['FlashBias'] = '0.67 EV'; break;
425:                 case '0020': $result['FlashBias'] = '1 EV'; break;
426:                 case '002c': $result['FlashBias'] = '1.33 EV'; break;
427:                 case '0030': $result['FlashBias'] = '1.5 EV'; break;
428:                 case '0034': $result['FlashBias'] = '1.67 EV'; break;
429:                 case '0040': $result['FlashBias'] = '2 EV'; break;
430:                 default: $result['FlashBias'] = Horde_Image_Translation::t("Unknown");
431:                 }
432:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
433:                 $place += 4;//16
434:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
435:                 $place += 4;//17
436:                 $result['Unknown'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
437:                 $place += 4;//18
438:                 $result['SubjectDistance'] = hexdec(Horde_Image_Exif::intel2Moto(substr($data, $place, 4)));
439:                 $place += 4;//19
440:                 $result['SubjectDistance'] .= '/100 m';
441:                 break;
442: 
443:             case '0008':
444:                 //image number
445:                 if ($intel == 1) {
446:                     $data = Horde_Image_Exif::intel2Moto($data);
447:                 }
448:                 $data = hexdec($data);
449:                 $result = round($data / 10000) . '-' . $data % 10000;
450:                 break;
451: 
452:             case '000c':
453:                 //camera serial number
454:                 if ($intel == 1) {
455:                     $data = Horde_Image_Exif::intel2Moto($data);
456:                 }
457:                 $data = hexdec($data);
458:                 $result = '#' . bin2hex(substr($data, 0, 16)) . substr($data, 16, 16);
459:                 break;
460:             }
461:             break;
462: 
463:         default:
464:             if ($type != 'UNDEFINED') {
465:                 $data = bin2hex($data);
466:                 if ($intel == 1) {
467:                     $data = Horde_Image_Exif::intel2Moto($data);
468:                 }
469:             }
470:             break;
471:         }
472: 
473:         return $data;
474:     }
475: 
476:     /**
477:      * Canon Special data section.
478:      *
479:      * @see http://www.burren.cx/david/canon.html
480:      * @see http://www.burren.cx/david/canon.html
481:      * @see http://www.ozhiker.com/electronics/pjmt/jpeg_info/canon_mn.html
482:      */
483:     public function parse($block, &$result, $seek, $globalOffset)
484:     {
485:         $place = 0; //current place
486:         if ($result['Endien'] == 'Intel') {
487:             $intel = 1;
488:         } else {
489:             $intel = 0;
490:         }
491: 
492:         $model = $result['IFD0']['Model'];
493: 
494:         //Get number of tags (2 bytes)
495:         $num = bin2hex(substr($block, $place, 2));
496:         $place += 2;
497:         if ($intel == 1) {
498:             $num = Horde_Image_Exif::intel2Moto($num);
499:         }
500:         $result['SubIFD']['MakerNote']['MakerNoteNumTags'] = hexdec($num);
501: 
502:         //loop thru all tags  Each field is 12 bytes
503:         for ($i = 0; $i < hexdec($num); $i++) {
504:             //2 byte tag
505:             $tag = bin2hex(substr($block, $place, 2));
506:             $place += 2;
507:             if ($intel == 1) {
508:                 $tag = Horde_Image_Exif::intel2Moto($tag);
509:             }
510:             $tag_name = $this->_lookupTag($tag);
511: 
512:             //2 byte type
513:             $type = bin2hex(substr($block, $place, 2));
514:             $place += 2;
515:             if ($intel == 1) {
516:                 $type = Horde_Image_Exif::intel2Moto($type);
517:             }
518:             $this->_lookupType($type, $size);
519: 
520:             //4 byte count of number of data units
521:             $count = bin2hex(substr($block, $place, 4));
522:             $place += 4;
523:             if ($intel == 1) {
524:                 $count = Horde_Image_Exif::intel2Moto($count);
525:             }
526:             $bytesofdata = $size * hexdec($count);
527: 
528:             if ($bytesofdata <= 0) {
529:                 return; //if this value is 0 or less then we have read all the tags we can
530:             }
531: 
532:             //4 byte value of data or pointer to data
533:             $value = substr($block, $place, 4);
534:             $place += 4;
535: 
536:             if ($bytesofdata <= 4) {
537:                 $data = $value;
538:             } else {
539:                 $value = bin2hex($value);
540:                 if ($intel == 1) {
541:                     $value = Horde_Image_Exif::intel2Moto($value);
542:                 }
543:                 //offsets are from TIFF header which is 12 bytes from the start
544:                 //of the file
545:                 $v = fseek($seek, $globalOffset + hexdec($value));
546:                 $exiferFileSize = 0;
547:                 if ($v == 0 && $bytesofdata < $exiferFileSize) {
548:                     $data = fread($seek, $bytesofdata);
549:                 } elseif ($v == -1) {
550:                     $result['Errors'] = $result['Errors']++;
551:                     $data = '';
552:                 } else {
553:                     $data = '';
554:                 }
555:             }
556:             // Ensure the index exists.
557:             $result['SubIFD']['MakerNote'][$tag_name] = '';
558:             $formated_data = $this->_formatData($type, $tag, $intel, $data, $result, $result['SubIFD']['MakerNote'][$tag_name]);
559:             $result['SubIFD']['MakerNote'][$tag_name] = $formated_data;
560:         }
561:     }
562: }
563: 
API documentation generated by ApiGen