Beispiel #1
0
/*
 * et_picture_load_file_data:
 * @file: the GFile from which to load an image
 * @error: a #GError to provide information on errors, or %NULL to ignore
 *
 * Load an image from the supplied @file.
 *
 * Returns: an image on success, %NULL otherwise
 */
static Picture *
et_picture_load_file_data (GFile *file, GError **error)
{
    Picture *pic;
    gchar *buffer = NULL;
    gsize size;
    gsize bytes_read;
    GFileInfo *info;
    GFileInputStream *file_istream;

    info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
                              G_FILE_QUERY_INFO_NONE, NULL, error);

    if (!info)
    {
        g_assert (error == NULL || *error != NULL);
        return NULL;
    }

    file_istream = g_file_read (file, NULL, error);

    if (!file_istream)
    {
        g_assert (error == NULL || *error != NULL);
        return NULL;
    }

    size = g_file_info_get_size (info);
    buffer = g_malloc (size);
    g_object_unref (info);

    if (!g_input_stream_read_all (G_INPUT_STREAM (file_istream), buffer, size,
                                  &bytes_read, NULL, error))
    {
        g_free (buffer);

        g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
                 " bytes of picture data were read", bytes_read, size);

        g_object_unref (file_istream);
        g_assert (error == NULL || *error != NULL);
        return NULL;
    }
    else
    {
        /* Image loaded. */
        pic = Picture_Allocate();
        pic->size = size;
        pic->data = (guchar *)buffer;

        g_object_unref (file_istream);
        g_assert (error == NULL || *error == NULL);
        return pic;
    }
}
Beispiel #2
0
Picture *Picture_Copy_One (const Picture *pic)
{
    Picture *pic2;

    g_return_val_if_fail (pic != NULL, NULL);

    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);
    }
    return pic2;
}
Beispiel #3
0
/*
 * Read tag data from a FLAC file using the level 1 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 (gchar *filename, File_Tag *FileTag)
{
    FLAC__Metadata_SimpleIterator *iter;
    gchar *string = NULL;
    gchar *filename_utf8 = filename_to_display(filename);
    guint i;
#ifndef LEGACY_FLAC // For FLAC >= 1.1.3
    Picture *prev_pic = NULL;
#endif
    //gint j = 1;


    if (!filename || !FileTag)
        return FALSE;

    flac_error_msg = NULL;

    // Initialize the iterator for the blocks
    iter = FLAC__metadata_simple_iterator_new();
    if ( iter == NULL || !FLAC__metadata_simple_iterator_init(iter, filename, true, false) )
    {
        if ( iter == NULL )
        {
            // Error with "FLAC__metadata_simple_iterator_new"
            flac_error_msg = FLAC__Metadata_SimpleIteratorStatusString[FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR];
        } else
        {
            // Error with "FLAC__metadata_simple_iterator_init"
            FLAC__Metadata_SimpleIteratorStatus status = FLAC__metadata_simple_iterator_status(iter);
            flac_error_msg = FLAC__Metadata_SimpleIteratorStatusString[status];

            FLAC__metadata_simple_iterator_delete(iter);
        }

        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' as FLAC (%s)."),filename_utf8,flac_error_msg);
        g_free(filename_utf8);
        return FALSE;
    }


    /* libFLAC is able to detect (and skip) ID3v2 tags by itself */

    while (FLAC__metadata_simple_iterator_next(iter))
    {
        // Get block data
        FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iter);
        //g_print("Read: %d %s -> block type: %d\n",j++,g_path_get_basename(filename),FLAC__metadata_simple_iterator_get_block_type(iter));

        // Action to do according the type
        switch ( FLAC__metadata_simple_iterator_get_block_type(iter) )
        {
        //
        // Read the VORBIS_COMMENT block (only one should exist)
        //
        case FLAC__METADATA_TYPE_VORBIS_COMMENT:
        {
            FLAC__StreamMetadata_VorbisComment       *vc;
            FLAC__StreamMetadata_VorbisComment_Entry *field;
            gint   field_num;
            gint   field_len;
            gchar *field_value;
            gchar *field_value_tmp;

            // Get comments from block
            vc = &block->data.vorbis_comment;

            /*********
             * Title *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"TITLE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->title==NULL)
                            FileTag->title = g_strdup(field_value);
                        else
                            FileTag->title = g_strconcat(FileTag->title,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /**********
             * Artist *
             **********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ARTIST")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->artist==NULL)
                            FileTag->artist = g_strdup(field_value);
                        else
                            FileTag->artist = g_strconcat(FileTag->artist,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*********
             * Album *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ALBUM")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->album==NULL)
                            FileTag->album = g_strdup(field_value);
                        else
                            FileTag->album = g_strconcat(FileTag->album,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***************
             * Disc Number *
             ***************/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"DISCNUMBER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        FileTag->disc_number = field_value;
                    }
                }
            }

            /********
             * Year *
             ********/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"DATE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        FileTag->year = field_value;
                        if (g_utf8_strlen(FileTag->year, -1) > 4)
                            Log_Print(LOG_WARNING,_("The year value '%s' seems to be invalid in file '%s'. The information will be lost while saving tag."),FileTag->year,filename_utf8);
                    }
                }
            }

            /*************************
             * Track and Total Track *
             *************************/
            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"TRACKTOTAL")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (NUMBER_TRACK_FORMATED)
                        {
                            FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(field_value));
                        } else
                        {
                            FileTag->track_total = g_strdup(field_value);
                        }
                        g_free(field_value);
                    }
                }
                // Below is also filled track_total if not done here
            }

            if ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,0,"TRACKNUMBER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        string = g_utf8_strchr(field_value, -1, '/');
                        if (NUMBER_TRACK_FORMATED)
                        {
                            // If track_total not filled before, try now...
                            if (string && !FileTag->track_total)
                            {
                                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string+1));
                                *string = '\0';
                            }
                            FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(field_value));
                        } else
                        {
                            if (string && !FileTag->track_total)
                            {
                                FileTag->track_total = g_strdup(string+1);
                                *string = '\0';
                            }
                            FileTag->track = g_strdup(field_value);
                        }
                        g_free(field_value);
                    }
                }
            }

            /*********
             * Genre *
             *********/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"GENRE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->genre==NULL)
                            FileTag->genre = g_strdup(field_value);
                        else
                            FileTag->genre = g_strconcat(FileTag->genre,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***********
             * Comment *
             ***********/
            field_num = 0;
            while ( 1 )
            {
                gint field_num1, field_num2;

                // The comment field can take two forms...
                field_num1 = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"DESCRIPTION");
                field_num2 = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COMMENT");

                if (field_num1 >= 0 && field_num2 >= 0)
                    // Note : We set field_num to the last "comment" field to avoid to concatenate
                    // the DESCRIPTION and COMMENT field if there are both present (EasyTAG writes the both...)
                    if (field_num1 < field_num2)
                        field_num = field_num2;
                    else
                        field_num = field_num1;
                else if (field_num1 >= 0)
                    field_num = field_num1;
                else if (field_num2 >= 0)
                    field_num = field_num2;
                else
                    break;

                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->comment==NULL)
                            FileTag->comment = g_strdup(field_value);
                        else
                            FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /************
             * Composer *
             ************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COMPOSER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->composer==NULL)
                            FileTag->composer = g_strdup(field_value);
                        else
                            FileTag->composer = g_strconcat(FileTag->composer,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*******************
             * Original artist *
             *******************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"PERFORMER")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->orig_artist==NULL)
                            FileTag->orig_artist = g_strdup(field_value);
                        else
                            FileTag->orig_artist = g_strconcat(FileTag->orig_artist,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*************
             * Copyright *
             *************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"COPYRIGHT")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->copyright==NULL)
                            FileTag->copyright = g_strdup(field_value);
                        else
                            FileTag->copyright = g_strconcat(FileTag->copyright,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /*******
             * URL *
             *******/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"LICENSE")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->url==NULL)
                            FileTag->url = g_strdup(field_value);
                        else
                            FileTag->url = g_strconcat(FileTag->url,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /**************
             * Encoded by *
             **************/
            field_num = 0;
            while ( (field_num = FLAC__metadata_object_vorbiscomment_find_entry_from(block,field_num,"ENCODED-BY")) >= 0 )
            {
                /* Extract field value */
                field = &vc->comments[field_num++];
                field_value = memchr(field->entry, '=', field->length);

                if (field_value)
                {
                    field_value++;
                    if ( field_value && g_utf8_strlen(field_value, -1) > 0 )
                    {
                        field_len = field->length - (field_value - (gchar*) field->entry);
                        field_value_tmp = g_strndup(field_value, field_len);
                        field_value = Try_To_Validate_Utf8_String(field_value_tmp);
                        g_free(field_value_tmp);
                        if (FileTag->encoded_by==NULL)
                            FileTag->encoded_by = g_strdup(field_value);
                        else
                            FileTag->encoded_by = g_strconcat(FileTag->encoded_by,MULTIFIELD_SEPARATOR,field_value,NULL);
                        g_free(field_value);
                    }
                }
            }

            /***************************
             * Save unsupported fields *
             ***************************/
            for (i=0; i<(guint)vc->num_comments; i++)
            {
                field = &vc->comments[i];
                if ( strncasecmp((gchar *)field->entry,"TITLE=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ARTIST=",      MIN(7,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ALBUM=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DISCNUMBER=",  MIN(11, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DATE=",        MIN(5,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"TRACKNUMBER=", MIN(12, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"TRACKTOTAL=",  MIN(11, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"GENRE=",       MIN(6,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"DESCRIPTION=", MIN(12, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COMMENT=",     MIN(8,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COMPOSER=",    MIN(9,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"PERFORMER=",   MIN(10, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"COPYRIGHT=",   MIN(10, field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"LICENSE=",     MIN(8,  field->length)) != 0
                        && strncasecmp((gchar *)field->entry,"ENCODED-BY=",  MIN(11, field->length)) != 0 )
                {
                    //g_print("custom %*s\n", field->length, field->entry);
                    FileTag->other = g_list_append(FileTag->other,g_strndup((const gchar *)field->entry, field->length));
                }
            }

            break;
        }


            //
            // Read the PICTURE block (severals can exist)
            //
#ifndef LEGACY_FLAC // For FLAC >= 1.1.3
        case FLAC__METADATA_TYPE_PICTURE:
        {

            /***********
             * Picture *
             ***********/
            FLAC__StreamMetadata_Picture *p;
            Picture *pic;

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

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

            pic->size = p->data_length;
            pic->data = g_memdup(p->data,pic->size);
            pic->type = p->type;
            pic->description = g_strdup((gchar *)p->description);
            // Not necessary: will be calculated later
            //pic->height = p->height;
            //pic->width  = p->width;

            //g_print("Picture type : %s\n",FLAC__StreamMetadata_Picture_TypeString[p->type]);
            //g_print("Mime    type : %s\n",p->mime_type);

            break;
        }
#endif

        default:
            break;
        }

        // Free block data
        //FLAC__metadata_object_delete(block);
    }

    // Free iter
    FLAC__metadata_simple_iterator_delete(iter);


#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       == NULL
            && FileTag->disc_number == 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)
    {
        gint rc = Id3tag_Read_File_Tag(filename,FileTag);

        // 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       != NULL
                || FileTag->disc_number != 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;
        }

        g_free(filename_utf8);
        return rc;
    }

    /* Part to get cover artist :
     * If we have read the ID3 tag previously we don't arrive here (and we have
     * the picture if it exists).
     * Else the ID3 tag wasn't read (as there was data in FLAC tag) so we try
     * to read it only to get the picture (not supported by the FLAC tag). */
    /***if (WRITE_ID3_TAGS_IN_FLAC_FILE && FileTag->picture == NULL)
    {
        File_Tag *FileTag_tmp = ET_File_Tag_Item_New();
        gint rc = Id3tag_Read_File_Tag(filename,FileTag_tmp);
        if (rc && FileTag_tmp->picture)
        {
            // Copy picture to FileTag
            FileTag->picture = Picture_Copy(FileTag_tmp->picture);
        }

        ET_Free_File_Tag_Item(FileTag_tmp);

        return rc;
    }***/
#endif

    g_free(filename_utf8);
    return TRUE;
}
Beispiel #4
0
/*
 * Read tag data into an Ogg Vorbis file.
 * Note:
 *  - if field is found but contains no info (strlen(str)==0), we don't read it
 */
gboolean Ogg_Tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FILE           *file;
    vcedit_state   *state;
    vorbis_comment *vc;
    gchar          *string = NULL;
    gchar          *string1 = NULL;
    gchar          *string2 = NULL;
    gchar          *filename_utf8 = filename_to_display(filename);
    guint           field_num, i;
    Picture        *prev_pic = NULL;


    if (!filename || !FileTag)
        return FALSE;

    ogg_error_msg = NULL;

    if ( (file=fopen(filename,"rb")) == NULL )
    {
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }

    {
    // Skip the id3v2 tag
    guchar tmp_id3[4];
    gulong id3v2size;

    // Check if there is an ID3v2 tag...
    fseek(file, 0L, SEEK_SET);
    if (fread(tmp_id3, 1, 4, file) == 4)
    {
        // Calculate ID3v2 length
        if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF)
        {
            // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
            fseek(file, 2, SEEK_CUR); // Size is 6-9 position
            if (fread(tmp_id3, 1, 4, file) == 4)
            {
                id3v2size = 10 + ( (long)(tmp_id3[3])        | ((long)(tmp_id3[2]) << 7)
                                | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) );
                fseek(file, id3v2size, SEEK_SET);
                Log_Print(LOG_ERROR,_("Warning : The Ogg Vorbis file '%s' contains an ID3v2 tag."),filename_utf8);
            }else
            {
                fseek(file, 0L, SEEK_SET);
            }
        }else
        {
            fseek(file, 0L, SEEK_SET);
        }
    }else
    {
        fseek(file, 0L, SEEK_SET);
    }
    }

    state = vcedit_new_state();    // Allocate memory for 'state'
    if ( vcedit_open(state,file) < 0 )
    {
        Log_Print(LOG_ERROR,_("ERROR: Failed to open file: '%s' as vorbis (%s)."),filename_utf8,vcedit_error(state));
        ogg_error_msg = vcedit_error(state);
        fclose(file);
        g_free(filename_utf8);
        vcedit_clear(state);
        return FALSE;
    }


    /* Get data from tag */
    vc = vcedit_comments(state);
    /*{
        gint i; 
        for (i=0;i<vc->comments;i++) 
            g_print("%s -> Ogg vc:'%s'\n",g_path_get_basename(filename),vc->user_comments[i]);
    }*/

    /*********
     * Title *
     *********/
    /* Note : don't forget to add any new field to 'Save unsupported fields' */
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"TITLE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->title==NULL)
                FileTag->title = g_strdup(string);
            else
                FileTag->title = g_strconcat(FileTag->title,MULTIFIELD_SEPARATOR,string,NULL);
            // If strlen = 0, then no allocated data!
        }

        g_free(string);
    }

    /**********
     * Artist *
     **********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ARTIST",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->artist==NULL)
                FileTag->artist = g_strdup(string);
            else
                FileTag->artist = g_strconcat(FileTag->artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /****************
     * Album Artist *
     ****************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ALBUMARTIST",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->album_artist==NULL)
                FileTag->album_artist = g_strdup(string);
            else
                FileTag->album_artist = g_strconcat(FileTag->album_artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*********
     * Album *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ALBUM",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->album==NULL)
                FileTag->album = g_strdup(string);
            else
                FileTag->album = g_strconcat(FileTag->album,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******************************
     * Disc Number (Part of a Set) *
     *******************************/
    if ( (string = vorbis_comment_query(vc,"DISCNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        FileTag->disc_number = g_strdup(string);
    }

    /********
     * Year *
     ********/
    if ( (string = vorbis_comment_query(vc,"DATE",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        FileTag->year = g_strdup(string);
        if (g_utf8_strlen(FileTag->year, -1) > 4)
            Log_Print(LOG_WARNING,_("The year value '%s' seems to be invalid in file '%s'. The information will be lost while saving tag."),FileTag->year,filename_utf8);
    }

    /*************************
     * Track and Total Track *
     *************************/
    if ( (string = vorbis_comment_query(vc,"TRACKNUMBER",0)) != NULL && g_utf8_strlen(string, -1) > 0 )
    {
        if (NUMBER_TRACK_FORMATED)
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1+1));
                *string1 = '\0';
            }
            FileTag->track = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string));
        }else
        {
            // Ckeck if TRACKTOTAL used, else takes it in TRACKNUMBER
            if ( (string1 = vorbis_comment_query(vc,"TRACKTOTAL",0)) != NULL && g_utf8_strlen(string1, -1) > 0 )
            {
                FileTag->track_total = g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,atoi(string1));
            }else
            if ( (string1 = g_utf8_strchr(string, -1, '/')) )
            {
                FileTag->track_total = g_strdup(string1+1);
                *string1 = '\0';
            }
            FileTag->track = g_strdup(string);
        }
    }

    /*********
     * Genre *
     *********/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"GENRE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->genre==NULL)
                FileTag->genre = g_strdup(string);
            else
                FileTag->genre = g_strconcat(FileTag->genre,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /***********
     * Comment *
     ***********/
    field_num = 0;
    string1 = NULL; // Cause it may be not updated into the 'while' condition
    while ( ((string2 = vorbis_comment_query(vc,"DESCRIPTION",field_num)) != NULL )   // New specifications
         || ((string  = vorbis_comment_query(vc,"COMMENT",    field_num)) != NULL )   // Old : Winamp format (for EasyTAG 1.99.11 and older)
         || ((string1 = vorbis_comment_query(vc,"",           field_num)) != NULL ) ) // Old : Xmms format   (for EasyTAG 1.99.11 and older)
    {
        string  = Try_To_Validate_Utf8_String(string);
        string1 = Try_To_Validate_Utf8_String(string1);
        string2 = Try_To_Validate_Utf8_String(string2);

        if ( string2 && g_utf8_strlen(string2, -1) > 0 ) // Contains comment to new specifications format and we prefer this format (field name defined)
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string2);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string2,NULL);

            // Frees allocated data
            if (string && g_utf8_strlen(string, -1) > 0)
                g_free(string);
            if (string1 && g_utf8_strlen(string1, -1) > 0)
                g_free(string1);
        }else if ( string && g_utf8_strlen(string, -1) > 0 ) // Contains comment to Winamp format and we prefer this format (field name defined)
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string,NULL);

            // Frees allocated data
            if (string1 && g_utf8_strlen(string1, -1) > 0)
                g_free(string1);
        }else if ( string1 && g_utf8_strlen(string1, -1) > 0 ) // Contains comment to Xmms format only
        {
            if (FileTag->comment==NULL)
                FileTag->comment = g_strdup(string1);
            else
                FileTag->comment = g_strconcat(FileTag->comment,MULTIFIELD_SEPARATOR,string1,NULL);
        }

        g_free(string);
        g_free(string1);
        g_free(string2);

        string  = NULL;
        string1 = NULL;
        field_num++;
    }

    /************
     * Composer *
     ************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COMPOSER",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->composer==NULL)
                FileTag->composer = g_strdup(string);
            else
                FileTag->composer = g_strconcat(FileTag->composer,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******************
     * Original artist *
     *******************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"PERFORMER",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->orig_artist==NULL)
                FileTag->orig_artist = g_strdup(string);
            else
                FileTag->orig_artist = g_strconcat(FileTag->orig_artist,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*************
     * Copyright *
     *************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COPYRIGHT",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->copyright==NULL)
                FileTag->copyright = g_strdup(string);
            else
                FileTag->copyright = g_strconcat(FileTag->copyright,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /*******
     * URL *
     *******/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"LICENSE",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->url==NULL)
                FileTag->url = g_strdup(string);
            else
                FileTag->url = g_strconcat(FileTag->url,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }

    /**************
     * Encoded by *
     **************/
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"ENCODED-BY",field_num++)) != NULL )
    {
        string = Try_To_Validate_Utf8_String(string);

        if ( g_utf8_strlen(string, -1) > 0 )
        {
            if (FileTag->encoded_by==NULL)
                FileTag->encoded_by = g_strdup(string);
            else
                FileTag->encoded_by = g_strconcat(FileTag->encoded_by,MULTIFIELD_SEPARATOR,string,NULL);
        }

        g_free(string);
    }


    /**************
     * Picture    *
     **************/
    /* Non officials tags used for picture information:
     *  - COVERART            : contains the picture data
     *  - COVERARTTYPE        : cover front, ...
     *  - COVERARTDESCRIPTION : information set by user
     *  - COVERARTMIME        : image/jpeg or image/png (written only)
     */
    field_num = 0;
    while ( (string = vorbis_comment_query(vc,"COVERART",field_num++)) != NULL )
    {
        gchar *data;
        gint size;
        Picture *pic;
            
        pic = Picture_Allocate();
        if (!prev_pic)
            FileTag->picture = pic;
        else
            prev_pic->next = pic;
        prev_pic = pic;

        pic->data = NULL;
        
        // Decode picture data
        data = g_strdup(string);
        size = base64_decode(string, data);
        if ( data && (pic->data = g_memdup(data, size)) )
            pic->size = size;
        g_free(data);

        if ( (string = vorbis_comment_query(vc,"COVERARTTYPE",field_num-1)) != NULL )
        {
            pic->type = atoi(string);
        }

        if ( (string = vorbis_comment_query(vc,"COVERARTDESCRIPTION",field_num-1)) != NULL )
        {
            pic->description = g_strdup(string);
        }

        //if ((string = vorbis_comment_query(vc,"COVERTARTMIME",field_num-1)) != NULL )
        //{
        //    pic->description = g_strdup(string);
        //}

    }


    /***************************
     * Save unsupported fields *
     ***************************/
    for (i=0;i<(guint)vc->comments;i++)
    {
        if ( strncasecmp(vc->user_comments[i],"TITLE=",            6) != 0
          && strncasecmp(vc->user_comments[i],"ARTIST=",           7) != 0
          && strncasecmp(vc->user_comments[i],"ALBUMARTIST=",     12) != 0
          && strncasecmp(vc->user_comments[i],"ALBUM=",            6) != 0
          && strncasecmp(vc->user_comments[i],"DISCNUMBER=",      11) != 0
          && strncasecmp(vc->user_comments[i],"DATE=",             5) != 0
          && strncasecmp(vc->user_comments[i],"TRACKNUMBER=",     12) != 0
          && strncasecmp(vc->user_comments[i],"TRACKTOTAL=",      11) != 0
          && strncasecmp(vc->user_comments[i],"GENRE=",            6) != 0
          && strncasecmp(vc->user_comments[i],"DESCRIPTION=",     12) != 0
          && strncasecmp(vc->user_comments[i],"COMMENT=",          8) != 0
          && strncasecmp(vc->user_comments[i],"=",                 1) != 0
          && strncasecmp(vc->user_comments[i],"COMPOSER=",         9) != 0
          && strncasecmp(vc->user_comments[i],"PERFORMER=",       10) != 0
          && strncasecmp(vc->user_comments[i],"COPYRIGHT=",       10) != 0
          && strncasecmp(vc->user_comments[i],"LICENSE=",          8) != 0
          && strncasecmp(vc->user_comments[i],"ENCODED-BY=",      11) != 0
          && strncasecmp(vc->user_comments[i],"COVERART=",         9) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTTYPE=",       13) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTMIME=",       13) != 0
          && strncasecmp(vc->user_comments[i],"COVERARTDESCRIPTION=",20) != 0
           )
        {
            FileTag->other = g_list_append(FileTag->other,
                                           Try_To_Validate_Utf8_String(vc->user_comments[i]));
        }
    }

    vcedit_clear(state);
    fclose(file);
    g_free(filename_utf8);

    return TRUE;
}