static void handle_id3v2_apic (xmms_xform_t *xform, xmms_id3v2_header_t *head, const gchar *key, gchar *buf, gsize len) { const gchar *enc, *typ, *desc, *data, *mime; gchar hash[33]; enc = binary_to_enc (buf[0]); buf++; len--; mime = buf; typ = find_nul (buf, &len); if (typ[0] != 0x00 && typ[0] != 0x03) { XMMS_DBG ("Picture type %02x not handled", typ[0]); return; } desc = typ + 1; len--; /* XXX desc might be UCS2 and find_nul will not do what we want */ data = find_nul (desc, &len); if (data && xmms_bindata_plugin_add ((const guchar *)data, len, hash)) { const gchar *metakey; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; xmms_xform_metadata_set_str (xform, metakey, mime); } }
static gboolean xmms_apetag_handle_tag_coverart (xmms_xform_t *xform, const gchar *key, const gchar *value, gsize length) { const gchar *mime, *ptr; gchar *filename; gchar hash[33]; gsize size; if (*value == '\0') { return FALSE; } filename = g_strndup (value, length); if (!filename) { return FALSE; } if (g_str_has_suffix (filename, "jpg")) { mime = "image/jpeg"; } else if (g_str_has_suffix (filename, "png")) { mime = "image/png"; } else { XMMS_DBG ("Unknown image format: %s", filename); g_free (filename); return FALSE; } ptr = value + strlen (filename) + 1; size = length - (ptr - value); if (xmms_bindata_plugin_add ((const guchar *) ptr, size, hash)) { const gchar *metakey; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; xmms_xform_metadata_set_str (xform, metakey, mime); } g_free (filename); return TRUE; }
static gboolean xmms_mp4_mediainfo_set_coverart (xmms_xform_t *xform, const gchar *key, const gchar *value, gsize length) { const gchar *metakey; gchar hash[33]; if (!xmms_bindata_plugin_add ((const guchar *) value, length, hash)) { return FALSE; } metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; xmms_xform_metadata_set_str (xform, metakey, "image/jpeg"); return TRUE; }
static void flac_callback_metadata (const FLAC__StreamDecoder *flacdecoder, const FLAC__StreamMetadata *metadata, void *client_data) { xmms_flac_data_t *data; xmms_xform_t *xform = (xmms_xform_t *) client_data; gint32 filesize; const gchar *metakey; g_return_if_fail (xform); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE; if (!xmms_xform_metadata_get_int (xform, metakey, &filesize)) { filesize = -1; } data = xmms_xform_private_data_get (xform); switch (metadata->type) { case FLAC__METADATA_TYPE_STREAMINFO: /* FLAC__metadata_object_clone ()? */ data->bits_per_sample = metadata->data.stream_info.bits_per_sample; data->sample_rate = metadata->data.stream_info.sample_rate; data->channels = metadata->data.stream_info.channels; data->total_samples = metadata->data.stream_info.total_samples; if (filesize > 0 && data->total_samples) { data->bit_rate = (guint) ((guint64) filesize * 8 * (guint64) data->sample_rate / (guint64) data->total_samples); } XMMS_DBG ("STREAMINFO: BPS %d. Samplerate: %d. Channels: %d.", data->bits_per_sample, data->sample_rate, data->channels); break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: data->vorbiscomment = FLAC__metadata_object_clone (metadata); break; #if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7 case FLAC__METADATA_TYPE_PICTURE: { gchar hash[33]; if (metadata->data.picture.type == FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER && xmms_bindata_plugin_add (metadata->data.picture.data, metadata->data.picture.data_length, hash)) { const gchar *metakey; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; xmms_xform_metadata_set_str (xform, metakey, metadata->data.picture.mime_type); } break; } #endif /* if we want to support more metadata types here, * don't forget to add a call to * FLAC__stream_decoder_set_metadata_respond() below. */ default: break; } }
static gboolean xmms_asf_handle_tag_coverart (xmms_xform_t *xform, const gchar *key, const gchar *value, gsize length) { const guint8 *uptr; const gchar *ptr; gchar *mime; gchar hash[33]; guint32 picture_length; gsize size; GError *err = NULL; uptr = (const guchar *) value; /* check picture type */ if (uptr[0] != 0x00 && uptr[0] != 0x03) { return FALSE; } /* step past picture type */ uptr++; picture_length = ((guint32) uptr[3] << 24) | ((guint32) uptr[2] << 16) | ((guint32) uptr[1] << 8) | ((guint32) uptr[0]); if (picture_length == 0) { return FALSE; } /* step past picture size */ uptr += sizeof (guint32); ptr = (const gchar *) uptr; /* parse the UTF-16 mime type */ size = xmms_asf_utf16_strnlen (ptr, (value + length) - ptr); mime = g_convert (ptr, size, "UTF-8", "UTF-16", NULL, NULL, &err); ptr += size + 2; if (mime == NULL || mime[0] == '\0') { return FALSE; } /* step past picture description */ size = xmms_asf_utf16_strnlen (ptr, (value + length) - ptr); ptr += size + 2; uptr = (const guchar *) ptr; if (xmms_bindata_plugin_add (uptr, picture_length, hash)) { const gchar *metakey; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; xmms_xform_metadata_set_str (xform, metakey, mime); } g_free (mime); return TRUE; }
static gboolean handle_image_comment (xmms_xform_t *xform, const gchar *key, const gchar *encoded_value, gsize length) { gsize len; guchar *value; guint32 typ, mime_len, desc_len, img_len; guchar *pos, *end, *mime_data, *img_data; gchar hash[33]; #if GLIB_CHECK_VERSION(2,12,0) value = g_base64_decode (encoded_value, &len); #else /* TODO: Implement/backport base64 decoding */ return; #endif pos = value; end = value + len; if (pos + sizeof (guint32) > end) { XMMS_DBG ("Malformed picture comment"); goto finish; } typ = decode_uint32 (&pos); if (typ != 0 && typ != 3) { XMMS_DBG ("Picture type %d not handled", typ); goto finish; } if (pos + sizeof (guint32) > end) { XMMS_DBG ("Malformed picture comment"); goto finish; } mime_len = decode_uint32 (&pos); mime_data = pos; pos += mime_len; if (pos + sizeof (guint32) > end) { XMMS_DBG ("Malformed picture comment"); goto finish; } desc_len = decode_uint32 (&pos); pos += desc_len; decode_uint32 (&pos); /* width */ decode_uint32 (&pos); /* height */ decode_uint32 (&pos); /* depth */ decode_uint32 (&pos); /* indexed palette length */ if (pos + sizeof (guint32) > end) { XMMS_DBG ("Malformed picture comment"); goto finish; } img_len = decode_uint32 (&pos); img_data = pos; if (img_data + img_len > end) { XMMS_DBG ("Malformed picture comment"); goto finish; } if (xmms_bindata_plugin_add (img_data, img_len, hash)) { const gchar *metakey; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT; xmms_xform_metadata_set_str (xform, metakey, hash); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_PICTURE_FRONT_MIME; mime_data[mime_len] = '\0'; xmms_xform_metadata_set_str (xform, metakey, (gchar *)mime_data); } finish: g_free (value); return TRUE; }