#include <u.h>#include <libc.h>#include "pdf.h" /* 7.4.6 CCITTFaxDecode filter */ enum { Tbyte = 1, Tascii, Tshort, Tlong, Trational, DImageWidth = 0, DImageLength, DBitsPerSample, DCompression, DPhotometricInterpretation, DStripOffsets, DRowsPerStrip, DStripByteCounts, Dcnt,}; #pragma pack ontypedef struct Entry Entry;typedef struct Header Header;typedef struct IFD IFD; struct Entry { u16int tag; u16int type; u32int cnt; u32int v;}; struct IFD { u16int decnt; Entry de[Dcnt]; u32int nextoff;}; /* TIFF header */struct Header { u16int order; u16int magic; u32int ifd₀off; IFD ifd; /* don't need more than one */};#pragma pack off static Header bh = { .order = 0x4949, /* II, little endian */ .magic = 42, .ifd₀off = 8, .ifd = { .decnt = Dcnt, .de = { [DImageWidth] = { 256, Tlong, 1, 0 }, [DImageLength] = { 257, Tlong, 1, 0 }, [DBitsPerSample] = { 258, Tshort, 1, 1 }, [DCompression] = { 259, Tshort, 1, 4 }, /* 4 ≡ ITU-T T.6 */ [DPhotometricInterpretation] = { 262, Tshort, 1, 0 }, /* 0 ≡ WhiteIsZero, 1 ≡ BlackIsZero */ [DStripOffsets] = { 273, Tlong, 1, sizeof(Header) }, [DRowsPerStrip] = { 278, Tlong, 1, 0 }, [DStripByteCounts] = { 279, Tlong, 1, 0 }, }, .nextoff = 0, /* last one */ },}; static intflreadall(void *aux, Buffer *bi, Buffer *bo){ Header *h; h = aux; h->ifd.de[DStripByteCounts].v = bi->sz; bufput(bo, (uchar*)h, sizeof(*h)); bufput(bo, bi->b, bi->sz); bi->off = bi->sz; return 0;} static intflopen(Filter *f, Object *o){ Object *parms; Header *h; if((h = malloc(sizeof(*h))) == nil) return -1; memmove(h, &bh, sizeof(bh)); parms = dictget(o, "DecodeParms"); h->ifd.de[DImageWidth].v = dictintopt(parms, "Columns", 1728); h->ifd.de[DImageLength].v = dictint(parms, "Rows"); h->ifd.de[DPhotometricInterpretation].v = !dictint(parms, "BlackIs1"); h->ifd.de[DRowsPerStrip].v = h->ifd.de[DImageLength].v; f->aux = h; return 0;} static voidflclose(Filter *f){ free(f->aux);} Filter filterCCITTFax = { .name = "CCITTFaxDecode", .readall = flreadall, .open = flopen, .close = flclose,};
#include <u.h>
#include <libc.h>
#include "pdf.h"
/* 7.4.6 CCITTFaxDecode filter */
enum {
Tbyte = 1,
Tascii,
Tshort,
Tlong,
Trational,
DImageWidth = 0,
DImageLength,
DBitsPerSample,
DCompression,
DPhotometricInterpretation,
DStripOffsets,
DRowsPerStrip,
DStripByteCounts,
Dcnt,
};
#pragma pack on
typedef struct Entry Entry;
typedef struct Header Header;
typedef struct IFD IFD;
struct Entry {
u16int tag;
u16int type;
u32int cnt;
u32int v;
};
struct IFD {
u16int decnt;
Entry de[Dcnt];
u32int nextoff;
};
/* TIFF header */
struct Header {
u16int order;
u16int magic;
u32int ifd₀off;
IFD ifd; /* don't need more than one */
};
#pragma pack off
static Header bh = {
.order = 0x4949, /* II, little endian */
.magic = 42,
.ifd₀off = 8,
.ifd = {
.decnt = Dcnt,
.de = {
[DImageWidth] = { 256, Tlong, 1, 0 },
[DImageLength] = { 257, Tlong, 1, 0 },
[DBitsPerSample] = { 258, Tshort, 1, 1 },
[DCompression] = { 259, Tshort, 1, 4 }, /* 4 ≡ ITU-T T.6 */
[DPhotometricInterpretation] = { 262, Tshort, 1, 0 }, /* 0 ≡ WhiteIsZero, 1 ≡ BlackIsZero */
[DStripOffsets] = { 273, Tlong, 1, sizeof(Header) },
[DRowsPerStrip] = { 278, Tlong, 1, 0 },
[DStripByteCounts] = { 279, Tlong, 1, 0 },
},
.nextoff = 0, /* last one */
},
};
static int
flreadall(void *aux, Buffer *bi, Buffer *bo)
{
Header *h;
h = aux;
h->ifd.de[DStripByteCounts].v = bi->sz;
bufput(bo, (uchar*)h, sizeof(*h));
bufput(bo, bi->b, bi->sz);
bi->off = bi->sz;
return 0;
}
static int
flopen(Filter *f, Object *o)
{
Object *parms;
Header *h;
if((h = malloc(sizeof(*h))) == nil)
return -1;
memmove(h, &bh, sizeof(bh));
parms = dictget(o, "DecodeParms");
h->ifd.de[DImageWidth].v = dictintopt(parms, "Columns", 1728);
h->ifd.de[DImageLength].v = dictint(parms, "Rows");
h->ifd.de[DPhotometricInterpretation].v = !dictint(parms, "BlackIs1");
h->ifd.de[DRowsPerStrip].v = h->ifd.de[DImageLength].v;
f->aux = h;
return 0;
}
static void
flclose(Filter *f)
{
free(f->aux);
}
Filter filterCCITTFax = {
.name = "CCITTFaxDecode",
.readall = flreadall,
.open = flopen,
.close = flclose,
};