import ext/codecparsers instead of git submodule
[profile/ivi/gstreamer-vaapi.git] / ext / codecparsers / 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 (br, ofs - br->byte + 2);
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
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;
490 }
491
492 void
493 gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables)
494 {
495   g_assert (huf_tables);
496
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]));
504
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]));
512 }
513
514 static void
515 build_quant_table (GstJpegQuantTable * quant_table, const guint8 values[64])
516 {
517   guint i;
518
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;
523 }
524
525 void
526 gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables)
527 {
528   g_assert (quant_tables);
529
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);
536 }
537
538 gboolean
539 gst_jpeg_parse (GstJpegMarkerSegment * seg,
540     const guint8 * data, gsize size, guint offset)
541 {
542   GstByteReader br;
543   guint16 length;
544
545   g_return_val_if_fail (seg != NULL, FALSE);
546
547   if (size <= offset) {
548     GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset);
549     return FALSE;
550   }
551
552   size -= offset;
553   gst_byte_reader_init (&br, &data[offset], size);
554
555   if (!jpeg_parse_to_next_marker (&br, &seg->marker)) {
556     GST_DEBUG ("failed to find marker code");
557     return FALSE;
558   }
559
560   seg->offset = offset + gst_byte_reader_get_pos (&br);
561   seg->size = -1;
562
563   /* Try to find end of segment */
564   switch (seg->marker) {
565     case GST_JPEG_MARKER_SOI:
566     case GST_JPEG_MARKER_EOI:
567     fixed_size_segment:
568       seg->size = 2;
569       break;
570
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);
587       seg->size = length;
588       break;
589
590     default:
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;
595
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;
600
601       /* Fallback: scan for next marker */
602       if (!jpeg_parse_to_next_marker (&br, NULL))
603         goto failed;
604       seg->size = gst_byte_reader_get_pos (&br) - seg->offset;
605       break;
606   }
607   return TRUE;
608
609 failed:
610   return FALSE;
611 }