mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
gst-libs/gst/tag/: API: add gst_tag_image_data_to_image_buffer()
Original commit message from CVS: * gst-libs/gst/tag/gstid3tag.c: (gst_tag_list_add_id3_image): * gst-libs/gst/tag/tag.h: (GST_TAG_IMAGE_TYPE_NONE), * gst-libs/gst/tag/tags.c: (register_tag_image_type_enum), (gst_tag_image_type_get_type), (gst_tag_image_type_is_valid), (gst_tag_image_data_to_image_buffer): Add two utility functions to avoid code duplication (#512333): API: add gst_tag_image_data_to_image_buffer() API: add gst_tag_list_add_id3_image()
This commit is contained in:
parent
eb93e07392
commit
cd9bb9a674
4 changed files with 203 additions and 2 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2008-06-03 Tim-Philipp Müller <tim.muller at collabora co uk>
|
||||||
|
|
||||||
|
* gst-libs/gst/tag/gstid3tag.c: (gst_tag_list_add_id3_image):
|
||||||
|
* gst-libs/gst/tag/tag.h: (GST_TAG_IMAGE_TYPE_NONE),
|
||||||
|
* gst-libs/gst/tag/tags.c: (register_tag_image_type_enum),
|
||||||
|
(gst_tag_image_type_get_type), (gst_tag_image_type_is_valid),
|
||||||
|
(gst_tag_image_data_to_image_buffer):
|
||||||
|
Add two utility functions to avoid code duplication (#512333):
|
||||||
|
API: add gst_tag_image_data_to_image_buffer()
|
||||||
|
API: add gst_tag_list_add_id3_image()
|
||||||
|
|
||||||
2008-06-03 Sebastian Dröge <slomo@circular-chaos.org>
|
2008-06-03 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
* win32/common/libgstaudio.def:
|
* win32/common/libgstaudio.def:
|
||||||
|
|
|
@ -428,3 +428,58 @@ gst_tag_id3_genre_get (const guint id)
|
||||||
return NULL;
|
return NULL;
|
||||||
return genres[id];
|
return genres[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_list_add_id3_image:
|
||||||
|
* @tag_list: a tag list
|
||||||
|
* @image_data: the (encoded) image
|
||||||
|
* @image_data_len: the length of the encoded image data at @image_data
|
||||||
|
* @id3_picture_type: picture type as per the ID3 (v2.4.0) specification for
|
||||||
|
* the APIC frame (0 = unknown/other)
|
||||||
|
*
|
||||||
|
* Adds an image from an ID3 APIC frame (or similar, such as used in FLAC)
|
||||||
|
* to the given tag list. Also see gst_tag_image_data_to_image_buffer() for
|
||||||
|
* more information on image tags in GStreamer.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the image was processed, otherwise %FALSE
|
||||||
|
*
|
||||||
|
* Since: 0.10.20
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_tag_list_add_id3_image (GstTagList * tag_list, const guint8 * image_data,
|
||||||
|
guint image_data_len, guint id3_picture_type)
|
||||||
|
{
|
||||||
|
GstTagImageType tag_image_type;
|
||||||
|
const gchar *tag_name;
|
||||||
|
GstBuffer *image;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_TAG_LIST (tag_list), FALSE);
|
||||||
|
g_return_val_if_fail (image_data != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (image_data_len > 0, FALSE);
|
||||||
|
|
||||||
|
if (id3_picture_type == 0x01 || id3_picture_type == 0x02) {
|
||||||
|
/* file icon for preview. Don't add image-type to caps, since there
|
||||||
|
* is only supposed to be one of these, and the type is already indicated
|
||||||
|
* via the special tag */
|
||||||
|
tag_name = GST_TAG_PREVIEW_IMAGE;
|
||||||
|
tag_image_type = GST_TAG_IMAGE_TYPE_NONE;
|
||||||
|
} else {
|
||||||
|
tag_name = GST_TAG_IMAGE;
|
||||||
|
|
||||||
|
/* Remap the ID3v2 APIC type our ImageType enum */
|
||||||
|
if (id3_picture_type >= 0x3 && id3_picture_type <= 0x14)
|
||||||
|
tag_image_type = (GstTagImageType) (id3_picture_type - 2);
|
||||||
|
else
|
||||||
|
tag_image_type = GST_TAG_IMAGE_TYPE_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = gst_tag_image_data_to_image_buffer (image_data, image_data_len,
|
||||||
|
tag_image_type);
|
||||||
|
|
||||||
|
if (image == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
gst_tag_list_add (tag_list, GST_TAG_MERGE_APPEND, tag_name, image, NULL);
|
||||||
|
gst_buffer_unref (image);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -126,6 +126,9 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstTagImageType:
|
* GstTagImageType:
|
||||||
|
* @GST_TAG_IMAGE_TYPE_NONE : No image type. Can be used to
|
||||||
|
* tell functions such as gst_tag_image_data_to_image_buffer() that no
|
||||||
|
* image type should be set. (Since: 0.10.20)
|
||||||
* @GST_TAG_IMAGE_TYPE_UNDEFINED : Undefined/other image type
|
* @GST_TAG_IMAGE_TYPE_UNDEFINED : Undefined/other image type
|
||||||
* @GST_TAG_IMAGE_TYPE_FRONT_COVER : Cover (front)
|
* @GST_TAG_IMAGE_TYPE_FRONT_COVER : Cover (front)
|
||||||
* @GST_TAG_IMAGE_TYPE_BACK_COVER : Cover (back)
|
* @GST_TAG_IMAGE_TYPE_BACK_COVER : Cover (back)
|
||||||
|
@ -152,7 +155,8 @@ G_BEGIN_DECLS
|
||||||
* Since: 0.10.9
|
* Since: 0.10.9
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_TAG_IMAGE_TYPE_UNDEFINED,
|
GST_TAG_IMAGE_TYPE_NONE = -1,
|
||||||
|
GST_TAG_IMAGE_TYPE_UNDEFINED = 0,
|
||||||
GST_TAG_IMAGE_TYPE_FRONT_COVER,
|
GST_TAG_IMAGE_TYPE_FRONT_COVER,
|
||||||
GST_TAG_IMAGE_TYPE_BACK_COVER,
|
GST_TAG_IMAGE_TYPE_BACK_COVER,
|
||||||
GST_TAG_IMAGE_TYPE_LEAFLET_PAGE,
|
GST_TAG_IMAGE_TYPE_LEAFLET_PAGE,
|
||||||
|
@ -209,6 +213,11 @@ G_CONST_RETURN gchar * gst_tag_from_id3_user_tag (const gchar *
|
||||||
const gchar * id3_user_tag);
|
const gchar * id3_user_tag);
|
||||||
G_CONST_RETURN gchar * gst_tag_to_id3_tag (const gchar * gst_tag);
|
G_CONST_RETURN gchar * gst_tag_to_id3_tag (const gchar * gst_tag);
|
||||||
|
|
||||||
|
gboolean gst_tag_list_add_id3_image (GstTagList * tag_list,
|
||||||
|
const guint8 * image_data,
|
||||||
|
guint image_data_len,
|
||||||
|
guint id3_picture_type);
|
||||||
|
|
||||||
/* other tag-related functions */
|
/* other tag-related functions */
|
||||||
|
|
||||||
gboolean gst_tag_parse_extended_comment (const gchar * ext_comment,
|
gboolean gst_tag_parse_extended_comment (const gchar * ext_comment,
|
||||||
|
@ -221,6 +230,10 @@ gchar * gst_tag_freeform_string_to_utf8 (const gchar * data,
|
||||||
gint size,
|
gint size,
|
||||||
const gchar ** env_vars);
|
const gchar ** env_vars);
|
||||||
|
|
||||||
|
GstBuffer * gst_tag_image_data_to_image_buffer (const guint8 * image_data,
|
||||||
|
guint image_data_len,
|
||||||
|
GstTagImageType image_type);
|
||||||
|
|
||||||
/* FIXME 0.11: replace with a more general gst_tag_library_init() */
|
/* FIXME 0.11: replace with a more general gst_tag_library_init() */
|
||||||
void gst_tag_register_musicbrainz_tags (void);
|
void gst_tag_register_musicbrainz_tags (void);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* GStreamer non-core tag registration and tag utility functions
|
/* GStreamer non-core tag registration and tag utility functions
|
||||||
* Copyright (C) 2005 Ross Burton <ross@burtonini.com>
|
* Copyright (C) 2005 Ross Burton <ross@burtonini.com>
|
||||||
* Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
|
* Copyright (C) 2006-2008 Tim-Philipp Müller <tim centricular net>
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gst/gst-i18n-plugin.h>
|
#include <gst/gst-i18n-plugin.h>
|
||||||
|
#include <gst/base/gsttypefindhelper.h>
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
|
||||||
|
@ -144,6 +145,9 @@ register_tag_image_type_enum (GType * id)
|
||||||
};
|
};
|
||||||
|
|
||||||
*id = g_enum_register_static ("GstTagImageType", image_types);
|
*id = g_enum_register_static ("GstTagImageType", image_types);
|
||||||
|
|
||||||
|
/* work around thread-safety issue with class creation in GLib */
|
||||||
|
g_type_class_ref (*id);
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
|
@ -156,6 +160,19 @@ gst_tag_image_type_get_type (void)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
gst_tag_image_type_is_valid (GstTagImageType type)
|
||||||
|
{
|
||||||
|
GEnumClass *klass;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
klass = g_type_class_ref (gst_tag_image_type_get_type ());
|
||||||
|
res = (g_enum_get_value (klass, type) != NULL);
|
||||||
|
g_type_class_unref (klass);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_tag_parse_extended_comment:
|
* gst_tag_parse_extended_comment:
|
||||||
* @ext_comment: an extended comment string, see #GST_TAG_EXTENDED_COMMENT
|
* @ext_comment: an extended comment string, see #GST_TAG_EXTENDED_COMMENT
|
||||||
|
@ -326,3 +343,108 @@ beach:
|
||||||
g_free (utf8);
|
g_free (utf8);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_tag_image_data_to_image_buffer:
|
||||||
|
* @image_data: the (encoded) image
|
||||||
|
* @image_data_len: the length of the encoded image data at @image_data
|
||||||
|
* @image_type: type of the image, or #GST_TAG_IMAGE_TYPE_UNDEFINED. Pass
|
||||||
|
* #GST_TAG_IMAGE_TYPE_NONE if no image type should be set at all (e.g.
|
||||||
|
* for preview images)
|
||||||
|
*
|
||||||
|
* Helper function for tag-reading plugins to create a #GstBuffer suitable to
|
||||||
|
* add to a #GstTagList as an image tag (such as #GST_TAG_IMAGE or
|
||||||
|
* #GST_TAG_PREVIEW_IMAGE) from the encoded image data and an (optional) image
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* Background: cover art and other images in tags are usually stored as a
|
||||||
|
* blob of binary image data, often accompanied by a MIME type or some other
|
||||||
|
* content type string (e.g. 'png', 'jpeg', 'jpg'). Sometimes there is also an
|
||||||
|
* 'image type' to indicate what kind of image this is (e.g. front cover,
|
||||||
|
* back cover, artist, etc.). The image data may also be an URI to the image
|
||||||
|
* rather than the image itself.
|
||||||
|
*
|
||||||
|
* In GStreamer, image tags are #GstBuffer<!-- -->s containing the raw image
|
||||||
|
* data, with the buffer caps describing the content type of the image
|
||||||
|
* (e.g. image/jpeg, image/png, text/uri-list). The buffer caps may contain
|
||||||
|
* an additional 'image-type' field of #GST_TYPE_TAG_IMAGE_TYPE to describe
|
||||||
|
* the type of image (front cover, back cover etc.). #GST_TAG_PREVIEW_IMAGE
|
||||||
|
* tags should not carry an image type, their type is already indicated via
|
||||||
|
* the special tag name.
|
||||||
|
*
|
||||||
|
* This function will do various checks and typefind the encoded image
|
||||||
|
* data (we can't trust the declared mime type).
|
||||||
|
*
|
||||||
|
* Returns: a newly-allocated image buffer for use in tag lists, or NULL
|
||||||
|
*
|
||||||
|
* Since: 0.10.20
|
||||||
|
*/
|
||||||
|
GstBuffer *
|
||||||
|
gst_tag_image_data_to_image_buffer (const guint8 * image_data,
|
||||||
|
guint image_data_len, GstTagImageType image_type)
|
||||||
|
{
|
||||||
|
const gchar *name;
|
||||||
|
GstBuffer *image;
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
g_return_val_if_fail (image_data != NULL, NULL);
|
||||||
|
g_return_val_if_fail (image_data_len > 0, NULL);
|
||||||
|
g_return_val_if_fail (gst_tag_image_type_is_valid (image_type), NULL);
|
||||||
|
|
||||||
|
GST_DEBUG ("image data len: %u bytes", image_data_len);
|
||||||
|
|
||||||
|
/* allocate space for a NUL terminator for an uri too */
|
||||||
|
image = gst_buffer_try_new_and_alloc (image_data_len + 1);
|
||||||
|
if (image == NULL) {
|
||||||
|
GST_WARNING ("failed to allocate buffer of %d for image", image_data_len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (GST_BUFFER_DATA (image), image_data, image_data_len);
|
||||||
|
GST_BUFFER_DATA (image)[image_data_len] = '\0';
|
||||||
|
GST_BUFFER_SIZE (image) = image_data_len;
|
||||||
|
|
||||||
|
/* Find GStreamer media type, can't trust declared type */
|
||||||
|
caps = gst_type_find_helper_for_buffer (NULL, image, NULL);
|
||||||
|
|
||||||
|
if (caps == NULL)
|
||||||
|
goto no_type;
|
||||||
|
|
||||||
|
GST_DEBUG ("Found GStreamer media type: %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
/* sanity check: make sure typefound/declared caps are either URI or image */
|
||||||
|
name = gst_structure_get_name (gst_caps_get_structure (caps, 0));
|
||||||
|
|
||||||
|
if (!g_str_has_prefix (name, "image/") &&
|
||||||
|
!g_str_has_prefix (name, "video/") &&
|
||||||
|
!g_str_equal (name, "text/uri-list")) {
|
||||||
|
GST_DEBUG ("Unexpected image type '%s', ignoring image frame", name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image_type != GST_TAG_IMAGE_TYPE_NONE) {
|
||||||
|
GST_LOG ("Setting image type: %d", image_type);
|
||||||
|
caps = gst_caps_make_writable (caps);
|
||||||
|
gst_caps_set_simple (caps, "image-type", GST_TYPE_TAG_IMAGE_TYPE,
|
||||||
|
image_type, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_buffer_set_caps (image, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return image;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_type:
|
||||||
|
{
|
||||||
|
GST_DEBUG ("Could not determine GStreamer media type, ignoring image");
|
||||||
|
/* fall through */
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
{
|
||||||
|
if (image)
|
||||||
|
gst_buffer_unref (image);
|
||||||
|
if (caps)
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue