Leptonica  1.82.0
Image processing and image analysis suite
pngio.c File Reference
#include <string.h>
#include "allheaders.h"
#include "png.h"
#include "zlib.h"

Go to the source code of this file.

Data Structures

struct  MemIOData
 

Macros

#define DEBUG_READ   0
 
#define DEBUG_WRITE   0
 

Typedefs

typedef struct MemIOData MEMIODATA
 

Functions

PIXpixReadStreamPng (FILE *fp)
 
l_ok readHeaderPng (const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
 
l_ok freadHeaderPng (FILE *fp, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
 
l_ok readHeaderMemPng (const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
 
l_int32 fgetPngResolution (FILE *fp, l_int32 *pxres, l_int32 *pyres)
 
l_ok isPngInterlaced (const char *filename, l_int32 *pinterlaced)
 
l_ok fgetPngColormapInfo (FILE *fp, PIXCMAP **pcmap, l_int32 *ptransparency)
 
l_ok pixWritePng (const char *filename, PIX *pix, l_float32 gamma)
 
l_ok pixWriteStreamPng (FILE *fp, PIX *pix, l_float32 gamma)
 
l_ok pixSetZlibCompression (PIX *pix, l_int32 compval)
 
void l_pngSetReadStrip16To8 (l_int32 flag)
 
static void memio_png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
 
static void memio_png_flush (MEMIODATA *pthing)
 
static void memio_png_read_data (png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead)
 
static void memio_free (MEMIODATA *pthing)
 
PIXpixReadMemPng (const l_uint8 *filedata, size_t filesize)
 
l_ok pixWriteMemPng (l_uint8 **pfiledata, size_t *pfilesize, PIX *pix, l_float32 gamma)
 

Variables

static l_int32 var_PNG_STRIP_16_TO_8 = 1
 
static const l_int32 MEMIO_BUFFER_SIZE = 8192
 

Detailed Description

   Reading png through stream
         PIX        *pixReadStreamPng()
   Reading png header
         l_int32     readHeaderPng()
         l_int32     freadHeaderPng()
         l_int32     readHeaderMemPng()
   Reading png metadata
         l_int32     fgetPngResolution()
         l_int32     isPngInterlaced()
         l_int32     fgetPngColormapInfo()
   Writing png through stream
         l_int32     pixWritePng()  [ special top level ]
         l_int32     pixWriteStreamPng()
         l_int32     pixSetZlibCompression()
   Set flag for special read mode
         void        l_pngSetReadStrip16To8()
   Low-level memio utility (thanks to T. D. Hintz)
         static void memio_png_write_data()
         static void memio_png_flush()
         static void memio_png_read_data()
         static void memio_free()
   Reading png from memory
         PIX        *pixReadMemPng()
   Writing png to memory
         l_int32     pixWriteMemPng()
   Documentation: libpng.txt and example.c
   On input (decompression from file), palette color images
   are read into an 8 bpp Pix with a colormap, and 24 bpp
   3 component color images are read into a 32 bpp Pix with
   rgb samples.  On output (compression to file), palette color
   images are written as 8 bpp with the colormap, and 32 bpp
   full color images are written compressed as a 24 bpp,
   3 component color image.
   In the following, we use these abbreviations:
      bps == bit/sample
      spp == samples/pixel
      bpp == bits/pixel of image in Pix (memory)
   where each component is referred to as a "sample".
   For reading and writing rgb and rgba images, we read and write
   alpha if it exists (spp == 4) and do not read or write if
   it doesn't (spp == 3).  The alpha component can be 'removed'
   simply by setting spp to 3.  In leptonica, we make relatively
   little explicit use of the alpha sample.  Note that the alpha
   sample in the image is also called "alpha transparency",
   "alpha component" and "alpha layer."
   To change the zlib compression level, use pixSetZlibCompression()
   before writing the file.  The default is for standard png compression.
   The zlib compression value can be set [0 ... 9], with
        0     no compression (huge files)
        1     fastest compression
        -1    default compression  (equivalent to 6 in latest version)
        9     best compression
   Note that if you are using the defined constants in zlib instead
   of the compression integers given above, you must include zlib.h.
   There is global for determining the size of retained samples:
            var_PNG_STRIP_16_to_8
   and a function l_pngSetReadStrip16To8() for setting it.
   The default is TRUE, which causes pixRead() to strip each 16 bit
   sample down to 8 bps:
    ~ For 16 bps rgb (16 bps, 3 spp) --> 32 bpp rgb Pix
    ~ For 16 bps gray (16 bps, 1 spp) --> 8 bpp grayscale Pix
   If the variable is set to FALSE, the 16 bit gray samples
   are saved when read; the 16 bit rgb samples return an error.
   Note: results can be non-deterministic if used with
   multi-threaded applications.
   Thanks to a memory buffering utility contributed by T. D. Hintz,
   encoding png directly into memory (and decoding from memory)
   is now enabled without the use of any temp files.  Unlike with webp,
   it is necessary to preserve the stream interface to enable writing
   pixa to memory.  So there are two independent but very similar
   implementations of png reading and writing.

Definition in file pngio.c.

Function Documentation

◆ freadHeaderPng()

l_ok freadHeaderPng ( FILE *  fp,
l_int32 *  pw,
l_int32 *  ph,
l_int32 *  pbps,
l_int32 *  pspp,
l_int32 *  piscmap 
)

freadHeaderPng()

Parameters
[in]fpfile stream
[out]pw[optional]
[out]ph[optional]
[out]pbps[optional] bits/sample
[out]pspp[optional] samples/pixel
[out]piscmap[optional]
Returns
0 if OK, 1 on error
Notes:
     (1) See readHeaderPng().  We only need the first 40 bytes in the file.

Definition at line 619 of file pngio.c.

References fnbytesInFile(), PixMemoryStore::nbytes, and readHeaderMemPng().

Referenced by readHeaderPng().

◆ isPngInterlaced()

l_ok isPngInterlaced ( const char *  filename,
l_int32 *  pinterlaced 
)

isPngInterlaced()

Parameters
[in]filename
[out]pinterlaced1 if interlaced png; 0 otherwise
Returns
0 if OK, 1 on error

Definition at line 827 of file pngio.c.

References fopenReadStream().

◆ l_pngSetReadStrip16To8()

void l_pngSetReadStrip16To8 ( l_int32  flag)

l_pngSetReadStrip16To8()

Parameters
[in]flag1 for stripping 16 bpp to 8 bpp on reading; 0 for leaving 16 bpp
Returns
void

Definition at line 1352 of file pngio.c.

◆ memio_png_write_data()

static void memio_png_write_data ( png_structp  png_ptr,
png_bytep  data,
png_size_t  len 
)
static

buffer alloc size

Definition at line 1404 of file pngio.c.

References MemIOData::m_Buffer, and MemIOData::m_Last.

◆ pixReadMemPng()

PIX* pixReadMemPng ( const l_uint8 *  filedata,
size_t  filesize 
)

pixReadMemPng()

Parameters
[in]filedatapng compressed data in memory
[in]filesizenumber of bytes in data
Returns
pix, or NULL on error
Notes:
     (1) See pixReastreamPng().

Definition at line 1595 of file pngio.c.

References MemIOData::m_Buffer, MemIOData::m_Count, MemIOData::m_Last, MemIOData::m_Next, and MemIOData::m_Size.

◆ pixReadStreamPng()

PIX* pixReadStreamPng ( FILE *  fp)

pixReadStreamPng()

Parameters
[in]fpfile stream
Returns
pix, or NULL on error
Notes:
     (1) If called from pixReadStream(), the stream is positioned
         at the beginning of the file.
     (2) To do sequential reads of png format images from a stream,
         use pixReadStreamPng()
     (3) All images with alpha is converted to RGBA (spp = 4, with
         equal red, green and blue channels) on reading.
         There are three cases with alpha:
         (a) RGBA: spp = 4.  The alpha value is the fourth byte
             (aka "channel, "component") in each 4-byte pixel.
         (b) grayscale-with-alpha (spp = 2), where bpp = 8, and each
             pixel has an associated alpha (transparency) value
             in the second component of the image data.
         (c) colormap (spp = 1) with alpha in the trans palette.
             d = 1, 2, 4, 8.  The trans palette in writing is derived
             from the alpha components in the cmap.  Transparency is
             often associated with a white background.
     (4) We use the high level png interface, where the transforms are set
         up in advance and the header and image are read with a single
         call.  The more complicated interface, where the header is
         read first and the buffers for the raster image are user-
         allocated before reading the image, works for single images,
         but I could not get it to work properly for the successive
         png reads that are required by pixaReadStream().

Definition at line 187 of file pngio.c.

◆ pixSetZlibCompression()

l_ok pixSetZlibCompression ( PIX pix,
l_int32  compval 
)

pixSetZlibCompression()

Parameters
[in]pix
[in]compvalzlib compression value
Returns
0 if OK, 1 on error
Notes:
     (1) Valid zlib compression values are in the interval [0 ... 9],
         where, as defined in zlib.h:
           0         Z_NO_COMPRESSION
           1         Z_BEST_SPEED    (poorest compression)
           9         Z_BEST_COMPRESSION
         For the default value, use either of these:
           6         Z_DEFAULT_COMPRESSION
          -1         (resolves to Z_DEFAULT_COMPRESSION)
     (2) If you use the defined constants in zlib.h instead of the
         compression integers given above, you must include zlib.h.

Definition at line 1325 of file pngio.c.

◆ pixWriteMemPng()

l_ok pixWriteMemPng ( l_uint8 **  pfiledata,
size_t *  pfilesize,
PIX pix,
l_float32  gamma 
)

pixWriteMemPng()

Parameters
[out]pfiledatapng encoded data of pix
[out]pfilesizesize of png encoded data
[in]pix
[in]gammause 0.0 if gamma is not defined
Returns
0 if OK; 1 on error
Notes:
     (1) See pixWriteStreamPng()

Definition at line 1986 of file pngio.c.

References MemIOData::m_Buffer, MemIOData::m_Count, MemIOData::m_Last, MemIOData::m_Next, and MemIOData::m_Size.

◆ pixWritePng()

l_ok pixWritePng ( const char *  filename,
PIX pix,
l_float32  gamma 
)

pixWritePng()

Parameters
[in]filename
[in]pix
[in]gamma
Returns
0 if OK; 1 on error
Notes:
     (1) Special version for writing png with a specified gamma.
         When using pixWrite(), no field is given for gamma.

Definition at line 972 of file pngio.c.

References fopenWriteStream(), and pixWriteStreamPng().

◆ pixWriteStreamPng()

l_ok pixWriteStreamPng ( FILE *  fp,
PIX pix,
l_float32  gamma 
)

pixWriteStreamPng()

Parameters
[in]fpfile stream
[in]pix
[in]gammause 0.0 if gamma is not defined
Returns
0 if OK; 1 on error
Notes:
     (1) If called from pixWriteStream(), the stream is positioned
         at the beginning of the file.
     (2) To do sequential writes of png format images to a stream,
         use pixWriteStreamPng() directly.
     (3) gamma is an optional png chunk.  If no gamma value is to be
         placed into the file, use gamma = 0.0.  Otherwise, if
         gamma > 0.0, its value is written into the header.
     (4) The use of gamma in png is highly problematic.  For an illuminating
         discussion, see:  http://hsivonen.iki.fi/png-gamma/
     (5) What is the effect/meaning of gamma in the png file?  This
         gamma, which we can call the 'source' gamma, is the
         inverse of the gamma that was used in enhance.c to brighten
         or darken images.  The 'source' gamma is supposed to indicate
         the intensity mapping that was done at the time the
         image was captured.  Display programs typically apply a
         'display' gamma of 2.2 to the output, which is intended
         to linearize the intensity based on the response of
         thermionic tubes (CRTs).  Flat panel LCDs have typically
         been designed to give a similar response as CRTs (call it
         "backward compatibility").  The 'display' gamma is
         in some sense the inverse of the 'source' gamma.
         jpeg encoders attached to scanners and cameras will lighten
         the pixels, applying a gamma corresponding to approximately
         a square-root relation of output vs input:
               output = input^(gamma)
         where gamma is often set near 0.4545  (1/gamma is 2.2).
         This is stored in the image file.  Then if the display
         program reads the gamma, it will apply a display gamma,
         typically about 2.2; the product is 1.0, and the
         display program produces a linear output.  This works because
         the dark colors were appropriately boosted by the scanner,
         as described by the 'source' gamma, so they should not
         be further boosted by the display program.
     (6) As an example, with xv and display, if no gamma is stored,
         the program acts as if gamma were 0.4545, multiplies this by 2.2,
         and does a linear rendering.  Taking this as a baseline
         brightness, if the stored gamma is:
             > 0.4545, the image is rendered lighter than baseline
             < 0.4545, the image is rendered darker than baseline
         In contrast, gqview seems to ignore the gamma chunk in png.
     (7) The only valid pixel depths in leptonica are 1, 2, 4, 8, 16
         and 32.  However, it is possible, and in some cases desirable,
         to write out a png file using an rgb pix that has 24 bpp.
         For example, the open source xpdf SplashBitmap class generates
         24 bpp rgb images.  Consequently, we enable writing 24 bpp pix.
         To generate such a pix, you can make a 24 bpp pix without data
         and assign the data array to the pix; e.g.,
             pix = pixCreateHeader(w, h, 24);
             pixSetData(pix, rgbdata);
         See pixConvert32To24() for an example, where we get rgbdata
         from the 32 bpp pix.  Caution: do not call pixSetPadBits(),
         because the alignment is wrong and you may erase part of the
         last pixel on each line.
     (8) If the pix has a colormap, it is written to file.  In most
         situations, the alpha component is 255 for each colormap entry,
         which is opaque and indicates that it should be ignored.
         However, if any alpha component is not 255, it is assumed that
         the alpha values are valid, and they are written to the png
         file in a tRNS segment.  On readback, the tRNS segment is
         identified, and the colormapped image with alpha is converted
         to a 4 spp rgba image.

Definition at line 1072 of file pngio.c.

Referenced by pixaWriteStream(), and pixWritePng().

◆ readHeaderMemPng()

l_ok readHeaderMemPng ( const l_uint8 *  data,
size_t  size,
l_int32 *  pw,
l_int32 *  ph,
l_int32 *  pbps,
l_int32 *  pspp,
l_int32 *  piscmap 
)

readHeaderMemPng()

Parameters
[in]data
[in]size40 bytes is sufficient
[out]pw[optional]
[out]ph[optional]
[out]pbps[optional] bits/sample
[out]pspp[optional] samples/pixel
[out]piscmap[optional] input NULL to ignore
Returns
0 if OK, 1 on error
Notes:
     (1) See readHeaderPng().
     (2) png colortypes (see png.h: PNG_COLOR_TYPE_*):
         0:  gray; fully transparent (with tRNS) (1 spp)
         2:  RGB (3 spp)
         3:  colormap; colormap+alpha (with tRNS) (1 spp)
         4:  gray + alpha (2 spp)
         6:  RGBA (4 spp)
         Note:
           0 and 3 have the alpha information in a tRNS chunk
           4 and 6 have separate alpha samples with each pixel.

Definition at line 676 of file pngio.c.

Referenced by freadHeaderPng().

◆ readHeaderPng()

l_ok readHeaderPng ( const char *  filename,
l_int32 *  pw,
l_int32 *  ph,
l_int32 *  pbps,
l_int32 *  pspp,
l_int32 *  piscmap 
)

readHeaderPng()

Parameters
[in]filename
[out]pw[optional]
[out]ph[optional]
[out]pbps[optional] bits/sample
[out]pspp[optional] samples/pixel
[out]piscmap[optional]
Returns
0 if OK, 1 on error
Notes:
     (1) If there is a colormap, iscmap is returned as 1; else 0.
     (2) For gray+alpha, although the png records bps = 16, we
         consider this as two 8 bpp samples (gray and alpha).
         When a gray+alpha is read, it is converted to 32 bpp RGBA.

Definition at line 575 of file pngio.c.

References fopenReadStream(), and freadHeaderPng().