ref: a6c9e64221b8553899fddb25dc3b14e989be752d
parent: 0cba24e79ef4e3fe049206599322cf8f434fc4b0
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Fri Apr 9 09:18:17 EDT 2021
extract ccitt fax as tiff
--- a/f_ccittfax.c
+++ b/f_ccittfax.c
@@ -2,6 +2,114 @@
#include <libc.h>
#include "pdf.h"
+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, 0 },
+ [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 = dictint(parms, "Columns");
+ h->ifd.de[DImageLength].v = dictint(parms, "Rows");
+ h->ifd.de[DBitsPerSample].v = dictint(o, "BitsPerComponent");
+ h->ifd.de[DPhotometricInterpretation].v = !dictint(parms, "BlackIs1");
+ h->ifd.de[DRowsPerStrip].v = h->ifd.de[DImageLength].v;
+ f->aux = h;
+
+ return 0;
+}
+
+void
+flclose(Filter *f)
+{
+ free(f->aux);
+}
+
Filter filterCCITTFax = {
.name = "CCITTFaxDecode",
+ .readall = flreadall,
+ .open = flopen,
+ .close = flclose,
};