2 * gstjpegparser.c - JPEG parser
4 * Copyright (C) 2011-2012 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
24 #include <gst/base/gstbytereader.h>
25 #include "gstjpegparser.h"
27 #ifndef GST_DISABLE_GST_DEBUG
29 #define GST_CAT_DEFAULT ensure_debug_category()
31 static GstDebugCategory *
32 ensure_debug_category (void)
34 static gsize cat_gonce = 0;
36 if (g_once_init_enter (&cat_gonce)) {
39 cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0,
40 "GstJpegCodecParser");
42 g_once_init_leave (&cat_gonce, cat_done);
45 return (GstDebugCategory *) cat_gonce;
49 #define ensure_debug_category() /* NOOP */
51 #endif /* GST_DISABLE_GST_DEBUG */
53 #define DEBUG_PRINT_COMMENT 0
55 #define READ_UINT8(reader, val) G_STMT_START { \
56 if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \
57 GST_WARNING ("failed to read uint8"); \
62 #define READ_UINT16(reader, val) G_STMT_START { \
63 if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \
64 GST_WARNING ("failed to read uint16"); \
69 #define READ_BYTES(reader, buf, length) G_STMT_START { \
71 if (!gst_byte_reader_get_data (reader, length, &vals)) { \
72 GST_WARNING ("failed to read bytes, size:%d", length); \
75 memcpy (buf, vals, length); \
78 #define U_READ_UINT8(reader, val) G_STMT_START { \
79 (val) = gst_byte_reader_get_uint8_unchecked(reader); \
82 #define U_READ_UINT16(reader, val) G_STMT_START { \
83 (val) = gst_byte_reader_get_uint16_be_unchecked(reader); \
87 /* Table used to address an 8x8 matrix in zig-zag order */
89 static const guint8 zigzag_index[64] = {
90 0, 1, 8, 16, 9, 2, 3, 10,
91 17, 24, 32, 25, 18, 11, 4, 5,
92 12, 19, 26, 33, 40, 48, 41, 34,
93 27, 20, 13, 6, 7, 14, 21, 28,
94 35, 42, 49, 56, 57, 50, 43, 36,
95 29, 22, 15, 23, 30, 37, 44, 51,
96 58, 59, 52, 45, 38, 31, 39, 46,
97 53, 60, 61, 54, 47, 55, 62, 63
101 /* Table K.1 - Luminance quantization table */
103 static const guint8 default_luminance_quant_table[64] = {
104 16, 11, 10, 16, 24, 40, 51, 61,
105 12, 12, 14, 19, 26, 58, 60, 55,
106 14, 13, 16, 24, 40, 57, 69, 56,
107 14, 17, 22, 29, 51, 87, 80, 62,
108 18, 22, 37, 56, 68, 109, 103, 77,
109 24, 35, 55, 64, 81, 104, 113, 92,
110 49, 64, 78, 87, 103, 121, 120, 101,
111 72, 92, 95, 98, 112, 100, 103, 99
115 /* Table K.2 - Chrominance quantization table */
117 static const guint8 default_chrominance_quant_table[64] = {
118 17, 18, 24, 47, 99, 99, 99, 99,
119 18, 21, 26, 66, 99, 99, 99, 99,
120 24, 26, 56, 99, 99, 99, 99, 99,
121 47, 66, 99, 99, 99, 99, 99, 99,
122 99, 99, 99, 99, 99, 99, 99, 99,
123 99, 99, 99, 99, 99, 99, 99, 99,
124 99, 99, 99, 99, 99, 99, 99, 99,
125 99, 99, 99, 99, 99, 99, 99, 99
129 typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry;
130 struct _GstJpegHuffmanTableEntry
132 guint8 value; /* category */
133 guint8 length; /* code length in bits */
136 /* Table K.3 - Table for luminance DC coefficient differences */
137 static const GstJpegHuffmanTableEntry default_luminance_dc_table[] = {
138 {0x00, 2}, {0x01, 3}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3},
139 {0x06, 4}, {0x07, 5}, {0x08, 6}, {0x09, 7}, {0x0a, 8}, {0x0b, 9}
142 /* Table K.4 - Table for chrominance DC coefficient differences */
143 static const GstJpegHuffmanTableEntry default_chrominance_dc_table[] = {
144 {0x00, 2}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
145 {0x06, 6}, {0x07, 7}, {0x08, 8}, {0x09, 9}, {0x0a, 10}, {0x0b, 11}
148 /* Table K.5 - Table for luminance AC coefficients */
150 static const GstJpegHuffmanTableEntry default_luminance_ac_table[] = {
151 {0x00, 4}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
152 {0x06, 7}, {0x07, 8}, {0x08, 10}, {0x09, 16}, {0x0a, 16}, {0x11, 4},
153 {0x12, 5}, {0x13, 7}, {0x14, 9}, {0x15, 11}, {0x16, 16}, {0x17, 16},
154 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
155 {0x24, 12}, {0x25, 16}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
156 {0x2a, 16}, {0x31, 6}, {0x32, 9}, {0x33, 12}, {0x34, 16}, {0x35, 16},
157 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
158 {0x42, 10}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
159 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 7}, {0x52, 11}, {0x53, 16},
160 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
161 {0x5a, 16}, {0x61, 7}, {0x62, 12}, {0x63, 16}, {0x64, 16}, {0x65, 16},
162 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 8},
163 {0x72, 12}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
164 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 9}, {0x82, 15}, {0x83, 16},
165 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
166 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
167 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
168 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
169 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 10}, {0xb2, 16}, {0xb3, 16},
170 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
171 {0xba, 16}, {0xc1, 10}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
172 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
173 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
174 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 16}, {0xe2, 16}, {0xe3, 16},
175 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
176 {0xea, 16}, {0xf0, 11}, {0xf1, 16}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
177 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
181 /* Table K.6 - Table for chrominance AC coefficients */
183 static const GstJpegHuffmanTableEntry default_chrominance_ac_table[] = {
184 {0x00, 2}, {0x01, 2}, {0x02, 3}, {0x03, 4}, {0x04, 5}, {0x05, 5},
185 {0x06, 6}, {0x07, 7}, {0x08, 9}, {0x09, 10}, {0x0a, 12}, {0x11, 4},
186 {0x12, 6}, {0x13, 8}, {0x14, 9}, {0x15, 11}, {0x16, 12}, {0x17, 16},
187 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
188 {0x24, 12}, {0x25, 15}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
189 {0x2a, 16}, {0x31, 5}, {0x32, 8}, {0x33, 10}, {0x34, 12}, {0x35, 16},
190 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
191 {0x42, 9}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
192 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 6}, {0x52, 10}, {0x53, 16},
193 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
194 {0x5a, 16}, {0x61, 7}, {0x62, 11}, {0x63, 16}, {0x64, 16}, {0x65, 16},
195 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 7},
196 {0x72, 11}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
197 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 8}, {0x82, 16}, {0x83, 16},
198 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
199 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
200 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
201 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
202 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 9}, {0xb2, 16}, {0xb3, 16},
203 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
204 {0xba, 16}, {0xc1, 9}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
205 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
206 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
207 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 14}, {0xe2, 16}, {0xe3, 16},
208 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
209 {0xea, 16}, {0xf0, 10}, {0xf1, 15}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
210 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
214 static inline gboolean
215 jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker)
219 ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte);
224 *marker = br->data[ofs + 1];
225 gst_byte_reader_skip (br, ofs - br->byte + 2);
230 gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset)
234 g_return_val_if_fail (data != NULL, -1);
235 g_return_val_if_fail (size > offset, -1);
237 for (i = offset; i < size - 1;) {
241 const guint8 v = data[i + 1];
242 if (v >= 0xc0 && v <= 0xfe)
251 gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr,
252 const guint8 * data, gsize size, guint offset)
259 g_return_val_if_fail (frame_hdr != NULL, FALSE);
260 g_return_val_if_fail (data != NULL, FALSE);
261 g_return_val_if_fail (size > offset, FALSE);
264 gst_byte_reader_init (&br, &data[offset], size);
265 g_return_val_if_fail (size >= 8, FALSE);
267 U_READ_UINT16 (&br, length); /* Lf */
268 g_return_val_if_fail (size >= length, FALSE);
270 U_READ_UINT8 (&br, frame_hdr->sample_precision);
271 U_READ_UINT16 (&br, frame_hdr->height);
272 U_READ_UINT16 (&br, frame_hdr->width);
273 U_READ_UINT8 (&br, frame_hdr->num_components);
274 g_return_val_if_fail (frame_hdr->num_components <=
275 GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
278 g_return_val_if_fail (length >= 3 * frame_hdr->num_components, FALSE);
279 for (i = 0; i < frame_hdr->num_components; i++) {
280 U_READ_UINT8 (&br, frame_hdr->components[i].identifier);
281 U_READ_UINT8 (&br, val);
282 frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F;
283 frame_hdr->components[i].vertical_factor = (val & 0x0F);
284 U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector);
285 g_return_val_if_fail ((frame_hdr->components[i].horizontal_factor <= 4 &&
286 frame_hdr->components[i].vertical_factor <= 4 &&
287 frame_hdr->components[i].quant_table_selector < 4), FALSE);
291 g_assert (length == 0);
296 gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr,
297 const guint8 * data, gsize size, guint offset)
304 g_return_val_if_fail (scan_hdr != NULL, FALSE);
305 g_return_val_if_fail (data != NULL, FALSE);
306 g_return_val_if_fail (size > offset, FALSE);
309 gst_byte_reader_init (&br, &data[offset], size);
310 g_return_val_if_fail (size >= 3, FALSE);
312 U_READ_UINT16 (&br, length); /* Ls */
313 g_return_val_if_fail (size >= length, FALSE);
315 U_READ_UINT8 (&br, scan_hdr->num_components);
316 g_return_val_if_fail (scan_hdr->num_components <=
317 GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
320 g_return_val_if_fail (length >= 2 * scan_hdr->num_components, FALSE);
321 for (i = 0; i < scan_hdr->num_components; i++) {
322 U_READ_UINT8 (&br, scan_hdr->components[i].component_selector);
323 U_READ_UINT8 (&br, val);
324 scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F;
325 scan_hdr->components[i].ac_selector = val & 0x0F;
326 g_return_val_if_fail ((scan_hdr->components[i].dc_selector < 4 &&
327 scan_hdr->components[i].ac_selector < 4), FALSE);
331 /* FIXME: Ss, Se, Ah, Al */
332 g_assert (length == 3);
337 gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables,
338 const guint8 * data, gsize size, guint offset)
341 GstJpegHuffmanTable *huf_table;
343 guint8 val, table_class, table_index;
347 g_return_val_if_fail (huf_tables != NULL, FALSE);
348 g_return_val_if_fail (data != NULL, FALSE);
349 g_return_val_if_fail (size > offset, FALSE);
352 gst_byte_reader_init (&br, &data[offset], size);
353 g_return_val_if_fail (size >= 2, FALSE);
355 U_READ_UINT16 (&br, length); /* Lh */
356 g_return_val_if_fail (size >= length, FALSE);
358 while (gst_byte_reader_get_remaining (&br)) {
359 U_READ_UINT8 (&br, val);
360 table_class = ((val >> 4) & 0x0F);
361 table_index = (val & 0x0F);
362 g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
363 if (table_class == 0) {
364 huf_table = &huf_tables->dc_tables[table_index];
366 huf_table = &huf_tables->ac_tables[table_index];
368 READ_BYTES (&br, huf_table->huf_bits, 16);
370 for (i = 0; i < 16; i++)
371 value_count += huf_table->huf_bits[i];
372 READ_BYTES (&br, huf_table->huf_values, value_count);
373 huf_table->valid = TRUE;
382 gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables,
383 const guint8 * data, gsize size, guint offset)
386 GstJpegQuantTable *quant_table;
388 guint8 val, table_index;
391 g_return_val_if_fail (quant_tables != NULL, FALSE);
392 g_return_val_if_fail (data != NULL, FALSE);
393 g_return_val_if_fail (size > offset, FALSE);
396 gst_byte_reader_init (&br, &data[offset], size);
397 g_return_val_if_fail (size >= 2, FALSE);
399 U_READ_UINT16 (&br, length); /* Lq */
400 g_return_val_if_fail (size >= length, FALSE);
402 while (gst_byte_reader_get_remaining (&br)) {
403 U_READ_UINT8 (&br, val);
404 table_index = (val & 0x0f);
405 g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
406 quant_table = &quant_tables->quant_tables[table_index];
407 quant_table->quant_precision = ((val >> 4) & 0x0f);
409 g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >=
410 GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision),
412 for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
413 if (!quant_table->quant_precision) { /* 8-bit values */
414 U_READ_UINT8 (&br, val);
415 quant_table->quant_table[i] = val;
416 } else { /* 16-bit values */
417 U_READ_UINT16 (&br, quant_table->quant_table[i]);
420 quant_table->valid = TRUE;
426 gst_jpeg_parse_restart_interval (guint * interval,
427 const guint8 * data, gsize size, guint offset)
432 g_return_val_if_fail (interval != NULL, FALSE);
433 g_return_val_if_fail (data != NULL, FALSE);
434 g_return_val_if_fail (size > offset, FALSE);
437 gst_byte_reader_init (&br, &data[offset], size);
438 g_return_val_if_fail (size >= 4, FALSE);
440 U_READ_UINT16 (&br, length); /* Lr */
441 g_return_val_if_fail (size >= length, FALSE);
443 U_READ_UINT16 (&br, val);
449 compare_huffman_table_entry (const void *a, const void *b)
451 const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a;
452 const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b;
454 if (e1->length == e2->length)
455 return (gint) e1->value - (gint) e2->value;
456 return (gint) e1->length - (gint) e2->length;
460 build_huffman_table (GstJpegHuffmanTable * huf_table,
461 const GstJpegHuffmanTableEntry * entries, guint num_entries)
463 const GstJpegHuffmanTableEntry *sorted_entries[256];
466 g_assert (num_entries <= G_N_ELEMENTS (sorted_entries));
468 for (i = 0; i < num_entries; i++)
469 sorted_entries[i] = &entries[i];
470 qsort (sorted_entries, num_entries, sizeof (sorted_entries[0]),
471 compare_huffman_table_entry);
473 for (i = 0, j = 1, n = 0; i < num_entries; i++) {
474 const GstJpegHuffmanTableEntry *const e = sorted_entries[i];
475 if (e->length != j) {
476 huf_table->huf_bits[j++ - 1] = n;
477 for (; j < e->length; j++)
478 huf_table->huf_bits[j - 1] = 0;
481 huf_table->huf_values[i] = e->value;
485 for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++)
486 huf_table->huf_bits[j] = 0;
487 for (; i < G_N_ELEMENTS (huf_table->huf_values); i++)
488 huf_table->huf_values[i] = 0;
489 huf_table->valid = TRUE;
493 gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables)
495 g_assert (huf_tables);
497 /* Build DC tables */
498 build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table,
499 G_N_ELEMENTS (default_luminance_dc_table));
500 build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table,
501 G_N_ELEMENTS (default_chrominance_dc_table));
502 memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1],
503 sizeof (huf_tables->dc_tables[2]));
505 /* Build AC tables */
506 build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table,
507 G_N_ELEMENTS (default_luminance_ac_table));
508 build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table,
509 G_N_ELEMENTS (default_chrominance_ac_table));
510 memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1],
511 sizeof (huf_tables->ac_tables[2]));
515 build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64])
519 for (i = 0; i < 64; i++)
520 quant_table->quant_table[i] = values[zigzag_index[i]];
521 quant_table->quant_precision = 0; /* Pq = 0 (8-bit precision) */
522 quant_table->valid = TRUE;
526 gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables)
528 g_assert (quant_tables);
530 build_quant_table (&quant_tables->quant_tables[0],
531 default_luminance_quant_table);
532 build_quant_table (&quant_tables->quant_tables[1],
533 default_chrominance_quant_table);
534 build_quant_table (&quant_tables->quant_tables[2],
535 default_chrominance_quant_table);
539 gst_jpeg_parse (GstJpegMarkerSegment * seg,
540 const guint8 * data, gsize size, guint offset)
545 g_return_val_if_fail (seg != NULL, FALSE);
547 if (size <= offset) {
548 GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset);
553 gst_byte_reader_init (&br, &data[offset], size);
555 if (!jpeg_parse_to_next_marker (&br, &seg->marker)) {
556 GST_DEBUG ("failed to find marker code");
560 seg->offset = offset + gst_byte_reader_get_pos (&br);
563 /* Try to find end of segment */
564 switch (seg->marker) {
565 case GST_JPEG_MARKER_SOI:
566 case GST_JPEG_MARKER_EOI:
571 case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */
572 case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */
573 case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */
574 case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */
575 case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */
576 case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */
577 case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */
578 case GST_JPEG_MARKER_SOS: /* Ls */
579 case GST_JPEG_MARKER_DQT: /* Lq */
580 case GST_JPEG_MARKER_DHT: /* Lh */
581 case GST_JPEG_MARKER_DAC: /* La */
582 case GST_JPEG_MARKER_DRI: /* Lr */
583 case GST_JPEG_MARKER_COM: /* Lc */
584 case GST_JPEG_MARKER_DNL: /* Ld */
585 variable_size_segment:
586 READ_UINT16 (&br, length);
591 /* Application data segment length (Lp) */
592 if (seg->marker >= GST_JPEG_MARKER_APP_MIN &&
593 seg->marker <= GST_JPEG_MARKER_APP_MAX)
594 goto variable_size_segment;
596 /* Restart markers (fixed size, two bytes only) */
597 if (seg->marker >= GST_JPEG_MARKER_RST_MIN &&
598 seg->marker <= GST_JPEG_MARKER_RST_MAX)
599 goto fixed_size_segment;
601 /* Fallback: scan for next marker */
602 if (!jpeg_parse_to_next_marker (&br, NULL))
604 seg->size = gst_byte_reader_get_pos (&br) - seg->offset;