|
| | FILE_LICENCE (GPL2_OR_LATER_OR_UBDL) |
| | FILE_SECBOOT (PERMITTED) |
| static const char * | png_type_name (uint32_t type) |
| | Transcribe PNG chunk type name (for debugging)
|
| static void | png_interlace (struct png_context *png, unsigned int pass, struct png_interlace *interlace) |
| | Calculate PNG interlace pass parameters.
|
| static unsigned int | png_pixel_len (struct png_context *png) |
| | Calculate PNG pixel length.
|
| static size_t | png_scanline_len (struct png_context *png, struct png_interlace *interlace) |
| | Calculate PNG scanline length.
|
| static int | png_image_header (struct image *image, struct png_context *png, size_t len) |
| | Handle PNG image header chunk.
|
| static int | png_palette (struct image *image, struct png_context *png, size_t len) |
| | Handle PNG palette chunk.
|
| static int | png_image_data (struct image *image, struct png_context *png, size_t len) |
| | Handle PNG image data chunk.
|
| 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.
|
| 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.
|
| 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.
|
| 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.
|
| static unsigned int | png_paeth_predictor (unsigned int a, unsigned int b, unsigned int c) |
| | Paeth predictor function (defined in RFC 2083)
|
| 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.
|
| static int | png_unfilter_pass (struct image *image, struct png_context *png, struct png_interlace *interlace) |
| | Unfilter one interlace pass of PNG raw data.
|
| static int | png_unfilter (struct image *image, struct png_context *png) |
| | Unfilter PNG raw data.
|
| static unsigned int | png_pixel (unsigned int raw, unsigned int alpha, unsigned int max) |
| | Calculate PNG pixel component value.
|
| static void | png_pixels_pass (struct image *image, struct png_context *png, struct png_interlace *interlace) |
| | Fill one interlace pass of PNG pixels.
|
| static void | png_pixels (struct image *image, struct png_context *png) |
| | Fill PNG pixels.
|
| static int | png_image_end (struct image *image, struct png_context *png, size_t len) |
| | Handle PNG image end chunk.
|
| static int | png_chunk (struct image *image, struct png_context *png, uint32_t type, size_t len) |
| | Handle PNG chunk.
|
| static int | png_pixbuf (struct image *image, struct pixel_buffer **pixbuf) |
| | Convert PNG image to pixel buffer.
|
| static int | png_probe (struct image *image) |
| | Probe PNG image.
|
| struct image_type png_image_type | __image_type (PROBE_NORMAL) |
| | PNG image type.
|
Portable Network Graphics (PNG) format.
The PNG format is defined in RFC 2083.
Definition in file png.c.
| void png_interlace |
( |
struct png_context * | png, |
|
|
unsigned int | pass, |
|
|
struct png_interlace * | interlace ) |
|
static |
Calculate PNG interlace pass parameters.
- Parameters
-
| png | PNG context |
| pass | Pass number (0=first pass) |
| interlace | Interlace pass to fill in |
Definition at line 119 of file png.c.
120 {
121 unsigned int grid_width_log2;
122 unsigned int grid_height_log2;
123 unsigned int x_indent;
124 unsigned int y_indent;
125 unsigned int x_stride_log2;
126 unsigned int y_stride_log2;
127 unsigned int x_stride;
128 unsigned int y_stride;
129 unsigned int width;
130 unsigned int height;
131
132
134
135
136 interlace->
pass = pass;
137
138
139 grid_width_log2 = ( png->
passes / 2 );
140 grid_height_log2 = ( ( png->
passes - 1 ) / 2 );
141
142
144 ( ( pass & 1 ) ?
145 ( 1 << ( grid_width_log2 - ( pass / 2 ) - 1 ) ) : 0 );
147 ( ( pass && ! ( pass & 1 ) ) ?
148 ( 1 << ( grid_height_log2 - ( ( pass - 1 ) / 2 ) - 1 ) ) : 0);
149
150
151 x_stride_log2 = ( grid_width_log2 - ( pass / 2 ) );
152 y_stride_log2 =
153 ( grid_height_log2 - ( pass ? ( ( pass - 1 ) / 2 ) : 0 ) );
154 interlace->
x_stride = x_stride = ( 1 << x_stride_log2 );
155 interlace->
y_stride = y_stride = ( 1 << y_stride_log2 );
156
157
161 ( ( width - x_indent + x_stride - 1 ) >> x_stride_log2 );
163 ( ( height - y_indent + y_stride - 1 ) >> y_stride_log2 );
164}
#define assert(condition)
Assert a condition at run-time.
unsigned int height
Height.
struct pixel_buffer * pixbuf
Pixel buffer.
unsigned int passes
Number of interlace passes.
unsigned int x_stride
X stride.
unsigned int height
Height.
unsigned int y_stride
Y stride.
unsigned int y_indent
Y starting indent.
unsigned int x_indent
X starting indent.
unsigned int pass
Pass number.
References assert, pixel_buffer::height, png_interlace::height, png_interlace::pass, png_context::passes, png_context::pixbuf, pixel_buffer::width, png_interlace::width, png_interlace::x_indent, png_interlace::x_stride, png_interlace::y_indent, and png_interlace::y_stride.
Referenced by png_image_header(), png_pixels(), and png_unfilter().
Handle PNG image header chunk.
- Parameters
-
| image | PNG image |
| png | PNG context |
| len | Chunk length |
- Return values
-
Definition at line 199 of file png.c.
200 {
204
205
206 if (
len !=
sizeof ( *ihdr ) ) {
207 DBGC (
image,
"PNG %s invalid IHDR length %zd\n",
210 }
214 }
215
216
218 DBGC (
image,
"PNG %s %dx%d depth %d type %d compression %d filter %d "
222
223
225 DBGC (
image,
"PNG %s unknown compression method %d\n",
228 }
230 DBGC (
image,
"PNG %s unknown filter method %d\n",
233 }
235 DBGC (
image,
"PNG %s unknown interlace method %d\n",
238 }
239
240
244 DBGC (
image,
"PNG %s could not allocate pixel buffer\n",
247 }
248
249
251 if ( ( png->
depth == 0 ) ||
252 ( ( png->
depth & ( png->
depth - 1 ) ) != 0 ) ) {
253 DBGC (
image,
"PNG %s invalid depth %d\n",
256 }
257
258
266 }
267
268
270
271
274 if ( interlace.width == 0 )
275 continue;
276 png->
raw.
len += ( interlace.height *
278 }
279
280
283 DBGC (
image,
"PNG %s could not allocate data buffer\n",
286 }
287
288 return 0;
289}
#define EINVAL
Invalid argument.
#define ENOMEM
Not enough space.
#define ENOTSUP
Operation not supported.
static __always_inline void * umalloc(size_t size)
Allocate external memory.
struct pixel_buffer * alloc_pixbuf(unsigned int width, unsigned int height)
Allocate pixel buffer.
static uint8_t png_interlace_passes[]
Number of interlacing passes.
static size_t png_scanline_len(struct png_context *png, struct png_interlace *interlace)
Calculate PNG scanline length.
static void png_interlace(struct png_context *png, unsigned int pass, struct png_interlace *interlace)
Calculate PNG interlace pass parameters.
@ PNG_FILTER_UNKNOWN
First unknown filter method.
@ PNG_INTERLACE_UNKNOWN
First unknown interlace method.
@ PNG_COLOUR_TYPE_ALPHA
Alpha channel is used.
@ PNG_COLOUR_TYPE_PALETTE
Palette is used.
@ PNG_COLOUR_TYPE_RGB
RGB colour is used.
@ PNG_COMPRESSION_UNKNOWN
First unknown compression method.
size_t len
Length of data.
const void * data
Read-only data.
size_t offset
Offset within image.
struct deflate_chunk raw
Decompression buffer for raw PNG data.
unsigned int colour_type
Colour type.
References alloc_pixbuf(), png_context::channels, png_context::colour_type, png_image_header::colour_type, png_image_header::compression, deflate_chunk::data, image::data, DBGC, png_context::depth, png_image_header::depth, EINVAL, ENOMEM, ENOTSUP, png_image_header::filter, png_image_header::height, png_interlace::height, png_image_header::interlace, deflate_chunk::len, len, image::name, ntohl, png_context::offset, png_interlace::pass, png_context::passes, png_context::pixbuf, PNG_COLOUR_TYPE_ALPHA, PNG_COLOUR_TYPE_PALETTE, PNG_COLOUR_TYPE_RGB, PNG_COMPRESSION_UNKNOWN, PNG_FILTER_UNKNOWN, png_interlace(), png_interlace_passes, PNG_INTERLACE_UNKNOWN, png_scanline_len(), png_context::raw, umalloc(), png_image_header::width, and png_interlace::width.
Unfilter one interlace pass of PNG raw data.
- Parameters
-
| image | PNG image |
| png | PNG context |
| interlace | Interlace pass |
- Return values
-
This routine may assume that it is impossible to overrun the raw data buffer, since the size is determined by the image dimensions.
Definition at line 503 of file png.c.
504 {
509 unsigned int scanline;
511 unsigned int filter_type;
512 unsigned int left;
513 unsigned int above;
514 unsigned int above_left;
515
516
517
518
519 above = 0;
520
521
522 for ( scanline = 0 ; scanline < interlace->
height ; scanline++ ) {
523
524
525 filter_type = *(
data++);
528 DBGC (
image,
"PNG %s unknown filter type %d\n",
531 }
534 DBGC2 (
image,
"PNG %s pass %d scanline %d filter type %d\n",
536
537
538
539
540 left = 0;
541 above_left = 0;
542
543
544 for ( byte = 0 ; byte < ( scanline_len - 1 ) ; byte++ ) {
545
546
547 if ( byte >= pixel_len )
548 left = *(
data - pixel_len );
549 if ( scanline > 0 )
550 above = *(
data - scanline_len );
551 if ( ( scanline > 0 ) && ( byte >= pixel_len ) ) {
552 above_left = *(
data - scanline_len -
553 pixel_len );
554 }
555
556
558 above_left );
560 }
561 }
562
563
565
566 return 0;
567}
#define NULL
NULL pointer (VOID *)
uint8_t data[48]
Additional event data.
static unsigned int png_pixel_len(struct png_context *png)
Calculate PNG pixel length.
static struct png_filter png_filters[]
PNG filter types.
UINT8_t filter
Receive packet filter.
size_t offset
Current offset.
References assert, data, deflate_chunk::data, DBGC, DBGC2, ENOTSUP, filter, png_interlace::height, image::name, NULL, deflate_chunk::offset, png_interlace::pass, png_filters, png_pixel_len(), png_scanline_len(), and png_context::raw.
Referenced by png_unfilter().
Unfilter PNG raw data.
- Parameters
-
| image | PNG image |
| png | PNG context |
- Return values
-
This routine may assume that it is impossible to overrun the raw data buffer, since the size is determined by the image dimensions.
Definition at line 579 of file png.c.
579 {
583
584
587
588
590
591
592 if ( interlace.width == 0 )
593 continue;
594
595
597 &interlace ) ) != 0 )
599 }
601
602 return 0;
603}
static int png_unfilter_pass(struct image *image, struct png_context *png, struct png_interlace *interlace)
Unfilter one interlace pass of PNG raw data.
References assert, deflate_chunk::len, deflate_chunk::offset, png_interlace::pass, png_context::passes, png_interlace(), png_unfilter_pass(), png_context::raw, rc, and png_interlace::width.
Referenced by png_image_end().
Fill one interlace pass of PNG pixels.
- Parameters
-
| image | PNG image |
| png | PNG context |
| interlace | Interlace pass |
This routine may assume that it is impossible to overrun either the raw data buffer or the pixel buffer, since the sizes of both are determined by the image dimensions.
Definition at line 636 of file png.c.
638 {
644 size_t data_stride;
645 unsigned int pixbuf_y_index;
646 unsigned int pixbuf_index;
647 unsigned int pixbuf_x_stride;
648 unsigned int pixbuf_y_stride;
651 unsigned int c;
653 unsigned int depth;
655 unsigned int alpha;
660
661
662
663
665 data_stride = ( ( depth + 7 ) / 8 );
666 if ( depth > 8 )
667 depth = 8;
668 max = ( ( 1 << depth ) - 1 );
669
670
673 pixbuf_x_stride = interlace->
x_stride;
675 DBGC2 (
image,
"PNG %s pass %d %dx%d at (%d,%d) stride (%d,%d)\n",
679
680
681 for (
y = 0 ;
y < interlace->
height ;
y++ ) {
682
683
685
686
688 pixbuf_index = pixbuf_y_index;
689 for (
x = 0 ;
x < interlace->
width ;
x++ ) {
690
691
692 for ( c = 0 ; c < png->
channels ; c++ ) {
693
694
695 current <<= depth;
701 }
702
703
704 channel[c] = ( current >> ( 8 - depth ) );
705 }
706
707
708 if ( is_indexed ) {
709
710
712
713 } else {
714
715
716 alpha = ( has_alpha ?
718
719
720 pixel = 0;
721 for ( c = 0 ; c < 3 ; c++ ) {
725 pixel = ( ( pixel << 8 ) |
value );
726 }
727 }
728
729
731 pixbuf_index += pixbuf_x_stride;
732 }
733
734
735 pixbuf_y_index += pixbuf_y_stride;
736 }
737
738
740}
pseudo_bit_t value[0x00020]
static volatile void * bits
uint32_t channel
RNDIS channel.
static unsigned int unsigned int y
static unsigned int png_pixel(unsigned int raw, unsigned int alpha, unsigned int max)
Calculate PNG pixel component value.
uint32_t * data
32-bit (8:8:8:8) xRGB pixel data, in host-endian order
References assert, bits, channel, png_context::channels, png_context::colour_type, data, deflate_chunk::data, pixel_buffer::data, DBGC2, png_context::depth, png_interlace::height, max, image::name, deflate_chunk::offset, png_context::palette, png_interlace::pass, png_context::pixbuf, PNG_COLOUR_TYPE_ALPHA, PNG_COLOUR_TYPE_PALETTE, PNG_COLOUR_TYPE_RGB, png_pixel(), png_context::raw, raw, value, pixel_buffer::width, png_interlace::width, x, png_interlace::x_indent, png_interlace::x_stride, y, png_interlace::y_indent, and png_interlace::y_stride.
Referenced by png_pixels().
Fill PNG pixels.
- Parameters
-
| image | PNG image |
| png | PNG context |
This routine may assume that it is impossible to overrun either the raw data buffer or the pixel buffer, since the sizes of both are determined by the image dimensions.
Definition at line 752 of file png.c.
752 {
755
756
759
760
762
763
764 if ( interlace.width == 0 )
765 continue;
766
767
769 }
771}
static void png_pixels_pass(struct image *image, struct png_context *png, struct png_interlace *interlace)
Fill one interlace pass of PNG pixels.
References assert, deflate_chunk::len, deflate_chunk::offset, png_interlace::pass, png_context::passes, png_interlace(), png_pixels_pass(), png_context::raw, and png_interlace::width.
Referenced by png_image_end().
Convert PNG image to pixel buffer.
- Parameters
-
| image | PNG image |
| pixbuf | Pixel buffer to fill in |
- Return values
-
Definition at line 885 of file png.c.
885 {
889 size_t remaining;
890 size_t chunk_len;
892
893
894 png =
zalloc (
sizeof ( *png ) );
895 if ( ! png ) {
897 goto err_alloc;
898 }
901
902
903 do {
904
905
907 if ( remaining < (
sizeof ( *
header ) +
sizeof ( *footer ) ) ){
908 DBGC (
image,
"PNG %s truncated chunk header/footer "
911 goto err_truncated;
912 }
914 png->
offset +=
sizeof ( *header );
915
916
918 if ( chunk_len > ( remaining -
sizeof ( *
header ) -
919 sizeof ( *footer ) ) ) {
920 DBGC (
image,
"PNG %s truncated chunk data at offset "
923 goto err_truncated;
924 }
925
926
928 chunk_len ) ) != 0 )
929 goto err_chunk;
930
931
932 png->
offset += ( chunk_len +
sizeof ( *footer ) );
933
935
936
938 DBGC (
image,
"PNG %s did not finish with IEND\n",
941 goto err_iend;
942 }
943
944
945 *pixbuf = pixbuf_get ( png->
pixbuf );
946
947
949
950 err_iend:
951 err_chunk:
952 err_truncated:
953 pixbuf_put ( png->
pixbuf );
956 err_alloc:
958}
void deflate_init(struct deflate *deflate, enum deflate_format format)
Initialise decompressor.
@ DEFLATE_ZLIB
ZLIB header and footer.
struct ena_llq_option header
Header locations.
static __always_inline void ufree(void *ptr)
Free external memory.
void * zalloc(size_t size)
Allocate cleared memory.
static int png_chunk(struct image *image, struct png_context *png, uint32_t type, size_t len)
Handle PNG chunk.
#define PNG_TYPE_IEND
PNG image end chunk type.
static void(* free)(struct refcnt *refcnt))
size_t len
Length of raw file image.
References deflate_chunk::data, image::data, DBGC, png_context::deflate, deflate_init(), DEFLATE_ZLIB, EINVAL, ENOMEM, free, header, htonl, image::len, image::name, ntohl, png_context::offset, png_context::pixbuf, png_chunk(), PNG_TYPE_IEND, png_context::raw, rc, ufree(), and zalloc().
Referenced by __image_type().