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