如何使用apng补丁在libpng中执行'SKIP'/'SEEK'动作

时间:2015-01-06 02:44:50

标签: android png libpng apng

我正在尝试将libpng / apng移植到Android平台,使用带有apng补丁的libpng来读取动画png文件。

我的问题是我没有在png.h中找到任何'skip'方法。我想做的是直接跳转到特定的框架。但是除非我从头开始阅读并为前面的每一帧执行png_read_frame_head()和png_read_image(),否则我无法得到正确的结果。

有没有办法可以通过指定索引跳转到特定的帧而不读取所有的帧信息/数据?

以下代码来自apng sample http://littlesvr.ca/apng/tutorial/x57.html您可以看到它在循环中读取apng文件。而且您似乎必须调用png_read_frame_head()和png_read_image()才能使 png_ptr_read info_ptr_read 中的内部信息更新。所以,如果有任何方法可以简单地修改这两个结构来纠正为阅读特定框架而准备的信息,我的问题就解决了。

for(count = 0; count < png_get_num_frames(png_ptr_read, info_ptr_read); count++)
{
    sprintf(filename, "extracted-%02d.png", count);
    newImage = fopen(filename, "wb");
    if(newImage == NULL)
        fatalError("couldn't create png for writing");

    writeSetup(newImage, &png_ptr_write, &info_ptr_write);
    if(setjmp(png_ptr_write->jmpbuf))
        fatalError("something didn't work, jump 2");

    png_read_frame_head(png_ptr_read, info_ptr_read);

    if(png_get_valid(png_ptr_read, info_ptr_read, PNG_INFO_fcTL))
    {
        png_get_next_frame_fcTL(png_ptr_read, info_ptr_read,
                                &next_frame_width, &next_frame_height,
                                &next_frame_x_offset, &next_frame_y_offset,
                                &next_frame_delay_num, &next_frame_delay_den,
                                &next_frame_dispose_op, &next_frame_blend_op);
    }
    else
    {
        /* the first frame doesn't have an fcTL so it's expected to be hidden, 
        * but we'll extract it anyway */
        next_frame_width = png_get_image_width(png_ptr_read, info_ptr_read);
        next_frame_height = png_get_image_height(png_ptr_read, info_ptr_read);
    }

    writeSetup2(png_ptr_read, info_ptr_read, png_ptr_write, info_ptr_write,
                next_frame_width, next_frame_height);

    png_write_info(png_ptr_write, info_ptr_write);

    png_read_image(png_ptr_read, rowPointers);

    png_write_image(png_ptr_write, rowPointers);

    png_write_end(png_ptr_write, NULL);

    png_destroy_write_struct(&png_ptr_write, &info_ptr_write);

    fclose(newImage);

    printf("extracted frame %d into %s\n", count, filename);
}

1 个答案:

答案 0 :(得分:2)

你做不到。 libpng旨在将PNG数据视为流,因此它逐个按顺序解码块。不确定为什么你需要跳过APNG帧。就像在视频格式中一样,一帧可能存储为“在前一帧之后改变了什么”而不是全帧,因此您可能也需要先前的帧。

这些代码示例可能很有用: https://sourceforge.net/projects/apng/files/libpng/examples/