about summary refs log tree commit diff
path: root/converter/other/cameratopam/util.c
blob: ede5ef6959ee9ea87bdb863aa507b7cadff69cda (plain) (blame)
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;
}