iPXE
png.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <byteswap.h>
32 #include <ipxe/umalloc.h>
33 #include <ipxe/pixbuf.h>
34 #include <ipxe/deflate.h>
35 #include <ipxe/png.h>
36 
37 /** @file
38  *
39  * Portable Network Graphics (PNG) format
40  *
41  * The PNG format is defined in RFC 2083.
42  */
43 
44 /** PNG context */
45 struct png_context {
46  /** Offset within image */
47  size_t offset;
48 
49  /** Pixel buffer */
51 
52  /** Bit depth */
53  unsigned int depth;
54  /** Colour type */
55  unsigned int colour_type;
56  /** Number of channels */
57  unsigned int channels;
58  /** Number of interlace passes */
59  unsigned int passes;
60  /** Palette, in iPXE's pixel buffer format */
62 
63  /** Decompression buffer for raw PNG data */
65  /** Decompressor */
66  struct deflate deflate;
67 };
68 
69 /** A PNG interlace pass */
70 struct png_interlace {
71  /** Pass number */
72  unsigned int pass;
73  /** X starting indent */
74  unsigned int x_indent;
75  /** Y starting indent */
76  unsigned int y_indent;
77  /** X stride */
78  unsigned int x_stride;
79  /** Y stride */
80  unsigned int y_stride;
81  /** Width */
82  unsigned int width;
83  /** Height */
84  unsigned int height;
85 };
86 
87 /** PNG file signature */
89 
90 /** Number of interlacing passes */
92  [PNG_INTERLACE_NONE] = 1,
93  [PNG_INTERLACE_ADAM7] = 7,
94 };
95 
96 /**
97  * Transcribe PNG chunk type name (for debugging)
98  *
99  * @v type Chunk type
100  * @ret name Chunk type name
101  */
102 static const char * png_type_name ( uint32_t type ) {
103  static union {
104  uint32_t type;
105  char name[ sizeof ( uint32_t ) + 1 /* NUL */ ];
106  } u;
107 
108  u.type = type;
109  return u.name;
110 }
111 
112 /**
113  * Calculate PNG interlace pass parameters
114  *
115  * @v png PNG context
116  * @v pass Pass number (0=first pass)
117  * @v interlace Interlace pass to fill in
118  */
119 static void png_interlace ( struct png_context *png, unsigned int pass,
120  struct png_interlace *interlace ) {
121  unsigned int grid_width_log2;
122  unsigned int grid_height_log2;
123  unsigned int x_indent;
124  unsigned int y_indent;
125  unsigned int x_stride_log2;
126  unsigned int y_stride_log2;
127  unsigned int x_stride;
128  unsigned int y_stride;
129  unsigned int width;
130  unsigned int height;
131 
132  /* Sanity check */
133  assert ( png->passes > 0 );
134 
135  /* Store pass number */
136  interlace->pass = pass;
137 
138  /* Calculate interlace grid dimensions */
139  grid_width_log2 = ( png->passes / 2 );
140  grid_height_log2 = ( ( png->passes - 1 ) / 2 );
141 
142  /* Calculate starting indents */
143  interlace->x_indent = x_indent =
144  ( ( pass & 1 ) ?
145  ( 1 << ( grid_width_log2 - ( pass / 2 ) - 1 ) ) : 0 );
146  interlace->y_indent = y_indent =
147  ( ( pass && ! ( pass & 1 ) ) ?
148  ( 1 << ( grid_height_log2 - ( ( pass - 1 ) / 2 ) - 1 ) ) : 0);
149 
150  /* Calculate strides */
151  x_stride_log2 = ( grid_width_log2 - ( pass / 2 ) );
152  y_stride_log2 =
153  ( grid_height_log2 - ( pass ? ( ( pass - 1 ) / 2 ) : 0 ) );
154  interlace->x_stride = x_stride = ( 1 << x_stride_log2 );
155  interlace->y_stride = y_stride = ( 1 << y_stride_log2 );
156 
157  /* Calculate pass dimensions */
158  width = png->pixbuf->width;
159  height = png->pixbuf->height;
160  interlace->width =
161  ( ( width - x_indent + x_stride - 1 ) >> x_stride_log2 );
162  interlace->height =
163  ( ( height - y_indent + y_stride - 1 ) >> y_stride_log2 );
164 }
165 
166 /**
167  * Calculate PNG pixel length
168  *
169  * @v png PNG context
170  * @ret pixel_len Pixel length
171  */
172 static unsigned int png_pixel_len ( struct png_context *png ) {
173 
174  return ( ( ( png->channels * png->depth ) + 7 ) / 8 );
175 }
176 
177 /**
178  * Calculate PNG scanline length
179  *
180  * @v png PNG context
181  * @v interlace Interlace pass
182  * @ret scanline_len Scanline length (including filter byte)
183  */
184 static size_t png_scanline_len ( struct png_context *png,
185  struct png_interlace *interlace ) {
186 
187  return ( 1 /* Filter byte */ +
188  ( ( interlace->width * png->channels * png->depth ) + 7 ) / 8);
189 }
190 
191 /**
192  * Handle PNG image header chunk
193  *
194  * @v image PNG image
195  * @v png PNG context
196  * @v len Chunk length
197  * @ret rc Return status code
198  */
199 static int png_image_header ( struct image *image, struct png_context *png,
200  size_t len ) {
201  const struct png_image_header *ihdr;
202  struct png_interlace interlace;
203  unsigned int pass;
204 
205  /* Sanity check */
206  if ( len != sizeof ( *ihdr ) ) {
207  DBGC ( image, "PNG %s invalid IHDR length %zd\n",
208  image->name, len );
209  return -EINVAL;
210  }
211  if ( png->pixbuf ) {
212  DBGC ( image, "PNG %s duplicate IHDR\n", image->name );
213  return -EINVAL;
214  }
215 
216  /* Extract image header */
217  ihdr = ( image->data + png->offset );
218  DBGC ( image, "PNG %s %dx%d depth %d type %d compression %d filter %d "
219  "interlace %d\n", image->name, ntohl ( ihdr->width ),
220  ntohl ( ihdr->height ), ihdr->depth, ihdr->colour_type,
221  ihdr->compression, ihdr->filter, ihdr->interlace );
222 
223  /* Sanity checks */
224  if ( ihdr->compression >= PNG_COMPRESSION_UNKNOWN ) {
225  DBGC ( image, "PNG %s unknown compression method %d\n",
226  image->name, ihdr->compression );
227  return -ENOTSUP;
228  }
229  if ( ihdr->filter >= PNG_FILTER_UNKNOWN ) {
230  DBGC ( image, "PNG %s unknown filter method %d\n",
231  image->name, ihdr->filter );
232  return -ENOTSUP;
233  }
234  if ( ihdr->interlace >= PNG_INTERLACE_UNKNOWN ) {
235  DBGC ( image, "PNG %s unknown interlace method %d\n",
236  image->name, ihdr->interlace );
237  return -ENOTSUP;
238  }
239 
240  /* Allocate pixel buffer */
241  png->pixbuf = alloc_pixbuf ( ntohl ( ihdr->width ),
242  ntohl ( ihdr->height ) );
243  if ( ! png->pixbuf ) {
244  DBGC ( image, "PNG %s could not allocate pixel buffer\n",
245  image->name );
246  return -ENOMEM;
247  }
248 
249  /* Extract bit depth */
250  png->depth = ihdr->depth;
251  if ( ( png->depth == 0 ) ||
252  ( ( png->depth & ( png->depth - 1 ) ) != 0 ) ) {
253  DBGC ( image, "PNG %s invalid depth %d\n",
254  image->name, png->depth );
255  return -EINVAL;
256  }
257 
258  /* Calculate number of channels */
259  png->colour_type = ihdr->colour_type;
260  png->channels = 1;
261  if ( ! ( ihdr->colour_type & PNG_COLOUR_TYPE_PALETTE ) ) {
262  if ( ihdr->colour_type & PNG_COLOUR_TYPE_RGB )
263  png->channels += 2;
264  if ( ihdr->colour_type & PNG_COLOUR_TYPE_ALPHA )
265  png->channels += 1;
266  }
267 
268  /* Calculate number of interlace passes */
269  png->passes = png_interlace_passes[ihdr->interlace];
270 
271  /* Calculate length of raw data buffer */
272  for ( pass = 0 ; pass < png->passes ; pass++ ) {
273  png_interlace ( png, pass, &interlace );
274  if ( interlace.width == 0 )
275  continue;
276  png->raw.len += ( interlace.height *
277  png_scanline_len ( png, &interlace ) );
278  }
279 
280  /* Allocate raw data buffer */
281  png->raw.data = umalloc ( png->raw.len );
282  if ( ! png->raw.data ) {
283  DBGC ( image, "PNG %s could not allocate data buffer\n",
284  image->name );
285  return -ENOMEM;
286  }
287 
288  return 0;
289 }
290 
291 /**
292  * Handle PNG palette chunk
293  *
294  * @v image PNG image
295  * @v png PNG context
296  * @v len Chunk length
297  * @ret rc Return status code
298  */
299 static int png_palette ( struct image *image, struct png_context *png,
300  size_t len ) {
301  const struct png_palette_entry *palette;
302  unsigned int i;
303 
304  /* Populate palette */
305  palette = ( image->data + png->offset );
306  for ( i = 0 ; i < ( sizeof ( png->palette ) /
307  sizeof ( png->palette[0] ) ) ; i++ ) {
308 
309  /* Stop when we run out of palette data */
310  if ( len < sizeof ( *palette ) )
311  break;
312 
313  /* Extract palette entry */
314  png->palette[i] = ( ( palette->red << 16 ) |
315  ( palette->green << 8 ) |
316  ( palette->blue << 0 ) );
317  DBGC2 ( image, "PNG %s palette entry %d is %#06x\n",
318  image->name, i, png->palette[i] );
319 
320  /* Move to next entry */
321  palette++;
322  len -= sizeof ( *palette );
323  }
324 
325  return 0;
326 }
327 
328 /**
329  * Handle PNG image data chunk
330  *
331  * @v image PNG image
332  * @v png PNG context
333  * @v len Chunk length
334  * @ret rc Return status code
335  */
336 static int png_image_data ( struct image *image, struct png_context *png,
337  size_t len ) {
338  int rc;
339 
340  /* Deflate this chunk */
341  if ( ( rc = deflate_inflate ( &png->deflate,
342  ( image->data + png->offset ),
343  len, &png->raw ) ) != 0 ) {
344  DBGC ( image, "PNG %s could not decompress: %s\n",
345  image->name, strerror ( rc ) );
346  return rc;
347  }
348 
349  return 0;
350 }
351 
352 /**
353  * Unfilter byte using the "None" filter
354  *
355  * @v current Filtered current byte
356  * @v left Unfiltered left byte
357  * @v above Unfiltered above byte
358  * @v above_left Unfiltered above-left byte
359  * @ret current Unfiltered current byte
360  */
361 static unsigned int png_unfilter_none ( unsigned int current,
362  unsigned int left __unused,
363  unsigned int above __unused,
364  unsigned int above_left __unused ) {
365 
366  return current;
367 }
368 
369 /**
370  * Unfilter byte using the "Sub" filter
371  *
372  * @v current Filtered current byte
373  * @v left Unfiltered left byte
374  * @v above Unfiltered above byte
375  * @v above_left Unfiltered above-left byte
376  * @ret current Unfiltered current byte
377  */
378 static unsigned int png_unfilter_sub ( unsigned int current,
379  unsigned int left,
380  unsigned int above __unused,
381  unsigned int above_left __unused ) {
382 
383  return ( current + left );
384 }
385 
386 /**
387  * Unfilter byte using the "Up" filter
388  *
389  * @v current Filtered current byte
390  * @v left Unfiltered left byte
391  * @v above Unfiltered above byte
392  * @v above_left Unfiltered above-left byte
393  * @ret current Unfiltered current byte
394  */
395 static unsigned int png_unfilter_up ( unsigned int current,
396  unsigned int left __unused,
397  unsigned int above,
398  unsigned int above_left __unused ) {
399 
400  return ( current + above );
401 }
402 
403 /**
404  * Unfilter byte using the "Average" filter
405  *
406  * @v current Filtered current byte
407  * @v left Unfiltered left byte
408  * @v above Unfiltered above byte
409  * @v above_left Unfiltered above-left byte
410  * @ret current Unfiltered current byte
411  */
412 static unsigned int png_unfilter_average ( unsigned int current,
413  unsigned int left,
414  unsigned int above,
415  unsigned int above_left __unused ) {
416 
417  return ( current + ( ( above + left ) >> 1 ) );
418 }
419 
420 /**
421  * Paeth predictor function (defined in RFC 2083)
422  *
423  * @v a Pixel A
424  * @v b Pixel B
425  * @v c Pixel C
426  * @ret predictor Predictor pixel
427  */
428 static unsigned int png_paeth_predictor ( unsigned int a, unsigned int b,
429  unsigned int c ) {
430  unsigned int p;
431  unsigned int pa;
432  unsigned int pb;
433  unsigned int pc;
434 
435  /* Algorithm as defined in RFC 2083 section 6.6 */
436  p = ( a + b - c );
437  pa = abs ( p - a );
438  pb = abs ( p - b );
439  pc = abs ( p - c );
440  if ( ( pa <= pb ) && ( pa <= pc ) ) {
441  return a;
442  } else if ( pb <= pc ) {
443  return b;
444  } else {
445  return c;
446  }
447 }
448 
449 /**
450  * Unfilter byte using the "Paeth" filter
451  *
452  * @v current Filtered current byte
453  * @v above_left Unfiltered above-left byte
454  * @v above Unfiltered above byte
455  * @v left Unfiltered left byte
456  * @ret current Unfiltered current byte
457  */
458 static unsigned int png_unfilter_paeth ( unsigned int current,
459  unsigned int left,
460  unsigned int above,
461  unsigned int above_left ) {
462 
463  return ( current + png_paeth_predictor ( left, above, above_left ) );
464 }
465 
466 /** A PNG filter */
467 struct png_filter {
468  /**
469  * Unfilter byte
470  *
471  * @v current Filtered current byte
472  * @v left Unfiltered left byte
473  * @v above Unfiltered above byte
474  * @v above_left Unfiltered above-left byte
475  * @ret current Unfiltered current byte
476  */
477  unsigned int ( * unfilter ) ( unsigned int current,
478  unsigned int left,
479  unsigned int above,
480  unsigned int above_left );
481 };
482 
483 /** PNG filter types */
484 static struct png_filter png_filters[] = {
490 };
491 
492 /**
493  * Unfilter one interlace pass of PNG raw data
494  *
495  * @v image PNG image
496  * @v png PNG context
497  * @v interlace Interlace pass
498  * @ret rc Return status code
499  *
500  * This routine may assume that it is impossible to overrun the raw
501  * data buffer, since the size is determined by the image dimensions.
502  */
503 static int png_unfilter_pass ( struct image *image, struct png_context *png,
504  struct png_interlace *interlace ) {
505  size_t pixel_len = png_pixel_len ( png );
506  size_t scanline_len = png_scanline_len ( png, interlace );
507  uint8_t *data = ( png->raw.data + png->raw.offset );
508  struct png_filter *filter;
509  unsigned int scanline;
510  unsigned int byte;
511  unsigned int filter_type;
512  unsigned int left;
513  unsigned int above;
514  unsigned int above_left;
515 
516  /* On the first scanline of a pass, above bytes are assumed to
517  * be zero.
518  */
519  above = 0;
520 
521  /* Iterate over each scanline in turn */
522  for ( scanline = 0 ; scanline < interlace->height ; scanline++ ) {
523 
524  /* Extract filter byte and determine filter type */
525  filter_type = *(data++);
526  if ( filter_type >= ( sizeof ( png_filters ) /
527  sizeof ( png_filters[0] ) ) ) {
528  DBGC ( image, "PNG %s unknown filter type %d\n",
529  image->name, filter_type );
530  return -ENOTSUP;
531  }
532  filter = &png_filters[filter_type];
533  assert ( filter->unfilter != NULL );
534  DBGC2 ( image, "PNG %s pass %d scanline %d filter type %d\n",
535  image->name, interlace->pass, scanline, filter_type );
536 
537  /* At the start of a line, both above-left and left
538  * bytes are taken to be zero.
539  */
540  left = 0;
541  above_left = 0;
542 
543  /* Iterate over each byte (not pixel) in turn */
544  for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
545 
546  /* Extract predictor bytes, if applicable */
547  if ( byte >= pixel_len )
548  left = *( data - pixel_len );
549  if ( scanline > 0 )
550  above = *( data - scanline_len );
551  if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
552  above_left = *( data - scanline_len -
553  pixel_len );
554  }
555 
556  /* Unfilter current byte */
557  *data = filter->unfilter ( *data, left, above,
558  above_left );
559  data++;
560  }
561  }
562 
563  /* Update offset */
564  png->raw.offset = ( ( ( void * ) data ) - png->raw.data );
565 
566  return 0;
567 }
568 
569 /**
570  * Unfilter PNG raw data
571  *
572  * @v image PNG image
573  * @v png PNG context
574  * @ret rc Return status code
575  *
576  * This routine may assume that it is impossible to overrun the raw
577  * data buffer, since the size is determined by the image dimensions.
578  */
579 static int png_unfilter ( struct image *image, struct png_context *png ) {
580  struct png_interlace interlace;
581  unsigned int pass;
582  int rc;
583 
584  /* Process each interlace pass */
585  png->raw.offset = 0;
586  for ( pass = 0 ; pass < png->passes ; pass++ ) {
587 
588  /* Calculate interlace pass parameters */
589  png_interlace ( png, pass, &interlace );
590 
591  /* Skip zero-width rows (which have no filter bytes) */
592  if ( interlace.width == 0 )
593  continue;
594 
595  /* Unfilter this pass */
596  if ( ( rc = png_unfilter_pass ( image, png,
597  &interlace ) ) != 0 )
598  return rc;
599  }
600  assert ( png->raw.offset == png->raw.len );
601 
602  return 0;
603 }
604 
605 /**
606  * Calculate PNG pixel component value
607  *
608  * @v raw Raw component value
609  * @v alpha Alpha value
610  * @v max Maximum raw/alpha value
611  * @ret value Component value in range 0-255
612  */
613 static inline unsigned int png_pixel ( unsigned int raw, unsigned int alpha,
614  unsigned int max ) {
615 
616  /* The basic calculation is 255*(raw/max)*(value/max). We use
617  * fixed-point arithmetic (scaling up to the maximum range for
618  * a 32-bit integer), in order to get the same results for
619  * alpha blending as the test cases (produced using
620  * ImageMagick).
621  */
622  return ( ( ( ( ( 0xff00 * raw * alpha ) / max ) / max ) + 0x80 ) >> 8 );
623 }
624 
625 /**
626  * Fill one interlace pass of PNG pixels
627  *
628  * @v image PNG image
629  * @v png PNG context
630  * @v interlace Interlace pass
631  *
632  * This routine may assume that it is impossible to overrun either the
633  * raw data buffer or the pixel buffer, since the sizes of both are
634  * determined by the image dimensions.
635  */
636 static void png_pixels_pass ( struct image *image,
637  struct png_context *png,
638  struct png_interlace *interlace ) {
639  uint8_t channel[png->channels];
640  int is_indexed = ( png->colour_type & PNG_COLOUR_TYPE_PALETTE );
641  int is_rgb = ( png->colour_type & PNG_COLOUR_TYPE_RGB );
642  int has_alpha = ( png->colour_type & PNG_COLOUR_TYPE_ALPHA );
643  const uint8_t *data = ( png->raw.data + png->raw.offset );
644  size_t data_stride;
645  unsigned int pixbuf_y_index;
646  unsigned int pixbuf_index;
647  unsigned int pixbuf_x_stride;
648  unsigned int pixbuf_y_stride;
649  unsigned int y;
650  unsigned int x;
651  unsigned int c;
652  unsigned int bits;
653  unsigned int depth;
654  unsigned int max;
655  unsigned int alpha;
656  unsigned int raw;
657  unsigned int value;
658  uint8_t current = 0;
659  uint32_t pixel;
660 
661  /* We only ever use the top byte of 16-bit pixels. Model this
662  * as a bit depth of 8 with a stride of more than one.
663  */
664  depth = png->depth;
665  data_stride = ( ( depth + 7 ) / 8 );
666  if ( depth > 8 )
667  depth = 8;
668  max = ( ( 1 << depth ) - 1 );
669 
670  /* Calculate pixel buffer offset and strides */
671  pixbuf_y_index = ( ( ( interlace->y_indent * png->pixbuf->width ) +
672  interlace->x_indent ) );
673  pixbuf_x_stride = interlace->x_stride;
674  pixbuf_y_stride = ( interlace->y_stride * png->pixbuf->width );
675  DBGC2 ( image, "PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
676  image->name, interlace->pass, interlace->width,
677  interlace->height, interlace->x_indent, interlace->y_indent,
678  interlace->x_stride, interlace->y_stride );
679 
680  /* Iterate over each scanline in turn */
681  for ( y = 0 ; y < interlace->height ; y++ ) {
682 
683  /* Skip filter byte */
684  data++;
685 
686  /* Iterate over each pixel in turn */
687  bits = depth;
688  pixbuf_index = pixbuf_y_index;
689  for ( x = 0 ; x < interlace->width ; x++ ) {
690 
691  /* Extract sample value */
692  for ( c = 0 ; c < png->channels ; c++ ) {
693 
694  /* Get sample value into high bits of current */
695  current <<= depth;
696  bits -= depth;
697  if ( ! bits ) {
698  current = *data;
699  data += data_stride;
700  bits = 8;
701  }
702 
703  /* Extract sample value */
704  channel[c] = ( current >> ( 8 - depth ) );
705  }
706 
707  /* Convert to native pixel format */
708  if ( is_indexed ) {
709 
710  /* Indexed */
711  pixel = png->palette[channel[0]];
712 
713  } else {
714 
715  /* Determine alpha value */
716  alpha = ( has_alpha ?
717  channel[ png->channels - 1 ] : max );
718 
719  /* Convert to RGB value */
720  pixel = 0;
721  for ( c = 0 ; c < 3 ; c++ ) {
722  raw = channel[ is_rgb ? c : 0 ];
723  value = png_pixel ( raw, alpha, max );
724  assert ( value <= 255 );
725  pixel = ( ( pixel << 8 ) | value );
726  }
727  }
728 
729  /* Store pixel */
730  png->pixbuf->data[pixbuf_index] = pixel;
731  pixbuf_index += pixbuf_x_stride;
732  }
733 
734  /* Move to next output row */
735  pixbuf_y_index += pixbuf_y_stride;
736  }
737 
738  /* Update offset */
739  png->raw.offset = ( ( ( const void * ) data ) - png->raw.data );
740 }
741 
742 /**
743  * Fill PNG pixels
744  *
745  * @v image PNG image
746  * @v png PNG context
747  *
748  * This routine may assume that it is impossible to overrun either the
749  * raw data buffer or the pixel buffer, since the sizes of both are
750  * determined by the image dimensions.
751  */
752 static void png_pixels ( struct image *image, struct png_context *png ) {
753  struct png_interlace interlace;
754  unsigned int pass;
755 
756  /* Process each interlace pass */
757  png->raw.offset = 0;
758  for ( pass = 0 ; pass < png->passes ; pass++ ) {
759 
760  /* Calculate interlace pass parameters */
761  png_interlace ( png, pass, &interlace );
762 
763  /* Skip zero-width rows (which have no filter bytes) */
764  if ( interlace.width == 0 )
765  continue;
766 
767  /* Unfilter this pass */
768  png_pixels_pass ( image, png, &interlace );
769  }
770  assert ( png->raw.offset == png->raw.len );
771 }
772 
773 /**
774  * Handle PNG image end chunk
775  *
776  * @v image PNG image
777  * @v png PNG context
778  * @v len Chunk length
779  * @ret rc Return status code
780  */
781 static int png_image_end ( struct image *image, struct png_context *png,
782  size_t len ) {
783  int rc;
784 
785  /* Sanity checks */
786  if ( len != 0 ) {
787  DBGC ( image, "PNG %s invalid IEND length %zd\n",
788  image->name, len );
789  return -EINVAL;
790  }
791  if ( ! png->pixbuf ) {
792  DBGC ( image, "PNG %s missing pixel buffer (no IHDR?)\n",
793  image->name );
794  return -EINVAL;
795  }
796  if ( ! deflate_finished ( &png->deflate ) ) {
797  DBGC ( image, "PNG %s decompression not complete\n",
798  image->name );
799  return -EINVAL;
800  }
801  if ( png->raw.offset != png->raw.len ) {
802  DBGC ( image, "PNG %s incorrect decompressed length (expected "
803  "%zd, got %zd)\n", image->name, png->raw.len,
804  png->raw.offset );
805  return -EINVAL;
806  }
807 
808  /* Unfilter raw data */
809  if ( ( rc = png_unfilter ( image, png ) ) != 0 )
810  return rc;
811 
812  /* Fill pixel buffer */
813  png_pixels ( image, png );
814 
815  return 0;
816 }
817 
818 /** A PNG chunk handler */
820  /** Chunk type */
822  /**
823  * Handle chunk
824  *
825  * @v image PNG image
826  * @v png PNG context
827  * @v len Chunk length
828  * @ret rc Return status code
829  */
830  int ( * handle ) ( struct image *image, struct png_context *png,
831  size_t len );
832 };
833 
834 /** PNG chunk handlers */
840 };
841 
842 /**
843  * Handle PNG chunk
844  *
845  * @v image PNG image
846  * @v png PNG context
847  * @v type Chunk type
848  * @v len Chunk length
849  * @ret rc Return status code
850  */
851 static int png_chunk ( struct image *image, struct png_context *png,
852  uint32_t type, size_t len ) {
853  struct png_chunk_handler *handler;
854  unsigned int i;
855 
856  DBGC ( image, "PNG %s chunk type %s offset %zd length %zd\n",
857  image->name, png_type_name ( type ), png->offset, len );
858 
859  /* Handle according to chunk type */
860  for ( i = 0 ; i < ( sizeof ( png_chunk_handlers ) /
861  sizeof ( png_chunk_handlers[0] ) ) ; i++ ) {
862  handler = &png_chunk_handlers[i];
863  if ( handler->type == type )
864  return handler->handle ( image, png, len );
865  }
866 
867  /* Fail if unknown chunk type is critical */
868  if ( ! ( type & htonl ( PNG_CHUNK_ANCILLARY ) ) ) {
869  DBGC ( image, "PNG %s unknown critical chunk type %s\n",
870  image->name, png_type_name ( type ) );
871  return -ENOTSUP;
872  }
873 
874  /* Ignore non-critical unknown chunk types */
875  return 0;
876 }
877 
878 /**
879  * Convert PNG image to pixel buffer
880  *
881  * @v image PNG image
882  * @v pixbuf Pixel buffer to fill in
883  * @ret rc Return status code
884  */
885 static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
886  struct png_context *png;
887  const struct png_chunk_header *header;
888  const struct png_chunk_footer *footer;
889  size_t remaining;
890  size_t chunk_len;
891  int rc;
892 
893  /* Allocate and initialise context */
894  png = zalloc ( sizeof ( *png ) );
895  if ( ! png ) {
896  rc = -ENOMEM;
897  goto err_alloc;
898  }
899  png->offset = sizeof ( struct png_signature );
900  deflate_init ( &png->deflate, DEFLATE_ZLIB );
901 
902  /* Process chunks */
903  do {
904 
905  /* Extract chunk header */
906  remaining = ( image->len - png->offset );
907  if ( remaining < ( sizeof ( *header ) + sizeof ( *footer ) ) ){
908  DBGC ( image, "PNG %s truncated chunk header/footer "
909  "at offset %zd\n", image->name, png->offset );
910  rc = -EINVAL;
911  goto err_truncated;
912  }
913  header = ( image->data + png->offset );
914  png->offset += sizeof ( *header );
915 
916  /* Validate chunk length */
917  chunk_len = ntohl ( header->len );
918  if ( chunk_len > ( remaining - sizeof ( *header ) -
919  sizeof ( *footer ) ) ) {
920  DBGC ( image, "PNG %s truncated chunk data at offset "
921  "%zd\n", image->name, png->offset );
922  rc = -EINVAL;
923  goto err_truncated;
924  }
925 
926  /* Handle chunk */
927  if ( ( rc = png_chunk ( image, png, header->type,
928  chunk_len ) ) != 0 )
929  goto err_chunk;
930 
931  /* Move to next chunk */
932  png->offset += ( chunk_len + sizeof ( *footer ) );
933 
934  } while ( png->offset < image->len );
935 
936  /* Check that we finished with an IEND chunk */
937  if ( header->type != htonl ( PNG_TYPE_IEND ) ) {
938  DBGC ( image, "PNG %s did not finish with IEND\n",
939  image->name );
940  rc = -EINVAL;
941  goto err_iend;
942  }
943 
944  /* Return pixel buffer */
945  *pixbuf = pixbuf_get ( png->pixbuf );
946 
947  /* Success */
948  rc = 0;
949 
950  err_iend:
951  err_chunk:
952  err_truncated:
953  pixbuf_put ( png->pixbuf );
954  ufree ( png->raw.data );
955  free ( png );
956  err_alloc:
957  return rc;
958 }
959 
960 /**
961  * Probe PNG image
962  *
963  * @v image PNG image
964  * @ret rc Return status code
965  */
966 static int png_probe ( struct image *image ) {
967  const struct png_signature *signature;
968 
969  /* Sanity check */
970  if ( image->len < sizeof ( *signature ) ) {
971  DBGC ( image, "PNG %s is too short\n", image->name );
972  return -ENOEXEC;
973  }
974 
975  /* Check signature */
976  signature = image->data;
977  if ( memcmp ( signature, &png_signature, sizeof ( *signature ) ) != 0 ){
978  DBGC ( image, "PNG %s has invalid signature\n", image->name );
979  return -ENOEXEC;
980  }
981 
982  return 0;
983 }
984 
985 /** PNG image type */
986 struct image_type png_image_type __image_type ( PROBE_NORMAL ) = {
987  .name = "PNG",
988  .probe = png_probe,
989  .pixbuf = png_pixbuf,
990 };
void * data
Data.
Definition: deflate.h:248
static __always_inline void ufree(void *ptr)
Free external memory.
Definition: umalloc.h:68
#define EINVAL
Invalid argument.
Definition: errno.h:429
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
RGB colour is used.
Definition: png.h:102
uint32_t palette[PNG_PALETTE_COUNT]
Palette, in iPXE's pixel buffer format.
Definition: png.c:61
unsigned int(* unfilter)(unsigned int current, unsigned int left, unsigned int above, unsigned int above_left)
Unfilter byte.
Definition: png.c:477
struct pixel_buffer * alloc_pixbuf(unsigned int width, unsigned int height)
Allocate pixel buffer.
Definition: pixbuf.c:60
static size_t png_scanline_len(struct png_context *png, struct png_interlace *interlace)
Calculate PNG scanline length.
Definition: png.c:184
static int png_chunk(struct image *image, struct png_context *png, uint32_t type, size_t len)
Handle PNG chunk.
Definition: png.c:851
#define max(x, y)
Definition: ath.h:41
Chunk is ancillary.
Definition: png.h:43
Portable Network Graphics (PNG) format.
uint32_t height
Height.
Definition: png.h:84
struct image_type png_image_type __image_type(PROBE_NORMAL)
PNG image type.
unsigned int x_indent
X starting indent.
Definition: png.c:74
static int png_palette(struct image *image, struct png_context *png, size_t len)
Handle PNG palette chunk.
Definition: png.c:299
UINT8_t filter
Receive packet filter.
Definition: pxe_api.h:68
Error codes.
const void * data
Read-only data.
Definition: image.h:51
uint8_t blue
Blue.
Definition: png.h:146
unsigned int height
Height.
Definition: pixbuf.h:23
static void png_pixels(struct image *image, struct png_context *png)
Fill PNG pixels.
Definition: png.c:752
Alpha channel is used.
Definition: png.h:104
static int png_unfilter(struct image *image, struct png_context *png)
Unfilter PNG raw data.
Definition: png.c:579
#define ENOEXEC
Exec format error.
Definition: errno.h:520
static const char * png_type_name(uint32_t type)
Transcribe PNG chunk type name (for debugging)
Definition: png.c:102
unsigned int y_stride
Y stride.
Definition: png.c:80
size_t offset
Offset within image.
Definition: png.c:47
uint32_t type
Operating system type.
Definition: ena.h:12
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int png_image_data(struct image *image, struct png_context *png, size_t len)
Handle PNG image data chunk.
Definition: png.c:336
#define DBGC(...)
Definition: compiler.h:505
uint32_t width
Width.
Definition: png.h:82
struct deflate_chunk raw
Decompression buffer for raw PNG data.
Definition: png.c:64
An executable image type.
Definition: image.h:95
static unsigned int x
Definition: pixbuf.h:63
#define PROBE_NORMAL
Normal image probe priority.
Definition: image.h:156
#define ntohl(value)
Definition: byteswap.h:135
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:412
int(* handle)(struct image *image, struct png_context *png, size_t len)
Handle chunk.
Definition: png.c:830
union @18 u
#define PNG_SIGNATURE
PNG file signature.
Definition: png.h:24
An executable image.
Definition: image.h:24
Pixel buffer.
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:428
No filtering.
Definition: png.h:164
unsigned int pass
Pass number.
Definition: png.c:72
static struct png_chunk_handler png_chunk_handlers[]
PNG chunk handlers.
Definition: png.c:835
#define htonl(value)
Definition: byteswap.h:134
Above byte used as predictor.
Definition: png.h:168
char * name
Name of this image type.
Definition: image.h:97
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
unsigned int width
Width.
Definition: png.c:82
#define abs(x)
Definition: ath.h:46
unsigned int depth
Bit depth.
Definition: png.c:53
#define PNG_TYPE_IDAT
PNG image data chunk type.
Definition: png.h:159
First unknown filter method.
Definition: png.h:123
A PNG image header.
Definition: png.h:80
#define ENOMEM
Not enough space.
Definition: errno.h:535
Adam7 interlacing.
Definition: png.h:131
A chunk of data.
Definition: deflate.h:246
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
Definition: deflate.c:992
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:378
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:458
PNG context.
Definition: png.c:45
uint8_t colour_type
Colour type.
Definition: png.h:88
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static int deflate_finished(struct deflate *deflate)
Check if decompression has finished.
Definition: deflate.h:278
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
ring len
Length.
Definition: dwmac.h:231
A PNG interlace pass.
Definition: png.c:70
#define PNG_TYPE_IEND
PNG image end chunk type.
Definition: png.h:176
Palette is used.
Definition: png.h:100
Above and left bytes used as predictors.
Definition: png.h:170
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
uint32_t * data
32-bit (8:8:8:8) xRGB pixel data, in host-endian order
Definition: pixbuf.h:25
A PNG filter.
Definition: png.c:467
ZLIB header and footer.
Definition: deflate.h:21
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#define PNG_PALETTE_COUNT
Maximum number of PNG palette entries.
Definition: png.h:156
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
size_t len
Length of raw file image.
Definition: image.h:56
Paeth filter.
Definition: png.h:172
A pixel buffer.
Definition: pixbuf.h:17
User memory allocation.
unsigned char uint8_t
Definition: stdint.h:10
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:361
FILE_SECBOOT(PERMITTED)
A PNG chunk handler.
Definition: png.c:819
unsigned int x_stride
X stride.
Definition: png.c:78
int deflate_inflate(struct deflate *deflate, const void *data, size_t len, struct deflate_chunk *out)
Inflate compressed data.
Definition: deflate.c:484
size_t offset
Current offset.
Definition: deflate.h:250
static int png_pixbuf(struct image *image, struct pixel_buffer **pixbuf)
Convert PNG image to pixel buffer.
Definition: png.c:885
A PNG palette chunk.
Definition: png.h:150
unsigned int uint32_t
Definition: stdint.h:12
struct deflate deflate
Decompressor.
Definition: png.c:66
unsigned char byte
Definition: smc9000.h:38
unsigned int colour_type
Colour type.
Definition: png.c:55
static int png_probe(struct image *image)
Probe PNG image.
Definition: png.c:966
Left byte used as predictor.
Definition: png.h:166
struct pixel_buffer * pixbuf
Pixel buffer.
Definition: png.c:50
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:636
#define PNG_TYPE_IHDR
PNG image header chunk type.
Definition: png.h:77
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:395
uint32_t type
Chunk type.
Definition: png.c:821
static struct png_filter png_filters[]
PNG filter types.
Definition: png.c:484
uint8_t compression
Compression method.
Definition: png.h:90
static volatile void * bits
Definition: bitops.h:28
#define DBGC2(...)
Definition: compiler.h:522
static uint8_t png_interlace_passes[]
Number of interlacing passes.
Definition: png.c:91
No interlacing.
Definition: png.h:129
First unknown interlace method.
Definition: png.h:133
static __always_inline void * umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:57
First unknown compression method.
Definition: png.h:115
static unsigned int unsigned int y
Definition: pixbuf.h:63
static int png_image_end(struct image *image, struct png_context *png, size_t len)
Handle PNG image end chunk.
Definition: png.c:781
struct ena_llq_option header
Header locations.
Definition: ena.h:16
static int png_image_header(struct image *image, struct png_context *png, size_t len)
Handle PNG image header chunk.
Definition: png.c:199
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:503
uint8_t data[48]
Additional event data.
Definition: ena.h:22
A PNG palette entry.
Definition: png.h:140
unsigned int passes
Number of interlace passes.
Definition: png.c:59
uint8_t interlace
Interlace method.
Definition: png.h:94
__be32 raw[7]
Definition: CIB_PRM.h:28
uint8_t filter
Filter method.
Definition: png.h:92
A PNG file signature.
Definition: png.h:18
uint8_t depth
Bit depth.
Definition: png.h:86
DEFLATE decompression algorithm.
static unsigned int png_pixel_len(struct png_context *png)
Calculate PNG pixel length.
Definition: png.c:172
#define PNG_TYPE_PLTE
PNG palette chunk type.
Definition: png.h:137
A PNG chunk header.
Definition: png.h:27
static void png_interlace(struct png_context *png, unsigned int pass, struct png_interlace *interlace)
Calculate PNG interlace pass parameters.
Definition: png.c:119
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
unsigned int channels
Number of channels.
Definition: png.c:57
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
char * name
Name.
Definition: image.h:38
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t len
Length of data.
Definition: deflate.h:252
String functions.
unsigned int height
Height.
Definition: png.c:84
uint8_t green
Green.
Definition: png.h:144
uint8_t red
Red.
Definition: png.h:142
unsigned int y_indent
Y starting indent.
Definition: png.c:76
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:613
Decompressor.
Definition: deflate.h:156