1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "fitz-base.h"
#include "fitz-stream.h"
#define noDEBUG 1
typedef struct fz_pipeline_s fz_pipeline;
fz_error * fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out);
struct fz_pipeline_s
{
fz_filter super;
fz_filter *head;
fz_buffer *buffer;
fz_filter *tail;
int tailneedsin;
};
fz_error *
fz_chainpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail, fz_buffer *buf)
{
FZ_NEWFILTER(fz_pipeline, p, pipeline);
p->head = fz_keepfilter(head);
p->tail = fz_keepfilter(tail);
p->tailneedsin = 1;
p->buffer = fz_keepbuffer(buf);
return nil;
}
void
fz_unchainpipeline(fz_filter *filter, fz_filter **oldfp, fz_buffer **oldbp)
{
fz_pipeline *p = (fz_pipeline*)filter;
*oldfp = fz_keepfilter(p->head);
*oldbp = fz_keepbuffer(p->buffer);
fz_dropfilter(filter);
}
fz_error *
fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail)
{
fz_error *error;
FZ_NEWFILTER(fz_pipeline, p, pipeline);
p->head = fz_keepfilter(head);
p->tail = fz_keepfilter(tail);
p->tailneedsin = 1;
error = fz_newbuffer(&p->buffer, FZ_BUFSIZE);
if (error) { fz_free(p); return error; }
return nil;
}
void
fz_droppipeline(fz_filter *filter)
{
fz_pipeline *p = (fz_pipeline*)filter;
fz_dropfilter(p->head);
fz_dropfilter(p->tail);
fz_dropbuffer(p->buffer);
}
fz_error *
fz_processpipeline(fz_filter *filter, fz_buffer *in, fz_buffer *out)
{
fz_pipeline *p = (fz_pipeline*)filter;
fz_error *e;
if (p->buffer->eof)
goto tail;
if (p->tailneedsin && p->head->produced)
goto tail;
head:
e = fz_process(p->head, in, p->buffer);
if (e == fz_ioneedin)
return fz_ioneedin;
else if (e == fz_ioneedout)
{
if (p->tailneedsin && !p->head->produced)
{
fz_error *be = nil;
if (p->buffer->rp > p->buffer->bp)
be = fz_rewindbuffer(p->buffer);
else
be = fz_growbuffer(p->buffer);
if (be)
return be;
goto head;
}
goto tail;
}
else if (e == fz_iodone)
goto tail;
else
return e;
tail:
e = fz_process(p->tail, p->buffer, out);
if (e == fz_ioneedin)
{
if (p->buffer->eof)
return fz_throw("ioerror: premature eof in pipeline");
p->tailneedsin = 1;
goto head;
}
else if (e == fz_ioneedout)
{
p->tailneedsin = 0;
return fz_ioneedout;
}
else if (e == fz_iodone)
return fz_iodone;
else
return e;
}
|