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