上层读取接口(用户主要使用的接口) 前面都是一些配置接口,到此主要内容才开始,接上篇
在这一点上,有两种方法可以进行: 通过高级读取接口,或通过一系列低级读取操作。 如果(a)您愿意将整个图像读入内存,并且(b)您要进行的输入转换限于以下设置,则可以使用高级接口:
PNG_TRANSFORM_IDENTITY No transformation
PNG_TRANSFORM_SCALE_16 Strip 16-bit samples to
8-bit accurately
PNG_TRANSFORM_STRIP_16 Chop 16-bit samples to
8-bit less accurately
PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel
PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit
samples to bytes
PNG_TRANSFORM_PACKSWAP Change order of packed
pixels to LSB first
PNG_TRANSFORM_EXPAND Perform set_expand()
PNG_TRANSFORM_INVERT_MONO Invert monochrome images
PNG_TRANSFORM_SHIFT Normalize pixels to the
sBIT depth
PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA
to BGRA
PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA
to AG
PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity
to transparency
PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples
PNG_TRANSFORM_GRAY_TO_RGB Expand grayscale samples
to RGB (or GA to RGBA)
PNG_TRANSFORM_EXPAND_16 Expand samples to 16 bits
(这不包括设置背景色,进行伽玛变换,量化和设置填充物。)如果是这种情况,只需执行以下操作:
png_read_png(png_ptr, info_ptr, png_transforms, NULL)
其中png_transforms是一个整数,其中包含一些转换标志集的按位或。 此调用等效于png_read_info(),后跟转换掩码指示的一组转换,
然后是png_read_image(),最后是png_read_end()。
(此调用的最终参数尚未使用。总有一天,它可能指向某些将来的输入转换所需的转换参数。)
使用png_read_png()时,必须使用png_transforms且不能调用任何png_set_transform()函数。
调用png_read_png()之后,您可以使用
row_pointers = png_get_rows(png_ptr, info_ptr);
其中row_pointers是指向每行像素数据的指针的数组:
png_bytep row_pointers[height];
如果您提前知道图像大小和像素大小,则可以在调用png_read_png()之前分配row_pointers
if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))
png_error (png_ptr,
"Image is too tall to process in memory");
if (width > PNG_UINT_32_MAX/pixel_size)
png_error (png_ptr,
"Image is too wide to process in memory");
row_pointers = png_malloc(png_ptr,
height*(sizeof (png_bytep)));
for (int i=0; i<height, i++)
row_pointers[i]=NULL; /* security precaution */
for (int i=0; i<height, i++)
row_pointers[i]=png_malloc(png_ptr,
width*pixel_size);
png_set_rows(png_ptr, info_ptr, &row_pointers);
或者,您可以在一个大块中分配映像,并定义row_pointers [i]指向块中的正确位置,但是首先请确保平台能够分配这么大的缓冲区:
/* Guard against integer overflow */
if (height > PNG_SIZE_MAX/(width*pixel_size)) {
png_error(png_ptr,"image_data buffer would be too large");
}
png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
for (int i=0; i<height, i++)
row_pointers[i]=buffer+i*width*pixel_size;
png_set_rows(png_ptr, info_ptr, &row_pointers);
如果使用png_set_rows(),则应用程序负责释放row_pointers(和row_pointers [i](如果分别分配))。
如果您不提前分配row_pointers,则png_read_png()会这样做,并且当您调用png_destroy _ *()时,libpng将释放它。
翻译到1222页,下一篇是底层读接口