Как извлечь встроенные файлы из PDF с помощью MuPDF
Мое приложение на iOS извлекает встроенные файлы из PDF. Теперь я пытаюсь сделать приложение для Android с той же функциональностью, используя MuPDF.
На iOS я могу использовать Quartz2d для извлечения встроенных файлов:
- Доступ к корневому словарю PDF (
CGPDFDocumentGetCatalog
) - Получить массив файлов (Имена> EmbeddedFiles > Имена) и перебрать его
- Скопируйте содержимое потока файла из словаря файлов (EF > F) в
NSData
и сохрани это.
Есть ли способ сделать это с MuPDF?
1 ответ
Решение, основанное на pdfextact.c, похоже на bruteforce, но работает:
- перебрать все объекты pdf (
pdf_load_object
) - определить, является ли объект внедренным файлом (
isembed
) - если это так - получить доступ к его потоку и сохранить файл (
saveembed
)
В большинстве тестовых случаев встроенные файлы хранятся в конце файла, поэтому имеет смысл использовать обратную итерацию.
static int isembed(pdf_obj *obj) {
pdf_obj *type = pdf_dict_gets(obj, "Type");
return pdf_is_name(type) && !strcmp(pdf_to_name(type), "Filespec");
}
static void saveembed(pdf_obj *dict) {
char *filename;
pdf_obj *obj = pdf_dict_gets(dict, "F");
if (obj) filename = pdf_to_str_buf(obj);
obj = pdf_dict_gets(dict, "EF");
if (!obj) return;
pdf_obj *stream = pdf_dict_gets(obj, "F");
if (!stream) return;
FILE *f;
fz_buffer *buf;
int n, len;
unsigned char *data;
buf = pdf_load_stream(doc, pdf_to_num(stream), pdf_to_gen(stream));
printf("extracting embedded file %s\n", filename);
f = fopen(filename, "wb");
len = fz_buffer_storage(ctx, buf, &data);
n = fwrite(data, 1, len, f);
fclose(f);
fz_drop_buffer(ctx, buf);
}