source: extensions/AMetaData/JpegMetaData/Common/ConvertData.class.php @ 4686

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

[Plugin:AMetaData] prepare the directory for a future plugin

  • Property svn:executable set to *
File size: 13.1 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 * | JpegMetaData - a PHP based Jpeg Metadata manager                      |
13 * +-----------------------------------------------------------------------+
14 * | Copyright(C) 2010  Grum - http://www.grum.fr                          |
15 * +-----------------------------------------------------------------------+
16 * | This program is free software; you can redistribute it and/or modify  |
17 * | it under the terms of the GNU General Public License as published by  |
18 * | the Free Software Foundation                                          |
19 * |                                                                       |
20 * | This program is distributed in the hope that it will be useful, but   |
21 * | WITHOUT ANY WARRANTY; without even the implied warranty of            |
22 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
23 * | General Public License for more details.                              |
24 * |                                                                       |
25 * | You should have received a copy of the GNU General Public License     |
26 * | along with this program; if not, write to the Free Software           |
27 * | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
28 * | USA.                                                                  |
29 * +-----------------------------------------------------------------------+
30 *
31 *
32 * -----------------------------------------------------------------------------
33 *
34 * ConvertData class is used to convert data from a type into another type
35 *
36 * This class provides theses public functions :
37 *  - (static) toUByte
38 *  - (static) toSByte
39 *  - (static) toUShort
40 *  - (static) toSShort
41 *  - (static) toULong
42 *  - (static) toSLong
43 *  - (static) toURational
44 *  - (static) toSRational
45 *  - (static) toExposureTime
46 *  - (static) toFNumber
47 *  - (static) toDateTime
48 *  - (static) toFocalLength
49 *  - (static) toEV
50 *  - (static) toDistance
51 *  - (static) toStrings
52 *  - (static) toDMS
53 *  - (static) toHexDump
54 *
55 * -----------------------------------------------------------------------------
56 */
57
58  require_once(JPEG_METADATA_DIR."Common/Const.class.php");
59
60  class ConvertData
61  {
62    /**
63     * Convert the given data into a single unsigned Byte (8bit)
64     *
65     * @param String $data : representing the unsigned Byte
66     * @return UByte
67     */
68    static public function toUByte($data)
69    {
70      if(strlen($data)>=1)
71        return(ord($data{0}));
72      else
73        return(0);
74    }
75
76    /**
77     * Convert the given data into a single signed Byte (8bit)
78     *
79     * @param String $data : representing the signed Byte
80     * @return SByte
81     */
82    static public function toSByte($data)
83    {
84      $unsigned = self::toUByte($data);
85      if($unsigned>127)
86        return($unsigned-256);
87      else
88        return($unsigned);
89    }
90
91    /**
92     * Convert the given data into an unsigned Short integer (16bit)
93     *
94     * @param String $data       : representing the unsigned Short
95     * @param String $endianType : the byte order
96     * @return UShort
97     */
98    static public function toUShort($data, $endianType)
99    {
100      if(strlen($data)>=2)
101      {
102        if($endianType==BYTE_ORDER_LITTLE_ENDIAN)
103          return(ord($data{0}) +
104                 ord($data{1})*256);
105        else
106          return(ord($data{0})*256 +
107                 ord($data{1}));
108      }
109      else
110      {
111        return(0);
112      }
113    }
114
115    /**
116     * Convert the given data into a signed Short integer (16bit)
117     *
118     * @param String $data       : representing the signed Short
119     * @param String $endianType : the byte order
120     * @return SShort
121     */
122    static public function toSShort($data, $endianType)
123    {
124      $unsigned = self::toUShort($data, $endianType);
125      if($unsigned>32767)
126        return($unsigned-65536);
127      else
128        return($unsigned);
129    }
130
131    /**
132     * Convert the given data into an unsigned Long integer (32bit)
133     *
134     * @param String $data       : representing the unsigned Long
135     * @param String $endianType : the byte order
136     * @return ULong
137     */
138    static public function toULong($data, $endianType)
139    {
140      if(strlen($data)>=4)
141      {
142        if($endianType==BYTE_ORDER_LITTLE_ENDIAN)
143          return(ord($data{0}) +
144                 ord($data{1})*256 +
145                 ord($data{2})*65536 +
146                 ord($data{3})*16777216);
147        else
148          return(ord($data{0})*16777216 +
149                 ord($data{1})*65536 +
150                 ord($data{2})*256 +
151                 ord($data{3}));
152      }
153      else
154      {
155        return(0);
156      }
157    }
158
159    /**
160     * Convert the given data into a signed Long integer (32bit)
161     *
162     * @param String $data       : representing the signed Long
163     * @param String $endianType : the byte order
164     * @return SLong
165     */
166    static public function toSLong($data, $endianType)
167    {
168      $unsigned = self::toULong($data, $endianType);
169      if($unsigned>2147483647)
170        return($unsigned-4294967296);
171      else
172        return($unsigned);
173    }
174
175    /**
176     * Convert the given data into an array of unsigned Long (2x32bit)
177     *
178     * @param String $data       : representing the unsigned Rational
179     * @param String $endianType : the byte order
180     * @return URational
181     */
182    static public function toURational($data, $endianType)
183    {
184      if(strlen($data)>=8)
185      {
186        return(
187          Array(
188            self::toULong($data, $endianType),
189            self::toULong(substr($data, 4), $endianType)
190          )
191        );
192      }
193      else
194      {
195        return(Array(0,0));
196      }
197    }
198
199    /**
200     * Convert the given data into an array of signed Long (2x32bit)
201     *
202     * @param String $data       : representing the signed Rational
203     * @param String $endianType : the byte order
204     * @return SRational
205     */
206    static public function toSRational($data, $endianType)
207    {
208      if(strlen($data)>=8)
209      {
210        return(
211          Array(
212            self::toSLong($data, $endianType),
213            self::toSLong(substr($data, 4), $endianType)
214          )
215        );
216      }
217      else
218      {
219        return(Array(0,0));
220      }
221    }
222
223    /**
224     * Convert a floating value exprimed in seconds into a "photographic"
225     * value
226     *
227     * example :
228     *  1.5   => "1.5s"
229     *  0.004 => "1/250s"     *
230     *
231     * @param Float $time : time to convert
232     * @return String
233     */
234    static public function toExposureTime($time)
235    {
236      if($time>=1 or $time==0)
237      {
238        return($time."s");
239      }
240      else
241      {
242        return(sprintf("1/%ds", 1/$time));
243      }
244    }
245
246    /**
247     * Convert a floating value in a f/x.y string
248     *
249     * example :
250     *  1.8 => "f/1.8"
251     *  8   => "f/8.0"
252     *
253     * @param Float $fNumber : fnumber
254     * @return String
255     */
256    static public function toFNumber($fNumber)
257    {
258      return(sprintf("f/%.1f", $fNumber));
259    }
260
261    /**
262     * Convert a string Date/Time into a DateTime object
263     *
264     * Example of valid string :
265     *  "2009:12:24 19:54"
266     *  "2009:12:24 19:54\x00"
267     *  "2009:12:24 19:54:38"
268     *  "2009:12:24 19:54:38\x00"
269     *  "2009-12-24 19:54"
270     *  "2009-12-24T19:54"
271     *  "2009-12-24 19:54:38"
272     *  "2009-12-24T19:54:38"
273     *  "2009-12-24 19:54Z"
274     *  "2009-12-24T19:54Z"
275     *  "2009-12-24 19:54:38Z"
276     *  "2009-12-24T19:54:38Z"
277     *  "2009-12-24 19:54+02:00"
278     *  "2009-12-24T19:54+02:00"
279     *  "2009-12-24 19:54:38+02:00"
280     *  "2009-12-24T19:54:38+02:00"
281     *  "20091224"
282     *
283     * returns null if date is not a valid date
284     *
285     * @param String $dateTime : date time in a valid format
286     * @return String
287     */
288    static public function toDateTime($dateTime)
289    {
290      if(preg_match('/^(\d{4}:\d{2}:\d{2}\s\d{2}:\d{2}(:\d{2}){0,1}\x00{0,1}|\d{4}-\d{2}-\d{2}(T|\s)\d{2}:\d{2}(:\d{2}){0,1}(Z|[+|-]\d{2}:\d{2}){0,1}|\d{4}\d{2}\d{2})/', $dateTime))
291      {
292        $returned=new DateTime($dateTime, new DateTimeZone("UTC"));
293      }
294      else
295      {
296        $returned=null;
297      }
298      return($returned);
299    }
300
301    /**
302     * Convert a floating value in a focal length string
303     *
304     * Example:
305     *  250 => "250.0mm"
306     *
307     * @param Float $focalLength : focal length in millimeters
308     * @return String
309     */
310    static public function toFocalLength($focalLength)
311    {
312      return(sprintf("%.1f mm", $focalLength));
313    }
314
315    /**
316     * Convert a floating value in an EV
317     *
318     * Example:
319     *  0.7 => "0.7 EV"
320     *
321     * @param Float $ev : EV
322     * @return String
323     */
324    static public function toEV($ev)
325    {
326      return(sprintf("%.1f EV", $ev));
327    }
328
329    /**
330     * Convert a floating value associated with a unit
331     *
332     * Example :
333     *  3.4 + "m" => "3.40 m"
334     *
335     * @param Float $distance : distance
336     * @param String $unit    : unit
337     * @return String
338     */
339    static public function toDistance($distance, $unit)
340    {
341      return(sprintf("%.2f ", $distance)).$unit;
342    }
343
344    /**
345     * Convert a null terminated string into a string
346     * or
347     * Convert multiples null terminated string into an array of string
348     *
349     * Example:
350     *  "test" => "test"
351     *  "test\x00" => "test"
352     *  "test1\x00test2\x00" => Array("test1", "test2")
353     *
354     * @param String $strings
355     * @return String or String[]
356     */
357    static public function toStrings($strings)
358    {
359      if(strpos($strings, chr(0))===false)
360        return($strings);
361
362      $occurs=preg_match_all('/(.*)\x00/U',$strings,$result);
363      if($occurs==0)
364      {
365        return("");
366      }
367      elseif($occurs==1)
368      {
369        return($result[1][0]);
370      }
371      else
372      {
373        return($result[1]);
374      }
375    }
376
377    /**
378     * Convert 3 rationnals (EXIF GPS format) into a Degree, Minute, Second into
379     * a formatted string   dd° mm' ss.cs"
380     *
381     * Example:
382     *  48/1 + 1600/100 + 347/10 => "48° 16' 34.70""
383     *
384     * @param URational $degrees : degrees
385     * @param URational $minutes : minutes
386     * @param URational $seconds : seconds
387     * @return String
388     */
389    static public function toDMS($degrees, $minutes, $seconds)
390    {
391      if($degrees[1]==0) $degrees[1]=1;
392      if($minutes[1]==0) $minutes[1]=1;
393      if($seconds[1]==0) $seconds[1]=1;
394
395      $deg=$degrees[0]/$degrees[1];
396      $min=($minutes[0]/$minutes[1])-((int)$deg-$deg)*60;
397      $sec=($seconds[0]/$seconds[1])-((int)$min-$min)*60;
398
399      $returned=sprintf("%d° %d' %.2f\"", $deg, $min, $sec);
400
401      return($returned);
402    }
403
404
405    /**
406     * Dump the given data into an hex string
407     *
408     * @param $data            : data to be dumped (the dump is function of the
409     *                           data type)
410     * @param UByte $type      : the type of data (uses the ByteType values)
411     * @param UShort $maxItems : for arrays (or ASCII string), the number or
412     *                           items (chars) to dump
413     * @return String
414     */
415    static public function toHexDump($data, $type, $maxItems = 0)
416    {
417      $returned="";
418      if(is_array($data))
419      {
420        if($maxItems==0)
421        {
422          $maxItems=count($data);
423        }
424        elseif($maxItems>count($data))
425        {
426          $maxItems=count($data);
427        }
428        else
429        {
430          $returned.="[returns only the first $maxItems of ".count($data)." values] ";
431        }
432
433        $tmp=Array();
434        for($i=0;$i<$maxItems;$i++)
435        {
436          $tmp[]=self::toHexDump($data[$i], $type, $maxItems);
437        }
438        $returned.="[".implode(",", $tmp)."]";
439      }
440      else
441      {
442        switch($type)
443        {
444          case ByteType::UBYTE :
445          case ByteType::SBYTE :
446            $returned.=sprintf("0x%02x", $data);
447            break;
448          case ByteType::USHORT :
449          case ByteType::SSHORT :
450            $returned.=sprintf("0x%04x", $data);
451            break;
452          case ByteType::ULONG :
453          case ByteType::SLONG :
454            $returned.=sprintf("0x%08x", $data);
455            break;
456          case ByteType::URATIONAL :
457          case ByteType::SRATIONAL :
458            $returned.=sprintf("0x%08x", $data);
459            break;
460          case ByteType::FLOAT :
461          case ByteType::DOUBLE :
462          case ByteType::ASCII :
463          case ByteType::UNDEFINED :
464          default:
465            if($maxItems==0)
466            {
467              $maxItems=strlen($data);
468            }
469            elseif($maxItems>strlen($data))
470            {
471              $maxItems=strlen($data);
472            }
473            else
474            {
475              $returned.="[returns only the first $maxItems of ".strlen($data)." bytes] ";
476            }
477
478            $tmp=array();
479            for($i=0;$i<$maxItems;$i++)
480            {
481              $tmp[]=sprintf("%02x", ord($data{$i}));
482            }
483            $returned.=implode(" ", $tmp);
484            break;
485        }
486      }
487      return($returned);
488    }
489
490
491  }
492
493
494?>
Note: See TracBrowser for help on using the repository browser.