1 /***************************************************************************
2     copyright            : (C) 2003 by Allan Sandfeld Jensen
3     email                : kde@carewolf.org
4  ***************************************************************************/
5 
6 /***************************************************************************
7  *   This library is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU Lesser General Public License version   *
9  *   2.1 as published by the Free Software Foundation.                     *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful, but   *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the Free Software   *
18  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
19  *   02110-1301  USA                                                       *
20  *                                                                         *
21  *   Alternatively, this file is available under the Mozilla Public        *
22  *   License Version 1.1.  You may obtain a copy of the License at         *
23  *   http://www.mozilla.org/MPL/                                           *
24  ***************************************************************************/
25 
26 #ifndef TAGLIB_FLACFILE_H
27 #define TAGLIB_FLACFILE_H
28 
29 #include "taglib_export.h"
30 #include "tfile.h"
31 #include "tlist.h"
32 #include "tag.h"
33 
34 #include "flacpicture.h"
35 #include "flacproperties.h"
36 
37 namespace TagLib {
38 
39   class Tag;
40   namespace ID3v2 { class FrameFactory; class Tag; }
41   namespace ID3v1 { class Tag; }
42   namespace Ogg { class XiphComment; }
43 
44   //! An implementation of FLAC metadata
45 
46   /*!
47    * This is implementation of FLAC metadata for non-Ogg FLAC files.  At some
48    * point when Ogg / FLAC is more common there will be a similar implementation
49    * under the Ogg hierarchy.
50    *
51    * This supports ID3v1, ID3v2 and Xiph style comments as well as reading stream
52    * properties from the file.
53    */
54 
55   namespace FLAC {
56 
57     //! An implementation of TagLib::File with FLAC specific methods
58 
59     /*!
60      * This implements and provides an interface for FLAC files to the
61      * TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
62      * the abstract TagLib::File API as well as providing some additional
63      * information specific to FLAC files.
64      */
65 
66     class TAGLIB_EXPORT File : public TagLib::File
67     {
68     public:
69       /*!
70        * This set of flags is used for various operations and is suitable for
71        * being OR-ed together.
72        */
73       enum TagTypes {
74         //! Empty set.  Matches no tag types.
75         NoTags      = 0x0000,
76         //! Matches Vorbis comments.
77         XiphComment = 0x0001,
78         //! Matches ID3v1 tags.
79         ID3v1       = 0x0002,
80         //! Matches ID3v2 tags.
81         ID3v2       = 0x0004,
82         //! Matches all tag types.
83         AllTags     = 0xffff
84       };
85 
86       /*!
87        * Constructs a FLAC file from \a file.  If \a readProperties is true the
88        * file's audio properties will also be read.
89        *
90        * \note In the current implementation, \a propertiesStyle is ignored.
91        *
92        * \deprecated This constructor will be dropped in favor of the one below
93        * in a future version.
94        */
95       File(FileName file, bool readProperties = true,
96            Properties::ReadStyle propertiesStyle = Properties::Average);
97 
98       /*!
99        * Constructs an FLAC file from \a file.  If \a readProperties is true the
100        * file's audio properties will also be read.
101        *
102        * If this file contains and ID3v2 tag the frames will be created using
103        * \a frameFactory.
104        *
105        * \note In the current implementation, \a propertiesStyle is ignored.
106        */
107       // BIC: merge with the above constructor
108       File(FileName file, ID3v2::FrameFactory *frameFactory,
109            bool readProperties = true,
110            Properties::ReadStyle propertiesStyle = Properties::Average);
111 
112       /*!
113        * Constructs a FLAC file from \a stream.  If \a readProperties is true the
114        * file's audio properties will also be read.
115        *
116        * \note TagLib will *not* take ownership of the stream, the caller is
117        * responsible for deleting it after the File object.
118        *
119        * If this file contains and ID3v2 tag the frames will be created using
120        * \a frameFactory.
121        *
122        * \note In the current implementation, \a propertiesStyle is ignored.
123        */
124       // BIC: merge with the above constructor
125       File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
126            bool readProperties = true,
127            Properties::ReadStyle propertiesStyle = Properties::Average);
128 
129       /*!
130        * Destroys this instance of the File.
131        */
132       virtual ~File();
133 
134       /*!
135        * Returns the Tag for this file.  This will be a union of XiphComment,
136        * ID3v1 and ID3v2 tags.
137        *
138        * \see ID3v2Tag()
139        * \see ID3v1Tag()
140        * \see XiphComment()
141        */
142       virtual TagLib::Tag *tag() const;
143 
144       /*!
145        * Implements the unified property interface -- export function.
146        * If the file contains more than one tag (e.g. XiphComment and ID3v1),
147        * only the first one (in the order XiphComment, ID3v2, ID3v1) will be
148        * converted to the PropertyMap.
149        */
150       PropertyMap properties() const;
151 
152       void removeUnsupportedProperties(const StringList &);
153 
154       /*!
155        * Implements the unified property interface -- import function.
156        * This always creates a Xiph comment, if none exists. The return value
157        * relates to the Xiph comment only.
158        * Ignores any changes to ID3v1 or ID3v2 comments since they are not allowed
159        * in the FLAC specification.
160        */
161       PropertyMap setProperties(const PropertyMap &);
162 
163       /*!
164        * Returns the FLAC::Properties for this file.  If no audio properties
165        * were read then this will return a null pointer.
166        */
167       virtual Properties *audioProperties() const;
168 
169       /*!
170        * Save the file.  This will primarily save the XiphComment, but
171        * will also keep any old ID3-tags up to date. If the file
172        * has no XiphComment, one will be constructed from the ID3-tags.
173        *
174        * This returns true if the save was successful.
175        */
176       virtual bool save();
177 
178       /*!
179        * Returns a pointer to the ID3v2 tag of the file.
180        *
181        * If \a create is false (the default) this returns a null pointer
182        * if there is no valid ID3v2 tag.  If \a create is true it will create
183        * an ID3v2 tag if one does not exist and returns a valid pointer.
184        *
185        * \note This may return a valid pointer regardless of whether or not the
186        * file on disk has an ID3v2 tag.  Use hasID3v2Tag() to check if the file
187        * on disk actually has an ID3v2 tag.
188        *
189        * \note The Tag <b>is still</b> owned by the MPEG::File and should not be
190        * deleted by the user.  It will be deleted when the file (object) is
191        * destroyed.
192        *
193        * \see hasID3v2Tag()
194        */
195       ID3v2::Tag *ID3v2Tag(bool create = false);
196 
197       /*!
198        * Returns a pointer to the ID3v1 tag of the file.
199        *
200        * If \a create is false (the default) this returns a null pointer
201        * if there is no valid APE tag.  If \a create is true it will create
202        * an APE tag if one does not exist and returns a valid pointer.
203        *
204        * \note This may return a valid pointer regardless of whether or not the
205        * file on disk has an ID3v1 tag.  Use hasID3v1Tag() to check if the file
206        * on disk actually has an ID3v1 tag.
207        *
208        * \note The Tag <b>is still</b> owned by the MPEG::File and should not be
209        * deleted by the user.  It will be deleted when the file (object) is
210        * destroyed.
211        *
212        * \see hasID3v1Tag()
213        */
214       ID3v1::Tag *ID3v1Tag(bool create = false);
215 
216       /*!
217        * Returns a pointer to the XiphComment for the file.
218        *
219        * If \a create is false (the default) this returns a null pointer
220        * if there is no valid XiphComment.  If \a create is true it will create
221        * a XiphComment if one does not exist and returns a valid pointer.
222        *
223        * \note This may return a valid pointer regardless of whether or not the
224        * file on disk has a XiphComment.  Use hasXiphComment() to check if the
225        * file on disk actually has a XiphComment.
226        *
227        * \note The Tag <b>is still</b> owned by the FLAC::File and should not be
228        * deleted by the user.  It will be deleted when the file (object) is
229        * destroyed.
230        *
231        * \see hasXiphComment()
232        */
233       Ogg::XiphComment *xiphComment(bool create = false);
234 
235       /*!
236        * Set the ID3v2::FrameFactory to something other than the default.  This
237        * can be used to specify the way that ID3v2 frames will be interpreted
238        * when
239        *
240        * \see ID3v2FrameFactory
241        * \deprecated This value should be passed in via the constructor
242        */
243       void setID3v2FrameFactory(const ID3v2::FrameFactory *factory);
244 
245       /*!
246        * Returns the block of data used by FLAC::Properties for parsing the
247        * stream properties.
248        *
249        * \deprecated Always returns an empty vector.
250        */
251       ByteVector streamInfoData(); // BIC: remove
252 
253       /*!
254        * Returns the length of the audio-stream, used by FLAC::Properties for
255        * calculating the bitrate.
256        *
257        * \deprecated Always returns zero.
258        */
259       long streamLength();  // BIC: remove
260 
261       /*!
262        * Returns a list of pictures attached to the FLAC file.
263        */
264       List<Picture *> pictureList();
265 
266       /*!
267        * Removes an attached picture. If \a del is true the picture's memory
268        * will be freed; if it is false, it must be deleted by the user.
269        */
270       void removePicture(Picture *picture, bool del = true);
271 
272       /*!
273        * Remove all attached images.
274        */
275       void removePictures();
276 
277       /*!
278        * Add a new picture to the file. The file takes ownership of the
279        * picture and will handle freeing its memory.
280        *
281        * \note The file will be saved only after calling save().
282        */
283       void addPicture(Picture *picture);
284 
285       /*!
286        * This will remove the tags that match the OR-ed together TagTypes from
287        * the file.  By default it removes all tags.
288        *
289        * \warning This will also invalidate pointers to the tags as their memory
290        * will be freed.
291        *
292        * \note In order to make the removal permanent save() still needs to be
293        * called.
294        *
295        * \note This won't remove the Vorbis comment block completely.  The
296        * vendor ID will be preserved.
297        */
298       void strip(int tags = AllTags);
299 
300       /*!
301        * Returns whether or not the file on disk actually has a XiphComment.
302        *
303        * \see xiphComment()
304        */
305       bool hasXiphComment() const;
306 
307       /*!
308        * Returns whether or not the file on disk actually has an ID3v1 tag.
309        *
310        * \see ID3v1Tag()
311        */
312       bool hasID3v1Tag() const;
313 
314       /*!
315        * Returns whether or not the file on disk actually has an ID3v2 tag.
316        *
317        * \see ID3v2Tag()
318        */
319       bool hasID3v2Tag() const;
320 
321       /*!
322        * Returns whether or not the given \a stream can be opened as a FLAC
323        * file.
324        *
325        * \note This method is designed to do a quick check.  The result may
326        * not necessarily be correct.
327        */
328       static bool isSupported(IOStream *stream);
329 
330     private:
331       File(const File &);
332       File &operator=(const File &);
333 
334       void read(bool readProperties);
335       void scan();
336 
337       class FilePrivate;
338       FilePrivate *d;
339     };
340   }
341 }
342 
343 #endif
344