codecparsers: jpeg: fix calculation of segment size.
[vaapi:gstreamer-codecparsers.git] / gst-libs / gst / codecparsers / gstjpegparser.c
1 /*
2  *  gstjpegparser.c - JPEG parser
3  *
4  *  Copyright (C) 2011-2012 Intel Corporation
5  *
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.
10  *
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.
15  *
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
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <gst/base/gstbytereader.h>
25 #include "gstjpegparser.h"
26
27 #ifndef GST_DISABLE_GST_DEBUG
28
29 #define GST_CAT_DEFAULT ensure_debug_category()
30
31 static GstDebugCategory *
32 ensure_debug_category (void)
33 {
34   static gsize cat_gonce = 0;
35
36   if (g_once_init_enter (&cat_gonce)) {
37     gsize cat_done;
38
39     cat_done = (gsize) _gst_debug_category_new ("codecparsers_jpeg", 0,
40         "GstJpegCodecParser");
41
42     g_once_init_leave (&cat_gonce, cat_done);
43   }
44
45   return (GstDebugCategory *) cat_gonce;
46 }
47 #else
48
49 #define ensure_debug_category() /* NOOP */
50
51 #endif /* GST_DISABLE_GST_DEBUG */
52
53 #define DEBUG_PRINT_COMMENT 0
54
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");                     \
58       goto failed;                                              \
59     }                                                           \
60   } G_STMT_END
61
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");                    \
65       goto failed;                                              \
66     }                                                           \
67   } G_STMT_END
68
69 #define READ_BYTES(reader, buf, length) G_STMT_START {          \
70     const guint8 *vals;                                         \
71     if (!gst_byte_reader_get_data (reader, length, &vals)) {    \
72       GST_WARNING ("failed to read bytes, size:%d", length);    \
73       goto failed;                                              \
74     }                                                           \
75     memcpy (buf, vals, length);                                 \
76   } G_STMT_END
77
78 #define U_READ_UINT8(reader, val) G_STMT_START {                \
79     (val) = gst_byte_reader_get_uint8_unchecked(reader);        \
80   } G_STMT_END
81
82 #define U_READ_UINT16(reader, val) G_STMT_START {               \
83     (val) = gst_byte_reader_get_uint16_be_unchecked(reader);    \
84   } G_STMT_END
85
86
87 /* Table used to address an 8x8 matrix in zig-zag order */
88 /* *INDENT-OFF* */
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
98 };
99 /* *INDENT-ON* */
100
101 /* Table K.1 - Luminance quantization table */
102 /* *INDENT-OFF* */
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
112 };
113 /* *INDENT-ON* */
114
115 /* Table K.2 - Chrominance quantization table */
116 /* *INDENT-OFF* */
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
126 };
127 /* *INDENT-ON* */
128
129 typedef struct _GstJpegHuffmanTableEntry GstJpegHuffmanTableEntry;
130 struct _GstJpegHuffmanTableEntry
131 {
132   guint8 value;                 /* category */
133   guint8 length;                /* code length in bits */
134 };
135
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}
140 };
141
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}
146 };
147
148 /* Table K.5 - Table for luminance AC coefficients */
149 /* *INDENT-OFF* */
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}
178 };
179 /* *INDENT-ON* */
180
181 /* Table K.6 - Table for chrominance AC coefficients */
182 /* *INDENT-OFF* */
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}
211 };
212 /* *INDENT-ON* */
213
214 static inline gboolean
215 jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker)
216 {
217   gint ofs;
218
219   ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte);
220   if (ofs < 0)
221     return FALSE;
222
223   if (marker)
224     *marker = br->data[ofs + 1];
225   gst_byte_reader_skip_unchecked (br, ofs - br->byte);
226   return TRUE;
227 }
228
229 gint
230 gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset)
231 {
232   guint i;
233
234   g_return_val_if_fail (data != NULL, -1);
235   g_return_val_if_fail (size > offset, -1);
236
237   for (i = offset; i < size - 1;) {
238     if (data[i] != 0xff)
239       i++;
240     else {
241       const guint8 v = data[i + 1];
242       if (v >= 0xc0 && v <= 0xfe)
243         return i;
244       i += 2;
245     }
246   }
247   return -1;
248 }
249
250 gboolean
251 gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr,
252     const guint8 * data, gsize size, guint offset)
253 {
254   GstByteReader br;
255   guint16 length;
256   guint8 val;
257   guint i;
258
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);
262
263   size -= offset;
264   gst_byte_reader_init (&br, &data[offset], size);
265   g_return_val_if_fail (size >= 8, FALSE);
266
267   U_READ_UINT16 (&br, length);  /* Lf */
268   g_return_val_if_fail (size >= length, FALSE);
269
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);
276
277   length -= 8;
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);
288     length -= 3;
289   }
290
291   g_assert (length == 0);
292   return TRUE;
293 }
294
295 gboolean
296 gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr,
297     const guint8 * data, gsize size, guint offset)
298 {
299   GstByteReader br;
300   guint16 length;
301   guint8 val;
302   guint i;
303
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);
307
308   size -= offset;
309   gst_byte_reader_init (&br, &data[offset], size);
310   g_return_val_if_fail (size >= 3, FALSE);
311
312   U_READ_UINT16 (&br, length);  /* Ls */
313   g_return_val_if_fail (size >= length, FALSE);
314
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);
318
319   length -= 3;
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);
328     length -= 2;
329   }
330
331   /* FIXME: Ss, Se, Ah, Al */
332   g_assert (length == 3);
333   return TRUE;
334 }
335
336 gboolean
337 gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables,
338     const guint8 * data, gsize size, guint offset)
339 {
340   GstByteReader br;
341   GstJpegHuffmanTable *huf_table;
342   guint16 length;
343   guint8 val, table_class, table_index;
344   guint32 value_count;
345   guint i;
346
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);
350
351   size -= offset;
352   gst_byte_reader_init (&br, &data[offset], size);
353   g_return_val_if_fail (size >= 2, FALSE);
354
355   U_READ_UINT16 (&br, length);  /* Lh */
356   g_return_val_if_fail (size >= length, FALSE);
357
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];
365     } else {
366       huf_table = &huf_tables->ac_tables[table_index];
367     }
368     READ_BYTES (&br, huf_table->huf_bits, 16);
369     value_count = 0;
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;
374   }
375   return TRUE;
376
377 failed:
378   return FALSE;
379 }
380
381 gboolean
382 gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables,
383     const guint8 * data, gsize size, guint offset)
384 {
385   GstByteReader br;
386   GstJpegQuantTable *quant_table;
387   guint16 length;
388   guint8 val, table_index;
389   guint i;
390
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);
394
395   size -= offset;
396   gst_byte_reader_init (&br, &data[offset], size);
397   g_return_val_if_fail (size >= 2, FALSE);
398
399   U_READ_UINT16 (&br, length);  /* Lq */
400   g_return_val_if_fail (size >= length, FALSE);
401
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);
408
409     g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >=
410         GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision),
411         FALSE);
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]);
418       }
419     }
420     quant_table->valid = TRUE;
421   }
422   return TRUE;
423 }
424
425 gboolean
426 gst_jpeg_parse_restart_interval (guint * interval,
427     const guint8 * data, gsize size, guint offset)
428 {
429   GstByteReader br;
430   guint16 length, val;
431
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);
435
436   size -= offset;
437   gst_byte_reader_init (&br, &data[offset], size);
438   g_return_val_if_fail (size >= 4, FALSE);
439
440   U_READ_UINT16 (&br, length);  /* Lr */
441   g_return_val_if_fail (size >= length, FALSE);
442
443   U_READ_UINT16 (&br, val);
444   *interval = val;
445   return TRUE;
446 }
447
448 static int
449 compare_huffman_table_entry (const void *a, const void *b)
450 {
451   const GstJpegHuffmanTableEntry *const e1 = *(GstJpegHuffmanTableEntry **) a;
452   const GstJpegHuffmanTableEntry *const e2 = *(GstJpegHuffmanTableEntry **) b;
453
454   if (e1->length == e2->length)
455     return (gint) e1->value - (gint) e2->value;
456   return (gint) e1->length - (gint) e2->length;
457 }
458
459 static void
460 build_huffman_table (GstJpegHuffmanTable * huf_table,
461     const GstJpegHuffmanTableEntry * entries, guint num_entries)
462 {
463   const GstJpegHuffmanTableEntry *sorted_entries[256];
464   guint i, j, n;
465
466   g_assert (num_entries <= G_N_ELEMENTS (sorted_entries));
467
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);
472
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;
479       n = 0;
480     }
481     huf_table->huf_values[i] = e->value;
482     n++;
483   }
484   huf_table->huf_bits[j - 1] = n;
485
486   for (; j < G_N_ELEMENTS (huf_table->huf_bits); j++)
487     huf_table->huf_bits[j] = 0;
488   for (; i < G_N_ELEMENTS (huf_table->huf_values); i++)
489     huf_table->huf_values[i] = 0;
490   huf_table->valid = TRUE;
491 }
492
493 void
494 gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables)
495 {
496   g_assert (huf_tables);
497
498   /* Build DC tables */
499   build_huffman_table (&huf_tables->dc_tables[0], default_luminance_dc_table,
500       G_N_ELEMENTS (default_luminance_dc_table));
501   build_huffman_table (&huf_tables->dc_tables[1], default_chrominance_dc_table,
502       G_N_ELEMENTS (default_chrominance_dc_table));
503   memcpy (&huf_tables->dc_tables[2], &huf_tables->dc_tables[1],
504       sizeof (huf_tables->dc_tables[2]));
505
506   /* Build AC tables */
507   build_huffman_table (&huf_tables->ac_tables[0], default_luminance_ac_table,
508       G_N_ELEMENTS (default_luminance_ac_table));
509   build_huffman_table (&huf_tables->ac_tables[1], default_chrominance_ac_table,
510       G_N_ELEMENTS (default_chrominance_ac_table));
511   memcpy (&huf_tables->ac_tables[2], &huf_tables->ac_tables[1],
512       sizeof (huf_tables->ac_tables[2]));
513 }
514
515 static void
516 build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64])
517 {
518   guint i;
519
520   for (i = 0; i < 64; i++)
521     quant_table->quant_table[i] = values[zigzag_index[i]];
522   quant_table->quant_precision = 0;     /* Pq = 0 (8-bit precision) */
523   quant_table->valid = TRUE;
524 }
525
526 void
527 gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables)
528 {
529   g_assert (quant_tables);
530
531   build_quant_table (&quant_tables->quant_tables[0],
532       default_luminance_quant_table);
533   build_quant_table (&quant_tables->quant_tables[1],
534       default_chrominance_quant_table);
535   build_quant_table (&quant_tables->quant_tables[2],
536       default_chrominance_quant_table);
537 }
538
539 gboolean
540 gst_jpeg_parse (GstJpegMarkerSegment * seg,
541     const guint8 * data, gsize size, guint offset)
542 {
543   GstByteReader br;
544   guint16 length;
545
546   g_return_val_if_fail (seg != NULL, FALSE);
547
548   if (size <= offset) {
549     GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset);
550     return FALSE;
551   }
552
553   size -= offset;
554   gst_byte_reader_init (&br, &data[offset], size);
555
556   if (!jpeg_parse_to_next_marker (&br, &seg->marker)) {
557     GST_DEBUG ("failed to find marker code");
558     return FALSE;
559   }
560
561   gst_byte_reader_skip_unchecked (&br, 2);
562   seg->offset = offset + gst_byte_reader_get_pos (&br);
563   seg->size = -1;
564
565   /* Try to find end of segment */
566   switch (seg->marker) {
567     case GST_JPEG_MARKER_SOI:
568     case GST_JPEG_MARKER_EOI:
569     fixed_size_segment:
570       seg->size = 0;
571       break;
572
573     case (GST_JPEG_MARKER_SOF_MIN + 0):        /* Lf */
574     case (GST_JPEG_MARKER_SOF_MIN + 1):        /* Lf */
575     case (GST_JPEG_MARKER_SOF_MIN + 2):        /* Lf */
576     case (GST_JPEG_MARKER_SOF_MIN + 3):        /* Lf */
577     case (GST_JPEG_MARKER_SOF_MIN + 9):        /* Lf */
578     case (GST_JPEG_MARKER_SOF_MIN + 10):       /* Lf */
579     case (GST_JPEG_MARKER_SOF_MIN + 11):       /* Lf */
580     case GST_JPEG_MARKER_SOS:  /* Ls */
581     case GST_JPEG_MARKER_DQT:  /* Lq */
582     case GST_JPEG_MARKER_DHT:  /* Lh */
583     case GST_JPEG_MARKER_DAC:  /* La */
584     case GST_JPEG_MARKER_DRI:  /* Lr */
585     case GST_JPEG_MARKER_COM:  /* Lc */
586     case GST_JPEG_MARKER_DNL:  /* Ld */
587     variable_size_segment:
588       READ_UINT16 (&br, length);
589       seg->size = length;
590       break;
591
592     default:
593       /* Application data segment length (Lp) */
594       if (seg->marker >= GST_JPEG_MARKER_APP_MIN &&
595           seg->marker <= GST_JPEG_MARKER_APP_MAX)
596         goto variable_size_segment;
597
598       /* Restart markers (fixed size, two bytes only) */
599       if (seg->marker >= GST_JPEG_MARKER_RST_MIN &&
600           seg->marker <= GST_JPEG_MARKER_RST_MAX)
601         goto fixed_size_segment;
602
603       /* Fallback: scan for next marker */
604       if (!jpeg_parse_to_next_marker (&br, NULL))
605         goto failed;
606       seg->size = gst_byte_reader_get_pos (&br) - seg->offset;
607       break;
608   }
609   return TRUE;
610
611 failed:
612   return FALSE;
613 }