libpng 源码的使用 第五节:简化用户接口

上一篇机器翻译完

libpng 源码的使用 第四节:写 (接口)

本篇开始翻译第五节,简化用户接口

简化的API(在libpng-1.6.0中可用)隐藏了libpng和PNG文件格式本身的详细信息。 它允许将PNG文件读取为非常有限的内存中位图格式,或从相同格式写入。 如果这些格式不能满足您的需求,那么您可以并且应该使用上面更复杂的API-这些API支持各种内存中格式以及对这些格式的各种复杂转换以及各种API 操纵辅助信息。

读取

要使用简化的API读取PNG文件,请执行以下操作:

1)在堆栈上声明一个'png_image'结构(请参见下文),将version字段设置为PNG_IMAGE_VERSION,

      并将'opaque'指针设置为NULL(这是必需的,如果不这样做,您的程序可能会崩溃。)

   2)调用适当的png_image_begin_read ...函数。

   3)将png_image'format'成员设置为所需的样本格式。

   4)为图像和颜色表(如果需要)分配一个缓冲区。

   5)调用png_image_finish_read读取图像,并在需要时将颜色图读取到缓冲区中。

对PNG输入本身的格式没有任何限制; 所有有效的颜色类型,位深度和隔行扫描方法都是可接受的,并且在png_image_finish_read()步骤期间,根据需要将输入图像转换为请求的内存格式。 唯一需要注意的是,如果您从全色PNG请求彩色映射图像或复杂地使用Alpha通道,则转换会造成极大的损失,并且结果可能看起来很糟糕。

写入

要使用简化的API写PNG文件,请执行以下操作:

1)在堆栈上声明一个“ png_image”结构,并将其memset()全部设为零。

   2)初始化描述图像的结构成员,将“格式”成员设置为图像样本的格式。

   3)调用适当的png_image_write ...函数,并带有指向图像的指针,并在必要时使用色图来写入PNG数据。

png_image是一种结构体,用于描述读取图像时的内存格式或定义您需要写入的图像的内存格式。

“ png_image”结构包含以下成员:

png_controlp opaque  Initialize to NULL, free with png_image_free
   png_uint_32  version Set to PNG_IMAGE_VERSION
   png_uint_32  width   Image width in pixels (columns)
   png_uint_32  height  Image height in pixels (rows)
   png_uint_32  format  Image format as defined below
   png_uint_32  flags   A bit mask containing informational flags
   png_uint_32  colormap_entries; Number of entries in the color-map
   png_uint_32  warning_or_error;
   char         message[64];

发生错误或警告时,“ warning_or_error”字段将设置为非零值,“ message”字段将包含带有libpng错误或警告消息的'\ 0'终止字符串。 如果同时遇到警告和错误,则仅记录错误。 如果有多个警告,则仅记录第一个。
“ warning_or_error”值的高30位被保留; 低两位包含两位代码,因此值大于1表示API刚刚调用失败:
    0-无警告或错误
    1-警告
    2-错误
    3-错误先于警告

图像的像素(样本)具有1-4个通道,其成分的原始值在0到1.0的范围内:
   1:单个灰色或亮度通道(G)。
   2:灰色/亮度通道和alpha通道(GA)。
   3:三个红色,绿色,蓝色通道(RGB)。
   4:三个颜色通道和一个alpha通道(RGBA)。

通道以以下两种方式之一进行编码:
  a)作为一个小整数,值0..255,包含在单个字节中。为了
alpha通道的原始值就是value / 255。对于颜色或亮度通道,该值根据sRGB规范进行编码,并与典型显示设备期望的8位格式匹配。
颜色/灰色通道不会被alpha通道缩放(预乘),并且适合传递给颜色管理软件。
  b)作为2字节整数中包含的0..65535范围内的值,
运行应用程序的平台的本机字节顺序。除以65535,可以将所有通道转换为原始值;所有通道都是线性的。色彩通道使用sRGB规范的RGB编码(RGB端点)。此编码由下面的PNG_FORMAT_FLAG_LINEAR标志标识。
当简化的API需要在sRGB和线性色彩空间之间转换时,将使用sRGB规范中定义的实际sRGB传输曲线(请参阅https://en.wikipedia.org/wiki/SRGB上的文章),而不是gamma = 1 /2.2近似值在libpng中的其他地方使用。
当存在Alpha通道时,它应表示颜色或亮度通道的像素覆盖率,并作为关联的Alpha通道返回:颜色/灰色通道被Alpha值缩放(预乘)。
样本要么直接包含在图像数据中,要么根据编码在每个像素1到8个字节之间,要么保存在以图像数据中的字节为索引的色彩映射表中。对于彩色图,彩色图条目是单独的样本,按上述方式编码,并且图像数据每像素有一个字节,可以从彩色图中选择相关样本。
PNG_FORMAT_ *

#defines 用于png_image :: format。

每个#define标识通道数据和alpha值(如果存在)的特定布局。两种分量编码中的每一种都有单独的定义。
使用单比特标志值建立格式。所有组合均有效。可以根据标志值建立格式,也可以使用以下预定义的值之一。当测试格式始终使用FORMAT_FLAG宏来测试单个功能时-库的未来版本可能会添加新标志。
在读取或写入色彩映射的图像时,应将格式设置为色彩图中的条目格式,然后调用png_image_ {read,write} _colormap来读取或写入色彩图,并正确设置图像数据的格式。不要直接设置PNG_FORMAT_FLAG_COLORMAP位!
注意:libpng可以在禁用特定功能的情况下构建。如果由于以下标志之一的定义已被编译而看到编译器错误,那是因为libpng没有所需的支持。但是,libpng配置有可能仅在读取或写入时启用该格式。在这种情况下,您可能会在运行时看到错误。您可以通过检查适当的“ _SUPPORTED”宏的定义来防止这种情况的发生,其中之一是:

   PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED

   PNG_FORMAT_FLAG_ALPHA    format with an alpha channel
   PNG_FORMAT_FLAG_COLOR    color format: otherwise grayscale
   PNG_FORMAT_FLAG_LINEAR   2-byte channels else 1-byte
   PNG_FORMAT_FLAG_COLORMAP image data is color-mapped
   PNG_FORMAT_FLAG_BGR      BGR colors, else order is RGB
   PNG_FORMAT_FLAG_AFIRST   alpha channel comes first

Supported formats are as follows.  Future versions of libpng may support more formats;
 for compatibility with older versions simply check if the format macro is defined 
using #ifdef.  These defines describe the in-memory layout of the components of 
the pixels of the image. 
First the single byte (sRGB) formats: 
   PNG_FORMAT_GRAY
   PNG_FORMAT_GA
   PNG_FORMAT_AG
   PNG_FORMAT_RGB
   PNG_FORMAT_BGR
   PNG_FORMAT_RGBA
   PNG_FORMAT_ARGB
   PNG_FORMAT_BGRA
   PNG_FORMAT_ABGR

Then the linear 2-byte formats.  When naming these "Y" is used to indicate 
a luminance (gray) channel.  The component order within the pixel is always 
the same - there is no provision for swapping the order of the components 
in the linear format.  The components are 16-bit integers in the native 
byte order for your platform, and there is no provision for swapping 
the bytes to a different endian condition. 
   PNG_FORMAT_LINEAR_Y
   PNG_FORMAT_LINEAR_Y_ALPHA
   PNG_FORMAT_LINEAR_RGB
   PNG_FORMAT_LINEAR_RGB_ALPHA

With color-mapped formats the image data is one byte for each pixel. 
The byte is an index into the color-map which is formatted as above.  
To obtain a color-mapped format it is sufficient just to add the 
PNG_FOMAT_FLAG_COLORMAP to one of the above definitions, 
or you can use one of the definitions below. 
   PNG_FORMAT_RGB_COLORMAP
   PNG_FORMAT_BGR_COLORMAP
   PNG_FORMAT_RGBA_COLORMAP
   PNG_FORMAT_ARGB_COLORMAP
   PNG_FORMAT_BGRA_COLORMAP
   PNG_FORMAT_ABGR_COLORMAP

PNG_IMAGE 宏

这些是方便宏,可从png_image结构中获取信息。 PNG_IMAGE_SAMPLE_宏返回适合于实际图像样本值的值-彩色图中的条目或图像中的像素。 PNG_IMAGE_PIXEL_宏返回像素的相应值,并且对于颜色映射格式将始终返回1。 其余的宏返回有关图像和完整图像中的行的信息。
注意:如果format参数本身是常量,则所有带有png_image :: format参数的宏都是编译时常量。 因此,这些宏可在需要时用于数组声明和大小写标签中。 同样,这些宏也是预处理器常量(未使用sizeof),因此可以在#if测试中使用它们。

  PNG_IMAGE_SAMPLE_CHANNELS(fmt)
    Returns the total number of channels in a given format: 1..4

  PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)
    Returns the size in bytes of a single component of a pixel or color-map
    entry (as appropriate) in the image: 1 or 2.

  PNG_IMAGE_SAMPLE_SIZE(fmt)
    This is the size of the sample data for one sample.  If the image is
    color-mapped it is the size of one color-map entry (and image pixels are
    one byte in size), otherwise it is the size of one image pixel.

  PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)
    The maximum size of the color-map required by the format expressed in a
    count of components.  This can be used to compile-time allocate a
    color-map:

    png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];

    png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];

    Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
    information from one of the png_image_begin_read_ APIs and dynamically
    allocate the required memory.

  PNG_IMAGE_COLORMAP_SIZE(fmt)
   The size of the color-map required by the format; this is the size of the
   color-map buffer passed to the png_image_{read,write}_colormap APIs. It is
   a fixed number determined by the format so can easily be allocated on the
   stack if necessary.

有关像素的相应信息

  PNG_IMAGE_PIXEL_CHANNELS(fmt)
   The number of separate channels (components) in a pixel; 1 for a
   color-mapped image.

  PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
   The size, in bytes, of each component in a pixel; 1 for a color-mapped
   image.

  PNG_IMAGE_PIXEL_SIZE(fmt)
   The size, in bytes, of a complete pixel; 1 for a color-mapped image.

有关整行或整个图像的信息

  PNG_IMAGE_ROW_STRIDE(image)
   Returns the total number of components in a single row of the image; this
   is the minimum 'row stride', the minimum count of components between each
   row.  For a color-mapped image this is the minimum number of bytes in a
   row.

   If you need the stride measured in bytes, row_stride_bytes is
   PNG_IMAGE_ROW_STRIDE(image) * PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)
   plus any padding bytes that your application might need, for example
   to start the next row on a 4-byte boundary.

  PNG_IMAGE_BUFFER_SIZE(image, row_stride)
   Return the size, in bytes, of an image buffer given a png_image and a row
   stride - the number of components to leave space for in each row.

  PNG_IMAGE_SIZE(image)
   Return the size, in bytes, of the image in memory given just a png_image;
   the row stride is the minimum stride required for the image.

  PNG_IMAGE_COLORMAP_SIZE(image)
   Return the size, in bytes, of the color-map of this image.  If the image
   format is not a color-map format this will return a size sufficient for
   256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if
   you don't want to allocate a color-map in this case.

PNG_IMAGE_FLAG_* 

包含有关图像的其他信息的标志保存在png_image的“标志”字段中。

  PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
    This indicates that the RGB values of the in-memory bitmap do not
    correspond to the red, green and blue end-points defined by sRGB.

  PNG_IMAGE_FLAG_FAST == 0x02
   On write emphasise speed over compression; the resultant PNG file will be
   larger but will be produced significantly faster, particular for large
   images.  Do not use this option for images which will be distributed, only
   used it when producing intermediate files that will be read back in
   repeatedly.  For a typical 24-bit image the option will double the read
   speed at the cost of increasing the image size by 25%, however for many
   more compressible images the PNG file can be 10 times larger with only a
   slight speed gain.

  PNG_IMAGE_FLAG_16BIT_sRGB == 0x04
    On read if the image is a 16-bit per component image and there is no gAMA
    or sRGB chunk assume that the components are sRGB encoded.  Notice that
    images output by the simplified API always have gamma information; setting
    this flag only affects the interpretation of 16-bit images from an
    external source.  It is recommended that the application expose this flag
    to the user; the user can normally easily recognize the difference between
    linear and sRGB encoding.  This flag has no effect on write - the data
    passed to the write APIs must have the correct encoding (as defined
    above.)

    If the flag is not set (the default) input 16-bit per component data is
    assumed to be linear.

    NOTE: the flag can only be set after the png_image_begin_read_ call,
    because that call initializes the 'flags' field.

READ API

传递给读取API的png_image必须已通过设置进行了初始化
    png_controlp字段“ opaque”为NULL(或者更好的是将整个过程设置为memset)。


   int png_image_begin_read_from_file( png_imagep image,
     const char *file_name)

     The named file is opened for read and the image header
     is filled in from the PNG header in the file.

   int png_image_begin_read_from_stdio (png_imagep image,
     FILE* file)

      The PNG header is read from the stdio FILE object.

   int png_image_begin_read_from_memory(png_imagep image,
      png_const_voidp memory, size_t size)

      The PNG header is read from the given memory buffer.

   int png_image_finish_read(png_imagep image,
      png_colorp background, void *buffer,
      png_int_32 row_stride, void *colormap));

      Finish reading the image into the supplied buffer and
      clean up the png_image structure.

      row_stride is the step, in png_byte or png_uint_16 units
      as appropriate, between adjacent rows.  A positive stride
      indicates that the top-most row is first in the buffer -
      the normal top-down arrangement.  A negative stride
      indicates that the bottom-most row is first in the buffer.

      background need only be supplied if an alpha channel must
      be removed from a png_byte format and the removal is to be
      done by compositing on a solid color; otherwise it may be
      NULL and any composition will be done directly onto the
      buffer.  The value is an sRGB color to use for the
      background, for grayscale output the green channel is used.

      For linear output removing the alpha channel is always done
      by compositing on black.

   void png_image_free(png_imagep image)

      Free any data allocated by libpng in image->opaque,
      setting the pointer to NULL.  May be called at any time
      after the structure is initialized.

当简化的API需要在sRGB和线性色彩空间之间转换时,将使用sRGB规范中定义的实际sRGB传输曲线(请参阅https://en.wikipedia.org/wiki/SRGB上的文章),而不是gamma = 1 /2.2近似值在libpng中的其他地方使用。

WRITE APIS 

为了进行写入,您必须初始化png_image结构来描述要写入的图像:

   version: must be set to PNG_IMAGE_VERSION
   opaque: must be initialized to NULL
   width: image width in pixels
   height: image height in rows
   format: the format of the data you wish to write
   flags: set to 0 unless one of the defined flags applies; set
      PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images
      where the RGB values do not correspond to the colors in sRGB.
   colormap_entries: set to the number of entries in the color-map (0 to 256)

   int png_image_write_to_file, (png_imagep image,
      const char *file, int convert_to_8bit, const void *buffer,
      png_int_32 row_stride, const void *colormap));

      Write the image to the named file.

   int png_image_write_to_memory (png_imagep image, void *memory,
      png_alloc_size_t * PNG_RESTRICT memory_bytes,
      int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride,
      const void *colormap));

      Write the image to memory.

   int png_image_write_to_stdio(png_imagep image, FILE *file,
      int convert_to_8_bit, const void *buffer,
      png_int_32 row_stride, const void *colormap)

      Write the image to the given (FILE*).

对于所有写入API,如果图像是具有(png_uint_16)数据的线性格式之一,则设置convert_to_8_bit将导致输出为根据sRGB规范编码的(png_byte)PNG伽玛,否则为16位线性编码的PNG文件 书面。
使用所有API时,row_stride的处理方式与读取API一样-以组件大小单位(浮点数)表示从一行到另一行的间距,如果为负,则表示缓冲区中的自底向上的行布局。 如果您传递零,libpng将根据通道的宽度和数量为您计算row_stride。
请注意,写入API不支持隔行扫描,低于8位的像素,索引(调色板)图像或大多数辅助块。

 

简化API翻译完成,下一篇是调整/自定义 libpng

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值