libpng 源码的使用 第三节:读 (续3 上层读取接口(用户主要使用的接口))

上层读取接口(用户主要使用的接口) 前面都是一些配置接口,到此主要内容才开始,接上篇

libpng 源码的使用 第三节:读 (续2)

在这一点上,有两种方法可以进行: 通过高级读取接口,或通过一系列低级读取操作。 如果(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页,下一篇是底层读接口

猜你喜欢

转载自blog.csdn.net/catshit322/article/details/114783813