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  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 */
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  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 }
328 
329 /**
330  * Handle PNG image data chunk
331  *
332  * @v image PNG image
333  * @v png PNG context
334  * @v len Chunk length
335  * @ret rc Return status code
336  */
337 static int png_image_data ( struct image *image, struct png_context *png,
338  size_t len ) {
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 }
353 
354 /**
355  * Unfilter byte using the "None" filter
356  *
357  * @v current Filtered current byte
358  * @v left Unfiltered left byte
359  * @v above Unfiltered above byte
360  * @v above_left Unfiltered above-left byte
361  * @ret current Unfiltered current byte
362  */
363 static unsigned int png_unfilter_none ( unsigned int current,
364  unsigned int left __unused,
365  unsigned int above __unused,
366  unsigned int above_left __unused ) {
367 
368  return current;
369 }
370 
371 /**
372  * Unfilter byte using the "Sub" filter
373  *
374  * @v current Filtered current byte
375  * @v left Unfiltered left byte
376  * @v above Unfiltered above byte
377  * @v above_left Unfiltered above-left byte
378  * @ret current Unfiltered current byte
379  */
380 static unsigned int png_unfilter_sub ( unsigned int current,
381  unsigned int left,
382  unsigned int above __unused,
383  unsigned int above_left __unused ) {
384 
385  return ( current + left );
386 }
387 
388 /**
389  * Unfilter byte using the "Up" filter
390  *
391  * @v current Filtered current byte
392  * @v left Unfiltered left byte
393  * @v above Unfiltered above byte
394  * @v above_left Unfiltered above-left byte
395  * @ret current Unfiltered current byte
396  */
397 static unsigned int png_unfilter_up ( unsigned int current,
398  unsigned int left __unused,
399  unsigned int above,
400  unsigned int above_left __unused ) {
401 
402  return ( current + above );
403 }
404 
405 /**
406  * Unfilter byte using the "Average" filter
407  *
408  * @v current Filtered current byte
409  * @v left Unfiltered left byte
410  * @v above Unfiltered above byte
411  * @v above_left Unfiltered above-left byte
412  * @ret current Unfiltered current byte
413  */
414 static unsigned int png_unfilter_average ( unsigned int current,
415  unsigned int left,
416  unsigned int above,
417  unsigned int above_left __unused ) {
418 
419  return ( current + ( ( above + left ) >> 1 ) );
420 }
421 
422 /**
423  * Paeth predictor function (defined in RFC 2083)
424  *
425  * @v a Pixel A
426  * @v b Pixel B
427  * @v c Pixel C
428  * @ret predictor Predictor pixel
429  */
430 static unsigned int png_paeth_predictor ( unsigned int a, unsigned int b,
431  unsigned int c ) {
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 }
450 
451 /**
452  * Unfilter byte using the "Paeth" filter
453  *
454  * @v current Filtered current byte
455  * @v above_left Unfiltered above-left byte
456  * @v above Unfiltered above byte
457  * @v left Unfiltered left byte
458  * @ret current Unfiltered current byte
459  */
460 static unsigned int png_unfilter_paeth ( unsigned int current,
461  unsigned int left,
462  unsigned int above,
463  unsigned int above_left ) {
464 
465  return ( current + png_paeth_predictor ( left, above, above_left ) );
466 }
467 
468 /** A PNG filter */
469 struct png_filter {
470  /**
471  * Unfilter byte
472  *
473  * @v current Filtered current byte
474  * @v left Unfiltered left byte
475  * @v above Unfiltered above byte
476  * @v above_left Unfiltered above-left byte
477  * @ret current Unfiltered current byte
478  */
479  unsigned int ( * unfilter ) ( unsigned int current,
480  unsigned int left,
481  unsigned int above,
482  unsigned int above_left );
483 };
484 
485 /** PNG filter types */
486 static struct png_filter png_filters[] = {
492 };
493 
494 /**
495  * Unfilter one interlace pass of PNG raw data
496  *
497  * @v image PNG image
498  * @v png PNG context
499  * @v interlace Interlace pass
500  * @ret rc Return status code
501  *
502  * This routine may assume that it is impossible to overrun the raw
503  * data buffer, since the size is determined by the image dimensions.
504  */
505 static int png_unfilter_pass ( struct image *image, struct png_context *png,
506  struct png_interlace *interlace ) {
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 }
583 
584 /**
585  * Unfilter PNG raw data
586  *
587  * @v image PNG image
588  * @v png PNG context
589  * @ret rc Return status code
590  *
591  * This routine may assume that it is impossible to overrun the raw
592  * data buffer, since the size is determined by the image dimensions.
593  */
594 static int png_unfilter ( struct image *image, struct png_context *png ) {
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 }
619 
620 /**
621  * Calculate PNG pixel component value
622  *
623  * @v raw Raw component value
624  * @v alpha Alpha value
625  * @v max Maximum raw/alpha value
626  * @ret value Component value in range 0-255
627  */
628 static inline unsigned int png_pixel ( unsigned int raw, unsigned int alpha,
629  unsigned int max ) {
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 }
639 
640 /**
641  * Fill one interlace pass of PNG pixels
642  *
643  * @v image PNG image
644  * @v png PNG context
645  * @v interlace Interlace pass
646  *
647  * This routine may assume that it is impossible to overrun either the
648  * raw data buffer or the pixel buffer, since the sizes of both are
649  * determined by the image dimensions.
650  */
651 static void png_pixels_pass ( struct image *image,
652  struct png_context *png,
653  struct png_interlace *interlace ) {
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 }
761 
762 /**
763  * Fill PNG pixels
764  *
765  * @v image PNG image
766  * @v png PNG context
767  *
768  * This routine may assume that it is impossible to overrun either the
769  * raw data buffer or the pixel buffer, since the sizes of both are
770  * determined by the image dimensions.
771  */
772 static void png_pixels ( struct image *image, struct png_context *png ) {
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 }
792 
793 /**
794  * Handle PNG image end chunk
795  *
796  * @v image PNG image
797  * @v png PNG context
798  * @v len Chunk length
799  * @ret rc Return status code
800  */
801 static int png_image_end ( struct image *image, struct png_context *png,
802  size_t len ) {
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 }
837 
838 /** A PNG chunk handler */
840  /** Chunk type */
842  /**
843  * Handle chunk
844  *
845  * @v image PNG image
846  * @v png PNG context
847  * @v len Chunk length
848  * @ret rc Return status code
849  */
850  int ( * handle ) ( struct image *image, struct png_context *png,
851  size_t len );
852 };
853 
854 /** PNG chunk handlers */
860 };
861 
862 /**
863  * Handle PNG chunk
864  *
865  * @v image PNG image
866  * @v png PNG context
867  * @v type Chunk type
868  * @v len Chunk length
869  * @ret rc Return status code
870  */
871 static int png_chunk ( struct image *image, struct png_context *png,
872  uint32_t type, size_t len ) {
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 }
897 
898 /**
899  * Convert PNG image to pixel buffer
900  *
901  * @v image PNG image
902  * @v pixbuf Pixel buffer to fill in
903  * @ret rc Return status code
904  */
905 static int png_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
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 }
980 
981 /**
982  * Probe PNG image
983  *
984  * @v image PNG image
985  * @ret rc Return status code
986  */
987 static int png_probe ( struct image *image ) {
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 }
1005 
1006 /** PNG image type */
1007 struct image_type png_image_type __image_type ( PROBE_NORMAL ) = {
1008  .name = "PNG",
1009  .probe = png_probe,
1010  .pixbuf = png_pixbuf,
1011 };
int deflate_inflate(struct deflate *deflate, struct deflate_chunk *in, struct deflate_chunk *out)
Inflate compressed data.
Definition: deflate.c:492
uint32_t c
Definition: md4.c:30
#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:479
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
static int png_chunk(struct image *image, struct png_context *png, uint32_t type, size_t len)
Handle PNG chunk.
Definition: png.c:871
#define max(x, y)
Definition: ath.h:39
__be32 in[4]
Definition: CIB_PRM.h:35
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.
uint8_t blue
Blue.
Definition: png.h:145
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:772
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:594
#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
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
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:337
#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:76
#define PROBE_NORMAL
Normal image probe priority.
Definition: image.h:137
#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:414
int(* handle)(struct image *image, struct png_context *png, size_t len)
Handle chunk.
Definition: png.c:850
#define PNG_SIGNATURE
PNG file signature.
Definition: png.h:23
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:430
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:855
#define htonl(value)
Definition: byteswap.h:133
Above byte used as predictor.
Definition: png.h:167
uint32_t a
Definition: md4.c:28
char * name
Name of this image type.
Definition: image.h:78
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
unsigned int width
Width.
Definition: png.c:81
#define abs(x)
Definition: ath.h:44
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:241
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
Definition: deflate.c:999
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
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:460
PNG context.
Definition: png.c:44
uint8_t colour_type
Colour type.
Definition: png.h:87
static int deflate_finished(struct deflate *deflate)
Check if decompression has finished.
Definition: deflate.h:273
A PNG interlace pass.
Definition: png.c:69
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#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
A PNG filter.
Definition: png.c:469
ZLIB header and footer.
Definition: deflate.h:21
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
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:624
size_t len
Length of raw file image.
Definition: image.h:43
Paeth filter.
Definition: png.h:171
A pixel buffer.
Definition: pixbuf.h:17
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
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:363
A PNG chunk handler.
Definition: png.c:839
unsigned int x_stride
X stride.
Definition: png.c:77
size_t offset
Current offset.
Definition: deflate.h:245
static int png_pixbuf(struct image *image, struct pixel_buffer **pixbuf)
Convert PNG image to pixel buffer.
Definition: png.c:905
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:987
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:651
#define PNG_TYPE_IHDR
PNG image header chunk type.
Definition: png.h:76
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
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
uint32_t type
Chunk type.
Definition: png.c:841
static struct png_filter png_filters[]
PNG filter types.
Definition: png.c:486
uint8_t compression
Compression method.
Definition: png.h:89
static volatile void * bits
Definition: bitops.h:27
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
#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
First unknown compression method.
Definition: png.h:114
static int png_image_end(struct image *image, struct png_context *png, size_t len)
Handle PNG image end chunk.
Definition: png.c:801
uint32_t b
Definition: md4.c:29
struct ena_aq_header header
Header.
Definition: ena.h:12
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:505
union @17 u
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
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
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
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:34
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
size_t len
Length of data.
Definition: deflate.h:247
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:21
static unsigned int png_pixel(unsigned int raw, unsigned int alpha, unsigned int max)
Calculate PNG pixel component value.
Definition: png.c:628
Decompressor.
Definition: deflate.h:156