ref: f342f5a5600a41bcf634e59af2a8f951cb24afb6
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,
};