source: extensions/AMetaData/JpegMetaData/Readers/PentaxReader.class.php

Last change on this file was 6729, checked in by grum, 14 years ago

feature:1777

  • Weight of the metadata database can becomes very heavy
  • Property svn:executable set to *
File size: 13.5 KB
Line 
1<?php
2/*
3 * --:: JPEG MetaDatas ::-------------------------------------------------------
4 *
5 *  Author    : Grum
6 *   email    : grum at piwigo.org
7 *   website  : http://photos.grum.fr
8 *
9 *   << May the Little SpaceFrog be with you ! >>
10 *
11 *
12 * +-----------------------------------------------------------------------+
13 * | JpegMetaData - a PHP based Jpeg Metadata manager                      |
14 * +-----------------------------------------------------------------------+
15 * | Copyright(C) 2010  Grum - http://www.grum.fr                          |
16 * +-----------------------------------------------------------------------+
17 * | This program is free software; you can redistribute it and/or modify  |
18 * | it under the terms of the GNU General Public License as published by  |
19 * | the Free Software Foundation                                          |
20 * |                                                                       |
21 * | This program is distributed in the hope that it will be useful, but   |
22 * | WITHOUT ANY WARRANTY; without even the implied warranty of            |
23 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
24 * | General Public License for more details.                              |
25 * |                                                                       |
26 * | You should have received a copy of the GNU General Public License     |
27 * | along with this program; if not, write to the Free Software           |
28 * | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
29 * | USA.                                                                  |
30 * +-----------------------------------------------------------------------+
31 *
32 *
33 * -----------------------------------------------------------------------------
34 *
35 * The PentaxReader class is the dedicated to read the specific Pentax tags
36 *
37 * ====> See MakerNotesReader.class.php to know more about the structure <======
38 *
39 * -----------------------------------------------------------------------------
40 *
41 * .. Notes ..
42 *
43 *
44 * ****             All known tags are not implemented !!                   ****
45 *
46 *
47 * The PentaxReader class is derived from the MakerNotesReader class.
48 *
49 * ======> See MakerNotesReader.class.php to know more about common methods <======
50 *
51 * -----------------------------------------------------------------------------
52 */
53
54
55
56  require_once(JPEG_METADATA_DIR."Common/GlobalTags.class.php");
57  require_once(JPEG_METADATA_DIR."TagDefinitions/PentaxTags.class.php");
58  require_once(JPEG_METADATA_DIR."Readers/MakerNotesReader.class.php");
59
60  class PentaxReader extends MakerNotesReader
61  {
62    protected $schema = Schemas::EXIF;
63
64    /**
65     * The constructor needs, like the ancestor, the datas to be parsed
66     *
67     * Some datas are offset on extra data, and this offset can be (some time)
68     * absolute inside the IFD, or relative. So, the offset of the IFD structure
69     * is needed
70     *
71     * The byte order can be different from the TIFF byte order !
72     *
73     * The constructor need the maker signature (see the MakerNotesSignatures
74     * class for a list of known signatures)
75     *
76     * @param String $data
77     * @param ULong $offset : offset of IFD block in the jpeg file
78     * @param String $byteOrder
79     * @param String $makerSignature :
80     */
81    function __construct($data, $offset, $byteOrder, $makerSignature)
82    {
83      $this->maker = MAKER_PENTAX;
84      switch($makerSignature)
85      {
86        case MakerNotesSignatures::PentaxHeader:
87          $this->header = MakerNotesSignatures::PentaxHeader;
88          $this->headerSize = MakerNotesSignatures::PentaxHeaderSize;
89          break;
90        case MakerNotesSignatures::Pentax2Header:
91          $this->header = MakerNotesSignatures::Pentax2Header;
92          $this->headerSize = MakerNotesSignatures::Pentax2HeaderSize;
93          break;
94      }
95
96      parent::__construct($data, $offset, $byteOrder);
97    }
98
99    function __destruct()
100    {
101      parent::__destruct();
102    }
103
104    /**
105     * initialize the definition for Pentax exif tags
106     */
107    protected function initializeTagDef()
108    {
109      $this->tagDef = new PentaxTags();
110    }
111
112    /**
113     * skip the IFD header
114     */
115    protected function skipHeader($headerSize=0)
116    {
117      parent::skipHeader($this->headerSize);
118    }
119
120    /**
121     * this function do the interpretation of specials tags
122     *
123     * the function return the interpreted value for the tag
124     *
125     * @param $tagId             : the id of the tag
126     * @param $values            : 'raw' value to be interpreted
127     * @param UByte $type        : if needed (for IFD structure) the type of data
128     * @param ULong $valueOffset : if needed, the offset of data in the jpeg file
129     * @return String or Array or DateTime or Integer or Float...
130     */
131    protected function processSpecialTag($tagId, $values, $type, $valuesOffset=0)
132    {
133      switch($tagId)
134      {
135        case 0x0000: // "Version"
136          $returned=sprintf("%d.%d.%d.%d", $values[0], $values[1], $values[2], $values[3]);
137          break;
138        case 0x0002: // "PreviewResolution"
139          $returned=sprintf("%dx%d", $values[0], $values[1]);
140          break;
141        case 0x0003: // "PreviewLength",
142        case 0x0004: // "PreviewOffset",
143          $returned=$values;
144          break;
145        case 0x0006: // "Date",
146          $returned=sprintf("%04d/%02d/%02d", ConvertData::toUShort($values, BYTE_ORDER_BIG_ENDIAN), ConvertData::toUByte($values{2}), ConvertData::toUByte($values{3}));
147          break;
148        case 0x0007: // "Time",
149          $returned=sprintf("%02d:%02d:%02d", ConvertData::toUByte($values{0}), ConvertData::toUByte($values{1}), ConvertData::toUByte($values{2}));
150          break;
151        case 0x000c: // "Flash",
152          $tag=$this->tagDef->getTagById(0x000c);
153          $returned=Array();
154          if(array_key_exists($values[0], $tag['tagValues.special'][0]))
155            $returned[]=$tag['tagValues.special'][0][$values[0]];
156          if(array_key_exists($values[1], $tag['tagValues.special'][1]))
157            $returned[]=$tag['tagValues.special'][1][$values[1]];
158          unset($tag);
159          break;
160        case 0x0012: // "ExposureTime", from exiftool
161           $returned=ConvertData::toExposureTime($values/100000);
162          break;
163        case 0x0013: // "FNumber",
164          $returned=ConvertData::toFNumber($values/10);
165          break;
166        case 0x0016: // "ExposureCompensation",
167          $returned=sprintf("%.1f EV", ($values-50)/10);
168          break;
169        case 0x0018: // "AutoBracketing",
170          /*
171           * $values if an array
172           *  [0] : exposure compensation
173           *  [1] : bracketing mode
174           */
175          if($values[0]<10)
176            $returned=Array(($values[0]/3)." EV");
177          else
178            $returned=Array(($values[0]-9.5)." EV");
179
180          if($values[1]==0)
181            $returned[]="No extended bracketing";
182          else
183          {
184            $type = $values[1] >> 8;
185            $range = $values[1] & 0xff;
186            switch ($type)
187            {
188              case 1:
189                $returned[]="WB-BA";
190                break;
191              case 2:
192                $returned[]="WB-GM";
193                break;
194              case 3:
195                $returned[]="Saturation";
196                break;
197              case 4:
198                $returned[]="Sharpness";
199                break;
200              case 5:
201                $returned[]="Contrast";
202                break;
203              default:
204                $returned[]="Unknown;".ConvertData::toHexDump($type, ByteType::USHORT);
205                break;
206            }
207            $returned[]=$range;
208          }
209          break;
210        case 0x001b: // "BlueBalance",
211        case 0x001c: // "RedBalance", from exiftool
212          $returned=sprintf("%d", $values/256+0.5);
213          break;
214        case 0x001d: // "FocalLength",
215          /* note : in exiftool, the formula change with the camera model... ? */
216          $returned=($values/100)." mm";
217          break;
218        case 0x001e: // "DigitalZoom", from exiftool
219          $returned=($values/100);
220          break;
221        case 0x0025: // "HometownDST",
222        case 0x0026: // "DestinationDST",
223          $returned=($values==1)?"Yes":"No";
224          break;
225        case 0x0027: // "DSPFirmwareVersion",
226        case 0x0028: // "CPUFirmwareVersion",
227          $returned=sprintf("%d.%d.%d.%d", 0xff-ConvertData::toUByte($values{0}), 0xff-ConvertData::toUByte($values{1}), 0xff-ConvertData::toUByte($values{2}), 0xff-ConvertData::toUByte($values{3}));
228          break;
229        case 0x002d: // "EffectiveLV",
230          $returned=sprintf("%.1f", $values/1024);
231          break;
232        case 0x0039: // "RawImageSize",
233          $returned=sprintf("%dx%d", $values[0], $values[1]);
234          break;
235        case 0x003e: // "PreviewImageBorders",
236          $returned=ConvertData::toHexDump($values, ByteType::UBYTE);
237          break;
238        case 0x003f: // "LensType",
239          $tag=$this->tagDef->getTagById(0x003f);
240          $id=$values[1]+($values[0]<<8);
241          if(!array_key_exists($id, $tag['tagValues.special'])) $id=0xffff;
242
243          $returned="";
244
245          $lensesList=$tag['tagValues.special'][$id];
246          if(is_array($lensesList))
247          {
248            foreach($lensesList as $lens)
249            {
250              /*
251               * If there is more than one lens associated with a lens id
252               *
253               * 1/ try to found the min/max focals of the lens
254               * 2/ try to found the min/max aperture of the lens
255               * 3/ if focal is fixed, make min = max
256               * 4/ if aperture is constant, make min)max
257               * 5/ look if : min focal <= photo focal <= max focal  and
258               *              photo aperture >= min aperture
259               *            if yes, the lens is returned, otherwise test next
260               *            lens
261               */
262              preg_match("/.*\s(?:([0-9]+){1}(?:-([0-9]+))?)mm.*/i", $lens, $focals);
263              preg_match("/.*\sF(?:([0-9\.]+){1}(?:-([0-9\.]+))?).*/i", $lens, $apertures);
264
265              if(count($focals)==2)
266              {
267                //focal is not a zoom, min = max
268                $focals[]=$focal[1];
269              }
270              elseif(count($focals)==0)
271              {
272                $focal=Array(0,0,0);
273              }
274
275
276              if(count($apertures)==2)
277              {
278                //aperture is constant, min = max
279                $apertures[]=$apertures[1];
280              }
281              elseif(count($apertures)==0)
282              {
283                $apertures=Array(0,0,0);
284              }
285
286              $focal=GlobalTags::getExifFocal();
287              if($focal=="") $focal=-1;
288
289              $aperture=GlobalTags::getExifAperture();
290              if($aperture=="") $aperture=-1;
291
292              if($focals[1]<=$focal && $focal<=$focals[2] && $aperture>=$apertures[1] && $returned=="")
293              {
294                $returned=$lens;
295              }
296
297              unset($lens);
298              unset($focals);
299              unset($apertures);
300            }
301            if($returned=="")
302            {
303              // no lens seems to be valid, returns the lens list
304              $returned=$lensesList;
305            }
306          }
307          else
308          {
309            // not a list, just a single lens
310            $returned=$lensesList;
311          }
312
313          unset($tag);
314          unset($id);
315          break;
316        case 0x0040: // "SensitivityAdjust", from exiftool
317          /* is the conversion perl => php is good !? */
318          $returned=sprintf("%.1f", ($values-50)/10+50);
319          break;
320        case 0x0047: // "Temperature",
321          $returned=(($values>127)?256-$values:$values)."°C";
322          break;
323        case 0x0048: // "AELock",
324        case 0x0049: // "NoiseReduction",
325          $returned=($values==1)?"On":"Off";
326          break;
327        case 0x004d: // "FlashExposureCompensation",
328          $returned=ConvertData::toEV($values/256);
329          break;
330        case 0x0050: // "ColorTemperature", from exiftool
331          $returned=53190 -$values;
332          break;
333
334        /* theses tags decoding is not yet implemented
335         * have to take a look on the algorithm in exiftool (it seems to work
336         * but I don't understand everything...)
337         */
338
339        case 0x0205: // "ShotInfo",
340        case 0x0206: // "AEInfo",
341        case 0x0207: // "LensInfo",
342        case 0x0208: // "FlashInfo",
343        case 0x0209: // "AEMeteringSegments",
344        case 0x020a: // "FlashADump",
345        case 0x020b: // "FlashBDump",
346        case 0x020d: // "WB_RGGBLevelsDaylight",
347        case 0x020e: // "WB_RGGBLevelsShade",
348        case 0x020f: // "WB_RGGBLevelsCloudy",
349        case 0x0210: // "WB_RGGBLevelsTungsten",
350        case 0x0211: // "WB_RGGBLevelsFluorescentD",
351        case 0x0212: // "WB_RGGBLevelsFluorescentN",
352        case 0x0213: // "WB_RGGBLevelsFluorescentW",
353        case 0x0214: // "WB_RGGBLevelsFlash",
354        case 0x0215: // "CameraInfo",
355        case 0x0216: // "BatteryInfo",
356        case 0x021f: // "AFInfo",
357        case 0x0222: // "ColorInfo",
358
359        case 0x0029: // "FrameNumber",
360        case 0x0041: // "DigitalFilter",
361        case 0x005c: // "ShakeReduction",
362        case 0x005d: // "ShutterCount",
363        case 0x0200: // "BlackPoint",
364        case 0x0201: // "WhitePoint",
365        case 0x0203: // "ColorMatrixA",
366        case 0x0204: // "ColorMatrixB",
367        default:
368          $returned="Not yet implemented;".ConvertData::toHexDump($tagId, ByteType::USHORT)." => ".ConvertData::toHexDump($values, $type);
369          break;
370      }
371      return($returned);
372    }
373  }
374
375?>
Note: See TracBrowser for help on using the repository browser.