From 8f93bbc93786a5964d4d36fe5053334af597a593 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Mon, 16 Jul 2012 17:35:19 +0200 Subject: [PATCH] codecparsers: jpeg: tweak parser API. ... to allow for more consistent parsing API among various codec parsers. In particular, drop use of GList. --- gst-libs/gst/codecparsers/gstjpegparser.c | 809 +++++++++++----------- gst-libs/gst/codecparsers/gstjpegparser.h | 146 ++-- 2 files changed, 469 insertions(+), 486 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstjpegparser.c b/gst-libs/gst/codecparsers/gstjpegparser.c index 35187c4101..49f80742f6 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.c +++ b/gst-libs/gst/codecparsers/gstjpegparser.c @@ -1,7 +1,7 @@ /* - * gstjpegparser.c - JPEG parser for baseline + * gstjpegparser.c - JPEG parser * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -19,10 +19,9 @@ * Boston, MA 02110-1301 USA */ -#include "gstjpegparser.h" - #include #include +#include "gstjpegparser.h" #ifndef GST_DISABLE_GST_DEBUG @@ -52,28 +51,15 @@ ensure_debug_category (void) #define DEBUG_PRINT_COMMENT 0 -#define CHECK_FAILED(exp, ret) G_STMT_START { \ - if (!(exp)) { \ - result = ret; \ - goto wrong_state; \ - } \ - } G_STMT_END - -#define JPEG_RESULT_CHECK(result) G_STMT_START { \ - if ((result) != GST_JPEG_PARSER_OK) { \ - goto wrong_state; \ - } \ - } G_STMT_END - #define READ_UINT8(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ + if (!gst_byte_reader_get_uint8 ((reader), &(val))) { \ GST_WARNING ("failed to read uint8"); \ goto failed; \ } \ } G_STMT_END #define READ_UINT16(reader, val) G_STMT_START { \ - if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ + if (!gst_byte_reader_get_uint16_be ((reader), &(val))) { \ GST_WARNING ("failed to read uint16"); \ goto failed; \ } \ @@ -81,11 +67,11 @@ ensure_debug_category (void) #define READ_BYTES(reader, buf, length) G_STMT_START { \ const guint8 *vals; \ - if (!gst_byte_reader_get_data(reader, length, &vals)) { \ - GST_WARNING("failed to read bytes, size:%d", length); \ + if (!gst_byte_reader_get_data (reader, length, &vals)) { \ + GST_WARNING ("failed to read bytes, size:%d", length); \ goto failed; \ } \ - memcpy(buf, vals, length); \ + memcpy (buf, vals, length); \ } G_STMT_END #define U_READ_UINT8(reader, val) G_STMT_START { \ @@ -97,464 +83,473 @@ ensure_debug_category (void) } G_STMT_END -static gboolean jpeg_parse_to_next_marker (GstByteReader * reader, - guint8 * marker); - /* CCITT T.81, Annex K.1 Quantization tables for luminance and chrominance components */ /* only for 8-bit per sample image */ -static const GstJpegQuantTables -default_quant_tables_zigzag = { +/* *INDENT-OFF* */ +static const GstJpegQuantTables default_quant_tables_zigzag = { .quant_tables = { /* luma */ - {0, { 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, - 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, - 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, - 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, - 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, - 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, - 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, - 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63 }, TRUE }, + {0, {0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, + 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x27, + 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, + 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, + 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0xa8, + 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0xb5, 0x57, + 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, + 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63}, TRUE}, /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, + {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, /* chroma */ - {0, { 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, - 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 }, TRUE }, - {0, } + {0, {0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, + 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63}, TRUE}, + {0,} } }; +/* *INDENT-ON* */ /* Table K.3: typical Huffman tables for 8-bit precision luminance and chrominance */ -/* -0..GST_JPEG_MAX_SCAN_COMPONENTS -1, DC huffman tables -GST_JPEG_MAX_SCAN_COMPONENTS...GST_JPEG_MAX_SCAN_COMPONENTS*2-1, AC huffman tables -*/ -static const -GstJpegHuffmanTables default_huf_tables = { +/* *INDENT-OFF* */ +static const GstJpegHuffmanTables default_huf_tables = { .dc_tables = { - /* DC luma */ - { { 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - /* DC chroma */ - { { 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }, - TRUE - }, - { { 0x0 }, - { 0x0 } - } + /* DC luma */ + {{0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + /* DC chroma */ + {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + /* DC chroma */ + {{0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b}, + TRUE}, + {{0x0,}, + {0x0,} + } }, .ac_tables = { - /* AC luma */ - { { 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d }, - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa}, - TRUE - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - TRUE - }, - /* AC chroma */ - { { 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - TRUE - }, - { { 0x00 }, - { 0x00 } - } + /* AC luma */ + {{0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d}, + {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + /* AC chroma */ + {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, + {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + /* AC chroma */ + {{0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77}, + {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa}, + TRUE}, + {{0x00,}, + {0x00,} + } } }; +/* *INDENT-ON* */ -static gboolean -jpeg_parse_to_next_marker (GstByteReader * reader, guint8 * marker) +static inline gboolean +jpeg_parse_to_next_marker (GstByteReader * br, guint8 * marker) { - guint8 value; + gint ofs; - while (gst_byte_reader_get_uint8 (reader, &value)) { - if (value != 0xFF) - continue; - while (value == 0xFF) { - READ_UINT8 (reader, value); + ofs = gst_jpeg_scan_for_marker_code (br->data, br->size, br->byte); + if (ofs < 0) + return FALSE; + + if (marker) + *marker = br->data[ofs + 1]; + gst_byte_reader_skip (br, ofs - br->byte + 2); + return TRUE; +} + +gint +gst_jpeg_scan_for_marker_code (const guint8 * data, gsize size, guint offset) +{ + guint i; + + g_return_val_if_fail (data != NULL, -1); + g_return_val_if_fail (size > offset, -1); + + for (i = offset; i < size - 1;) { + if (data[i] != 0xff) + i++; + else { + const guint8 v = data[i + 1]; + if (v >= 0xc0 && v <= 0xfe) + return i; + i += 2; } - if (value == 0x00) - continue; - *marker = value; - return TRUE; } + return -1; +} + +gboolean +gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + guint16 length; + guint8 val; + guint i; + + g_return_val_if_fail (frame_hdr != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 8, FALSE); + + U_READ_UINT16 (&br, length); /* Lf */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT8 (&br, frame_hdr->sample_precision); + U_READ_UINT16 (&br, frame_hdr->height); + U_READ_UINT16 (&br, frame_hdr->width); + U_READ_UINT8 (&br, frame_hdr->num_components); + g_return_val_if_fail (frame_hdr->num_components <= + GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + + length -= 8; + g_return_val_if_fail (length >= 3 * frame_hdr->num_components, FALSE); + for (i = 0; i < frame_hdr->num_components; i++) { + U_READ_UINT8 (&br, frame_hdr->components[i].identifier); + U_READ_UINT8 (&br, val); + frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; + frame_hdr->components[i].vertical_factor = (val & 0x0F); + U_READ_UINT8 (&br, frame_hdr->components[i].quant_table_selector); + g_return_val_if_fail ((frame_hdr->components[i].horizontal_factor <= 4 && + frame_hdr->components[i].vertical_factor <= 4 && + frame_hdr->components[i].quant_table_selector < 4), FALSE); + length -= 3; + } + + g_assert (length == 0); + return TRUE; +} + +gboolean +gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + guint16 length; + guint8 val; + guint i; + + g_return_val_if_fail (scan_hdr != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 3, FALSE); + + U_READ_UINT16 (&br, length); /* Ls */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT8 (&br, scan_hdr->num_components); + g_return_val_if_fail (scan_hdr->num_components <= + GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + + length -= 3; + g_return_val_if_fail (length >= 2 * scan_hdr->num_components, FALSE); + for (i = 0; i < scan_hdr->num_components; i++) { + U_READ_UINT8 (&br, scan_hdr->components[i].component_selector); + U_READ_UINT8 (&br, val); + scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; + scan_hdr->components[i].ac_selector = val & 0x0F; + g_return_val_if_fail ((scan_hdr->components[i].dc_selector < 4 && + scan_hdr->components[i].ac_selector < 4), FALSE); + length -= 2; + } + + /* FIXME: Ss, Se, Ah, Al */ + g_assert (length == 3); + return TRUE; +} + +gboolean +gst_jpeg_parse_huffman_table (GstJpegHuffmanTables * huf_tables, + const guint8 * data, gsize size, guint offset) +{ + GstByteReader br; + GstJpegHuffmanTable *huf_table; + guint16 length; + guint8 val, table_class, table_index; + guint32 value_count; + guint i; + + g_return_val_if_fail (huf_tables != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 2, FALSE); + + U_READ_UINT16 (&br, length); /* Lh */ + g_return_val_if_fail (size >= length, FALSE); + + while (gst_byte_reader_get_remaining (&br)) { + U_READ_UINT8 (&br, val); + table_class = ((val >> 4) & 0x0F); + table_index = (val & 0x0F); + g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); + if (table_class == 0) { + huf_table = &huf_tables->dc_tables[table_index]; + } else { + huf_table = &huf_tables->ac_tables[table_index]; + } + READ_BYTES (&br, huf_table->huf_bits, 16); + value_count = 0; + for (i = 0; i < 16; i++) + value_count += huf_table->huf_bits[i]; + READ_BYTES (&br, huf_table->huf_values, value_count); + huf_table->valid = TRUE; + } + return TRUE; failed: return FALSE; } -GstJpegParserResult -gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * frame_hdr, +gboolean +gst_jpeg_parse_quant_table (GstJpegQuantTables * quant_tables, const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - guint8 val; - u_int i; - - g_assert (frame_hdr && data && size); - - CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 6, GST_JPEG_PARSER_ERROR); - U_READ_UINT8 (&bytes_reader, frame_hdr->sample_precision); - U_READ_UINT16 (&bytes_reader, frame_hdr->height); - U_READ_UINT16 (&bytes_reader, frame_hdr->width); - U_READ_UINT8 (&bytes_reader, frame_hdr->num_components); - CHECK_FAILED (frame_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_ERROR); - - CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= 3*frame_hdr->num_components, - GST_JPEG_PARSER_ERROR); - for (i = 0; i < frame_hdr->num_components; i++) { - U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].identifier); - U_READ_UINT8 (&bytes_reader, val); - frame_hdr->components[i].horizontal_factor = (val >> 4) & 0x0F; - frame_hdr->components[i].vertical_factor = (val & 0x0F); - U_READ_UINT8 (&bytes_reader, frame_hdr->components[i].quant_table_selector); - CHECK_FAILED ((frame_hdr->components[i].horizontal_factor <= 4 && - frame_hdr->components[i].vertical_factor <= 4 && - frame_hdr->components[i].quant_table_selector < 4), - GST_JPEG_PARSER_ERROR); - } - return GST_JPEG_PARSER_OK; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_scan_hdr (GstJpegScanHdr * scan_hdr, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - guint8 val; - u_int i; - - g_assert (scan_hdr && data && size); - READ_UINT8 (&bytes_reader, scan_hdr->num_components); - CHECK_FAILED (scan_hdr->num_components <= GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); - - CHECK_FAILED (gst_byte_reader_get_remaining (&bytes_reader) >= 2*scan_hdr->num_components, - GST_JPEG_PARSER_ERROR); - for (i = 0; i < scan_hdr->num_components; i++) { - U_READ_UINT8 (&bytes_reader, - scan_hdr->components[i].component_selector); - U_READ_UINT8 (&bytes_reader, val); - scan_hdr->components[i].dc_selector = (val >> 4) & 0x0F; - scan_hdr->components[i].ac_selector = val & 0x0F; - g_assert (scan_hdr->components[i].dc_selector < 4 && - scan_hdr->components[i].ac_selector < 4); - CHECK_FAILED ((scan_hdr->components[i].dc_selector < 4 && - scan_hdr->components[i].ac_selector < 4), - GST_JPEG_PARSER_BROKEN_DATA); - } - return GST_JPEG_PARSER_OK; - -failed: - return GST_JPEG_PARSER_ERROR; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_huffman_table ( - GstJpegHuffmanTables *huf_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data+offset, size-offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; - GstJpegHuffmanTable * huf_table; - guint8 tmp_val; - gboolean is_dc; - guint8 table_index; - guint32 value_count; - u_int i; - - g_assert (huf_tables && data && size); - while (gst_byte_reader_get_remaining (&bytes_reader)) { - U_READ_UINT8 (&bytes_reader, tmp_val); - is_dc = !((tmp_val >> 4) & 0x0F); - table_index = (tmp_val & 0x0F); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); - if (is_dc) { - huf_table = &huf_tables->dc_tables[table_index]; - } else { - huf_table = &huf_tables->ac_tables[table_index]; - } - READ_BYTES (&bytes_reader, huf_table->huf_bits, 16); - value_count = 0; - for (i = 0; i < 16; i++) - value_count += huf_table->huf_bits[i]; - READ_BYTES (&bytes_reader, huf_table->huf_values, value_count); - huf_table->valid = TRUE; - } - return GST_JPEG_PARSER_OK; - -failed: - return GST_JPEG_PARSER_ERROR; - -wrong_state: - return result; -} - -GstJpegParserResult -gst_jpeg_parse_quant_table ( - GstJpegQuantTables *quant_tables, - const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - GstJpegParserResult result = GST_JPEG_PARSER_OK; + GstByteReader br; GstJpegQuantTable *quant_table; - guint8 val; - guint8 table_index; + guint16 length; + guint8 val, table_index; guint i; - g_assert (quant_tables && data && size); - while (gst_byte_reader_get_remaining (&bytes_reader)) { - U_READ_UINT8 (&bytes_reader, val); + g_return_val_if_fail (quant_tables != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); + + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 2, FALSE); + + U_READ_UINT16 (&br, length); /* Lq */ + g_return_val_if_fail (size >= length, FALSE); + + while (gst_byte_reader_get_remaining (&br)) { + U_READ_UINT8 (&br, val); table_index = (val & 0x0f); - CHECK_FAILED (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, - GST_JPEG_PARSER_BROKEN_DATA); + g_return_val_if_fail (table_index < GST_JPEG_MAX_SCAN_COMPONENTS, FALSE); quant_table = &quant_tables->quant_tables[table_index]; quant_table->quant_precision = ((val >> 4) & 0x0f); - CHECK_FAILED (gst_byte_reader_get_remaining(&bytes_reader) >= GST_JPEG_MAX_QUANT_ELEMENTS * (1 + !!quant_table->quant_precision), - GST_JPEG_PARSER_BROKEN_DATA); + g_return_val_if_fail (gst_byte_reader_get_remaining (&br) >= + GST_JPEG_MAX_QUANT_ELEMENTS * (1 + ! !quant_table->quant_precision), + FALSE); for (i = 0; i < GST_JPEG_MAX_QUANT_ELEMENTS; i++) { - if (!quant_table->quant_precision) { /* 8-bit values */ - U_READ_UINT8 (&bytes_reader, val); - quant_table->quant_table[i] = val; - } else { /* 16-bit values */ - U_READ_UINT16 (&bytes_reader, quant_table->quant_table[i]); - } + if (!quant_table->quant_precision) { /* 8-bit values */ + U_READ_UINT8 (&br, val); + quant_table->quant_table[i] = val; + } else { /* 16-bit values */ + U_READ_UINT16 (&br, quant_table->quant_table[i]); + } } quant_table->valid = TRUE; } - return GST_JPEG_PARSER_OK; - -wrong_state: - return result; + return TRUE; } -GstJpegParserResult +gboolean gst_jpeg_parse_restart_interval (guint * interval, const guint8 * data, gsize size, guint offset) { - GstByteReader bytes_reader = GST_BYTE_READER_INIT (data + offset, size - offset); - guint16 tmp; + GstByteReader br; + guint16 length, val; - g_assert (interval && data && size); - READ_UINT16 (&bytes_reader, tmp); - *interval = tmp; - return GST_JPEG_PARSER_OK; + g_return_val_if_fail (interval != NULL, FALSE); + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (size > offset, FALSE); -failed: - return GST_JPEG_PARSER_BROKEN_DATA; + size -= offset; + gst_byte_reader_init (&br, &data[offset], size); + g_return_val_if_fail (size >= 4, FALSE); + + U_READ_UINT16 (&br, length); /* Lr */ + g_return_val_if_fail (size >= length, FALSE); + + U_READ_UINT16 (&br, val); + *interval = val; + return TRUE; } void -gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables) +gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables * huf_tables) { g_assert (huf_tables); - memcpy (huf_tables, &default_huf_tables, sizeof (GstJpegHuffmanTables)); + memcpy (huf_tables, &default_huf_tables, sizeof (*huf_tables)); } void -gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables) +gst_jpeg_get_default_quantization_tables (GstJpegQuantTables * quant_tables) { g_assert (quant_tables); - memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (GstJpegQuantTables)); + + memcpy (quant_tables, &default_quant_tables_zigzag, sizeof (*quant_tables)); } -static gint32 -jpeg_scan_to_end (const guint8 *start, guint32 size) +gboolean +gst_jpeg_parse (GstJpegMarkerSegment * seg, + const guint8 * data, gsize size, guint offset) { - const guint8 *pos = start, *end = start + size; + GstByteReader br; + guint16 length; - for (; pos < end; ++pos) { - if (*pos != 0xFF) - continue; - while (*pos == 0xFF && pos + 1 < end) - ++pos; - if (*pos == 0x00 || *pos == 0xFF || - (*pos >= GST_JPEG_MARKER_RST_MIN && *pos <= GST_JPEG_MARKER_RST_MAX)) - continue; - break; + g_return_val_if_fail (seg != NULL, FALSE); + + if (size <= offset) { + GST_DEBUG ("failed to parse from offset %u, buffer is too small", offset); + return FALSE; } - if (pos >= end) - return size; - return pos - start - 1; -} - -static GstJpegTypeOffsetSize * -gst_jpeg_segment_new (guint8 marker, guint offset, gint size) -{ - GstJpegTypeOffsetSize *seg; - - if (GST_JPEG_MARKER_SOS == marker) - seg = g_malloc0 (sizeof (GstJpegScanOffsetSize)); - else - seg = g_malloc0 (sizeof (GstJpegTypeOffsetSize)); - seg->type = marker; - seg->offset = offset; - seg->size = size; - return seg; -} - -GList * -gst_jpeg_parse(const guint8 * data, gsize size, guint offset) -{ - GstByteReader bytes_reader; - guint8 marker; - guint16 header_length; - GList *segments = NULL; - GstJpegTypeOffsetSize *seg; - const guint8 *scan_start; - gint scan_size = 0; size -= offset; + gst_byte_reader_init (&br, &data[offset], size); - if ((gssize)size <= 0) { - GST_DEBUG ("Can't parse from offset %d, buffer is too small", offset); - return NULL; + if (!jpeg_parse_to_next_marker (&br, &seg->marker)) { + GST_DEBUG ("failed to find marker code"); + return FALSE; } - gst_byte_reader_init (&bytes_reader, &data[offset], size); + seg->offset = offset + gst_byte_reader_get_pos (&br); + seg->size = -1; - /* read SOI */ - if (!jpeg_parse_to_next_marker (&bytes_reader, &marker) || - marker != GST_JPEG_MARKER_SOI) - goto failed; - - while (jpeg_parse_to_next_marker (&bytes_reader, &marker)) { - if (marker == GST_JPEG_MARKER_EOI) + /* Try to find end of segment */ + switch (seg->marker) { + case GST_JPEG_MARKER_SOI: + case GST_JPEG_MARKER_EOI: + fixed_size_segment: + seg->size = 2; break; - READ_UINT16 (&bytes_reader, header_length); - if (header_length < 2 || - gst_byte_reader_get_remaining (&bytes_reader) < header_length - 2) - goto failed; + case (GST_JPEG_MARKER_SOF_MIN + 0): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 1): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 2): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 3): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 9): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 10): /* Lf */ + case (GST_JPEG_MARKER_SOF_MIN + 11): /* Lf */ + case GST_JPEG_MARKER_SOS: /* Ls */ + case GST_JPEG_MARKER_DQT: /* Lq */ + case GST_JPEG_MARKER_DHT: /* Lh */ + case GST_JPEG_MARKER_DAC: /* La */ + case GST_JPEG_MARKER_DRI: /* Lr */ + case GST_JPEG_MARKER_COM: /* Lc */ + case GST_JPEG_MARKER_DNL: /* Ld */ + variable_size_segment: + READ_UINT16 (&br, length); + seg->size = length; + break; - seg = gst_jpeg_segment_new (marker, - gst_byte_reader_get_pos(&bytes_reader) + offset, - header_length - 2); - segments = g_list_prepend(segments, seg); - gst_byte_reader_skip (&bytes_reader, header_length - 2); + default: + /* Application data segment length (Lp) */ + if (seg->marker >= GST_JPEG_MARKER_APP_MIN && + seg->marker <= GST_JPEG_MARKER_APP_MAX) + goto variable_size_segment; - if (seg->type == GST_JPEG_MARKER_SOS) { - GstJpegScanOffsetSize * const scan_seg = (GstJpegScanOffsetSize *)seg; - scan_start = gst_byte_reader_peek_data_unchecked (&bytes_reader); - scan_size = jpeg_scan_to_end (scan_start, - gst_byte_reader_get_remaining (&bytes_reader)); - if (scan_size <= 0) - break; + /* Restart markers (fixed size, two bytes only) */ + if (seg->marker >= GST_JPEG_MARKER_RST_MIN && + seg->marker <= GST_JPEG_MARKER_RST_MAX) + goto fixed_size_segment; - scan_seg->data_offset = gst_byte_reader_get_pos (&bytes_reader) + offset; - scan_seg->data_size = scan_size; - gst_byte_reader_skip (&bytes_reader, scan_size); - } + /* Fallback: scan for next marker */ + if (!jpeg_parse_to_next_marker (&br, NULL)) + goto failed; + seg->size = gst_byte_reader_get_pos (&br) - seg->offset; + break; } - return g_list_reverse (segments); + return TRUE; failed: - { - GST_WARNING ("Failed to parse"); - return g_list_reverse (segments); - } + return FALSE; } diff --git a/gst-libs/gst/codecparsers/gstjpegparser.h b/gst-libs/gst/codecparsers/gstjpegparser.h index a3f2b858f3..7237584e25 100644 --- a/gst-libs/gst/codecparsers/gstjpegparser.h +++ b/gst-libs/gst/codecparsers/gstjpegparser.h @@ -1,7 +1,7 @@ /* * gstjpegparser.h - JPEG parser * - * Copyright (C) 2011 Intel Corporation + * Copyright (C) 2011-2012 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -60,25 +60,7 @@ typedef struct _GstJpegScanComponent GstJpegScanComponent; typedef struct _GstJpegScanHdr GstJpegScanHdr; typedef struct _GstJpegFrameComponent GstJpegFrameComponent; typedef struct _GstJpegFrameHdr GstJpegFrameHdr; -typedef struct _GstJpegTypeOffsetSize GstJpegTypeOffsetSize; -typedef struct _GstJpegScanOffsetSize GstJpegScanOffsetSize; - -/** - * GstJpegParserResult: - * @GST_JPEG_PARSER_OK: The parsing succeeded - * @GST_JPEG_PARSER_BROKEN_DATA: The data to parse is broken - * @GST_JPEG_PARSER_NO_SCAN_FOUND: No scan found during the parsing - * @GST_JPEG_PARSER_ERROR: An error occured while parsing - * - * The result of parsing JPEG data. - */ -typedef enum -{ - GST_JPEG_PARSER_OK, - GST_JPEG_PARSER_BROKEN_DATA, - GST_JPEG_PARSER_NO_SCAN_FOUND, - GST_JPEG_PARSER_ERROR, -} GstJpegParserResult; +typedef struct _GstJpegMarkerSegment GstJpegMarkerSegment; /** * GstJpegMarkerCode: @@ -124,7 +106,6 @@ typedef enum { * @GST_JPEG_PROFILE_EXTENDED: Extended sequential DCT * @GST_JPEG_PROFILE_PROGRESSIVE: Progressive DCT * @GST_JPEG_PROFILE_LOSSLESS: Lossless (sequential) - * @GST_JPEG_PROFILE_ARITHMETIC: Flag for arithmetic coding * * JPEG encoding processes. */ @@ -133,9 +114,20 @@ typedef enum { GST_JPEG_PROFILE_EXTENDED = 0x01, GST_JPEG_PROFILE_PROGRESSIVE = 0x02, GST_JPEG_PROFILE_LOSSLESS = 0x03, - GST_JPEG_PROFILE_ARITHMETIC = 0x80 } GstJpegProfile; +/** + * GstJpegEntropyCodingMode: + * @GST_JPEG_ENTROPY_CODING_HUFFMAN: Huffman coding + * @GST_JPEG_ENTROPY_CODING_ARITHMETIC: arithmetic coding + * + * JPEG entropy coding mode. + */ +typedef enum { + GST_JPEG_ENTROPY_CODING_HUFFMAN = 0x00, + GST_JPEG_ENTROPY_CODING_ARITHMETIC = 0x08 +} GstJpegEntropyCodingMode; + /** * GstJpegQuantTable: * @quant_precision: Quantization table element precision (Pq) @@ -241,7 +233,6 @@ struct _GstJpegFrameComponent /** * GstJpegFrameHdr: - * @profile: JPEG encoding process (see #GstJpegProfile) * @sample_precision: Sample precision (P) * @height: Number of lines (Y) * @width: Number of samples per line (X) @@ -253,7 +244,6 @@ struct _GstJpegFrameComponent */ struct _GstJpegFrameHdr { - guint8 profile; guint8 sample_precision; /* 2 .. 16 */ guint16 width; /* 1 .. 65535 */ guint16 height; /* 0 .. 65535 */ @@ -262,38 +252,37 @@ struct _GstJpegFrameHdr }; /** - * GstJpegTypeOffsetSize: + * GstJpegMarkerSegment: * @type: The type of the segment that starts at @offset - * @offset: The offset to the segment start in bytes - * @size: The size in bytes of the segment, or -1 if the end was not found + * @offset: The offset to the segment start in bytes. This is the + * exact start of the segment, no marker code included + * @size: The size in bytes of the segment, or -1 if the end was not + * found. It is the exact size of the segment, no marker code included * * A structure that contains the type of a segment, its offset and its size. */ -struct _GstJpegTypeOffsetSize +struct _GstJpegMarkerSegment { - guint8 type; + guint8 marker; guint offset; gint size; }; /** - * GstJpegScanOffsetSize: - * @header: The header info associated to the scan - * @data_offset: The offset to the first entropy-coded segment in bytes - * @data_size: The size in bytes of the scan data, including all ECS - * and RST segments, or -1 if the end was not found + * gst_jpeg_scan_for_marker_code: + * @data: The data to parse + * @size: The size of @data + * @offset: The offset from which to start parsing * - * A structure that contains information on a scan. A scan comprises of the - * scan @header, and all entropy-coded segment (ECS) and restart marker (RST) - * associated to it. The header type MUST be set to @GST_JPEG_MARKER_SOS. + * Scans the JPEG bitstream contained in @data for the next marker + * code. If found, the function returns an offset to the marker code, + * including the 0xff prefix code but excluding any extra fill bytes. + * + * Returns: offset to the marker code if found, or -1 if not found. */ -struct _GstJpegScanOffsetSize -{ - GstJpegTypeOffsetSize header; - guint data_offset; - gint data_size; -}; - +gint gst_jpeg_scan_for_marker_code (const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse: @@ -301,15 +290,15 @@ struct _GstJpegScanOffsetSize * @size: The size of @data * @offset: The offset from which to start parsing * - * Parses the JPEG bitstream contained in @data, and returns the detected - * segments as a newly-allocated list of #GstJpegTypeOffsetSize elements. - * The caller is responsible for destroying the list when no longer needed. + * Parses the JPEG bitstream contained in @data, and returns the + * detected segment as a #GstJpegMarkerSegment. * - * Returns: a #GList of #GstJpegTypeOffsetSize. + * Returns: TRUE if a packet start code was found. */ -GList *gst_jpeg_parse (const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse (GstJpegMarkerSegment * seg, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_frame_hdr: @@ -320,12 +309,12 @@ GList *gst_jpeg_parse (const guint8 * data, * * Parses the @hdr JPEG frame header structure members from @data. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the frame header was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_scan_hdr: @@ -336,12 +325,12 @@ GstJpegParserResult gst_jpeg_parse_frame_hdr (GstJpegFrameHdr * hdr, * * Parses the @hdr JPEG scan header structure members from @data. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the scan header was correctly parsed */ -GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_quantization_table: @@ -359,12 +348,12 @@ GstJpegParserResult gst_jpeg_parse_scan_hdr (GstJpegScanHdr * hdr, * (Tq). While doing so, the @valid flag of the specified quantization * table will also be set to %TRUE. * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the quantization table was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_quant_table (GstJpegQuantTables *quant_tables, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_huffman_table: @@ -381,12 +370,12 @@ GstJpegParserResult gst_jpeg_parse_quant_table (GstJpegQuantTables *qua * the @valid flag of the specified Huffman table will also be set to * %TRUE; * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the Huffman table was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *huf_tables, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_parse_restart_interval: @@ -395,12 +384,12 @@ GstJpegParserResult gst_jpeg_parse_huffman_table (GstJpegHuffmanTables *h * @size: The size of @data * @offset: The offset in bytes from which to start parsing @data * - * Returns: a #GstJpegParserResult + * Returns: TRUE if the restart interval value was correctly parsed. */ -GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, - const guint8 * data, - gsize size, - guint offset); +gboolean gst_jpeg_parse_restart_interval (guint * interval, + const guint8 * data, + gsize size, + guint offset); /** * gst_jpeg_get_default_huffman_tables: @@ -409,8 +398,7 @@ GstJpegParserResult gst_jpeg_parse_restart_interval (guint * interval, * Fills in @huf_tables with the default AC/DC Huffman tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_huffman_tables ( - GstJpegHuffmanTables *huf_tables); +void gst_jpeg_get_default_huffman_tables (GstJpegHuffmanTables *huf_tables); /** * gst_jpeg_get_default_quantization_table: @@ -419,7 +407,7 @@ void gst_jpeg_get_default_huffman_tables ( * Fills in @quant_tables with the default quantization tables, as * specified by the JPEG standard. */ -void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); +void gst_jpeg_get_default_quantization_tables (GstJpegQuantTables *quant_tables); G_END_DECLS