• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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