forked from smuehlst/jbig2enc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
jbig2segments.h
158 lines (138 loc) · 4.62 KB
/
jbig2segments.h
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
// Copyright 2006 Google Inc. All Rights Reserved.
// Author: agl@google.com (Adam Langley)
#ifndef THIRD_PARTY_JBIG2ENC_JBIG2SEGMENTS_H__
#define THIRD_PARTY_JBIG2ENC_JBIG2SEGMENTS_H__
#include <vector>
#ifdef _MSC_VER
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
// -----------------------------------------------------------------------------
// See comments in jbig2structs.h about the bit packing in this structure.
// -----------------------------------------------------------------------------
#if defined(WIN32)
#pragma pack(1)
#endif
struct jbig2_segment {
u32 number;
#ifndef _BIG_ENDIAN
unsigned char type : 6;
unsigned char page_assoc_size : 1;
unsigned char deferred_non_retain : 1;
#else
unsigned char deferred_non_retain : 1;
unsigned char page_assoc_size : 1;
unsigned char type : 6;
#endif
#ifndef _BIG_ENDIAN
unsigned char retain_bits : 5;
unsigned char segment_count : 3;
#else
unsigned char segment_count : 3;
unsigned char retain_bits : 5;
#endif
}
#if defined(WIN32)
;
#pragma pack()
#else
__attribute__((packed));
#endif
;
// -----------------------------------------------------------------------------
// This structure represents a JBIG2 segment header because they have too many
// variable length fields (number of referred to segments, page length etc).
// You should access and set the members directly. Endian swapping is carried
// out internally.
// -----------------------------------------------------------------------------
struct Segment {
unsigned number; // segment number
int type; // segment type (see enum in jbig2structs.h)
int deferred_non_retain; // see JBIG2 spec
int retain_bits;
std::vector<unsigned> referred_to; // list of segment numbers referred to
unsigned page; // page number
unsigned len; // length of trailing data
Segment()
: number(0),
type(0),
deferred_non_retain(0),
retain_bits(0),
page(0),
len(0) {}
// ---------------------------------------------------------------------------
// Return the size of the segment reference for this segment. Segments can
// only refer to previous segments, so the bits needed is determined by the
// number of this segment. (7.2.5)
// ---------------------------------------------------------------------------
unsigned reference_size() const {
int refsize;
if (number <= 256) {
refsize = 1;
} else if (number <= 65536) {
refsize = 2;
} else {
refsize = 4;
}
return refsize;
}
// ---------------------------------------------------------------------------
// Return the size of the segment page association field for this segment.
// (7.2.6)
// ---------------------------------------------------------------------------
unsigned page_size() const {
return page <= 255 ? 1 : 4;
}
// ---------------------------------------------------------------------------
// Return the number of bytes that this segment header will take up
// ---------------------------------------------------------------------------
unsigned size() const {
const int refsize = reference_size();
const int pagesize = page_size();
return sizeof(struct jbig2_segment) + refsize * referred_to.size() +
pagesize + sizeof(u32);
}
// ---------------------------------------------------------------------------
// Serialise this segment header into the memory pointed to by buf, which
// must be at least long enough to contain it (e.g. size() bytes)
// ---------------------------------------------------------------------------
void write(u8 *buf) {
struct jbig2_segment s;
memset(&s, 0, sizeof(s));
#define F(x) s.x = x;
s.number = htonl(number);
s.type = type;
s.deferred_non_retain = deferred_non_retain;
s.retain_bits = retain_bits;
#undef F
s.segment_count = referred_to.size();
const int pagesize = page_size();
const int refsize = reference_size();
if (pagesize == 4) s.page_assoc_size = 1;
unsigned j = 0;
memcpy(buf, &s, sizeof(s));
j += sizeof(s);
#define APPEND(type, val) type __i; __i = val; \
memcpy(&buf[j], &__i, sizeof(type)); \
j += sizeof(type)
for (std::vector<unsigned>::const_iterator i = referred_to.begin();
i != referred_to.end(); ++i) {
if (refsize == 4) {
APPEND(u32, htonl(*i));
} else if (refsize == 2) {
APPEND(u16, htons(*i));
} else {
APPEND(u8, *i);
}
}
if (pagesize == 4) {
APPEND(u32, htonl(page));
} else {
APPEND(u8, page);
}
APPEND(u32, htonl(len));
if (j != size()) abort();
}
};
#endif // THIRD_PARTY_JBIG2ENC_JBIG2SEGMENTS_H__