summaryrefslogtreecommitdiff
path: root/modules/autorotate/lib/pel/PelEntryNumber.php
blob: 0e94992cd9161df2b82749644e097f3adf3641a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<?php

/**
 *  PEL: PHP Exif Library.  A library with support for reading and
 *  writing all Exif headers in JPEG and TIFF images using PHP.
 *
 *  Copyright (C) 2004, 2005, 2006  Martin Geisler.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program in the file COPYING; if not, write to the
 *  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

/* $Id$ */


/**
 * Abstract class for numbers.
 *
 * @author Martin Geisler <mgeisler@users.sourceforge.net>
 * @version $Revision$
 * @date $Date$
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public
 * License (GPL)
 * @package PEL
 */

/**#@+ Required class definitions. */
require_once('PelException.php');
require_once('PelEntry.php');
/**#@-*/


/**
 * Exception cast when numbers overflow.
 *
 * @author Martin Geisler <mgeisler@users.sourceforge.net>
 * @package PEL
 * @subpackage Exception
 */
class PelOverflowException extends PelException {

    /**
     * Construct a new overflow exception.
     *
     * @param int the value that is out of range.
     *
     * @param int the minimum allowed value.
     *
     * @param int the maximum allowed value.
     */
    function __construct($v, $min, $max) {
        parent::__construct('Value %.0f out of range [%.0f, %.0f]',
        $v, $min, $max);
    }
}


/**
 * Class for holding numbers.
 *
 * This class can hold numbers, with range checks.
 *
 * @author Martin Geisler <mgeisler@users.sourceforge.net>
 * @package PEL
 */
abstract class PelEntryNumber extends PelEntry {

    /**
     * The value held by this entry.
     *
     * @var array
     */
    protected $value = array();

    /**
     * The minimum allowed value.
     *
     * Any attempt to change the value below this variable will result
     * in a {@link PelOverflowException} being thrown.
     *
     * @var int
     */
    protected $min;

    /**
     * The maximum allowed value.
     *
     * Any attempt to change the value over this variable will result in
     * a {@link PelOverflowException} being thrown.
     *
     * @var int
     */
    protected $max;

    /**
     * The dimension of the number held.
     *
     * Normal numbers have a dimension of one, pairs have a dimension of
     * two, etc.
     *
     * @var int
     */
    protected $dimension = 1;


    /**
     * Change the value.
     *
     * This method can change both the number of components and the
     * value of the components.  Range checks will be made on the new
     * value, and a {@link PelOverflowException} will be thrown if the
     * value is found to be outside the legal range.
     *
     * The method accept several number arguments.  The {@link getValue}
     * method will always return an array except for when a single
     * number is given here.
     *
     * @param int|array $value... the new value(s).  This can be zero or
     * more numbers, that is, either integers or arrays.  The input will
     * be checked to ensure that the numbers are within the valid range.
     * If not, then a {@link PelOverflowException} will be thrown.
     *
     * @see getValue
     */
    function setValue(/* $value... */) {
        $value = func_get_args();
        $this->setValueArray($value);
    }


    /**
     * Change the value.
     *
     * This method can change both the number of components and the
     * value of the components.  Range checks will be made on the new
     * value, and a {@link PelOverflowException} will be thrown if the
     * value is found to be outside the legal range.
     *
     * @param array the new values.  The array must contain the new
     * numbers.
     *
     * @see getValue
     */
    function setValueArray($value) {
        foreach ($value as $v)
        $this->validateNumber($v);

        $this->components = count($value);
        $this->value      = $value;
    }


    /**
     * Return the numeric value held.
     *
     * @return int|array this will either be a single number if there is
     * only one component, or an array of numbers otherwise.
     */
    function getValue() {
        if ($this->components == 1)
        return $this->value[0];
        else
        return $this->value;
    }


    /**
     * Validate a number.
     *
     * This method will check that the number given is within the range
     * given my {@link getMin()} and {@link getMax()}, inclusive.  If
     * not, then a {@link PelOverflowException} is thrown.
     *
     * @param int|array the number in question.
     *
     * @return void nothing, but will throw a {@link
     * PelOverflowException} if the number is found to be outside the
     * legal range and {@link Pel::$strict} is true.
     */
    function validateNumber($n) {
        if ($this->dimension == 1) {
            if ($n < $this->min || $n > $this->max)
            Pel::maybeThrow(new PelOverflowException($n,
            $this->min,
            $this->max));
        } else {
            for ($i = 0; $i < $this->dimension; $i++)
            if ($n[$i] < $this->min || $n[$i] > $this->max)
            Pel::maybeThrow(new PelOverflowException($n[$i],
            $this->min,
            $this->max));
        }
    }


    /**
     * Add a number.
     *
     * This appends a number to the numbers already held by this entry,
     * thereby increasing the number of components by one.
     *
     * @param int|array the number to be added.
     */
    function addNumber($n) {
        $this->validateNumber($n);
        $this->value[] = $n;
        $this->components++;
    }


    /**
     * Convert a number into bytes.
     *
     * The concrete subclasses will have to implement this method so
     * that the numbers represented can be turned into bytes.
     *
     * The method will be called once for each number held by the entry.
     *
     * @param int the number that should be converted.
     *
     * @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
     * {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
     *
     * @return string bytes representing the number given.
     */
    abstract function numberToBytes($number, $order);


    /**
     * Turn this entry into bytes.
     *
     * @param PelByteOrder the desired byte order, which must be either
     * {@link PelConvert::LITTLE_ENDIAN} or {@link
     * PelConvert::BIG_ENDIAN}.
     *
     * @return string bytes representing this entry.
     */
    function getBytes($o) {
        $bytes = '';
        for ($i = 0; $i < $this->components; $i++) {
            if ($this->dimension == 1) {
                $bytes .= $this->numberToBytes($this->value[$i], $o);
            } else {
                for ($j = 0; $j < $this->dimension; $j++) {
                    $bytes .= $this->numberToBytes($this->value[$i][$j], $o);
                }
            }
        }
        return $bytes;
    }


    /**
     * Format a number.
     *
     * This method is called by {@link getText} to format numbers.
     * Subclasses should override this method if they need more
     * sophisticated behavior than the default, which is to just return
     * the number as is.
     *
     * @param int the number which will be formatted.
     *
     * @param boolean it could be that there is both a verbose and a
     * brief formatting available, and this argument controls that.
     *
     * @return string the number formatted as a string suitable for
     * display.
     */
    function formatNumber($number, $brief = false) {
        return $number;
    }


    /**
     * Get the numeric value of this entry as text.
     *
     * @param boolean use brief output?  The numbers will be separated
     * by a single space if brief output is requested, otherwise a space
     * and a comma will be used.
     *
     * @return string the numbers(s) held by this entry.
     */
    function getText($brief = false) {
        if ($this->components == 0)
        return '';

        $str = $this->formatNumber($this->value[0]);
        for ($i = 1; $i < $this->components; $i++) {
            $str .= ($brief ? ' ' : ', ');
            $str .= $this->formatNumber($this->value[$i]);
        }

        return $str;
    }

}