Files
core/ASCImageStudio3/ASCImageJBig2/Encoder/jbig2segments.h

150 lines
4.3 KiB
C++

// 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 number of bytes that this segment header will take up
// ---------------------------------------------------------------------------
unsigned size() const {
const int refsize = reference_size();
const int pagesize = page <= 255 ? 1 : 2;
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 <= 255 ? 1 : 2;
const int refsize = reference_size();
if (pagesize == 2) 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 == 2) {
APPEND(u16, htonl(page));
} else {
APPEND(u8, page);
}
APPEND(u32, htonl(len));
if (j != size()) abort();
}
};
#endif // THIRD_PARTY_JBIG2ENC_JBIG2SEGMENTS_H__