shithub: pdffs

Download patch

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,
 };