Пример #1
0
/*
 * Read tag data from a FLAC file using the level 2 flac interface,
 * Note:
 *  - if field is found but contains no info (strlen(str)==0), we don't read it
 */
gboolean
flac_tag_read_file_tag (GFile *file,
                        File_Tag *FileTag,
                        GError **error)
{
    FLAC__Metadata_Chain *chain;
    EtFlacReadState state;
    FLAC__IOCallbacks callbacks = { et_flac_read_func,
                                    NULL, /* Do not set a write callback. */
                                    et_flac_seek_func, et_flac_tell_func,
                                    et_flac_eof_func,
                                    et_flac_read_close_func
                                  };
    FLAC__Metadata_Iterator *iter;

    EtPicture *prev_pic = NULL;

    g_return_val_if_fail (file != NULL && FileTag != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    chain = FLAC__metadata_chain_new ();

    if (chain == NULL)
    {
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, "%s",
                     g_strerror (ENOMEM));
        return FALSE;
    }

    state.error = NULL;
    state.istream = g_file_read (file, NULL, &state.error);
    state.seekable = G_SEEKABLE (state.istream);

    if (!FLAC__metadata_chain_read_with_callbacks (chain, &state, callbacks))
    {
        /* TODO: Provide a dedicated error enum corresponding to status. */
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                     _("Error opening FLAC file"));
        et_flac_read_close_func (&state);

        return FALSE;
    }

    iter = FLAC__metadata_iterator_new ();

    if (iter == NULL)
    {
        et_flac_read_close_func (&state);
        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, "%s",
                     g_strerror (ENOMEM));
        return FALSE;
    }

    FLAC__metadata_iterator_init (iter, chain);

    while (FLAC__metadata_iterator_next (iter))
    {
        FLAC__StreamMetadata *block;

        block = FLAC__metadata_iterator_get_block (iter);

        if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
        {
            const FLAC__StreamMetadata_VorbisComment *vc;
            GHashTable *tags;
            GSList *strings;
            GHashTableIter tags_iter;
            gchar *key;

            /* Get comments from block. */
            vc = &block->data.vorbis_comment;
            tags = populate_tag_hash_table (vc);

            /* Title */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_TITLE)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->title);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_TITLE);
            }

            /* Artist */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_ARTIST)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->artist);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_ARTIST);
            }

            /* Album artist. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_ALBUM_ARTIST)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->album_artist);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_ALBUM_ARTIST);
            }

            /* Album. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_ALBUM)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->album);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_ALBUM);
            }

            /* Disc number and total discs. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_DISC_TOTAL)))
            {
                /* Only take values from the first total discs field. */
                if (!et_str_empty (strings->data))
                {
                    FileTag->disc_total = et_disc_number_to_string (atoi (strings->data));
                }

                g_slist_free_full (strings, g_free);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_DISC_TOTAL);
            }

            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_DISC_NUMBER)))
            {
                /* Only take values from the first disc number field. */
                if (!et_str_empty (strings->data))
                {
                    gchar *separator;

                    separator = strchr (strings->data, '/');

                    if (separator && !FileTag->disc_total)
                    {
                        FileTag->disc_total = et_disc_number_to_string (atoi (separator + 1));
                        *separator = '\0';
                    }

                    FileTag->disc_number = et_disc_number_to_string (atoi (strings->data));
                }

                g_slist_free_full (strings, g_free);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_DISC_NUMBER);
            }

            /* Track number and total tracks. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_TRACK_TOTAL)))
            {
                /* Only take values from the first total tracks field. */
                if (!et_str_empty (strings->data))
                {
                    FileTag->track_total = et_track_number_to_string (atoi (strings->data));
                }

                g_slist_free_full (strings, g_free);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_TRACK_TOTAL);
            }

            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_TRACK_NUMBER)))
            {
                /* Only take values from the first track number field. */
                if (!et_str_empty (strings->data))
                {
                    gchar *separator;

                    separator = strchr (strings->data, '/');

                    if (separator && !FileTag->track_total)
                    {
                        FileTag->track_total = et_track_number_to_string (atoi (separator + 1));
                        *separator = '\0';
                    }

                    FileTag->track = et_track_number_to_string (atoi (strings->data));
                }

                g_slist_free_full (strings, g_free);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_TRACK_NUMBER);
            }

            /* Year. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_DATE)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->year);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_DATE);
            }

            /* Genre. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_GENRE)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->genre);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_GENRE);
            }

            /* Comment. */
            {
                GSList *descs;
                GSList *comments;

                descs = g_hash_table_lookup (tags,
                                             ET_VORBIS_COMMENT_FIELD_DESCRIPTION);
                comments = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_COMMENT);

                /* Prefer DESCRIPTION, as it is part of the spec. */
                if (descs && !comments)
                {
                    g_slist_foreach (descs, values_list_foreach,
                                     &FileTag->comment);
                }
                else if (descs && comments)
                {
                    /* Mark the file as modified, so that comments are written
                     * to the DESCRIPTION field on saving. */
                    FileTag->saved = FALSE;

                    g_slist_foreach (descs, values_list_foreach,
                                     &FileTag->comment);
                    g_slist_foreach (comments, values_list_foreach,
                                     &FileTag->comment);
                }
                else if (comments)
                {
                    FileTag->saved = FALSE;

                    g_slist_foreach (comments, values_list_foreach,
                                     &FileTag->comment);
                }

                g_slist_free (descs);
                g_slist_free (comments);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_DESCRIPTION);
                g_hash_table_remove (tags,
                                     ET_VORBIS_COMMENT_FIELD_COMMENT);
            }

            /* Composer. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_COMPOSER)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->composer);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_COMPOSER);
            }

            /* Original artist. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_PERFORMER)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->orig_artist);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_PERFORMER);
            }

            /* Copyright. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_COPYRIGHT)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->copyright);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_COPYRIGHT);
            }

            /* URL. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_CONTACT)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->url);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_CONTACT);
            }

            /* Encoded by. */
            if ((strings = g_hash_table_lookup (tags,
                                                ET_VORBIS_COMMENT_FIELD_ENCODED_BY)))
            {
                g_slist_foreach (strings, values_list_foreach,
                                 &FileTag->encoded_by);
                g_slist_free (strings);
                g_hash_table_remove (tags, ET_VORBIS_COMMENT_FIELD_ENCODED_BY);
            }

            /* Save unsupported fields. */
            g_hash_table_iter_init (&tags_iter, tags);

            while (g_hash_table_iter_next (&tags_iter, (gpointer *)&key,
                                           (gpointer *)&strings))
            {
                GSList *l;

                for (l = strings; l != NULL; l = g_slist_next (l))
                {
                    FileTag->other = g_list_prepend (FileTag->other,
                                                     g_strconcat (key,
                                                             "=",
                                                             l->data,
                                                             NULL));
                }

                g_slist_free_full (strings, g_free);
                g_hash_table_iter_remove (&tags_iter);
            }

            if (FileTag->other)
            {
                FileTag->other = g_list_reverse (FileTag->other);
            }

            /* The hash table should now only contain keys. */
            g_hash_table_unref (tags);
        }
        else if (block->type == FLAC__METADATA_TYPE_PICTURE)
        {
            /* Picture. */
            const FLAC__StreamMetadata_Picture *p;
            GBytes *bytes;
            EtPicture *pic;

            /* Get picture data from block. */
            p = &block->data.picture;

            bytes = g_bytes_new (p->data, p->data_length);

            pic = et_picture_new (p->type, (const gchar *)p->description,
                                  0, 0, bytes);
            g_bytes_unref (bytes);

            if (!prev_pic)
            {
                FileTag->picture = pic;
            }
            else
            {
                prev_pic->next = pic;
            }

            prev_pic = pic;
        }
    }

    FLAC__metadata_iterator_delete (iter);
    FLAC__metadata_chain_delete (chain);
    et_flac_read_close_func (&state);

#ifdef ENABLE_MP3
    /* If no FLAC vorbis tag found : we try to get the ID3 tag if it exists
     * (but it will be deleted when rewriting the tag) */
    if ( FileTag->title       == NULL
            && FileTag->artist      == NULL
            && FileTag->album_artist == NULL
            && FileTag->album       == NULL
            && FileTag->disc_number == NULL
            && FileTag->disc_total == NULL
            && FileTag->year        == NULL
            && FileTag->track       == NULL
            && FileTag->track_total == NULL
            && FileTag->genre       == NULL
            && FileTag->comment     == NULL
            && FileTag->composer    == NULL
            && FileTag->orig_artist == NULL
            && FileTag->copyright   == NULL
            && FileTag->url         == NULL
            && FileTag->encoded_by  == NULL
            && FileTag->picture     == NULL)
    {
        id3tag_read_file_tag (file, FileTag, NULL);

        // If an ID3 tag has been found (and no FLAC tag), we mark the file as
        // unsaved to rewrite a flac tag.
        if ( FileTag->title       != NULL
                || FileTag->artist      != NULL
                || FileTag->album_artist != NULL
                || FileTag->album       != NULL
                || FileTag->disc_number != NULL
                || FileTag->disc_total != NULL
                || FileTag->year        != NULL
                || FileTag->track       != NULL
                || FileTag->track_total != NULL
                || FileTag->genre       != NULL
                || FileTag->comment     != NULL
                || FileTag->composer    != NULL
                || FileTag->orig_artist != NULL
                || FileTag->copyright   != NULL
                || FileTag->url         != NULL
                || FileTag->encoded_by  != NULL
                || FileTag->picture     != NULL)
        {
            FileTag->saved = FALSE;
        }
    }
#endif

    return TRUE;
}
Пример #2
0
/*
 * Read tag data from a Wavpack file.
 */
gboolean Wavpack_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    WavpackContext *wpc;
    gchar *field, *field2;
    guint length;

    int open_flags = OPEN_TAGS;

    g_return_val_if_fail (filename != NULL && FileTag != NULL, FALSE);

    wpc = WavpackOpenFileInput(filename, NULL, open_flags, 0);

    if ( wpc == NULL ) {
        return FALSE;
    }

    /*
     * Title
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "title", field, MAXLEN);

    if ( length > 0 && FileTag->title == NULL ) {
        FileTag->title = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Artist
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "artist", field, MAXLEN);

    if ( length > 0 && FileTag->artist == NULL) {
        FileTag->artist = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Album
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "album", field, MAXLEN);

    if ( length > 0 && FileTag->album == NULL ) {
        FileTag->album = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Discnumber + Disctotal.
     */
    field = g_malloc0 (sizeof (char) * MAXLEN);
    length = WavpackGetTagItem (wpc, "part", field, MAXLEN);
    field2 = g_utf8_strchr (field, -1, '/');

    /* Need to cut off the total tracks if present */
    if (field2)
    {
        *field2 = 0;
        field2++;
    }

    if (field2 && FileTag->disc_total == NULL)
    {
        FileTag->disc_total = et_disc_number_to_string (atoi (Try_To_Validate_Utf8_String (field2)));
    }
    if (length > 0 && FileTag->disc_number == NULL)
    {
        FileTag->disc_number = et_disc_number_to_string (atoi (Try_To_Validate_Utf8_String (field)));
    }

    g_free (field);

    /*
     * Year
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "year", field, MAXLEN);

    if ( length > 0 && FileTag->year == NULL ) {
        FileTag->year = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Tracknumber + tracktotal
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "track", field, MAXLEN);
    field2 = g_utf8_strchr(field, -1, '/');

    /* Need to cut off the total tracks if present */
    if (field2) {
        *field2 = 0;
        field2++;
    }

    if (field2 && FileTag->track_total == NULL)
    {
        FileTag->track_total = et_track_number_to_string (atoi (Try_To_Validate_Utf8_String (field2)));
    }
    if (length > 0 && FileTag->track == NULL)
    {
        FileTag->track = et_track_number_to_string (atoi (Try_To_Validate_Utf8_String (field)));
    }

    g_free (field);

    /*
     * Genre
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "genre", field, MAXLEN);

    if ( length > 0 && FileTag->genre == NULL ) {
        FileTag->genre = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Comment
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "comment", field, MAXLEN);

    if ( length > 0 && FileTag->comment == NULL ) {
        FileTag->comment = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Composer
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "composer", field, MAXLEN);

    if ( length > 0 && FileTag->composer == NULL ) {
        FileTag->composer = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Original artist
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "original artist", field, MAXLEN);

    if ( length > 0 && FileTag->orig_artist == NULL ) {
        FileTag->orig_artist  = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Copyright
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "copyright", field, MAXLEN);

    if ( length > 0 && FileTag->copyright == NULL ) {
        FileTag->copyright = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * URL
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "copyright url", field, MAXLEN);

    if ( length > 0 && FileTag->url == NULL ) {
        FileTag->url = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    /*
     * Encoded by
     */
    field = g_malloc0(sizeof(char) * MAXLEN);
    length = WavpackGetTagItem(wpc, "encoded by", field, MAXLEN);

    if ( length > 0 && FileTag->encoded_by == NULL ) {
        FileTag->encoded_by = Try_To_Validate_Utf8_String(field);
    }

    g_free (field);

    WavpackCloseFile(wpc);

    return TRUE;
}
Пример #3
0
/*
 * Read tag data from a Wavpack file.
 */
gboolean
wavpack_tag_read_file_tag (GFile *file,
                           File_Tag *FileTag,
                           GError **error)
{
    WavpackStreamReader reader = { wavpack_read_bytes, wavpack_get_pos,
                                   wavpack_set_pos_abs, wavpack_set_pos_rel,
                                   wavpack_push_back_byte, wavpack_get_length,
                                   wavpack_can_seek, NULL /* No writing. */ };
    EtWavpackState state;
    WavpackContext *wpc;
    gchar message[80];
    gchar field[MAXLEN] = { 0, };
    gchar *field2;
    guint length;
    const int open_flags = OPEN_TAGS;

    g_return_val_if_fail (file != NULL && FileTag != NULL, FALSE);
    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

    state.error = NULL;
    state.istream = g_file_read (file, NULL, &state.error);

    if (!state.istream)
    {
        g_propagate_error (error, state.error);
        return FALSE;
    }

    state.seekable = G_SEEKABLE (state.istream);

    /* NULL for the WavPack correction file. */
    wpc = WavpackOpenFileInputEx (&reader, &state, NULL, message, open_flags,
                                  0);

    if (wpc == NULL)
    {
        if (state.error)
        {
            g_propagate_error (error, state.error);
        }
        else
        {
            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
                         message);
        }

        g_object_unref (state.istream);
        return FALSE;
    }

    /*
     * Title
     */
    length = WavpackGetTagItem(wpc, "title", field, MAXLEN);

    if ( length > 0 && FileTag->title == NULL ) {
        FileTag->title = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Artist
     */
    length = WavpackGetTagItem(wpc, "artist", field, MAXLEN);

    if ( length > 0 && FileTag->artist == NULL) {
        FileTag->artist = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /* Album artist. */
    length = WavpackGetTagItem (wpc, "album artist", field, MAXLEN);

    if (length > 0 && FileTag->album_artist == NULL)
    {
        FileTag->album_artist = Try_To_Validate_Utf8_String (field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Album
     */
    length = WavpackGetTagItem(wpc, "album", field, MAXLEN);

    if ( length > 0 && FileTag->album == NULL ) {
        FileTag->album = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Discnumber + Disctotal.
     */
    length = WavpackGetTagItem (wpc, "part", field, MAXLEN);
    field2 = strchr (field, '/');

    /* Need to cut off the total tracks if present */
    if (field2)
    {
        *field2 = 0;
        field2++;
    }

    if (field2 && FileTag->disc_total == NULL)
    {
        gchar *tmp;

        tmp = Try_To_Validate_Utf8_String (field2);
        FileTag->disc_total = et_disc_number_to_string (atoi (tmp));
        g_free (tmp);
    }

    if (length > 0 && FileTag->disc_number == NULL)
    {
        gchar *tmp;

        tmp = Try_To_Validate_Utf8_String (field);
        FileTag->disc_number = et_disc_number_to_string (atoi (tmp));
        g_free (tmp);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Year
     */
    length = WavpackGetTagItem(wpc, "year", field, MAXLEN);

    if ( length > 0 && FileTag->year == NULL ) {
        FileTag->year = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Tracknumber + tracktotal
     */
    length = WavpackGetTagItem(wpc, "track", field, MAXLEN);
    field2 = strchr (field, '/');

    /* Need to cut off the total tracks if present */
    if (field2) {
        *field2 = 0;
        field2++;
    }

    if (field2 && FileTag->track_total == NULL)
    {
        gchar *tmp;

        tmp = Try_To_Validate_Utf8_String (field2);
        FileTag->track_total = et_track_number_to_string (atoi (tmp));
        g_free (tmp);
    }

    if (length > 0 && FileTag->track == NULL)
    {
        gchar *tmp;

        tmp = Try_To_Validate_Utf8_String (field);
        FileTag->track = et_track_number_to_string (atoi (tmp));
        g_free (tmp);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Genre
     */
    length = WavpackGetTagItem(wpc, "genre", field, MAXLEN);

    if ( length > 0 && FileTag->genre == NULL ) {
        FileTag->genre = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Comment
     */
    length = WavpackGetTagItem(wpc, "comment", field, MAXLEN);

    if ( length > 0 && FileTag->comment == NULL ) {
        FileTag->comment = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Composer
     */
    length = WavpackGetTagItem(wpc, "composer", field, MAXLEN);

    if ( length > 0 && FileTag->composer == NULL ) {
        FileTag->composer = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Original artist
     */
    length = WavpackGetTagItem(wpc, "original artist", field, MAXLEN);

    if ( length > 0 && FileTag->orig_artist == NULL ) {
        FileTag->orig_artist  = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Copyright
     */
    length = WavpackGetTagItem(wpc, "copyright", field, MAXLEN);

    if ( length > 0 && FileTag->copyright == NULL ) {
        FileTag->copyright = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * URL
     */
    length = WavpackGetTagItem(wpc, "copyright url", field, MAXLEN);

    if ( length > 0 && FileTag->url == NULL ) {
        FileTag->url = Try_To_Validate_Utf8_String(field);
    }

    memset (field, '\0', MAXLEN);

    /*
     * Encoded by
     */
    length = WavpackGetTagItem(wpc, "encoded by", field, MAXLEN);

    if ( length > 0 && FileTag->encoded_by == NULL ) {
        FileTag->encoded_by = Try_To_Validate_Utf8_String(field);
    }

    WavpackCloseFile(wpc);

    g_object_unref (state.istream);

    return TRUE;
}