mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
Added support for PNG/XMP. Indentation. And fixed pull mode to parse the file.
Original commit message from CVS: Added support for PNG/XMP. Indentation. And fixed pull mode to parse the file.
This commit is contained in:
parent
05e1fdf681
commit
f17824d0d1
18 changed files with 553 additions and 154 deletions
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
|||
2007-11-02 Edgard Lima <edgard.lima@indt.org.br>
|
||||
|
||||
* ext/metadata/Makefile.am:
|
||||
* ext/metadata/gstmetadataparse.c:
|
||||
* ext/metadata/gstmetadataparse.h:
|
||||
* ext/metadata/metadataparse.c:
|
||||
* ext/metadata/metadataparse.h:
|
||||
* ext/metadata/metadataparseexif.c:
|
||||
* ext/metadata/metadataparseexif.h:
|
||||
* ext/metadata/metadataparseiptc.c:
|
||||
* ext/metadata/metadataparseiptc.h:
|
||||
* ext/metadata/metadataparsejpeg.c:
|
||||
* ext/metadata/metadataparsejpeg.h:
|
||||
* ext/metadata/metadataparsepng.c:
|
||||
* ext/metadata/metadataparsepng.h:
|
||||
* ext/metadata/metadataparseutil.c:
|
||||
* ext/metadata/metadataparseutil.h:
|
||||
* ext/metadata/metadataparsexmp.c:
|
||||
* ext/metadata/metadataparsexmp.h:
|
||||
Added support for PNG/XMP. Indentation. And fixed pull mode to parse
|
||||
the file.
|
||||
|
||||
2007-11-02 Edgard Lima <edgard.lima@indt.org.br>
|
||||
|
||||
* ext/metadata/gstmetadataparse.c: (gst_metadata_parse_init),
|
||||
|
|
|
@ -4,6 +4,7 @@ libgstmetadata_la_SOURCES = gstmetadata.c \
|
|||
gstmetadataparse.c \
|
||||
metadataparse.c \
|
||||
metadataparsejpeg.c \
|
||||
metadataparsepng.c \
|
||||
metadataparseexif.c \
|
||||
metadataparseiptc.c \
|
||||
metadataparsexmp.c \
|
||||
|
@ -16,6 +17,7 @@ libgstmetadata_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
|||
noinst_HEADERS = gstmetadataparse.h \
|
||||
metadataparse.h \
|
||||
metadataparsejpeg.h \
|
||||
metadataparsepng.h \
|
||||
metadataparseexif.h \
|
||||
metadataparseiptc.h \
|
||||
metadataparsexmp.h \
|
||||
|
|
|
@ -146,6 +146,8 @@ static gboolean gst_metadata_parse_activate (GstPad * pad);
|
|||
static gboolean
|
||||
gst_metadata_parse_element_activate_src_pull (GstPad * pad, gboolean active);
|
||||
|
||||
static gboolean gst_metadata_parse_pull_range_parse (GstMetadataParse * filter);
|
||||
|
||||
static void gst_metadata_parse_init_members (GstMetadataParse * filter);
|
||||
static void gst_metadata_parse_dispose_members (GstMetadataParse * filter);
|
||||
|
||||
|
@ -486,7 +488,7 @@ gst_metadata_parse_dispose_members (GstMetadataParse * filter)
|
|||
static void
|
||||
gst_metadata_parse_init_members (GstMetadataParse * filter)
|
||||
{
|
||||
filter->need_send_tag = TRUE;
|
||||
filter->need_send_tag = FALSE;
|
||||
filter->exif = TRUE;
|
||||
filter->iptc = TRUE;
|
||||
filter->xmp = TRUE;
|
||||
|
@ -708,6 +710,7 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
|
|||
} else {
|
||||
filter->state = MT_STATE_PARSED;
|
||||
filter->need_more_data = FALSE;
|
||||
filter->need_send_tag = TRUE;
|
||||
}
|
||||
|
||||
if (filter->img_type != PARSE_DATA_IMG_TYPE (filter->parse_data)) {
|
||||
|
@ -807,22 +810,14 @@ done:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_metadata_parse_activate (GstPad * pad)
|
||||
gst_metadata_parse_pull_range_parse (GstMetadataParse * filter)
|
||||
{
|
||||
GstMetadataParse *filter = NULL;
|
||||
|
||||
int res;
|
||||
gboolean ret = TRUE;
|
||||
guint32 offset = 0;
|
||||
gint64 duration = 0;
|
||||
GstFormat format = GST_FORMAT_BYTES;
|
||||
int res;
|
||||
guint32 offset = 0;
|
||||
|
||||
filter = GST_METADATA_PARSE (GST_PAD_PARENT (pad));
|
||||
|
||||
if (!gst_pad_check_pull_range (pad) ||
|
||||
!gst_pad_activate_pull (filter->sinkpad, TRUE)) {
|
||||
/* nothing to be done by now, activate push mode */
|
||||
return gst_pad_activate_push (pad, TRUE);
|
||||
}
|
||||
|
||||
if (!(ret =
|
||||
gst_pad_query_peer_duration (filter->sinkpad, &format, &duration))) {
|
||||
|
@ -836,7 +831,6 @@ gst_metadata_parse_activate (GstPad * pad)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* try to parse */
|
||||
do {
|
||||
GstFlowReturn flow;
|
||||
GstBuffer *buf = NULL;
|
||||
|
@ -870,6 +864,32 @@ gst_metadata_parse_activate (GstPad * pad)
|
|||
|
||||
} while (res > 0);
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_metadata_parse_activate (GstPad * pad)
|
||||
{
|
||||
GstMetadataParse *filter = NULL;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
|
||||
filter = GST_METADATA_PARSE (GST_PAD_PARENT (pad));
|
||||
|
||||
if (!gst_pad_check_pull_range (pad) ||
|
||||
!gst_pad_activate_pull (filter->sinkpad, TRUE)) {
|
||||
/* nothing to be done by now, activate push mode */
|
||||
return gst_pad_activate_push (pad, TRUE);
|
||||
}
|
||||
|
||||
/* try to parse */
|
||||
if (filter->state == MT_STATE_NULL) {
|
||||
ret = gst_metadata_parse_pull_range_parse (filter);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (ret) {
|
||||
|
@ -911,6 +931,10 @@ gst_metadata_parse_element_activate_src_pull (GstPad * pad, gboolean active)
|
|||
|
||||
ret = gst_pad_activate_pull (filter->sinkpad, active);
|
||||
|
||||
if (ret && filter->state == MT_STATE_NULL) {
|
||||
ret = gst_metadata_parse_pull_range_parse (filter);
|
||||
}
|
||||
|
||||
gst_object_unref (filter);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "metadataparse.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* #defines don't like whitespacey bits */
|
||||
#define GST_TYPE_METADATA_PARSE \
|
||||
(gst_metadata_parse_get_type())
|
||||
|
@ -61,13 +60,12 @@ G_BEGIN_DECLS
|
|||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_METADATA_PARSE))
|
||||
#define GST_IS_METADATA_PARSE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_METADATA_PARSE))
|
||||
|
||||
typedef struct _GstMetadataParse GstMetadataParse;
|
||||
typedef struct _GstMetadataParse GstMetadataParse;
|
||||
typedef struct _GstMetadataParseClass GstMetadataParseClass;
|
||||
|
||||
typedef enum _tag_MetadataState {
|
||||
MT_STATE_NULL, /* still need to check media type */
|
||||
MT_STATE_READING,
|
||||
typedef enum _tag_MetadataState
|
||||
{
|
||||
MT_STATE_NULL, /* still need to check media type */
|
||||
MT_STATE_PARSED
|
||||
} MetadataState;
|
||||
|
||||
|
@ -85,7 +83,7 @@ struct _GstMetadataParse
|
|||
|
||||
GstTagList *taglist;
|
||||
ParseData parse_data;
|
||||
GstAdapter * adapter;
|
||||
GstAdapter *adapter;
|
||||
guint32 next_offset;
|
||||
guint32 next_size;
|
||||
ImageType img_type;
|
||||
|
@ -98,17 +96,14 @@ struct _GstMetadataParse
|
|||
|
||||
};
|
||||
|
||||
struct _GstMetadataParseClass
|
||||
struct _GstMetadataParseClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
extern GType
|
||||
gst_metadata_parse_get_type (void);
|
||||
extern GType gst_metadata_parse_get_type (void);
|
||||
|
||||
extern gboolean
|
||||
gst_metadata_parse_plugin_init (GstPlugin * plugin);
|
||||
extern gboolean gst_metadata_parse_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_METADATA_PARSE_H__ */
|
||||
|
|
|
@ -43,9 +43,6 @@
|
|||
|
||||
#include "metadataparse.h"
|
||||
|
||||
#include "metadataparsejpeg.h"
|
||||
|
||||
|
||||
/*
|
||||
*static declarations
|
||||
*/
|
||||
|
@ -103,7 +100,9 @@ metadataparse_parse (ParseData * parse_data, const guint8 * buf,
|
|||
(guint8 *) buf, &bufsize, &next_start, next_size);
|
||||
break;
|
||||
case IMG_PNG:
|
||||
ret = 0;
|
||||
ret =
|
||||
metadataparse_png_parse (&parse_data->format_data.png,
|
||||
(guint8 *) buf, &bufsize, &next_start, next_size);
|
||||
break;
|
||||
default:
|
||||
/* unexpected */
|
||||
|
@ -131,6 +130,9 @@ metadataparse_dispose (ParseData * parse_data)
|
|||
case IMG_JPEG:
|
||||
metadataparse_jpeg_dispose (&parse_data->format_data.jpeg);
|
||||
break;
|
||||
case IMG_PNG:
|
||||
metadataparse_png_dispose (&parse_data->format_data.png);
|
||||
break;
|
||||
}
|
||||
|
||||
if (parse_data->adpt_xmp) {
|
||||
|
@ -169,13 +171,12 @@ metadataparse_parse_none (ParseData * parse_data, const guint8 * buf,
|
|||
|
||||
parse_data->img_type = IMG_NONE;
|
||||
|
||||
if (*bufsize < 4) {
|
||||
*next_size = 4;
|
||||
if (*bufsize < 3) {
|
||||
*next_size = 3;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (parse_data->option & PARSE_OPT_EXIF)
|
||||
adpt_exif = &parse_data->adpt_exif;
|
||||
if (parse_data->option & PARSE_OPT_IPTC)
|
||||
|
@ -186,12 +187,25 @@ metadataparse_parse_none (ParseData * parse_data, const guint8 * buf,
|
|||
if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF) {
|
||||
metadataparse_jpeg_init (&parse_data->format_data.jpeg, adpt_exif,
|
||||
adpt_iptc, adpt_xmp);
|
||||
ret = 0;
|
||||
parse_data->img_type = IMG_JPEG;
|
||||
} else if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4e
|
||||
&& buf[3] == 0x47) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (*bufsize < 8) {
|
||||
*next_size = 8;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47 &&
|
||||
buf[4] == 0x0D && buf[5] == 0x0A && buf[6] == 0x1A && buf[7] == 0x0A) {
|
||||
metadataparse_png_init (&parse_data->format_data.png, adpt_exif,
|
||||
adpt_iptc, adpt_xmp);
|
||||
ret = 0;
|
||||
parse_data->img_type = IMG_PNG;
|
||||
} else
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
|
|
|
@ -47,35 +47,41 @@
|
|||
#include <gst/base/gstadapter.h>
|
||||
|
||||
#include "metadataparsejpeg.h"
|
||||
#include "metadataparsepng.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum _tag_ParseOption {
|
||||
typedef enum _tag_ParseOption
|
||||
{
|
||||
PARSE_OPT_EXIF = (1 << 0),
|
||||
PARSE_OPT_IPTC = (1 << 1),
|
||||
PARSE_OPT_XMP = (1 << 2),
|
||||
PARSE_OPT_ALL = (1 << 3) -1
|
||||
PARSE_OPT_XMP = (1 << 2),
|
||||
PARSE_OPT_ALL = (1 << 3) - 1
|
||||
} ParseOption;
|
||||
|
||||
typedef enum _tag_ParseState {
|
||||
typedef enum _tag_ParseState
|
||||
{
|
||||
STATE_NULL,
|
||||
STATE_READING,
|
||||
STATE_DONE
|
||||
} ParseState;
|
||||
|
||||
typedef enum _tag_ImageType {
|
||||
typedef enum _tag_ImageType
|
||||
{
|
||||
IMG_NONE,
|
||||
IMG_JPEG,
|
||||
IMG_PNG
|
||||
} ImageType;
|
||||
|
||||
|
||||
typedef struct _tag_ParseData {
|
||||
typedef struct _tag_ParseData
|
||||
{
|
||||
ParseState state;
|
||||
ImageType img_type;
|
||||
ImageType img_type;
|
||||
ParseOption option;
|
||||
union {
|
||||
union
|
||||
{
|
||||
JpegData jpeg;
|
||||
PngData png;
|
||||
} format_data;
|
||||
GstAdapter *adpt_exif;
|
||||
GstAdapter *adpt_iptc;
|
||||
|
@ -87,8 +93,7 @@ typedef struct _tag_ParseData {
|
|||
#define set_parse_option(p, m) do { (p).option = (p).option | (m); } while(FALSE)
|
||||
#define unset_parse_option(p, m) do { (p).option = (p).option & ~(m); } while(FALSE)
|
||||
|
||||
extern void
|
||||
metadataparse_init(ParseData *parse_data);
|
||||
extern void metadataparse_init (ParseData * parse_data);
|
||||
|
||||
/*
|
||||
* offset: number of bytes to jump (just a hint to jump a chunk)
|
||||
|
@ -98,12 +103,11 @@ metadataparse_init(ParseData *parse_data);
|
|||
* 1 -> need more data
|
||||
*/
|
||||
extern int
|
||||
metadataparse_parse(ParseData *parse_data, const guint8 *buf, guint32 bufsize, guint32 * next_offset, guint32 * next_size);
|
||||
metadataparse_parse (ParseData * parse_data, const guint8 * buf,
|
||||
guint32 bufsize, guint32 * next_offset, guint32 * next_size);
|
||||
|
||||
|
||||
extern void
|
||||
metadataparse_dispose(ParseData *parse_data);
|
||||
extern void metadataparse_dispose (ParseData * parse_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __METADATAPARSE_H__ */
|
||||
|
|
|
@ -65,7 +65,7 @@ metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
|
||||
GST_LOG ("EXIF not defined, here I should send just one tag as whole chunk");
|
||||
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, adapter);
|
||||
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
}
|
||||
|
||||
/* add chunk tag */
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, adapter);
|
||||
|
||||
buf = gst_adapter_peek (adapter, size);
|
||||
|
||||
|
|
|
@ -48,13 +48,11 @@
|
|||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
extern void
|
||||
metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
||||
GstAdapter * adapter);
|
||||
|
||||
extern void
|
||||
metadataparse_exif_tag_list_add (GstTagList *taglist, GstTagMergeMode mode, GstAdapter * adapter);
|
||||
|
||||
extern void
|
||||
metadataparse_exif_tags_register (void);
|
||||
extern void metadataparse_exif_tags_register (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_METADATAPARSE_EXIF_H__ */
|
||||
|
|
|
@ -65,7 +65,7 @@ metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
|
||||
GST_LOG ("IPTC not defined, here I should send just one tag as whole chunk");
|
||||
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, adapter);
|
||||
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
}
|
||||
|
||||
/* add chunk tag */
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, adapter);
|
||||
|
||||
buf = gst_adapter_peek (adapter, size);
|
||||
|
||||
|
|
|
@ -50,11 +50,10 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
extern void
|
||||
metadataparse_iptc_tag_list_add (GstTagList *taglist, GstTagMergeMode mode, GstAdapter * adapter);
|
||||
metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
||||
GstAdapter * adapter);
|
||||
|
||||
extern void
|
||||
metadataparse_iptc_tags_register (void);
|
||||
extern void metadataparse_iptc_tags_register (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_METADATAPARSE_IPTC_H__ */
|
||||
|
|
|
@ -51,12 +51,6 @@ static int
|
|||
metadataparse_jpeg_reading (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
|
||||
static int
|
||||
metadataparse_jpeg_hold_chunk (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start,
|
||||
guint32 * next_size, GstAdapter ** adapter);
|
||||
|
||||
static int
|
||||
metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
@ -245,7 +239,9 @@ metadataparse_jpeg_reading (JpegData * jpeg_data, guint8 ** buf,
|
|||
|
||||
if (jpeg_data->adpt_xmp) {
|
||||
if (0 == memcmp (XmpHeader, *buf, 29)) {
|
||||
jpeg_data->read = chunk_size - 2;
|
||||
*buf += 29;
|
||||
*bufsize -= 29;
|
||||
jpeg_data->read = chunk_size - 2 - 29;
|
||||
ret = 0;
|
||||
jpeg_data->state = JPEG_XMP;
|
||||
goto done;
|
||||
|
@ -291,44 +287,18 @@ done:
|
|||
|
||||
}
|
||||
|
||||
static int
|
||||
metadataparse_jpeg_hold_chunk (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start,
|
||||
guint32 * next_size, GstAdapter ** adapter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (jpeg_data->read > *bufsize) {
|
||||
*next_start = *buf;
|
||||
*next_size = jpeg_data->read;
|
||||
ret = 1;
|
||||
} else {
|
||||
GstBuffer *gst_buf;
|
||||
|
||||
if (NULL == *adapter) {
|
||||
*adapter = gst_adapter_new ();
|
||||
}
|
||||
gst_buf = gst_buffer_new_and_alloc (jpeg_data->read);
|
||||
memcpy (GST_BUFFER_DATA (gst_buf), *buf, jpeg_data->read);
|
||||
gst_adapter_push (*adapter, gst_buf);
|
||||
|
||||
*next_start = *buf + jpeg_data->read;
|
||||
*buf += jpeg_data->read;
|
||||
*bufsize -= jpeg_data->read;
|
||||
jpeg_data->state = JPEG_READING;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
return metadataparse_jpeg_hold_chunk (jpeg_data, buf,
|
||||
ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf,
|
||||
bufsize, next_start, next_size, jpeg_data->adpt_exif);
|
||||
if (ret == 0) {
|
||||
jpeg_data->state = JPEG_READING;
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
@ -339,7 +309,7 @@ metadataparse_jpeg_iptc (JpegData * jpeg_data, guint8 ** buf,
|
|||
|
||||
int ret;
|
||||
|
||||
ret = metadataparse_jpeg_hold_chunk (jpeg_data, buf,
|
||||
ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf,
|
||||
bufsize, next_start, next_size, jpeg_data->adpt_iptc);
|
||||
|
||||
|
||||
|
@ -350,6 +320,8 @@ metadataparse_jpeg_iptc (JpegData * jpeg_data, guint8 ** buf,
|
|||
unsigned int iptc_len;
|
||||
int res;
|
||||
|
||||
jpeg_data->state = JPEG_READING;
|
||||
|
||||
size = gst_adapter_available (*jpeg_data->adpt_iptc);
|
||||
buf = gst_adapter_peek (*jpeg_data->adpt_iptc, size);
|
||||
|
||||
|
@ -383,32 +355,22 @@ static int
|
|||
metadataparse_jpeg_xmp (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
return metadataparse_jpeg_hold_chunk (jpeg_data, buf,
|
||||
ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf,
|
||||
bufsize, next_start, next_size, jpeg_data->adpt_xmp);
|
||||
|
||||
if (ret == 0) {
|
||||
jpeg_data->state = JPEG_READING;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
metadataparse_jpeg_jump (JpegData * jpeg_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (jpeg_data->read > *bufsize) {
|
||||
jpeg_data->read -= *bufsize;
|
||||
*next_size = 2;
|
||||
*next_start = *buf + *bufsize + jpeg_data->read;
|
||||
jpeg_data->read = 0;
|
||||
*bufsize = 0;
|
||||
jpeg_data->state = JPEG_READING;
|
||||
ret = 1;
|
||||
} else {
|
||||
*next_start = *buf + jpeg_data->read;
|
||||
*buf += jpeg_data->read;
|
||||
*bufsize -= jpeg_data->read;
|
||||
jpeg_data->state = JPEG_READING;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
jpeg_data->state = JPEG_READING;
|
||||
return metadataparse_util_jump_chunk (&jpeg_data->read, buf,
|
||||
bufsize, next_start, next_size);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum _tag_JpegState {
|
||||
typedef enum _tag_JpegState
|
||||
{
|
||||
JPEG_NULL,
|
||||
JPEG_READING,
|
||||
JPEG_JUMPING,
|
||||
|
@ -59,7 +60,8 @@ typedef enum _tag_JpegState {
|
|||
} JpegState;
|
||||
|
||||
|
||||
typedef struct _tag_JpegData {
|
||||
typedef struct _tag_JpegData
|
||||
{
|
||||
JpegState state;
|
||||
GstAdapter **adpt_exif;
|
||||
GstAdapter **adpt_iptc;
|
||||
|
@ -69,17 +71,15 @@ typedef struct _tag_JpegData {
|
|||
|
||||
|
||||
extern void
|
||||
metadataparse_jpeg_init(JpegData *jpeg_data, GstAdapter **adpt_exif, GstAdapter **adpt_iptc, GstAdapter **adpt_xmp);
|
||||
metadataparse_jpeg_init (JpegData * jpeg_data, GstAdapter ** adpt_exif,
|
||||
GstAdapter ** adpt_iptc, GstAdapter ** adpt_xmp);
|
||||
|
||||
extern void
|
||||
metadataparse_jpeg_dispose(JpegData *jpeg_data);
|
||||
extern void metadataparse_jpeg_dispose (JpegData * jpeg_data);
|
||||
|
||||
|
||||
int
|
||||
metadataparse_jpeg_parse(JpegData *jpeg_data, guint8 *buf,
|
||||
guint32 *bufsize, guint8 ** next_start,
|
||||
guint32 * next_size);
|
||||
metadataparse_jpeg_parse (JpegData * jpeg_data, guint8 * buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __METADATAPARSE_JPEG_H__ */
|
||||
|
|
245
ext/metadata/metadataparsepng.c
Normal file
245
ext/metadata/metadataparsepng.c
Normal file
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright 2007 Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
|
||||
* which case the following provisions apply instead of the ones
|
||||
* mentioned above:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "metadataparsepng.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static int
|
||||
metadataparse_png_reading (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
static int
|
||||
metadataparse_png_xmp (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
static int
|
||||
metadataparse_png_jump (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
#define READ(buf, size) ( (size)--, *((buf)++) )
|
||||
|
||||
void
|
||||
metadataparse_png_init (PngData * png_data, GstAdapter ** adpt_exif,
|
||||
GstAdapter ** adpt_iptc, GstAdapter ** adpt_xmp)
|
||||
{
|
||||
png_data->state = PNG_NULL;
|
||||
png_data->adpt_xmp = adpt_xmp;
|
||||
png_data->read = 0;
|
||||
|
||||
metadataparse_xmp_init ();
|
||||
}
|
||||
|
||||
void
|
||||
metadataparse_png_dispose (PngData * png_data)
|
||||
{
|
||||
metadataparse_xmp_dispose ();
|
||||
|
||||
png_data->adpt_xmp = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
metadataparse_png_parse (PngData * png_data, guint8 * buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
guint8 mark[8];
|
||||
|
||||
*next_start = buf;
|
||||
|
||||
if (png_data->state == PNG_NULL) {
|
||||
|
||||
if (*bufsize < 8) {
|
||||
*next_size = (buf - *next_start) + 8;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mark[0] = READ (buf, *bufsize);
|
||||
mark[1] = READ (buf, *bufsize);
|
||||
mark[2] = READ (buf, *bufsize);
|
||||
mark[3] = READ (buf, *bufsize);
|
||||
mark[4] = READ (buf, *bufsize);
|
||||
mark[5] = READ (buf, *bufsize);
|
||||
mark[6] = READ (buf, *bufsize);
|
||||
mark[7] = READ (buf, *bufsize);
|
||||
|
||||
if (mark[0] != 0x89 || mark[1] != 0x50 || mark[2] != 0x4E || mark[3] != 0x47
|
||||
|| mark[4] != 0x0D || mark[5] != 0x0A || mark[6] != 0x1A
|
||||
|| mark[7] != 0x0A) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
png_data->state = PNG_READING;
|
||||
|
||||
}
|
||||
|
||||
while (ret == 0) {
|
||||
switch (png_data->state) {
|
||||
case PNG_READING:
|
||||
ret =
|
||||
metadataparse_png_reading (png_data, &buf, bufsize, next_start,
|
||||
next_size);
|
||||
break;
|
||||
case PNG_JUMPING:
|
||||
ret =
|
||||
metadataparse_png_jump (png_data, &buf, bufsize, next_start,
|
||||
next_size);
|
||||
break;
|
||||
case PNG_XMP:
|
||||
ret =
|
||||
metadataparse_png_xmp (png_data, &buf, bufsize, next_start,
|
||||
next_size);
|
||||
break;
|
||||
case PNG_DONE:
|
||||
goto done;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* look for markers */
|
||||
static int
|
||||
metadataparse_png_reading (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
|
||||
int ret = -1;
|
||||
guint8 mark[4];
|
||||
guint32 chunk_size = 0;
|
||||
|
||||
static const char XmpHeader[] = "XML:com.adobe.xmp";
|
||||
|
||||
*next_start = *buf;
|
||||
|
||||
if (*bufsize < 8) {
|
||||
*next_size = (*buf - *next_start) + 8;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
chunk_size = READ (*buf, *bufsize) << 24;
|
||||
chunk_size += READ (*buf, *bufsize) << 16;
|
||||
chunk_size += READ (*buf, *bufsize) << 8;
|
||||
chunk_size += READ (*buf, *bufsize);
|
||||
|
||||
mark[0] = READ (*buf, *bufsize);
|
||||
mark[1] = READ (*buf, *bufsize);
|
||||
mark[2] = READ (*buf, *bufsize);
|
||||
mark[3] = READ (*buf, *bufsize);
|
||||
|
||||
if (mark[0] == 'I' && mark[1] == 'E' && mark[2] == 'N' && mark[3] == 'D') {
|
||||
ret = 0;
|
||||
png_data->state = PNG_DONE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mark[0] == 'i' && mark[1] == 'T' && mark[2] == 'X' && mark[3] == 't') {
|
||||
if (chunk_size >= 22) { /* "XML:com.adobe.xmp" plus some flags */
|
||||
if (*bufsize < 22) {
|
||||
*next_size = (*buf - *next_start) + 22;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (png_data->adpt_xmp) {
|
||||
if (0 == memcmp (XmpHeader, *buf, 18)) {
|
||||
*buf += 22; /* jump "XML:com.adobe.xmp" plus some flags */
|
||||
*bufsize -= 22;
|
||||
png_data->read = chunk_size - 22; /* four CRC bytes at the end will be jumped after */
|
||||
png_data->state = PNG_XMP;
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* just set jump sise */
|
||||
png_data->read = chunk_size + 4; /* four CRC bytes at the end */
|
||||
png_data->state = PNG_JUMPING;
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
metadataparse_png_jump (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
png_data->state = PNG_READING;
|
||||
return metadataparse_util_jump_chunk (&png_data->read, buf,
|
||||
bufsize, next_start, next_size);
|
||||
}
|
||||
|
||||
static int
|
||||
metadataparse_png_xmp (PngData * png_data, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = metadataparse_util_hold_chunk (&png_data->read, buf,
|
||||
bufsize, next_start, next_size, png_data->adpt_xmp);
|
||||
if (ret == 0) {
|
||||
/* jump four CRC bytes at the end of chunk */
|
||||
png_data->read = 4;
|
||||
png_data->state = PNG_JUMPING;
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
81
ext/metadata/metadataparsepng.h
Normal file
81
ext/metadata/metadataparsepng.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright 2007 Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
|
||||
* which case the following provisions apply instead of the ones
|
||||
* mentioned above:
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __METADATAPARSE_PNG_H__
|
||||
#define __METADATAPARSE_PNG_H__
|
||||
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum _tag_PngState
|
||||
{
|
||||
PNG_NULL,
|
||||
PNG_READING,
|
||||
PNG_JUMPING,
|
||||
PNG_XMP,
|
||||
PNG_DONE
|
||||
} PngState;
|
||||
|
||||
|
||||
typedef struct _tag_PngData
|
||||
{
|
||||
PngState state;
|
||||
GstAdapter **adpt_xmp;
|
||||
guint32 read;
|
||||
} PngData;
|
||||
|
||||
|
||||
extern void
|
||||
metadataparse_png_init (PngData * png_data, GstAdapter ** adpt_exif,
|
||||
GstAdapter ** adpt_iptc, GstAdapter ** adpt_xmp);
|
||||
|
||||
extern void metadataparse_png_dispose (PngData * png_data);
|
||||
|
||||
|
||||
int
|
||||
metadataparse_png_parse (PngData * png_data, guint8 * buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __METADATAPARSE_PNG_H__ */
|
|
@ -44,8 +44,8 @@
|
|||
#include "metadataparseutil.h"
|
||||
|
||||
void
|
||||
metadataparse_tag_list_add_chunk (GstTagList * taglist, GstTagMergeMode mode,
|
||||
const gchar * name, GstAdapter * adapter)
|
||||
metadataparse_util_tag_list_add_chunk (GstTagList * taglist,
|
||||
GstTagMergeMode mode, const gchar * name, GstAdapter * adapter)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
guint size;
|
||||
|
@ -62,3 +62,57 @@ metadataparse_tag_list_add_chunk (GstTagList * taglist, GstTagMergeMode mode,
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
metadataparse_util_hold_chunk (guint32 * read, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start,
|
||||
guint32 * next_size, GstAdapter ** adapter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (*read > *bufsize) {
|
||||
*next_start = *buf;
|
||||
*next_size = *read;
|
||||
ret = 1;
|
||||
} else {
|
||||
GstBuffer *gst_buf;
|
||||
|
||||
if (NULL == *adapter) {
|
||||
*adapter = gst_adapter_new ();
|
||||
}
|
||||
gst_buf = gst_buffer_new_and_alloc (*read);
|
||||
memcpy (GST_BUFFER_DATA (gst_buf), *buf, *read);
|
||||
gst_adapter_push (*adapter, gst_buf);
|
||||
|
||||
*next_start = *buf + *read;
|
||||
*buf += *read;
|
||||
*bufsize -= *read;
|
||||
*read = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
metadataparse_util_jump_chunk (guint32 * read, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (*read > *bufsize) {
|
||||
*read -= *bufsize;
|
||||
*next_size = 2;
|
||||
*next_start = *buf + *bufsize + *read;
|
||||
*read = 0;
|
||||
*bufsize = 0;
|
||||
ret = 1;
|
||||
} else {
|
||||
*next_start = *buf + *read;
|
||||
*buf += *read;
|
||||
*bufsize -= *read;
|
||||
*read = 0;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -50,9 +50,15 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
extern void
|
||||
metadataparse_tag_list_add_chunk (GstTagList * taglist, GstTagMergeMode mode,
|
||||
const gchar * name, GstAdapter * adapter);
|
||||
metadataparse_util_tag_list_add_chunk (GstTagList * taglist,
|
||||
GstTagMergeMode mode, const gchar * name, GstAdapter * adapter);
|
||||
extern int metadataparse_util_hold_chunk (guint32 * read, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size,
|
||||
GstAdapter ** adapter);
|
||||
|
||||
extern int
|
||||
metadataparse_util_jump_chunk (guint32 * read, guint8 ** buf,
|
||||
guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_METADATAPARSE_UTIL_H__ */
|
||||
|
|
|
@ -65,7 +65,7 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
|
||||
GST_LOG ("XMP not defined, here I should send just one tag as whole chunk");
|
||||
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter);
|
||||
|
||||
}
|
||||
|
||||
|
@ -111,13 +111,10 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
}
|
||||
|
||||
/* add chunk tag */
|
||||
metadataparse_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter);
|
||||
metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter);
|
||||
|
||||
buf = gst_adapter_peek (adapter, size);
|
||||
|
||||
buf += 29; /* jump "http://ns.adobe.com/xap/1.0/" */
|
||||
size -= 29;
|
||||
|
||||
xmp = xmp_new (buf, size);
|
||||
if (!xmp)
|
||||
goto done;
|
||||
|
@ -128,7 +125,6 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
|||
|
||||
xmp_serialize (xmp, xmp_str, XMP_SERIAL_ENCODEUTF8, 2);
|
||||
|
||||
|
||||
GST_LOG (xmp_string_cstr (xmp_str));
|
||||
|
||||
done:
|
||||
|
|
|
@ -50,17 +50,14 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
extern void
|
||||
metadataparse_xmp_tag_list_add (GstTagList *taglist, GstTagMergeMode mode, GstAdapter * adapter);
|
||||
metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
|
||||
GstAdapter * adapter);
|
||||
|
||||
extern gboolean
|
||||
metadataparse_xmp_init(void);
|
||||
extern gboolean metadataparse_xmp_init (void);
|
||||
|
||||
extern void
|
||||
metadataparse_xmp_dispose(void);
|
||||
extern void metadataparse_xmp_dispose (void);
|
||||
|
||||
extern void
|
||||
metadataparse_xmp_tags_register (void);
|
||||
extern void metadataparse_xmp_tags_register (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_METADATAPARSE_XMP_H__ */
|
||||
|
|
Loading…
Reference in a new issue