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
|
#define _XOPEN_SOURCE /* Make sure unistd.h contains swab() */
#include <unistd.h>
#include "netpbm/pm.h"
#include "netpbm/mallocvar.h"
#include "global_variables.h"
#include "util.h"
#include "stdio_nofail.h"
#ifndef LONG_BITS
#define LONG_BITS (8 * sizeof(long))
#endif
/*
Get a 2-byte integer, making no assumptions about CPU byte order.
Nor should we assume that the compiler evaluates left-to-right.
*/
unsigned short
get2(FILE * const ifp)
{
unsigned char a, b;
a = fgetc_nofail(ifp); b = fgetc_nofail(ifp);
if (order == 0x4949) /* "II" means little-endian */
return a | b << 8;
else /* "MM" means big-endian */
return a << 8 | b;
}
/*
Same for a 4-byte integer.
*/
int
get4(FILE * const ifp)
{
unsigned char a, b, c, d;
a = fgetc_nofail(ifp); b = fgetc_nofail(ifp);
c = fgetc_nofail(ifp); d = fgetc_nofail(ifp);
if (order == 0x4949)
return a | b << 8 | c << 16 | d << 24;
else
return a << 24 | b << 16 | c << 8 | d;
}
/*
Faster than calling get2() multiple times.
*/
void
read_shorts (FILE * const ifp, unsigned short *pixel, int count)
{
unsigned short * buffer;
MALLOCARRAY(buffer, count);
if (!buffer)
pm_error("Failed to allocate a buffer for reading %u short "
"integers from file", count);
else {
fread_nofail(buffer, 2, count, ifp);
if ((order == 0x4949) == (BYTE_ORDER == BIG_ENDIAN))
swab(buffer, pixel, count*2);
free(buffer);
}
}
/*
getbits(-1) initializes the buffer
getbits(n) where 0 <= n <= 25 returns an n-bit integer
*/
unsigned
getbits (FILE * const ifp, int nbits)
{
static unsigned long bitbuf=0;
static int vbits=0;
unsigned c, ret;
if (nbits == 0) return 0;
if (nbits == -1)
ret = bitbuf = vbits = 0;
else {
ret = bitbuf << (LONG_BITS - vbits) >> (LONG_BITS - nbits);
vbits -= nbits;
}
while (vbits < LONG_BITS - 7) {
c = fgetc_nofail(ifp);
bitbuf = (bitbuf << 8) + c;
if (c == 0xff && zero_after_ff)
fgetc_nofail(ifp);
vbits += 8;
}
return ret;
}
|