These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / 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 };