1 #ifndef _IPXE_PNG_H
2 #define _IPXE_PNG_H
3 
4 /** @file
5  *
6  * Portable Network Graphics (PNG) format
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <byteswap.h>
14 #include <ipxe/image.h>
15 
16 /** A PNG file signature */
17 struct png_signature {
18 	/** Signature bytes */
19 	uint8_t bytes[8];
20 } __attribute__ (( packed ));
21 
22 /** PNG file signature */
23 #define PNG_SIGNATURE { { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n' } }
24 
25 /** A PNG chunk header */
26 struct png_chunk_header {
27 	/** Length of the chunk (excluding header and footer) */
28 	uint32_t len;
29 	/** Chunk type */
30 	uint32_t type;
31 } __attribute__ (( packed ));
32 
33 /** A PNG chunk footer */
34 struct png_chunk_footer {
35 	/** CRC */
36 	uint32_t crc;
37 } __attribute__ (( packed ));
38 
39 /** PNG chunk type property bits */
40 enum png_chunk_type_bits {
41 	/** Chunk is ancillary */
42 	PNG_CHUNK_ANCILLARY = 0x20000000UL,
43 	/** Chunk is private */
44 	PNG_CHUNK_PRIVATE = 0x00200000UL,
45 	/** Reserved */
46 	PNG_CHUNK_RESERVED = 0x00002000UL,
47 	/** Chunk is safe to copy */
48 	PNG_CHUNK_SAFE = 0x00000020UL,
49 };
50 
51 /**
52  * Canonicalise PNG chunk type
53  *
54  * @v type		Raw chunk type
55  * @ret type		Canonicalised chunk type (excluding property bits)
56  */
57 static inline __attribute__ (( always_inline )) uint32_t
png_canonical_type(uint32_t type)58 png_canonical_type ( uint32_t type ) {
59 	return ( type & ~( htonl ( PNG_CHUNK_ANCILLARY | PNG_CHUNK_PRIVATE |
60 				   PNG_CHUNK_RESERVED | PNG_CHUNK_SAFE ) ) );
61 }
62 
63 /**
64  * Define a canonical PNG chunk type
65  *
66  * @v first		First letter (in upper case)
67  * @v second		Second letter (in upper case)
68  * @v third		Third letter (in upper case)
69  * @v fourth		Fourth letter (in upper case)
70  * @ret type		Canonical chunk type
71  */
72 #define PNG_TYPE( first, second, third, fourth ) \
73 	( ( (first) << 24 ) | ( (second) << 16 ) | ( (third) << 8 ) | (fourth) )
74 
75 /** PNG image header chunk type */
76 #define PNG_TYPE_IHDR PNG_TYPE ( 'I', 'H', 'D', 'R' )
77 
78 /** A PNG image header */
79 struct png_image_header {
80 	/** Width */
81 	uint32_t width;
82 	/** Height */
83 	uint32_t height;
84 	/** Bit depth */
85 	uint8_t depth;
86 	/** Colour type */
87 	uint8_t colour_type;
88 	/** Compression method */
89 	uint8_t compression;
90 	/** Filter method */
91 	uint8_t filter;
92 	/** Interlace method */
93 	uint8_t interlace;
94 } __attribute__ (( packed ));
95 
96 /** PNG colour type bits */
97 enum png_colour_type {
98 	/** Palette is used */
99 	PNG_COLOUR_TYPE_PALETTE = 0x01,
100 	/** RGB colour is used */
101 	PNG_COLOUR_TYPE_RGB = 0x02,
102 	/** Alpha channel is used */
103 	PNG_COLOUR_TYPE_ALPHA = 0x04,
104 };
105 
106 /** PNG colour type mask */
107 #define PNG_COLOUR_TYPE_MASK 0x07
108 
109 /** PNG compression methods */
110 enum png_compression_method {
111 	/** DEFLATE compression with 32kB sliding window */
112 	PNG_COMPRESSION_DEFLATE = 0x00,
113 	/** First unknown compression method */
114 	PNG_COMPRESSION_UNKNOWN = 0x01,
115 };
116 
117 /** PNG filter methods */
118 enum png_filter_method {
119 	/** Adaptive filtering with five basic types */
120 	PNG_FILTER_BASIC = 0x00,
121 	/** First unknown filter method */
122 	PNG_FILTER_UNKNOWN = 0x01,
123 };
124 
125 /** PNG interlace methods */
126 enum png_interlace_method {
127 	/** No interlacing */
128 	PNG_INTERLACE_NONE = 0x00,
129 	/** Adam7 interlacing */
130 	PNG_INTERLACE_ADAM7 = 0x01,
131 	/** First unknown interlace method */
132 	PNG_INTERLACE_UNKNOWN = 0x02,
133 };
134 
135 /** PNG palette chunk type */
136 #define PNG_TYPE_PLTE PNG_TYPE ( 'P', 'L', 'T', 'E' )
137 
138 /** A PNG palette entry */
139 struct png_palette_entry {
140 	/** Red */
141 	uint8_t red;
142 	/** Green */
143 	uint8_t green;
144 	/** Blue */
145 	uint8_t blue;
146 } __attribute__ (( packed ));
147 
148 /** A PNG palette chunk */
149 struct png_palette {
150 	/** Palette entries */
151 	struct png_palette_entry entries[0];
152 } __attribute__ (( packed ));
153 
154 /** Maximum number of PNG palette entries */
155 #define PNG_PALETTE_COUNT 256
156 
157 /** PNG image data chunk type */
158 #define PNG_TYPE_IDAT PNG_TYPE ( 'I', 'D', 'A', 'T' )
159 
160 /** PNG basic filter types */
161 enum png_basic_filter_type {
162 	/** No filtering */
163 	PNG_FILTER_BASIC_NONE = 0,
164 	/** Left byte used as predictor */
165 	PNG_FILTER_BASIC_SUB = 1,
166 	/** Above byte used as predictor */
167 	PNG_FILTER_BASIC_UP = 2,
168 	/** Above and left bytes used as predictors */
169 	PNG_FILTER_BASIC_AVERAGE = 3,
170 	/** Paeth filter */
171 	PNG_FILTER_BASIC_PAETH = 4,
172 };
173 
174 /** PNG image end chunk type */
175 #define PNG_TYPE_IEND PNG_TYPE ( 'I', 'E', 'N', 'D' )
176 
177 extern struct image_type png_image_type __image_type ( PROBE_NORMAL );
178 
179 #endif /* _IPXE_PNG_H */
180