… | |
… | |
19 | |
19 | |
20 | #include "config.h" |
20 | #include "config.h" |
21 | #include "compat.h" |
21 | #include "compat.h" |
22 | |
22 | |
23 | #include <stdlib.h> |
23 | #include <stdlib.h> |
|
|
24 | #include <math.h> |
24 | |
25 | |
25 | #include "parse_routines.h" |
26 | #include "parse_routines.h" |
26 | #include "error.h" |
27 | #include "error.h" |
27 | |
28 | |
28 | psiconv_u8 psiconv_read_u8(const psiconv_buffer buf,int lev,psiconv_u32 off, |
29 | psiconv_u8 psiconv_read_u8(const psiconv_buffer buf,int lev,psiconv_u32 off, |
29 | int *status) |
30 | int *status) |
30 | { |
31 | { |
31 | psiconv_u8 *ptr; |
32 | psiconv_u8 *ptr; |
32 | ptr = psiconv_list_get(buf,off); |
33 | ptr = psiconv_buffer_get(buf,off); |
33 | if (!ptr) { |
34 | if (!ptr) { |
34 | psiconv_warn(lev,off,"Trying byte read past the end of the file"); |
35 | psiconv_warn(lev,off,"Trying byte read past the end of the file"); |
35 | if (status) |
36 | if (status) |
36 | *status = -PSICONV_E_PARSE; |
37 | *status = -PSICONV_E_PARSE; |
37 | return 0; |
38 | return 0; |
… | |
… | |
43 | |
44 | |
44 | psiconv_u16 psiconv_read_u16(const psiconv_buffer buf,int lev,psiconv_u32 off, |
45 | psiconv_u16 psiconv_read_u16(const psiconv_buffer buf,int lev,psiconv_u32 off, |
45 | int *status) |
46 | int *status) |
46 | { |
47 | { |
47 | psiconv_u8 *ptr0,*ptr1; |
48 | psiconv_u8 *ptr0,*ptr1; |
48 | ptr0 = psiconv_list_get(buf,off); |
49 | ptr0 = psiconv_buffer_get(buf,off); |
49 | ptr1 = psiconv_list_get(buf,off+1); |
50 | ptr1 = psiconv_buffer_get(buf,off+1); |
50 | if (!ptr0 || !ptr1) { |
51 | if (!ptr0 || !ptr1) { |
51 | psiconv_warn(lev,off,"Trying word read past the end of the file"); |
52 | psiconv_warn(lev,off,"Trying word read past the end of the file"); |
52 | if (status) |
53 | if (status) |
53 | *status = -PSICONV_E_PARSE; |
54 | *status = -PSICONV_E_PARSE; |
54 | return 0; |
55 | return 0; |
… | |
… | |
60 | |
61 | |
61 | psiconv_u32 psiconv_read_u32(const psiconv_buffer buf,int lev,psiconv_u32 off, |
62 | psiconv_u32 psiconv_read_u32(const psiconv_buffer buf,int lev,psiconv_u32 off, |
62 | int *status) |
63 | int *status) |
63 | { |
64 | { |
64 | psiconv_u8 *ptr0,*ptr1,*ptr2,*ptr3; |
65 | psiconv_u8 *ptr0,*ptr1,*ptr2,*ptr3; |
65 | ptr0 = psiconv_list_get(buf,off); |
66 | ptr0 = psiconv_buffer_get(buf,off); |
66 | ptr1 = psiconv_list_get(buf,off+1); |
67 | ptr1 = psiconv_buffer_get(buf,off+1); |
67 | ptr2 = psiconv_list_get(buf,off+2); |
68 | ptr2 = psiconv_buffer_get(buf,off+2); |
68 | ptr3 = psiconv_list_get(buf,off+3); |
69 | ptr3 = psiconv_buffer_get(buf,off+3); |
69 | if (!ptr0 || !ptr1 || !ptr2 || !ptr3) { |
70 | if (!ptr0 || !ptr1 || !ptr2 || !ptr3) { |
70 | psiconv_warn(lev,off,"Trying long read past the end of the file"); |
71 | psiconv_warn(lev,off,"Trying long read past the end of the file"); |
71 | if (status) |
72 | if (status) |
72 | *status = -PSICONV_E_PARSE; |
73 | *status = -PSICONV_E_PARSE; |
73 | return 0; |
74 | return 0; |
… | |
… | |
301 | *status = localstatus; |
302 | *status = localstatus; |
302 | if (length) |
303 | if (length) |
303 | *length = 0; |
304 | *length = 0; |
304 | return NULL; |
305 | return NULL; |
305 | } |
306 | } |
|
|
307 | |
|
|
308 | psiconv_float_t psiconv_read_float(const psiconv_buffer buf, int lev, |
|
|
309 | psiconv_u32 off, int *length, int *status) |
|
|
310 | { |
|
|
311 | psiconv_float_t result,bitvalue; |
|
|
312 | int res,bit; |
|
|
313 | psiconv_u32 temp=0; |
|
|
314 | |
|
|
315 | psiconv_progress(lev+1,off,"Going to read a float"); |
|
|
316 | |
|
|
317 | bitvalue = 0.5; |
|
|
318 | result = 1.0; |
|
|
319 | for (bit = 0x33; bit > 0; bit--) { |
|
|
320 | if ((bit == 0x33) || ((bit & 0x07) == 0x07)) |
|
|
321 | temp = psiconv_read_u8(buf,lev+2,off+ (bit >> 3),&res); |
|
|
322 | if (res) |
|
|
323 | goto ERROR; |
|
|
324 | if (temp & (0x01 << (bit & 0x07))) |
|
|
325 | result += bitvalue; |
|
|
326 | bitvalue /= 2.0; |
|
|
327 | } |
|
|
328 | temp = psiconv_read_u16(buf,lev+2,off+6,&res); |
|
|
329 | if (res) |
|
|
330 | goto ERROR; |
|
|
331 | if (temp & 0x8000) |
|
|
332 | result = -result; |
|
|
333 | temp = (temp & 0x7ff0) >> 4; |
|
|
334 | result *= pow(2.0,((int) temp)-0x3ff); |
|
|
335 | psiconv_debug(lev+1,off,"Float value: %f",result); |
|
|
336 | if (length) |
|
|
337 | *length = 8; |
|
|
338 | if (*status) |
|
|
339 | *status = res; |
|
|
340 | return result; |
|
|
341 | ERROR: |
|
|
342 | psiconv_warn(lev+1,off,"Reading of float failed"); |
|
|
343 | if (length) |
|
|
344 | *length = 0; |
|
|
345 | if (*status) |
|
|
346 | *status = res; |
|
|
347 | return 0.0; |
|
|
348 | } |