/src/wireshark/epan/dissectors/file-png.c
Line | Count | Source (jump to first uncovered line) |
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 | int offset=0, nul_offset; |
192 | |
|
193 | 0 | nul_offset = tvb_find_uint8(tvb, offset, tvb_captured_length_remaining(tvb, offset), 0); |
194 | | /* nul_offset == 0 means empty keyword, this is not allowed by the png standard */ |
195 | 0 | if (nul_offset<=0) { |
196 | | /* XXX exception */ |
197 | 0 | return; |
198 | 0 | } |
199 | | |
200 | 0 | proto_tree_add_item(tree, hf_png_text_keyword, tvb, offset, nul_offset, ENC_ISO_8859_1); |
201 | 0 | offset = nul_offset+1; /* length of the key word + 0 character */ |
202 | |
|
203 | 0 | proto_tree_add_item(tree, hf_png_text_string, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_ISO_8859_1); |
204 | |
|
205 | 0 | } |
206 | | |
207 | | static void |
208 | | dissect_png_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
209 | 0 | { |
210 | 0 | proto_tree_add_item(tree, hf_png_time_year, tvb, 0, 2, ENC_BIG_ENDIAN); |
211 | 0 | proto_tree_add_item(tree, hf_png_time_month, tvb, 2, 1, ENC_BIG_ENDIAN); |
212 | 0 | proto_tree_add_item(tree, hf_png_time_day, tvb, 3, 1, ENC_BIG_ENDIAN); |
213 | 0 | proto_tree_add_item(tree, hf_png_time_hour, tvb, 4, 1, ENC_BIG_ENDIAN); |
214 | 0 | proto_tree_add_item(tree, hf_png_time_minute, tvb, 5, 1, ENC_BIG_ENDIAN); |
215 | 0 | proto_tree_add_item(tree, hf_png_time_second, tvb, 6, 1, ENC_BIG_ENDIAN); |
216 | 0 | } |
217 | | |
218 | | static void |
219 | | dissect_png_phys(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
220 | 0 | { |
221 | 0 | proto_tree_add_item(tree, hf_png_phys_horiz, tvb, 0, 4, ENC_BIG_ENDIAN); |
222 | 0 | proto_tree_add_item(tree, hf_png_phys_vert, tvb, 4, 4, ENC_BIG_ENDIAN); |
223 | 0 | proto_tree_add_item(tree, hf_png_phys_unit, tvb, 8, 1, ENC_BIG_ENDIAN); |
224 | 0 | } |
225 | | |
226 | | static void |
227 | | dissect_png_bkgd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
228 | 0 | { |
229 | 0 | switch(tvb_reported_length(tvb)){ |
230 | 0 | case 1: /* colour type 3 */ |
231 | 0 | proto_tree_add_item(tree, hf_png_bkgd_palette_index, tvb, 0, 1, ENC_BIG_ENDIAN); |
232 | 0 | break; |
233 | 0 | case 2: /* colour type 0, 4 */ |
234 | 0 | proto_tree_add_item(tree, hf_png_bkgd_greyscale, tvb, 0, 2, ENC_BIG_ENDIAN); |
235 | 0 | break; |
236 | 0 | case 6: /* colour type 2, 6 */ |
237 | 0 | proto_tree_add_item(tree, hf_png_bkgd_red, tvb, 0, 2, ENC_BIG_ENDIAN); |
238 | 0 | proto_tree_add_item(tree, hf_png_bkgd_green, tvb, 2, 2, ENC_BIG_ENDIAN); |
239 | 0 | proto_tree_add_item(tree, hf_png_bkgd_blue, tvb, 4, 2, ENC_BIG_ENDIAN); |
240 | 0 | break; |
241 | 0 | } |
242 | 0 | } |
243 | | |
244 | | static void |
245 | | dissect_png_chrm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
246 | 0 | { |
247 | 0 | float wx, wy, rx, ry, gx, gy, bx, by; |
248 | 0 | int offset = 0; |
249 | |
|
250 | 0 | wx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
251 | 0 | proto_tree_add_float(tree, hf_png_chrm_white_x, |
252 | 0 | tvb, offset, 4, wx); |
253 | 0 | offset += 4; |
254 | |
|
255 | 0 | wy = tvb_get_ntohl(tvb, offset) / 100000.0f; |
256 | 0 | proto_tree_add_float(tree, hf_png_chrm_white_y, |
257 | 0 | tvb, offset, 4, wy); |
258 | 0 | offset += 4; |
259 | |
|
260 | 0 | rx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
261 | 0 | proto_tree_add_float(tree, hf_png_chrm_red_x, |
262 | 0 | tvb, offset, 4, rx); |
263 | 0 | offset += 4; |
264 | |
|
265 | 0 | ry = tvb_get_ntohl(tvb, offset) / 100000.0f; |
266 | 0 | proto_tree_add_float(tree, hf_png_chrm_red_y, |
267 | 0 | tvb, offset, 4, ry); |
268 | 0 | offset += 4; |
269 | |
|
270 | 0 | gx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
271 | 0 | proto_tree_add_float(tree, hf_png_chrm_green_x, |
272 | 0 | tvb, offset, 4, gx); |
273 | 0 | offset += 4; |
274 | |
|
275 | 0 | gy = tvb_get_ntohl(tvb, offset) / 100000.0f; |
276 | 0 | proto_tree_add_float(tree, hf_png_chrm_green_y, |
277 | 0 | tvb, offset, 4, gy); |
278 | 0 | offset += 4; |
279 | |
|
280 | 0 | bx = tvb_get_ntohl(tvb, offset) / 100000.0f; |
281 | 0 | proto_tree_add_float(tree, hf_png_chrm_blue_x, |
282 | 0 | tvb, offset, 4, bx); |
283 | 0 | offset += 4; |
284 | |
|
285 | 0 | by = tvb_get_ntohl(tvb, offset) / 100000.0f; |
286 | 0 | proto_tree_add_float(tree, hf_png_chrm_blue_y, |
287 | 0 | tvb, offset, 4, by); |
288 | 0 | } |
289 | | |
290 | | static void |
291 | | dissect_png_gama(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree) |
292 | 0 | { |
293 | 0 | float gamma; |
294 | |
|
295 | 0 | gamma = tvb_get_ntohl(tvb, 0) / 100000.0f; |
296 | 0 | proto_tree_add_float(tree, hf_png_gama_gamma, |
297 | 0 | tvb, 0, 4, gamma); |
298 | 0 | } |
299 | | |
300 | | static int |
301 | | dissect_png(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_) |
302 | 311 | { |
303 | 311 | proto_tree *tree; |
304 | 311 | proto_item *ti; |
305 | 311 | int offset=0; |
306 | | /* http://libpng.org/pub/png/spec/1.2/PNG-Structure.html#PNG-file-signature */ |
307 | 311 | static const uint8_t magic[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; |
308 | | |
309 | 311 | if (tvb_captured_length(tvb) < 20) |
310 | 133 | return 0; |
311 | 178 | if (tvb_memeql(tvb, 0, magic, sizeof(magic)) != 0) |
312 | 175 | return 0; |
313 | | |
314 | 3 | col_append_str(pinfo->cinfo, COL_INFO, " (PNG)"); |
315 | | |
316 | 3 | ti=proto_tree_add_item(parent_tree, proto_png, tvb, offset, -1, ENC_NA); |
317 | 3 | tree=proto_item_add_subtree(ti, ett_png); |
318 | | |
319 | 3 | proto_tree_add_item(tree, hf_png_signature, tvb, offset, 8, ENC_NA); |
320 | 3 | offset+=8; |
321 | | |
322 | 5 | while(tvb_reported_length_remaining(tvb, offset) > 0){ |
323 | 3 | uint32_t len_field; |
324 | 3 | proto_item *len_it; |
325 | 3 | proto_tree *chunk_tree; |
326 | 3 | uint32_t type; |
327 | 3 | uint8_t *type_str; |
328 | 3 | tvbuff_t *chunk_tvb; |
329 | | |
330 | 3 | len_field = tvb_get_ntohl(tvb, offset); |
331 | | |
332 | 3 | type = tvb_get_ntohl(tvb, offset+4); |
333 | 3 | type_str = tvb_get_string_enc(pinfo->pool, |
334 | 3 | tvb, offset+4, 4, ENC_ASCII|ENC_NA); |
335 | | |
336 | | /* 4 byte len field, 4 byte chunk type, 4 byte CRC */ |
337 | 3 | chunk_tree = proto_tree_add_subtree_format(tree, tvb, offset, 4+4+len_field+4, ett_png_chunk, NULL, |
338 | 3 | "%s (%s)", val_to_str_const(type, chunk_types, "unknown"), type_str); |
339 | | |
340 | 3 | len_it = proto_tree_add_item(chunk_tree, hf_png_chunk_len, |
341 | 3 | tvb, offset, 4, ENC_BIG_ENDIAN); |
342 | 3 | offset+=4; |
343 | 3 | if (len_field > INT_MAX) { |
344 | 1 | expert_add_info(pinfo, len_it, &ei_png_chunk_too_large); |
345 | 1 | return offset; |
346 | 1 | } |
347 | | |
348 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_type_str, |
349 | 2 | tvb, offset, 4, ENC_ASCII); |
350 | | |
351 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_anc, tvb, offset, 4, ENC_BIG_ENDIAN); |
352 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_priv, tvb, offset, 4, ENC_BIG_ENDIAN); |
353 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_flag_stc, tvb, offset, 4, ENC_BIG_ENDIAN); |
354 | 2 | offset+=4; |
355 | | |
356 | 2 | chunk_tvb=tvb_new_subset_length(tvb, offset, len_field); |
357 | 2 | switch (type) { |
358 | 0 | case CHUNK_TYPE_IHDR: |
359 | 0 | dissect_png_ihdr(chunk_tvb, pinfo, chunk_tree); |
360 | 0 | break; |
361 | 0 | case CHUNK_TYPE_bKGD: |
362 | 0 | dissect_png_bkgd(chunk_tvb, pinfo, chunk_tree); |
363 | 0 | break; |
364 | 0 | case CHUNK_TYPE_cHRM: |
365 | 0 | dissect_png_chrm(chunk_tvb, pinfo, chunk_tree); |
366 | 0 | break; |
367 | 0 | case CHUNK_TYPE_gAMA: |
368 | 0 | dissect_png_gama(chunk_tvb, pinfo, chunk_tree); |
369 | 0 | break; |
370 | 0 | case CHUNK_TYPE_pHYs: |
371 | 0 | dissect_png_phys(chunk_tvb, pinfo, chunk_tree); |
372 | 0 | break; |
373 | 0 | case CHUNK_TYPE_sRGB: |
374 | 0 | dissect_png_srgb(chunk_tvb, pinfo, chunk_tree); |
375 | 0 | break; |
376 | 0 | case CHUNK_TYPE_tEXt: |
377 | 0 | dissect_png_text(chunk_tvb, pinfo, chunk_tree); |
378 | 0 | break; |
379 | 0 | case CHUNK_TYPE_tIME: |
380 | 0 | dissect_png_time(chunk_tvb, pinfo, chunk_tree); |
381 | 0 | break; |
382 | 2 | default: |
383 | 2 | if (len_field>0) { |
384 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_data, |
385 | 2 | tvb, offset, len_field, ENC_NA); |
386 | 2 | } |
387 | 2 | break; |
388 | 2 | } |
389 | 2 | offset += len_field; |
390 | | |
391 | 2 | proto_tree_add_item(chunk_tree, hf_png_chunk_crc, tvb, offset, 4, ENC_BIG_ENDIAN); |
392 | 2 | offset+=4; |
393 | 2 | } |
394 | 2 | return offset; |
395 | 3 | } |
396 | | |
397 | | void |
398 | | proto_register_png(void) |
399 | 14 | { |
400 | 14 | static hf_register_info hf[] = { |
401 | 14 | { &hf_png_signature, |
402 | 14 | { "PNG Signature", "png.signature", |
403 | 14 | FT_BYTES, BASE_NONE, NULL, 0, |
404 | 14 | NULL, HFILL } |
405 | 14 | }, |
406 | 14 | { &hf_png_chunk_data, |
407 | 14 | { "Data", "png.chunk.data", |
408 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
409 | 14 | NULL, HFILL } |
410 | 14 | }, |
411 | 14 | { &hf_png_chunk_type_str, |
412 | 14 | { "Type", "png.chunk.type", |
413 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
414 | 14 | NULL, HFILL } |
415 | 14 | }, |
416 | 14 | { &hf_png_chunk_len, |
417 | 14 | { "Len", "png.chunk.len", |
418 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
419 | 14 | NULL, HFILL } |
420 | 14 | }, |
421 | 14 | { &hf_png_chunk_crc, |
422 | 14 | { "CRC", "png.chunk.crc", |
423 | 14 | FT_UINT32, BASE_HEX, NULL, 0, |
424 | 14 | NULL, HFILL } |
425 | 14 | }, |
426 | 14 | { &hf_png_chunk_flag_anc, |
427 | 14 | { "Ancillary", "png.chunk.flag.ancillary", |
428 | 14 | FT_BOOLEAN, 32, TFS(&png_chunk_anc), 0x20000000, |
429 | 14 | NULL, HFILL } |
430 | 14 | }, |
431 | 14 | { &hf_png_chunk_flag_priv, |
432 | 14 | { "Private", "png.chunk.flag.private", |
433 | 14 | FT_BOOLEAN, 32, TFS(&png_chunk_priv), 0x00200000, |
434 | 14 | NULL, HFILL } |
435 | 14 | }, |
436 | 14 | { &hf_png_chunk_flag_stc, |
437 | 14 | { "Safe To Copy", "png.chunk.flag.stc", |
438 | 14 | FT_BOOLEAN, 32, TFS(&png_chunk_stc), 0x00000020, |
439 | 14 | NULL, HFILL } |
440 | 14 | }, |
441 | 14 | { &hf_png_ihdr_width, |
442 | 14 | { "Width", "png.ihdr.width", |
443 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
444 | 14 | NULL, HFILL } |
445 | 14 | }, |
446 | 14 | { &hf_png_ihdr_height, |
447 | 14 | { "Height", "png.ihdr.height", |
448 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
449 | 14 | NULL, HFILL } |
450 | 14 | }, |
451 | 14 | { &hf_png_ihdr_bitdepth, |
452 | 14 | { "Bit Depth", "png.ihdr.bitdepth", |
453 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
454 | 14 | NULL, HFILL } |
455 | 14 | }, |
456 | 14 | { &hf_png_ihdr_colour_type, |
457 | 14 | { "Colour Type", "png.ihdr.colour_type", |
458 | 14 | FT_UINT8, BASE_DEC, VALS(colour_type_vals), 0, |
459 | 14 | NULL, HFILL } |
460 | 14 | }, |
461 | 14 | { &hf_png_ihdr_compression_method, |
462 | 14 | { "Compression Method", "png.ihdr.compression_method", |
463 | 14 | FT_UINT8, BASE_DEC, VALS(compression_method_vals), 0, |
464 | 14 | NULL, HFILL } |
465 | 14 | }, |
466 | 14 | { &hf_png_ihdr_filter_method, |
467 | 14 | { "Filter Method", "png.ihdr.filter_method", |
468 | 14 | FT_UINT8, BASE_DEC, VALS(filter_method_vals), 0, |
469 | 14 | NULL, HFILL } |
470 | 14 | }, |
471 | 14 | { &hf_png_ihdr_interlace_method, |
472 | 14 | { "Interlace Method", "png.ihdr.interlace_method", |
473 | 14 | FT_UINT8, BASE_DEC, VALS(interlace_method_vals), 0, |
474 | 14 | NULL, HFILL } |
475 | 14 | }, |
476 | 14 | { &hf_png_srgb_intent, |
477 | 14 | { "Intent", "png.srgb.intent", |
478 | 14 | FT_UINT8, BASE_DEC, VALS(srgb_intent_vals), 0, |
479 | 14 | NULL, HFILL } |
480 | 14 | }, |
481 | 14 | { &hf_png_text_keyword, |
482 | 14 | { "Keyword", "png.text.keyword", |
483 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
484 | 14 | NULL, HFILL } |
485 | 14 | }, |
486 | 14 | { &hf_png_text_string, |
487 | 14 | { "String", "png.text.string", |
488 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
489 | 14 | NULL, HFILL } |
490 | 14 | }, |
491 | 14 | { &hf_png_time_year, |
492 | 14 | { "Year", "png.time.year", |
493 | 14 | FT_UINT16, BASE_DEC, NULL, 0, |
494 | 14 | NULL, HFILL } |
495 | 14 | }, |
496 | 14 | { &hf_png_time_month, |
497 | 14 | { "Month", "png.time.month", |
498 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
499 | 14 | NULL, HFILL } |
500 | 14 | }, |
501 | 14 | { &hf_png_time_day, |
502 | 14 | { "Day", "png.time.day", |
503 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
504 | 14 | NULL, HFILL } |
505 | 14 | }, |
506 | 14 | { &hf_png_time_hour, |
507 | 14 | { "Hour", "png.time.hour", |
508 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
509 | 14 | NULL, HFILL } |
510 | 14 | }, |
511 | 14 | { &hf_png_time_minute, |
512 | 14 | { "Minute", "png.time.minute", |
513 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
514 | 14 | NULL, HFILL } |
515 | 14 | }, |
516 | 14 | { &hf_png_time_second, |
517 | 14 | { "Second", "png.time.second", |
518 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
519 | 14 | NULL, HFILL } |
520 | 14 | }, |
521 | 14 | { &hf_png_phys_horiz, |
522 | 14 | { "Horizontal pixels per unit", "png.phys.horiz", |
523 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
524 | 14 | NULL, HFILL } |
525 | 14 | }, |
526 | 14 | { &hf_png_phys_vert, |
527 | 14 | { "Vertical pixels per unit", "png.phys.vert", |
528 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
529 | 14 | NULL, HFILL } |
530 | 14 | }, |
531 | 14 | { &hf_png_phys_unit, |
532 | 14 | { "Unit", "png.phys.unit", |
533 | 14 | FT_UINT8, BASE_DEC, VALS(phys_unit_vals), 0, |
534 | 14 | NULL, HFILL } |
535 | 14 | }, |
536 | 14 | { &hf_png_bkgd_palette_index, |
537 | 14 | { "Palette Index", "png.bkgd.palette_index", |
538 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
539 | 14 | NULL, HFILL } |
540 | 14 | }, |
541 | 14 | { &hf_png_bkgd_greyscale, |
542 | 14 | { "Greyscale", "png.bkgd.greyscale", |
543 | 14 | FT_UINT16, BASE_HEX, NULL, 0, |
544 | 14 | NULL, HFILL } |
545 | 14 | }, |
546 | 14 | { &hf_png_bkgd_red, |
547 | 14 | { "Red", "png.bkgd.red", |
548 | 14 | FT_UINT16, BASE_HEX, NULL, 0, |
549 | 14 | NULL, HFILL } |
550 | 14 | }, |
551 | 14 | { &hf_png_bkgd_green, |
552 | 14 | { "Green", "png.bkgd.green", |
553 | 14 | FT_UINT16, BASE_HEX, NULL, 0, |
554 | 14 | NULL, HFILL } |
555 | 14 | }, |
556 | 14 | { &hf_png_bkgd_blue, |
557 | 14 | { "Blue", "png.bkgd.blue", |
558 | 14 | FT_UINT16, BASE_HEX, NULL, 0, |
559 | 14 | NULL, HFILL } |
560 | 14 | }, |
561 | 14 | { &hf_png_chrm_white_x, |
562 | 14 | { "White X", "png.chrm.white.x", |
563 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
564 | 14 | NULL, HFILL } |
565 | 14 | }, |
566 | 14 | { &hf_png_chrm_white_y, |
567 | 14 | { "White Y", "png.chrm.white.y", |
568 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
569 | 14 | NULL, HFILL } |
570 | 14 | }, |
571 | 14 | { &hf_png_chrm_red_x, |
572 | 14 | { "Red X", "png.chrm.red.x", |
573 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
574 | 14 | NULL, HFILL } |
575 | 14 | }, |
576 | 14 | { &hf_png_chrm_red_y, |
577 | 14 | { "Red Y", "png.chrm.red.y", |
578 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
579 | 14 | NULL, HFILL } |
580 | 14 | }, |
581 | 14 | { &hf_png_chrm_green_x, |
582 | 14 | { "Green X", "png.chrm.green.x", |
583 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
584 | 14 | NULL, HFILL } |
585 | 14 | }, |
586 | 14 | { &hf_png_chrm_green_y, |
587 | 14 | { "Green Y", "png.chrm.green.y", |
588 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
589 | 14 | NULL, HFILL } |
590 | 14 | }, |
591 | 14 | { &hf_png_chrm_blue_x, |
592 | 14 | { "Blue X", "png.chrm.blue.x", |
593 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
594 | 14 | NULL, HFILL } |
595 | 14 | }, |
596 | 14 | { &hf_png_chrm_blue_y, |
597 | 14 | { "Blue Y", "png.chrm.blue.y", |
598 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
599 | 14 | NULL, HFILL } |
600 | 14 | }, |
601 | 14 | { &hf_png_gama_gamma, |
602 | 14 | { "Gamma", "png.gama.gamma", |
603 | 14 | FT_FLOAT, BASE_NONE, NULL, 0, |
604 | 14 | NULL, HFILL } |
605 | 14 | }, |
606 | 14 | }; |
607 | | |
608 | 14 | static int *ett[] = |
609 | 14 | { |
610 | 14 | &ett_png, |
611 | 14 | &ett_png_chunk, |
612 | 14 | }; |
613 | | |
614 | 14 | static ei_register_info ei[] = { |
615 | 14 | { &ei_png_chunk_too_large, |
616 | 14 | { "png.chunk_too_large", PI_PROTOCOL, PI_WARN, |
617 | 14 | "chunk size too large, dissection of this chunk is not supported", EXPFILL }} |
618 | 14 | }; |
619 | 14 | expert_module_t *expert_png; |
620 | | |
621 | 14 | proto_png = proto_register_protocol("Portable Network Graphics","PNG","png"); |
622 | 14 | proto_register_field_array(proto_png, hf, array_length(hf)); |
623 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
624 | | |
625 | 14 | expert_png = expert_register_protocol(proto_png); |
626 | 14 | expert_register_field_array(expert_png, ei, array_length(ei)); |
627 | | |
628 | 14 | png_handle = register_dissector("png", dissect_png, proto_png); |
629 | 14 | } |
630 | | |
631 | | static bool dissect_png_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
632 | 305 | { |
633 | 305 | return dissect_png(tvb, pinfo, tree, data) > 0; |
634 | 305 | } |
635 | | |
636 | | void |
637 | | proto_reg_handoff_png(void) |
638 | 14 | { |
639 | 14 | dissector_add_string("media_type", "image/png", png_handle); |
640 | 14 | heur_dissector_add("http", dissect_png_heur, "PNG file in HTTP", "png_http", proto_png, HEURISTIC_ENABLE); |
641 | 14 | heur_dissector_add("wtap_file", dissect_png_heur, "PNG file in HTTP", "png_wtap", proto_png, HEURISTIC_ENABLE); |
642 | 14 | } |
643 | | |
644 | | /* |
645 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
646 | | * |
647 | | * Local variables: |
648 | | * c-basic-offset: 4 |
649 | | * tab-width: 8 |
650 | | * indent-tabs-mode: nil |
651 | | * End: |
652 | | * |
653 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
654 | | * :indentSize=4:tabSize=8:noTabs=true: |
655 | | */ |