ref: 7dd87721538f0392ba840134ecf3e7468b5d4a3f
dir: /f_ccittfax.c/
#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 = calloc(sizeof(*h), 1)) == 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, };