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>
* ext/metadata/gstmetadataparse.c: (gst_metadata_parse_init),

View file

@ -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 \

View file

@ -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;

View file

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

View file

@ -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:

View file

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

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");
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);

View file

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

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");
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);

View file

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

View file

@ -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);
}

View file

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

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

View file

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

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");
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:

View file

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