1 /* Copyright (C) 2001-2012 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13 CA 94903, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Level 2 encoded number reading utilities for Ghostscript */
18 #include "math_.h"
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "opcheck.h"
22 #include "ierrors.h"
23 #include "stream.h"
24 #include "ibnum.h"
25 #include "imemory.h" /* for iutil.h */
26 #include "iutil.h"
27
28 /* Define the number of bytes for a given format of encoded number. */
29 const byte enc_num_bytes[] = {
30 enc_num_bytes_values
31 };
32
33 /* ------ Encoded number reading ------ */
34
35 /* Set up to read from an encoded number array/string. */
36 /* Return <0 for error, or a number format. */
37 int
num_array_format(const ref * op)38 num_array_format(const ref * op)
39 {
40 int format;
41
42 switch (r_type(op)) {
43 case t_string:
44 {
45 /* Check that this is a legitimate encoded number string. */
46 const byte *bp = op->value.bytes;
47
48 if (r_size(op) < 4 || bp[0] != bt_num_array_value)
49 return_error(e_typecheck);
50 format = bp[1];
51 if (!num_is_valid(format) ||
52 sdecodeshort(bp + 2, format) !=
53 (r_size(op) - 4) / encoded_number_bytes(format)
54 )
55 return_error(e_rangecheck);
56 }
57 break;
58 case t_array:
59 case t_mixedarray:
60 case t_shortarray:
61 format = num_array;
62 break;
63 default:
64 return_error(e_typecheck);
65 }
66 check_read(*op);
67 return format;
68 }
69
70 /* Get the number of elements in an encoded number array/string. */
71 uint
num_array_size(const ref * op,int format)72 num_array_size(const ref * op, int format)
73 {
74 return (format == num_array ? r_size(op) :
75 (r_size(op) - 4) / encoded_number_bytes(format));
76 }
77
78 /* Get an encoded number from an array/string according to the given format. */
79 /* Put the value in np->value.{intval,realval}. */
80 /* Return t_int if integer, t_real if real, t_null if end of stream, */
81 /* or an error if the format is invalid. */
82 int
num_array_get(const gs_memory_t * mem,const ref * op,int format,uint index,ref * np)83 num_array_get(const gs_memory_t *mem, const ref * op, int format, uint index, ref * np)
84 {
85 if (format == num_array) {
86 int code = array_get(mem, op, (long)index, np);
87
88 if (code < 0)
89 return t_null;
90 switch (r_type(np)) {
91 case t_integer:
92 return t_integer;
93 case t_real:
94 return t_real;
95 default:
96 return_error(e_typecheck);
97 }
98 } else {
99 uint nbytes = encoded_number_bytes(format);
100
101 if (index >= (r_size(op) - 4) / nbytes)
102 return t_null;
103 return sdecode_number(op->value.bytes + 4 + index * nbytes,
104 format, np);
105 }
106 }
107
108 /* Internal routine to decode a number in a given format. */
109 /* Same returns as sget_encoded_number. */
110 static const double binary_scale[32] = {
111 #define EXPN2(n) (0.5 / (1L << (n-1)))
112 1.0, EXPN2(1), EXPN2(2), EXPN2(3),
113 EXPN2(4), EXPN2(5), EXPN2(6), EXPN2(7),
114 EXPN2(8), EXPN2(9), EXPN2(10), EXPN2(11),
115 EXPN2(12), EXPN2(13), EXPN2(14), EXPN2(15),
116 EXPN2(16), EXPN2(17), EXPN2(18), EXPN2(19),
117 EXPN2(20), EXPN2(21), EXPN2(22), EXPN2(23),
118 EXPN2(24), EXPN2(25), EXPN2(26), EXPN2(27),
119 EXPN2(28), EXPN2(29), EXPN2(30), EXPN2(31)
120 #undef EXPN2
121 };
122 int
sdecode_number(const byte * str,int format,ref * np)123 sdecode_number(const byte * str, int format, ref * np)
124 {
125 switch (format & 0x170) {
126 case num_int32:
127 case num_int32 + 16:
128 if ((format & 31) == 0) {
129 np->value.intval = sdecodeint32(str, format);
130 return t_integer;
131 } else {
132 np->value.realval =
133 (double)sdecodeint32(str, format) *
134 binary_scale[format & 31];
135 return t_real;
136 }
137 case num_int16:
138 if ((format & 15) == 0) {
139 np->value.intval = sdecodeshort(str, format);
140 return t_integer;
141 } else {
142 np->value.realval =
143 sdecodeshort(str, format) *
144 binary_scale[format & 15];
145 return t_real;
146 }
147 case num_float:
148 {
149 float fval;
150 int code = sdecode_float(str, format, &fval);
151
152 if (code < 0)
153 return code;
154 np->value.realval = fval;
155 return t_real;
156 }
157 default:
158 return_error(e_syntaxerror); /* invalid format?? */
159 }
160 }
161
162 /* ------ Decode number ------ */
163
164 /* Decode encoded numbers from a string according to format. */
165
166 /* Decode a (16-bit, signed or unsigned) short. */
167 uint
sdecodeushort(const byte * p,int format)168 sdecodeushort(const byte * p, int format)
169 {
170 int a = p[0], b = p[1];
171
172 return (num_is_lsb(format) ? (b << 8) + a : (a << 8) + b);
173 }
174 int
sdecodeshort(const byte * p,int format)175 sdecodeshort(const byte * p, int format)
176 {
177 int v = (int)sdecodeushort(p, format);
178
179 return (v & 0x7fff) - (v & 0x8000);
180 }
181
182 /* Decode a (32-bit, signed) long. */
183 int
sdecodeint32(const byte * p,int format)184 sdecodeint32(const byte * p, int format)
185 {
186 int a = p[0], b = p[1], c = p[2], d = p[3];
187 int v = (num_is_lsb(format) ?
188 ((int)d << 24) + ((int)c << 16) + (b << 8) + a :
189 ((int)a << 24) + ((int)b << 16) + (c << 8) + d);
190 return v;
191 }
192
193 /* Decode a 32-bit number. Return the resukt through a pointer */
194 /* to work around a gcc 4.2.1 bug on PowerPC, bug 689586 */
195 static void
sdecodebits32(const byte * p,int format,bits32 * v)196 sdecodebits32(const byte * p, int format, bits32 *v)
197 {
198 int a = p[0], b = p[1], c = p[2], d = p[3];
199 *v = (num_is_lsb(format) ?
200 ((long)d << 24) + ((long)c << 16) + (b << 8) + a :
201 ((long)a << 24) + ((long)b << 16) + (c << 8) + d);
202
203 }
204
205 /* Decode a float. We assume that native floats occupy 32 bits. */
206 /* If the float is an IEEE NaN or Inf, return e_undefinedresult. */
207 int
sdecode_float(const byte * p,int format,float * pfnum)208 sdecode_float(const byte * p, int format, float *pfnum)
209 {
210 bits32 lnum;
211
212 if ((format & ~(num_msb | num_lsb)) == num_float_native) {
213 /*
214 * Just read 4 bytes and interpret them as a float, ignoring
215 * any indication of byte ordering.
216 */
217 memcpy(pfnum, p, 4);
218 #if !ARCH_FLOATS_ARE_IEEE
219 return 0; /* no way to check for anomalies */
220 #endif
221 lnum = *(bits32 *)pfnum;
222 } else {
223 sdecodebits32(p, format, &lnum);
224
225 #if !ARCH_FLOATS_ARE_IEEE
226 {
227 /* We know IEEE floats take 32 bits. */
228 /* Convert IEEE float to native float. */
229 int sign_expt = lnum >> 23;
230 int expt = sign_expt & 0xff;
231 long mant = lnum & 0x7fffff;
232 float fnum;
233
234 if (expt == 0 && mant == 0)
235 fnum = 0;
236 else if (expt == 0xff)
237 return_error(e_undefinedresult); /* Inf or NaN */
238 else {
239 mant += 0x800000;
240 fnum = (float)ldexp((float)mant, expt - 127 - 23);
241 }
242 if (sign_expt & 0x100)
243 fnum = -fnum;
244 *pfnum = fnum;
245 return 0; /* checked for Infs and NaNs above */
246 }
247 #else
248 *pfnum = *(float *)&lnum;
249 #endif
250 }
251 /*
252 * Unfortunately, there is no portable way for testing whether a float
253 * is a NaN or Inf. Do it "by hand" if the input representation is
254 * IEEE (which is the case if control arrives here).
255 */
256 if (!(~lnum & 0x7f800000)) /* i.e. exponent all 1's */
257 return_error(e_undefinedresult); /* Inf or NaN */
258 return 0;
259 }
260