/src/wireshark/epan/dissectors/file-png.c
Line | Count | Source |
1 | | /* file-png.c |
2 | | * |
3 | | * Routines for PNG (Portable Network Graphics) image file dissection |
4 | | * |
5 | | * Copyright 2006 Ronnie Sahlberg |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | /* See http://www.w3.org/TR/PNG for specification |
14 | | */ |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/expert.h> |
19 | | #include <epan/tfs.h> |
20 | | #include <wsutil/array.h> |
21 | | |
22 | 0 | #define MAKE_TYPE_VAL(a, b, c, d) ((a)<<24 | (b)<<16 | (c)<<8 | (d)) |
23 | | |
24 | 0 | #define CHUNK_TYPE_IHDR MAKE_TYPE_VAL('I', 'H', 'D', 'R') |
25 | 0 | #define CHUNK_TYPE_bKGD MAKE_TYPE_VAL('b', 'K', 'G', 'D') |
26 | 0 | #define CHUNK_TYPE_gAMA MAKE_TYPE_VAL('g', 'A', 'M', 'A') |
27 | | #define CHUNK_TYPE_iCCP MAKE_TYPE_VAL('i', 'C', 'C', 'P') |
28 | 0 | #define CHUNK_TYPE_cHRM MAKE_TYPE_VAL('c', 'H', 'R', 'M') |
29 | 0 | #define CHUNK_TYPE_pHYs MAKE_TYPE_VAL('p', 'H', 'Y', 's') |
30 | | #define CHUNK_TYPE_iTXt MAKE_TYPE_VAL('i', 'T', 'X', 't') |
31 | 0 | #define CHUNK_TYPE_tEXt MAKE_TYPE_VAL('t', 'E', 'X', 't') |
32 | | #define CHUNK_TYPE_sBIT MAKE_TYPE_VAL('s', 'B', 'I', 'T') |
33 | 0 | #define CHUNK_TYPE_sRGB MAKE_TYPE_VAL('s', 'R', 'G', 'B') |
34 | 0 | #define CHUNK_TYPE_tIME MAKE_TYPE_VAL('t', 'I', 'M', 'E') |
35 | | #define CHUNK_TYPE_IDAT MAKE_TYPE_VAL('I', 'D', 'A', 'T') |
36 | | #define CHUNK_TYPE_IEND MAKE_TYPE_VAL('I', 'E', 'N', 'D') |
37 | | #define CHUNK_TYPE_tRNS MAKE_TYPE_VAL('t', 'R', 'N', 'S') |
38 | | #define CHUNK_TYPE_PLTE MAKE_TYPE_VAL('P', 'L', 'T', 'E') |
39 | | |
40 | | static const value_string chunk_types[] = { |
41 | | { CHUNK_TYPE_IHDR, "Image Header" }, |
42 | | { CHUNK_TYPE_bKGD, "Background colour" }, |
43 | | { CHUNK_TYPE_gAMA, "Image gamma" }, |
44 | | { CHUNK_TYPE_iCCP, "Embedded ICC profile" }, |
45 | | { CHUNK_TYPE_cHRM, "Primary chromaticities and white point" }, |
46 | | { CHUNK_TYPE_pHYs, "Physical pixel dimensions" }, |
47 | | { CHUNK_TYPE_iTXt, "International textual data" }, |
48 | | { CHUNK_TYPE_tEXt, "Textual data" }, |
49 | | { CHUNK_TYPE_sBIT, "Significant bits" }, |
50 | | { CHUNK_TYPE_sRGB, "Standard RGB colour space" }, |
51 | | { CHUNK_TYPE_tIME, "Image last-modification time" }, |
52 | | { CHUNK_TYPE_IDAT, "Image data chunk" }, |
53 | | { CHUNK_TYPE_IEND, "Image Trailer" }, |
54 | | { CHUNK_TYPE_tRNS, "Transparency" }, |
55 | | { CHUNK_TYPE_PLTE, "Palette" }, |
56 | | { 0, NULL } |
57 | | }; |
58 | | |
59 | | |
60 | | void proto_register_png(void); |
61 | | void proto_reg_handoff_png(void); |
62 | | |
63 | | static const true_false_string png_chunk_anc = { |
64 | | "This is an ANCILLARY chunk", |
65 | | "This is a CRITICAL chunk" |
66 | | }; |
67 | | |
68 | | static const true_false_string png_chunk_priv = { |
69 | | "This is a PRIVATE chunk", |
70 | | "This is a PUBLIC chunk" |
71 | | }; |
72 | | |
73 | | static const true_false_string png_chunk_stc = { |
74 | | "This chunk is SAFE TO COPY", |
75 | | "This chunk is NOT safe to copy" |
76 | | }; |
77 | | |
78 | | static const value_string colour_type_vals[] = { |
79 | | { 0, "Greyscale"}, |
80 | | { 2, "Truecolour"}, |
81 | | { 3, "Indexed-colour"}, |
82 | | { 4, "Greyscale with alpha"}, |
83 | | { 6, "Truecolour with alpha"}, |
84 | | { 0, NULL } |
85 | | }; |
86 | | |
87 | | static const value_string compression_method_vals[] = { |
88 | | { 0, "Deflate"}, |
89 | | { 0, NULL } |
90 | | }; |
91 | | |
92 | | static const value_string filter_method_vals[] = { |
93 | | { 0, "Adaptive"}, |
94 | | { 0, NULL } |
95 | | }; |
96 | | |
97 | | static const value_string interlace_method_vals[] = { |
98 | | { 0, "No interlace"}, |
99 | | { 1, "Adam7"}, |
100 | | { 0, NULL } |
101 | | }; |
102 | | |
103 | | static const value_string srgb_intent_vals[] = { |
104 | | { 0, "Perceptual" }, |
105 | | { 1, "Relative colorimetric" }, |
106 | | { 2, "Saturation" }, |
107 | | { 3, "Absolute colorimetric" }, |
108 | | { 0, NULL } |
109 | | }; |
110 | | |
111 | | static const value_string phys_unit_vals[] = { |
112 | | { 0, "Unit is unknown"}, |
113 | | { 1, "Unit is METRE"}, |
114 | | { 0, NULL } |
115 | | }; |
116 | | |
117 | | static int proto_png; |
118 | | |
119 | | static int hf_png_bkgd_blue; |
120 | | static int hf_png_bkgd_green; |
121 | | static int hf_png_bkgd_greyscale; |
122 | | static int hf_png_bkgd_palette_index; |
123 | | static int hf_png_bkgd_red; |
124 | | static int hf_png_chrm_blue_x; |
125 | | static int hf_png_chrm_blue_y; |
126 | | static int hf_png_chrm_green_x; |
127 | | static int hf_png_chrm_green_y; |
128 | | static int hf_png_chrm_red_x; |
129 | | static int hf_png_chrm_red_y; |
130 | | static int hf_png_chrm_white_x; |
131 | | static int hf_png_chrm_white_y; |
132 | | static int hf_png_chunk_crc; |
133 | | static int hf_png_chunk_data; |
134 | | static int hf_png_chunk_flag_anc; |
135 | | static int hf_png_chunk_flag_priv; |
136 | | static int hf_png_chunk_flag_stc; |
137 | | static int hf_png_chunk_len; |
138 | | static int hf_png_chunk_type_str; |
139 | | static int hf_png_gama_gamma; |
140 | | static int hf_png_ihdr_bitdepth; |
141 | | static int hf_png_ihdr_colour_type; |
142 | | static int hf_png_ihdr_compression_method; |
143 | | static int hf_png_ihdr_filter_method; |
144 | | static int hf_png_ihdr_height; |
145 | | static int hf_png_ihdr_interlace_method; |
146 | | static int hf_png_ihdr_width; |
147 | | static int hf_png_phys_horiz; |
148 | | static int hf_png_phys_unit; |
149 | | static int hf_png_phys_vert; |
150 | | static int hf_png_signature; |
151 | | static int hf_png_srgb_intent; |
152 | | static int hf_png_text_keyword; |
153 | | static int hf_png_text_string; |
154 | | static int hf_png_time_day; |
155 | | static int hf_png_time_hour; |
156 | | static int hf_png_time_minute; |
157 | | static int hf_png_time_month; |
158 | | static int hf_png_time_second; |
159 | | static int hf_png_time_year; |
160 | | |
161 | | static int ett_png; |
162 | | static int ett_png_chunk; |
163 | | |
164 | | static expert_field ei_png_chunk_too_large; |
165 | | |
166 | | static dissector_handle_t png_handle; |
167 | | |
168 | | static void |
169 | | dissect_png_ihdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
170 | 0 | { |
171 | 0 | proto_tree_add_item(tree, hf_png_ihdr_width, tvb, 0, 4, ENC_BIG_ENDIAN); |
172 | 0 | proto_tree_add_item(tree, hf_png_ihdr_height, tvb, 4, 4, ENC_BIG_ENDIAN); |
173 | 0 | proto_tree_add_item(tree, hf_png_ihdr_bitdepth, tvb, 8, 1, ENC_BIG_ENDIAN); |
174 | 0 | proto_tree_add_item(tree, hf_png_ihdr_colour_type, tvb, 9, 1, ENC_BIG_ENDIAN); |
175 | 0 | proto_tree_add_item(tree, hf_png_ihdr_compression_method, tvb, 10, 1, ENC_BIG_ENDIAN); |
176 | 0 | proto_tree_add_item(tree, hf_png_ihdr_filter_method, tvb, 11, 1, ENC_BIG_ENDIAN); |
177 | 0 | proto_tree_add_item(tree, hf_png_ihdr_interlace_method, tvb, 12, 1, ENC_BIG_ENDIAN); |
178 | |
|
179 | 0 | } |
180 | | |
181 | | static void |
182 | | dissect_png_srgb(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
183 | 0 | { |
184 | 0 | proto_tree_add_item(tree, hf_png_srgb_intent, |
185 | 0 | tvb, 0, 1, ENC_BIG_ENDIAN); |
186 | 0 | } |
187 | | |
188 | | static void |
189 | | dissect_png_text(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
190 | 0 | { |
191 | 0 | unsigned offset=0, nul_offset; |
192 | 0 | bool nul_offset_found; |
193 | |
|
194 | 0 | nul_offset_found = tvb_find_uint8_length(tvb, offset, tvb_captured_length_remaining(tvb, offset), 0, &nul_offset); |
195 | | /* nul_offset == 0 means empty keyword, this is not allowed by the png standard */ |
196 | 0 | if (nul_offset==0 || nul_offset_found == false) { |
197 | | /* XXX exception */ |
198 | 0 | return; |
199 | 0 | } |
200 | | |
201 | 0 | proto_tree_add_item(tree, hf_png_text_keyword, tvb, offset, nul_offset, ENC_ISO_8859_1); |
202 | 0 | offset = nul_offset+1; /* length of the key word + 0 character */ |
203 | |
|
204 | 0 | proto_tree_add_item(tree, hf_png_text_string, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_ISO_8859_1); |
205 | |
|
206 | 0 | } |
207 | | |
208 | | static void |
209 | | dissect_png_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
210 | 0 | { |
211 | 0 | proto_tree_add_item(tree, hf_png_time_year, tvb, 0, 2, ENC_BIG_ENDIAN); |
212 | 0 | proto_tree_add_item(tree, hf_png_time_month, tvb, 2, 1, ENC_BIG_ENDIAN); |
213 | 0 | proto_tree_add_item(tree, hf_png_time_day, tvb, 3, 1, ENC_BIG_ENDIAN); |
214 | 0 | proto_tree_add_item(tree, hf_png_time_hour, tvb, 4, 1, ENC_BIG_ENDIAN); |
215 | 0 | proto_tree_add_item(tree, hf_png_time_minute, tvb, 5, 1, ENC_BIG_ENDIAN); |
216 | 0 | proto_tree_add_item(tree, hf_png_time_second, tvb, 6, 1, ENC_BIG_ENDIAN); |
217 | 0 | } |
218 | | |
219 | | static void |
220 | | dissect_png_phys(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
221 | 0 | { |
222 | 0 | proto_tree_add_item(tree, hf_png_phys_horiz, tvb, 0, 4, ENC_BIG_ENDIAN); |
223 | 0 | proto_tree_add_item(tree, hf_png_phys_vert, tvb, 4, 4, ENC_BIG_ENDIAN); |
224 | 0 | proto_tree_add_item(tree, hf_png_phys_unit, tvb, 8, 1, ENC_BIG_ENDIAN); |
225 | 0 | } |
226 | | |
227 | | static void |
228 | | dissect_png_bkgd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
229 | 0 | { |
230 | 0 | switch(tvb_reported_length(tvb)){ |
231 | 0 | case 1: /* colour type 3 */ |
232 | 0 | proto_tree_add_item(tree, hf_png_bkgd_palette_index, tvb, 0, 1, ENC_BIG_ENDIAN); |
233 | 0 | break; |
234 | 0 | case 2: /* colour type 0, 4 */ |
235 | 0 | proto_tree_add_item(tree, hf_png_bkgd_greyscale, tvb, 0, 2, ENC_BIG_ENDIAN); |
236 | 0 | break; |
237 | 0 | case 6: /* colour type 2, 6 */ |
238 | 0 | proto_tree_add_item(tree, hf_png_bkgd_red, tvb, 0, 2, ENC_BIG_ENDIAN); |
239 | 0 | proto_tree_add_item(tree, hf_png_bkgd_green, tvb, 2, 2, ENC_BIG_ENDIAN); |
240 | 0 | proto_tree_add_item(tree, hf_png_bkgd_blue, tvb, 4, 2, ENC_BIG_ENDIAN); |
241 | 0 | break; |
242 | 0 | } |
243 | 0 | } |
244 | | |
245 | | static void |
246 | | dissect_png_chrm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
247 | 0 | { |
248 | 0 | float wx, wy, rx, ry, gx, gy, bx, by; |
249 | 0 | unsigned offset = 0; |
250 | |
|
251 | 0 | wx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
252 | 0 | proto_tree_add_float(tree, hf_png_chrm_white_x, |
253 | 0 | tvb, offset, 4, wx); |
254 | 0 | offset += 4; |
255 | |
|
256 | 0 | wy = tvb_get_ntohl(tvb, offset) / 100000.0f; |
257 | 0 | proto_tree_add_float(tree, hf_png_chrm_white_y, |
258 | 0 | tvb, offset, 4, wy); |
259 | 0 | offset += 4; |
260 | |
|
261 | 0 | rx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
262 | 0 | proto_tree_add_float(tree, hf_png_chrm_red_x, |
263 | 0 | tvb, offset, 4, rx); |
264 | 0 | offset += 4; |
265 | |
|
266 | 0 | ry = tvb_get_ntohl(tvb, offset) / 100000.0f; |
267 | 0 | proto_tree_add_float(tree, hf_png_chrm_red_y, |
268 | 0 | tvb, offset, 4, ry); |
269 | 0 | offset += 4; |
270 | |
|
271 | 0 | gx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
272 | 0 | proto_tree_add_float(tree, hf_png_chrm_green_x, |
273 | 0 | tvb, offset, 4, gx); |
274 | 0 | offset += 4; |
275 | |
|
276 | 0 | gy = tvb_get_ntohl(tvb, offset) / 100000.0f; |
277 | 0 | proto_tree_add_float(tree, hf_png_chrm_green_y, |
278 | 0 | tvb, offset, 4, gy); |
279 | 0 | offset += 4; |
280 | |
|
281 | 0 | bx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
282 | 0 | proto_tree_add_float(tree, hf_png_chrm_blue_x, |
283 | 0 | tvb, offset, 4, bx); |
284 | 0 | offset += 4; |
285 | |
|
286 | 0 | by = tvb_get_ntohl(tvb, offset) / 100000.0f; |
287 | 0 | proto_tree_add_float(tree, hf_png_chrm_blue_y, |
288 | 0 | tvb, offset, 4, by); |
289 | 0 | } |
290 | | |
291 | | static void |
292 | | dissect_png_gama(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
293 | 0 | { |
294 | 0 | float gamma; |
295 | |
|
296 | 0 | gamma = tvb_get_ntohl(tvb, 0) / 100000.0f; |
297 | 0 | proto_tree_add_float(tree, hf_png_gama_gamma, |
298 | 0 | tvb, 0, 4, gamma); |
299 | 0 | } |
300 | | |
301 | | static int |
302 | | dissect_png(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_) |
303 | 187 | { |
304 | 187 | proto_tree *tree; |
305 | 187 | proto_item *ti; |
306 | 187 | unsigned offset=0; |
307 | | /* http://libpng.org/pub/png/spec/1.2/PNG-Structure.html#PNG-file-signature */ |
308 | 187 | static const uint8_t magic[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; |
309 | | |
310 | 187 | if (tvb_captured_length(tvb) < 20) |
311 | 36 | return 0; |
312 | 151 | if (tvb_memeql(tvb, 0, magic, sizeof(magic)) != 0) |
313 | 139 | return 0; |
314 | | |
315 | 12 | col_append_str(pinfo->cinfo, COL_INFO, " (PNG)"); |
316 | | |
317 | 12 | ti=proto_tree_add_item(parent_tree, proto_png, tvb, offset, -1, ENC_NA); |
318 | 12 | tree=proto_item_add_subtree(ti, ett_png); |
319 | | |
320 | 12 | proto_tree_add_item(tree, hf_png_signature, tvb, offset, 8, ENC_NA); |
321 | 12 | offset+=8; |
322 | | |
323 | 159 | while(tvb_reported_length_remaining(tvb, offset) > 0){ |
324 | 148 | uint32_t len_field; |
325 | 148 | proto_item *len_it; |
326 | 148 | proto_tree *chunk_tree; |
327 | 148 | uint32_t type; |
328 | 148 | uint8_t *type_str; |
329 | 148 | tvbuff_t *chunk_tvb; |
330 | | |
331 | 148 | len_field = tvb_get_ntohl(tvb, offset); |
332 | | |
333 | 148 | type = tvb_get_ntohl(tvb, offset+4); |
334 | 148 | type_str = tvb_get_string_enc(pinfo->pool, |
335 | 148 | tvb, offset+4, 4, ENC_ASCII|ENC_NA); |
336 | | |
337 | | /* 4 byte len field, 4 byte chunk type, 4 byte CRC */ |
338 | 148 | chunk_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4+4+len_field+4, ett_png_chunk, NULL, |
339 | 148 | "%s (%s)", val_to_str_const(type, chunk_types, "unknown"), type_str); |
340 | | |
341 | 148 | len_it = proto_tree_add_item(chunk_tree, hf_png_chunk_len, |
342 | 148 | tvb, offset, 4, ENC_BIG_ENDIAN); |
343 | 148 | offset+=4; |
344 | 148 | if (len_field > INT_MAX) { |
345 | 1 | expert_add_info(pinfo, len_it, &ei_png_chunk_too_large); |
346 | 1 | return offset; |
347 | 1 | } |
348 | | |
349 | 147 | proto_tree_add_item(chunk_tree, hf_png_chunk_type_str, |
350 | 147 | tvb, offset, 4, ENC_ASCII); |
351 | | |
352 | 147 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_anc, tvb, offset, 4, ENC_BIG_ENDIAN); |
353 | 147 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_priv, tvb, offset, 4, ENC_BIG_ENDIAN); |
354 | 147 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_stc, tvb, offset, 4, ENC_BIG_ENDIAN); |
355 | 147 | offset+=4; |
356 | | |
357 | 147 | chunk_tvb=tvb_new_subset_length(tvb, offset, len_field); |
358 | 147 | switch (type) { |
359 | 0 | case CHUNK_TYPE_IHDR: |
360 | 0 | dissect_png_ihdr(chunk_tvb, pinfo, chunk_tree); |
361 | 0 | break; |
362 | 0 | case CHUNK_TYPE_bKGD: |
363 | 0 | dissect_png_bkgd(chunk_tvb, pinfo, chunk_tree); |
364 | 0 | break; |
365 | 0 | case CHUNK_TYPE_cHRM: |
366 | 0 | dissect_png_chrm(chunk_tvb, pinfo, chunk_tree); |
367 | 0 | break; |
368 | 0 | case CHUNK_TYPE_gAMA: |
369 | 0 | dissect_png_gama(chunk_tvb, pinfo, chunk_tree); |
370 | 0 | break; |
371 | 0 | case CHUNK_TYPE_pHYs: |
372 | 0 | dissect_png_phys(chunk_tvb, pinfo, chunk_tree); |
373 | 0 | break; |
374 | 0 | case CHUNK_TYPE_sRGB: |
375 | 0 | dissect_png_srgb(chunk_tvb, pinfo, chunk_tree); |
376 | 0 | break; |
377 | 0 | case CHUNK_TYPE_tEXt: |
378 | 0 | dissect_png_text(chunk_tvb, pinfo, chunk_tree); |
379 | 0 | break; |
380 | 0 | case CHUNK_TYPE_tIME: |
381 | 0 | dissect_png_time(chunk_tvb, pinfo, chunk_tree); |
382 | 0 | break; |
383 | 147 | default: |
384 | 147 | if (len_field>0) { |
385 | 19 | proto_tree_add_item(chunk_tree, hf_png_chunk_data, |
386 | 19 | tvb, offset, len_field, ENC_NA); |
387 | 19 | } |
388 | 147 | break; |
389 | 147 | } |
390 | 147 | offset += len_field; |
391 | | |
392 | 147 | proto_tree_add_item(chunk_tree, hf_png_chunk_crc, tvb, offset, 4, ENC_BIG_ENDIAN); |
393 | 147 | offset+=4; |
394 | 147 | } |
395 | 11 | return offset; |
396 | 12 | } |
397 | | |
398 | | void |
399 | | proto_register_png(void) |
400 | 16 | { |
401 | 16 | static hf_register_info hf[] = { |
402 | 16 | { &hf_png_signature, |
403 | 16 | { "PNG Signature", "png.signature", |
404 | 16 | FT_BYTES, BASE_NONE, NULL, 0, |
405 | 16 | NULL, HFILL } |
406 | 16 | }, |
407 | 16 | { &hf_png_chunk_data, |
408 | 16 | { "Data", "png.chunk.data", |
409 | 16 | FT_NONE, BASE_NONE, NULL, 0, |
410 | 16 | NULL, HFILL } |
411 | 16 | }, |
412 | 16 | { &hf_png_chunk_type_str, |
413 | 16 | { "Type", "png.chunk.type", |
414 | 16 | FT_STRING, BASE_NONE, NULL, 0, |
415 | 16 | NULL, HFILL } |
416 | 16 | }, |
417 | 16 | { &hf_png_chunk_len, |
418 | 16 | { "Len", "png.chunk.len", |
419 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
420 | 16 | NULL, HFILL } |
421 | 16 | }, |
422 | 16 | { &hf_png_chunk_crc, |
423 | 16 | { "CRC", "png.chunk.crc", |
424 | 16 | FT_UINT32, BASE_HEX, NULL, 0, |
425 | 16 | NULL, HFILL } |
426 | 16 | }, |
427 | 16 | { &hf_png_chunk_flag_anc, |
428 | 16 | { "Ancillary", "png.chunk.flag.ancillary", |
429 | 16 | FT_BOOLEAN, 32, TFS(&png_chunk_anc), 0x20000000, |
430 | 16 | NULL, HFILL } |
431 | 16 | }, |
432 | 16 | { &hf_png_chunk_flag_priv, |
433 | 16 | { "Private", "png.chunk.flag.private", |
434 | 16 | FT_BOOLEAN, 32, TFS(&png_chunk_priv), 0x00200000, |
435 | 16 | NULL, HFILL } |
436 | 16 | }, |
437 | 16 | { &hf_png_chunk_flag_stc, |
438 | 16 | { "Safe To Copy", "png.chunk.flag.stc", |
439 | 16 | FT_BOOLEAN, 32, TFS(&png_chunk_stc), 0x00000020, |
440 | 16 | NULL, HFILL } |
441 | 16 | }, |
442 | 16 | { &hf_png_ihdr_width, |
443 | 16 | { "Width", "png.ihdr.width", |
444 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
445 | 16 | NULL, HFILL } |
446 | 16 | }, |
447 | 16 | { &hf_png_ihdr_height, |
448 | 16 | { "Height", "png.ihdr.height", |
449 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
450 | 16 | NULL, HFILL } |
451 | 16 | }, |
452 | 16 | { &hf_png_ihdr_bitdepth, |
453 | 16 | { "Bit Depth", "png.ihdr.bitdepth", |
454 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
455 | 16 | NULL, HFILL } |
456 | 16 | }, |
457 | 16 | { &hf_png_ihdr_colour_type, |
458 | 16 | { "Colour Type", "png.ihdr.colour_type", |
459 | 16 | FT_UINT8, BASE_DEC, VALS(colour_type_vals), 0, |
460 | 16 | NULL, HFILL } |
461 | 16 | }, |
462 | 16 | { &hf_png_ihdr_compression_method, |
463 | 16 | { "Compression Method", "png.ihdr.compression_method", |
464 | 16 | FT_UINT8, BASE_DEC, VALS(compression_method_vals), 0, |
465 | 16 | NULL, HFILL } |
466 | 16 | }, |
467 | 16 | { &hf_png_ihdr_filter_method, |
468 | 16 | { "Filter Method", "png.ihdr.filter_method", |
469 | 16 | FT_UINT8, BASE_DEC, VALS(filter_method_vals), 0, |
470 | 16 | NULL, HFILL } |
471 | 16 | }, |
472 | 16 | { &hf_png_ihdr_interlace_method, |
473 | 16 | { "Interlace Method", "png.ihdr.interlace_method", |
474 | 16 | FT_UINT8, BASE_DEC, VALS(interlace_method_vals), 0, |
475 | 16 | NULL, HFILL } |
476 | 16 | }, |
477 | 16 | { &hf_png_srgb_intent, |
478 | 16 | { "Intent", "png.srgb.intent", |
479 | 16 | FT_UINT8, BASE_DEC, VALS(srgb_intent_vals), 0, |
480 | 16 | NULL, HFILL } |
481 | 16 | }, |
482 | 16 | { &hf_png_text_keyword, |
483 | 16 | { "Keyword", "png.text.keyword", |
484 | 16 | FT_STRING, BASE_NONE, NULL, 0, |
485 | 16 | NULL, HFILL } |
486 | 16 | }, |
487 | 16 | { &hf_png_text_string, |
488 | 16 | { "String", "png.text.string", |
489 | 16 | FT_STRING, BASE_NONE, NULL, 0, |
490 | 16 | NULL, HFILL } |
491 | 16 | }, |
492 | 16 | { &hf_png_time_year, |
493 | 16 | { "Year", "png.time.year", |
494 | 16 | FT_UINT16, BASE_DEC, NULL, 0, |
495 | 16 | NULL, HFILL } |
496 | 16 | }, |
497 | 16 | { &hf_png_time_month, |
498 | 16 | { "Month", "png.time.month", |
499 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
500 | 16 | NULL, HFILL } |
501 | 16 | }, |
502 | 16 | { &hf_png_time_day, |
503 | 16 | { "Day", "png.time.day", |
504 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
505 | 16 | NULL, HFILL } |
506 | 16 | }, |
507 | 16 | { &hf_png_time_hour, |
508 | 16 | { "Hour", "png.time.hour", |
509 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
510 | 16 | NULL, HFILL } |
511 | 16 | }, |
512 | 16 | { &hf_png_time_minute, |
513 | 16 | { "Minute", "png.time.minute", |
514 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
515 | 16 | NULL, HFILL } |
516 | 16 | }, |
517 | 16 | { &hf_png_time_second, |
518 | 16 | { "Second", "png.time.second", |
519 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
520 | 16 | NULL, HFILL } |
521 | 16 | }, |
522 | 16 | { &hf_png_phys_horiz, |
523 | 16 | { "Horizontal pixels per unit", "png.phys.horiz", |
524 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
525 | 16 | NULL, HFILL } |
526 | 16 | }, |
527 | 16 | { &hf_png_phys_vert, |
528 | 16 | { "Vertical pixels per unit", "png.phys.vert", |
529 | 16 | FT_UINT32, BASE_DEC, NULL, 0, |
530 | 16 | NULL, HFILL } |
531 | 16 | }, |
532 | 16 | { &hf_png_phys_unit, |
533 | 16 | { "Unit", "png.phys.unit", |
534 | 16 | FT_UINT8, BASE_DEC, VALS(phys_unit_vals), 0, |
535 | 16 | NULL, HFILL } |
536 | 16 | }, |
537 | 16 | { &hf_png_bkgd_palette_index, |
538 | 16 | { "Palette Index", "png.bkgd.palette_index", |
539 | 16 | FT_UINT8, BASE_DEC, NULL, 0, |
540 | 16 | NULL, HFILL } |
541 | 16 | }, |
542 | 16 | { &hf_png_bkgd_greyscale, |
543 | 16 | { "Greyscale", "png.bkgd.greyscale", |
544 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
545 | 16 | NULL, HFILL } |
546 | 16 | }, |
547 | 16 | { &hf_png_bkgd_red, |
548 | 16 | { "Red", "png.bkgd.red", |
549 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
550 | 16 | NULL, HFILL } |
551 | 16 | }, |
552 | 16 | { &hf_png_bkgd_green, |
553 | 16 | { "Green", "png.bkgd.green", |
554 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
555 | 16 | NULL, HFILL } |
556 | 16 | }, |
557 | 16 | { &hf_png_bkgd_blue, |
558 | 16 | { "Blue", "png.bkgd.blue", |
559 | 16 | FT_UINT16, BASE_HEX, NULL, 0, |
560 | 16 | NULL, HFILL } |
561 | 16 | }, |
562 | 16 | { &hf_png_chrm_white_x, |
563 | 16 | { "White X", "png.chrm.white.x", |
564 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
565 | 16 | NULL, HFILL } |
566 | 16 | }, |
567 | 16 | { &hf_png_chrm_white_y, |
568 | 16 | { "White Y", "png.chrm.white.y", |
569 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
570 | 16 | NULL, HFILL } |
571 | 16 | }, |
572 | 16 | { &hf_png_chrm_red_x, |
573 | 16 | { "Red X", "png.chrm.red.x", |
574 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
575 | 16 | NULL, HFILL } |
576 | 16 | }, |
577 | 16 | { &hf_png_chrm_red_y, |
578 | 16 | { "Red Y", "png.chrm.red.y", |
579 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
580 | 16 | NULL, HFILL } |
581 | 16 | }, |
582 | 16 | { &hf_png_chrm_green_x, |
583 | 16 | { "Green X", "png.chrm.green.x", |
584 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
585 | 16 | NULL, HFILL } |
586 | 16 | }, |
587 | 16 | { &hf_png_chrm_green_y, |
588 | 16 | { "Green Y", "png.chrm.green.y", |
589 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
590 | 16 | NULL, HFILL } |
591 | 16 | }, |
592 | 16 | { &hf_png_chrm_blue_x, |
593 | 16 | { "Blue X", "png.chrm.blue.x", |
594 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
595 | 16 | NULL, HFILL } |
596 | 16 | }, |
597 | 16 | { &hf_png_chrm_blue_y, |
598 | 16 | { "Blue Y", "png.chrm.blue.y", |
599 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
600 | 16 | NULL, HFILL } |
601 | 16 | }, |
602 | 16 | { &hf_png_gama_gamma, |
603 | 16 | { "Gamma", "png.gama.gamma", |
604 | 16 | FT_FLOAT, BASE_NONE, NULL, 0, |
605 | 16 | NULL, HFILL } |
606 | 16 | }, |
607 | 16 | }; |
608 | | |
609 | 16 | static int *ett[] = |
610 | 16 | { |
611 | 16 | &ett_png, |
612 | 16 | &ett_png_chunk, |
613 | 16 | }; |
614 | | |
615 | 16 | static ei_register_info ei[] = { |
616 | 16 | { &ei_png_chunk_too_large, |
617 | 16 | { "png.chunk_too_large", PI_PROTOCOL, PI_WARN, |
618 | 16 | "chunk size too large, dissection of this chunk is not supported", EXPFILL }} |
619 | 16 | }; |
620 | 16 | expert_module_t *expert_png; |
621 | | |
622 | 16 | proto_png = proto_register_protocol("Portable Network Graphics","PNG","png"); |
623 | 16 | proto_register_field_array(proto_png, hf, array_length(hf)); |
624 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
625 | | |
626 | 16 | expert_png = expert_register_protocol(proto_png); |
627 | 16 | expert_register_field_array(expert_png, ei, array_length(ei)); |
628 | | |
629 | 16 | png_handle = register_dissector("png", dissect_png, proto_png); |
630 | 16 | } |
631 | | |
632 | | static bool dissect_png_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
633 | 187 | { |
634 | 187 | return dissect_png(tvb, pinfo, tree, data) > 0; |
635 | 187 | } |
636 | | |
637 | | void |
638 | | proto_reg_handoff_png(void) |
639 | 16 | { |
640 | 16 | dissector_add_string("media_type", "image/png", png_handle); |
641 | 16 | heur_dissector_add("http", dissect_png_heur, "PNG file in HTTP", "png_http", proto_png, HEURISTIC_ENABLE); |
642 | 16 | heur_dissector_add("wtap_file", dissect_png_heur, "PNG file in HTTP", "png_wtap", proto_png, HEURISTIC_ENABLE); |
643 | 16 | } |
644 | | |
645 | | /* |
646 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
647 | | * |
648 | | * Local variables: |
649 | | * c-basic-offset: 4 |
650 | | * tab-width: 8 |
651 | | * indent-tabs-mode: nil |
652 | | * End: |
653 | | * |
654 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
655 | | * :indentSize=4:tabSize=8:noTabs=true: |
656 | | */ |