Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}