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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
#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 fz_okay;
}
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);
error = fz_newbuffer(&p->buffer, FZ_BUFSIZE);
if (error)
{
fz_free(p);
return fz_rethrow(error, "cannot create buffer");
}
p->head = fz_keepfilter(head);
p->tail = fz_keepfilter(tail);
p->tailneedsin = 1;
return fz_okay;
}
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 = fz_okay;
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 if (e)
return fz_rethrow(e, "cannot process head filter");
else
return fz_okay;
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)
{
/* Make sure that the head is also done.
* It may still contain end-of-data markers or garbage.
*/
e = fz_process(p->head, in, p->buffer);
if (e != fz_iodone)
fz_catch(e, "head filter not done");
return fz_iodone;
}
else if (e)
return fz_rethrow(e, "cannot process tail filter");
else
return fz_okay;
}
|