iPXE
Data Structures | Functions | Variables
png.c File Reference

Portable Network Graphics (PNG) format. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/umalloc.h>
#include <ipxe/pixbuf.h>
#include <ipxe/deflate.h>
#include <ipxe/png.h>

Go to the source code of this file.

Data Structures

struct  png_context
 PNG context. More...
 
struct  png_interlace
 A PNG interlace pass. More...
 
struct  png_filter
 A PNG filter. More...
 
struct  png_chunk_handler
 A PNG chunk handler. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static const char * png_type_name (uint32_t type)
 Transcribe PNG chunk type name (for debugging) More...
 
static void png_interlace (struct png_context *png, unsigned int pass, struct png_interlace *interlace)
 Calculate PNG interlace pass parameters. More...
 
static unsigned int png_pixel_len (struct png_context *png)
 Calculate PNG pixel length. More...
 
static size_t png_scanline_len (struct png_context *png, struct png_interlace *interlace)
 Calculate PNG scanline length. More...
 
static int png_image_header (struct image *image, struct png_context *png, size_t len)
 Handle PNG image header chunk. More...
 
static int png_palette (struct image *image, struct png_context *png, size_t len)
 Handle PNG palette chunk. More...
 
static int png_image_data (struct image *image, struct png_context *png, size_t len)
 Handle PNG image data chunk. More...
 
static unsigned int png_unfilter_none (unsigned int current, unsigned int left __unused, unsigned int above __unused, unsigned int above_left __unused)
 Unfilter byte using the "None" filter. More...
 
static unsigned int png_unfilter_sub (unsigned int current, unsigned int left, unsigned int above __unused, unsigned int above_left __unused)
 Unfilter byte using the "Sub" filter. More...
 
static unsigned int png_unfilter_up (unsigned int current, unsigned int left __unused, unsigned int above, unsigned int above_left __unused)
 Unfilter byte using the "Up" filter. More...
 
static unsigned int png_unfilter_average (unsigned int current, unsigned int left, unsigned int above, unsigned int above_left __unused)
 Unfilter byte using the "Average" filter. More...
 
static unsigned int png_paeth_predictor (unsigned int a, unsigned int b, unsigned int c)
 Paeth predictor function (defined in RFC 2083) More...
 
static unsigned int png_unfilter_paeth (unsigned int current, unsigned int left, unsigned int above, unsigned int above_left)
 Unfilter byte using the "Paeth" filter. More...
 
static int png_unfilter_pass (struct image *image, struct png_context *png, struct png_interlace *interlace)
 Unfilter one interlace pass of PNG raw data. More...
 
static int png_unfilter (struct image *image, struct png_context *png)
 Unfilter PNG raw data. More...
 
static unsigned int png_pixel (unsigned int raw, unsigned int alpha, unsigned int max)
 Calculate PNG pixel component value. More...
 
static void png_pixels_pass (struct image *image, struct png_context *png, struct png_interlace *interlace)
 Fill one interlace pass of PNG pixels. More...
 
static void png_pixels (struct image *image, struct png_context *png)
 Fill PNG pixels. More...
 
static int png_image_end (struct image *image, struct png_context *png, size_t len)
 Handle PNG image end chunk. More...
 
static int png_chunk (struct image *image, struct png_context *png, uint32_t type, size_t len)
 Handle PNG chunk. More...
 
static int png_pixbuf (struct image *image, struct pixel_buffer **pixbuf)
 Convert PNG image to pixel buffer. More...
 
static int png_probe (struct image *image)
 Probe PNG image. More...
 
struct image_type png_image_type __image_type (PROBE_NORMAL)
 PNG image type. More...
 

Variables

static struct png_signature png_signature = PNG_SIGNATURE
 PNG file signature. More...
 
static uint8_t png_interlace_passes []
 Number of interlacing passes. More...
 
static struct png_filter png_filters []
 PNG filter types. More...
 
static struct png_chunk_handler png_chunk_handlers []
 PNG chunk handlers. More...
 

Detailed Description

Portable Network Graphics (PNG) format.

The PNG format is defined in RFC 2083.

Definition in file png.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ png_type_name()

static const char* png_type_name ( uint32_t  type)
static

Transcribe PNG chunk type name (for debugging)

Parameters
typeChunk type
Return values
nameChunk type name

Definition at line 101 of file png.c.

101  {
102  static union {
103  uint32_t type;
104  char name[ sizeof ( uint32_t ) + 1 /* NUL */ ];
105  } u;
106 
107  u.type = type;
108  return u.name;
109 }
const char * name
Definition: ath9k_hw.c:1984
unsigned int uint32_t
Definition: stdint.h:12
uint32_t type
Operating system type.
Definition: ena.h:12
union @17 u

References name, type, and u.

Referenced by png_chunk().

◆ png_interlace()

static void png_interlace ( struct png_context png,
unsigned int  pass,
struct png_interlace interlace 
)
static

Calculate PNG interlace pass parameters.

Parameters
pngPNG context
passPass number (0=first pass)
interlaceInterlace pass to fill in

Definition at line 118 of file png.c.

119  {
120  unsigned int grid_width_log2;
121  unsigned int grid_height_log2;
122  unsigned int x_indent;
123  unsigned int y_indent;
124  unsigned int x_stride_log2;
125  unsigned int y_stride_log2;
126  unsigned int x_stride;
127  unsigned int y_stride;
128  unsigned int width;
129  unsigned int height;
130 
131  /* Sanity check */
132  assert ( png->passes > 0 );
133 
134  /* Store pass number */
135  interlace->pass = pass;
136 
137  /* Calculate interlace grid dimensions */
138  grid_width_log2 = ( png->passes / 2 );
139  grid_height_log2 = ( ( png->passes - 1 ) / 2 );
140 
141  /* Calculate starting indents */
142  interlace->x_indent = x_indent =
143  ( ( pass & 1 ) ?
144  ( 1 << ( grid_width_log2 - ( pass / 2 ) - 1 ) ) : 0 );
145  interlace->y_indent = y_indent =
146  ( ( pass && ! ( pass & 1 ) ) ?
147  ( 1 << ( grid_height_log2 - ( ( pass - 1 ) / 2 ) - 1 ) ) : 0);
148 
149  /* Calculate strides */
150  x_stride_log2 = ( grid_width_log2 - ( pass / 2 ) );
151  y_stride_log2 =
152  ( grid_height_log2 - ( pass ? ( ( pass - 1 ) / 2 ) : 0 ) );
153  interlace->x_stride = x_stride = ( 1 << x_stride_log2 );
154  interlace->y_stride = y_stride = ( 1 << y_stride_log2 );
155 
156  /* Calculate pass dimensions */
157  width = png->pixbuf->width;
158  height = png->pixbuf->height;
159  interlace->width =
160  ( ( width - x_indent + x_stride - 1 ) >> x_stride_log2 );
161  interlace->height =
162  ( ( height - y_indent + y_stride - 1 ) >> y_stride_log2 );
163 }
unsigned int x_indent
X starting indent.
Definition: png.c:73
unsigned int height
Height.
Definition: pixbuf.h:23
unsigned int y_stride
Y stride.
Definition: png.c:79
unsigned int pass
Pass number.
Definition: png.c:71
unsigned int width
Width.
Definition: png.c:81
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int x_stride
X stride.
Definition: png.c:77
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:49
unsigned int passes
Number of interlace passes.
Definition: png.c:58
unsigned int height
Height.
Definition: png.c:83
unsigned int y_indent
Y starting indent.
Definition: png.c:75
unsigned int width
Width.
Definition: pixbuf.h:21

References assert(), pixel_buffer::height, png_interlace::height, png_interlace::pass, png_context::passes, png_context::pixbuf, pixel_buffer::width, png_interlace::width, png_interlace::x_indent, png_interlace::x_stride, png_interlace::y_indent, and png_interlace::y_stride.

Referenced by png_image_header(), png_pixels(), and png_unfilter().

◆ png_pixel_len()

static unsigned int png_pixel_len ( struct png_context png)
static

Calculate PNG pixel length.

Parameters
pngPNG context
Return values
pixel_lenPixel length

Definition at line 171 of file png.c.

171  {
172 
173  return ( ( ( png->channels * png->depth ) + 7 ) / 8 );
174 }
unsigned int depth
Bit depth.
Definition: png.c:52
unsigned int channels
Number of channels.
Definition: png.c:56

References png_context::channels, and png_context::depth.

Referenced by png_unfilter_pass().

◆ png_scanline_len()

static size_t png_scanline_len ( struct png_context png,
struct png_interlace interlace 
)
static

Calculate PNG scanline length.

Parameters
pngPNG context
interlaceInterlace pass
Return values
scanline_lenScanline length (including filter byte)

Definition at line 183 of file png.c.

184  {
185 
186  return ( 1 /* Filter byte */ +
187  ( ( interlace->width * png->channels * png->depth ) + 7 ) / 8);
188 }
unsigned int width
Width.
Definition: png.c:81
unsigned int depth
Bit depth.
Definition: png.c:52
unsigned int channels
Number of channels.
Definition: png.c:56

References png_context::channels, png_context::depth, and png_interlace::width.

Referenced by png_image_header(), and png_unfilter_pass().

◆ png_image_header()

static int png_image_header ( struct image image,
struct png_context png,
size_t  len 
)
static

Handle PNG image header chunk.

Parameters
imagePNG image
pngPNG context
lenChunk length
Return values
rcReturn status code

Definition at line 198 of file png.c.

199  {
200  struct png_image_header ihdr;
201  struct png_interlace interlace;
202  unsigned int pass;
203 
204  /* Sanity check */
205  if ( len != sizeof ( ihdr ) ) {
206  DBGC ( image, "PNG %s invalid IHDR length %zd\n",
207  image->name, len );
208  return -EINVAL;
209  }
210  if ( png->pixbuf ) {
211  DBGC ( image, "PNG %s duplicate IHDR\n", image->name );
212  return -EINVAL;
213  }
214 
215  /* Extract image header */
216  copy_from_user ( &ihdr, image->data, png->offset, len );
217  DBGC ( image, "PNG %s %dx%d depth %d type %d compression %d filter %d "
218  "interlace %d\n", image->name, ntohl ( ihdr.width ),
219  ntohl ( ihdr.height ), ihdr.depth, ihdr.colour_type,
220  ihdr.compression, ihdr.filter, ihdr.interlace );
221 
222  /* Sanity checks */
223  if ( ihdr.compression >= PNG_COMPRESSION_UNKNOWN ) {
224  DBGC ( image, "PNG %s unknown compression method %d\n",
225  image->name, ihdr.compression );
226  return -ENOTSUP;
227  }
228  if ( ihdr.filter >= PNG_FILTER_UNKNOWN ) {
229  DBGC ( image, "PNG %s unknown filter method %d\n",
230  image->name, ihdr.filter );
231  return -ENOTSUP;
232  }
233  if ( ihdr.interlace >= PNG_INTERLACE_UNKNOWN ) {
234  DBGC ( image, "PNG %s unknown interlace method %d\n",
235  image->name, ihdr.interlace );
236  return -ENOTSUP;
237  }
238 
239  /* Allocate pixel buffer */
240  png->pixbuf = alloc_pixbuf ( ntohl ( ihdr.width ),
241  ntohl ( ihdr.height ) );
242  if ( ! png->pixbuf ) {
243  DBGC ( image, "PNG %s could not allocate pixel buffer\n",
244  image->name );
245  return -ENOMEM;
246  }
247 
248  /* Extract bit depth */
249  png->depth = ihdr.depth;
250  if ( ( png->depth == 0 ) ||
251  ( ( png->depth & ( png->depth - 1 ) ) != 0 ) ) {
252  DBGC ( image, "PNG %s invalid depth %d\n",
253  image->name, png->depth );
254  return -EINVAL;
255  }
256 
257  /* Calculate number of channels */
258  png->colour_type = ihdr.colour_type;
259  png->channels = 1;
260  if ( ! ( ihdr.colour_type & PNG_COLOUR_TYPE_PALETTE ) ) {
261  if ( ihdr.colour_type & PNG_COLOUR_TYPE_RGB )
262  png->channels += 2;
263  if ( ihdr.colour_type & PNG_COLOUR_TYPE_ALPHA )
264  png->channels += 1;
265  }
266 
267  /* Calculate number of interlace passes */
268  png->passes = png_interlace_passes[ihdr.interlace];
269 
270  /* Calculate length of raw data buffer */
271  for ( pass = 0 ; pass < png->passes ; pass++ ) {
272  png_interlace ( png, pass, &interlace );
273  if ( interlace.width == 0 )
274  continue;
275  png->raw.len += ( interlace.height *
276  png_scanline_len ( png, &interlace ) );
277  }
278 
279  /* Allocate raw data buffer */
280  png->raw.data = umalloc ( png->raw.len );
281  if ( ! png->raw.data ) {
282  DBGC ( image, "PNG %s could not allocate data buffer\n",
283  image->name );
284  return -ENOMEM;
285  }
286 
287  return 0;
288 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
RGB colour is used.
Definition: png.h:101
struct pixel_buffer * alloc_pixbuf(unsigned int width, unsigned int height)
Allocate pixel buffer.
Definition: pixbuf.c:58
userptr_t data
Raw file image.
Definition: image.h:41
static size_t png_scanline_len(struct png_context *png, struct png_interlace *interlace)
Calculate PNG scanline length.
Definition: png.c:183
Alpha channel is used.
Definition: png.h:103
size_t offset
Offset within image.
Definition: png.c:46
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
#define ntohl(value)
Definition: byteswap.h:134
An executable image.
Definition: image.h:24
unsigned int pass
Pass number.
Definition: png.c:71
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
unsigned int depth
Bit depth.
Definition: png.c:52
First unknown filter method.
Definition: png.h:122
A PNG image header.
Definition: png.h:79
#define ENOMEM
Not enough space.
Definition: errno.h:534
A PNG interlace pass.
Definition: png.c:69
Palette is used.
Definition: png.h:99
unsigned int colour_type
Colour type.
Definition: png.c:54
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:49
uint32_t len
Length.
Definition: ena.h:14
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
static uint8_t png_interlace_passes[]
Number of interlacing passes.
Definition: png.c:90
First unknown interlace method.
Definition: png.h:132
First unknown compression method.
Definition: png.h:114
unsigned int passes
Number of interlace passes.
Definition: png.c:58
userptr_t data
Data.
Definition: deflate.h:243
static void png_interlace(struct png_context *png, unsigned int pass, struct png_interlace *interlace)
Calculate PNG interlace pass parameters.
Definition: png.c:118
unsigned int channels
Number of channels.
Definition: png.c:56
char * name
Name.
Definition: image.h:34
size_t len
Length of data.
Definition: deflate.h:247

References alloc_pixbuf(), png_context::channels, png_context::colour_type, png_image_header::colour_type, png_image_header::compression, copy_from_user(), image::data, deflate_chunk::data, DBGC, png_context::depth, png_image_header::depth, EINVAL, ENOMEM, ENOTSUP, png_image_header::filter, png_interlace::height, png_image_header::height, png_image_header::interlace, len, deflate_chunk::len, image::name, ntohl, png_context::offset, png_interlace::pass, png_context::passes, png_context::pixbuf, PNG_COLOUR_TYPE_ALPHA, PNG_COLOUR_TYPE_PALETTE, PNG_COLOUR_TYPE_RGB, PNG_COMPRESSION_UNKNOWN, PNG_FILTER_UNKNOWN, png_interlace(), png_interlace_passes, PNG_INTERLACE_UNKNOWN, png_scanline_len(), png_context::raw, umalloc(), png_image_header::width, and png_interlace::width.

◆ png_palette()

static int png_palette ( struct image image,
struct png_context png,
size_t  len 
)
static

Handle PNG palette chunk.

Parameters
imagePNG image
pngPNG context
lenChunk length
Return values
rcReturn status code

Definition at line 298 of file png.c.

299  {
300  size_t offset = png->offset;
301  struct png_palette_entry palette;
302  unsigned int i;
303 
304  /* Populate palette */
305  for ( i = 0 ; i < ( sizeof ( png->palette ) /
306  sizeof ( png->palette[0] ) ) ; i++ ) {
307 
308  /* Stop when we run out of palette data */
309  if ( len < sizeof ( palette ) )
310  break;
311 
312  /* Extract palette entry */
313  copy_from_user ( &palette, image->data, offset,
314  sizeof ( palette ) );
315  png->palette[i] = ( ( palette.red << 16 ) |
316  ( palette.green << 8 ) |
317  ( palette.blue << 0 ) );
318  DBGC2 ( image, "PNG %s palette entry %d is %#06x\n",
319  image->name, i, png->palette[i] );
320 
321  /* Move to next entry */
322  offset += sizeof ( palette );
323  len -= sizeof ( palette );
324  }
325 
326  return 0;
327 }
uint32_t palette[PNG_PALETTE_COUNT]
Palette, in iPXE's pixel buffer format.
Definition: png.c:60
userptr_t data
Raw file image.
Definition: image.h:41
size_t offset
Offset within image.
Definition: png.c:46
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
An executable image.
Definition: image.h:24
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
A PNG palette entry.
Definition: png.h:139
char * name
Name.
Definition: image.h:34

References png_palette_entry::blue, copy_from_user(), image::data, DBGC2, png_palette_entry::green, len, image::name, png_context::offset, offset, png_context::palette, and png_palette_entry::red.

◆ png_image_data()

static int png_image_data ( struct image image,
struct png_context png,
size_t  len 
)
static

Handle PNG image data chunk.

Parameters
imagePNG image
pngPNG context
lenChunk length
Return values
rcReturn status code

Definition at line 337 of file png.c.

338  {
339  struct deflate_chunk in;
340  int rc;
341 
342  /* Deflate this chunk */
343  deflate_chunk_init ( &in, image->data, png->offset,
344  ( png->offset + len ) );
345  if ( ( rc = deflate_inflate ( &png->deflate, &in, &png->raw ) ) != 0 ) {
346  DBGC ( image, "PNG %s could not decompress: %s\n",
347  image->name, strerror ( rc ) );
348  return rc;
349  }
350 
351  return 0;
352 }
int deflate_inflate(struct deflate *deflate, struct deflate_chunk *in, struct deflate_chunk *out)
Inflate compressed data.
Definition: deflate.c:492
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
__be32 in[4]
Definition: CIB_PRM.h:35
size_t offset
Offset within image.
Definition: png.c:46
#define DBGC(...)
Definition: compiler.h:505
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
A chunk of data.
Definition: deflate.h:241
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct deflate deflate
Decompressor.
Definition: png.c:65
uint32_t len
Length.
Definition: ena.h:14
char * name
Name.
Definition: image.h:34

References image::data, DBGC, png_context::deflate, deflate_inflate(), in, len, image::name, png_context::offset, png_context::raw, rc, and strerror().

◆ png_unfilter_none()

static unsigned int png_unfilter_none ( unsigned int  current,
unsigned int left  __unused,
unsigned int above  __unused,
unsigned int above_left  __unused 
)
static

Unfilter byte using the "None" filter.

Parameters
currentFiltered current byte
leftUnfiltered left byte
aboveUnfiltered above byte
above_leftUnfiltered above-left byte
Return values
currentUnfiltered current byte

Definition at line 363 of file png.c.

366  {
367 
368  return current;
369 }

◆ png_unfilter_sub()

static unsigned int png_unfilter_sub ( unsigned int  current,
unsigned int  left,
unsigned int above  __unused,
unsigned int above_left  __unused 
)
static

Unfilter byte using the "Sub" filter.

Parameters
currentFiltered current byte
leftUnfiltered left byte
aboveUnfiltered above byte
above_leftUnfiltered above-left byte
Return values
currentUnfiltered current byte

Definition at line 380 of file png.c.

383  {
384 
385  return ( current + left );
386 }

◆ png_unfilter_up()

static unsigned int png_unfilter_up ( unsigned int  current,
unsigned int left  __unused,
unsigned int  above,
unsigned int above_left  __unused 
)
static

Unfilter byte using the "Up" filter.

Parameters
currentFiltered current byte
leftUnfiltered left byte
aboveUnfiltered above byte
above_leftUnfiltered above-left byte
Return values
currentUnfiltered current byte

Definition at line 397 of file png.c.

400  {
401 
402  return ( current + above );
403 }

◆ png_unfilter_average()

static unsigned int png_unfilter_average ( unsigned int  current,
unsigned int  left,
unsigned int  above,
unsigned int above_left  __unused 
)
static

Unfilter byte using the "Average" filter.

Parameters
currentFiltered current byte
leftUnfiltered left byte
aboveUnfiltered above byte
above_leftUnfiltered above-left byte
Return values
currentUnfiltered current byte

Definition at line 414 of file png.c.

417  {
418 
419  return ( current + ( ( above + left ) >> 1 ) );
420 }

◆ png_paeth_predictor()

static unsigned int png_paeth_predictor ( unsigned int  a,
unsigned int  b,
unsigned int  c 
)
static

Paeth predictor function (defined in RFC 2083)

Parameters
aPixel A
bPixel B
cPixel C
Return values
predictorPredictor pixel

Definition at line 430 of file png.c.

431  {
432  unsigned int p;
433  unsigned int pa;
434  unsigned int pb;
435  unsigned int pc;
436 
437  /* Algorithm as defined in RFC 2083 section 6.6 */
438  p = ( a + b - c );
439  pa = abs ( p - a );
440  pb = abs ( p - b );
441  pc = abs ( p - c );
442  if ( ( pa <= pb ) && ( pa <= pc ) ) {
443  return a;
444  } else if ( pb <= pc ) {
445  return b;
446  } else {
447  return c;
448  }
449 }
uint32_t c
Definition: md4.c:30
uint32_t a
Definition: md4.c:28
#define abs(x)
Definition: ath.h:44
uint32_t b
Definition: md4.c:29

References a, abs, b, and c.

Referenced by png_unfilter_paeth().

◆ png_unfilter_paeth()

static unsigned int png_unfilter_paeth ( unsigned int  current,
unsigned int  left,
unsigned int  above,
unsigned int  above_left 
)
static

Unfilter byte using the "Paeth" filter.

Parameters
currentFiltered current byte
above_leftUnfiltered above-left byte
aboveUnfiltered above byte
leftUnfiltered left byte
Return values
currentUnfiltered current byte

Definition at line 460 of file png.c.

463  {
464 
465  return ( current + png_paeth_predictor ( left, above, above_left ) );
466 }
static unsigned int png_paeth_predictor(unsigned int a, unsigned int b, unsigned int c)
Paeth predictor function (defined in RFC 2083)
Definition: png.c:430

References png_paeth_predictor().

◆ png_unfilter_pass()

static int png_unfilter_pass ( struct image image,
struct png_context png,
struct png_interlace interlace 
)
static

Unfilter one interlace pass of PNG raw data.

Parameters
imagePNG image
pngPNG context
interlaceInterlace pass
Return values
rcReturn status code

This routine may assume that it is impossible to overrun the raw data buffer, since the size is determined by the image dimensions.

Definition at line 505 of file png.c.

506  {
507  size_t offset = png->raw.offset;
508  size_t pixel_len = png_pixel_len ( png );
509  size_t scanline_len = png_scanline_len ( png, interlace );
510  struct png_filter *filter;
511  unsigned int scanline;
512  unsigned int byte;
513  uint8_t filter_type;
514  uint8_t left;
515  uint8_t above;
516  uint8_t above_left;
517  uint8_t current;
518 
519  /* On the first scanline of a pass, above bytes are assumed to
520  * be zero.
521  */
522  above = 0;
523 
524  /* Iterate over each scanline in turn */
525  for ( scanline = 0 ; scanline < interlace->height ; scanline++ ) {
526 
527  /* Extract filter byte and determine filter type */
528  copy_from_user ( &filter_type, png->raw.data, offset++,
529  sizeof ( filter_type ) );
530  if ( filter_type >= ( sizeof ( png_filters ) /
531  sizeof ( png_filters[0] ) ) ) {
532  DBGC ( image, "PNG %s unknown filter type %d\n",
533  image->name, filter_type );
534  return -ENOTSUP;
535  }
536  filter = &png_filters[filter_type];
537  assert ( filter->unfilter != NULL );
538  DBGC2 ( image, "PNG %s pass %d scanline %d filter type %d\n",
539  image->name, interlace->pass, scanline, filter_type );
540 
541  /* At the start of a line, both above-left and left
542  * bytes are taken to be zero.
543  */
544  left = 0;
545  above_left = 0;
546 
547  /* Iterate over each byte (not pixel) in turn */
548  for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
549 
550  /* Extract predictor bytes, if applicable */
551  if ( byte >= pixel_len ) {
552  copy_from_user ( &left, png->raw.data,
553  ( offset - pixel_len ),
554  sizeof ( left ) );
555  }
556  if ( scanline > 0 ) {
557  copy_from_user ( &above, png->raw.data,
558  ( offset - scanline_len ),
559  sizeof ( above ) );
560  }
561  if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
562  copy_from_user ( &above_left, png->raw.data,
563  ( offset - scanline_len -
564  pixel_len ),
565  sizeof ( above_left ) );
566  }
567 
568  /* Unfilter current byte */
569  copy_from_user ( &current, png->raw.data,
570  offset, sizeof ( current ) );
571  current = filter->unfilter ( current, left, above,
572  above_left );
573  copy_to_user ( png->raw.data, offset++,
574  &current, sizeof ( current ) );
575  }
576  }
577 
578  /* Update offset */
579  png->raw.offset = offset;
580 
581  return 0;
582 }
static size_t png_scanline_len(struct png_context *png, struct png_interlace *interlace)
Calculate PNG scanline length.
Definition: png.c:183
UINT8_t filter
Receive packet filter.
Definition: pxe_api.h:68
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
unsigned int pass
Pass number.
Definition: png.c:71
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
A PNG filter.
Definition: png.c:469
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
unsigned char uint8_t
Definition: stdint.h:10
size_t offset
Current offset.
Definition: deflate.h:245
unsigned char byte
Definition: smc9000.h:38
static struct png_filter png_filters[]
PNG filter types.
Definition: png.c:486
#define DBGC2(...)
Definition: compiler.h:522
userptr_t data
Data.
Definition: deflate.h:243
static unsigned int png_pixel_len(struct png_context *png)
Calculate PNG pixel length.
Definition: png.c:171
char * name
Name.
Definition: image.h:34
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
unsigned int height
Height.
Definition: png.c:83

References assert(), copy_from_user(), copy_to_user(), deflate_chunk::data, DBGC, DBGC2, ENOTSUP, filter, png_interlace::height, image::name, NULL, deflate_chunk::offset, offset, png_interlace::pass, png_filters, png_pixel_len(), png_scanline_len(), and png_context::raw.

Referenced by png_unfilter().

◆ png_unfilter()

static int png_unfilter ( struct image image,
struct png_context png 
)
static

Unfilter PNG raw data.

Parameters
imagePNG image
pngPNG context
Return values
rcReturn status code

This routine may assume that it is impossible to overrun the raw data buffer, since the size is determined by the image dimensions.

Definition at line 594 of file png.c.

594  {
595  struct png_interlace interlace;
596  unsigned int pass;
597  int rc;
598 
599  /* Process each interlace pass */
600  png->raw.offset = 0;
601  for ( pass = 0 ; pass < png->passes ; pass++ ) {
602 
603  /* Calculate interlace pass parameters */
604  png_interlace ( png, pass, &interlace );
605 
606  /* Skip zero-width rows (which have no filter bytes) */
607  if ( interlace.width == 0 )
608  continue;
609 
610  /* Unfilter this pass */
611  if ( ( rc = png_unfilter_pass ( image, png,
612  &interlace ) ) != 0 )
613  return rc;
614  }
615  assert ( png->raw.offset == png->raw.len );
616 
617  return 0;
618 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
unsigned int pass
Pass number.
Definition: png.c:71
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A PNG interlace pass.
Definition: png.c:69
size_t offset
Current offset.
Definition: deflate.h:245
static int png_unfilter_pass(struct image *image, struct png_context *png, struct png_interlace *interlace)
Unfilter one interlace pass of PNG raw data.
Definition: png.c:505
unsigned int passes
Number of interlace passes.
Definition: png.c:58
static void png_interlace(struct png_context *png, unsigned int pass, struct png_interlace *interlace)
Calculate PNG interlace pass parameters.
Definition: png.c:118
size_t len
Length of data.
Definition: deflate.h:247

References assert(), deflate_chunk::len, deflate_chunk::offset, png_interlace::pass, png_context::passes, png_interlace(), png_unfilter_pass(), png_context::raw, rc, and png_interlace::width.

Referenced by png_image_end().

◆ png_pixel()

static unsigned int png_pixel ( unsigned int  raw,
unsigned int  alpha,
unsigned int  max 
)
inlinestatic

Calculate PNG pixel component value.

Parameters
rawRaw component value
alphaAlpha value
maxMaximum raw/alpha value
Return values
valueComponent value in range 0-255

Definition at line 628 of file png.c.

629  {
630 
631  /* The basic calculation is 255*(raw/max)*(value/max). We use
632  * fixed-point arithmetic (scaling up to the maximum range for
633  * a 32-bit integer), in order to get the same results for
634  * alpha blending as the test cases (produced using
635  * ImageMagick).
636  */
637  return ( ( ( ( ( 0xff00 * raw * alpha ) / max ) / max ) + 0x80 ) >> 8 );
638 }
#define max(x, y)
Definition: ath.h:39
__be32 raw[7]
Definition: CIB_PRM.h:28

References max, and raw.

Referenced by png_pixels_pass().

◆ png_pixels_pass()

static void png_pixels_pass ( struct image image,
struct png_context png,
struct png_interlace interlace 
)
static

Fill one interlace pass of PNG pixels.

Parameters
imagePNG image
pngPNG context
interlaceInterlace pass

This routine may assume that it is impossible to overrun either the raw data buffer or the pixel buffer, since the sizes of both are determined by the image dimensions.

Definition at line 651 of file png.c.

653  {
654  size_t raw_offset = png->raw.offset;
655  uint8_t channel[png->channels];
656  int is_indexed = ( png->colour_type & PNG_COLOUR_TYPE_PALETTE );
657  int is_rgb = ( png->colour_type & PNG_COLOUR_TYPE_RGB );
658  int has_alpha = ( png->colour_type & PNG_COLOUR_TYPE_ALPHA );
659  size_t pixbuf_y_offset;
660  size_t pixbuf_offset;
661  size_t pixbuf_x_stride;
662  size_t pixbuf_y_stride;
663  size_t raw_stride;
664  unsigned int y;
665  unsigned int x;
666  unsigned int c;
667  unsigned int bits;
668  unsigned int depth;
669  unsigned int max;
670  unsigned int alpha;
671  unsigned int raw;
672  unsigned int value;
673  uint8_t current = 0;
674  uint32_t pixel;
675 
676  /* We only ever use the top byte of 16-bit pixels. Model this
677  * as a bit depth of 8 with a stride of more than one.
678  */
679  depth = png->depth;
680  raw_stride = ( ( depth + 7 ) / 8 );
681  if ( depth > 8 )
682  depth = 8;
683  max = ( ( 1 << depth ) - 1 );
684 
685  /* Calculate pixel buffer offset and strides */
686  pixbuf_y_offset = ( ( ( interlace->y_indent * png->pixbuf->width ) +
687  interlace->x_indent ) * sizeof ( pixel ) );
688  pixbuf_x_stride = ( interlace->x_stride * sizeof ( pixel ) );
689  pixbuf_y_stride = ( interlace->y_stride * png->pixbuf->width *
690  sizeof ( pixel ) );
691  DBGC2 ( image, "PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
692  image->name, interlace->pass, interlace->width,
693  interlace->height, interlace->x_indent, interlace->y_indent,
694  interlace->x_stride, interlace->y_stride );
695 
696  /* Iterate over each scanline in turn */
697  for ( y = 0 ; y < interlace->height ; y++ ) {
698 
699  /* Skip filter byte */
700  raw_offset++;
701 
702  /* Iterate over each pixel in turn */
703  bits = depth;
704  pixbuf_offset = pixbuf_y_offset;
705  for ( x = 0 ; x < interlace->width ; x++ ) {
706 
707  /* Extract sample value */
708  for ( c = 0 ; c < png->channels ; c++ ) {
709 
710  /* Get sample value into high bits of current */
711  current <<= depth;
712  bits -= depth;
713  if ( ! bits ) {
714  copy_from_user ( &current,
715  png->raw.data,
716  raw_offset,
717  sizeof ( current ) );
718  raw_offset += raw_stride;
719  bits = 8;
720  }
721 
722  /* Extract sample value */
723  channel[c] = ( current >> ( 8 - depth ) );
724  }
725 
726  /* Convert to native pixel format */
727  if ( is_indexed ) {
728 
729  /* Indexed */
730  pixel = png->palette[channel[0]];
731 
732  } else {
733 
734  /* Determine alpha value */
735  alpha = ( has_alpha ?
736  channel[ png->channels - 1 ] : max );
737 
738  /* Convert to RGB value */
739  pixel = 0;
740  for ( c = 0 ; c < 3 ; c++ ) {
741  raw = channel[ is_rgb ? c : 0 ];
742  value = png_pixel ( raw, alpha, max );
743  assert ( value <= 255 );
744  pixel = ( ( pixel << 8 ) | value );
745  }
746  }
747 
748  /* Store pixel */
749  copy_to_user ( png->pixbuf->data, pixbuf_offset,
750  &pixel, sizeof ( pixel ) );
751  pixbuf_offset += pixbuf_x_stride;
752  }
753 
754  /* Move to next output row */
755  pixbuf_y_offset += pixbuf_y_stride;
756  }
757 
758  /* Update offset */
759  png->raw.offset = raw_offset;
760 }
uint32_t c
Definition: md4.c:30
RGB colour is used.
Definition: png.h:101
uint32_t palette[PNG_PALETTE_COUNT]
Palette, in iPXE's pixel buffer format.
Definition: png.c:60
#define max(x, y)
Definition: ath.h:39
unsigned int x_indent
X starting indent.
Definition: png.c:73
Alpha channel is used.
Definition: png.h:103
unsigned int y_stride
Y stride.
Definition: png.c:79
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
unsigned int pass
Pass number.
Definition: png.c:71
unsigned int width
Width.
Definition: png.c:81
unsigned int depth
Bit depth.
Definition: png.c:52
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Palette is used.
Definition: png.h:99
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
unsigned char uint8_t
Definition: stdint.h:10
unsigned int x_stride
X stride.
Definition: png.c:77
size_t offset
Current offset.
Definition: deflate.h:245
unsigned int uint32_t
Definition: stdint.h:12
unsigned int colour_type
Colour type.
Definition: png.c:54
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:49
static volatile void * bits
Definition: bitops.h:27
#define DBGC2(...)
Definition: compiler.h:522
__be32 raw[7]
Definition: CIB_PRM.h:28
userptr_t data
Data.
Definition: deflate.h:243
userptr_t data
32-bit (8:8:8:8) xRGB pixel data, in host-endian order
Definition: pixbuf.h:25
unsigned int channels
Number of channels.
Definition: png.c:56
char * name
Name.
Definition: image.h:34
unsigned int height
Height.
Definition: png.c:83
unsigned int y_indent
Y starting indent.
Definition: png.c:75
unsigned int width
Width.
Definition: pixbuf.h:21
static unsigned int png_pixel(unsigned int raw, unsigned int alpha, unsigned int max)
Calculate PNG pixel component value.
Definition: png.c:628

References assert(), bits, c, channel, png_context::channels, png_context::colour_type, copy_from_user(), copy_to_user(), pixel_buffer::data, deflate_chunk::data, DBGC2, png_context::depth, png_interlace::height, max, image::name, deflate_chunk::offset, png_context::palette, png_interlace::pass, png_context::pixbuf, PNG_COLOUR_TYPE_ALPHA, PNG_COLOUR_TYPE_PALETTE, PNG_COLOUR_TYPE_RGB, png_pixel(), raw, png_context::raw, value, pixel_buffer::width, png_interlace::width, png_interlace::x_indent, png_interlace::x_stride, png_interlace::y_indent, and png_interlace::y_stride.

Referenced by png_pixels().

◆ png_pixels()

static void png_pixels ( struct image image,
struct png_context png 
)
static

Fill PNG pixels.

Parameters
imagePNG image
pngPNG context

This routine may assume that it is impossible to overrun either the raw data buffer or the pixel buffer, since the sizes of both are determined by the image dimensions.

Definition at line 772 of file png.c.

772  {
773  struct png_interlace interlace;
774  unsigned int pass;
775 
776  /* Process each interlace pass */
777  png->raw.offset = 0;
778  for ( pass = 0 ; pass < png->passes ; pass++ ) {
779 
780  /* Calculate interlace pass parameters */
781  png_interlace ( png, pass, &interlace );
782 
783  /* Skip zero-width rows (which have no filter bytes) */
784  if ( interlace.width == 0 )
785  continue;
786 
787  /* Unfilter this pass */
788  png_pixels_pass ( image, png, &interlace );
789  }
790  assert ( png->raw.offset == png->raw.len );
791 }
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
unsigned int pass
Pass number.
Definition: png.c:71
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A PNG interlace pass.
Definition: png.c:69
size_t offset
Current offset.
Definition: deflate.h:245
static void png_pixels_pass(struct image *image, struct png_context *png, struct png_interlace *interlace)
Fill one interlace pass of PNG pixels.
Definition: png.c:651
unsigned int passes
Number of interlace passes.
Definition: png.c:58
static void png_interlace(struct png_context *png, unsigned int pass, struct png_interlace *interlace)
Calculate PNG interlace pass parameters.
Definition: png.c:118
size_t len
Length of data.
Definition: deflate.h:247

References assert(), deflate_chunk::len, deflate_chunk::offset, png_interlace::pass, png_context::passes, png_interlace(), png_pixels_pass(), png_context::raw, and png_interlace::width.

Referenced by png_image_end().

◆ png_image_end()

static int png_image_end ( struct image image,
struct png_context png,
size_t  len 
)
static

Handle PNG image end chunk.

Parameters
imagePNG image
pngPNG context
lenChunk length
Return values
rcReturn status code

Definition at line 801 of file png.c.

802  {
803  int rc;
804 
805  /* Sanity checks */
806  if ( len != 0 ) {
807  DBGC ( image, "PNG %s invalid IEND length %zd\n",
808  image->name, len );
809  return -EINVAL;
810  }
811  if ( ! png->pixbuf ) {
812  DBGC ( image, "PNG %s missing pixel buffer (no IHDR?)\n",
813  image->name );
814  return -EINVAL;
815  }
816  if ( ! deflate_finished ( &png->deflate ) ) {
817  DBGC ( image, "PNG %s decompression not complete\n",
818  image->name );
819  return -EINVAL;
820  }
821  if ( png->raw.offset != png->raw.len ) {
822  DBGC ( image, "PNG %s incorrect decompressed length (expected "
823  "%zd, got %zd)\n", image->name, png->raw.len,
824  png->raw.offset );
825  return -EINVAL;
826  }
827 
828  /* Unfilter raw data */
829  if ( ( rc = png_unfilter ( image, png ) ) != 0 )
830  return rc;
831 
832  /* Fill pixel buffer */
833  png_pixels ( image, png );
834 
835  return 0;
836 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void png_pixels(struct image *image, struct png_context *png)
Fill PNG pixels.
Definition: png.c:772
static int png_unfilter(struct image *image, struct png_context *png)
Unfilter PNG raw data.
Definition: png.c:594
#define DBGC(...)
Definition: compiler.h:505
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
An executable image.
Definition: image.h:24
static int deflate_finished(struct deflate *deflate)
Check if decompression has finished.
Definition: deflate.h:273
size_t offset
Current offset.
Definition: deflate.h:245
struct deflate deflate
Decompressor.
Definition: png.c:65
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:49
uint32_t len
Length.
Definition: ena.h:14
char * name
Name.
Definition: image.h:34
size_t len
Length of data.
Definition: deflate.h:247

References DBGC, png_context::deflate, deflate_finished(), EINVAL, len, deflate_chunk::len, image::name, deflate_chunk::offset, png_context::pixbuf, png_pixels(), png_unfilter(), png_context::raw, and rc.

◆ png_chunk()

static int png_chunk ( struct image image,
struct png_context png,
uint32_t  type,
size_t  len 
)
static

Handle PNG chunk.

Parameters
imagePNG image
pngPNG context
typeChunk type
lenChunk length
Return values
rcReturn status code

Definition at line 871 of file png.c.

872  {
873  struct png_chunk_handler *handler;
874  unsigned int i;
875 
876  DBGC ( image, "PNG %s chunk type %s offset %zd length %zd\n",
877  image->name, png_type_name ( type ), png->offset, len );
878 
879  /* Handle according to chunk type */
880  for ( i = 0 ; i < ( sizeof ( png_chunk_handlers ) /
881  sizeof ( png_chunk_handlers[0] ) ) ; i++ ) {
882  handler = &png_chunk_handlers[i];
883  if ( handler->type == type )
884  return handler->handle ( image, png, len );
885  }
886 
887  /* Fail if unknown chunk type is critical */
888  if ( ! ( type & htonl ( PNG_CHUNK_ANCILLARY ) ) ) {
889  DBGC ( image, "PNG %s unknown critical chunk type %s\n",
890  image->name, png_type_name ( type ) );
891  return -ENOTSUP;
892  }
893 
894  /* Ignore non-critical unknown chunk types */
895  return 0;
896 }
Chunk is ancillary.
Definition: png.h:42
static const char * png_type_name(uint32_t type)
Transcribe PNG chunk type name (for debugging)
Definition: png.c:101
size_t offset
Offset within image.
Definition: png.c:46
#define DBGC(...)
Definition: compiler.h:505
int(* handle)(struct image *image, struct png_context *png, size_t len)
Handle chunk.
Definition: png.c:850
An executable image.
Definition: image.h:24
static struct png_chunk_handler png_chunk_handlers[]
PNG chunk handlers.
Definition: png.c:855
#define htonl(value)
Definition: byteswap.h:133
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A PNG chunk handler.
Definition: png.c:839
uint32_t type
Chunk type.
Definition: png.c:841
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
char * name
Name.
Definition: image.h:34

References DBGC, ENOTSUP, png_chunk_handler::handle, htonl, len, image::name, png_context::offset, PNG_CHUNK_ANCILLARY, png_chunk_handlers, png_type_name(), type, and png_chunk_handler::type.

Referenced by png_pixbuf().

◆ png_pixbuf()

static int png_pixbuf ( struct image image,
struct pixel_buffer **  pixbuf 
)
static

Convert PNG image to pixel buffer.

Parameters
imagePNG image
pixbufPixel buffer to fill in
Return values
rcReturn status code

Definition at line 905 of file png.c.

905  {
906  struct png_context *png;
907  struct png_chunk_header header;
908  struct png_chunk_footer footer;
909  size_t remaining;
910  size_t chunk_len;
911  int rc;
912 
913  /* Allocate and initialise context */
914  png = zalloc ( sizeof ( *png ) );
915  if ( ! png ) {
916  rc = -ENOMEM;
917  goto err_alloc;
918  }
919  png->offset = sizeof ( struct png_signature );
920  deflate_init ( &png->deflate, DEFLATE_ZLIB );
921 
922  /* Process chunks */
923  do {
924 
925  /* Extract chunk header */
926  remaining = ( image->len - png->offset );
927  if ( remaining < ( sizeof ( header ) + sizeof ( footer ) ) ) {
928  DBGC ( image, "PNG %s truncated chunk header/footer "
929  "at offset %zd\n", image->name, png->offset );
930  rc = -EINVAL;
931  goto err_truncated;
932  }
934  sizeof ( header ) );
935  png->offset += sizeof ( header );
936 
937  /* Validate chunk length */
938  chunk_len = ntohl ( header.len );
939  if ( chunk_len > ( remaining - sizeof ( header ) -
940  sizeof ( footer ) ) ) {
941  DBGC ( image, "PNG %s truncated chunk data at offset "
942  "%zd\n", image->name, png->offset );
943  rc = -EINVAL;
944  goto err_truncated;
945  }
946 
947  /* Handle chunk */
948  if ( ( rc = png_chunk ( image, png, header.type,
949  chunk_len ) ) != 0 )
950  goto err_chunk;
951 
952  /* Move to next chunk */
953  png->offset += ( chunk_len + sizeof ( footer ) );
954 
955  } while ( png->offset < image->len );
956 
957  /* Check that we finished with an IEND chunk */
958  if ( header.type != htonl ( PNG_TYPE_IEND ) ) {
959  DBGC ( image, "PNG %s did not finish with IEND\n",
960  image->name );
961  rc = -EINVAL;
962  goto err_iend;
963  }
964 
965  /* Return pixel buffer */
966  *pixbuf = pixbuf_get ( png->pixbuf );
967 
968  /* Success */
969  rc = 0;
970 
971  err_iend:
972  err_chunk:
973  err_truncated:
974  pixbuf_put ( png->pixbuf );
975  ufree ( png->raw.data );
976  free ( png );
977  err_alloc:
978  return rc;
979 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
static int png_chunk(struct image *image, struct png_context *png, uint32_t type, size_t len)
Handle PNG chunk.
Definition: png.c:871
size_t offset
Offset within image.
Definition: png.c:46
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:63
#define ntohl(value)
Definition: byteswap.h:134
An executable image.
Definition: image.h:24
#define htonl(value)
Definition: byteswap.h:133
#define ENOMEM
Not enough space.
Definition: errno.h:534
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
Definition: deflate.c:999
PNG context.
Definition: png.c:44
#define PNG_TYPE_IEND
PNG image end chunk type.
Definition: png.h:175
ZLIB header and footer.
Definition: deflate.h:21
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
size_t len
Length of raw file image.
Definition: image.h:43
struct deflate deflate
Decompressor.
Definition: png.c:65
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:49
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
struct ena_aq_header header
Header.
Definition: ena.h:12
A PNG file signature.
Definition: png.h:17
userptr_t data
Data.
Definition: deflate.h:243
A PNG chunk header.
Definition: png.h:26
char * name
Name.
Definition: image.h:34

References copy_from_user(), image::data, deflate_chunk::data, DBGC, png_context::deflate, deflate_init(), DEFLATE_ZLIB, EINVAL, ENOMEM, free, header, htonl, image::len, image::name, ntohl, png_context::offset, png_context::pixbuf, png_chunk(), PNG_TYPE_IEND, png_context::raw, rc, ufree(), and zalloc().

◆ png_probe()

static int png_probe ( struct image image)
static

Probe PNG image.

Parameters
imagePNG image
Return values
rcReturn status code

Definition at line 987 of file png.c.

987  {
988  struct png_signature signature;
989 
990  /* Sanity check */
991  if ( image->len < sizeof ( signature ) ) {
992  DBGC ( image, "PNG %s is too short\n", image->name );
993  return -ENOEXEC;
994  }
995 
996  /* Check signature */
997  copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
998  if ( memcmp ( &signature, &png_signature, sizeof ( signature ) ) != 0 ){
999  DBGC ( image, "PNG %s has invalid signature\n", image->name );
1000  return -ENOEXEC;
1001  }
1002 
1003  return 0;
1004 }
userptr_t data
Raw file image.
Definition: image.h:41
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
size_t len
Length of raw file image.
Definition: image.h:43
A PNG file signature.
Definition: png.h:17
u8 signature
Signature.
Definition: CIB_PRM.h:35
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
char * name
Name.
Definition: image.h:34

References copy_from_user(), image::data, DBGC, ENOEXEC, image::len, memcmp(), image::name, and signature.

◆ __image_type()

struct image_type png_image_type __image_type ( PROBE_NORMAL  )

PNG image type.

Variable Documentation

◆ png_signature

PNG file signature.

Definition at line 87 of file png.c.

◆ png_interlace_passes

uint8_t png_interlace_passes[]
static
Initial value:
= {
}
Adam7 interlacing.
Definition: png.h:130
No interlacing.
Definition: png.h:128

Number of interlacing passes.

Definition at line 90 of file png.c.

Referenced by png_image_header().

◆ png_filters

struct png_filter png_filters[]
static
Initial value:
= {
}
static unsigned int png_unfilter_average(unsigned int current, unsigned int left, unsigned int above, unsigned int above_left __unused)
Unfilter byte using the "Average" filter.
Definition: png.c:414
No filtering.
Definition: png.h:163
Above byte used as predictor.
Definition: png.h:167
static unsigned int png_unfilter_sub(unsigned int current, unsigned int left, unsigned int above __unused, unsigned int above_left __unused)
Unfilter byte using the "Sub" filter.
Definition: png.c:380
static unsigned int png_unfilter_paeth(unsigned int current, unsigned int left, unsigned int above, unsigned int above_left)
Unfilter byte using the "Paeth" filter.
Definition: png.c:460
Above and left bytes used as predictors.
Definition: png.h:169
Paeth filter.
Definition: png.h:171
static unsigned int png_unfilter_none(unsigned int current, unsigned int left __unused, unsigned int above __unused, unsigned int above_left __unused)
Unfilter byte using the "None" filter.
Definition: png.c:363
Left byte used as predictor.
Definition: png.h:165
static unsigned int png_unfilter_up(unsigned int current, unsigned int left __unused, unsigned int above, unsigned int above_left __unused)
Unfilter byte using the "Up" filter.
Definition: png.c:397

PNG filter types.

Definition at line 486 of file png.c.

Referenced by png_unfilter_pass().

◆ png_chunk_handlers

struct png_chunk_handler png_chunk_handlers[]
static
Initial value:
= {
}
static int png_image_data(struct image *image, struct png_context *png, size_t len)
Handle PNG image data chunk.
Definition: png.c:337
#define htonl(value)
Definition: byteswap.h:133
#define PNG_TYPE_IDAT
PNG image data chunk type.
Definition: png.h:158
A PNG image header.
Definition: png.h:79
#define PNG_TYPE_IEND
PNG image end chunk type.
Definition: png.h:175
A PNG palette chunk.
Definition: png.h:149
#define PNG_TYPE_IHDR
PNG image header chunk type.
Definition: png.h:76
static int png_image_end(struct image *image, struct png_context *png, size_t len)
Handle PNG image end chunk.
Definition: png.c:801
#define PNG_TYPE_PLTE
PNG palette chunk type.
Definition: png.h:136

PNG chunk handlers.

Definition at line 855 of file png.c.

Referenced by png_chunk().