[easytag] Use GBytes for image data inside Picture
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag] Use GBytes for image data inside Picture
- Date: Wed, 17 Dec 2014 19:14:04 +0000 (UTC)
commit 2f38620fdfce98ed381ac9b72a6f8d82ca4d0c63
Author: David King <amigadave amigadave com>
Date: Wed Dec 17 17:10:39 2014 +0000
Use GBytes for image data inside Picture
Avoid many superfluous memory allocations when copying Picture instances
by using GBytes instead of a bare pointer, and incrementing the
reference count when copying. Use the slice allocator to allocate
Picture instances. Avoid Picture->bytes from ever being NULL. Update the
Picture tests.
Inspired by a report of excessive memory usage on the mailing list:
https://mail.gnome.org/archives/easytag-list/2014-December/msg00000.html
src/et_core.c | 11 +--
src/et_core.h | 9 +-
src/picture.c | 118 +++++++++++++-----------
src/picture.h | 3 +-
src/tag_area.c | 16 ++--
src/tags/flac_tag.c | 12 ++-
src/tags/id3_tag.c | 8 ++-
src/tags/id3v24_tag.c | 29 ++++--
src/tags/mp4_tag.cc | 13 ++-
src/tags/ogg_tag.c | 240 +++++++++++++++++++++++++------------------------
tests/test-picture.c | 14 ++--
11 files changed, 253 insertions(+), 220 deletions(-)
---
diff --git a/src/et_core.c b/src/et_core.c
index 9143924..e7c1044 100644
--- a/src/et_core.c
+++ b/src/et_core.c
@@ -3913,15 +3913,10 @@ ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1,
//if (!pic1->data || !pic2->data)
// break; // => no changes
- if (!pic1->data && !pic2->data)
- return FALSE;
- if (pic1->data && !pic2->data)
- return TRUE;
- if (!pic1->data && pic2->data)
- return TRUE;
- if (pic1->size != pic2->size
- || memcmp(pic1->data, pic2->data, pic1->size))
+ if (!g_bytes_equal (pic1->bytes, pic2->bytes))
+ {
return TRUE;
+ }
if (pic1->type != pic2->type)
return TRUE;
if (pic1->description && !pic2->description
diff --git a/src/et_core.h b/src/et_core.h
index af52c39..1c520df 100644
--- a/src/et_core.h
+++ b/src/et_core.h
@@ -22,11 +22,11 @@
#include "setting.h"
+G_BEGIN_DECLS
+
#include <glib.h>
#include <gdk/gdk.h>
-G_BEGIN_DECLS
-
/*
* Colors Used (see declaration into et_core.c)
*/
@@ -88,12 +88,11 @@ struct _File_Name
typedef struct _Picture Picture;
struct _Picture
{
- gint type;
+ gint type;
gchar *description;
gint width; /* Original width of the picture */
gint height; /* Original height of the picture */
- gsize size; /* Picture size in bytes (like stat) */
- guchar *data;
+ GBytes *bytes;
Picture *next;
};
diff --git a/src/picture.c b/src/picture.c
index 6a64d6f..c2f4d0c 100644
--- a/src/picture.c
+++ b/src/picture.c
@@ -111,42 +111,33 @@ et_picture_type_from_filename (const gchar *filename_utf8)
Picture_Format
Picture_Format_From_Data (const Picture *pic)
{
- // JPEG : "\xff\xd8"
- if (pic->data && pic->size > 2
- && pic->data[0] == 0xff
- && pic->data[1] == 0xd8)
+ gsize size;
+ gconstpointer data;
+
+ g_return_val_if_fail (pic != NULL, PICTURE_FORMAT_UNKNOWN);
+
+ data = g_bytes_get_data (pic->bytes, &size);
+
+ /* JPEG : "\xff\xd8". */
+ if (size > 2 && memcmp (data, "\xff\xd8", 2))
+ {
return PICTURE_FORMAT_JPEG;
+ }
- // PNG : "\x89PNG\x0d\x0a\x1a\x0a"
- if (pic->data && pic->size > 8
- && pic->data[0] == 0x89
- && pic->data[1] == 0x50
- && pic->data[2] == 0x4e
- && pic->data[3] == 0x47
- && pic->data[4] == 0x0d
- && pic->data[5] == 0x0a
- && pic->data[6] == 0x1a
- && pic->data[7] == 0x0a)
+ /* PNG : "\x89PNG\x0d\x0a\x1a\x0a". */
+ if (size > 8 && memcmp (data, "\x89PNG\x0d\x0a\x1a\x0a", 8))
+ {
return PICTURE_FORMAT_PNG;
+ }
/* GIF: "GIF87a" */
- if (pic->data && pic->size > 6
- && pic->data[0] == 0x47
- && pic->data[1] == 0x49
- && pic->data[2] == 0x46
- && pic->data[3] == 0x38
- && pic->data[4] == 0x37
- && pic->data[5] == 0x61)
+ if (size > 6 && memcmp (data, "GIF87a", 6))
+ {
return PICTURE_FORMAT_GIF;
+ }
/* GIF: "GIF89a" */
- if (pic->data && pic->size > 6
- && pic->data[0] == 0x47
- && pic->data[1] == 0x49
- && pic->data[2] == 0x46
- && pic->data[3] == 0x38
- && pic->data[4] == 0x39
- && pic->data[5] == 0x61)
+ if (size > 6 && memcmp (data, "GIF89a", 6))
{
return PICTURE_FORMAT_GIF;
}
@@ -154,7 +145,8 @@ Picture_Format_From_Data (const Picture *pic)
return PICTURE_FORMAT_UNKNOWN;
}
-const gchar *Picture_Mime_Type_String (Picture_Format format)
+const gchar *
+Picture_Mime_Type_String (Picture_Format format)
{
switch (format)
{
@@ -255,8 +247,8 @@ Picture_Info (const Picture *pic,
else
desc = "";
- type = Picture_Type_String(pic->type);
- size_str = g_format_size (pic->size);
+ type = Picture_Type_String (pic->type);
+ size_str = g_format_size (g_bytes_get_size (pic->bytes));
// Behaviour following the tag type...
switch (tag_type)
@@ -285,34 +277,37 @@ Picture_Info (const Picture *pic,
return r;
}
-Picture *Picture_Allocate (void)
+Picture *
+Picture_Allocate (void)
{
- Picture *pic = g_malloc0(sizeof(Picture));
+ Picture *pic = g_slice_new0 (Picture);
return pic;
}
-Picture *Picture_Copy_One (const Picture *pic)
+Picture *
+Picture_Copy_One (const Picture *pic)
{
Picture *pic2;
g_return_val_if_fail (pic != NULL, NULL);
- pic2 = Picture_Allocate();
+ pic2 = Picture_Allocate ();
pic2->type = pic->type;
pic2->width = pic->width;
pic2->height = pic->height;
+
if (pic->description)
- pic2->description = g_strdup(pic->description);
- if (pic->data)
{
- pic2->size = pic->size;
- pic2->data = g_malloc(pic2->size);
- memcpy(pic2->data, pic->data, pic->size);
+ pic2->description = g_strdup (pic->description);
}
+
+ pic2->bytes = g_bytes_ref (pic->bytes);
+
return pic2;
}
-Picture *Picture_Copy (const Picture *pic)
+Picture *
+Picture_Copy (const Picture *pic)
{
Picture *pic2 = Picture_Copy_One(pic);
if (pic->next)
@@ -320,17 +315,24 @@ Picture *Picture_Copy (const Picture *pic)
return pic2;
}
-void Picture_Free (Picture *pic)
+void
+Picture_Free (Picture *pic)
{
- if (!pic)
+ if (pic == NULL)
+ {
return;
+ }
+
if (pic->next)
- Picture_Free(pic->next);
- if (pic->description)
- g_free(pic->description);
- if (pic->data)
- g_free(pic->data);
- g_free(pic);
+ {
+ Picture_Free (pic->next);
+ }
+
+ g_free (pic->description);
+ g_bytes_unref (pic->bytes);
+ pic->bytes = NULL;
+
+ g_slice_free (Picture, pic);
}
@@ -397,6 +399,8 @@ et_picture_load_file_data (GFile *file, GError **error)
{
/* Image loaded. */
Picture *pic;
+ gpointer data;
+ gsize data_size;
g_object_unref (file_istream);
@@ -410,8 +414,10 @@ et_picture_load_file_data (GFile *file, GError **error)
g_assert (error == NULL || *error == NULL);
pic = Picture_Allocate ();
- pic->data = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream));
- pic->size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream));
+ data = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream));
+ data_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream));
+ pic->bytes = g_bytes_new_take (data, data_size);
+ /* TODO: Use g_memory_output_stream_steal_as_bytes(). */
g_object_unref (ostream);
g_assert (error == NULL || *error == NULL);
@@ -433,6 +439,8 @@ gboolean
et_picture_save_file_data (const Picture *pic, GFile *file, GError **error)
{
GFileOutputStream *file_ostream;
+ gconstpointer data;
+ gsize data_size;
gsize bytes_written;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -446,12 +454,14 @@ et_picture_save_file_data (const Picture *pic, GFile *file, GError **error)
return FALSE;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (file_ostream), pic->data,
- pic->size, &bytes_written, NULL, error))
+ data = g_bytes_get_data (pic->bytes, &data_size);
+
+ if (!g_output_stream_write_all (G_OUTPUT_STREAM (file_ostream), data,
+ data_size, &bytes_written, NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
" bytes of picture data were written", bytes_written,
- pic->size);
+ g_bytes_get_size (pic->bytes));
g_object_unref (file_ostream);
g_assert (error == NULL || *error != NULL);
return FALSE;
diff --git a/src/picture.h b/src/picture.h
index 2363dfc..bb8f2d1 100644
--- a/src/picture.h
+++ b/src/picture.h
@@ -32,8 +32,7 @@ struct _Picture
gchar *description;
gint width; // Original width of the picture
gint height; // Original height of the picture
- gulong size; // Picture size in bits
- guchar *data;
+ GBytes *bytes;
Picture *next;
};*/
diff --git a/src/tag_area.c b/src/tag_area.c
index 30c2dfb..c6968c3 100644
--- a/src/tag_area.c
+++ b/src/tag_area.c
@@ -1223,6 +1223,8 @@ PictureEntry_Clear (EtTagArea *self)
model = GTK_TREE_MODEL (priv->images_model);
+ /* FIXME: Make Picture a boxed type, so that it can be freed
+ * automatically. */
if (gtk_tree_model_get_iter_first (model, &iter))
{
do
@@ -1248,17 +1250,17 @@ PictureEntry_Update (EtTagArea *self,
priv = et_tag_area_get_instance_private (self);
- if (!pic->data)
- {
- PictureEntry_Clear (self);
- return;
- }
-
loader = gdk_pixbuf_loader_new ();
if (loader)
{
- if (gdk_pixbuf_loader_write(loader, pic->data, pic->size, &error))
+ gconstpointer data;
+ gsize data_size;
+
+ data = g_bytes_get_data (pic->bytes, &data_size);
+
+ /* TODO: Use gdk_pixbuf_loader_write_bytes(). */
+ if (gdk_pixbuf_loader_write (loader, data, data_size, &error))
{
GtkTreeSelection *selection;
GdkPixbuf *pixbuf;
diff --git a/src/tags/flac_tag.c b/src/tags/flac_tag.c
index e659210..7156fcb 100644
--- a/src/tags/flac_tag.c
+++ b/src/tags/flac_tag.c
@@ -678,8 +678,7 @@ flac_tag_read_file_tag (GFile *file,
prev_pic->next = pic;
prev_pic = pic;
- pic->size = p->data_length;
- pic->data = g_memdup(p->data,pic->size);
+ pic->bytes = g_bytes_new (p->data, p->data_length);
pic->type = p->type;
pic->description = g_strdup((gchar *)p->description);
// Not necessary: will be calculated later
@@ -1077,11 +1076,14 @@ flac_tag_write_file_tag (const ET_File *ETFile,
Picture *pic = FileTag->picture;
while (pic)
{
- if (pic->data)
+ /* TODO: Can this ever be NULL? */
+ if (pic->bytes)
{
const gchar *violation;
FLAC__StreamMetadata *picture_block; // For picture data
Picture_Format format;
+ gconstpointer data;
+ gsize data_size;
// Allocate block for picture data
picture_block = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PICTURE);
@@ -1107,8 +1109,10 @@ flac_tag_write_file_tag (const ET_File *ETFile,
picture_block->data.picture.depth = 0;
/* Picture data. */
+ data = g_bytes_get_data (pic->bytes, &data_size);
FLAC__metadata_object_picture_set_data (picture_block,
- (FLAC__byte *)pic->data, (FLAC__uint32) pic->size,
+ (FLAC__byte *)data,
+ (FLAC__uint32)data_size,
TRUE);
if (!FLAC__metadata_object_picture_is_legal (picture_block,
diff --git a/src/tags/id3_tag.c b/src/tags/id3_tag.c
index 7300600..e755c7a 100644
--- a/src/tags/id3_tag.c
+++ b/src/tags/id3_tag.c
@@ -520,7 +520,13 @@ id3tag_write_file_v23tag (const ET_File *ETFile,
Id3tag_Set_Field(id3_frame, ID3FN_DESCRIPTION, pic->description);
if ((id3_field = ID3Frame_GetField(id3_frame,ID3FN_DATA)))
- ID3Field_SetBINARY(id3_field, pic->data, pic->size);
+ {
+ gconstpointer data;
+ gsize data_size;
+
+ data = g_bytes_get_data (pic->bytes, &data_size);
+ ID3Field_SetBINARY (id3_field, data, data_size);
+ }
has_picture = TRUE;
}
diff --git a/src/tags/id3v24_tag.c b/src/tags/id3v24_tag.c
index a6b4dca..8c5159a 100644
--- a/src/tags/id3v24_tag.c
+++ b/src/tags/id3v24_tag.c
@@ -456,9 +456,7 @@ id3tag_read_file_tag (GFile *gfile,
prev_pic->next = pic;
prev_pic = pic;
- pic->data = NULL;
-
- // Picture file data
+ /* Picture file data. */
for (j = 0; (field = id3_frame_field(frame, j)); j++)
{
switch (id3_field_type(field))
@@ -468,14 +466,21 @@ id3tag_read_file_tag (GFile *gfile,
id3_length_t size;
id3_byte_t const *data;
- data = id3_field_getbinarydata(field, &size);
- if (pic->data)
- g_free(pic->data);
- if ( data && (pic->data = g_memdup(data, size)) )
- pic->size = size;
+ data = id3_field_getbinarydata (field, &size);
+
+ if (data)
+ {
+ if (pic->bytes)
+ {
+ g_bytes_unref (pic->bytes);
+ }
+
+ pic->bytes = g_bytes_new (data, size);
+ }
}
break;
case ID3_FIELD_TYPE_INT8:
+ /* TODO: Verify that the type matches with EtPictureType. */
pic->type = id3_field_getint(field);
break;
default:
@@ -1157,7 +1162,13 @@ id3tag_write_file_v24tag (const ET_File *ETFile,
id3_field_setint(field, pic->type);
break;
case ID3_FIELD_TYPE_BINARYDATA:
- id3_field_setbinarydata(field, pic->data, pic->size);
+ {
+ gconstpointer data;
+ gsize data_size;
+
+ data = g_bytes_get_data (pic->bytes, &data_size);
+ id3_field_setbinarydata (field, data, data_size);
+ }
break;
default:
break;
diff --git a/src/tags/mp4_tag.cc b/src/tags/mp4_tag.cc
index f03a2d2..7be5b9e 100644
--- a/src/tags/mp4_tag.cc
+++ b/src/tags/mp4_tag.cc
@@ -211,9 +211,9 @@ mp4tag_read_file_tag (GFile *file,
FileTag->picture = Picture_Allocate ();
- FileTag->picture->size = art.data ().size ();
- FileTag->picture->data = (guchar *)g_memdup (art.data ().data (),
- art.data ().size ());
+ /* TODO: Use g_bytes_new_with_free_func()? */
+ FileTag->picture->bytes = g_bytes_new (art.data ().data (),
+ art.data ().size ());
}
else
{
@@ -438,6 +438,8 @@ mp4tag_write_file_tag (const ET_File *ETFile,
{
Picture_Format pf;
TagLib::MP4::CoverArt::Format f;
+ gconstpointer data;
+ gsize data_size;
pf = Picture_Format_From_Data (FileTag->picture);
@@ -458,8 +460,9 @@ mp4tag_write_file_tag (const ET_File *ETFile,
break;
}
- TagLib::MP4::CoverArt art (f, TagLib::ByteVector((char *)FileTag->picture->data,
- FileTag->picture->size));
+ data = g_bytes_get_data (FileTag->picture->bytes, &data_size);
+ TagLib::MP4::CoverArt art (f, TagLib::ByteVector((char *)data,
+ data_size));
extra_items.insert ("covr",
TagLib::MP4::Item (TagLib::MP4::CoverArtList ().append (art)));
diff --git a/src/tags/ogg_tag.c b/src/tags/ogg_tag.c
index 2bdcbce..fe2aba2 100644
--- a/src/tags/ogg_tag.c
+++ b/src/tags/ogg_tag.c
@@ -120,13 +120,16 @@ convert_to_byte_array (guint32 n, guchar *array)
*/
static void
-add_to_guchar_str (guchar *ustr, gsize *ustr_len, guchar *str, gsize str_len)
+add_to_guchar_str (guchar *ustr,
+ gsize *ustr_len,
+ const guchar *str,
+ gsize str_len)
{
gsize i;
for (i = *ustr_len; i < *ustr_len + str_len; i++)
{
- ustr [i] = str [i - *ustr_len];
+ ustr[i] = str[i - *ustr_len];
}
*ustr_len += str_len;
@@ -479,6 +482,8 @@ et_add_file_tags_from_vorbis_comments (vorbis_comment *vc,
while ( (string = vorbis_comment_query(vc,"COVERART",field_num++)) != NULL )
{
Picture *pic;
+ guchar *data;
+ gsize data_size;
/* Force marking the file as modified, so that the deprecated cover art
* field in converted in a METADATA_PICTURE_BLOCK field. */
@@ -491,10 +496,9 @@ et_add_file_tags_from_vorbis_comments (vorbis_comment *vc,
prev_pic->next = pic;
prev_pic = pic;
- pic->data = NULL;
-
- // Decode picture data
- pic->data = g_base64_decode (string, &pic->size);
+ /* Decode picture data. */
+ data = g_base64_decode (string, &data_size);
+ pic->bytes = g_bytes_new_take (data, data_size);
if ( (string = vorbis_comment_query(vc,"COVERARTTYPE",field_num-1)) != NULL )
{
@@ -521,7 +525,9 @@ et_add_file_tags_from_vorbis_comments (vorbis_comment *vc,
Picture *pic;
gsize bytes_pos, mimelen, desclen;
guchar *decoded_ustr;
- gsize decoded_len;
+ GBytes *bytes;
+ gsize decoded_size;
+ gsize data_size;
pic = Picture_Allocate();
@@ -536,10 +542,9 @@ et_add_file_tags_from_vorbis_comments (vorbis_comment *vc,
prev_pic = pic;
- pic->data = NULL;
-
/* Decode picture data. */
- decoded_ustr = g_base64_decode (string, &decoded_len);
+ decoded_ustr = g_base64_decode (string, &decoded_size);
+ bytes = g_bytes_new_take (decoded_ustr, decoded_size);
/* Reading picture type. */
pic->type = read_guint32_from_byte (decoded_ustr, 0);
@@ -564,18 +569,14 @@ et_add_file_tags_from_vorbis_comments (vorbis_comment *vc,
bytes_pos += desclen + 16;
/* Reading picture size */
- pic->size = read_guint32_from_byte (decoded_ustr, bytes_pos);
+ data_size = read_guint32_from_byte (decoded_ustr, bytes_pos);
bytes_pos += 4;
- /* Reading decoded picture */
- pic->data = g_malloc (pic->size);
+ /* Read only the image data into a new GBytes. */
+ pic->bytes = g_bytes_new_from_bytes (bytes, bytes_pos, data_size);
- for (i = 0; i < pic->size; i++)
- {
- pic->data [i] = decoded_ustr [i + bytes_pos];
- }
-
- g_free (decoded_ustr);
+ /* pic->bytes still holds a ref on the decoded data. */
+ g_bytes_unref (bytes);
}
/***************************
@@ -900,139 +901,142 @@ ogg_tag_write_file_tag (const ET_File *ETFile,
**************/
et_ogg_set_tag (vc, "ENCODED-BY=", FileTag->encoded_by, FALSE);
-
/***********
* Picture *
***********/
for (pic = FileTag->picture; pic != NULL; pic = pic->next)
{
- if (pic->data)
+ const gchar *mime;
+ guchar array[4];
+ guchar *ustring = NULL;
+ gsize ustring_len = 0;
+ gchar *base64_string;
+ gsize desclen;
+ gconstpointer data;
+ gsize data_size;
+ Picture_Format format = Picture_Format_From_Data (pic);
+
+ /* According to the specification, only PNG and JPEG images should
+ * be added to Vorbis comments. */
+ if (format != PICTURE_FORMAT_PNG && format != PICTURE_FORMAT_JPEG)
{
- const gchar *mime;
- guchar array[4];
- guchar *ustring = NULL;
- gsize ustring_len = 0;
- gchar *base64_string;
- gsize desclen;
- Picture_Format format = Picture_Format_From_Data (pic);
-
- /* According to the specification, only PNG and JPEG images should
- * be added to Vorbis comments. */
- if (format != PICTURE_FORMAT_PNG && format != PICTURE_FORMAT_JPEG)
- {
- GdkPixbufLoader *loader;
- GError *error = NULL;
+ GdkPixbufLoader *loader;
+ gconstpointer data;
+ gsize data_size;
+ GError *error = NULL;
- loader = gdk_pixbuf_loader_new ();
+ loader = gdk_pixbuf_loader_new ();
+
+ data = g_bytes_get_data (pic->bytes, &data_size);
+
+ /* TODO: Use gdk_pixbuf_loader_write_bytes() */
+ if (!gdk_pixbuf_loader_write (loader, data, data_size, &error))
+ {
+ g_debug ("Error parsing image data: %s", error->message);
+ g_error_free (error);
+ g_object_unref (loader);
+ continue;
+ }
+ else
+ {
+ GdkPixbuf *pixbuf;
+ gchar *buffer;
+ gsize buffer_size;
- if (!gdk_pixbuf_loader_write (loader, pic->data, pic->size,
- &error))
+ if (!gdk_pixbuf_loader_close (loader, &error))
{
- g_debug ("Error parsing image data: %s", error->message);
+ g_debug ("Error parsing image data: %s",
+ error->message);
g_error_free (error);
g_object_unref (loader);
continue;
}
- else
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (!pixbuf)
{
- GdkPixbuf *pixbuf;
- gchar *buffer;
- gsize buffer_size;
-
- if (!gdk_pixbuf_loader_close (loader, &error))
- {
- g_debug ("Error parsing image data: %s",
- error->message);
- g_error_free (error);
- g_object_unref (loader);
- continue;
- }
-
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
-
- if (!pixbuf)
- {
- g_object_unref (loader);
- continue;
- }
-
- g_object_ref (pixbuf);
g_object_unref (loader);
+ continue;
+ }
- /* Always convert to PNG. */
- if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer,
- &buffer_size, "png",
- &error, NULL))
- {
- g_debug ("Error while converting image to PNG: %s",
- error->message);
- g_error_free (error);
- g_object_unref (pixbuf);
- continue;
- }
+ g_object_ref (pixbuf);
+ g_object_unref (loader);
+ /* Always convert to PNG. */
+ if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer,
+ &buffer_size, "png",
+ &error, NULL))
+ {
+ g_debug ("Error while converting image to PNG: %s",
+ error->message);
+ g_error_free (error);
g_object_unref (pixbuf);
+ continue;
+ }
- g_free (pic->data);
- pic->data = (guchar *)buffer;
- pic->size = buffer_size;
+ g_object_unref (pixbuf);
- /* Set the picture format to reflect the new data. */
- format = Picture_Format_From_Data (pic);
- }
+ g_bytes_unref (pic->bytes);
+ pic->bytes = g_bytes_new_take (buffer, buffer_size);
+
+ /* Set the picture format to reflect the new data. */
+ format = Picture_Format_From_Data (pic);
}
+ }
- mime = Picture_Mime_Type_String (format);
+ mime = Picture_Mime_Type_String (format);
- /* Calculating full length of byte string and allocating. */
- desclen = pic->description ? strlen (pic->description) : 0;
- ustring = g_malloc (4 * 8 + strlen (mime) + desclen + pic->size);
+ data = g_bytes_get_data (pic->bytes, &data_size);
- /* Adding picture type. */
- convert_to_byte_array (pic->type, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ /* Calculating full length of byte string and allocating. */
+ desclen = pic->description ? strlen (pic->description) : 0;
+ ustring = g_malloc (4 * 8 + strlen (mime) + desclen + data_size);
- /* Adding MIME string and its length. */
- convert_to_byte_array (strlen (mime), array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
- add_to_guchar_str (ustring, &ustring_len, (guchar *)mime,
- strlen (mime));
+ /* Adding picture type. */
+ convert_to_byte_array (pic->type, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- /* Adding picture description. */
- convert_to_byte_array (desclen, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
- add_to_guchar_str (ustring, &ustring_len,
- (guchar *)pic->description,
- desclen);
+ /* Adding MIME string and its length. */
+ convert_to_byte_array (strlen (mime), array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
+ add_to_guchar_str (ustring, &ustring_len, (guchar *)mime,
+ strlen (mime));
- /* Adding width, height, color depth, indexed colors. */
- convert_to_byte_array (pic->width, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ /* Adding picture description. */
+ convert_to_byte_array (desclen, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
+ add_to_guchar_str (ustring, &ustring_len,
+ (guchar *)pic->description,
+ desclen);
- convert_to_byte_array (pic->height, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ /* Adding width, height, color depth, indexed colors. */
+ convert_to_byte_array (pic->width, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- convert_to_byte_array (0, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ convert_to_byte_array (pic->height, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- convert_to_byte_array (0, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ convert_to_byte_array (0, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- /* Adding picture data and its size. */
- convert_to_byte_array (pic->size, array);
- add_to_guchar_str (ustring, &ustring_len, array, 4);
+ convert_to_byte_array (0, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- add_to_guchar_str (ustring, &ustring_len, pic->data, pic->size);
+ /* Adding picture data and its size. */
+ convert_to_byte_array (data_size, array);
+ add_to_guchar_str (ustring, &ustring_len, array, 4);
- base64_string = g_base64_encode (ustring, ustring_len);
- string = g_strconcat ("METADATA_BLOCK_PICTURE=", base64_string,
- NULL);
- vorbis_comment_add (vc, string);
+ add_to_guchar_str (ustring, &ustring_len, data, data_size);
- g_free (base64_string);
- g_free (ustring);
- g_free (string);
- }
+ base64_string = g_base64_encode (ustring, ustring_len);
+ string = g_strconcat ("METADATA_BLOCK_PICTURE=", base64_string,
+ NULL);
+ vorbis_comment_add (vc, string);
+
+ g_free (base64_string);
+ g_free (ustring);
+ g_free (string);
}
/**************************
diff --git a/tests/test-picture.c b/tests/test-picture.c
index a1970d1..adcb7d6 100644
--- a/tests/test-picture.c
+++ b/tests/test-picture.c
@@ -34,8 +34,7 @@ picture_copy (void)
pic1->width = 640;
pic1->height = 480;
pic1->description = g_strdup ("foobar.png");
- pic1->size = 10;
- pic1->data = g_malloc0 (pic1->size);
+ pic1->bytes = g_bytes_new_static ("foobar", 6);
pic2 = Picture_Copy (pic1);
@@ -43,7 +42,9 @@ picture_copy (void)
g_assert_cmpint (pic2->width, ==, 640);
g_assert_cmpint (pic2->height, ==, 480);
g_assert_cmpstr (pic2->description, ==, "foobar.png");
- g_assert_cmpint (pic2->size, ==, 10);
+ g_assert_cmpint (g_bytes_hash (pic2->bytes), ==,
+ g_bytes_hash (pic1->bytes));
+ g_assert (pic2->bytes == pic1->bytes);
g_assert (pic2->next == NULL);
pic3 = Picture_Allocate ();
@@ -52,8 +53,7 @@ picture_copy (void)
pic3->width = 320;
pic3->height = 240;
pic3->description = g_strdup ("bash.jpg");
- pic3->size = 20;
- pic3->data = g_malloc0 (pic3->size);
+ pic3->bytes = g_bytes_new_static ("foo", 3);
pic1->next = pic2;
pic2->next = pic3;
@@ -64,7 +64,7 @@ picture_copy (void)
g_assert_cmpint (pic2_copy->width, ==, 640);
g_assert_cmpint (pic2_copy->height, ==, 480);
g_assert_cmpstr (pic2_copy->description, ==, "foobar.png");
- g_assert_cmpint (pic2_copy->size, ==, 10);
+ g_assert_cmpint (g_bytes_get_size (pic2_copy->bytes), ==, 6);
g_assert (pic2_copy->next == NULL);
pic1_copy = Picture_Copy (pic1);
@@ -79,7 +79,7 @@ picture_copy (void)
g_assert_cmpint (pic3_copy->width, ==, 320);
g_assert_cmpint (pic3_copy->height, ==, 240);
g_assert_cmpstr (pic3_copy->description, ==, "bash.jpg");
- g_assert_cmpint (pic3_copy->size, ==, 20);
+ g_assert_cmpint (g_bytes_get_size (pic3_copy->bytes), ==, 3);
Picture_Free (pic1_copy);
Picture_Free (pic2_copy);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]