You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MuPDF(C语言)解析PDF Pages数组Kids条目时,解析后的对象显示为unknown的问题

MuPDF(C语言)解析PDF Pages数组Kids条目时,解析后的对象显示为unknown的问题

我来帮你排查这个问题哈,结合你提供的代码和现象,咱们从几个常见的方向入手分析:

一、先检查pdf_print_obj的参数和输出对象是否正确

你当前调用pdf_print_obj时用的是自己传入的out对象,如果这个输出对象没有正确初始化(比如没有关联到标准输出),或者参数设置不对,都可能导致打印异常。

你可以先把输出对象替换为MuPDF提供的标准输出fz_stdout(ctx),同时调整print_raw参数(最后一个参数)试试:

// 替换原打印代码为:
pdf_print_obj(ctx, fz_stdout(ctx), direct_obj, 0, 0);
  • fz_stdout(ctx)是MuPDF封装的标准输出流,能保证输出正常;
  • 最后一个参数设为0时,会以格式化的方式打印对象,而不是原始字节,避免加密或特殊格式的对象被识别为unknown。

二、解析后的对象可能是PDF页/页节点字典,pdf_print_obj对这类特殊对象有处理逻辑

PDF的Kids数组里的条目本质是页节点(Pages)或页对象(Page),它们都是PDF字典类型。但pdf_print_obj默认可能不会直接打印这类特殊字典的完整内容,而是需要我们手动遍历字典的键值对来查看:

你可以在拿到direct_obj后,先判断它是不是字典,然后手动遍历打印:

if (pdf_is_dict(ctx, direct_obj)) {
    printf("  这是一个PDF字典对象(页/页节点):\n");
    int dict_len = pdf_dict_len(ctx, direct_obj);
    for (int j=0; j<dict_len; j++) {
        pdf_obj *key = pdf_dict_get_key(ctx, direct_obj, j);
        pdf_obj *val = pdf_dict_get_val(ctx, direct_obj, j);
        printf("    ");
        pdf_print_obj(ctx, fz_stdout(ctx), key, 0, 1);
        printf(": ");
        pdf_print_obj(ctx, fz_stdout(ctx), val, 0, 1);
        printf("\n");
    }
}

这样就能绕过pdf_print_obj的特殊处理,直接看到字典里的实际内容。

三、尝试用pdf_load_obj替代pdf_resolve_indirect加载间接对象

你当前用的pdf_resolve_indirect只是返回间接对象的引用,而pdf_load_obj会真正加载对象的完整内容,对于某些特殊的PDF结构,这个方法的解析更可靠:

// 替换原解析代码:
pdf_obj *direct_obj = pdf_load_obj(ctx, cur_item_obj);

注意这个返回的对象同样需要用pdf_drop_obj释放,和你之前的逻辑一致。

四、关于你提到的kind=221的问题

这个数值明显超出了MuPDF公开的pdf_obj类型枚举范围(标准类型一般在0~20之间),这是因为你直接访问了pdf_obj结构体的内部私有成员——MuPDF的内部结构体字段是不对外公开的,这些数值可能是结构体的其他字段干扰值,或者是版本私有扩展,完全不能用来判断对象类型。你应该始终用MuPDF提供的公开API(比如pdf_is_dict、pdf_is_array等)来判断对象类型。

最后给你一个修改后的代码示例,整合了上面的优化点:

void print_pages_array_recurs(fz_output* out, fz_context* ctx, pdf_obj* array_obj, int level) {
    bool is_array = pdf_is_array(ctx, array_obj);
    if (!is_array) {
        printf("---------not array !!!!!!!!!!!!!\n");
        return;
    }

    int n = pdf_array_len(ctx, array_obj);
    printf("===Array total elements: %d \n", n);

    // 使用MuPDF标准输出流,避免自定义out的问题
    fz_output *std_out = fz_stdout(ctx);

    for (int i = 0; i < n; i++) {
        pdf_obj* cur_item_obj = pdf_array_get(ctx, array_obj, i);

        // 打印原始间接引用
        printf(" %d.[%d]: ", level, i);
        pdf_print_obj(ctx, std_out, cur_item_obj, 0, 1);
        printf("\n");

        bool cur_indirect = pdf_is_indirect(ctx, cur_item_obj);
        if (cur_indirect) {
            // 用pdf_load_obj加载完整对象
            pdf_obj* direct_obj = pdf_load_obj(ctx, cur_item_obj);
            if (!direct_obj) {
                printf("  加载间接对象失败!\n");
                continue;
            }

            printf("__解析后的直接对象:\n");
            // 按对象类型分别处理
            if (pdf_is_dict(ctx, direct_obj)) {
                printf("  类型:PDF字典(页/页节点)\n");
                int dict_len = pdf_dict_len(ctx, direct_obj);
                for (int j=0; j<dict_len; j++) {
                    pdf_obj *key = pdf_dict_get_key(ctx, direct_obj, j);
                    pdf_obj *val = pdf_dict_get_val(ctx, direct_obj, j);
                    printf("    ");
                    pdf_print_obj(ctx, std_out, key, 0, 1);
                    printf(": ");
                    pdf_print_obj(ctx, std_out, val, 0, 1);
                    printf("\n");
                }
            } else if (pdf_is_array(ctx, direct_obj)) {
                printf("  类型:PDF数组\n");
                pdf_print_obj(ctx, std_out, direct_obj, 2, 0);
            } else {
                // 其他基础类型直接打印
                pdf_print_obj(ctx, std_out, direct_obj, 2, 0);
            }
            printf("\n");

            pdf_drop_obj(ctx, direct_obj);
        }
    }
    printf("\n");
}

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 10:37:59