[fdt] Add ability to parse a MAC address from a flattened device tree
[ipxe.git] / src / image / png.c
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 */
49 struct pixel_buffer *pixbuf;
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 */
60 uint32_t palette[PNG_PALETTE_COUNT];
61
62 /** Decompression buffer for raw PNG data */
63 struct deflate_chunk raw;
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 */
87 static struct png_signature png_signature = PNG_SIGNATURE;
88
89 /** Number of interlacing passes */
90 static uint8_t png_interlace_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 */
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 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[] = {
487 [PNG_FILTER_BASIC_NONE] = { png_unfilter_none },
488 [PNG_FILTER_BASIC_SUB] = { png_unfilter_sub },
489 [PNG_FILTER_BASIC_UP] = { png_unfilter_up },
490 [PNG_FILTER_BASIC_AVERAGE] = { png_unfilter_average },
491 [PNG_FILTER_BASIC_PAETH] = { png_unfilter_paeth },
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 */
839 struct png_chunk_handler {
840 /** Chunk type */
841 uint32_t 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 */
855 static struct png_chunk_handler png_chunk_handlers[] = {
856 { htonl ( PNG_TYPE_IHDR ), png_image_header },
857 { htonl ( PNG_TYPE_PLTE ), png_palette },
858 { htonl ( PNG_TYPE_IDAT ), png_image_data },
859 { htonl ( PNG_TYPE_IEND ), png_image_end },
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 ) ) {
928 DBGC ( image, "PNG %s truncated chunk header at offset "
929 "%zd\n", image->name, png->offset );
930 rc = -EINVAL;
931 goto err_truncated;
932 }
933 copy_from_user ( &header, image->data, png->offset,
934 sizeof ( header ) );
935 png->offset += sizeof ( header );
936
937 /* Validate chunk length */
938 chunk_len = ntohl ( header.len );
939 if ( remaining < ( sizeof ( header ) + chunk_len +
940 sizeof ( footer ) ) ) {
941 DBGC ( image, "PNG %s truncated chunk data/footer at "
942 "offset %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 };