如何使用MuPDF从pdf中提取嵌入文件

时间:2013-01-24 14:43:25

标签: android pdf mupdf

我在iOS上的应用程序从PDF中提取嵌入文件。现在,我尝试使用MuPDF制作具有相同功能的Android应用。

在iOS上,我可以使用Quartz2d来提取嵌入文件:

  1. 访问根PDF PDF词典(CGPDFDocumentGetCatalog
  2. 获取文件数组(名称> EmbeddedFiles>名称)并通过它进行删除
  3. 将文件流内容从文件字典(EF> F)复制到NSData并保存。
  4. 有没有办法用MuPDF做到这一点?

1 个答案:

答案 0 :(得分:1)

基于pdfextact.c的解决方案看起来像bruteforce,但它可以工作:

  1. 透过所有pdf对象(pdf_load_object
  2. 确定对象是否为嵌入文件(isembed
  3. 如果是 - 访问它的流并保存文件(saveembed
  4. 在大多数测试用例中存储在文件末尾的嵌入文件,因此,反复迭代会使这种情况发生。

    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);
    }