shithub: pdffs

Download patch

ref: 14a773539df70e5fe32c31979abf032eba58ecf4
parent: 2d3fd9732381d95ebc7e6ba8e38dfa7addce77e3
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Wed Jun 2 12:07:38 EDT 2021

convert image streams to plan 9 Memimage

--- a/buffer.c
+++ b/buffer.c
@@ -1,6 +1,8 @@
 #include <u.h>
 #include <libc.h>
 #include <bio.h>
+#include <draw.h>
+#include <memdraw.h>
 #include "pdf.h"
 
 static int
@@ -24,6 +26,24 @@
 	}
 
 	return 0;
+}
+
+void *
+buf2memimage(Buffer *b, char *prog, char **argv)
+{
+	Memimage *m;
+	int fd;
+
+	if(pipeexec(&fd, prog, argv) < 0)
+		return nil;
+
+	write(fd, b->b, b->sz);
+	write(fd, "", 0);
+
+	m = readmemimage(fd);
+	close(fd);
+
+	return m;
 }
 
 void
--- a/f_dct.c
+++ b/f_dct.c
@@ -4,6 +4,13 @@
 
 /* 7.4.8 DCTDecode filter */
 
+static void *
+memimage(Buffer *b)
+{
+	char *argv[] = {"jpg", "-9", nil};
+	return buf2memimage(b, "/bin/jpg", argv);
+}
+
 static int
 flreadall(void *aux, Buffer *bi, Buffer *bo)
 {
@@ -13,6 +20,7 @@
 
 	bufput(bo, bi->b, bi->sz);
 	bi->off = bi->sz;
+	bo->memimage = memimage;
 
 	return 0;
 }
--- a/f_jbig2.c
+++ b/f_jbig2.c
@@ -10,6 +10,13 @@
 	/* one page   */ 0x00, 0x00, 0x00, 0x01,
 };
 
+static void *
+memimage(Buffer *b)
+{
+	char *argv[] = {"jbig2", nil};
+	return buf2memimage(b, "/bin/jbig2", argv);
+}
+
 static int
 flreadall(void *aux, Buffer *bi, Buffer *bo)
 {
@@ -21,6 +28,7 @@
 		bufput(bo, s->buf.b, s->buf.sz);
 	bufput(bo, bi->b, bi->sz);
 	bi->off = bi->sz;
+	bo->memimage = memimage;
 
 	return 0;
 }
--- a/f_jpx.c
+++ b/f_jpx.c
@@ -4,6 +4,13 @@
 
 /* 7.4.9 JPXDecode filter */
 
+static void *
+memimage(Buffer *b)
+{
+	char *argv[] = {"jp2", nil};
+	return buf2memimage(b, "/bin/jp2", argv);
+}
+
 static int
 flreadall(void *aux, Buffer *bi, Buffer *bo)
 {
@@ -11,6 +18,7 @@
 
 	bufput(bo, bi->b, bi->sz);
 	bi->off = bi->sz;
+	bo->memimage = memimage;
 
 	return 0;
 }
--- a/main.c
+++ b/main.c
@@ -4,6 +4,8 @@
 #include <ctype.h>
 #include <bio.h>
 #include <flate.h>
+#include <draw.h>
+#include <memdraw.h>
 #include "pdf.h"
 
 int mainstacksize = 128*1024;
@@ -58,6 +60,8 @@
 
 	quotefmtinstall();
 	inflateinit();
+	memimageinit();
+	threadwaitchan();
 
 	ARGBEGIN{
 	default:
@@ -68,7 +72,7 @@
 
 	if(argc < 1)
 		usage();
-	if((b = Bopen(argv[0], OREAD)) == nil)
+	if((b = Bopen(argv[0], OREAD|OCEXEC)) == nil)
 		sysfatal("%r");
 	if((pdf = pdfopen(b)) == nil)
 		sysfatal("%s: %r", argv[0]);
@@ -76,11 +80,16 @@
 		if(isdigit(argv[i][0])){
 			n = atoi(argv[i]);
 			v = arrayget(v, n);
-		}else if(argv[i][0] == '.' && argv[i][1] == 0 && v->type == Ostream){
+		}else if((argv[i][0] == '.' || argv[i][0] == '!') && argv[i][1] == 0 && v->type == Ostream){
+			Memimage *m;
 			if((s = Sopen(v)) == nil)
 				sysfatal("%r");
-			if(write(1, s->buf.b, s->buf.sz) != s->buf.sz)
+			if(argv[i][0] != '!' && (m = Sgetmemimage(s)) != nil){
+				writememimage(1, m);
+				freememimage(m);
+			}else if(write(1, s->buf.b, s->buf.sz) != s->buf.sz){
 				sysfatal("write failed");
+			}
 			Sclose(s);
 			v = nil;
 			break;
--- a/misc.c
+++ b/misc.c
@@ -1,7 +1,22 @@
 #include <u.h>
 #include <libc.h>
+#include <thread.h>
 #include "pdf.h"
 
+enum {
+	Us,
+	Them,
+};
+
+typedef struct Exec Exec;
+
+struct Exec {
+	char *file;
+	char **argv;
+	int p[2];
+	Channel *pid;
+};
+
 static char *otypes[] = {
 	[Obool] = "bool",
 	[Onum] = "num",
@@ -120,4 +135,47 @@
 	}
 
 	return i >= len;
+}
+
+static void
+pexec(void *args)
+{
+	Exec *e = args;
+
+	if(e->p[0] >= 0){
+		dup(e->p[Them], 0);
+		dup(e->p[Them], 1);
+		close(e->p[0]);
+		close(e->p[1]);
+	}else{
+		close(0);
+		close(1);
+	}
+	procexec(e->pid, e->file, e->argv);
+}
+
+int
+pipeexec(int *fd, char *file, char **argv)
+{
+	int pid;
+	Exec e;
+
+	e.file = file;
+	e.argv = argv;
+	e.pid = chancreate(sizeof(int), 0);
+	e.p[0] = e.p[1] = -1;
+	if(fd != nil){
+		pipe(e.p);
+		*fd = e.p[Us];
+	}
+	procrfork(pexec, &e, 4096, RFFDG);
+	recv(e.pid, &pid);
+	chanfree(e.pid);
+	if(fd != nil){
+		close(e.p[Them]);
+		if(pid < 0)
+			close(e.p[Us]);
+	}
+
+	return pid;
 }
--- a/pdf.h
+++ b/pdf.h
@@ -11,10 +11,10 @@
 };
 
 typedef struct Buffer Buffer;
-typedef struct D D;
 typedef struct Filter Filter;
-typedef struct Font Font;
 typedef struct GS GS;
+typedef struct GSD GSD;
+typedef struct GSFont GSFont;
 typedef struct KeyValue KeyValue;
 typedef struct Object Object;
 typedef struct Pdf Pdf;
@@ -30,6 +30,9 @@
 	int maxsz;
 	int sz;
 	int off;
+
+	/* get buffer contents as a memimage */
+	void *(*memimage)(Buffer *b);
 };
 
 struct Page {
@@ -92,13 +95,13 @@
 	Object *value;
 };
 
-struct D {
+struct GSD {
 	int *d;
 	int nd;
 	int phase;
 };
 
-struct Font {
+struct GSFont {
 	Object *font;
 	double size;
 };
@@ -108,11 +111,11 @@
 	int LW, LC, LJ, ML, RI, OP, op, OPM, SA, AIS, TK;
 	double SM, CA, ca;
 	struct {
-		Font *Font;
+		GSFont *Font;
 		int nFont;
 	};
 	struct {
-		D *d;
+		GSD *d;
 		int nd;
 	};
 };
@@ -192,6 +195,8 @@
 
 int isutf8(char *s, int len);
 
+int pipeexec(int *fd, char *file, char **argv);
+
 int arraylen(Object *o);
 Object *arraynew(Pdf *pdf);
 Object *arrayget(Object *o, int i);
@@ -218,6 +223,7 @@
 int Sgetd(Stream *s, double *d);
 int Sgeti(Stream *s, int *i);
 char *Srdstr(Stream *s, int delim, int zero);
+void *Sgetmemimage(Stream *s);
 int Slinelen(Stream *s);
 
 Filter *filteropen(char *name, Object *o);
@@ -229,6 +235,7 @@
 int flopenpredict(Filter *f, Object *o);
 void flclosepredict(Filter *f);
 
+void *buf2memimage(Buffer *b, char *prog, char **argv);
 void bufinit(Buffer *b, uchar *d, int sz);
 void buffree(Buffer *b);
 int bufeof(Buffer *b);
--- a/stream.c
+++ b/stream.c
@@ -185,6 +185,12 @@
 	return res;
 }
 
+void *
+Sgetmemimage(Stream *s)
+{
+	return s->buf.memimage != nil ? s->buf.memimage(&s->buf) : nil;
+}
+
 int
 Sseek(Stream *s, int off, int whence)
 {