summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/metadata/TODO3
-rw-r--r--ext/metadata/gstmetadatademux.c16
-rw-r--r--ext/metadata/metadata.c6
-rw-r--r--ext/metadata/metadata.h9
-rw-r--r--ext/metadata/metadataparsejpeg.c76
-rw-r--r--ext/metadata/metadataparsejpeg.h5
-rw-r--r--ext/metadata/metadataparsepng.c21
-rw-r--r--ext/metadata/metadataparsepng.h6
-rw-r--r--ext/metadata/test/MetadataEditorMain.glade15
-rw-r--r--ext/metadata/test/metadata_editor.c137
10 files changed, 239 insertions, 55 deletions
diff --git a/ext/metadata/TODO b/ext/metadata/TODO
index d44c2f33..b85e38dc 100644
--- a/ext/metadata/TODO
+++ b/ext/metadata/TODO
@@ -15,6 +15,5 @@ OPEN ISSUES:
ex: file.jpeg has XMP, then we do filesrc ! metadataparse ! jpegdec ! pngenc ! metadatamux ! files
is the metadata still valid? which fields are no valid anymore?
3- Add GST_TYPE_FRACTION support for GStreamer TAGS
-4- Have parse, demux and mux? (or just demux and must) see issue (5)
-5- After decided issue (4) put more things to gstmetadatacommon (or else create a Class)
+4- After decided issue (4) put more things to gstmetadatacommon (or else create a Class)
diff --git a/ext/metadata/gstmetadatademux.c b/ext/metadata/gstmetadatademux.c
index 9e53be54..b0d09950 100644
--- a/ext/metadata/gstmetadatademux.c
+++ b/ext/metadata/gstmetadatademux.c
@@ -88,7 +88,8 @@ enum
ARG_0,
ARG_EXIF,
ARG_IPTC,
- ARG_XMP
+ ARG_XMP,
+ ARG_PARSE_ONLY
};
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -211,6 +212,10 @@ gst_metadata_demux_class_init (GstMetadataDemuxClass * klass)
g_param_spec_boolean ("xmp", "XMP", "Send XMP metadata ?",
TRUE, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_PARSE_ONLY,
+ g_param_spec_boolean ("parse-only", "parse-only",
+ "If TRUE, don't strip out any chunk", FALSE, G_PARAM_READWRITE));
+
gstelement_class->change_state = gst_metadata_demux_change_state;
}
@@ -300,6 +305,12 @@ gst_metadata_demux_set_property (GObject * object, guint prop_id,
else
filter->options &= ~META_OPT_XMP;
break;
+ case ARG_PARSE_ONLY:
+ if (g_value_get_boolean (value))
+ filter->options |= META_OPT_PARSE_ONLY;
+ else
+ filter->options &= ~META_OPT_PARSE_ONLY;
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -322,6 +333,9 @@ gst_metadata_demux_get_property (GObject * object, guint prop_id,
case ARG_XMP:
g_value_set_boolean (value, filter->options & META_OPT_XMP);
break;
+ case ARG_PARSE_ONLY:
+ g_value_set_boolean (value, filter->options & META_OPT_PARSE_ONLY);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/ext/metadata/metadata.c b/ext/metadata/metadata.c
index 4fcd7c1c..7909db23 100644
--- a/ext/metadata/metadata.c
+++ b/ext/metadata/metadata.c
@@ -295,7 +295,8 @@ metadata_parse_none (MetaData * meta_data, const guint8 * buf,
if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF) {
if (G_LIKELY (meta_data->parse))
metadataparse_jpeg_init (&meta_data->format_data.jpeg_parse, exif, iptc,
- xmp, &meta_data->strip_chunks, &meta_data->inject_chunks);
+ xmp, &meta_data->strip_chunks, &meta_data->inject_chunks,
+ meta_data->options & META_OPT_PARSE_ONLY);
else
metadatamux_jpeg_init (&meta_data->format_data.jpeg_mux,
&meta_data->strip_chunks, &meta_data->inject_chunks);
@@ -315,7 +316,8 @@ metadata_parse_none (MetaData * meta_data, const guint8 * buf,
buf[4] == 0x0D && buf[5] == 0x0A && buf[6] == 0x1A && buf[7] == 0x0A) {
if (G_LIKELY (meta_data->parse))
metadataparse_png_init (&meta_data->format_data.png_parse, exif, iptc,
- xmp, &meta_data->strip_chunks, &meta_data->inject_chunks);
+ xmp, &meta_data->strip_chunks, &meta_data->inject_chunks,
+ meta_data->options & META_OPT_PARSE_ONLY);
else
metadatamux_png_init (&meta_data->format_data.png_mux,
&meta_data->strip_chunks, &meta_data->inject_chunks);
diff --git a/ext/metadata/metadata.h b/ext/metadata/metadata.h
index 2a5329a6..2853136d 100644
--- a/ext/metadata/metadata.h
+++ b/ext/metadata/metadata.h
@@ -58,10 +58,11 @@ G_BEGIN_DECLS
typedef enum _tag_MetaOption
{
- META_OPT_EXIF = (1 << 0),
- META_OPT_IPTC = (1 << 1),
- META_OPT_XMP = (1 << 2),
- META_OPT_ALL = (1 << 3) - 1
+ META_OPT_EXIF = (1 << 0),
+ META_OPT_IPTC = (1 << 1),
+ META_OPT_XMP = (1 << 2),
+ META_OPT_PARSE_ONLY = (1 << 3),
+ META_OPT_ALL = (1 << 4) - 1
} MetaOption;
/* *INDENT-ON* */
diff --git a/ext/metadata/metadataparsejpeg.c b/ext/metadata/metadataparsejpeg.c
index 54d9b26d..f2482c72 100644
--- a/ext/metadata/metadataparsejpeg.c
+++ b/ext/metadata/metadataparsejpeg.c
@@ -83,7 +83,8 @@ metadataparse_jpeg_lazy_update (JpegParseData * jpeg_data)
void
metadataparse_jpeg_init (JpegParseData * jpeg_data, GstAdapter ** exif_adpt,
GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt,
- MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks)
+ MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks,
+ gboolean parse_only)
{
jpeg_data->state = JPEG_PARSE_NULL;
jpeg_data->exif_adapter = exif_adpt;
@@ -95,6 +96,8 @@ metadataparse_jpeg_init (JpegParseData * jpeg_data, GstAdapter ** exif_adpt,
jpeg_data->strip_chunks = strip_chunks;
jpeg_data->inject_chunks = inject_chunks;
+ jpeg_data->parse_only = parse_only;
+
}
void
@@ -258,12 +261,17 @@ metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf,
if (0 == memcmp (ExifHeader, *buf, 6)) {
MetadataChunk chunk;
- memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
- chunk.size = chunk_size + 2; /* chunk size plus app marker */
- chunk.type = MD_CHUNK_EXIF;
+ if (!jpeg_data->parse_only) {
+
+ memset (&chunk, 0x00, sizeof (MetadataChunk));
+ chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
+ chunk.size = chunk_size + 2; /* chunk size plus app marker */
+ chunk.type = MD_CHUNK_EXIF;
- metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, &chunk);
+ metadata_chunk_array_append_sorted (jpeg_data->strip_chunks,
+ &chunk);
+
+ }
if (!jpeg_data->jfif_found) {
/* only inject if no JFIF has been found */
@@ -275,16 +283,19 @@ metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf,
0x00, 0x00
};
+ if (!jpeg_data->parse_only) {
- memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = 2;
- chunk.size = 18;
- chunk.type = MD_CHUNK_UNKNOWN;
- chunk.data = g_new (guint8, 18);
- memcpy (chunk.data, segment, 18);
+ memset (&chunk, 0x00, sizeof (MetadataChunk));
+ chunk.offset_orig = 2;
+ chunk.size = 18;
+ chunk.type = MD_CHUNK_UNKNOWN;
+ chunk.data = g_new (guint8, 18);
+ memcpy (chunk.data, segment, 18);
- metadata_chunk_array_append_sorted (jpeg_data->inject_chunks,
- &chunk);
+ metadata_chunk_array_append_sorted (jpeg_data->inject_chunks,
+ &chunk);
+
+ }
}
@@ -304,15 +315,20 @@ metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf,
}
if (0 == memcmp (XmpHeader, *buf, 29)) {
- MetadataChunk chunk;
- memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
- chunk.size = chunk_size + 2; /* chunk size plus app marker */
- chunk.type = MD_CHUNK_XMP;
+ if (!jpeg_data->parse_only) {
- metadata_chunk_array_append_sorted (jpeg_data->strip_chunks,
- &chunk);
+ MetadataChunk chunk;
+
+ memset (&chunk, 0x00, sizeof (MetadataChunk));
+ chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
+ chunk.size = chunk_size + 2; /* chunk size plus app marker */
+ chunk.type = MD_CHUNK_XMP;
+
+ metadata_chunk_array_append_sorted (jpeg_data->strip_chunks,
+ &chunk);
+
+ }
/* if adapter has been provided, prepare to hold chunk */
if (jpeg_data->xmp_adapter) {
@@ -339,14 +355,20 @@ metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf,
if (0 == memcmp (IptcHeader, *buf, 14)) {
- MetadataChunk chunk;
- memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
- chunk.size = chunk_size + 2; /* chunk size plus app marker */
- chunk.type = MD_CHUNK_IPTC;
+ if (!jpeg_data->parse_only) {
+
+ MetadataChunk chunk;
- metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, &chunk);
+ memset (&chunk, 0x00, sizeof (MetadataChunk));
+ chunk.offset_orig = (*buf - step_buf) + offset - 4; /* maker + size */
+ chunk.size = chunk_size + 2; /* chunk size plus app marker */
+ chunk.type = MD_CHUNK_IPTC;
+
+ metadata_chunk_array_append_sorted (jpeg_data->strip_chunks,
+ &chunk);
+
+ }
/* if adapter has been provided, prepare to hold chunk */
if (jpeg_data->iptc_adapter) {
diff --git a/ext/metadata/metadataparsejpeg.h b/ext/metadata/metadataparsejpeg.h
index d4e6bcdd..e00095d9 100644
--- a/ext/metadata/metadataparsejpeg.h
+++ b/ext/metadata/metadataparsejpeg.h
@@ -73,6 +73,8 @@ typedef struct _tag_JpegParseData
MetadataChunkArray * strip_chunks;
MetadataChunkArray * inject_chunks;
+ gboolean parse_only;
+
guint32 read;
gboolean jfif_found;
} JpegParseData;
@@ -81,7 +83,8 @@ typedef struct _tag_JpegParseData
extern void
metadataparse_jpeg_init (JpegParseData * jpeg_data, GstAdapter ** exif_adpt,
GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt,
- MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks);
+ MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks,
+ gboolean parse_only);
extern void metadataparse_jpeg_dispose (JpegParseData * jpeg_data);
diff --git a/ext/metadata/metadataparsepng.c b/ext/metadata/metadataparsepng.c
index 32595ad4..a5de4dbe 100644
--- a/ext/metadata/metadataparsepng.c
+++ b/ext/metadata/metadataparsepng.c
@@ -69,14 +69,16 @@ metadataparse_png_lazy_update (PngParseData * jpeg_data)
void
metadataparse_png_init (PngParseData * png_data, GstAdapter ** exif_adpt,
GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt,
- MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks)
+ MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks,
+ gboolean parse_only)
{
png_data->state = PNG_PARSE_NULL;
png_data->xmp_adapter = xmp_adpt;
png_data->read = 0;
png_data->strip_chunks = strip_chunks;
- png_data->inject_chunks = inject_chunks;
+
+ png_data->parse_only = parse_only;
}
@@ -205,14 +207,17 @@ metadataparse_png_reading (PngParseData * png_data, guint8 ** buf,
}
if (0 == memcmp (XmpHeader, *buf, 18)) {
- MetadataChunk chunk;
- memset (&chunk, 0x00, sizeof (MetadataChunk));
- chunk.offset_orig = (*buf - step_buf) + offset - 8; /* maker + size */
- chunk.size = chunk_size + 12; /* chunk size plus app marker plus crc */
- chunk.type = MD_CHUNK_XMP;
+ if (!png_data->parse_only) {
+ MetadataChunk chunk;
+
+ memset (&chunk, 0x00, sizeof (MetadataChunk));
+ chunk.offset_orig = (*buf - step_buf) + offset - 8; /* maker + size */
+ chunk.size = chunk_size + 12; /* chunk size plus app marker plus crc */
+ chunk.type = MD_CHUNK_XMP;
- metadata_chunk_array_append_sorted (png_data->strip_chunks, &chunk);
+ metadata_chunk_array_append_sorted (png_data->strip_chunks, &chunk);
+ }
/* if adapter has been provided, prepare to hold chunk */
if (png_data->xmp_adapter) {
diff --git a/ext/metadata/metadataparsepng.h b/ext/metadata/metadataparsepng.h
index 224b48f7..26f87294 100644
--- a/ext/metadata/metadataparsepng.h
+++ b/ext/metadata/metadataparsepng.h
@@ -67,7 +67,8 @@ typedef struct _tag_PngParseData
GstAdapter ** xmp_adapter;
MetadataChunkArray * strip_chunks;
- MetadataChunkArray * inject_chunks;
+
+ gboolean parse_only;
guint32 read;
} PngParseData;
@@ -76,7 +77,8 @@ typedef struct _tag_PngParseData
extern void
metadataparse_png_init (PngParseData * png_data, GstAdapter ** exif_adpt,
GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt,
- MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks);
+ MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks,
+ gboolean parse_only);
extern void metadataparse_png_dispose (PngParseData * png_data);
diff --git a/ext/metadata/test/MetadataEditorMain.glade b/ext/metadata/test/MetadataEditorMain.glade
index ecd09be5..871d8e6b 100644
--- a/ext/metadata/test/MetadataEditorMain.glade
+++ b/ext/metadata/test/MetadataEditorMain.glade
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.2.0 on Wed Dec 12 14:07:03 2007 by edlima@feisty-laptop-->
+<!--Generated with glade3 3.2.0 on Mon Dec 17 11:42:47 2007 by edlima@feisty-laptop-->
<glade-interface>
<widget class="GtkWindow" id="windowMain">
<property name="width_request">800</property>
@@ -123,6 +123,19 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <widget class="GtkCheckButton" id="checkbuttonCapture">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Capture image from camera</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_checkbuttonCapture_toggled"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/ext/metadata/test/metadata_editor.c b/ext/metadata/test/metadata_editor.c
index e3b1cee5..0479e785 100644
--- a/ext/metadata/test/metadata_editor.c
+++ b/ext/metadata/test/metadata_editor.c
@@ -77,6 +77,9 @@ static void me_gst_cleanup_elements ();
static int
me_gst_setup_view_pipeline (const gchar * filename, GdkWindow * window);
static int
+me_gst_setup_capture_pipeline (const gchar * src_file, const gchar * dest_file,
+ gint * encode_status);
+static int
me_gst_setup_encode_pipeline (const gchar * src_file, const gchar * dest_file,
gint * encode_status);
@@ -92,6 +95,7 @@ GstElement *gst_source = NULL;
GstElement *gst_metadata_demux = NULL;
GstElement *gst_metadata_mux = NULL;
GstElement *gst_image_dec = NULL;
+GstElement *gst_image_enc = NULL;
GstElement *gst_video_scale = NULL;
GstElement *gst_video_convert = NULL;
GstElement *gst_video_sink = NULL;
@@ -108,6 +112,8 @@ GtkWidget *ui_tree = NULL;
GtkEntry *ui_entry_insert_tag = NULL;
GtkEntry *ui_entry_insert_value = NULL;
+GtkToggleButton *ui_chk_bnt_capture = NULL;
+
GString *filename = NULL;
/*
@@ -278,6 +284,29 @@ on_buttonInsert_clicked (GtkButton * button, gpointer user_data)
}
+static void
+setup_new_filename (GString * str, const gchar * ext)
+{
+ int i = 0;
+
+ for (i = str->len - 1; i > 0; --i) {
+ if (str->str[i] == '/') {
+ ++i;
+ break;
+ }
+ }
+ g_string_insert (str, i, "_new_");
+ if (ext) {
+ int len = strlen (ext);
+
+ if (len > str->len)
+ g_string_append (str, ext);
+ else if (strcasecmp (ext, &str->str[str->len - len]))
+ g_string_append (str, ext);
+
+ }
+}
+
void
on_buttonSaveFile_clicked (GtkButton * button, gpointer user_data)
{
@@ -290,14 +319,22 @@ on_buttonSaveFile_clicked (GtkButton * button, gpointer user_data)
src_file = g_string_new (filename->str);
- g_string_prepend (filename, "_new_");
- remove (filename->str);
+ if (gtk_toggle_button_get_active (ui_chk_bnt_capture)) {
+ setup_new_filename (filename, ".jpg");
+ if (me_gst_setup_capture_pipeline (src_file->str, filename->str,
+ &enc_status)) {
+ goto done;
+ }
+ } else {
+ setup_new_filename (filename, NULL);
+ if (me_gst_setup_encode_pipeline (src_file->str, filename->str,
+ &enc_status)) {
+ goto done;
+ }
+ }
ui_refresh ();
-
- if (me_gst_setup_encode_pipeline (src_file->str, filename->str, &enc_status)) {
- goto done;
- }
+ remove (filename->str);
if (tag_list && gst_metadata_mux) {
GstTagSetter *setter = GST_TAG_SETTER (gst_metadata_mux);
@@ -342,6 +379,14 @@ done:
}
+void
+on_checkbuttonCapture_toggled (GtkToggleButton * togglebutton,
+ gpointer user_data)
+{
+ if (gtk_toggle_button_get_active (togglebutton)) {
+ }
+}
+
/*
* UI handling functions
*/
@@ -498,8 +543,12 @@ ui_create ()
ui_entry_insert_value =
GTK_ENTRY (glade_xml_get_widget (ui_glade_xml, "entryValue"));
+ ui_chk_bnt_capture =
+ GTK_TOGGLE_BUTTON (glade_xml_get_widget (ui_glade_xml,
+ "checkbuttonCapture"));
+
if (!(ui_main_window && ui_drawing && ui_tree && ui_entry_insert_tag
- && ui_entry_insert_value)) {
+ && ui_entry_insert_value && ui_chk_bnt_capture)) {
fprintf (stderr, "Some widgets couldn't be created\n");
ret = -105;
goto done;
@@ -648,6 +697,10 @@ me_gst_cleanup_elements ()
gst_object_unref (gst_image_dec);
gst_image_dec = NULL;
}
+ if (gst_image_enc) {
+ gst_object_unref (gst_image_enc);
+ gst_image_enc = NULL;
+ }
if (gst_video_scale) {
gst_object_unref (gst_video_scale);
gst_video_scale = NULL;
@@ -697,6 +750,76 @@ done:
}
static int
+me_gst_setup_capture_pipeline (const gchar * src_file, const gchar * dest_file,
+ gint * encode_status)
+{
+ int ret = 0;
+ GstBus *bus = NULL;
+ gboolean linked;
+
+ *encode_status = ENC_ERROR;
+
+ me_gst_cleanup_elements ();
+
+ /* create elements */
+ gst_source = gst_element_factory_make ("v4l2src", NULL);
+ gst_video_convert = gst_element_factory_make ("ffmpegcolorspace", NULL);
+ gst_image_enc = gst_element_factory_make ("jpegenc", NULL);
+ gst_metadata_mux = gst_element_factory_make ("metadatamux", NULL);
+ gst_file_sink = gst_element_factory_make ("filesink", NULL);
+
+ if (!(gst_source && gst_video_convert && gst_image_enc && gst_metadata_mux
+ && gst_file_sink)) {
+ fprintf (stderr, "An element couldn't be created for ecoding\n");
+ ret = -300;
+ goto done;
+ }
+
+ /* create gst_pipeline */
+ gst_pipeline = gst_pipeline_new (NULL);
+
+ if (NULL == gst_pipeline) {
+ fprintf (stderr, "Pipeline couldn't be created\n");
+ ret = -305;
+ goto done;
+ }
+
+ /* set elements's properties */
+ g_object_set (gst_source, "num-buffers", 1, NULL);
+ g_object_set (gst_file_sink, "location", dest_file, NULL);
+
+ /* adding and linking elements */
+ gst_bin_add_many (GST_BIN (gst_pipeline), gst_source, gst_video_convert,
+ gst_image_enc, gst_metadata_mux, gst_file_sink, NULL);
+
+ linked =
+ gst_element_link_many (gst_source, gst_video_convert, gst_image_enc,
+ gst_metadata_mux, gst_file_sink, NULL);
+
+ /* now element are owned by pipeline (for videosink we keep a extra ref) */
+ gst_source = gst_video_convert = gst_image_enc = gst_file_sink = NULL;
+ gst_object_ref (gst_metadata_mux);
+
+ if (!linked) {
+ fprintf (stderr, "Elements couldn't be linked\n");
+ ret = -310;
+ goto done;
+ }
+
+ *encode_status = ENC_UNKNOWN;
+
+ /* adding message bus */
+ bus = gst_pipeline_get_bus (GST_PIPELINE (gst_pipeline));
+ gst_bus_add_watch (bus, me_gst_bus_callback_encode, encode_status);
+ gst_object_unref (bus);
+
+done:
+
+ return ret;
+
+}
+
+static int
me_gst_setup_encode_pipeline (const gchar * src_file, const gchar * dest_file,
gint * encode_status)
{