0

似乎在使用 libpng 解码 PNG 文件时,它不会读取最后 16 个字节,所以我向前寻找 16 个字节以到达结尾。我可以假设所有 PNG 文件都是如此吗?

#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
#include<png.h>
int fd;
void png_read(png_struct *png,png_byte *data,png_size_t len){
  read(fd,data,len);
}
int main(void){
  fd=open("foo.png",O_RDONLY);
  png_struct *png=png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
  png_info *png_info=png_create_info_struct(png);
  png_set_read_fn(png,0,png_read);
  struct stat s;
  fstat(fd,&s);
  printf("File Size: %d\n",s.st_size);
  png_read_info(png,png_info);
  int x=png_get_image_width(png,png_info);
  int y=png_get_image_height(png,png_info);
  int c=png_get_channels(png,png_info);
  char *buf=malloc(x*y*c);
  char **row=malloc(sizeof(*row)*y);
  {
    int i=0;
    while(i<y){
      row[i]=buf+x*i*c;
      i++;
    }
  }
  png_read_image(png,(png_byte**)row);
  printf("Ending File Position: %d\n",lseek(fd,0,SEEK_CUR));
  return(0);
}

.

File Size: 20279  
Ending File Position: 20263
4

2 回答 2

4

在 png_read_image 之后,从技术上讲,您应该有一个 png_read_end 调用:

// ...
png_read_image(png,(png_byte**)row);

png_infop end_info = png_create_info_struct(png);
png_read_end(png, end_info);

之后位置应该匹配。

不过,即使是libpng 文档(第 13.7 节的最后几段)也显得没有必要。

于 2011-04-20T03:26:13.533 回答
1

仅当您对 PNG 之外的其余数据流感兴趣时才有必要(kaykun 就是!)。但是,如果您只想到达 PNG 的末尾并且不关心剩余 PNG 块的内容,正如参考书所说,您可以使用 NULL 而不是 end_info (因此不需要创建end_info 结构)。您不能指望 PNG 文件的其余部分正好是 16 个字节。如果 PNG 恰好在最后一个 IDAT 块之后包含文本块,将会有更多。

于 2011-04-20T22:16:01.450 回答