Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-jpeg.c
blob66052f2f08c1b0fdfa60d947c1473e8c31400598
1 /* packet-jpeg.c
3 * Routines for RFC 2435 JPEG dissection
5 * Copyright 2006
6 * Erwin Rol <erwin@erwinrol.com>
7 * Copyright 2001,
8 * Francisco Javier Cabello Torres, <fjcabello@vtools.es>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
20 #include <epan/rtp_pt.h>
22 #include "packet-ber.h"
24 void proto_register_jpeg(void);
25 void proto_reg_handoff_jpeg(void);
27 static dissector_handle_t jpeg_handle;
29 static const range_string jpeg_ts_rvals [] = {
30 {0, 0, "Progressively scanned"},
31 {1, 1, "Odd field of interlaced signal"},
32 {2, 2, "Even field of interlaced signal"},
33 {3, 3, "Interlaced field to be line doubled"},
34 {3, 0xff, "Unspecified"},
35 {0, 0, NULL}
38 static const range_string jpeg_type_rvals [] = {
39 { 0, 0, "4:2:2 Video"},
40 { 1, 1, "4:2:0 Video"},
41 { 2, 5, "Reserved"}, /* Previously assigned by RFC 2035 */
42 { 6, 63, "Unassigned"},
43 { 64, 64, "4:2:0 Video, Restart Markers present"},
44 { 65, 65, "4:2:0 Video, Restart Markers present"},
45 { 66, 69, "Reserved"}, /* Since [2,5] are reserved */
46 { 70, 127, "Unassigned, Restart Markers present"},
47 {128, 255, "Dynamically assigned"},
48 { 0, 0, NULL}
51 static int proto_jpeg;
53 static int hf_rtp_jpeg_main_hdr;
54 static int hf_rtp_jpeg_main_hdr_height;
55 static int hf_rtp_jpeg_main_hdr_offs;
56 static int hf_rtp_jpeg_main_hdr_q;
57 static int hf_rtp_jpeg_main_hdr_ts;
58 static int hf_rtp_jpeg_main_hdr_type;
59 static int hf_rtp_jpeg_main_hdr_width;
60 static int hf_rtp_jpeg_payload;
61 static int hf_rtp_jpeg_qtable_hdr;
62 static int hf_rtp_jpeg_qtable_hdr_data;
63 static int hf_rtp_jpeg_qtable_hdr_length;
64 static int hf_rtp_jpeg_qtable_hdr_mbz;
65 static int hf_rtp_jpeg_qtable_hdr_prec;
66 static int hf_rtp_jpeg_restart_hdr;
67 static int hf_rtp_jpeg_restart_hdr_count;
68 static int hf_rtp_jpeg_restart_hdr_f;
69 static int hf_rtp_jpeg_restart_hdr_interval;
70 static int hf_rtp_jpeg_restart_hdr_l;
72 /* JPEG fields defining a sub tree */
73 static int ett_jpeg;
75 static int
76 dissect_jpeg( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ )
78 proto_item *ti = NULL;
79 proto_tree *jpeg_tree = NULL;
80 proto_tree *main_hdr_tree = NULL;
81 proto_tree *restart_hdr_tree = NULL;
82 proto_tree *qtable_hdr_tree = NULL;
83 uint32_t fragment_offset = 0;
84 uint16_t len = 0;
85 uint8_t type = 0;
86 uint8_t q = 0;
87 int h = 0;
88 int w = 0;
90 unsigned int offset = 0;
92 col_set_str(pinfo->cinfo, COL_PROTOCOL, "JPEG");
94 col_set_str(pinfo->cinfo, COL_INFO, "JPEG message");
96 if ( tree ) {
97 ti = proto_tree_add_item( tree, proto_jpeg, tvb, offset, -1, ENC_NA );
98 jpeg_tree = proto_item_add_subtree( ti, ett_jpeg );
100 ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_main_hdr, tvb, offset, 8, ENC_NA);
101 main_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
103 proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_ts, tvb, offset, 1, ENC_BIG_ENDIAN);
104 offset += 1;
105 proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_offs, tvb, offset, 3, ENC_BIG_ENDIAN);
106 fragment_offset = tvb_get_ntoh24(tvb, offset);
107 offset += 3;
108 proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
109 type = tvb_get_uint8(tvb, offset);
110 offset += 1;
111 proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_q, tvb, offset, 1, ENC_BIG_ENDIAN);
112 q = tvb_get_uint8(tvb, offset);
113 offset += 1;
114 w = tvb_get_uint8(tvb, offset) * 8;
115 proto_tree_add_uint(main_hdr_tree, hf_rtp_jpeg_main_hdr_width, tvb, offset, 1, w);
116 offset += 1;
117 h = tvb_get_uint8(tvb, offset) * 8;
118 proto_tree_add_uint(main_hdr_tree, hf_rtp_jpeg_main_hdr_height, tvb, offset, 1, h);
119 offset += 1;
121 if (type >= 64 && type <= 127) {
122 ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_restart_hdr, tvb, offset, 4, ENC_NA);
123 restart_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
124 proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
125 offset += 2;
126 proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_f, tvb, offset, 2, ENC_BIG_ENDIAN);
127 proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_l, tvb, offset, 2, ENC_BIG_ENDIAN);
128 proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_count, tvb, offset, 2, ENC_BIG_ENDIAN);
129 offset += 2;
132 if (q >= 128 && fragment_offset == 0) {
133 ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_qtable_hdr, tvb, offset, -1, ENC_NA);
134 qtable_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
135 proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_mbz, tvb, offset, 1, ENC_BIG_ENDIAN);
136 offset += 1;
137 proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_prec, tvb, offset, 1, ENC_BIG_ENDIAN);
138 offset += 1;
139 proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN);
140 len = tvb_get_ntohs(tvb, offset);
141 offset += 2;
142 if (len > 0) {
143 proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_data, tvb, offset, len, ENC_NA);
144 offset += len;
146 proto_item_set_len(ti, len + 4);
149 /* The rest of the packet is the JPEG data */
150 proto_tree_add_item( jpeg_tree, hf_rtp_jpeg_payload, tvb, offset, -1, ENC_NA );
152 return tvb_captured_length(tvb);
155 void
156 proto_register_jpeg(void)
158 static hf_register_info hf[] = {
159 { &hf_rtp_jpeg_main_hdr,
160 { "Main Header", "jpeg.main_hdr",
161 FT_NONE, BASE_NONE, NULL, 0,
162 NULL, HFILL }
164 { &hf_rtp_jpeg_main_hdr_ts,
165 { "Type Specific", "jpeg.main_hdr.ts",
166 FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(jpeg_ts_rvals), 0,
167 NULL, HFILL }
169 { &hf_rtp_jpeg_main_hdr_offs,
170 { "Fragment Offset", "jpeg.main_hdr.offset",
171 FT_UINT24, BASE_DEC, NULL, 0,
172 NULL, HFILL }
174 { &hf_rtp_jpeg_main_hdr_type,
175 { "Type", "jpeg.main_hdr.type",
176 FT_UINT8, BASE_DEC|BASE_RANGE_STRING, RVALS(jpeg_type_rvals), 0,
177 NULL, HFILL }
179 { &hf_rtp_jpeg_main_hdr_q,
180 { "Q", "jpeg.main_hdr.q",
181 FT_UINT8, BASE_DEC, NULL, 0,
182 NULL, HFILL }
184 { &hf_rtp_jpeg_main_hdr_width,
185 { "Width", "jpeg.main_hdr.width",
186 FT_UINT8, BASE_DEC, NULL, 0,
187 NULL, HFILL }
189 { &hf_rtp_jpeg_main_hdr_height,
190 { "Height", "jpeg.main_hdr.height",
191 FT_UINT8, BASE_DEC, NULL, 0,
192 NULL, HFILL }
194 { &hf_rtp_jpeg_restart_hdr,
195 { "Restart Marker Header", "jpeg.restart_hdr",
196 FT_NONE, BASE_NONE, NULL, 0,
197 NULL, HFILL }
199 { &hf_rtp_jpeg_restart_hdr_interval,
200 { "Restart Interval", "jpeg.restart_hdr.interval",
201 FT_UINT16, BASE_DEC, NULL, 0,
202 NULL, HFILL }
204 { &hf_rtp_jpeg_restart_hdr_f,
205 { "F", "jpeg.restart_hdr.f",
206 FT_UINT16, BASE_DEC, NULL, 0x8000,
207 NULL, HFILL }
209 { &hf_rtp_jpeg_restart_hdr_l,
210 { "L", "jpeg.restart_hdr.l",
211 FT_UINT16, BASE_DEC, NULL, 0x4000,
212 NULL, HFILL }
214 { &hf_rtp_jpeg_restart_hdr_count,
215 { "Restart Count", "jpeg.restart_hdr.count",
216 FT_UINT16, BASE_DEC, NULL, 0x3FFF,
217 NULL, HFILL }
219 { &hf_rtp_jpeg_qtable_hdr,
220 { "Quantization Table Header", "jpeg.qtable_hdr",
221 FT_NONE, BASE_NONE, NULL, 0,
222 NULL, HFILL }
224 { &hf_rtp_jpeg_qtable_hdr_mbz,
225 { "MBZ", "jpeg.qtable_hdr.mbz",
226 FT_UINT8, BASE_DEC, NULL, 0,
227 NULL, HFILL }
229 { &hf_rtp_jpeg_qtable_hdr_prec,
230 { "Precision", "jpeg.qtable_hdr.precision",
231 FT_UINT8, BASE_DEC, NULL, 0,
232 NULL, HFILL }
234 { &hf_rtp_jpeg_qtable_hdr_length,
235 { "Length", "jpeg.qtable_hdr.length",
236 FT_UINT16, BASE_DEC, NULL, 0,
237 NULL, HFILL }
239 { &hf_rtp_jpeg_qtable_hdr_data,
240 { "Quantization Table Data", "jpeg.qtable_hdr.data",
241 FT_BYTES, BASE_NONE, NULL, 0,
242 NULL, HFILL }
244 { &hf_rtp_jpeg_payload,
245 { "Payload", "jpeg.payload",
246 FT_BYTES, BASE_NONE, NULL, 0,
247 NULL, HFILL }
251 static int *ett[] = {
252 &ett_jpeg,
255 proto_jpeg = proto_register_protocol("RFC 2435 JPEG","JPEG","jpeg");
256 proto_register_field_array(proto_jpeg, hf, array_length(hf));
257 proto_register_subtree_array(ett, array_length(ett));
259 jpeg_handle = register_dissector("jpeg", dissect_jpeg, proto_jpeg);
261 /* RFC 2798 */
262 register_ber_oid_dissector_handle("0.9.2342.19200300.100.1.60", jpeg_handle, proto_jpeg, "jpegPhoto");
265 void
266 proto_reg_handoff_jpeg(void)
268 dissector_add_uint("rtp.pt", PT_JPEG, jpeg_handle);
272 * Editor modelines - https://www.wireshark.org/tools/modelines.html
274 * Local variables:
275 * c-basic-offset: 8
276 * tab-width: 8
277 * indent-tabs-mode: t
278 * End:
280 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
281 * :indentSize=8:tabSize=8:noTabs=false: