Как извлечь встроенные файлы из PDF с помощью MuPDF

Мое приложение на iOS извлекает встроенные файлы из PDF. Теперь я пытаюсь сделать приложение для Android с той же функциональностью, используя MuPDF.

На iOS я могу использовать Quartz2d для извлечения встроенных файлов:

  1. Доступ к корневому словарю PDF (CGPDFDocumentGetCatalog)
  2. Получить массив файлов (Имена> EmbeddedFiles > Имена) и перебрать его
  3. Скопируйте содержимое потока файла из словаря файлов (EF > F) в NSData и сохрани это.

Есть ли способ сделать это с MuPDF?

1 ответ

Решение, основанное на pdfextact.c, похоже на bruteforce, но работает:

  1. перебрать все объекты pdf (pdf_load_object)
  2. определить, является ли объект внедренным файлом (isembed)
  3. если это так - получить доступ к его потоку и сохранить файл (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);
}
Другие вопросы по тегам