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:
Edgard Lima 2007-11-02 16:50:42 +00:00
parent 05e1fdf681
commit f17824d0d1
18 changed files with 553 additions and 154 deletions

View file

@ -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> 2007-11-02 Edgard Lima <edgard.lima@indt.org.br>
* ext/metadata/gstmetadataparse.c: (gst_metadata_parse_init), * ext/metadata/gstmetadataparse.c: (gst_metadata_parse_init),

View file

@ -4,6 +4,7 @@ libgstmetadata_la_SOURCES = gstmetadata.c \
gstmetadataparse.c \ gstmetadataparse.c \
metadataparse.c \ metadataparse.c \
metadataparsejpeg.c \ metadataparsejpeg.c \
metadataparsepng.c \
metadataparseexif.c \ metadataparseexif.c \
metadataparseiptc.c \ metadataparseiptc.c \
metadataparsexmp.c \ metadataparsexmp.c \
@ -16,6 +17,7 @@ libgstmetadata_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstmetadataparse.h \ noinst_HEADERS = gstmetadataparse.h \
metadataparse.h \ metadataparse.h \
metadataparsejpeg.h \ metadataparsejpeg.h \
metadataparsepng.h \
metadataparseexif.h \ metadataparseexif.h \
metadataparseiptc.h \ metadataparseiptc.h \
metadataparsexmp.h \ metadataparsexmp.h \

View file

@ -146,6 +146,8 @@ static gboolean gst_metadata_parse_activate (GstPad * pad);
static gboolean static gboolean
gst_metadata_parse_element_activate_src_pull (GstPad * pad, gboolean active); 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_init_members (GstMetadataParse * filter);
static void gst_metadata_parse_dispose_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 static void
gst_metadata_parse_init_members (GstMetadataParse * filter) gst_metadata_parse_init_members (GstMetadataParse * filter)
{ {
filter->need_send_tag = TRUE; filter->need_send_tag = FALSE;
filter->exif = TRUE; filter->exif = TRUE;
filter->iptc = TRUE; filter->iptc = TRUE;
filter->xmp = TRUE; filter->xmp = TRUE;
@ -708,6 +710,7 @@ gst_metadata_parse_parse (GstMetadataParse * filter, const guint8 * buf,
} else { } else {
filter->state = MT_STATE_PARSED; filter->state = MT_STATE_PARSED;
filter->need_more_data = FALSE; filter->need_more_data = FALSE;
filter->need_send_tag = TRUE;
} }
if (filter->img_type != PARSE_DATA_IMG_TYPE (filter->parse_data)) { if (filter->img_type != PARSE_DATA_IMG_TYPE (filter->parse_data)) {
@ -807,22 +810,14 @@ done:
} }
static gboolean static gboolean
gst_metadata_parse_activate (GstPad * pad) gst_metadata_parse_pull_range_parse (GstMetadataParse * filter)
{ {
GstMetadataParse *filter = NULL;
int res;
gboolean ret = TRUE; gboolean ret = TRUE;
guint32 offset = 0;
gint64 duration = 0; gint64 duration = 0;
GstFormat format = GST_FORMAT_BYTES; 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 = if (!(ret =
gst_pad_query_peer_duration (filter->sinkpad, &format, &duration))) { gst_pad_query_peer_duration (filter->sinkpad, &format, &duration))) {
@ -836,7 +831,6 @@ gst_metadata_parse_activate (GstPad * pad)
goto done; goto done;
} }
/* try to parse */
do { do {
GstFlowReturn flow; GstFlowReturn flow;
GstBuffer *buf = NULL; GstBuffer *buf = NULL;
@ -870,6 +864,32 @@ gst_metadata_parse_activate (GstPad * pad)
} while (res > 0); } 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: done:
if (ret) { 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); 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); gst_object_unref (filter);
return ret; return ret;

View file

@ -49,7 +49,6 @@
#include "metadataparse.h" #include "metadataparse.h"
G_BEGIN_DECLS G_BEGIN_DECLS
/* #defines don't like whitespacey bits */ /* #defines don't like whitespacey bits */
#define GST_TYPE_METADATA_PARSE \ #define GST_TYPE_METADATA_PARSE \
(gst_metadata_parse_get_type()) (gst_metadata_parse_get_type())
@ -61,13 +60,12 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_METADATA_PARSE)) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_METADATA_PARSE))
#define GST_IS_METADATA_PARSE_CLASS(klass) \ #define GST_IS_METADATA_PARSE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_METADATA_PARSE)) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_METADATA_PARSE))
typedef struct _GstMetadataParse GstMetadataParse;
typedef struct _GstMetadataParse GstMetadataParse;
typedef struct _GstMetadataParseClass GstMetadataParseClass; typedef struct _GstMetadataParseClass GstMetadataParseClass;
typedef enum _tag_MetadataState { typedef enum _tag_MetadataState
MT_STATE_NULL, /* still need to check media type */ {
MT_STATE_READING, MT_STATE_NULL, /* still need to check media type */
MT_STATE_PARSED MT_STATE_PARSED
} MetadataState; } MetadataState;
@ -85,7 +83,7 @@ struct _GstMetadataParse
GstTagList *taglist; GstTagList *taglist;
ParseData parse_data; ParseData parse_data;
GstAdapter * adapter; GstAdapter *adapter;
guint32 next_offset; guint32 next_offset;
guint32 next_size; guint32 next_size;
ImageType img_type; ImageType img_type;
@ -103,12 +101,9 @@ struct _GstMetadataParseClass
GstElementClass parent_class; GstElementClass parent_class;
}; };
extern GType extern GType gst_metadata_parse_get_type (void);
gst_metadata_parse_get_type (void);
extern gboolean extern gboolean gst_metadata_parse_plugin_init (GstPlugin * plugin);
gst_metadata_parse_plugin_init (GstPlugin * plugin);
G_END_DECLS G_END_DECLS
#endif /* __GST_METADATA_PARSE_H__ */ #endif /* __GST_METADATA_PARSE_H__ */

View file

@ -43,9 +43,6 @@
#include "metadataparse.h" #include "metadataparse.h"
#include "metadataparsejpeg.h"
/* /*
*static declarations *static declarations
*/ */
@ -103,7 +100,9 @@ metadataparse_parse (ParseData * parse_data, const guint8 * buf,
(guint8 *) buf, &bufsize, &next_start, next_size); (guint8 *) buf, &bufsize, &next_start, next_size);
break; break;
case IMG_PNG: case IMG_PNG:
ret = 0; ret =
metadataparse_png_parse (&parse_data->format_data.png,
(guint8 *) buf, &bufsize, &next_start, next_size);
break; break;
default: default:
/* unexpected */ /* unexpected */
@ -131,6 +130,9 @@ metadataparse_dispose (ParseData * parse_data)
case IMG_JPEG: case IMG_JPEG:
metadataparse_jpeg_dispose (&parse_data->format_data.jpeg); metadataparse_jpeg_dispose (&parse_data->format_data.jpeg);
break; break;
case IMG_PNG:
metadataparse_png_dispose (&parse_data->format_data.png);
break;
} }
if (parse_data->adpt_xmp) { if (parse_data->adpt_xmp) {
@ -169,13 +171,12 @@ metadataparse_parse_none (ParseData * parse_data, const guint8 * buf,
parse_data->img_type = IMG_NONE; parse_data->img_type = IMG_NONE;
if (*bufsize < 4) { if (*bufsize < 3) {
*next_size = 4; *next_size = 3;
ret = 1; ret = 1;
goto done; goto done;
} }
ret = 0;
if (parse_data->option & PARSE_OPT_EXIF) if (parse_data->option & PARSE_OPT_EXIF)
adpt_exif = &parse_data->adpt_exif; adpt_exif = &parse_data->adpt_exif;
if (parse_data->option & PARSE_OPT_IPTC) 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) { if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF) {
metadataparse_jpeg_init (&parse_data->format_data.jpeg, adpt_exif, metadataparse_jpeg_init (&parse_data->format_data.jpeg, adpt_exif,
adpt_iptc, adpt_xmp); adpt_iptc, adpt_xmp);
ret = 0;
parse_data->img_type = IMG_JPEG; parse_data->img_type = IMG_JPEG;
} else if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4e goto done;
&& buf[3] == 0x47) { }
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; parse_data->img_type = IMG_PNG;
} else goto done;
ret = -1; }
done: done:

View file

@ -47,35 +47,41 @@
#include <gst/base/gstadapter.h> #include <gst/base/gstadapter.h>
#include "metadataparsejpeg.h" #include "metadataparsejpeg.h"
#include "metadataparsepng.h"
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum _tag_ParseOption { typedef enum _tag_ParseOption
{
PARSE_OPT_EXIF = (1 << 0), PARSE_OPT_EXIF = (1 << 0),
PARSE_OPT_IPTC = (1 << 1), PARSE_OPT_IPTC = (1 << 1),
PARSE_OPT_XMP = (1 << 2), PARSE_OPT_XMP = (1 << 2),
PARSE_OPT_ALL = (1 << 3) -1 PARSE_OPT_ALL = (1 << 3) - 1
} ParseOption; } ParseOption;
typedef enum _tag_ParseState { typedef enum _tag_ParseState
{
STATE_NULL, STATE_NULL,
STATE_READING, STATE_READING,
STATE_DONE STATE_DONE
} ParseState; } ParseState;
typedef enum _tag_ImageType { typedef enum _tag_ImageType
{
IMG_NONE, IMG_NONE,
IMG_JPEG, IMG_JPEG,
IMG_PNG IMG_PNG
} ImageType; } ImageType;
typedef struct _tag_ParseData
typedef struct _tag_ParseData { {
ParseState state; ParseState state;
ImageType img_type; ImageType img_type;
ParseOption option; ParseOption option;
union { union
{
JpegData jpeg; JpegData jpeg;
PngData png;
} format_data; } format_data;
GstAdapter *adpt_exif; GstAdapter *adpt_exif;
GstAdapter *adpt_iptc; 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 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) #define unset_parse_option(p, m) do { (p).option = (p).option & ~(m); } while(FALSE)
extern void extern void metadataparse_init (ParseData * parse_data);
metadataparse_init(ParseData *parse_data);
/* /*
* offset: number of bytes to jump (just a hint to jump a chunk) * 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 * 1 -> need more data
*/ */
extern int 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 extern void metadataparse_dispose (ParseData * parse_data);
metadataparse_dispose(ParseData *parse_data);
G_END_DECLS G_END_DECLS
#endif /* __METADATAPARSE_H__ */ #endif /* __METADATAPARSE_H__ */

View file

@ -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"); 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 */ /* 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); buf = gst_adapter_peek (adapter, size);

View file

@ -48,13 +48,11 @@
#include <gst/base/gstadapter.h> #include <gst/base/gstadapter.h>
G_BEGIN_DECLS G_BEGIN_DECLS
extern void
metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
GstAdapter * adapter);
extern void extern void metadataparse_exif_tags_register (void);
metadataparse_exif_tag_list_add (GstTagList *taglist, GstTagMergeMode mode, GstAdapter * adapter);
extern void
metadataparse_exif_tags_register (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_METADATAPARSE_EXIF_H__ */ #endif /* __GST_METADATAPARSE_EXIF_H__ */

View file

@ -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"); 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 */ /* 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); buf = gst_adapter_peek (adapter, size);

View file

@ -50,11 +50,10 @@
G_BEGIN_DECLS G_BEGIN_DECLS
extern void 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 extern void metadataparse_iptc_tags_register (void);
metadataparse_iptc_tags_register (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_METADATAPARSE_IPTC_H__ */ #endif /* __GST_METADATAPARSE_IPTC_H__ */

View file

@ -51,12 +51,6 @@ static int
metadataparse_jpeg_reading (JpegData * jpeg_data, guint8 ** buf, metadataparse_jpeg_reading (JpegData * jpeg_data, guint8 ** buf,
guint32 * bufsize, guint8 ** next_start, guint32 * next_size); 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 static int
metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf, metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf,
guint32 * bufsize, guint8 ** next_start, guint32 * next_size); 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 (jpeg_data->adpt_xmp) {
if (0 == memcmp (XmpHeader, *buf, 29)) { 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; ret = 0;
jpeg_data->state = JPEG_XMP; jpeg_data->state = JPEG_XMP;
goto done; 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 static int
metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf, metadataparse_jpeg_exif (JpegData * jpeg_data, guint8 ** buf,
guint32 * bufsize, guint8 ** next_start, guint32 * next_size) 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); 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; 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); 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; unsigned int iptc_len;
int res; int res;
jpeg_data->state = JPEG_READING;
size = gst_adapter_available (*jpeg_data->adpt_iptc); size = gst_adapter_available (*jpeg_data->adpt_iptc);
buf = gst_adapter_peek (*jpeg_data->adpt_iptc, size); buf = gst_adapter_peek (*jpeg_data->adpt_iptc, size);
@ -383,32 +355,22 @@ static int
metadataparse_jpeg_xmp (JpegData * jpeg_data, guint8 ** buf, metadataparse_jpeg_xmp (JpegData * jpeg_data, guint8 ** buf,
guint32 * bufsize, guint8 ** next_start, guint32 * next_size) 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); bufsize, next_start, next_size, jpeg_data->adpt_xmp);
if (ret == 0) {
jpeg_data->state = JPEG_READING;
}
return ret;
} }
static int static int
metadataparse_jpeg_jump (JpegData * jpeg_data, guint8 ** buf, metadataparse_jpeg_jump (JpegData * jpeg_data, guint8 ** buf,
guint32 * bufsize, guint8 ** next_start, guint32 * next_size) guint32 * bufsize, guint8 ** next_start, guint32 * next_size)
{ {
int ret; jpeg_data->state = JPEG_READING;
return metadataparse_util_jump_chunk (&jpeg_data->read, buf,
if (jpeg_data->read > *bufsize) { bufsize, next_start, next_size);
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;
} }

View file

@ -48,7 +48,8 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum _tag_JpegState { typedef enum _tag_JpegState
{
JPEG_NULL, JPEG_NULL,
JPEG_READING, JPEG_READING,
JPEG_JUMPING, JPEG_JUMPING,
@ -59,7 +60,8 @@ typedef enum _tag_JpegState {
} JpegState; } JpegState;
typedef struct _tag_JpegData { typedef struct _tag_JpegData
{
JpegState state; JpegState state;
GstAdapter **adpt_exif; GstAdapter **adpt_exif;
GstAdapter **adpt_iptc; GstAdapter **adpt_iptc;
@ -69,17 +71,15 @@ typedef struct _tag_JpegData {
extern void 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 extern void metadataparse_jpeg_dispose (JpegData * jpeg_data);
metadataparse_jpeg_dispose(JpegData *jpeg_data);
int int
metadataparse_jpeg_parse(JpegData *jpeg_data, guint8 *buf, metadataparse_jpeg_parse (JpegData * jpeg_data, guint8 * buf,
guint32 *bufsize, guint8 ** next_start, guint32 * bufsize, guint8 ** next_start, guint32 * next_size);
guint32 * next_size);
G_END_DECLS G_END_DECLS
#endif /* __METADATAPARSE_JPEG_H__ */ #endif /* __METADATAPARSE_JPEG_H__ */

View 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;
}

View 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__ */

View file

@ -44,8 +44,8 @@
#include "metadataparseutil.h" #include "metadataparseutil.h"
void void
metadataparse_tag_list_add_chunk (GstTagList * taglist, GstTagMergeMode mode, metadataparse_util_tag_list_add_chunk (GstTagList * taglist,
const gchar * name, GstAdapter * adapter) GstTagMergeMode mode, const gchar * name, GstAdapter * adapter)
{ {
GstBuffer *buf; GstBuffer *buf;
guint size; 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;
}

View file

@ -50,9 +50,15 @@
G_BEGIN_DECLS G_BEGIN_DECLS
extern void extern void
metadataparse_tag_list_add_chunk (GstTagList * taglist, GstTagMergeMode mode, metadataparse_util_tag_list_add_chunk (GstTagList * taglist,
const gchar * name, GstAdapter * adapter); 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 G_END_DECLS
#endif /* __GST_METADATAPARSE_UTIL_H__ */ #endif /* __GST_METADATAPARSE_UTIL_H__ */

View file

@ -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"); 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 */ /* 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 = gst_adapter_peek (adapter, size);
buf += 29; /* jump "http://ns.adobe.com/xap/1.0/" */
size -= 29;
xmp = xmp_new (buf, size); xmp = xmp_new (buf, size);
if (!xmp) if (!xmp)
goto done; goto done;
@ -128,7 +125,6 @@ metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode,
xmp_serialize (xmp, xmp_str, XMP_SERIAL_ENCODEUTF8, 2); xmp_serialize (xmp, xmp_str, XMP_SERIAL_ENCODEUTF8, 2);
GST_LOG (xmp_string_cstr (xmp_str)); GST_LOG (xmp_string_cstr (xmp_str));
done: done:

View file

@ -50,17 +50,14 @@
G_BEGIN_DECLS G_BEGIN_DECLS
extern void 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 extern gboolean metadataparse_xmp_init (void);
metadataparse_xmp_init(void);
extern void extern void metadataparse_xmp_dispose (void);
metadataparse_xmp_dispose(void);
extern void extern void metadataparse_xmp_tags_register (void);
metadataparse_xmp_tags_register (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_METADATAPARSE_XMP_H__ */ #endif /* __GST_METADATAPARSE_XMP_H__ */