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
23 #include <gst/base/gstbytereader.h>
24 #include "gstjpegparser.h"
26 #ifndef GST_DISABLE_GST_DEBUG
28 #define GST_CAT_DEFAULT ensure_debug_category()
30 static GstDebugCategory *
31 ensure_debug_category (void)
33 static gsize cat_gonce = 0;
35 if (g_once_init_enter (&cat_gonce)) {
38 cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0,
39 "GstJpegCodecParser");
41 g_once_init_leave (&cat_gonce, cat_done);
44 return (GstDebugCategory *) cat_gonce;
48 #define ensure_debug_category() /* NOOP */
50 #endif /* GST_DISABLE_GST_DEBUG */
52 #define DEBUG_PRINT_COMMENT 0
54 #define READ_UINT8(reader, val) G_STMT_START { \
55 if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \
56 GST_WARNING ("failed to read uint8"); \
61 #define READ_UINT16(reader, val) G_STMT_START { \
62 if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \
63 GST_WARNING ("failed to read uint16"); \
68 #define READ_BYTES(reader, buf, length) G_STMT_START { \
70 if (!gst_byte_reader_get_data (reader, length, &vals)) { \
71 GST_WARNING ("failed to read bytes, size:%d", length); \
74 memcpy (buf, vals, length); \
77 #define U_READ_UINT8(reader, val) G_STMT_START { \
78 (val) = gst_byte_reader_get_uint8_unchecked(reader); \
81 #define U_READ_UINT16(reader, val) G_STMT_START { \
82 (val) = gst_byte_reader_get_uint16_be_unchecked(reader); \
86 /* Table used to address an 8x8 matrix in zig-zag order */
88 static const guint8 zigzag_index[64] = {
89 0, 1, 8, 16, 9, 2, 3, 10,
90 17, 24, 32, 25, 18, 11, 4, 5,
91 12, 19, 26, 33, 40, 48, 41, 34,
92 27, 20, 13, 6, 7, 14, 21, 28,
93 35, 42, 49, 56, 57, 50, 43, 36,
94 29, 22, 15, 23, 30, 37, 44, 51,
95 58, 59, 52, 45, 38, 31, 39, 46,
96 53, 60, 61, 54, 47, 55, 62, 63
100 /* Table K.1 - Luminance quantization table */
102 static const guint8 default_luminance_quant_table[64] = {
103 16, 11, 10, 16, 24, 40, 51, 61,
104 12, 12, 14, 19, 26, 58, 60, 55,
105 14, 13, 16, 24, 40, 57, 69, 56,
106 14, 17, 22, 29, 51, 87, 80, 62,
107 18, 22, 37, 56, 68, 109, 103, 77,
108 24, 35, 55, 64, 81, 104, 113, 92,
109 49, 64, 78, 87, 103, 121, 120, 101,
110 72, 92, 95, 98, 112, 100, 103, 99
114 /* Table K.2 - Chrominance quantization table */
116 static const guint8 default_chrominance_quant_table[64] = {
117 17, 18, 24, 47, 99, 99, 99, 99,
118 18, 21, 26, 66, 99, 99, 99, 99,
119 24, 26, 56, 99, 99, 99, 99, 99,
120 47, 66, 99, 99, 99, 99, 99, 99,
121 99, 99, 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
128 typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry;
129 struct _GstJpegHuffmanTableEntry
131 guint8 value; /* category */
132 guint8 length; /* code length in bits */
135 /* Table K.3 - Table for luminance DC coefficient differences */
136 static const GstJpegHuffmanTableEntry default_luminance_dc_table[] = {
137 {0x00, 2}, {0x01, 3}, {0x02, 3}, {0x03, 3}, {0x04, 3}, {0x05, 3},
138 {0x06, 4}, {0x07, 5}, {0x08, 6}, {0x09, 7}, {0x0a, 8}, {0x0b, 9}
141 /* Table K.4 - Table for chrominance DC coefficient differences */
142 static const GstJpegHuffmanTableEntry default_chrominance_dc_table[] = {
143 {0x00, 2}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
144 {0x06, 6}, {0x07, 7}, {0x08, 8}, {0x09, 9}, {0x0a, 10}, {0x0b, 11}
147 /* Table K.5 - Table for luminance AC coefficients */
149 static const GstJpegHuffmanTableEntry default_luminance_ac_table[] = {
150 {0x00, 4}, {0x01, 2}, {0x02, 2}, {0x03, 3}, {0x04, 4}, {0x05, 5},
151 {0x06, 7}, {0x07, 8}, {0x08, 10}, {0x09, 16}, {0x0a, 16}, {0x11, 4},
152 {0x12, 5}, {0x13, 7}, {0x14, 9}, {0x15, 11}, {0x16, 16}, {0x17, 16},
153 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
154 {0x24, 12}, {0x25, 16}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
155 {0x2a, 16}, {0x31, 6}, {0x32, 9}, {0x33, 12}, {0x34, 16}, {0x35, 16},
156 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
157 {0x42, 10}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
158 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 7}, {0x52, 11}, {0x53, 16},
159 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
160 {0x5a, 16}, {0x61, 7}, {0x62, 12}, {0x63, 16}, {0x64, 16}, {0x65, 16},
161 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 8},
162 {0x72, 12}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
163 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 9}, {0x82, 15}, {0x83, 16},
164 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
165 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
166 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
167 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
168 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 10}, {0xb2, 16}, {0xb3, 16},
169 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
170 {0xba, 16}, {0xc1, 10}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
171 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
172 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
173 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 16}, {0xe2, 16}, {0xe3, 16},
174 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
175 {0xea, 16}, {0xf0, 11}, {0xf1, 16}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
176 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
180 /* Table K.6 - Table for chrominance AC coefficients */
182 static const GstJpegHuffmanTableEntry default_chrominance_ac_table[] = {
183 {0x00, 2}, {0x01, 2}, {0x02, 3}, {0x03, 4}, {0x04, 5}, {0x05, 5},
184 {0x06, 6}, {0x07, 7}, {0x08, 9}, {0x09, 10}, {0x0a, 12}, {0x11, 4},
185 {0x12, 6}, {0x13, 8}, {0x14, 9}, {0x15, 11}, {0x16, 12}, {0x17, 16},
186 {0x18, 16}, {0x19, 16}, {0x1a, 16}, {0x21, 5}, {0x22, 8}, {0x23, 10},
187 {0x24, 12}, {0x25, 15}, {0x26, 16}, {0x27, 16}, {0x28, 16}, {0x29, 16},
188 {0x2a, 16}, {0x31, 5}, {0x32, 8}, {0x33, 10}, {0x34, 12}, {0x35, 16},
189 {0x36, 16}, {0x37, 16}, {0x38, 16}, {0x39, 16}, {0x3a, 16}, {0x41, 6},
190 {0x42, 9}, {0x43, 16}, {0x44, 16}, {0x45, 16}, {0x46, 16}, {0x47, 16},
191 {0x48, 16}, {0x49, 16}, {0x4a, 16}, {0x51, 6}, {0x52, 10}, {0x53, 16},
192 {0x54, 16}, {0x55, 16}, {0x56, 16}, {0x57, 16}, {0x58, 16}, {0x59, 16},
193 {0x5a, 16}, {0x61, 7}, {0x62, 11}, {0x63, 16}, {0x64, 16}, {0x65, 16},
194 {0x66, 16}, {0x67, 16}, {0x68, 16}, {0x69, 16}, {0x6a, 16}, {0x71, 7},
195 {0x72, 11}, {0x73, 16}, {0x74, 16}, {0x75, 16}, {0x76, 16}, {0x77, 16},
196 {0x78, 16}, {0x79, 16}, {0x7a, 16}, {0x81, 8}, {0x82, 16}, {0x83, 16},
197 {0x84, 16}, {0x85, 16}, {0x86, 16}, {0x87, 16}, {0x88, 16}, {0x89, 16},
198 {0x8a, 16}, {0x91, 9}, {0x92, 16}, {0x93, 16}, {0x94, 16}, {0x95, 16},
199 {0x96, 16}, {0x97, 16}, {0x98, 16}, {0x99, 16}, {0x9a, 16}, {0xa1, 9},
200 {0xa2, 16}, {0xa3, 16}, {0xa4, 16}, {0xa5, 16}, {0xa6, 16}, {0xa7, 16},
201 {0xa8, 16}, {0xa9, 16}, {0xaa, 16}, {0xb1, 9}, {0xb2, 16}, {0xb3, 16},
202 {0xb4, 16}, {0xb5, 16}, {0xb6, 16}, {0xb7, 16}, {0xb8, 16}, {0xb9, 16},
203 {0xba, 16}, {0xc1, 9}, {0xc2, 16}, {0xc3, 16}, {0xc4, 16}, {0xc5, 16},
204 {0xc6, 16}, {0xc7, 16}, {0xc8, 16}, {0xc9, 16}, {0xca, 16}, {0xd1, 11},
205 {0xd2, 16}, {0xd3, 16}, {0xd4, 16}, {0xd5, 16}, {0xd6, 16}, {0xd7, 16},
206 {0xd8, 16}, {0xd9, 16}, {0xda, 16}, {0xe1, 14}, {0xe2, 16}, {0xe3, 16},
207 {0xe4, 16}, {0xe5, 16}, {0xe6, 16}, {0xe7, 16}, {0xe8, 16}, {0xe9, 16},
208 {0xea, 16}, {0xf0, 10}, {0xf1, 15}, {0xf2, 16}, {0xf3, 16}, {0xf4, 16},
209 {0xf5, 16}, {0xf6, 16}, {0xf7, 16}, {0xf8, 16}, {0xf9, 16}, {0xfa, 16}
213 static inline gboolean
214 jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker)
218 ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte);
223 *marker = br->data[ofs + 1];
224 gst_byte_reader_skip (br, ofs - br->byte + 2);
229 gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset)
233 g_return_val_if_fail (data != NULL, -1);
234 g_return_val_if_fail (size > offset, -1);
236 for (i = offset; i < size - 1;) {
240 const guint8 v = data[i + 1];
241 if (v >= 0xc0 && v <= 0xfe)
250 gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr,
251 const guint8 * data, gsize size, guint offset)
258 g_return_val_if_fail (frame_hdr != NULL, FALSE);
259 g_return_val_if_fail (data != NULL, FALSE);
260 g_return_val_if_fail (size > offset, FALSE);
263 gst_byte_reader_init (&br, &data[offset], size);
264 g_return_val_if_fail (size >= 8, FALSE);
266 U_READ_UINT16 (&br, length); /* Lf */
267 g_return_val_if_fail (size >= length, FALSE);
269 U_READ_UINT8 (&br, frame_hdr->sample_precision);
270 U_READ_UINT16 (&br, frame_hdr->height);
271 U_READ_UINT16 (&br, frame_hdr->width);
272 U_READ_UINT8 (&br, frame_hdr->num_components);
273 g_return_val_if_fail (frame_hdr->num_components <=
274 GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
277 g_return_val_if_fail (length >= 3 * frame_hdr->num_components, FALSE);
278 for (i = 0; i < frame_hdr->num_components; i++) {
279 U_READ_UINT8 (&br, frame_hdr->components[i].identifier);
280 U_READ_UINT8 (&br, val);
281 frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F;
282 frame_hdr->components[i].vertical_factor = (val & 0x0F);
283 U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector);
284 g_return_val_if_fail ((frame_hdr->components[i].horizontal_factor <= 4 &&
285 frame_hdr->components[i].vertical_factor <= 4 &&
286 frame_hdr->components[i].quant_table_selector < 4), FALSE);
290 g_assert (length == 0);
295 gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr,
296 const guint8 * data, gsize size, guint offset)
303 g_return_val_if_fail (scan_hdr != NULL, FALSE);
304 g_return_val_if_fail (data != NULL, FALSE);
305 g_return_val_if_fail (size > offset, FALSE);
308 gst_byte_reader_init (&br, &data[offset], size);
309 g_return_val_if_fail (size >= 3, FALSE);
311 U_READ_UINT16 (&br, length); /* Ls */
312 g_return_val_if_fail (size >= length, FALSE);
314 U_READ_UINT8 (&br, scan_hdr->num_components);
315 g_return_val_if_fail (scan_hdr->num_components <=
316 GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
319 g_return_val_if_fail (length >= 2 * scan_hdr->num_components, FALSE);
320 for (i = 0; i < scan_hdr->num_components; i++) {
321 U_READ_UINT8 (&br, scan_hdr->components[i].component_selector);
322 U_READ_UINT8 (&br, val);
323 scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F;
324 scan_hdr->components[i].ac_selector = val & 0x0F;
325 g_return_val_if_fail ((scan_hdr->components[i].dc_selector < 4 &&
326 scan_hdr->components[i].ac_selector < 4), FALSE);
330 /* FIXME: Ss, Se, Ah, Al */
331 g_assert (length == 3);
336 gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables,
337 const guint8 * data, gsize size, guint offset)
340 GstJpegHuffmanTable *huf_table;
342 guint8 val, table_class, table_index;
346 g_return_val_if_fail (huf_tables != NULL, FALSE);
347 g_return_val_if_fail (data != NULL, FALSE);
348 g_return_val_if_fail (size > offset, FALSE);
351 gst_byte_reader_init (&br, &data[offset], size);
352 g_return_val_if_fail (size >= 2, FALSE);
354 U_READ_UINT16 (&br, length); /* Lh */
355 g_return_val_if_fail (size >= length, FALSE);
357 while (gst_byte_reader_get_remaining (&br)) {
358 U_READ_UINT8 (&br, val);
359 table_class = ((val >> 4) & 0x0F);
360 table_index = (val & 0x0F);
361 g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
362 if (table_class == 0) {
363 huf_table = &huf_tables->dc_tables[table_index];
365 huf_table = &huf_tables->ac_tables[table_index];
367 READ_BYTES (&br, huf_table->huf_bits, 16);
369 for (i = 0; i < 16; i++)
370 value_count += huf_table->huf_bits[i];
371 READ_BYTES (&br, huf_table->huf_values, value_count);
372 huf_table->valid = TRUE;
381 gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables,
382 const guint8 * data, gsize size, guint offset)
385 GstJpegQuantTable *quant_table;
387 guint8 val, table_index;
390 g_return_val_if_fail (quant_tables != NULL, FALSE);
391 g_return_val_if_fail (data != NULL, FALSE);
392 g_return_val_if_fail (size > offset, FALSE);
395 gst_byte_reader_init (&br, &data[offset], size);
396 g_return_val_if_fail (size >= 2, FALSE);
398 U_READ_UINT16 (&br, length); /* Lq */
399 g_return_val_if_fail (size >= length, FALSE);
401 while (gst_byte_reader_get_remaining (&br)) {
402 U_READ_UINT8 (&br, val);
403 table_index = (val & 0x0f);
404 g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE);
405 quant_table = &quant_tables->quant_tables[table_index];
406 quant_table->quant_precision = ((val >> 4) & 0x0f);
408 g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >=
409 GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision),
411 for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) {
412 if (!quant_table->quant_precision) { /* 8-bit values */
413 U_READ_UINT8 (&br, val);
414 quant_table->quant_table[i] = val;
415 } else { /* 16-bit values */
416 U_READ_UINT16 (&br, quant_table->quant_table[i]);
419 quant_table->valid = TRUE;
425 gst_jpeg_parse_restart_interval (guint * interval,
426 const guint8 * data, gsize size, guint offset)
431 g_return_val_if_fail (interval != NULL, FALSE);
432 g_return_val_if_fail (data != NULL, FALSE);
433 g_return_val_if_fail (size > offset, FALSE);
436 gst_byte_reader_init (&br, &data[offset], size);
437 g_return_val_if_fail (size >= 4, FALSE);
439 U_READ_UINT16 (&br, length); /* Lr */
440 g_return_val_if_fail (size >= length, FALSE);
442 U_READ_UINT16 (&br, val);
448 compare_huffman_table_entry (const void *a, const void *b)
450 const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a;
451 const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b;
453 if (e1->length == e2->length)
454 return (gint) e1->value - (gint) e2->value;
455 return (gint) e1->length - (gint) e2->length;
459 build_huffman_table (GstJpegHuffmanTable * huf_table,
460 const GstJpegHuffmanTableEntry * entries, guint num_entries)
462 const GstJpegHuffmanTableEntry *sorted_entries[256];
465 g_assert (num_entries <= G_N_ELEMENTS (sorted_entries));
467 for (i = 0; i < num_entries; i++)
468 sorted_entries[i] = &entries[i];
469 qsort (sorted_entries, num_entries, sizeof (sorted_entries[0]),
470 compare_huffman_table_entry);
472 for (i = 0, j = 1, n = 0; i < num_entries; i++) {
473 const GstJpegHuffmanTableEntry *const e = sorted_entries[i];
474 if (e->length != j) {
475 huf_table->huf_bits[j++ - 1] = n;
476 for (; j < e->length; j++)
477 huf_table->huf_bits[j - 1] = 0;
480 huf_table->huf_values[i] = e->value;
484 for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++)
485 huf_table->huf_bits[j] = 0;
486 for (; i < G_N_ELEMENTS (huf_table->huf_values); i++)
487 huf_table->huf_values[i] = 0;
488 huf_table->valid = TRUE;
492 gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables)
494 g_assert (huf_tables);
496 /* Build DC tables */
497 build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table,
498 G_N_ELEMENTS (default_luminance_dc_table));
499 build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table,
500 G_N_ELEMENTS (default_chrominance_dc_table));
501 memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1],
502 sizeof (huf_tables->dc_tables[2]));
504 /* Build AC tables */
505 build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table,
506 G_N_ELEMENTS (default_luminance_ac_table));
507 build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table,
508 G_N_ELEMENTS (default_chrominance_ac_table));
509 memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1],
510 sizeof (huf_tables->ac_tables[2]));
514 build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64])
518 for (i = 0; i < 64; i++)
519 quant_table->quant_table[i] = values[zigzag_index[i]];
520 quant_table->quant_precision = 0; /* Pq = 0 (8-bit precision) */
521 quant_table->valid = TRUE;
525 gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables)
527 g_assert (quant_tables);
529 build_quant_table (&quant_tables->quant_tables[0],
530 default_luminance_quant_table);
531 build_quant_table (&quant_tables->quant_tables[1],
532 default_chrominance_quant_table);
533 build_quant_table (&quant_tables->quant_tables[2],
534 default_chrominance_quant_table);
538 gst_jpeg_parse (GstJpegMarkerSegment * seg,
539 const guint8 * data, gsize size, guint offset)
544 g_return_val_if_fail (seg != NULL, FALSE);
546 if (size <= offset) {
547 GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset);
552 gst_byte_reader_init (&br, &data[offset], size);
554 if (!jpeg_parse_to_next_marker (&br, &seg->marker)) {
555 GST_DEBUG ("failed to find marker code");
559 seg->offset = offset + gst_byte_reader_get_pos (&br);
562 /* Try to find end of segment */
563 switch (seg->marker) {
564 case GST_JPEG_MARKER_SOI:
565 case GST_JPEG_MARKER_EOI:
570 case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */
571 case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */
572 case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */
573 case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */
574 case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */
575 case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */
576 case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */
577 case GST_JPEG_MARKER_SOS: /* Ls */
578 case GST_JPEG_MARKER_DQT: /* Lq */
579 case GST_JPEG_MARKER_DHT: /* Lh */
580 case GST_JPEG_MARKER_DAC: /* La */
581 case GST_JPEG_MARKER_DRI: /* Lr */
582 case GST_JPEG_MARKER_COM: /* Lc */
583 case GST_JPEG_MARKER_DNL: /* Ld */
584 variable_size_segment:
585 READ_UINT16 (&br, length);
590 /* Application data segment length (Lp) */
591 if (seg->marker >= GST_JPEG_MARKER_APP_MIN &&
592 seg->marker <= GST_JPEG_MARKER_APP_MAX)
593 goto variable_size_segment;
595 /* Restart markers (fixed size, two bytes only) */
596 if (seg->marker >= GST_JPEG_MARKER_RST_MIN &&
597 seg->marker <= GST_JPEG_MARKER_RST_MAX)
598 goto fixed_size_segment;
600 /* Fallback: scan for next marker */
601 if (!jpeg_parse_to_next_marker (&br, NULL))
603 seg->size = gst_byte_reader_get_pos (&br) - seg->offset;