Enable Python for HEAD to make sure build problems are found.
[obnox/wireshark/wip.git] / wiretap / jpeg_jfif.c
1 /* jpeg_jfif.c
2  *
3  * JPEG/JFIF file format decoder for the Wiretap library.
4  * Written by Marton Nemeth <nm127@freemail.hu>
5  * Copyright 2009 Marton Nemeth
6  *
7  * $Id$
8  *
9  * The JPEG and JFIF specification can be found at:
10  * http://www.jpeg.org/public/jfif.pdf
11  * http://www.w3.org/Graphics/JPEG/itu-t81.pdf
12  *
13  * Wiretap Library
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #include <errno.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45
46 #include "wtap-int.h"
47 #include "file_wrappers.h"
48 #include "buffer.h"
49 #include "jpeg_jfif.h"
50
51 static const guchar jpeg_jfif_magic[] = { 0xFF, 0xD8, /* SOF */
52                                           0xFF        /* start of the next marker */
53                                         };
54
55 static gboolean
56 jpeg_jfif_read(wtap *wth, int *err, gchar **err_info,
57                 gint64 *data_offset)
58 {
59         guint8 *buf;
60         gint64 file_size;
61         int packet_size;
62         gint64 capture_size;
63
64         *err = 0;
65
66         /* interpret the file as one packet only */
67         if (wth->data_offset)
68                 return FALSE;
69
70         *data_offset = wth->data_offset;
71
72         if ((file_size = wtap_file_size(wth, err)) == -1)
73                 return FALSE;
74
75         /* Read maximum possible packet size */
76         if (file_size <= WTAP_MAX_PACKET_SIZE) {
77                 capture_size = file_size;
78         } else {
79                 capture_size = WTAP_MAX_PACKET_SIZE;
80         }
81         packet_size = (int)capture_size;
82
83         buffer_assure_space(wth->frame_buffer, packet_size);
84         buf = buffer_start_ptr(wth->frame_buffer);
85
86         wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err);
87
88         wth->data_offset += packet_size;
89
90         wth->phdr.caplen = packet_size;
91         wth->phdr.len = (int)file_size;
92
93         wth->phdr.ts.secs = 0;
94         wth->phdr.ts.nsecs = 0;
95
96         *err_info = NULL;
97         return TRUE;
98 }
99
100 static gboolean
101 jpeg_jfif_seek_read(wtap *wth, gint64 seek_off,
102                 union wtap_pseudo_header *pseudo_header _U_, guchar *pd, int length,
103                 int *err, gchar **err_info)
104 {
105         int packet_size = length;
106
107         /* interpret the file as one packet only */
108         if (0 < seek_off) {
109                 *err = 0;
110                 *err_info = NULL;
111                 return FALSE;
112         }
113
114         if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
115                 *err_info = NULL;
116                 return FALSE;
117         }
118
119         wtap_file_read_expected_bytes(pd, packet_size, wth->random_fh, err);
120
121         *err = 0;
122         *err_info = NULL;
123         return TRUE;
124 }
125
126 int
127 jpeg_jfif_open(wtap *wth, int *err, gchar **err_info)
128 {
129         int bytes_read;
130         char magic_buf[3];
131         int ret = 0;
132
133         errno = WTAP_ERR_CANT_READ;
134         bytes_read = file_read(magic_buf, 1, sizeof(magic_buf), wth->fh);
135         if (bytes_read != (int) sizeof(magic_buf)) {
136                 *err = file_error(wth->fh);
137                 if (*err != 0) {
138                         *err_info = NULL;
139                         ret = -1;
140                 }
141         } else {
142                 if (memcmp(magic_buf, jpeg_jfif_magic, sizeof(magic_buf)) == 0) {
143                         ret = 1;
144
145                         wth->file_type = WTAP_FILE_JPEG_JFIF;
146                         wth->file_encap = WTAP_ENCAP_JPEG_JFIF;
147                         wth->tsprecision = WTAP_FILE_TSPREC_SEC;
148                         wth->subtype_read = jpeg_jfif_read;
149                         wth->subtype_seek_read = jpeg_jfif_seek_read;
150                         wth->snapshot_length = 0;
151                 }
152         }
153
154         /* Seek to the start of the file */
155         if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
156                 *err = -1;
157                 *err_info = NULL;
158                 ret = -1;
159         }
160
161         return ret;
162 }