Skip Menu |

This queue is for tickets about the Audio-FLAC-Header CPAN distribution.

Report information
The Basics
Id: 32693
Status: resolved
Priority: 0/
Queue: Audio-FLAC-Header

People
Owner: Nobody in particular
Requestors: carl.asplund [...] sassa.nu
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.7
  • 1.8
  • 1.9
Fixed in: (no value)



Subject: Will not retrieve multiple pictures of the same picture type, proposed solution
Hi again :) In my work with adding support for embedded pictures to flac2mp3 I stumbled over a problem with the extraction of picture data using Audio-FLAC-Header, 'sub picture'. It is perfectly possible to embed several pictures of the same picture type (0..20) into a FLAC file using various tagging software (or using metaflac), and the FLAC format specification allows it. However, Audio:FLAC:Header 1.9 (and earlier versions) will not return more than ONE picture of each picture type. For instance, if there are several embedded pictures of type 5 ('Leaflet page') in the source file, then the command $srcfile->picture(5) will just return the data for the one which was most recently added (having the highest metadata block number). This is because the picture type is used as a hash key, and the hash holding the picture data is thus overwritten each time a new block is parsed which has the same picture type. I would like to suggest a slight modification of 'sub picture' and 'sub _parsePicture' which adds valuable functionality to the existing version. I propose that the string 'all' be added as an alternative to the numeric inputs (0..20) for 'sub picture'. When called with 'all', the subroutine will return not a hash, but an array of hashes. Each item in the array represents a picture and the hash data is organized just like in the existing released version. However, each hash has an additional key=>value pair containing the picture type info. This data structure in a natural way lends itself to retrieval of multiple pictures of the same type. At the same time, the existing functionality for numeric input arguments (0..20) is fully retained. The data structure (array-of-hashes) is basically the same as you get with the call $ID3v2->get_frames( "APIC" ) to the MP3::Tag module. It turned out to be really easy to do the necessary additions to the code. To this bug report I attach a patch file for all proposed changes, including changes to the documentation. A few comments: Besides the obvious modification of 'sub picture', we build an array consisting of the hashes generated by every pass of 'sub_parsePicture'. Line 700: - + $self->{'picture'}->{$pictureType}->{'pictureType'} = $pictureType; may look odd at first, and there may be other ways to do it, but somehow we must include the picture type info into the hash before pushing it into the array. A typical call, along with code for debugging would look like as in the attachment #2. This may save you some time when checking the result. I have used the patched Audio:FLAC:Header in the context of my modification of flac2mp3 and it works like a charm, I must say! I use ActivePerl 5.8.8 Build 822 on a MSWin32-x86 machine. Operating system is Windows XP pro, SP2. It hope you find it interesting and worthwhile to include in the next release. Best regards, Carl Asplund
Subject: Patch_Header_v1.9_to_v1.9bugfixed_extended.diff.txt
--- H:/test/flac2mp3-0.3.0rc1/old/Header_v1.9.pm Thu Jan 24 10:23:19 2008 +++ H:/test/flac2mp3-0.3.0rc1/lib/Audio/FLAC/Header_v1.9_bugfixed_extended.pm Sat Jan 26 09:42:37 2008 @@ -164,8 +164,11 @@ sub picture { my $self = shift; - my $type = shift || 3; # front cover - + my $type; + $type = 3 unless defined ($type = shift); # defaults to front cover + if ($type eq 'all') { + return $self->{'allpictures'} if exists($self->{'allpictures'}); + }; # if the picture block exists, return it's content return $self->{'picture'}->{$type} if exists($self->{'picture'}->{$type}); @@ -694,7 +697,11 @@ $self->{'picture'}->{$pictureType}->{'depth'} = $depth; $self->{'picture'}->{$pictureType}->{'colorIndex'} = $colorIndex; $self->{'picture'}->{$pictureType}->{'imageData'} = $imageData; - + $self->{'picture'}->{$pictureType}->{'pictureType'} = $pictureType; + + # Create array of hashes with picture data from all the picture metadata blocks + push ( @{$self->{'allpictures'}}, {%{$self->{'picture'}->{$pictureType}}} ); + return 1; } @@ -960,9 +967,13 @@ =item * picture( [$type ] ) -Returns a hash containing data from a PICTURE block if found. +Returns a hash containing data from the last PICTURE block of this type if found. Defaults to type 3 - "Front Cover" + +When the passed variable is 'all', an array of hashes containing +picture data from all PICTURE blocks is returned. Allows for multiple instances +of the same picture type. =item * vendor_string( )
Subject: testcall.pl
#!/usr/bin/env perl -w use warnings; use strict; use FindBin; use lib "$FindBin::Bin/lib"; use Data::Dumper; use Audio::FLAC::Header; my $srcfilename = 'h:\test\4.flac'; # create object to access flac tags my $srcfile = Audio::FLAC::Header->new($srcfilename); # get all picture data from flac file my $allsrcpictures = $srcfile->picture('all'); # my $allsrcpictures = $srcfile->picture(4); print "Data from FLAC picture metadata blocks:\n"; print Dumper($allsrcpictures);
Thanks - will be fixed in 2.0