/src/wireshark/epan/dissectors/file-tiff.c
Line | Count | Source |
1 | | /* file-tiff.c |
2 | | * |
3 | | * Routines for image/tiff dissection |
4 | | * Copyright 2021, Daniel Dulaney. |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * The TIFF 6 specification can be found at: |
11 | | * https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf |
12 | | * |
13 | | * SPDX-License-Identifier: GPL-2.0-or-later |
14 | | */ |
15 | | |
16 | | #include "config.h" |
17 | | #include <epan/packet.h> |
18 | | #include <epan/expert.h> |
19 | | #include <epan/tfs.h> |
20 | | #include <wsutil/array.h> |
21 | | |
22 | | void proto_reg_handoff_tiff(void); |
23 | | void proto_register_tiff(void); |
24 | | |
25 | | static int proto_tiff; |
26 | | |
27 | | // Header fields |
28 | | static int hf_tiff_header_endianness; |
29 | | static int hf_tiff_header_magic; |
30 | | static int hf_tiff_header_lead_ifd; |
31 | | |
32 | | // IFD fields |
33 | | static int hf_tiff_ifd_count; |
34 | | static int hf_tiff_ifd_next; |
35 | | |
36 | | // Entry fields |
37 | | static int hf_tiff_entry_tag; |
38 | | static int hf_tiff_entry_type; |
39 | | static int hf_tiff_entry_count; |
40 | | static int hf_tiff_entry_offset; |
41 | | static int hf_tiff_entry_unknown; |
42 | | |
43 | | // Expert fields |
44 | | static expert_field ei_tiff_unknown_tag; |
45 | | static expert_field ei_tiff_bad_entry; |
46 | | static expert_field ei_tiff_zero_denom; |
47 | | |
48 | | |
49 | | static int ett_tiff; |
50 | | static int ett_ifd; |
51 | | static int ett_t6; |
52 | | |
53 | | #define TIFF_TAG_NEW_SUBFILE_TYPE 254 |
54 | | // Fields TBD |
55 | | |
56 | | #define TIFF_TAG_SUBFILE_TYPE 255 |
57 | | // Fields TBD |
58 | | |
59 | 0 | #define TIFF_TAG_IMAGE_WIDTH 256 |
60 | | static int hf_tiff_image_width; |
61 | | |
62 | 0 | #define TIFF_TAG_IMAGE_LENGTH 257 |
63 | | static int hf_tiff_image_length; |
64 | | |
65 | 0 | #define TIFF_TAG_BITS_PER_SAMPLE 258 |
66 | | static int hf_tiff_bits_per_sample; |
67 | | |
68 | 0 | #define TIFF_TAG_COMPRESSION 259 |
69 | | static int hf_tiff_compression; |
70 | | |
71 | 0 | #define TIFF_TAG_PHOTOMETRIC_INTERPRETATION 262 |
72 | | static int hf_tiff_photometric_interp; |
73 | | |
74 | 0 | #define TIFF_TAG_THRESHHOLDING 263 |
75 | | static int hf_tiff_threshholding; |
76 | | |
77 | 0 | #define TIFF_TAG_CELL_WIDTH 264 |
78 | | static int hf_tiff_cell_width; |
79 | | |
80 | 0 | #define TIFF_TAG_CELL_LENGTH 265 |
81 | | static int hf_tiff_cell_length; |
82 | | |
83 | 0 | #define TIFF_TAG_FILL_ORDER 266 |
84 | | static int hf_tiff_fill_order; |
85 | | |
86 | 0 | #define TIFF_TAG_DOCUMENT_NAME 269 |
87 | | static int hf_tiff_document_name; |
88 | | |
89 | 0 | #define TIFF_TAG_IMAGE_DESCRIPTION 270 |
90 | | static int hf_tiff_image_description; |
91 | | |
92 | 0 | #define TIFF_TAG_MAKE 271 |
93 | | static int hf_tiff_make; |
94 | | |
95 | 0 | #define TIFF_TAG_MODEL 272 |
96 | | static int hf_tiff_model; |
97 | | |
98 | 0 | #define TIFF_TAG_STRIP_OFFSETS 273 |
99 | | static int hf_tiff_strip_offset; |
100 | | |
101 | 0 | #define TIFF_TAG_ORIENTATION 274 |
102 | | static int hf_tiff_orientation; |
103 | | |
104 | 0 | #define TIFF_TAG_SAMPLES_PER_PIXEL 277 |
105 | | static int hf_tiff_samples_per_pixel; |
106 | | |
107 | 0 | #define TIFF_TAG_ROWS_PER_STRIP 278 |
108 | | static int hf_tiff_rows_per_strip; |
109 | | |
110 | 0 | #define TIFF_TAG_STRIP_BYTE_COUNTS 279 |
111 | | static int hf_tiff_strip_byte_count; |
112 | | |
113 | | #define TIFF_TAG_MIN_SAMPLE_VALUE 280 |
114 | | // Fields TBD |
115 | | |
116 | | #define TIFF_TAG_MAX_SAMPLE_VALUE 281 |
117 | | // Fields TBD |
118 | | |
119 | 0 | #define TIFF_TAG_X_RESOLUTION 282 |
120 | | static int hf_tiff_x_res_numer; |
121 | | static int hf_tiff_x_res_denom; |
122 | | static int hf_tiff_x_res_approx; |
123 | | |
124 | 0 | #define TIFF_TAG_Y_RESOLUTION 283 |
125 | | static int hf_tiff_y_res_numer; |
126 | | static int hf_tiff_y_res_denom; |
127 | | static int hf_tiff_y_res_approx; |
128 | | |
129 | 0 | #define TIFF_TAG_PLANAR_CONFIGURATION 284 |
130 | | static int hf_tiff_planar_configuration; |
131 | | |
132 | 0 | #define TIFF_TAG_PAGE_NAME 285 |
133 | | static int hf_tiff_page_name; |
134 | | |
135 | | #define TIFF_TAG_X_POSITION 286 |
136 | | // Fields TBD |
137 | | |
138 | | #define TIFF_TAG_Y_POSITION 287 |
139 | | // Fields TBD |
140 | | |
141 | | #define TIFF_TAG_FREE_OFFSETS 288 |
142 | | // Fields TBD |
143 | | |
144 | | #define TIFF_TAG_FREE_BYTE_COUNTS 289 |
145 | | // Fields TBD |
146 | | |
147 | 0 | #define TIFF_TAG_GRAY_RESPONSE_UNIT 290 |
148 | | static int hf_tiff_gray_response_unit; |
149 | | |
150 | | #define TIFF_TAG_GRAY_RESPONSE_CURVE 291 |
151 | | // Fields TBD |
152 | | |
153 | | #define TIFF_TAG_T4_OPTIONS 292 |
154 | | // Fields TBD |
155 | | |
156 | 0 | #define TIFF_TAG_T6_OPTIONS 293 |
157 | | static int hf_tiff_t6_options; |
158 | | static int hf_tiff_t6_unused; |
159 | | static int hf_tiff_t6_allow_uncompressed; |
160 | | |
161 | 0 | #define TIFF_TAG_RESOLUTION_UNIT 296 |
162 | | static int hf_tiff_resolution_unit; |
163 | | |
164 | | #define TIFF_TAG_PAGE_NUMBER 297 |
165 | | // Fields TBD |
166 | | |
167 | | #define TIFF_TAG_TRANSFER_FUNCTION 301 |
168 | | // Fields TBD |
169 | | |
170 | 0 | #define TIFF_TAG_SOFTWARE 305 |
171 | | static int hf_tiff_software; |
172 | | |
173 | 0 | #define TIFF_TAG_DATE_TIME 306 |
174 | | static int hf_tiff_date_time; |
175 | | |
176 | 0 | #define TIFF_TAG_ARTIST 315 |
177 | | static int hf_tiff_artist; |
178 | | |
179 | 0 | #define TIFF_TAG_HOST_COMPUTER 316 |
180 | | static int hf_tiff_host_computer; |
181 | | |
182 | 0 | #define TIFF_TAG_PREDICTOR 317 |
183 | | static int hf_tiff_predictor; |
184 | | |
185 | | #define TIFF_TAG_WHITE_POINT 318 |
186 | | // Fields TBD |
187 | | |
188 | | #define TIFF_TAG_PRIMARY_CHROMATICITIES 319 |
189 | | // Fields TBD |
190 | | |
191 | | #define TIFF_TAG_COLOR_MAP 320 |
192 | | // Fields TBD |
193 | | |
194 | | #define TIFF_TAG_HALFTONE_HINTS 321 |
195 | | // Fields TBD |
196 | | |
197 | 0 | #define TIFF_TAG_TILE_WIDTH 322 |
198 | | static int hf_tiff_tile_width; |
199 | | |
200 | 0 | #define TIFF_TAG_TILE_LENGTH 323 |
201 | | static int hf_tiff_tile_length; |
202 | | |
203 | | #define TIFF_TAG_TILE_OFFSETS 324 |
204 | | // Fields TBD |
205 | | |
206 | | #define TIFF_TAG_TILE_BYTE_COUNTS 325 |
207 | | // Fields TBD |
208 | | |
209 | 0 | #define TIFF_TAG_INK_SET 332 |
210 | | static int hf_tiff_ink_set; |
211 | | |
212 | | #define TIFF_TAG_INK_NAMES 333 |
213 | | // Fields TBD |
214 | | |
215 | 0 | #define TIFF_TAG_NUMBER_OF_INKS 334 |
216 | | static int hf_tiff_number_of_inks; |
217 | | |
218 | | #define TIFF_TAG_DOT_RANGE 336 |
219 | | // Fields TBD |
220 | | |
221 | 0 | #define TIFF_TAG_TARGET_PRINTER 337 |
222 | | static int hf_tiff_target_printer; |
223 | | |
224 | | #define TIFF_TAG_EXTRA_SAMPLES 338 |
225 | | // Fields TBD |
226 | | |
227 | | #define TIFF_TAG_SAMPLE_FORMAT 339 |
228 | | // Fields TBD |
229 | | |
230 | | #define TIFF_TAG_S_MIN_SAMPLE_VALUE 340 |
231 | | // Fields TBD |
232 | | |
233 | | #define TIFF_TAG_S_MAX_SAMPLE_VALUE 341 |
234 | | // Fields TBD |
235 | | |
236 | | #define TIFF_TAG_TRANSFER_RANGE 342 |
237 | | // Fields TBD |
238 | | |
239 | | #define TIFF_TAG_JPEG_PROC 512 |
240 | | // Fields TBD |
241 | | |
242 | | #define TIFF_TAG_JPEG_INTERCHANGE_FORMAT 513 |
243 | | // Fields TBD |
244 | | |
245 | | #define TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH 514 |
246 | | // Fields TBD |
247 | | |
248 | | #define TIFF_TAG_JPEG_RESTART_INTERVAL 515 |
249 | | // Fields TBD |
250 | | |
251 | | #define TIFF_TAG_JPEG_LOSSLESS_PREDICTORS 517 |
252 | | // Fields TBD |
253 | | |
254 | | #define TIFF_TAG_JPEG_POINT_TRANSFORMS 518 |
255 | | // Fields TBD |
256 | | |
257 | | #define TIFF_TAG_JPEG_Q_TABLES 519 |
258 | | // Fields TBD |
259 | | |
260 | | #define TIFF_TAG_JPEG_DC_TABLES 520 |
261 | | // Fields TBD |
262 | | |
263 | | #define TIFF_TAG_JPEG_AC_TABLES 521 |
264 | | // Fields TBD |
265 | | |
266 | | #define TIFF_TAG_YCBCR_COEFFICIENTS 529 |
267 | | // Fields TBD |
268 | | |
269 | | #define TIFF_TAG_YCBCR_SUBSAMPLING 530 |
270 | | // Fields TBD |
271 | | |
272 | | #define TIFF_TAG_YCBCR_POSITIONING 531 |
273 | | // Fields TBD |
274 | | |
275 | | #define TIFF_TAG_REFERENCE_BLACK_WHITE 532 |
276 | | // Fields TBD |
277 | | |
278 | 0 | #define TIFF_TAG_COPYRIGHT 0x8298 |
279 | | static int hf_tiff_copyright; |
280 | | |
281 | | static const value_string tiff_endianness_names[] = { |
282 | | { 0x4949, "Little-Endian" }, |
283 | | { 0x4D4D, "Big-Endian" }, |
284 | | { 0, NULL }, |
285 | | }; |
286 | | |
287 | | static const value_string tiff_tag_names[] = { |
288 | | { TIFF_TAG_NEW_SUBFILE_TYPE, "New Subfile Type" }, |
289 | | { TIFF_TAG_SUBFILE_TYPE, "Subfile Type" }, |
290 | | { TIFF_TAG_IMAGE_WIDTH, "Image Width" }, |
291 | | { TIFF_TAG_IMAGE_LENGTH, "Image Length" }, |
292 | | { TIFF_TAG_BITS_PER_SAMPLE, "Bits Per Sample" }, |
293 | | { TIFF_TAG_COMPRESSION, "Compression" }, |
294 | | { TIFF_TAG_PHOTOMETRIC_INTERPRETATION, "Photometric Interpretation" }, |
295 | | { TIFF_TAG_THRESHHOLDING, "Threshholding" }, |
296 | | { TIFF_TAG_CELL_WIDTH, "Cell Width" }, |
297 | | { TIFF_TAG_CELL_LENGTH, "Cell Length" }, |
298 | | { TIFF_TAG_FILL_ORDER, "Fill Order" }, |
299 | | { TIFF_TAG_DOCUMENT_NAME, "Document Name" }, |
300 | | { TIFF_TAG_IMAGE_DESCRIPTION, "Image Description" }, |
301 | | { TIFF_TAG_MAKE, "Make" }, |
302 | | { TIFF_TAG_MODEL, "Model" }, |
303 | | { TIFF_TAG_STRIP_OFFSETS, "Strip Offsets" }, |
304 | | { TIFF_TAG_ORIENTATION, "Orientation" }, |
305 | | { TIFF_TAG_SAMPLES_PER_PIXEL, "Samples Per Pixel" }, |
306 | | { TIFF_TAG_ROWS_PER_STRIP, "Rows Per Strip" }, |
307 | | { TIFF_TAG_STRIP_BYTE_COUNTS, "Strip Byte Counts" }, |
308 | | { TIFF_TAG_MIN_SAMPLE_VALUE, "Min Sample Value" }, |
309 | | { TIFF_TAG_MAX_SAMPLE_VALUE, "Max Sample Value" }, |
310 | | { TIFF_TAG_X_RESOLUTION, "X Resolution" }, |
311 | | { TIFF_TAG_Y_RESOLUTION, "Y Resolution" }, |
312 | | { TIFF_TAG_PLANAR_CONFIGURATION, "Planar Configuration" }, |
313 | | { TIFF_TAG_PAGE_NAME, "Page Name" }, |
314 | | { TIFF_TAG_X_POSITION, "X Position" }, |
315 | | { TIFF_TAG_Y_POSITION, "Y Position" }, |
316 | | { TIFF_TAG_FREE_OFFSETS, "Free Offsets" }, |
317 | | { TIFF_TAG_FREE_BYTE_COUNTS, "Free Byte Counts" }, |
318 | | { TIFF_TAG_GRAY_RESPONSE_UNIT, "Gray Response Unit" }, |
319 | | { TIFF_TAG_GRAY_RESPONSE_CURVE, "Gray Response Curve" }, |
320 | | { TIFF_TAG_T4_OPTIONS, "T4 Options" }, |
321 | | { TIFF_TAG_T6_OPTIONS, "T6 Options" }, |
322 | | { TIFF_TAG_RESOLUTION_UNIT, "Resolution Unit" }, |
323 | | { TIFF_TAG_PAGE_NUMBER, "Page Number" }, |
324 | | { TIFF_TAG_TRANSFER_FUNCTION, "Transfer Function" }, |
325 | | { TIFF_TAG_SOFTWARE, "Software" }, |
326 | | { TIFF_TAG_DATE_TIME, "Date Time" }, |
327 | | { TIFF_TAG_ARTIST, "Artist" }, |
328 | | { TIFF_TAG_HOST_COMPUTER, "Host Computer" }, |
329 | | { TIFF_TAG_PREDICTOR, "Predictor" }, |
330 | | { TIFF_TAG_WHITE_POINT, "White Point" }, |
331 | | { TIFF_TAG_PRIMARY_CHROMATICITIES, "Primary Chromaticities" }, |
332 | | { TIFF_TAG_COLOR_MAP, "Color Map" }, |
333 | | { TIFF_TAG_HALFTONE_HINTS, "Halftone Hints" }, |
334 | | { TIFF_TAG_TILE_WIDTH, "Tile Width" }, |
335 | | { TIFF_TAG_TILE_LENGTH, "Tile Length" }, |
336 | | { TIFF_TAG_TILE_OFFSETS, "Tile Offsets" }, |
337 | | { TIFF_TAG_TILE_BYTE_COUNTS, "Tile Byte Counts" }, |
338 | | { TIFF_TAG_INK_SET, "Ink Set" }, |
339 | | { TIFF_TAG_INK_NAMES, "Ink Names" }, |
340 | | { TIFF_TAG_NUMBER_OF_INKS, "Number Of Inks" }, |
341 | | { TIFF_TAG_DOT_RANGE, "Dot Range" }, |
342 | | { TIFF_TAG_TARGET_PRINTER, "Target Printer" }, |
343 | | { TIFF_TAG_EXTRA_SAMPLES, "Extra Samples" }, |
344 | | { TIFF_TAG_SAMPLE_FORMAT, "Sample Format" }, |
345 | | { TIFF_TAG_S_MIN_SAMPLE_VALUE, "S Min Sample Value" }, |
346 | | { TIFF_TAG_S_MAX_SAMPLE_VALUE, "S Max Sample Value" }, |
347 | | { TIFF_TAG_TRANSFER_RANGE, "Transfer Range" }, |
348 | | { TIFF_TAG_JPEG_PROC, "JPEG Proc" }, |
349 | | { TIFF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEG Interchange Format" }, |
350 | | { TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, "JPEG Interchange Format Length" }, |
351 | | { TIFF_TAG_JPEG_RESTART_INTERVAL, "JPEG Restart Interval" }, |
352 | | { TIFF_TAG_JPEG_LOSSLESS_PREDICTORS, "JPEG Lossless Predictors" }, |
353 | | { TIFF_TAG_JPEG_POINT_TRANSFORMS, "JPEG Point Transforms" }, |
354 | | { TIFF_TAG_JPEG_Q_TABLES, "JPEG Q Tables" }, |
355 | | { TIFF_TAG_JPEG_DC_TABLES, "JPEG DC Tables" }, |
356 | | { TIFF_TAG_JPEG_AC_TABLES, "JPEG AC Tables" }, |
357 | | { TIFF_TAG_YCBCR_COEFFICIENTS, "YCbCr Coefficients" }, |
358 | | { TIFF_TAG_YCBCR_SUBSAMPLING, "YCbCr Subsampling" }, |
359 | | { TIFF_TAG_YCBCR_POSITIONING, "YCbCr Positioning" }, |
360 | | { TIFF_TAG_REFERENCE_BLACK_WHITE, "Reference Black White" }, |
361 | | { TIFF_TAG_COPYRIGHT, "Copyright" }, |
362 | | { 0, NULL }, |
363 | | }; |
364 | | |
365 | 0 | #define TIFF_TYPE_BYTE 1 |
366 | 0 | #define TIFF_TYPE_ASCII 2 |
367 | 0 | #define TIFF_TYPE_SHORT 3 |
368 | 0 | #define TIFF_TYPE_LONG 4 |
369 | 0 | #define TIFF_TYPE_RATIONAL 5 |
370 | 0 | #define TIFF_TYPE_SBYTE 6 |
371 | 0 | #define TIFF_TYPE_UNDEFINED 7 |
372 | 0 | #define TIFF_TYPE_SSHORT 8 |
373 | 0 | #define TIFF_TYPE_SLONG 9 |
374 | 0 | #define TIFF_TYPE_SRATIONAL 10 |
375 | 0 | #define TIFF_TYPE_FLOAT 11 |
376 | 0 | #define TIFF_TYPE_DOUBLE 12 |
377 | | |
378 | | static const value_string tiff_type_names[] = { |
379 | | { TIFF_TYPE_BYTE, "Byte" }, |
380 | | { TIFF_TYPE_ASCII, "ASCII" }, |
381 | | { TIFF_TYPE_SHORT, "Unsigned Short" }, |
382 | | { TIFF_TYPE_LONG, "Unsigned Long" }, |
383 | | { TIFF_TYPE_RATIONAL, "Rational" }, |
384 | | { TIFF_TYPE_SBYTE, "Signed Byte" }, |
385 | | { TIFF_TYPE_UNDEFINED, "Undefined" }, |
386 | | { TIFF_TYPE_SSHORT, "Signed Short" }, |
387 | | { TIFF_TYPE_SLONG, "Signed Long" }, |
388 | | { TIFF_TYPE_SRATIONAL, "Signed Rational" }, |
389 | | { TIFF_TYPE_FLOAT, "Float" }, |
390 | | { TIFF_TYPE_DOUBLE, "Double" }, |
391 | | { 0, NULL }, |
392 | | }; |
393 | | |
394 | | static const value_string tiff_compression_names[] = { |
395 | | { 1, "Uncompressed" }, |
396 | | { 2, "CITT 1D" }, |
397 | | { 3, "Group 3 Fax" }, |
398 | | { 4, "Group 4 Fax" }, |
399 | | { 5, "LZW" }, |
400 | | { 6, "JPEG" }, |
401 | | { 32773, "PackBits" }, |
402 | | { 0, NULL }, |
403 | | }; |
404 | | |
405 | | static const value_string tiff_photometric_interp_names[] = { |
406 | | { 0, "White is Zero" }, |
407 | | { 1, "Black is Zero" }, |
408 | | { 2, "RGB" }, |
409 | | { 3, "RGB Palette" }, |
410 | | { 4, "Transparency Mask" }, |
411 | | { 5, "CMYK" }, |
412 | | { 6, "YCbCr" }, |
413 | | /* N.B. no value for 7 (see Appendix A) */ |
414 | | { 8, "CIELab" }, |
415 | | { 0, NULL }, |
416 | | }; |
417 | | |
418 | | static const value_string tiff_threshholding_names[] = { |
419 | | { 0, "None" }, |
420 | | { 1, "Ordered" }, |
421 | | { 2, "Randomized" }, |
422 | | { 0, NULL }, |
423 | | }; |
424 | | |
425 | | static const value_string tiff_fill_order_names[] = { |
426 | | { 1, "High-order first" }, |
427 | | { 2, "Low-order first" }, |
428 | | { 0, NULL }, |
429 | | }; |
430 | | |
431 | | static const value_string tiff_orientation_names[] = { |
432 | | { 1, "Origin at Top-Left, Horizontal Rows" }, |
433 | | { 2, "Origin at Top-Right, Horizontal Rows" }, |
434 | | { 3, "Origin at Bottom-Right, Horizontal Rows" }, |
435 | | { 4, "Origin at Bottom-Left, Horizontal Rows" }, |
436 | | { 5, "Origin at Top-Left, Vertical Rows" }, |
437 | | { 6, "Origin at Top-Right, Vertical Rows" }, |
438 | | { 7, "Origin at Bottom-Right, Vertical Rows" }, |
439 | | { 8, "Origin at Bottom-Left, Vertical Rows" }, |
440 | | { 0, NULL }, |
441 | | }; |
442 | | |
443 | | static const value_string tiff_planar_configuration_names[] = { |
444 | | { 1, "Chunky" }, |
445 | | { 2, "Planar" }, |
446 | | { 0, NULL }, |
447 | | }; |
448 | | |
449 | | static const value_string tiff_gray_response_unit_names[] = { |
450 | | { 1, "Tenths" }, |
451 | | { 2, "Hundredths" }, |
452 | | { 3, "Thousandths" }, |
453 | | { 4, "Ten-thousandths" }, |
454 | | { 5, "Hundred-thousandths" }, |
455 | | { 0, NULL }, |
456 | | }; |
457 | | |
458 | | static const value_string tiff_resolution_unit_names[] = { |
459 | | { 1, "None" }, |
460 | | { 2, "Inch" }, |
461 | | { 3, "Centimeter" }, |
462 | | { 0, NULL }, |
463 | | }; |
464 | | |
465 | | static const value_string tiff_predictor_names[] = { |
466 | | { 1, "No Predictor" }, |
467 | | { 2, "Horizontal Differencing" }, |
468 | | { 0, NULL }, |
469 | | }; |
470 | | |
471 | | static const value_string tiff_ink_set_names[] = { |
472 | | { 1, "CMYK" }, |
473 | | { 2, "Not CMYK" }, |
474 | | { 0, NULL }, |
475 | | }; |
476 | | |
477 | | // Return the length of the given data type. |
478 | | // |
479 | | // If the type isn't known, return -1. |
480 | | static int |
481 | 0 | tiff_type_len(const uint16_t type) { |
482 | 0 | switch (type) { |
483 | 0 | case TIFF_TYPE_BYTE: return 1; |
484 | 0 | case TIFF_TYPE_ASCII: return 1; |
485 | 0 | case TIFF_TYPE_SHORT: return 2; |
486 | 0 | case TIFF_TYPE_LONG: return 4; |
487 | 0 | case TIFF_TYPE_RATIONAL: return 8; |
488 | 0 | case TIFF_TYPE_SBYTE: return 1; |
489 | 0 | case TIFF_TYPE_UNDEFINED: return 1; |
490 | 0 | case TIFF_TYPE_SSHORT: return 2; |
491 | 0 | case TIFF_TYPE_SLONG: return 4; |
492 | 0 | case TIFF_TYPE_SRATIONAL: return 8; |
493 | 0 | case TIFF_TYPE_FLOAT: return 4; |
494 | 0 | case TIFF_TYPE_DOUBLE: return 8; |
495 | | |
496 | 0 | default: return -1; |
497 | 0 | } |
498 | 0 | } |
499 | | |
500 | | // Return the length of the given array of data. |
501 | | // |
502 | | // If the type isn't known, return -1. |
503 | | static int |
504 | 0 | tiff_data_len(const uint16_t type, const uint32_t count) { |
505 | 0 | const int field = tiff_type_len(type); |
506 | 0 | if (field < 0) return -1; |
507 | 0 | else return field * count; |
508 | 0 | } |
509 | | |
510 | | static void |
511 | | dissect_tiff_tag_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint16_t type, uint32_t count, int encoding _U_) |
512 | 0 | { |
513 | 0 | const int len = tiff_data_len(type, count); |
514 | |
|
515 | 0 | expert_add_info(pinfo, tree, &ei_tiff_unknown_tag); |
516 | |
|
517 | 0 | uint32_t item_offset; |
518 | 0 | if (len <= 0) { |
519 | | // If we can't determine the length, that's an issue |
520 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Could not determine length of entry"); |
521 | 0 | return; |
522 | 0 | } else if (len <= 4) { |
523 | | // If the length is <= 4, the item is located directly at the offset |
524 | 0 | item_offset = offset; |
525 | 0 | } else { |
526 | | // If the length is >4, the offset is a pointer indicating where the item is located |
527 | 0 | proto_tree_add_item_ret_uint(tree, hf_tiff_entry_offset, tvb, offset, 4, encoding, &item_offset); |
528 | 0 | } |
529 | | |
530 | 0 | proto_tree_add_item(tree, hf_tiff_entry_unknown, tvb, item_offset, len, encoding); |
531 | 0 | } |
532 | | |
533 | | static void |
534 | 0 | dissect_tiff_single_uint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint16_t type, uint32_t count, int encoding, int hfindex) { |
535 | 0 | if (count != 1) { |
536 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected a single item; found %d items", count); |
537 | 0 | return; |
538 | 0 | } |
539 | | |
540 | 0 | if (type == TIFF_TYPE_BYTE) { |
541 | 0 | proto_tree_add_item(tree, hfindex, tvb, offset, 1, encoding); |
542 | 0 | } else if (type == TIFF_TYPE_SHORT) { |
543 | 0 | proto_tree_add_item(tree, hfindex, tvb, offset, 2, encoding); |
544 | 0 | } else if (type == TIFF_TYPE_LONG) { |
545 | 0 | proto_tree_add_item(tree, hfindex, tvb, offset, 4, encoding); |
546 | 0 | } else { |
547 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected an unsigned integer, found type %s", val_to_str_const(type, tiff_type_names, "Unknown")); |
548 | 0 | } |
549 | 0 | } |
550 | | |
551 | | static void |
552 | 0 | dissect_tiff_array_uint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint16_t type, uint32_t count, int encoding, int hfindex) { |
553 | 0 | if (!(type == TIFF_TYPE_BYTE || type == TIFF_TYPE_SHORT || type == TIFF_TYPE_LONG)) { |
554 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected an unsigned integer, found type %s", val_to_str_const(type, tiff_type_names, "Unknown")); |
555 | 0 | return; |
556 | 0 | } |
557 | | |
558 | 0 | if (count < 1) { |
559 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "At least 1 item; found %d items", count); |
560 | 0 | return; |
561 | 0 | } |
562 | | |
563 | 0 | const int item_len = tiff_type_len(type); |
564 | 0 | const int len = tiff_data_len(type, count); |
565 | |
|
566 | 0 | uint32_t item_offset; |
567 | 0 | if (len <= 0 || item_len <= 0) { |
568 | | // If we can't determine the length, that's an issue |
569 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Could not determine length of entry"); |
570 | 0 | return; |
571 | 0 | } else if (len <= 4) { |
572 | | // If the length is <= 4, the item is located directly at the offset |
573 | 0 | item_offset = offset; |
574 | 0 | } else { |
575 | | // If the length is >4, the offset is a pointer indicating where the item is located |
576 | 0 | proto_tree_add_item_ret_uint(tree, hf_tiff_entry_offset, tvb, offset, 4, encoding, &item_offset); |
577 | 0 | } |
578 | | |
579 | | // Add each item |
580 | 0 | for (uint32_t i = 0; i < count; i++) { |
581 | 0 | proto_tree_add_item(tree, hfindex, tvb, item_offset + item_len * i, item_len, encoding); |
582 | 0 | } |
583 | 0 | } |
584 | | |
585 | | static void |
586 | 0 | dissect_tiff_single_string(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint16_t type, uint32_t count, int encoding, int hfindex) { |
587 | 0 | if (type != TIFF_TYPE_ASCII) { |
588 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected an ASCII string"); |
589 | 0 | return; |
590 | 0 | } |
591 | | |
592 | 0 | uint32_t item_offset; |
593 | 0 | if (count == 0) { |
594 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected at least one byte for an ASCII string; got zero"); |
595 | 0 | return; |
596 | 0 | } else if (count <= 4) { |
597 | | // If there are 4 or fewer bytes, the string is embedded in the pointer |
598 | 0 | item_offset = offset; |
599 | 0 | } else { |
600 | | // If the length is >4, the offset is a pointer indicating where the item is located |
601 | 0 | proto_tree_add_item_ret_uint(tree, hf_tiff_entry_offset, tvb, offset, 4, encoding, &item_offset); |
602 | 0 | } |
603 | | |
604 | 0 | proto_tree_add_item(tree, hfindex, tvb, item_offset, count, ENC_ASCII); |
605 | 0 | } |
606 | | |
607 | | static void |
608 | 0 | dissect_tiff_single_urational(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint16_t type, uint32_t count, int encoding, int hfnumer, int hfdenom, int hfapprox) { |
609 | 0 | if (count != 1) { |
610 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected a single item; found %d items", count); |
611 | 0 | return; |
612 | 0 | } |
613 | | |
614 | 0 | if (type != TIFF_TYPE_RATIONAL) { |
615 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected an unsigned rational"); |
616 | 0 | return; |
617 | 0 | } |
618 | | |
619 | 0 | uint32_t item_offset; |
620 | 0 | proto_tree_add_item_ret_uint(tree, hf_tiff_entry_offset, tvb, offset, 4, encoding, &item_offset); |
621 | |
|
622 | 0 | uint32_t numer = 0; |
623 | 0 | uint32_t denom = 0; |
624 | 0 | proto_tree_add_item_ret_uint(tree, hfnumer, tvb, item_offset, 4, encoding, &numer); |
625 | 0 | proto_item *denom_ti = proto_tree_add_item_ret_uint(tree, hfdenom, tvb, item_offset + 4, 4, encoding, &denom); |
626 | |
|
627 | 0 | if (denom > 0) { |
628 | 0 | proto_item *approx_item = proto_tree_add_double(tree, hfapprox, tvb, item_offset, 8, (double)numer / (double)denom); |
629 | 0 | proto_item_set_generated(approx_item); |
630 | 0 | } |
631 | 0 | else { |
632 | 0 | expert_add_info(pinfo, denom_ti, &ei_tiff_zero_denom); |
633 | 0 | } |
634 | 0 | } |
635 | | |
636 | | static void |
637 | 0 | dissect_tiff_t6_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint16_t type, uint32_t count, int encoding) { |
638 | 0 | if (count != 1) { |
639 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected a single item; found %d items", count); |
640 | 0 | return; |
641 | 0 | } |
642 | | |
643 | 0 | if (type != TIFF_TYPE_LONG) { |
644 | 0 | expert_add_info_format(pinfo, tree, &ei_tiff_bad_entry, "Expected an unsigned long"); |
645 | 0 | return; |
646 | 0 | } |
647 | | |
648 | 0 | proto_item *t6_ti = proto_tree_add_item(tree, hf_tiff_t6_options, tvb, offset, 4, encoding); |
649 | 0 | proto_tree *t6_tree = proto_item_add_subtree(t6_ti, ett_t6); |
650 | 0 | proto_tree_add_item(t6_tree, hf_tiff_t6_unused, tvb, offset, 4, encoding); |
651 | 0 | proto_tree_add_item(t6_tree, hf_tiff_t6_allow_uncompressed, tvb, offset, 4, encoding); |
652 | 0 | } |
653 | | |
654 | | static void |
655 | 0 | dissect_tiff_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, int encoding) { |
656 | 0 | const uint16_t tag = tvb_get_uint16(tvb, offset, encoding); |
657 | |
|
658 | 0 | proto_tree *entry_tree = proto_tree_add_subtree_format(tree, tvb, offset, 12, ett_ifd, NULL, "%s", val_to_str_const(tag, tiff_tag_names, "Unknown Entry")); |
659 | |
|
660 | 0 | proto_tree_add_item(entry_tree, hf_tiff_entry_tag, tvb, offset, 2, encoding); |
661 | |
|
662 | 0 | uint32_t type = 0; |
663 | 0 | uint32_t count = 0; |
664 | 0 | proto_tree_add_item_ret_uint(entry_tree, hf_tiff_entry_type, tvb, offset + 2, 2, encoding, &type); |
665 | 0 | proto_tree_add_item_ret_uint(entry_tree, hf_tiff_entry_count, tvb, offset + 4, 4, encoding, &count); |
666 | |
|
667 | 0 | switch (tag) { |
668 | 0 | case TIFF_TAG_IMAGE_WIDTH: |
669 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_image_width); |
670 | 0 | break; |
671 | 0 | case TIFF_TAG_IMAGE_LENGTH: |
672 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_image_length); |
673 | 0 | break; |
674 | 0 | case TIFF_TAG_BITS_PER_SAMPLE: |
675 | 0 | dissect_tiff_array_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_bits_per_sample); |
676 | 0 | break; |
677 | 0 | case TIFF_TAG_COMPRESSION: |
678 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_compression); |
679 | 0 | break; |
680 | 0 | case TIFF_TAG_PHOTOMETRIC_INTERPRETATION: |
681 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_photometric_interp); |
682 | 0 | break; |
683 | 0 | case TIFF_TAG_THRESHHOLDING: |
684 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_threshholding); |
685 | 0 | break; |
686 | 0 | case TIFF_TAG_CELL_WIDTH: |
687 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_cell_width); |
688 | 0 | break; |
689 | 0 | case TIFF_TAG_CELL_LENGTH: |
690 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_cell_length); |
691 | 0 | break; |
692 | 0 | case TIFF_TAG_FILL_ORDER: |
693 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_fill_order); |
694 | 0 | break; |
695 | 0 | case TIFF_TAG_DOCUMENT_NAME: |
696 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_document_name); |
697 | 0 | break; |
698 | 0 | case TIFF_TAG_IMAGE_DESCRIPTION: |
699 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_image_description); |
700 | 0 | break; |
701 | 0 | case TIFF_TAG_MAKE: |
702 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_make); |
703 | 0 | break; |
704 | 0 | case TIFF_TAG_MODEL: |
705 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_model); |
706 | 0 | break; |
707 | 0 | case TIFF_TAG_STRIP_OFFSETS: |
708 | 0 | dissect_tiff_array_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_strip_offset); |
709 | 0 | break; |
710 | 0 | case TIFF_TAG_ORIENTATION: |
711 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_orientation); |
712 | 0 | break; |
713 | 0 | case TIFF_TAG_SAMPLES_PER_PIXEL: |
714 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_samples_per_pixel); |
715 | 0 | break; |
716 | 0 | case TIFF_TAG_ROWS_PER_STRIP: |
717 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_rows_per_strip); |
718 | 0 | break; |
719 | 0 | case TIFF_TAG_STRIP_BYTE_COUNTS: |
720 | 0 | dissect_tiff_array_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_strip_byte_count); |
721 | 0 | break; |
722 | 0 | case TIFF_TAG_X_RESOLUTION: |
723 | 0 | dissect_tiff_single_urational(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_x_res_numer, hf_tiff_x_res_denom, hf_tiff_x_res_approx); |
724 | 0 | break; |
725 | 0 | case TIFF_TAG_Y_RESOLUTION: |
726 | 0 | dissect_tiff_single_urational(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_y_res_numer, hf_tiff_y_res_denom, hf_tiff_y_res_approx); |
727 | 0 | break; |
728 | 0 | case TIFF_TAG_PLANAR_CONFIGURATION: |
729 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_planar_configuration); |
730 | 0 | break; |
731 | 0 | case TIFF_TAG_PAGE_NAME: |
732 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_page_name); |
733 | 0 | break; |
734 | 0 | case TIFF_TAG_GRAY_RESPONSE_UNIT: |
735 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_gray_response_unit); |
736 | 0 | break; |
737 | 0 | case TIFF_TAG_T6_OPTIONS: |
738 | 0 | dissect_tiff_t6_options(tvb, pinfo, entry_tree, offset + 8, type, count, encoding); |
739 | 0 | break; |
740 | 0 | case TIFF_TAG_RESOLUTION_UNIT: |
741 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_resolution_unit); |
742 | 0 | break; |
743 | 0 | case TIFF_TAG_SOFTWARE: |
744 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_software); |
745 | 0 | break; |
746 | 0 | case TIFF_TAG_DATE_TIME: |
747 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_date_time); |
748 | 0 | break; |
749 | 0 | case TIFF_TAG_ARTIST: |
750 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_artist); |
751 | 0 | break; |
752 | 0 | case TIFF_TAG_HOST_COMPUTER: |
753 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_host_computer); |
754 | 0 | break; |
755 | 0 | case TIFF_TAG_PREDICTOR: |
756 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_predictor); |
757 | 0 | break; |
758 | 0 | case TIFF_TAG_TILE_WIDTH: |
759 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_tile_width); |
760 | 0 | break; |
761 | 0 | case TIFF_TAG_TILE_LENGTH: |
762 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_tile_length); |
763 | 0 | break; |
764 | 0 | case TIFF_TAG_INK_SET: |
765 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_ink_set); |
766 | 0 | break; |
767 | 0 | case TIFF_TAG_NUMBER_OF_INKS: |
768 | 0 | dissect_tiff_single_uint(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_number_of_inks); |
769 | 0 | break; |
770 | 0 | case TIFF_TAG_TARGET_PRINTER: |
771 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_target_printer); |
772 | 0 | break; |
773 | 0 | case TIFF_TAG_COPYRIGHT: |
774 | 0 | dissect_tiff_single_string(tvb, pinfo, entry_tree, offset + 8, type, count, encoding, hf_tiff_copyright); |
775 | 0 | break; |
776 | 0 | default: |
777 | 0 | dissect_tiff_tag_unknown(tvb, pinfo, entry_tree, offset + 8, type, count, encoding); |
778 | 0 | } |
779 | 0 | } |
780 | | |
781 | | // Dissect an IFD with all of its fields, starting at the given offset |
782 | | // |
783 | | // Return the offset of the next IFD, or 0 if there isn't one |
784 | | static uint32_t |
785 | 0 | dissect_tiff_ifd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, uint32_t offset, int encoding) { |
786 | 0 | uint16_t ifd_count = tvb_get_uint16(tvb, offset, encoding); |
787 | 0 | int ifd_length = 2 + (ifd_count * 12) + 4; |
788 | |
|
789 | 0 | proto_tree *ifd_tree = proto_tree_add_subtree(tree, tvb, offset, ifd_length, ett_ifd, NULL, "Image File Directory"); |
790 | |
|
791 | 0 | proto_tree_add_item(ifd_tree, hf_tiff_ifd_count, tvb, offset, 2, encoding); |
792 | 0 | offset += 2; |
793 | |
|
794 | 0 | for (int i = 0; i < ifd_count; i++) { |
795 | 0 | dissect_tiff_entry(tvb, pinfo, ifd_tree, offset, encoding); |
796 | 0 | offset += 12; |
797 | 0 | } |
798 | |
|
799 | 0 | proto_tree_add_item(ifd_tree, hf_tiff_ifd_next, tvb, offset, 4, encoding); |
800 | 0 | uint32_t ifd_next = tvb_get_uint32(tvb, offset, encoding); |
801 | |
|
802 | 0 | return ifd_next; |
803 | 0 | } |
804 | | |
805 | | static int |
806 | 2 | dissect_tiff(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { |
807 | 2 | int encoding; |
808 | | |
809 | | // Reject if we don't have enough room for the heuristics |
810 | 2 | if (tvb_captured_length(tvb) < 4) { |
811 | 1 | return 0; |
812 | 1 | } |
813 | | |
814 | | // Figure out if we're big-endian or little endian |
815 | 1 | uint16_t raw_encoding = tvb_get_ntohs(tvb, 0); |
816 | 1 | uint16_t magic; |
817 | 1 | uint32_t ifd_offset; |
818 | 1 | if (raw_encoding == 0x4949) { |
819 | 0 | encoding = ENC_LITTLE_ENDIAN; |
820 | 1 | } else if (raw_encoding == 0x4D4D) { |
821 | 0 | encoding = ENC_BIG_ENDIAN; |
822 | 1 | } else { |
823 | | // If we don't recognize the endianness, abort with nothing decoded |
824 | 1 | return 0; |
825 | 1 | } |
826 | | |
827 | 0 | magic = tvb_get_uint16(tvb, 2, encoding); |
828 | | |
829 | | // If the magic number isn't 42, abort with nothing decoded |
830 | 0 | if (magic != 42) { |
831 | 0 | return 0; |
832 | 0 | } |
833 | | |
834 | 0 | proto_item *ti = proto_tree_add_item(tree, proto_tiff, tvb, 0, -1, ENC_NA); |
835 | 0 | proto_tree *tiff_tree = proto_item_add_subtree(ti, ett_tiff); |
836 | | |
837 | | // Dissect the rest of the header |
838 | 0 | proto_tree_add_item(tiff_tree, hf_tiff_header_endianness, tvb, 0, 2, encoding); |
839 | 0 | proto_tree_add_item(tiff_tree, hf_tiff_header_magic, tvb, 2, 2, encoding); |
840 | 0 | proto_tree_add_item_ret_uint(tiff_tree, hf_tiff_header_lead_ifd, tvb, 4, 4, encoding, &ifd_offset); |
841 | | |
842 | | // Keep dissecting IFDs until the offset to the next one is zero |
843 | 0 | while (ifd_offset != 0) { |
844 | 0 | ifd_offset = dissect_tiff_ifd(tvb, pinfo, tiff_tree, ifd_offset, encoding); |
845 | 0 | } |
846 | |
|
847 | 0 | return tvb_captured_length(tvb); |
848 | 0 | } |
849 | | |
850 | | void |
851 | | proto_register_tiff(void) |
852 | 15 | { |
853 | 15 | static hf_register_info hf[] = { |
854 | 15 | { &hf_tiff_header_endianness, |
855 | 15 | { "Endianness", "tiff.endianness", |
856 | 15 | FT_UINT16, BASE_HEX, VALS(tiff_endianness_names), |
857 | 15 | 0x0, NULL, HFILL } |
858 | 15 | }, |
859 | 15 | { &hf_tiff_header_magic, |
860 | 15 | { "Magic", "tiff.magic", |
861 | 15 | FT_UINT16, BASE_HEX, NULL, |
862 | 15 | 0x0, NULL, HFILL } |
863 | 15 | }, |
864 | 15 | { &hf_tiff_header_lead_ifd, |
865 | 15 | { "Lead IFD Offset", "tiff.lead_ifd", |
866 | 15 | FT_UINT32, BASE_HEX, NULL, |
867 | 15 | 0x0, NULL, HFILL } |
868 | 15 | }, |
869 | 15 | { &hf_tiff_ifd_count, |
870 | 15 | { "Number of Entries", "tiff.ifd_count", |
871 | 15 | FT_UINT16, BASE_DEC, NULL, |
872 | 15 | 0x0, NULL, HFILL } |
873 | 15 | }, |
874 | 15 | { &hf_tiff_ifd_next, |
875 | 15 | { "Next IFD Offset", "tiff.next_ifd", |
876 | 15 | FT_UINT32, BASE_HEX, NULL, |
877 | 15 | 0x0, NULL, HFILL } |
878 | 15 | }, |
879 | 15 | { &hf_tiff_entry_tag, |
880 | 15 | { "Tag", "tiff.tag", |
881 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_tag_names), |
882 | 15 | 0x0, NULL, HFILL } |
883 | 15 | }, |
884 | 15 | { &hf_tiff_entry_type, |
885 | 15 | { "Type", "tiff.type", |
886 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_type_names), |
887 | 15 | 0x0, NULL, HFILL } |
888 | 15 | }, |
889 | 15 | { &hf_tiff_entry_count, |
890 | 15 | { "Count", "tiff.count", |
891 | 15 | FT_UINT32, BASE_DEC, NULL, |
892 | 15 | 0x0, NULL, HFILL } |
893 | 15 | }, |
894 | 15 | { &hf_tiff_entry_offset, |
895 | 15 | { "Offset", "tiff.offset", |
896 | 15 | FT_UINT32, BASE_DEC, NULL, |
897 | 15 | 0x0, NULL, HFILL } |
898 | 15 | }, |
899 | 15 | { &hf_tiff_entry_unknown, |
900 | 15 | { "Unknown Data", "tiff.unknown", |
901 | 15 | FT_BYTES, BASE_NONE, NULL, |
902 | 15 | 0x0, NULL, HFILL } |
903 | 15 | }, |
904 | 15 | { &hf_tiff_image_width, |
905 | 15 | { "Image Width", "tiff.image_width", |
906 | 15 | FT_UINT32, BASE_DEC, NULL, |
907 | 15 | 0x0, NULL, HFILL } |
908 | 15 | }, |
909 | 15 | { &hf_tiff_image_length, |
910 | 15 | { "Image Length", "tiff.image_length", |
911 | 15 | FT_UINT32, BASE_DEC, NULL, |
912 | 15 | 0x0, NULL, HFILL } |
913 | 15 | }, |
914 | 15 | { &hf_tiff_bits_per_sample, |
915 | 15 | { "Bits per Sample", "tiff.bits_per_sample", |
916 | 15 | FT_UINT16, BASE_DEC, NULL, |
917 | 15 | 0x0, NULL, HFILL } |
918 | 15 | }, |
919 | 15 | { &hf_tiff_compression, |
920 | 15 | { "Compression", "tiff.compression", |
921 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_compression_names), |
922 | 15 | 0x0, NULL, HFILL } |
923 | 15 | }, |
924 | 15 | { &hf_tiff_photometric_interp, |
925 | 15 | { "Photometric Interpretation", "tiff.photometric_interp", |
926 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_photometric_interp_names), |
927 | 15 | 0x0, NULL, HFILL } |
928 | 15 | }, |
929 | 15 | { &hf_tiff_threshholding, |
930 | 15 | { "Threshholding", "tiff.threshholding", |
931 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_threshholding_names), |
932 | 15 | 0x0, NULL, HFILL } |
933 | 15 | }, |
934 | 15 | { &hf_tiff_cell_width, |
935 | 15 | { "Cell Width", "tiff.cell_width", |
936 | 15 | FT_UINT16, BASE_DEC, NULL, |
937 | 15 | 0x0, NULL, HFILL } |
938 | 15 | }, |
939 | 15 | { &hf_tiff_cell_length, |
940 | 15 | { "Cell Length", "tiff.cell_length", |
941 | 15 | FT_UINT16, BASE_DEC, NULL, |
942 | 15 | 0x0, NULL, HFILL } |
943 | 15 | }, |
944 | 15 | { &hf_tiff_fill_order, |
945 | 15 | { "Fill Order", "tiff.fill_order", |
946 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_fill_order_names), |
947 | 15 | 0x0, NULL, HFILL } |
948 | 15 | }, |
949 | 15 | { &hf_tiff_document_name, |
950 | 15 | { "Document Name", "tiff.document_name", |
951 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
952 | 15 | 0x0, NULL, HFILL } |
953 | 15 | }, |
954 | 15 | { &hf_tiff_image_description, |
955 | 15 | { "Image Description", "tiff.image_description", |
956 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
957 | 15 | 0x0, NULL, HFILL } |
958 | 15 | }, |
959 | 15 | { &hf_tiff_make, |
960 | 15 | { "Make", "tiff.make", |
961 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
962 | 15 | 0x0, NULL, HFILL } |
963 | 15 | }, |
964 | 15 | { &hf_tiff_model, |
965 | 15 | { "Model", "tiff.model", |
966 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
967 | 15 | 0x0, NULL, HFILL } |
968 | 15 | }, |
969 | 15 | { &hf_tiff_strip_offset, |
970 | 15 | { "Strip Offset", "tiff.strip_offset", |
971 | 15 | FT_UINT32, BASE_DEC, NULL, |
972 | 15 | 0x0, NULL, HFILL } |
973 | 15 | }, |
974 | 15 | { &hf_tiff_orientation, |
975 | 15 | { "Orientation", "tiff.orientation", |
976 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_orientation_names), |
977 | 15 | 0x0, NULL, HFILL } |
978 | 15 | }, |
979 | 15 | { &hf_tiff_samples_per_pixel, |
980 | 15 | { "Samples per Pixel", "tiff.samples_per_pixel", |
981 | 15 | FT_UINT16, BASE_DEC, NULL, |
982 | 15 | 0x0, NULL, HFILL } |
983 | 15 | }, |
984 | 15 | { &hf_tiff_rows_per_strip, |
985 | 15 | { "Rows per Strip", "tiff.rows_per_strip", |
986 | 15 | FT_UINT16, BASE_DEC, NULL, |
987 | 15 | 0x0, NULL, HFILL } |
988 | 15 | }, |
989 | 15 | { &hf_tiff_strip_byte_count, |
990 | 15 | { "Strip Byte Count", "tiff.strip_byte_count", |
991 | 15 | FT_UINT32, BASE_DEC, NULL, |
992 | 15 | 0x0, NULL, HFILL } |
993 | 15 | }, |
994 | 15 | { &hf_tiff_x_res_numer, |
995 | 15 | { "X Resolution Numerator", "tiff.x_res_numer", |
996 | 15 | FT_UINT32, BASE_DEC, NULL, |
997 | 15 | 0x0, NULL, HFILL } |
998 | 15 | }, |
999 | 15 | { &hf_tiff_x_res_denom, |
1000 | 15 | { "X Resolution Denominator", "tiff.x_res_denom", |
1001 | 15 | FT_UINT32, BASE_DEC, NULL, |
1002 | 15 | 0x0, NULL, HFILL } |
1003 | 15 | }, |
1004 | 15 | { &hf_tiff_x_res_approx, |
1005 | 15 | { "X Resolution Approximation", "tiff.x_res_approx", |
1006 | 15 | FT_DOUBLE, BASE_NONE, NULL, |
1007 | 15 | 0x0, NULL, HFILL } |
1008 | 15 | }, |
1009 | 15 | { &hf_tiff_y_res_numer, |
1010 | 15 | { "Y Resolution Numerator", "tiff.y_res_numer", |
1011 | 15 | FT_UINT32, BASE_DEC, NULL, |
1012 | 15 | 0x0, NULL, HFILL } |
1013 | 15 | }, |
1014 | 15 | { &hf_tiff_y_res_denom, |
1015 | 15 | { "Y Resolution Denominator", "tiff.y_res_denom", |
1016 | 15 | FT_UINT32, BASE_DEC, NULL, |
1017 | 15 | 0x0, NULL, HFILL } |
1018 | 15 | }, |
1019 | 15 | { &hf_tiff_y_res_approx, |
1020 | 15 | { "Y Resolution Approximation", "tiff.y_res_approx", |
1021 | 15 | FT_DOUBLE, BASE_NONE, NULL, |
1022 | 15 | 0x0, NULL, HFILL } |
1023 | 15 | }, |
1024 | 15 | { &hf_tiff_planar_configuration, |
1025 | 15 | { "Planar Configuration", "tiff.planar_configuration", |
1026 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_planar_configuration_names), |
1027 | 15 | 0x0, NULL, HFILL } |
1028 | 15 | }, |
1029 | 15 | { &hf_tiff_page_name, |
1030 | 15 | { "Page Name", "tiff.page_name", |
1031 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1032 | 15 | 0x0, NULL, HFILL } |
1033 | 15 | }, |
1034 | 15 | { &hf_tiff_gray_response_unit, |
1035 | 15 | { "Gray Response Unit", "tiff.gray_response_unit", |
1036 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_gray_response_unit_names), |
1037 | 15 | 0x0, NULL, HFILL } |
1038 | 15 | }, |
1039 | 15 | { &hf_tiff_t6_options, |
1040 | 15 | { "T6 Options", "tiff.t6", |
1041 | 15 | FT_UINT32, BASE_HEX, NULL, |
1042 | 15 | 0x0, NULL, HFILL } |
1043 | 15 | }, |
1044 | 15 | { &hf_tiff_t6_unused, |
1045 | 15 | { "Unused", "tiff.t6.unused", |
1046 | 15 | FT_UINT32, BASE_HEX, NULL, |
1047 | 15 | 0xFFFFFFFD, NULL, HFILL } |
1048 | 15 | }, |
1049 | 15 | { &hf_tiff_t6_allow_uncompressed, |
1050 | 15 | { "Allow Uncompressed", "tiff.t6.allow_uncompressed", |
1051 | 15 | FT_BOOLEAN, 32, TFS(&tfs_allowed_not_allowed), |
1052 | 15 | 0x00000002, NULL, HFILL } |
1053 | 15 | }, |
1054 | 15 | { &hf_tiff_resolution_unit, |
1055 | 15 | { "Resolution Unit", "tiff.resolution_unit", |
1056 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_resolution_unit_names), |
1057 | 15 | 0x0, NULL, HFILL } |
1058 | 15 | }, |
1059 | 15 | { &hf_tiff_software, |
1060 | 15 | { "Software", "tiff.software", |
1061 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1062 | 15 | 0x0, NULL, HFILL } |
1063 | 15 | }, |
1064 | 15 | { &hf_tiff_date_time, |
1065 | 15 | { "Date/Time", "tiff.date_time", |
1066 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1067 | 15 | 0x0, NULL, HFILL } |
1068 | 15 | }, |
1069 | 15 | { &hf_tiff_artist, |
1070 | 15 | { "Artist", "tiff.artist", |
1071 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1072 | 15 | 0x0, NULL, HFILL } |
1073 | 15 | }, |
1074 | 15 | { &hf_tiff_host_computer, |
1075 | 15 | { "Host Computer", "tiff.host_computer", |
1076 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1077 | 15 | 0x0, NULL, HFILL } |
1078 | 15 | }, |
1079 | 15 | { &hf_tiff_predictor, |
1080 | 15 | { "Predictor", "tiff.predictor", |
1081 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_predictor_names), |
1082 | 15 | 0x0, NULL, HFILL } |
1083 | 15 | }, |
1084 | 15 | { &hf_tiff_tile_width, |
1085 | 15 | { "Tile Width", "tiff.tile_width", |
1086 | 15 | FT_UINT32, BASE_DEC, NULL, |
1087 | 15 | 0x0, NULL, HFILL } |
1088 | 15 | }, |
1089 | 15 | { &hf_tiff_tile_length, |
1090 | 15 | { "Tile Width", "tiff.tile_length", |
1091 | 15 | FT_UINT32, BASE_DEC, NULL, |
1092 | 15 | 0x0, NULL, HFILL } |
1093 | 15 | }, |
1094 | 15 | { &hf_tiff_ink_set, |
1095 | 15 | { "Ink Set", "tiff.ink_set", |
1096 | 15 | FT_UINT16, BASE_DEC, VALS(tiff_ink_set_names), |
1097 | 15 | 0x0, NULL, HFILL } |
1098 | 15 | }, |
1099 | 15 | { &hf_tiff_number_of_inks, |
1100 | 15 | { "Number of Inks", "tiff.number_of_inks", |
1101 | 15 | FT_UINT16, BASE_DEC, NULL, |
1102 | 15 | 0x0, NULL, HFILL } |
1103 | 15 | }, |
1104 | 15 | { &hf_tiff_target_printer, |
1105 | 15 | { "Target Printer", "tiff.target_printer", |
1106 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1107 | 15 | 0x0, NULL, HFILL } |
1108 | 15 | }, |
1109 | 15 | { &hf_tiff_copyright, |
1110 | 15 | { "Copyright", "tiff.copyright", |
1111 | 15 | FT_STRINGZ, BASE_NONE, NULL, |
1112 | 15 | 0x0, NULL, HFILL } |
1113 | 15 | } |
1114 | 15 | }; |
1115 | | |
1116 | 15 | static int *ett[] = { |
1117 | 15 | &ett_tiff, |
1118 | 15 | &ett_ifd, |
1119 | 15 | &ett_t6, |
1120 | 15 | }; |
1121 | | |
1122 | 15 | static ei_register_info ei[] = { |
1123 | 15 | { &ei_tiff_unknown_tag, |
1124 | 15 | { "tiff.unknown_tag", PI_UNDECODED, PI_NOTE, |
1125 | 15 | "Unknown tag", EXPFILL } |
1126 | 15 | }, |
1127 | 15 | { &ei_tiff_bad_entry, |
1128 | 15 | { "tiff.bad_entry", PI_PROTOCOL, PI_WARN, |
1129 | 15 | "Invalid entry contents", EXPFILL } |
1130 | 15 | }, |
1131 | 15 | { &ei_tiff_zero_denom, |
1132 | 15 | { "tiff.zero_denom", PI_PROTOCOL, PI_WARN, |
1133 | 15 | "Denominator is zero", EXPFILL } |
1134 | 15 | }, |
1135 | | |
1136 | 15 | }; |
1137 | | |
1138 | 15 | proto_tiff = proto_register_protocol("Tagged Image File Format", "TIFF image", "tiff"); |
1139 | | |
1140 | 15 | register_dissector("tiff", dissect_tiff, proto_tiff); |
1141 | 15 | proto_register_field_array(proto_tiff, hf, array_length(hf)); |
1142 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1143 | | |
1144 | 15 | expert_module_t *expert_tiff = expert_register_protocol(proto_tiff); |
1145 | 15 | expert_register_field_array(expert_tiff, ei, array_length(ei)); |
1146 | 15 | } |
1147 | | |
1148 | | static bool |
1149 | | dissect_tiff_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
1150 | 0 | { |
1151 | 0 | return dissect_tiff(tvb, pinfo, tree, data) > 0; |
1152 | 0 | } |
1153 | | |
1154 | | void |
1155 | | proto_reg_handoff_tiff(void) |
1156 | 15 | { |
1157 | 15 | dissector_handle_t tiff_handle = find_dissector("tiff"); |
1158 | | |
1159 | | // Register the TIFF media type |
1160 | 15 | dissector_add_string("media_type", "image/tiff", tiff_handle); |
1161 | | |
1162 | | // Register the TIFF heuristic dissector |
1163 | 15 | heur_dissector_add("wtap_file", dissect_tiff_heur, "TIFF file", "tiff_wtap", proto_tiff, HEURISTIC_ENABLE); |
1164 | 15 | } |