1 /* GStreamer JPEG parser
2 * Copyright (C) 2011-2012 Intel Corporation
3 * Copyright (C) 2015 Tim-Philipp Müller <tim@centricular.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:gstjpegparser
23 * @title: GstJpegParser
24 * @short_description: Convenience library for JPEG bitstream parsing.
25 *
26 * Provides useful functions for parsing JPEG images
27 *
28 */
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <stdlib.h>
35 #include <gst/base/gstbytereader.h>
36 #include "gstjpegparser.h"
37
38 #ifndef GST_DISABLE_GST_DEBUG
39
40 #define GST_CAT_DEFAULT ensure_debug_category()
41
42 static GstDebugCategory *
ensure_debug_category(void)43 ensure_debug_category (void)
44 {
45 static gsize cat_gonce = 0;
46
47 if (g_once_init_enter (&cat_gonce)) {
48 gsize cat_done;
49
50 cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0,
51 "GstJpegCodecParser");
52
53 g_once_init_leave (&cat_gonce, cat_done);
54 }
55
56 return (GstDebugCategory *) cat_gonce;
57 }
58 #else
59
60 #define ensure_debug_category() /* NOOP */
61
62 #endif /* GST_DISABLE_GST_DEBUG */
63
64 #define DEBUG_PRINT_COMMENT 0
65
66 #define READ_UINT8(reader, val) G_STMT_START { \
67 if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \
68 GST_WARNING ("failed to read uint8"); \
69 goto failed; \
70 } \
71 } G_STMT_END
72
73 #define READ_UINT16(reader, val) G_STMT_START { \
74 if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \
75 GST_WARNING ("failed to read uint16"); \
76 goto failed; \
77 } \
78 } G_STMT_END
79
80 #define READ_BYTES(reader, buf, length) G_STMT_START { \
81 const guint8 *vals; \
82 if (!gst_byte_reader_get_data (reader, length, &vals)) { \
83 GST_WARNING ("failed to read bytes, size:%d", length); \
84 goto failed; \
85 } \
86 memcpy (buf, vals, length); \
87 } G_STMT_END
88
89 #define U_READ_UINT8(reader, val) G_STMT_START { \
90 (val) = gst_byte_reader_get_uint8_unchecked(reader); \
91 } G_STMT_END
92
93 #define U_READ_UINT16(reader, val) G_STMT_START { \
94 (val) = gst_byte_reader_get_uint16_be_unchecked(reader); \
95 } G_STMT_END
96
97
98 /* Table used to address an 8x8 matrix in zig-zag order */
99 /* *INDENT-OFF* */
100 static const guint8 zigzag_index[64] = {
101 0, 1, 8, 16, 9, 2, 3, 10,
102 17, 24, 32, 25, 18, 11, 4, 5,
103 12, 19, 26, 33, 40, 48, 41, 34,
104 27, 20, 13, 6, 7, 14, 21, 28,
105 35, 42, 49, 56, 57, 50, 43, 36,
106 29, 22, 15, 23, 30, 37, 44, 51,
107 58, 59, 52, 45, 38, 31, 39, 46,
108 53, 60, 61, 54, 47, 55, 62, 63
109 };
110 /* *INDENT-ON* */
111
112 /* Table K.1 - Luminance quantization table */
113 /* *INDENT-OFF* */
114 static const guint8 default_luminance_quant_table[64] = {
115 16, 11, 10, 16, 24, 40, 51, 61,
116 12, 12, 14, 19, 26, 58, 60, 55,
117 14, 13, 16, 24, 40, 57, 69, 56,
118 14, 17, 22, 29, 51, 87, 80, 62,
119 18, 22, 37, 56, 68, 109, 103, 77,
120 24, 35, 55, 64, 81, 104, 113, 92,
121 49, 64, 78, 87, 103, 121, 120, 101,
122 72, 92, 95, 98, 112, 100, 103, 99
123 };
124 /* *INDENT-ON* */
125
126 /* Table K.2 - Chrominance quantization table */
127 /* *INDENT-OFF* */
128 static const guint8 default_chrominance_quant_table[64] = {
129 17, 18, 24, 47, 99, 99, 99, 99,
130 18, 21, 26, 66, 99, 99, 99, 99,
131 24, 26, 56, 99, 99, 99, 99, 99,
132 47, 66, 99, 99, 99, 99, 99, 99,
133 99, 99, 99, 99, 99, 99, 99, 99,
134 99, 99, 99, 99, 99, 99, 99, 99,
135 99, 99, 99, 99, 99, 99, 99, 99,
136 99, 99, 99, 99, 99, 99, 99, 99
137 };
138 /* *INDENT-ON* */
139
140 typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry;
141 struct _GstJpegHuffmanTableEntry
142 {
143 guint8 value; /* category */
144 guint8 length; /* code length in bits */
145 };
146
147 /* Table K.3 - Table for luminance DC coefficient differences */
148 static const GstJpegHuffmanTableEntry default_luminance_dc_table[] = {
149 {0x00, 2}, {0x01, 3}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3},
150 {0x06, 4}, {0x07, 5}, {0x08, 6}, {0x09, 7}, {0x0a, 8}, {0x0b, 9}
151 };
152
153 /* Table K.4 - Table for chrominance DC coefficient differences */
154 static const GstJpegHuffmanTableEntry default_chrominance_dc_table[] = {
155 {0x00, 2}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
156 {0x06, 6}, {0x07, 7}, {0x08, 8}, {0x09, 9}, {0x0a, 10}, {0x0b, 11}
157 };
158
159 /* Table K.5 - Table for luminance AC coefficients */
160 /* *INDENT-OFF* */
161 static const GstJpegHuffmanTableEntry default_luminance_ac_table[] = {
162 {0x00, 4}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
163 {0x06, 7}, {0x07, 8}, {0x08, 10}, {0x09, 16}, {0x0a, 16}, {0x11, 4},
164 {0x12, 5}, {0x13, 7}, {0x14, 9}, {0x15, 11}, {0x16, 16}, {0x17, 16},
165 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
166 {0x24, 12}, {0x25, 16}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
167 {0x2a, 16}, {0x31, 6}, {0x32, 9}, {0x33, 12}, {0x34, 16}, {0x35, 16},
168 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
169 {0x42, 10}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
170 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 7}, {0x52, 11}, {0x53, 16},
171 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
172 {0x5a, 16}, {0x61, 7}, {0x62, 12}, {0x63, 16}, {0x64, 16}, {0x65, 16},
173 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 8},
174 {0x72, 12}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
175 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 9}, {0x82, 15}, {0x83, 16},
176 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
177 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
178 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
179 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
180 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 10}, {0xb2, 16}, {0xb3, 16},
181 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
182 {0xba, 16}, {0xc1, 10}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
183 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
184 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
185 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 16}, {0xe2, 16}, {0xe3, 16},
186 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
187 {0xea, 16}, {0xf0, 11}, {0xf1, 16}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
188 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
189 };
190 /* *INDENT-ON* */
191
192 /* Table K.6 - Table for chrominance AC coefficients */
193 /* *INDENT-OFF* */
194 static const GstJpegHuffmanTableEntry default_chrominance_ac_table[] = {
195 {0x00, 2}, {0x01, 2}, {0x02, 3}, {0x03, 4}, {0x04, 5}, {0x05, 5},
196 {0x06, 6}, {0x07, 7}, {0x08, 9}, {0x09, 10}, {0x0a, 12}, {0x11, 4},
197 {0x12, 6}, {0x13, 8}, {0x14, 9}, {0x15, 11}, {0x16, 12}, {0x17, 16},
198 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
199 {0x24, 12}, {0x25, 15}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
200 {0x2a, 16}, {0x31, 5}, {0x32, 8}, {0x33, 10}, {0x34, 12}, {0x35, 16},
201 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
202 {0x42, 9}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
203 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 6}, {0x52, 10}, {0x53, 16},
204 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
205 {0x5a, 16}, {0x61, 7}, {0x62, 11}, {0x63, 16}, {0x64, 16}, {0x65, 16},
206 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 7},
207 {0x72, 11}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
208 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 8}, {0x82, 16}, {0x83, 16},
209 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
210 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
211 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
212 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
213 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 9}, {0xb2, 16}, {0xb3, 16},
214 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
215 {0xba, 16}, {0xc1, 9}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
216 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
217 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
218 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 14}, {0xe2, 16}, {0xe3, 16},
219 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
220 {0xea, 16}, {0xf0, 10}, {0xf1, 15}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
221 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
222 };
223 /* *INDENT-ON* */
224
225 static gint gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size,
226 guint offset);
227
228 static inline gboolean
jpeg_parse_to_next_marker(GstByteReader * br,GstJpegMarker * marker)229 jpeg_parse_to_next_marker (GstByteReader * br, GstJpegMarker * marker)
230 {
231 gint ofs;
232
233 ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte);
234 if (ofs < 0)
235 return FALSE;
236
237 if (marker)
238 *marker = (GstJpegMarker) br->data[ofs + 1];
239
240 gst_byte_reader_skip_unchecked (br, ofs - br->byte);
241 return TRUE;
242 }
243
244 /* gst_jpeg_scan_for_marker_code:
245 * @data: The data to parse
246 * @size: The size of @data
247 * @offset: The offset from which to start parsing
248 *
249 * Scans the JPEG bitstream contained in @data for the next marker
250 * code. If found, the function returns an offset to the marker code,
251 * including the 0xff prefix code but excluding any extra fill bytes.
252 *
253 * Returns: offset to the marker code if found, or -1 if not found.
254 */
255 static gint
gst_jpeg_scan_for_marker_code(const guint8 * data,gsize size,guint offset)256 gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset)
257 {
258 guint i;
259
260 i = offset + 1;
261 while (i < size) {
262 const guint8 v = data[i];
263 if (v < 0xc0)
264 i += 2;
265 else if (v < 0xff && data[i - 1] == 0xff)
266 return i - 1;
267 else
268 i++;
269 }
270 return -1;
271 }
272
273 /**
274 * gst_jpeg_segment_parse_frame_header:
275 * @segment: the JPEG segment
276 * @frame_hdr: (out): The #GstJpegFrameHdr structure to fill in
277 *
278 * Parses the @frame_hdr JPEG frame header structure members from @segment.
279 *
280 * The caller must make sure there is enough data for the whole segment
281 * available.
282 *
283 * Returns: TRUE if the frame header was correctly parsed.
284 *
285 * Since: 1.6
286 */
287 gboolean
gst_jpeg_segment_parse_frame_header(const GstJpegSegment * segment,GstJpegFrameHdr * frame_hdr)288 gst_jpeg_segment_parse_frame_header (const GstJpegSegment * segment,
289 GstJpegFrameHdr * frame_hdr)
290 {
291 GstByteReader br;
292 guint8 val;
293 guint i;
294
295 g_return_val_if_fail (segment != NULL, FALSE);
296 g_return_val_if_fail (frame_hdr != NULL, FALSE);
297
298 if (segment->size < 8)
299 return FALSE;
300
301 gst_byte_reader_init (&br, segment->data + segment->offset, segment->size);
302 gst_byte_reader_skip_unchecked (&br, 2);
303
304 U_READ_UINT8 (&br, frame_hdr->sample_precision);
305 U_READ_UINT16 (&br, frame_hdr->height);
306 U_READ_UINT16 (&br, frame_hdr->width);
307 U_READ_UINT8 (&br, frame_hdr->num_components);
308
309 if (frame_hdr->num_components > GST_JPEG_MAX_SCAN_COMPONENTS)
310 return FALSE;
311
312 if (gst_byte_reader_get_remaining (&br) < 3 * frame_hdr->num_components)
313 return FALSE;
314
315 for (i = 0; i < frame_hdr->num_components; i++) {
316 U_READ_UINT8 (&br, frame_hdr->components[i].identifier);
317 U_READ_UINT8 (&br, val);
318 frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F;
319 frame_hdr->components[i].vertical_factor = (val & 0x0F);
320 U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector);
321 if (frame_hdr->components[i].horizontal_factor > 4
322 || frame_hdr->components[i].vertical_factor > 4
323 || frame_hdr->components[i].quant_table_selector >= 4)
324 return FALSE;
325 }
326
327 if (gst_byte_reader_get_remaining (&br) > 0)
328 GST_DEBUG ("data left at end of frame header segment");
329
330 return TRUE;
331 }
332
333 /**
334 * gst_jpeg_segment_parse_scan_header:
335 * @segment: the JPEG segment
336 * @scan_hdr: (out): The #GstJpegScanHdr structure to fill in
337 *
338 * Parses the @scan_hdr JPEG scan header structure members from @segment.
339 *
340 * The caller must make sure there is enough data for the whole segment
341 * available.
342 *
343 * Returns: TRUE if the scan header was correctly parsed
344 *
345 * Since: 1.6
346 */
347 gboolean
gst_jpeg_segment_parse_scan_header(const GstJpegSegment * segment,GstJpegScanHdr * scan_hdr)348 gst_jpeg_segment_parse_scan_header (const GstJpegSegment * segment,
349 GstJpegScanHdr * scan_hdr)
350 {
351 GstByteReader br;
352 guint8 val;
353 guint i;
354
355 g_return_val_if_fail (segment != NULL, FALSE);
356 g_return_val_if_fail (scan_hdr != NULL, FALSE);
357
358 gst_byte_reader_init (&br, segment->data + segment->offset, segment->size);
359
360 if (segment->size < 3)
361 return FALSE;
362
363 gst_byte_reader_skip_unchecked (&br, 2);
364
365 U_READ_UINT8 (&br, scan_hdr->num_components);
366
367 if (scan_hdr->num_components > GST_JPEG_MAX_SCAN_COMPONENTS)
368 return FALSE;
369
370 if (gst_byte_reader_get_remaining (&br) < 2 * scan_hdr->num_components)
371 return FALSE;
372
373 for (i = 0; i < scan_hdr->num_components; i++) {
374 U_READ_UINT8 (&br, scan_hdr->components[i].component_selector);
375 U_READ_UINT8 (&br, val);
376 scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F;
377 scan_hdr->components[i].ac_selector = val & 0x0F;
378 if (scan_hdr->components[i].dc_selector >= 4
379 || scan_hdr->components[i].ac_selector >= 4)
380 return FALSE;
381 }
382
383 if (gst_byte_reader_get_remaining (&br) < 3)
384 return FALSE;
385
386 /* FIXME: Ss, Se, Ah, Al */
387 gst_byte_reader_skip_unchecked (&br, 3);
388
389 if (gst_byte_reader_get_remaining (&br) > 0)
390 GST_DEBUG ("data left at end of scan header segment");
391
392 return TRUE;
393 }
394
395 /**
396 * gst_jpeg_segment_parse_huffman_table:
397 * @segment: the JPEG segment
398 * @huff_tables: (out): The #GstJpegHuffmanTables structure to fill in
399 *
400 * Parses the JPEG Huffman table structure members from @segment.
401 *
402 * The caller must make sure there is enough data for the whole segment
403 * available.
404 *
405 * Note: @huf_tables represents the complete set of possible Huffman
406 * tables. However, the parser will only write to the Huffman table
407 * specified by the table destination identifier (Th). While doing so,
408 * the @valid flag of the specified Huffman table will also be set to
409 * %TRUE;
410 *
411 * Returns: TRUE if the Huffman table was correctly parsed.
412 *
413 * Since: 1.6
414 */
415 gboolean
gst_jpeg_segment_parse_huffman_table(const GstJpegSegment * segment,GstJpegHuffmanTables * huff_tables)416 gst_jpeg_segment_parse_huffman_table (const GstJpegSegment * segment,
417 GstJpegHuffmanTables * huff_tables)
418 {
419 GstByteReader br;
420 GstJpegHuffmanTable *huf_table;
421 guint8 val, table_class, table_index;
422 guint32 value_count;
423 guint i;
424
425 g_return_val_if_fail (segment != NULL, FALSE);
426 g_return_val_if_fail (huff_tables != NULL, FALSE);
427
428 if (segment->size < 2)
429 return FALSE;
430
431 gst_byte_reader_init (&br, segment->data + segment->offset, segment->size);
432
433 gst_byte_reader_skip_unchecked (&br, 2);
434
435 while (gst_byte_reader_get_remaining (&br) > 0) {
436 U_READ_UINT8 (&br, val);
437 table_class = ((val >> 4) & 0x0F);
438 table_index = (val & 0x0F);
439 if (table_index >= GST_JPEG_MAX_SCAN_COMPONENTS)
440 return FALSE;
441 if (table_class == 0) {
442 huf_table = &huff_tables->dc_tables[table_index];
443 } else {
444 huf_table = &huff_tables->ac_tables[table_index];
445 }
446 READ_BYTES (&br, huf_table->huf_bits, 16);
447 value_count = 0;
448 for (i = 0; i < 16; i++)
449 value_count += huf_table->huf_bits[i];
450 READ_BYTES (&br, huf_table->huf_values, value_count);
451 huf_table->valid = TRUE;
452 }
453 return TRUE;
454
455 failed:
456 return FALSE;
457 }
458
459 /**
460 * gst_jpeg_segment_parse_quantization_table:
461 * @segment: the JPEG segment
462 * @quant_tables: (out): The #GstJpegQuantTables structure to fill in
463 *
464 * Parses the JPEG quantization table structure members from @segment.
465 *
466 * The caller must make sure there is enough data for the whole segment
467 * available.
468 *
469 * Note: @quant_tables represents the complete set of possible
470 * quantization tables. However, the parser will only write to the
471 * quantization table specified by the table destination identifier
472 * (Tq). While doing so, the @valid flag of the specified quantization
473 * table will also be set to %TRUE.
474 *
475 * Returns: TRUE if the quantization table was correctly parsed.
476 *
477 * Since: 1.6
478 */
479 gboolean
gst_jpeg_segment_parse_quantization_table(const GstJpegSegment * segment,GstJpegQuantTables * quant_tables)480 gst_jpeg_segment_parse_quantization_table (const GstJpegSegment * segment,
481 GstJpegQuantTables * quant_tables)
482 {
483 GstByteReader br;
484 GstJpegQuantTable *quant_table;
485 guint8 val, table_index;
486 guint i;
487
488 g_return_val_if_fail (segment != NULL, FALSE);
489 g_return_val_if_fail (quant_tables != NULL, FALSE);
490
491 if (segment->size < 2)
492 return FALSE;
493
494 gst_byte_reader_init (&br, segment->data + segment->offset, segment->size);
495
496 gst_byte_reader_skip_unchecked (&br, 2);
497
498 while (gst_byte_reader_get_remaining (&br) > 0) {
499 guint8 element_size;
500
501 U_READ_UINT8 (&br, val);
502 table_index = (val & 0x0f);
503 if (table_index >= GST_JPEG_MAX_SCAN_COMPONENTS)
504 return FALSE;
505 quant_table = &quant_tables->quant_tables[table_index];
506 quant_table->quant_precision = ((val >> 4) & 0x0f);
507
508 element_size = (quant_table->quant_precision == 0) ? 1 : 2;
509 if (gst_byte_reader_get_remaining (&br) <
510 GST_JPEG_MAX_QUANT_ELEMENTS * element_size)
511 return FALSE;
512 for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
513 if (!quant_table->quant_precision) { /* 8-bit values */
514 U_READ_UINT8 (&br, val);
515 quant_table->quant_table[i] = val;
516 } else { /* 16-bit values */
517 U_READ_UINT16 (&br, quant_table->quant_table[i]);
518 }
519 }
520 quant_table->valid = TRUE;
521 }
522 return TRUE;
523 }
524
525 /**
526 * gst_jpeg_segment_parse_restart_interval:
527 * @segment: the JPEG segment
528 * @interval: (out): The parsed restart interval value
529 *
530 * The caller must make sure there is enough data for the whole segment
531 * available.
532 *
533 * Returns: TRUE if the restart interval value was correctly parsed.
534 *
535 * Since: 1.6
536 */
537 gboolean
gst_jpeg_segment_parse_restart_interval(const GstJpegSegment * segment,guint * interval)538 gst_jpeg_segment_parse_restart_interval (const GstJpegSegment * segment,
539 guint * interval)
540 {
541 GstByteReader br;
542 guint16 val;
543
544 g_return_val_if_fail (segment != NULL, FALSE);
545 g_return_val_if_fail (interval != NULL, FALSE);
546
547 if (segment->size < 4)
548 return FALSE;
549
550 gst_byte_reader_init (&br, segment->data + segment->offset, segment->size);
551 gst_byte_reader_skip_unchecked (&br, 2);
552
553 U_READ_UINT16 (&br, val);
554 *interval = val;
555 return TRUE;
556 }
557
558 static int
compare_huffman_table_entry(const void * a,const void * b)559 compare_huffman_table_entry (const void *a, const void *b)
560 {
561 const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a;
562 const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b;
563
564 if (e1->length == e2->length)
565 return (gint) e1->value - (gint) e2->value;
566 return (gint) e1->length - (gint) e2->length;
567 }
568
569 static void
build_huffman_table(GstJpegHuffmanTable * huf_table,const GstJpegHuffmanTableEntry * entries,guint num_entries)570 build_huffman_table (GstJpegHuffmanTable * huf_table,
571 const GstJpegHuffmanTableEntry * entries, guint num_entries)
572 {
573 const GstJpegHuffmanTableEntry *sorted_entries[256];
574 guint i, j, n;
575
576 g_assert (num_entries <= G_N_ELEMENTS (sorted_entries));
577
578 for (i = 0; i < num_entries; i++)
579 sorted_entries[i] = &entries[i];
580 qsort ((void *) sorted_entries, num_entries, sizeof (sorted_entries[0]),
581 compare_huffman_table_entry);
582
583 for (i = 0, j = 1, n = 0; i < num_entries; i++) {
584 const GstJpegHuffmanTableEntry *const e = sorted_entries[i];
585 if (e->length != j) {
586 huf_table->huf_bits[j++ - 1] = n;
587 for (; j < e->length; j++)
588 huf_table->huf_bits[j - 1] = 0;
589 n = 0;
590 }
591 huf_table->huf_values[i] = e->value;
592 n++;
593 }
594 huf_table->huf_bits[j - 1] = n;
595
596 for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++)
597 huf_table->huf_bits[j] = 0;
598 for (; i < G_N_ELEMENTS (huf_table->huf_values); i++)
599 huf_table->huf_values[i] = 0;
600 huf_table->valid = TRUE;
601 }
602
603 /**
604 * gst_jpeg_get_default_huffman_tables:
605 * @huf_tables: (out): The default DC/AC Huffman tables to fill in
606 *
607 * Fills in @huf_tables with the default AC/DC Huffman tables, as
608 * specified by the JPEG standard.
609 *
610 * Since: 1.6
611 */
612 void
gst_jpeg_get_default_huffman_tables(GstJpegHuffmanTables * huf_tables)613 gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables)
614 {
615 g_return_if_fail (huf_tables != NULL);
616
617 /* Build DC tables */
618 build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table,
619 G_N_ELEMENTS (default_luminance_dc_table));
620 build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table,
621 G_N_ELEMENTS (default_chrominance_dc_table));
622 memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1],
623 sizeof (huf_tables->dc_tables[2]));
624
625 /* Build AC tables */
626 build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table,
627 G_N_ELEMENTS (default_luminance_ac_table));
628 build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table,
629 G_N_ELEMENTS (default_chrominance_ac_table));
630 memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1],
631 sizeof (huf_tables->ac_tables[2]));
632 }
633
634 static void
build_quant_table(GstJpegQuantTable * quant_table,const guint8 values[64])635 build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64])
636 {
637 guint i;
638
639 for (i = 0; i < 64; i++)
640 quant_table->quant_table[i] = values[zigzag_index[i]];
641 quant_table->quant_precision = 0; /* Pq = 0 (8-bit precision) */
642 quant_table->valid = TRUE;
643 }
644
645 /**
646 * gst_jpeg_get_default_quantization_table:
647 * @quant_tables: (out): The default luma/chroma quant-tables in zigzag mode
648 *
649 * Fills in @quant_tables with the default quantization tables, as
650 * specified by the JPEG standard.
651 *
652 * Since: 1.6
653 */
654 void
gst_jpeg_get_default_quantization_tables(GstJpegQuantTables * quant_tables)655 gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables)
656 {
657 g_return_if_fail (quant_tables != NULL);
658
659 build_quant_table (&quant_tables->quant_tables[0],
660 default_luminance_quant_table);
661 build_quant_table (&quant_tables->quant_tables[1],
662 default_chrominance_quant_table);
663 build_quant_table (&quant_tables->quant_tables[2],
664 default_chrominance_quant_table);
665 }
666
667 /**
668 * gst_jpeg_parse:
669 * @segment: (out): pointer to a #GstJpegSegment structure to fill in
670 * @data: The data to parse
671 * @size: The size of @data
672 * @offset: The offset from which to start parsing
673 *
674 * Parses the JPEG bitstream contained in @data, and returns the
675 * detected segment as a #GstJpegSegment.
676 *
677 * Note that a valid segment may be returned with a length that exceeds
678 * the available data. It is up to the caller to make sure there's enough
679 * data available when parsing the segment.
680 *
681 * Returns: TRUE if a packet start code was found.
682 *
683 * Since: 1.6
684 */
685 gboolean
gst_jpeg_parse(GstJpegSegment * segment,const guint8 * data,gsize size,guint offset)686 gst_jpeg_parse (GstJpegSegment * segment,
687 const guint8 * data, gsize size, guint offset)
688 {
689 GstJpegSegment *seg = segment;
690 GstByteReader br;
691 guint16 length;
692
693 g_return_val_if_fail (seg != NULL, FALSE);
694 g_return_val_if_fail (data != NULL, FALSE);
695
696 if (size <= offset) {
697 GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset);
698 return FALSE;
699 }
700
701 size -= offset;
702 gst_byte_reader_init (&br, &data[offset], size);
703
704 if (!jpeg_parse_to_next_marker (&br, &seg->marker)) {
705 GST_DEBUG ("failed to find marker code");
706 return FALSE;
707 }
708
709 gst_byte_reader_skip_unchecked (&br, 2);
710 seg->offset = offset + gst_byte_reader_get_pos (&br);
711 seg->size = -1;
712
713 /* Try to find end of segment */
714 switch (seg->marker) {
715 case GST_JPEG_MARKER_SOI:
716 case GST_JPEG_MARKER_EOI:
717 fixed_size_segment:
718 seg->size = 0;
719 break;
720
721 case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */
722 case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */
723 case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */
724 case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */
725 case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */
726 case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */
727 case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */
728 case GST_JPEG_MARKER_SOS: /* Ls */
729 case GST_JPEG_MARKER_DQT: /* Lq */
730 case GST_JPEG_MARKER_DHT: /* Lh */
731 case GST_JPEG_MARKER_DAC: /* La */
732 case GST_JPEG_MARKER_DRI: /* Lr */
733 case GST_JPEG_MARKER_COM: /* Lc */
734 case GST_JPEG_MARKER_DNL: /* Ld */
735 variable_size_segment:
736 READ_UINT16 (&br, length);
737 seg->size = length;
738 break;
739
740 default:
741 /* Application data segment length (Lp) */
742 if (seg->marker >= GST_JPEG_MARKER_APP_MIN &&
743 seg->marker <= GST_JPEG_MARKER_APP_MAX)
744 goto variable_size_segment;
745
746 /* Restart markers (fixed size, two bytes only) */
747 if (seg->marker >= GST_JPEG_MARKER_RST_MIN &&
748 seg->marker <= GST_JPEG_MARKER_RST_MAX)
749 goto fixed_size_segment;
750
751 /* Fallback: scan for next marker */
752 if (!jpeg_parse_to_next_marker (&br, NULL))
753 goto failed;
754 seg->size = gst_byte_reader_get_pos (&br) - seg->offset;
755 break;
756 }
757
758 seg->data = data;
759 return TRUE;
760
761 failed:
762 return FALSE;
763 }
764