3 * Routines for RFC 2435 JPEG dissection
8 * Erwin Rol <erwin@erwinrol.com>
10 * Francisco Javier Cabello Torres, <fjcabello@vtools.es>
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #define NEW_PROTO_TREE_API
36 #include <epan/packet.h>
38 #include <epan/rtp_pt.h>
40 #include "packet-ber.h"
42 static dissector_handle_t jpeg_handle
;
44 static header_field_info
*hfi_jpeg
= NULL
;
46 #define JPEG_HFI_INIT HFI_INIT(proto_jpeg)
48 /* JPEG header fields */
49 static header_field_info hfi_rtp_jpeg_main_hdr JPEG_HFI_INIT
= {
52 FT_NONE
, BASE_NONE
, NULL
, 0,
56 static header_field_info hfi_rtp_jpeg_main_hdr_ts JPEG_HFI_INIT
= {
59 FT_UINT8
, BASE_DEC
, NULL
, 0,
63 static header_field_info hfi_rtp_jpeg_main_hdr_offs JPEG_HFI_INIT
= {
65 "jpeg.main_hdr.offset",
66 FT_UINT24
, BASE_DEC
, NULL
, 0,
70 static header_field_info hfi_rtp_jpeg_main_hdr_type JPEG_HFI_INIT
= {
73 FT_UINT8
, BASE_DEC
, NULL
, 0,
77 static header_field_info hfi_rtp_jpeg_main_hdr_q JPEG_HFI_INIT
= {
80 FT_UINT8
, BASE_DEC
, NULL
, 0,
84 static header_field_info hfi_rtp_jpeg_main_hdr_width JPEG_HFI_INIT
= {
86 "jpeg.main_hdr.width",
87 FT_UINT8
, BASE_DEC
, NULL
, 0,
91 static header_field_info hfi_rtp_jpeg_main_hdr_height JPEG_HFI_INIT
= {
93 "jpeg.main_hdr.height",
94 FT_UINT8
, BASE_DEC
, NULL
, 0,
98 static header_field_info hfi_rtp_jpeg_restart_hdr JPEG_HFI_INIT
= {
99 "Restart Marker Header",
101 FT_NONE
, BASE_NONE
, NULL
, 0,
105 static header_field_info hfi_rtp_jpeg_restart_hdr_interval JPEG_HFI_INIT
= {
107 "jpeg.restart_hdr.interval",
108 FT_UINT16
, BASE_DEC
, NULL
, 0,
112 static header_field_info hfi_rtp_jpeg_restart_hdr_f JPEG_HFI_INIT
= {
114 "jpeg.restart_hdr.f",
115 FT_UINT16
, BASE_DEC
, NULL
, 0x8000,
119 static header_field_info hfi_rtp_jpeg_restart_hdr_l JPEG_HFI_INIT
= {
121 "jpeg.restart_hdr.l",
122 FT_UINT16
, BASE_DEC
, NULL
, 0x4000,
126 static header_field_info hfi_rtp_jpeg_restart_hdr_count JPEG_HFI_INIT
= {
128 "jpeg.restart_hdr.count",
129 FT_UINT16
, BASE_DEC
, NULL
, 0x3FFF,
133 static header_field_info hfi_rtp_jpeg_qtable_hdr JPEG_HFI_INIT
= {
134 "Quantization Table Header",
136 FT_NONE
, BASE_NONE
, NULL
, 0,
140 static header_field_info hfi_rtp_jpeg_qtable_hdr_mbz JPEG_HFI_INIT
= {
142 "jpeg.qtable_hdr.mbz",
143 FT_UINT8
, BASE_DEC
, NULL
, 0,
147 static header_field_info hfi_rtp_jpeg_qtable_hdr_prec JPEG_HFI_INIT
= {
149 "jpeg.qtable_hdr.precision",
150 FT_UINT8
, BASE_DEC
, NULL
, 0,
154 static header_field_info hfi_rtp_jpeg_qtable_hdr_length JPEG_HFI_INIT
= {
156 "jpeg.qtable_hdr.length",
157 FT_UINT16
, BASE_DEC
, NULL
, 0,
161 static header_field_info hfi_rtp_jpeg_qtable_hdr_data JPEG_HFI_INIT
= {
162 "Quantization Table Data",
163 "jpeg.qtable_hdr.data",
164 FT_BYTES
, BASE_NONE
, NULL
, 0,
169 static header_field_info hfi_rtp_jpeg_payload JPEG_HFI_INIT
= {
172 FT_BYTES
, BASE_NONE
, NULL
, 0,
177 /* JPEG fields defining a sub tree */
178 static gint ett_jpeg
= -1;
181 dissect_jpeg( tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
183 proto_item
*ti
= NULL
;
184 proto_tree
*jpeg_tree
= NULL
;
185 proto_tree
*main_hdr_tree
= NULL
;
186 proto_tree
*restart_hdr_tree
= NULL
;
187 proto_tree
*qtable_hdr_tree
= NULL
;
188 guint32 fragment_offset
= 0;
195 unsigned int offset
= 0;
197 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "JPEG");
199 col_set_str(pinfo
->cinfo
, COL_INFO
, "JPEG message");
202 ti
= proto_tree_add_item( tree
, hfi_jpeg
, tvb
, offset
, -1, ENC_NA
);
203 jpeg_tree
= proto_item_add_subtree( ti
, ett_jpeg
);
205 ti
= proto_tree_add_item(jpeg_tree
, &hfi_rtp_jpeg_main_hdr
, tvb
, offset
, 8, ENC_NA
);
206 main_hdr_tree
= proto_item_add_subtree(ti
, ett_jpeg
);
208 proto_tree_add_item(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_ts
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
210 proto_tree_add_item(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_offs
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
211 fragment_offset
= tvb_get_ntoh24(tvb
, offset
);
213 proto_tree_add_item(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
214 type
= tvb_get_guint8(tvb
, offset
);
216 proto_tree_add_item(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_q
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
217 q
= tvb_get_guint8(tvb
, offset
);
219 w
= tvb_get_guint8(tvb
, offset
) * 8;
220 proto_tree_add_uint(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_width
, tvb
, offset
, 1, w
);
222 h
= tvb_get_guint8(tvb
, offset
) * 8;
223 proto_tree_add_uint(main_hdr_tree
, &hfi_rtp_jpeg_main_hdr_height
, tvb
, offset
, 1, h
);
226 if (type
>= 64 && type
<= 127) {
227 ti
= proto_tree_add_item(jpeg_tree
, &hfi_rtp_jpeg_restart_hdr
, tvb
, offset
, 4, ENC_NA
);
228 restart_hdr_tree
= proto_item_add_subtree(ti
, ett_jpeg
);
229 proto_tree_add_item(restart_hdr_tree
, &hfi_rtp_jpeg_restart_hdr_interval
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
231 proto_tree_add_item(restart_hdr_tree
, &hfi_rtp_jpeg_restart_hdr_f
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
232 proto_tree_add_item(restart_hdr_tree
, &hfi_rtp_jpeg_restart_hdr_l
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
233 proto_tree_add_item(restart_hdr_tree
, &hfi_rtp_jpeg_restart_hdr_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
237 if (q
>= 128 && fragment_offset
== 0) {
238 ti
= proto_tree_add_item(jpeg_tree
, &hfi_rtp_jpeg_qtable_hdr
, tvb
, offset
, -1, ENC_NA
);
239 qtable_hdr_tree
= proto_item_add_subtree(ti
, ett_jpeg
);
240 proto_tree_add_item(qtable_hdr_tree
, &hfi_rtp_jpeg_qtable_hdr_mbz
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
242 proto_tree_add_item(qtable_hdr_tree
, &hfi_rtp_jpeg_qtable_hdr_prec
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
244 proto_tree_add_item(qtable_hdr_tree
, &hfi_rtp_jpeg_qtable_hdr_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
245 len
= tvb_get_ntohs(tvb
, offset
);
248 proto_tree_add_item(qtable_hdr_tree
, &hfi_rtp_jpeg_qtable_hdr_data
, tvb
, offset
, len
, ENC_NA
);
251 proto_item_set_len(ti
, len
+ 4);
254 /* The rest of the packet is the JPEG data */
255 proto_tree_add_item( jpeg_tree
, &hfi_rtp_jpeg_payload
, tvb
, offset
, -1, ENC_NA
);
260 proto_register_jpeg(void)
262 #ifndef HAVE_HFI_SECTION_INIT
263 static header_field_info
*hfi
[] =
265 &hfi_rtp_jpeg_main_hdr
,
266 &hfi_rtp_jpeg_main_hdr_ts
,
267 &hfi_rtp_jpeg_main_hdr_offs
,
268 &hfi_rtp_jpeg_main_hdr_type
,
269 &hfi_rtp_jpeg_main_hdr_q
,
270 &hfi_rtp_jpeg_main_hdr_width
,
271 &hfi_rtp_jpeg_main_hdr_height
,
272 &hfi_rtp_jpeg_restart_hdr
,
273 &hfi_rtp_jpeg_restart_hdr_interval
,
274 &hfi_rtp_jpeg_restart_hdr_f
,
275 &hfi_rtp_jpeg_restart_hdr_l
,
276 &hfi_rtp_jpeg_restart_hdr_count
,
277 &hfi_rtp_jpeg_qtable_hdr
,
278 &hfi_rtp_jpeg_qtable_hdr_mbz
,
279 &hfi_rtp_jpeg_qtable_hdr_prec
,
280 &hfi_rtp_jpeg_qtable_hdr_length
,
281 &hfi_rtp_jpeg_qtable_hdr_data
,
282 &hfi_rtp_jpeg_payload
,
293 proto_jpeg
= proto_register_protocol("RFC 2435 JPEG","JPEG","jpeg");
294 hfi_jpeg
= proto_registrar_get_nth(proto_jpeg
);
296 proto_register_fields(proto_jpeg
, hfi
, array_length(hfi
));
297 proto_register_subtree_array(ett
, array_length(ett
));
299 jpeg_handle
= create_dissector_handle(dissect_jpeg
, proto_jpeg
);
302 register_ber_oid_dissector_handle("0.9.2342.19200300.100.1.60", jpeg_handle
, proto_jpeg
, "jpegPhoto");
306 proto_reg_handoff_jpeg(void)
308 dissector_add_uint("rtp.pt", PT_JPEG
, jpeg_handle
);