7 writestream(fz_stream
*out
, pdf_xref
*xref
, pdf_crypt
*encrypt
, int oid
, int gen
)
12 unsigned char buf
[4096];
16 fz_print(out
, "stream\n");
20 error
= pdf_cryptstream(&ef
, encrypt
, oid
, gen
);
24 error
= fz_openrfilter(&dststm
, ef
, out
);
31 dststm
= fz_keepstream(out
);
34 error
= pdf_openrawstream(&srcstm
, xref
, oid
, gen
);
40 n
= fz_read(srcstm
, buf
, sizeof buf
);
45 error
= fz_ioerror(srcstm
);
49 n
= fz_write(dststm
, buf
, n
);
52 error
= fz_ioerror(dststm
);
57 fz_dropstream(srcstm
);
58 fz_dropstream(dststm
);
60 fz_print(out
, "endstream\n");
65 fz_dropstream(srcstm
);
67 fz_dropstream(dststm
);
72 writeobject(fz_stream
*out
, pdf_xref
*xref
, pdf_crypt
*encrypt
, int oid
, int gen
)
74 pdf_xrefentry
*x
= xref
->table
+ oid
;
77 error
= pdf_cacheobject(xref
, oid
, gen
);
82 pdf_cryptobj(encrypt
, x
->obj
, oid
, gen
);
84 fz_print(out
, "%d %d obj\n", oid
, gen
);
85 fz_printobj(out
, x
->obj
, TIGHT
);
89 pdf_cryptobj(encrypt
, x
->obj
, oid
, gen
);
91 if (pdf_isstream(xref
, oid
, gen
))
93 error
= writestream(out
, xref
, encrypt
, oid
, gen
);
98 fz_print(out
, "endobj\n\n");
103 static int countmodified(pdf_xref
*xref
, int oid
)
106 for (i
= oid
; i
< xref
->len
; i
++)
107 if (xref
->table
[i
].type
!= 'a' && xref
->table
[i
].type
!= 'd')
113 pdf_updatexref(pdf_xref
*xref
, char *path
)
122 pdf_logxref("updatexref '%s' %p\n", path
, xref
);
124 error
= fz_openafile(&out
, path
);
130 for (oid
= 0; oid
< xref
->len
; oid
++)
132 if (xref
->table
[oid
].type
== 'a')
134 xref
->table
[oid
].ofs
= fz_tell(out
);
135 error
= writeobject(out
, xref
, xref
->crypt
, oid
, xref
->table
[oid
].gen
);
141 /* always write out entry 0 in appended xref sections */
142 xref
->table
[0].type
= 'd';
144 startxref
= fz_tell(out
);
145 fz_print(out
, "xref\n");
148 while (oid
< xref
->len
)
150 n
= countmodified(xref
, oid
);
152 pdf_logxref(" section %d +%d\n", oid
, n
);
154 fz_print(out
, "%d %d\n", oid
, n
);
156 for (i
= 0; i
< n
; i
++)
158 if (xref
->table
[oid
+ i
].type
== 'd')
159 xref
->table
[oid
+ i
].type
= 'f';
160 if (xref
->table
[oid
+ i
].type
== 'a')
161 xref
->table
[oid
+ i
].type
= 'n';
163 fz_print(out
, "%010d %05d %c \n",
164 xref
->table
[oid
+ i
].ofs
,
165 xref
->table
[oid
+ i
].gen
,
166 xref
->table
[oid
+ i
].type
);
170 while (oid
< xref
->len
&&
171 xref
->table
[oid
].type
!= 'a' &&
172 xref
->table
[oid
].type
!= 'd')
178 fz_print(out
, "trailer\n<<\n /Size %d\n /Prev %d", xref
->len
, xref
->startxref
);
180 obj
= fz_dictgets(xref
->trailer
, "Root");
181 fz_print(out
,"\n /Root %d %d R", fz_tonum(obj
), fz_togen(obj
));
183 obj
= fz_dictgets(xref
->trailer
, "Info");
185 fz_print(out
,"\n /Info %d %d R", fz_tonum(obj
), fz_togen(obj
));
187 obj
= fz_dictgets(xref
->trailer
, "Encrypt");
189 fz_print(out
,"\n /Encrypt ");
190 fz_printobj(out
, obj
, TIGHT
);
193 obj
= fz_dictgets(xref
->trailer
, "ID");
195 fz_print(out
,"\n /ID ");
196 fz_printobj(out
, obj
, TIGHT
);
199 fz_print(out
, "\n>>\n\n");
201 fz_print(out
, "startxref\n");
202 fz_print(out
, "%d\n", startxref
);
203 fz_print(out
, "%%%%EOF\n");
205 xref
->startxref
= startxref
;
216 pdf_savexref(pdf_xref
*xref
, char *path
, pdf_crypt
*encrypt
)
226 pdf_logxref("savexref '%s' %p\n", path
, xref
);
228 /* need to add encryption object for acrobat < 6 */
231 pdf_logxref("make encryption dict\n");
233 error
= pdf_allocobject(xref
, &eoid
, &egen
);
237 pdf_cryptobj(encrypt
, encrypt
->encrypt
, eoid
, egen
);
239 error
= pdf_updateobject(xref
, eoid
, egen
, encrypt
->encrypt
);
244 ofsbuf
= fz_malloc(sizeof(int) * xref
->len
);
248 error
= fz_openwfile(&out
, path
);
255 fz_print(out
, "%%PDF-%1.1f\n", xref
->version
);
256 fz_print(out
, "%%\342\343\317\323\n\n");
258 for (oid
= 0; oid
< xref
->len
; oid
++)
260 pdf_xrefentry
*x
= xref
->table
+ oid
;
261 if (x
->type
== 'n' || x
->type
== 'o' || x
->type
== 'a')
263 ofsbuf
[oid
] = fz_tell(out
);
264 error
= writeobject(out
, xref
, encrypt
, oid
, x
->type
== 'o' ? 0 : x
->gen
);
270 ofsbuf
[oid
] = x
->ofs
;
274 startxref
= fz_tell(out
);
275 fz_print(out
, "xref\n");
276 fz_print(out
, "0 %d\n", xref
->len
);
278 for (oid
= 0; oid
< xref
->len
; oid
++)
280 int gen
= xref
->table
[oid
].gen
;
281 int type
= xref
->table
[oid
].type
;
284 if (type
== 'a' || type
== 'o')
288 fz_print(out
, "%010d %05d %c \n", ofsbuf
[oid
], gen
, type
);
293 fz_print(out
, "trailer\n<<\n /Size %d", xref
->len
);
294 obj
= fz_dictgets(xref
->trailer
, "Root");
295 fz_print(out
, "\n /Root %d %d R", fz_tonum(obj
), fz_togen(obj
));
296 obj
= fz_dictgets(xref
->trailer
, "Info");
298 fz_print(out
, "\n /Info %d %d R", fz_tonum(obj
), fz_togen(obj
));
301 fz_print(out
, "\n /Encrypt %d %d R", eoid
, egen
);
302 fz_print(out
, "\n /ID [");
303 fz_printobj(out
, encrypt
->id
, 1);
304 fz_printobj(out
, encrypt
->id
, 1);
307 pdf_cryptobj(encrypt
, encrypt
->encrypt
, eoid
, egen
);
309 fz_print(out
, "\n>>\n\n");
311 fz_print(out
, "startxref\n");
312 fz_print(out
, "%d\n", startxref
);
313 fz_print(out
, "%%%%EOF\n");
315 xref
->startxref
= startxref
;
317 if(ofsbuf
) fz_free(ofsbuf
);
322 if(ofsbuf
) fz_free(ofsbuf
);