source: extensions/AMetaData/JpegMetaData/Common/Data.class.php @ 4705

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

Change Locale class by L10n class ; add Readers for Nikon and Canon cameras ; some bug corrected

  • Property svn:executable set to *
File size: 12.7 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 Data class is used to read Strings content like files
36 *
37 * The class manages automaticaly the offset allowing to read sequentially the
38 * datas
39 *  - Opening a new String reset the offset to zero.
40 *  - Reading data moves the offset to the next byte
41 *
42 *
43 * -----------------------------------------------------------------------------
44 *
45 * This class provides theses public functions :
46 *  - getLength
47 *  - getByteOrder
48 *  - setByteOrder
49 *  - clear
50 *  - setData
51 *  - seek
52 *  - eod
53 *  - bod
54 *  - offset
55 *  - seekPush
56 *  - seekPop
57 *  - readUByte
58 *  - readSByte
59 *  - readUShort
60 *  - readSShort
61 *  - readULong
62 *  - readSLong
63 *  - readURational
64 *  - readSRational
65 *  - readASCII
66 *
67 * -----------------------------------------------------------------------------
68 */
69
70  require_once(JPEG_METADATA_DIR."Common/Const.class.php");
71  require_once(JPEG_METADATA_DIR."Common/ConvertData.class.php");
72
73  class Data
74  {
75    private $data = "";
76    private $byteOrder;
77    private $offset=0;
78    private $length;
79    private $startOffset = 0;
80    private $currentPos = Array();
81
82    /**
83     * The constructor needs datas, and optionaly the byteOrder (by default,
84     * assuming the byte order is little endian)
85     *
86     * offset is set to zero when the object is instancied
87     *
88     * @param String $data                 : datas
89     * @param String $byteOrder (optional) : a valid byte order value (uses the
90     *                                       BYTE_ORDER const)
91     *
92     */
93    function __construct($data, $byteOrder = BYTE_ORDER_LITTLE_ENDIAN)
94    {
95      $this->setData($data);
96      $this->byteOrder = $byteOrder;
97    }
98
99    function __destruct()
100    {
101      unset($this->byteOrder);
102      unset($this->offset);
103      unset($this->length);
104      unset($this->startOffset);
105      unset($this->data);
106      unset($this->currentPos);
107    }
108
109    /**
110     * returns the datas length
111     *
112     * @return ULong
113     */
114    public function getLength()
115    {
116      return($this->length);
117    }
118
119    /**
120     * returns the byte order
121     *
122     * @return String
123     */
124    public function getByteOrder()
125    {
126      return($this->byteOrder);
127    }
128
129
130    /**
131     * set the byte order
132     *
133     * @param String $value : a valid byte order value
134     * @return String
135     */
136    public function setByteOrder($value)
137    {
138      if($value==BYTE_ORDER_BIG_ENDIAN or
139         $value==BYTE_ORDER_LITTLE_ENDIAN) $this->byteOrder=$value;
140      return($this->byteOrder);
141    }
142
143    /**
144     * clear the datas
145     */
146    public function clear()
147    {
148      $this->setData("");
149    }
150
151    /**
152     * set the datas and reset the offset to zero
153     *
154     * @param String $data : the datas
155     */
156    public function setData($data)
157    {
158      $this->data = $data;
159      $this->length=strlen($data);
160      $this->seek();
161      unset($this->currentPos);
162      $this->currentPos=Array();
163    }
164
165
166    /**
167     * seek the given offset
168     *
169     * if offset is not specified, or offset is less than zero, assuming to seek
170     * on the offset zero
171     *
172     * if offset is greater than the data length, assuming to seek on the last
173     * byte
174     *
175     *
176     * @param ULong $offset : offset to seek on
177     */
178    public function seek($offset=0)
179    {
180      if($offset<0)
181      {
182        $this->offset=0;
183      }
184      elseif($offset>$this->length)
185      {
186        $this->offset=$this->length;
187      }
188      else
189      {
190        $this->offset=$offset;
191      }
192    }
193
194    /**
195     * returns true if the offset is on the last data byte
196     *
197     * @return Boolean
198     */
199    public function eod()
200    {
201      return($this->offset>=$this->length);
202    }
203
204    /**
205     * returns true if the offset is on the first data byte (zero)
206     *
207     * @return Boolean
208     */
209    public function bod()
210    {
211      return($this->offset==0);
212    }
213
214    /**
215     * returns the current offset
216     *
217     * @return ULong
218     */
219    public function offset()
220    {
221      return($this->offset);
222    }
223
224    /**
225     * Memorize the current offset by pushing it in a stack
226     */
227    public function seekPush()
228    {
229      $this->currentPos[]=$this->offset;
230    }
231
232    /**
233     * Restore the last pushed offset on the stack
234     * If there is nothing in the stack, returns -1
235     *
236     * @return ULong
237     */
238    public function seekPop()
239    {
240      if(count($this->currentPos)>0)
241        $this->seek(array_pop($this->currentPos));
242      else return(-1);
243    }
244
245    /**
246     * Read an unsigned byte from the data
247     *
248     * If offset is given, reading data from the given offset
249     * If offset is not given, reading data from the current offset, and
250     * increment it (+1)
251     *
252     * @param ULong $offset (optional) : optional offset
253     * @return UByte
254     */
255    public function readUByte($offset=null)
256    {
257      if(is_null($offset))
258      {
259        $offset=$this->offset;
260        $this->offset+=ByteType::$typeSizes[ByteType::UBYTE];
261      }
262
263      if($offset+ByteType::$typeSizes[ByteType::UBYTE]>$this->length) return(0);
264
265      return(ConvertData::toUbyte(substr($this->data,$offset,ByteType::$typeSizes[ByteType::UBYTE])));
266    }
267
268    /**
269     * Read a signed byte from the data
270     *
271     * If offset is given, reading data from the given offset
272     * If offset is not given, reading data from the current offset, and
273     * increment it (+1)
274     *
275     * @param ULong $offset (optional) : optional offset
276     * @return SByte
277     */
278    public function readSByte($offset=null)
279    {
280      if(is_null($offset))
281      {
282        $offset=$this->offset;
283        $this->offset+=ByteType::$typeSizes[ByteType::SBYTE];
284      }
285
286      if($offset+ByteType::$typeSizes[ByteType::SBYTE]>$this->length) return(0);
287
288      return(ConvertData::toSbyte(substr($this->data,$offset,ByteType::$typeSizes[ByteType::SBYTE])));
289    }
290
291    /**
292     * Read an unsigned Short from the data
293     *
294     * If offset is given, reading data from the given offset
295     * If offset is not given, reading data from the current offset, and
296     * increment it (+2)
297     *
298     * @param ULong $offset (optional) : optional offset
299     * @return UShort
300     */
301    public function readUShort($offset=null)
302    {
303      if(is_null($offset))
304      {
305        $offset=$this->offset;
306        $this->offset+=ByteType::$typeSizes[ByteType::USHORT];
307      }
308
309      if($offset+ByteType::$typeSizes[ByteType::USHORT]>$this->length) return(0);
310
311      return(ConvertData::toUShort(substr($this->data, $offset,ByteType::$typeSizes[ByteType::USHORT]), $this->byteOrder));
312    }
313
314    /**
315     * Read a signed Short from the data
316     *
317     * If offset is given, reading data from the given offset
318     * If offset is not given, reading data from the current offset, and
319     * increment it (+2)
320     *
321     * @param ULong $offset (optional) : optional offset
322     * @return SShort
323     */
324    public function readSShort($offset=null)
325    {
326      if(is_null($offset))
327      {
328        $offset=$this->offset;
329        $this->offset+=ByteType::$typeSizes[ByteType::SSHORT];
330      }
331
332      if($offset+ByteType::$typeSizes[ByteType::SSHORT]>$this->length) return(0);
333
334      return(ConvertData::toSShort(substr($this->data, $offset,ByteType::$typeSizes[ByteType::SSHORT]), $this->byteOrder));
335    }
336
337    /**
338     * Read an unsigned Long from the data
339     *
340     * If offset is given, reading data from the given offset
341     * If offset is not given, reading data from the current offset, and
342     * increment it (+4)
343     *
344     * @param ULong $offset (optional) : optional offset
345     * @return ULong
346     */
347    public function readULong($offset=null)
348    {
349      if(is_null($offset))
350      {
351        $offset=$this->offset;
352        $this->offset+=ByteType::$typeSizes[ByteType::ULONG];
353      }
354
355      if($offset+ByteType::$typeSizes[ByteType::ULONG]>$this->length) return(0);
356
357      return(ConvertData::toULong(substr($this->data, $offset,ByteType::$typeSizes[ByteType::ULONG]), $this->byteOrder));
358    }
359
360    /**
361     * Read a signed Long from the data
362     *
363     * If offset is given, reading data from the given offset
364     * If offset is not given, reading data from the current offset, and
365     * increment it (+4)
366     *
367     * @param ULong $offset (optional) : optional offset
368     * @return SLong
369     */
370    public function readSLong($offset=null)
371    {
372      if(is_null($offset))
373      {
374        $offset=$this->offset;
375        $this->offset+=ByteType::$typeSizes[ByteType::SLONG];
376      }
377
378      if($offset+ByteType::$typeSizes[ByteType::SLONG]>$this->length) return(0);
379
380      return(ConvertData::toSLong(substr($this->data, $offset,ByteType::$typeSizes[ByteType::SLONG]), $this->byteOrder));
381    }
382
383    /**
384     * Read an unsigned Rational from the data
385     *
386     * If offset is given, reading data from the given offset
387     * If offset is not given, reading data from the current offset, and
388     * increment it (+8)
389     *
390     * @param ULong $offset (optional) : optional offset
391     * @return URational
392     */
393    public function readURational($offset=null)
394    {
395      if(is_null($offset))
396      {
397        $offset=$this->offset;
398        $this->offset+=ByteType::$typeSizes[ByteType::URATIONAL];
399      }
400      if($offset+ByteType::$typeSizes[ByteType::URATIONAL]>$this->length) return(0);
401
402      return(ConvertData::toURational(substr($this->data, $offset,ByteType::$typeSizes[ByteType::URATIONAL]), $this->byteOrder));
403    }
404
405    /**
406     * Read a signed Rational from the data
407     *
408     * If offset is given, reading data from the given offset
409     * If offset is not given, reading data from the current offset, and
410     * increment it (+8)
411     *
412     * @param ULong $offset (optional) : optional offset
413     * @return SRational
414     */
415    public function readSRational($offset=null)
416    {
417      if(is_null($offset))
418      {
419        $offset=$this->offset;
420        $this->offset+=ByteType::$typeSizes[ByteType::SRATIONAL];
421      }
422
423      if($offset+ByteType::$typeSizes[ByteType::SRATIONAL]>$this->length) return(0);
424
425      return(ConvertData::toSRational(substr($this->data, $offset,ByteType::$typeSizes[ByteType::SRATIONAL]), $this->byteOrder));
426    }
427
428    /**
429     * Read a string from the data
430     *
431     * If length is given, read a number of char equals to the length
432     * If length is not given, or length is negative, read all char from the
433     * offset to the data length
434     *
435     * If offset is given, reading data from the given offset
436     * If offset is not given, reading data from the current offset, and
437     * increment it by the number of char readed
438     *
439     * @param ULong $length (optional) : optional length
440     * @param ULong $offset (optional) : optional offset
441     * @return String
442     */
443
444    public function readASCII($length=-1, $offset=null)
445    {
446      if($length<=0) $length=$this->length;
447
448      if(is_null($offset))
449      {
450        $offset=$this->offset;
451        $this->seek($this->offset+$length);
452      }
453
454      //if($offset+$length>$this->length) return("");
455
456      return(substr($this->data, $offset,$length));
457    }
458
459    public function readFloat($offset=null)
460    {
461    }
462
463    public function readDouble($offset=null)
464    {
465    }
466
467  }
468
469
470?>
Note: See TracBrowser for help on using the repository browser.