ref: 14a773539df70e5fe32c31979abf032eba58ecf4
parent: 2d3fd9732381d95ebc7e6ba8e38dfa7addce77e3
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
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)
{