From 42064890b76bc39b0471ce052a6959cc87173e6f Mon Sep 17 00:00:00 2001 From: chudov Date: Fri, 13 Apr 2012 23:27:50 +0000 Subject: [PATCH] taglib-sharp initial import (r553) --- taglib-sharp/.gitignore | 31 + taglib-sharp/.gitmodules | 3 + taglib-sharp/AUTHORS | 29 + taglib-sharp/COPYING | 504 ++ taglib-sharp/ChangeLog | 7032 +++++++++++++++++ taglib-sharp/Makefile.am | 76 + taglib-sharp/NEWS | 333 + taglib-sharp/README | 29 + taglib-sharp/autogen.sh | 136 + taglib-sharp/configure.ac | 153 + taglib-sharp/docs/Makefile.am | 66 + taglib-sharp/docs/Package.en.xml.in | 221 + taglib-sharp/docs/XmlInjector.cs | 191 + taglib-sharp/docs/taglib-sharp-docs.source | 4 + taglib-sharp/examples/.gitignore | 2 + taglib-sharp/examples/BatchSet.cs | 131 + taglib-sharp/examples/GenerateTestFixture.cs | 924 +++ .../examples/ListSupportedMimeTypes.cs | 13 + taglib-sharp/examples/Makefile.am | 61 + taglib-sharp/examples/ParsePhoto.cs | 82 + taglib-sharp/examples/ReadFromUri.boo | 136 + taglib-sharp/examples/ReadFromUri.cs | 171 + taglib-sharp/examples/ReadFromUri.csproj | 55 + taglib-sharp/examples/SetPictures.cs | 28 + taglib-sharp/examples/SetPictures.csproj | 52 + taglib-sharp/examples/StripImageData.cs | 117 + taglib-sharp/examples/covers/sample_a.jpg | Bin 0 -> 31212 bytes taglib-sharp/examples/covers/sample_a.png | Bin 0 -> 14318 bytes taglib-sharp/examples/covers/sample_b.jpg | Bin 0 -> 32434 bytes taglib-sharp/examples/covers/sample_b.png | Bin 0 -> 15015 bytes taglib-sharp/examples/covers/sample_c.jpg | Bin 0 -> 31007 bytes taglib-sharp/examples/covers/sample_c.png | Bin 0 -> 14066 bytes taglib-sharp/examples/extractKey.cpp | 41 + taglib-sharp/examples/listData.cpp | 62 + taglib-sharp/src/AssemblyInfo.cs.in | 36 + taglib-sharp/src/Makefile.am | 69 + taglib-sharp/src/TagLib/Aac/AudioHeader.cs | 433 + taglib-sharp/src/TagLib/Aac/BitStream.cs | 110 + taglib-sharp/src/TagLib/Aac/File.cs | 282 + taglib-sharp/src/TagLib/Aiff/File.cs | 481 ++ taglib-sharp/src/TagLib/Aiff/StreamHeader.cs | 324 + taglib-sharp/src/TagLib/Ape/File.cs | 280 + taglib-sharp/src/TagLib/Ape/Footer.cs | 418 + taglib-sharp/src/TagLib/Ape/Item.cs | 532 ++ taglib-sharp/src/TagLib/Ape/StreamHeader.cs | 372 + taglib-sharp/src/TagLib/Ape/Tag.cs | 1563 ++++ .../TagLib/Asf/ContentDescriptionObject.cs | 270 + .../src/TagLib/Asf/ContentDescriptor.cs | 494 ++ .../src/TagLib/Asf/DescriptionRecord.cs | 617 ++ .../Asf/ExtendedContentDescriptionObject.cs | 276 + taglib-sharp/src/TagLib/Asf/File.cs | 431 + .../src/TagLib/Asf/FilePropertiesObject.cs | 319 + taglib-sharp/src/TagLib/Asf/Guid.cs | 111 + .../src/TagLib/Asf/HeaderExtensionObject.cs | 176 + taglib-sharp/src/TagLib/Asf/HeaderObject.cs | 275 + .../src/TagLib/Asf/MetadataLibraryObject.cs | 298 + taglib-sharp/src/TagLib/Asf/Object.cs | 253 + taglib-sharp/src/TagLib/Asf/PaddingObject.cs | 139 + .../src/TagLib/Asf/StreamPropertiesObject.cs | 270 + taglib-sharp/src/TagLib/Asf/Tag.cs | 1416 ++++ taglib-sharp/src/TagLib/Asf/UnknownObject.cs | 110 + taglib-sharp/src/TagLib/ByteVector.cs | 2704 +++++++ taglib-sharp/src/TagLib/ByteVectorList.cs | 281 + taglib-sharp/src/TagLib/CombinedTag.cs | 1513 ++++ .../src/TagLib/CorruptFileException.cs | 168 + taglib-sharp/src/TagLib/Debugger.cs | 144 + taglib-sharp/src/TagLib/File.cs | 1835 +++++ taglib-sharp/src/TagLib/FileTypes.cs | 148 + taglib-sharp/src/TagLib/Flac/Block.cs | 200 + taglib-sharp/src/TagLib/Flac/BlockHeader.cs | 197 + taglib-sharp/src/TagLib/Flac/File.cs | 682 ++ taglib-sharp/src/TagLib/Flac/Picture.cs | 332 + taglib-sharp/src/TagLib/Flac/StreamHeader.cs | 237 + taglib-sharp/src/TagLib/Genres.cs | 406 + taglib-sharp/src/TagLib/Gif/Codec.cs | 62 + taglib-sharp/src/TagLib/Gif/File.cs | 781 ++ taglib-sharp/src/TagLib/Gif/GifCommentTag.cs | 103 + taglib-sharp/src/TagLib/ICodec.cs | 244 + .../src/TagLib/IFD/Entries/ByteIFDEntry.cs | 100 + .../TagLib/IFD/Entries/ByteVectorIFDEntry.cs | 100 + .../TagLib/IFD/Entries/LongArrayIFDEntry.cs | 89 + .../src/TagLib/IFD/Entries/LongIFDEntry.cs | 100 + .../TagLib/IFD/Entries/MakernoteIFDEntry.cs | 279 + .../src/TagLib/IFD/Entries/Rational.cs | 174 + .../IFD/Entries/RationalArrayIFDEntry.cs | 92 + .../TagLib/IFD/Entries/RationalIFDEntry.cs | 104 + .../src/TagLib/IFD/Entries/SByteIFDEntry.cs | 100 + .../TagLib/IFD/Entries/SLongArrayIFDEntry.cs | 89 + .../src/TagLib/IFD/Entries/SLongIFDEntry.cs | 100 + .../src/TagLib/IFD/Entries/SRational.cs | 175 + .../IFD/Entries/SRationalArrayIFDEntry.cs | 92 + .../TagLib/IFD/Entries/SRationalIFDEntry.cs | 104 + .../TagLib/IFD/Entries/SShortArrayIFDEntry.cs | 89 + .../src/TagLib/IFD/Entries/SShortIFDEntry.cs | 100 + .../TagLib/IFD/Entries/ShortArrayIFDEntry.cs | 89 + .../src/TagLib/IFD/Entries/ShortIFDEntry.cs | 100 + .../src/TagLib/IFD/Entries/StringIFDEntry.cs | 104 + .../IFD/Entries/StripOffsetsIFDEntry.cs | 151 + .../TagLib/IFD/Entries/SubIFDArrayEntry.cs | 97 + .../src/TagLib/IFD/Entries/SubIFDEntry.cs | 128 + .../IFD/Entries/ThumbnailDataIFDEntry.cs | 106 + .../TagLib/IFD/Entries/UndefinedIFDEntry.cs | 100 + .../TagLib/IFD/Entries/UserCommentIFDEntry.cs | 211 + taglib-sharp/src/TagLib/IFD/IFDDirectory.cs | 35 + taglib-sharp/src/TagLib/IFD/IFDEntry.cs | 135 + taglib-sharp/src/TagLib/IFD/IFDEntryType.cs | 108 + taglib-sharp/src/TagLib/IFD/IFDReader.cs | 1015 +++ taglib-sharp/src/TagLib/IFD/IFDRenderer.cs | 277 + taglib-sharp/src/TagLib/IFD/IFDStructure.cs | 468 ++ taglib-sharp/src/TagLib/IFD/IFDTag.cs | 631 ++ .../IFD/Makernotes/Nikon3MakernoteReader.cs | 123 + .../TagLib/IFD/Tags/CanonFileInfoEntryTag.cs | 92 + .../TagLib/IFD/Tags/CanonMakerNoteEntryTag.cs | 159 + .../IFD/Tags/CanonPictureInfoEntryTag.cs | 62 + .../src/TagLib/IFD/Tags/ExifEntryTag.cs | 385 + .../src/TagLib/IFD/Tags/GPSEntryTag.cs | 222 + .../src/TagLib/IFD/Tags/IFDEntryTag.cs | 1062 +++ .../src/TagLib/IFD/Tags/IOPEntryTag.cs | 61 + .../IFD/Tags/Nikon3MakerNoteEntryTag.cs | 473 ++ .../TagLib/IFD/Tags/NikonIsoInfoEntryTag.cs | 55 + .../TagLib/IFD/Tags/NikonLensData3EntryTag.cs | 105 + .../IFD/Tags/NikonPictureControlEntryTag.cs | 100 + .../IFD/Tags/NikonPreviewMakerNoteEntryTag.cs | 80 + .../TagLib/IFD/Tags/NikonShotInfoEntryTag.cs | 80 + .../Tags/NikonVibrationReductionEntryTag.cs | 45 + .../TagLib/IFD/Tags/NikonWorldTimeEntryTag.cs | 50 + .../IFD/Tags/OlympusMakerNoteEntryTag.cs | 352 + .../IFD/Tags/PanasonicMakerNoteEntryTag.cs | 295 + .../IFD/Tags/PentaxMakerNoteEntryTag.cs | 437 + .../TagLib/IFD/Tags/SonyMakerNoteEntryTag.cs | 242 + .../src/TagLib/Id3v1/StringHandler.cs | 77 + taglib-sharp/src/TagLib/Id3v1/Tag.cs | 500 ++ .../src/TagLib/Id3v2/ExtendedHeader.cs | 122 + taglib-sharp/src/TagLib/Id3v2/Footer.cs | 295 + taglib-sharp/src/TagLib/Id3v2/Frame.cs | 539 ++ taglib-sharp/src/TagLib/Id3v2/FrameFactory.cs | 283 + taglib-sharp/src/TagLib/Id3v2/FrameHeader.cs | 489 ++ taglib-sharp/src/TagLib/Id3v2/FrameTypes.cs | 85 + .../Id3v2/Frames/AttachedPictureFrame.cs | 705 ++ .../src/TagLib/Id3v2/Frames/CommentsFrame.cs | 539 ++ .../Frames/GeneralEncapsulatedObjectFrame.cs | 450 ++ .../Id3v2/Frames/MusicCdIdentifierFrame.cs | 328 + .../src/TagLib/Id3v2/Frames/PlayCountFrame.cs | 361 + .../TagLib/Id3v2/Frames/PopularimeterFrame.cs | 297 + .../src/TagLib/Id3v2/Frames/PrivateFrame.cs | 432 + .../Id3v2/Frames/RelativeVolumeFrame.cs | 610 ++ .../Id3v2/Frames/SynchronizedLyricsFrame.cs | 722 ++ .../TagLib/Id3v2/Frames/TermsOfUseFrame.cs | 390 + .../Id3v2/Frames/TextIdentificationFrame.cs | 1344 ++++ .../Id3v2/Frames/UniqueFileIdentifierFrame.cs | 325 + .../src/TagLib/Id3v2/Frames/UnknownFrame.cs | 208 + .../Id3v2/Frames/UnsynchronisedLyricsFrame.cs | 530 ++ taglib-sharp/src/TagLib/Id3v2/Header.cs | 320 + taglib-sharp/src/TagLib/Id3v2/SynchData.cs | 144 + taglib-sharp/src/TagLib/Id3v2/Tag.cs | 2069 +++++ taglib-sharp/src/TagLib/Image/Codec.cs | 145 + .../src/TagLib/Image/CombinedImageTag.cs | 647 ++ taglib-sharp/src/TagLib/Image/File.cs | 229 + .../src/TagLib/Image/ImageBlockFile.cs | 317 + .../src/TagLib/Image/ImageOrientation.cs | 92 + taglib-sharp/src/TagLib/Image/ImageTag.cs | 241 + .../src/TagLib/Image/NoMetadata/File.cs | 186 + taglib-sharp/src/TagLib/Jpeg/Codec.cs | 66 + taglib-sharp/src/TagLib/Jpeg/File.cs | 736 ++ .../src/TagLib/Jpeg/JpegCommentTag.cs | 101 + taglib-sharp/src/TagLib/Jpeg/Marker.cs | 349 + taglib-sharp/src/TagLib/Jpeg/Table.cs | 63 + taglib-sharp/src/TagLib/ListBase.cs | 459 ++ .../src/TagLib/Matroska/AudioTrack.cs | 156 + .../src/TagLib/Matroska/EBMLElement.cs | 270 + taglib-sharp/src/TagLib/Matroska/EBMLIDs.cs | 76 + taglib-sharp/src/TagLib/Matroska/File.cs | 588 ++ .../src/TagLib/Matroska/MatroskaIDs.cs | 450 ++ .../src/TagLib/Matroska/SubtitleTrack.cs | 98 + taglib-sharp/src/TagLib/Matroska/Tag.cs | 680 ++ taglib-sharp/src/TagLib/Matroska/Track.cs | 154 + .../src/TagLib/Matroska/VideoTrack.cs | 190 + taglib-sharp/src/TagLib/Mpc/File.cs | 278 + taglib-sharp/src/TagLib/Mpc/StreamHeader.cs | 363 + taglib-sharp/src/TagLib/Mpeg/AudioFile.cs | 296 + taglib-sharp/src/TagLib/Mpeg/AudioHeader.cs | 796 ++ taglib-sharp/src/TagLib/Mpeg/File.cs | 697 ++ taglib-sharp/src/TagLib/Mpeg/VBRIHeader.cs | 205 + taglib-sharp/src/TagLib/Mpeg/VideoHeader.cs | 206 + taglib-sharp/src/TagLib/Mpeg/XingHeader.cs | 221 + taglib-sharp/src/TagLib/Mpeg4/AppleTag.cs | 1434 ++++ taglib-sharp/src/TagLib/Mpeg4/Box.cs | 592 ++ taglib-sharp/src/TagLib/Mpeg4/BoxFactory.cs | 265 + taglib-sharp/src/TagLib/Mpeg4/BoxHeader.cs | 424 + taglib-sharp/src/TagLib/Mpeg4/BoxTypes.cs | 95 + .../Mpeg4/Boxes/AppleAdditionalInfoBox.cs | 119 + .../TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs | 110 + .../src/TagLib/Mpeg4/Boxes/AppleDataBox.cs | 207 + .../Boxes/AppleElementaryStreamDescriptor.cs | 314 + .../TagLib/Mpeg4/Boxes/AppleItemListBox.cs | 105 + .../src/TagLib/Mpeg4/Boxes/FullBox.cs | 210 + .../TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs | 237 + .../Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs | 190 + .../TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs | 187 + .../src/TagLib/Mpeg4/Boxes/IsoFreeSpaceBox.cs | 117 + .../src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs | 174 + .../src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs | 128 + .../TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs | 248 + .../Mpeg4/Boxes/IsoSampleDescriptionBox.cs | 132 + .../src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs | 109 + .../TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs | 97 + .../src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs | 127 + .../Mpeg4/Boxes/IsoVisualSampleEntry.cs | 197 + .../src/TagLib/Mpeg4/Boxes/UnknownBox.cs | 97 + taglib-sharp/src/TagLib/Mpeg4/File.cs | 478 ++ taglib-sharp/src/TagLib/Mpeg4/FileParser.cs | 632 ++ .../src/TagLib/NonContainer/EndTag.cs | 368 + taglib-sharp/src/TagLib/NonContainer/File.cs | 401 + .../src/TagLib/NonContainer/StartTag.cs | 330 + taglib-sharp/src/TagLib/NonContainer/Tag.cs | 266 + taglib-sharp/src/TagLib/Ogg/Bitstream.cs | 227 + taglib-sharp/src/TagLib/Ogg/Codec.cs | 287 + taglib-sharp/src/TagLib/Ogg/Codecs/Theora.cs | 381 + taglib-sharp/src/TagLib/Ogg/Codecs/Vorbis.cs | 356 + taglib-sharp/src/TagLib/Ogg/File.cs | 443 ++ taglib-sharp/src/TagLib/Ogg/GroupedComment.cs | 1269 +++ taglib-sharp/src/TagLib/Ogg/Page.cs | 299 + taglib-sharp/src/TagLib/Ogg/PageHeader.cs | 559 ++ taglib-sharp/src/TagLib/Ogg/Paginator.cs | 275 + taglib-sharp/src/TagLib/Ogg/XiphComment.cs | 1204 +++ taglib-sharp/src/TagLib/Picture.cs | 450 ++ taglib-sharp/src/TagLib/Png/Codec.cs | 62 + taglib-sharp/src/TagLib/Png/File.cs | 912 +++ taglib-sharp/src/TagLib/Png/PngTag.cs | 304 + taglib-sharp/src/TagLib/Properties.cs | 484 ++ taglib-sharp/src/TagLib/ReadOnlyByteVector.cs | 216 + taglib-sharp/src/TagLib/Riff/AviHeaderList.cs | 364 + taglib-sharp/src/TagLib/Riff/AviStream.cs | 595 ++ .../src/TagLib/Riff/BitmapInfoHeader.cs | 853 ++ taglib-sharp/src/TagLib/Riff/DivXTag.cs | 406 + taglib-sharp/src/TagLib/Riff/File.cs | 644 ++ taglib-sharp/src/TagLib/Riff/InfoTag.cs | 313 + taglib-sharp/src/TagLib/Riff/List.cs | 610 ++ taglib-sharp/src/TagLib/Riff/ListTag.cs | 497 ++ taglib-sharp/src/TagLib/Riff/MovieIdTag.cs | 237 + taglib-sharp/src/TagLib/Riff/WaveFormatEx.cs | 775 ++ taglib-sharp/src/TagLib/StringList.cs | 157 + taglib-sharp/src/TagLib/SupportedMimeType.cs | 205 + taglib-sharp/src/TagLib/Tag.cs | 1337 ++++ taglib-sharp/src/TagLib/TagLib.sources | 228 + taglib-sharp/src/TagLib/Tiff/Arw/File.cs | 170 + taglib-sharp/src/TagLib/Tiff/BaseTiffFile.cs | 249 + taglib-sharp/src/TagLib/Tiff/Codec.cs | 83 + taglib-sharp/src/TagLib/Tiff/Cr2/File.cs | 286 + taglib-sharp/src/TagLib/Tiff/Dng/File.cs | 208 + taglib-sharp/src/TagLib/Tiff/File.cs | 292 + taglib-sharp/src/TagLib/Tiff/Nef/File.cs | 169 + taglib-sharp/src/TagLib/Tiff/Pef/File.cs | 169 + taglib-sharp/src/TagLib/Tiff/Rw2/File.cs | 354 + taglib-sharp/src/TagLib/Tiff/Rw2/IFDReader.cs | 140 + taglib-sharp/src/TagLib/Tiff/Rw2/IFDTag.cs | 85 + .../src/TagLib/UnsupportedFormatException.cs | 164 + taglib-sharp/src/TagLib/WavPack/File.cs | 277 + .../src/TagLib/WavPack/StreamHeader.cs | 366 + .../src/TagLib/Xmp/XmlNodeExtensions.cs | 97 + taglib-sharp/src/TagLib/Xmp/XmpNode.cs | 431 + taglib-sharp/src/TagLib/Xmp/XmpNodeType.cs | 59 + taglib-sharp/src/TagLib/Xmp/XmpNodeVisitor.cs | 41 + taglib-sharp/src/TagLib/Xmp/XmpTag.cs | 1382 ++++ .../src/policy.2.0.taglib-sharp.config.in | 10 + taglib-sharp/src/taglib-sharp.csproj | 293 + taglib-sharp/taglib-sharp.pc.in | 8 + taglib-sharp/taglib-sharp.sln | 37 + taglib-sharp/taglib-sharp.snk | Bin 0 -> 596 bytes 269 files changed, 91425 insertions(+) create mode 100644 taglib-sharp/.gitignore create mode 100644 taglib-sharp/.gitmodules create mode 100644 taglib-sharp/AUTHORS create mode 100644 taglib-sharp/COPYING create mode 100644 taglib-sharp/ChangeLog create mode 100644 taglib-sharp/Makefile.am create mode 100644 taglib-sharp/NEWS create mode 100644 taglib-sharp/README create mode 100644 taglib-sharp/autogen.sh create mode 100644 taglib-sharp/configure.ac create mode 100644 taglib-sharp/docs/Makefile.am create mode 100644 taglib-sharp/docs/Package.en.xml.in create mode 100644 taglib-sharp/docs/XmlInjector.cs create mode 100644 taglib-sharp/docs/taglib-sharp-docs.source create mode 100644 taglib-sharp/examples/.gitignore create mode 100644 taglib-sharp/examples/BatchSet.cs create mode 100644 taglib-sharp/examples/GenerateTestFixture.cs create mode 100644 taglib-sharp/examples/ListSupportedMimeTypes.cs create mode 100644 taglib-sharp/examples/Makefile.am create mode 100644 taglib-sharp/examples/ParsePhoto.cs create mode 100644 taglib-sharp/examples/ReadFromUri.boo create mode 100644 taglib-sharp/examples/ReadFromUri.cs create mode 100644 taglib-sharp/examples/ReadFromUri.csproj create mode 100644 taglib-sharp/examples/SetPictures.cs create mode 100644 taglib-sharp/examples/SetPictures.csproj create mode 100644 taglib-sharp/examples/StripImageData.cs create mode 100644 taglib-sharp/examples/covers/sample_a.jpg create mode 100644 taglib-sharp/examples/covers/sample_a.png create mode 100644 taglib-sharp/examples/covers/sample_b.jpg create mode 100644 taglib-sharp/examples/covers/sample_b.png create mode 100644 taglib-sharp/examples/covers/sample_c.jpg create mode 100644 taglib-sharp/examples/covers/sample_c.png create mode 100644 taglib-sharp/examples/extractKey.cpp create mode 100644 taglib-sharp/examples/listData.cpp create mode 100644 taglib-sharp/src/AssemblyInfo.cs.in create mode 100644 taglib-sharp/src/Makefile.am create mode 100644 taglib-sharp/src/TagLib/Aac/AudioHeader.cs create mode 100644 taglib-sharp/src/TagLib/Aac/BitStream.cs create mode 100644 taglib-sharp/src/TagLib/Aac/File.cs create mode 100644 taglib-sharp/src/TagLib/Aiff/File.cs create mode 100644 taglib-sharp/src/TagLib/Aiff/StreamHeader.cs create mode 100644 taglib-sharp/src/TagLib/Ape/File.cs create mode 100644 taglib-sharp/src/TagLib/Ape/Footer.cs create mode 100644 taglib-sharp/src/TagLib/Ape/Item.cs create mode 100644 taglib-sharp/src/TagLib/Ape/StreamHeader.cs create mode 100644 taglib-sharp/src/TagLib/Ape/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Asf/ContentDescriptionObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/ContentDescriptor.cs create mode 100644 taglib-sharp/src/TagLib/Asf/DescriptionRecord.cs create mode 100644 taglib-sharp/src/TagLib/Asf/ExtendedContentDescriptionObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/File.cs create mode 100644 taglib-sharp/src/TagLib/Asf/FilePropertiesObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/Guid.cs create mode 100644 taglib-sharp/src/TagLib/Asf/HeaderExtensionObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/HeaderObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/MetadataLibraryObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/Object.cs create mode 100644 taglib-sharp/src/TagLib/Asf/PaddingObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/StreamPropertiesObject.cs create mode 100644 taglib-sharp/src/TagLib/Asf/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Asf/UnknownObject.cs create mode 100644 taglib-sharp/src/TagLib/ByteVector.cs create mode 100644 taglib-sharp/src/TagLib/ByteVectorList.cs create mode 100644 taglib-sharp/src/TagLib/CombinedTag.cs create mode 100644 taglib-sharp/src/TagLib/CorruptFileException.cs create mode 100644 taglib-sharp/src/TagLib/Debugger.cs create mode 100644 taglib-sharp/src/TagLib/File.cs create mode 100644 taglib-sharp/src/TagLib/FileTypes.cs create mode 100644 taglib-sharp/src/TagLib/Flac/Block.cs create mode 100644 taglib-sharp/src/TagLib/Flac/BlockHeader.cs create mode 100644 taglib-sharp/src/TagLib/Flac/File.cs create mode 100644 taglib-sharp/src/TagLib/Flac/Picture.cs create mode 100644 taglib-sharp/src/TagLib/Flac/StreamHeader.cs create mode 100644 taglib-sharp/src/TagLib/Genres.cs create mode 100644 taglib-sharp/src/TagLib/Gif/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Gif/File.cs create mode 100644 taglib-sharp/src/TagLib/Gif/GifCommentTag.cs create mode 100644 taglib-sharp/src/TagLib/ICodec.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/ByteIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/ByteVectorIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/LongArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/LongIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/MakernoteIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/Rational.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/RationalArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/RationalIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SByteIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SLongArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SLongIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SRational.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SRationalArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SRationalIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SShortArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SShortIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/ShortArrayIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/ShortIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/StringIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/StripOffsetsIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SubIFDArrayEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/SubIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/ThumbnailDataIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/UndefinedIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Entries/UserCommentIFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDDirectory.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDEntry.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDEntryType.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDReader.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDRenderer.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDStructure.cs create mode 100644 taglib-sharp/src/TagLib/IFD/IFDTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Makernotes/Nikon3MakernoteReader.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/CanonFileInfoEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/CanonMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/CanonPictureInfoEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/ExifEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/GPSEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/IFDEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/IOPEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/Nikon3MakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonIsoInfoEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonLensData3EntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonPictureControlEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonPreviewMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonShotInfoEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonVibrationReductionEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/NikonWorldTimeEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/OlympusMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/PanasonicMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/PentaxMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/IFD/Tags/SonyMakerNoteEntryTag.cs create mode 100644 taglib-sharp/src/TagLib/Id3v1/StringHandler.cs create mode 100644 taglib-sharp/src/TagLib/Id3v1/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/ExtendedHeader.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Footer.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/FrameFactory.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/FrameHeader.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/FrameTypes.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/CommentsFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/PlayCountFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/PopularimeterFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/PrivateFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/UnknownFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Header.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/SynchData.cs create mode 100644 taglib-sharp/src/TagLib/Id3v2/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Image/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Image/CombinedImageTag.cs create mode 100644 taglib-sharp/src/TagLib/Image/File.cs create mode 100644 taglib-sharp/src/TagLib/Image/ImageBlockFile.cs create mode 100644 taglib-sharp/src/TagLib/Image/ImageOrientation.cs create mode 100644 taglib-sharp/src/TagLib/Image/ImageTag.cs create mode 100644 taglib-sharp/src/TagLib/Image/NoMetadata/File.cs create mode 100644 taglib-sharp/src/TagLib/Jpeg/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Jpeg/File.cs create mode 100644 taglib-sharp/src/TagLib/Jpeg/JpegCommentTag.cs create mode 100644 taglib-sharp/src/TagLib/Jpeg/Marker.cs create mode 100644 taglib-sharp/src/TagLib/Jpeg/Table.cs create mode 100644 taglib-sharp/src/TagLib/ListBase.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/AudioTrack.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/EBMLElement.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/EBMLIDs.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/File.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/MatroskaIDs.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/SubtitleTrack.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/Track.cs create mode 100644 taglib-sharp/src/TagLib/Matroska/VideoTrack.cs create mode 100644 taglib-sharp/src/TagLib/Mpc/File.cs create mode 100644 taglib-sharp/src/TagLib/Mpc/StreamHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/AudioFile.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/AudioHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/File.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/VBRIHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/VideoHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg/XingHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/AppleTag.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Box.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/BoxFactory.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/BoxHeader.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/BoxTypes.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/AppleDataBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/FullBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoFreeSpaceBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/Boxes/UnknownBox.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/File.cs create mode 100644 taglib-sharp/src/TagLib/Mpeg4/FileParser.cs create mode 100644 taglib-sharp/src/TagLib/NonContainer/EndTag.cs create mode 100644 taglib-sharp/src/TagLib/NonContainer/File.cs create mode 100644 taglib-sharp/src/TagLib/NonContainer/StartTag.cs create mode 100644 taglib-sharp/src/TagLib/NonContainer/Tag.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Bitstream.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Codecs/Theora.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Codecs/Vorbis.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/File.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/GroupedComment.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Page.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/PageHeader.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/Paginator.cs create mode 100644 taglib-sharp/src/TagLib/Ogg/XiphComment.cs create mode 100644 taglib-sharp/src/TagLib/Picture.cs create mode 100644 taglib-sharp/src/TagLib/Png/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Png/File.cs create mode 100644 taglib-sharp/src/TagLib/Png/PngTag.cs create mode 100644 taglib-sharp/src/TagLib/Properties.cs create mode 100644 taglib-sharp/src/TagLib/ReadOnlyByteVector.cs create mode 100644 taglib-sharp/src/TagLib/Riff/AviHeaderList.cs create mode 100644 taglib-sharp/src/TagLib/Riff/AviStream.cs create mode 100644 taglib-sharp/src/TagLib/Riff/BitmapInfoHeader.cs create mode 100644 taglib-sharp/src/TagLib/Riff/DivXTag.cs create mode 100644 taglib-sharp/src/TagLib/Riff/File.cs create mode 100644 taglib-sharp/src/TagLib/Riff/InfoTag.cs create mode 100644 taglib-sharp/src/TagLib/Riff/List.cs create mode 100644 taglib-sharp/src/TagLib/Riff/ListTag.cs create mode 100644 taglib-sharp/src/TagLib/Riff/MovieIdTag.cs create mode 100644 taglib-sharp/src/TagLib/Riff/WaveFormatEx.cs create mode 100644 taglib-sharp/src/TagLib/StringList.cs create mode 100644 taglib-sharp/src/TagLib/SupportedMimeType.cs create mode 100644 taglib-sharp/src/TagLib/Tag.cs create mode 100644 taglib-sharp/src/TagLib/TagLib.sources create mode 100644 taglib-sharp/src/TagLib/Tiff/Arw/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/BaseTiffFile.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Codec.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Cr2/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Dng/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Nef/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Pef/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Rw2/File.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Rw2/IFDReader.cs create mode 100644 taglib-sharp/src/TagLib/Tiff/Rw2/IFDTag.cs create mode 100644 taglib-sharp/src/TagLib/UnsupportedFormatException.cs create mode 100644 taglib-sharp/src/TagLib/WavPack/File.cs create mode 100644 taglib-sharp/src/TagLib/WavPack/StreamHeader.cs create mode 100644 taglib-sharp/src/TagLib/Xmp/XmlNodeExtensions.cs create mode 100644 taglib-sharp/src/TagLib/Xmp/XmpNode.cs create mode 100644 taglib-sharp/src/TagLib/Xmp/XmpNodeType.cs create mode 100644 taglib-sharp/src/TagLib/Xmp/XmpNodeVisitor.cs create mode 100644 taglib-sharp/src/TagLib/Xmp/XmpTag.cs create mode 100644 taglib-sharp/src/policy.2.0.taglib-sharp.config.in create mode 100644 taglib-sharp/src/taglib-sharp.csproj create mode 100644 taglib-sharp/taglib-sharp.pc.in create mode 100644 taglib-sharp/taglib-sharp.sln create mode 100644 taglib-sharp/taglib-sharp.snk diff --git a/taglib-sharp/.gitignore b/taglib-sharp/.gitignore new file mode 100644 index 0000000..24cb39e --- /dev/null +++ b/taglib-sharp/.gitignore @@ -0,0 +1,31 @@ +INSTALL +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +bin/ +config.log +config.status +configure +*.exe +*.mdb +*.pidb +*.config +install-sh +missing +src/AssemblyInfo.cs +*.pc +*.zip +tests/samples/tmp* +docs/*.xml +docs/*/* +docs/*.tree +*.dll.xml +examples/*.dll +*.userprefs +src/*.dll +src/*.snk +tests/*.dll +tests/*.xml +test-results +.*.swp diff --git a/taglib-sharp/.gitmodules b/taglib-sharp/.gitmodules new file mode 100644 index 0000000..da55947 --- /dev/null +++ b/taglib-sharp/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tests/raw-samples"] + path = tests/raw-samples + url = git://gitorious.org/taglib-sharp/raw-samples.git diff --git a/taglib-sharp/AUTHORS b/taglib-sharp/AUTHORS new file mode 100644 index 0000000..615e9ab --- /dev/null +++ b/taglib-sharp/AUTHORS @@ -0,0 +1,29 @@ +Maintainer: + Gabriel Burt + +Contributors: + Aaron Bockover + Alexander Kojevnikov + Andrés G. Aragoneses + Andy Beal + Bernd Niedergesaess + Bertrand Lorentz + Colin Turner + Eamon Nerbonne + Félix Velasco + Gregory S. Chudov + Helmut Wahrmann + Jeffrey Stedfast + Jeroen Asselman + John Millikin + Julien Moutte + Marek Habersack + Mike Gemünde + Patrick Dehne + Paul Lange + Ruben Vermeersch + Stephane Delcroix + Tim Howard + +Creator, past maintainer: + Brian Nickel diff --git a/taglib-sharp/COPYING b/taglib-sharp/COPYING new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/taglib-sharp/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/taglib-sharp/ChangeLog b/taglib-sharp/ChangeLog new file mode 100644 index 0000000..490a9fb --- /dev/null +++ b/taglib-sharp/ChangeLog @@ -0,0 +1,7032 @@ + +commit 3f6c8a5a3dabfb335ab67259e258bc747219a9ae +Author: Ruben Vermeersch +Date: Sat Aug 7 09:43:59 2010 + + [IFD] Fix parsing with non-null delimited strings. + + There was an interesting off-by-one parsing error for strings that were + not delimited by a null byte. This commit makes sure we read the entire + byte array and then cut of everything up to the null byte. + + https://bugzilla.gnome.org/show_bug.cgi?id=493530 + +commit dbad977936d4efc6187767b9ae1cec1edfa288f1 +Author: Ruben Vermeersch +Date: Thu Jul 22 08:26:13 2010 + + [Jpeg] Don't complain if the stream Length can't be read. + + https://bugzilla.gnome.org/show_bug.cgi?id=624671 + +commit be510696d1b0d7eee1e8947c29ff0d7949e4f543 +Author: Ruben Vermeersch +Date: Thu Jul 22 08:08:32 2010 + + Detect IFD entry type 0 corruption. + + https://bugzilla.gnome.org/show_bug.cgi?id=625009 + +commit 8d44e11a5473417f3bbf2590260c57257ec8d7ab +Author: Ruben Vermeersch +Date: Thu Jul 22 08:08:04 2010 + + Ignore compiled helper binaries. + +commit ce41ae6314ab5a891140856e6b7c7d1c50b8d91d +Author: Ruben Vermeersch +Date: Thu Jul 22 07:50:17 2010 + + Comment out unused lines. + +commit a1161e8b901ca73f56a3984a23f64379c6522dbb +Author: Ruben Vermeersch +Date: Thu Jul 22 07:48:14 2010 + + Update unit tests, the used XMP tags do not contain the Orientation. + +commit 2bdf23c46adff2d46a58694005a8e5beb3063f38 +Author: Ruben Vermeersch +Date: Thu Jul 22 07:47:13 2010 + + Don't throw exception on invalid IFD offsets. + + Mark as corrupt instead. + +commit e88f64ec9c9953037ff6aad0d3d8dcc4ec432473 +Author: Mike Gemünde +Date: Tue Jul 20 05:52:08 2010 + + Fix CopyFromTest to be unsensitive to different formats of ToString for DateTime + +commit ecfe021ae3549140067de5ea7fd990bf606d4d91 +Author: Mike Gemünde +Date: Tue Jul 20 05:50:02 2010 + + Add default value for ImageOrientation (None = 0) + + It was not possible to distinguish wether a orientation is not set + or it is set to TopLeft, because TopLeft was used as the default. + This caused problems when determining the orientation in CombinedImageTag. + Therfore, a default is now added to get the correct value. + +commit 486632c7bc8ef86c41a60680272481c3e5fdee24 +Author: Mike Gemünde +Date: Sun Jul 18 02:51:05 2010 + + Fix typo in mime type of cr2 files + +commit 8c922c0387d32176ef940791f25ec9db533ac0cf +Author: Ruben Vermeersch +Date: Tue Jul 13 13:31:27 2010 + + Cycle detection to avoid endless IFD loops. + + https://bugzilla.gnome.org/show_bug.cgi?id=391671 + +commit 0bf4c68da62ad73a927b127d9d61571a68cbd43c +Author: Ruben Vermeersch +Date: Tue Jul 13 11:47:55 2010 + + Parse and detect corruption in Olympus makernotes. + + https://bugzilla.gnome.org/show_bug.cgi?id=555340 + +commit 634a55d461819277f1cd032e602b0468e5c71870 +Author: Ruben Vermeersch +Date: Tue Jul 13 10:47:24 2010 + + Handle all space comments. + + https://bugzilla.gnome.org/show_bug.cgi?id=397002 + +commit 9ac4daf03c50f697aea45333692d9d0e51396095 +Author: Ruben Vermeersch +Date: Tue Jul 13 10:46:31 2010 + + Support generating fixtures for Olympus files. + +commit 5b595bef6bdf74f70239248bf46a8a8193c5b085 +Author: Ruben Vermeersch +Date: Tue Jul 13 10:34:30 2010 + + Add support for empty comments consisting of only spaces. + +commit fb8e08b00909eea17cf2c08553c3c5aaf165dd5a +Author: Ruben Vermeersch +Date: Tue Jul 13 10:22:07 2010 + + Add SVG support via NoMetadata, for now. + +commit a67a562149925fd0862b9d3858c401f4f5d97ddb +Author: Ruben Vermeersch +Date: Mon Jul 12 10:48:24 2010 + + Refuse to write files with unknown corruptions. + + Certain Nikon files can have strange corruptions which we're not sure + how to parse (nor do other metadata libraries). This may be a bug or a + feature. We detect it and refuse to write in such cases. + + https://bugzilla.gnome.org/show_bug.cgi?id=624097 + +commit 6c3ce99097a13e6194a755dfeec8ab82aeec23a1 +Author: Ruben Vermeersch +Date: Sun Jul 11 06:05:01 2010 + + Validate remaining XmpTag values. + +commit 785e4cb1bbfccc3a2d4a2d2258b69937abf3f524 +Author: Ruben Vermeersch +Date: Sun Jul 11 05:42:59 2010 + + Start validating ImageTag implementations. + + Fixes some bugs in XmpTag and adds some fallbacks. + +commit 0659501225f66d8e22df141502fc1a897d797067 +Author: Ruben Vermeersch +Date: Tue Jul 6 17:33:26 2010 + + Parse embedded JpgFromRaw in RW2 files. + +commit a58728170f54fd7823df1bca318cf2a6214f9c02 +Author: Ruben Vermeersch +Date: Mon Jul 5 12:08:27 2010 + + Remove debug statements. + +commit fa81e725cd7104e12a75b92c622d302780713892 +Author: Ruben Vermeersch +Date: Thu Jul 1 12:30:21 2010 + + Add Rw2 files to Monodevelop projects. + +commit c8964265eebde4e623716e4e9ef906f3a505eef0 +Author: Ruben Vermeersch +Date: Sun Jun 27 10:39:10 2010 + + First incomplete attempt at RW2 support. + + Different approach is needed, but I'm too frustrated with Panasonics + horrible format for now. + +commit adddbacf46b928c207e1104be98c5ed584d58b53 +Author: Ruben Vermeersch +Date: Tue Jul 6 12:28:13 2010 + + Fix build breakage. + +commit 4a6f66c806c0f725778e4fb091c674bf6434cc62 +Author: Ruben Vermeersch +Date: Mon Jul 5 16:20:27 2010 + + Add initial DNG support. + + Gets the size wrong, but I'll fix that soon, when I start adding a + simple API test for each file type. + +commit 97668fecb6f55ec15610c39f58c81608f9caa015 +Author: Ruben Vermeersch +Date: Mon Jul 5 12:50:35 2010 + + Add Sony ARW support. + +commit dd99430ab167520497e584eb9a562eceadf269c6 +Author: Ruben Vermeersch +Date: Fri Jul 2 16:17:50 2010 + + Add PCX support to NoMetadata. + +commit f96cca366b0d34a76a9679df69de8868d435df33 +Author: Ruben Vermeersch +Date: Fri Jul 2 16:12:42 2010 + + Add mime types and extensions for Netpbm to NoMetadata. + +commit 454ae09e6cb5f5d6d1815bb5d3ed2785b2de0c5a +Author: Ruben Vermeersch +Date: Fri Jul 2 16:09:43 2010 + + Add mime types for bitmaps. + +commit 9f7bdc3a04a89cd339dbe647198cbcb1f9536c78 +Author: Ruben Vermeersch +Date: Fri Jul 2 15:37:43 2010 + + Add bitmap as a non-metadata type. + +commit a96174f6eae4eabeeda59b427afe7d9ba1f5d76b +Author: Ruben Vermeersch +Date: Fri Jul 2 15:31:13 2010 + + Add a fallback type for images without metadata. + +commit 3e2f3819ad7ce424672e2127c5894a33ab372573 +Author: Ruben Vermeersch +Date: Fri Jul 2 03:32:31 2010 + + Make a list copy to avoid out-of-sync enumerators. + +commit 8445fc0927f14607f0c4a32d4233ec2f1e9f703d +Author: Ruben Vermeersch +Date: Fri Jul 2 03:29:55 2010 + + Remove empty Sub IFDs before rendering. + +commit 7d632cc334efea165190c19863363252bf2b6539 +Author: Ruben Vermeersch +Date: Fri Jul 2 03:23:14 2010 + + Revert "Don't render empty Sub IFDs" + + This reverts commit 359bf87df97b991d9e9de53d0e63ba02424796ab. + + Not the right way to fix it. + +commit aa93264a11e5b994c829d57521860d62bac58191 +Author: Ruben Vermeersch +Date: Fri Jul 2 03:17:11 2010 + + Don't render empty Sub IFDs + +commit 0c1bf35b0cf9f68dbb96df6501ae1cd3144daa08 +Author: Ruben Vermeersch +Date: Fri Jul 2 03:04:30 2010 + + Fix handling of nullable assignments. + +commit d4ab524264c5defe57046950697ba41c9dc96715 +Author: Ruben Vermeersch +Date: Thu Jul 1 18:25:53 2010 + + Add metadata copying between images. + + Only copies the values from ImageTag. Good enough. + + https://bugzilla.gnome.org/show_bug.cgi?id=618770 + +commit f8bc4a360d158cbc76852d94f5e0ab8baddfb976 +Author: Ruben Vermeersch +Date: Thu Jul 1 11:14:02 2010 + + Update MonoDevelop support. + +commit 3a625b1054f3cb1eed898471dbb4406783d94142 +Author: Ruben Vermeersch +Date: Sun Jun 27 10:11:51 2010 + + Indent values in ParsePhoto. + +commit 00a049969c3428e06c81422afa0ed8258ef117fc +Author: Ruben Vermeersch +Date: Sat Jun 26 17:54:55 2010 + + Remove stray file from build. + + This shouldn't have been committed. + +commit 80942aae30028a919022c26ae117296fc0912c3a +Author: Ruben Vermeersch +Date: Sat Jun 26 17:08:10 2010 + + Make the Tiff Codec type reusable. + + Avoid having to define a new one for each new Tiff-derived type. + +commit f5a98009508fc8961eff1cb5c0c18447dfaf7af7 +Author: Ruben Vermeersch +Date: Sat Jun 26 16:54:58 2010 + + Move Tiff-based RAW types into Tiff namespace. + + There will be a lot of them, don't want to clutter the main source tree. + +commit dd7c59b844ee8c840b544b7bffb60935f1b1409e +Author: Ruben Vermeersch +Date: Sat Jun 26 16:19:08 2010 + + Don't crash when writing empty XMP collections. + +commit 06211a9fc78172fb7bce88136d268391c11c974f +Author: Ruben Vermeersch +Date: Thu Jun 24 13:27:59 2010 + + Expand Nikon format support. + + Nikon encodes a ton of info into byte arrays. These are not parsed yet. + Perhaps we should do so at some point, or at least pull the interesting + bits out. + +commit 6d75fdc99e004d0b1e24e15474d163c638d3ffb6 +Author: Ruben Vermeersch +Date: Thu Jun 24 13:26:43 2010 + + Add support for SubIFDs and SubImages. + +commit 737857b640e60a0424e9317b83d768685ca096a7 +Author: Ruben Vermeersch +Date: Thu Jun 24 13:11:04 2010 + + Update to test repository with NEF file. + +commit 8fe3d0ee40610d78e27da996d3a379a022eeadb3 +Author: Ruben Vermeersch +Date: Thu Jun 24 11:26:36 2010 + + Don't inherit file type attributes. + + This makes it possible to make an inherited TIFF type for NEF files. + +commit 40af7636c446833561d203b64e47e961e51cb973 +Author: Ruben Vermeersch +Date: Wed Jun 23 04:36:09 2010 + + Add initial NEF support. + +commit 7b1311a55c9a2d4173ac3f3c472007f87668a827 +Author: Ruben Vermeersch +Date: Wed Jun 23 04:09:40 2010 + + Fix copy/paste error in comments. + +commit 5c986c18a831105556aff482cd75be6e6ba213d9 +Author: Ruben Vermeersch +Date: Sun Jun 20 08:29:27 2010 + + Compare visual data based on hashes. + + Slightly faster. + +commit 5d39e3d9dbe06cf357469335a9f698a4afefe1cf +Author: Mike Gemünde +Date: Thu Jun 17 06:14:34 2010 + + Add Canon CR2 test + +commit 405d847b7ac611cbe07555987096df6a9ab0d692 +Author: Ruben Vermeersch +Date: Sun Jun 20 08:55:09 2010 + + Add IFD tags for a bunch of Canon fields. + +commit 731f2e0b76e79b8587c8ea1d9c1f53e336cccbe8 +Author: Ruben Vermeersch +Date: Sun Jun 20 08:22:45 2010 + + Compare very large values by MD5. + +commit 640714afe48fe208dbdd7f8366db4757192f859e +Author: Mike Gemünde +Date: Thu Jun 17 06:13:30 2010 + + Extend ImageTest + + ImageTest is extended to handle image files in different locations and to allow + read-only images tested. + +commit 51ceeb695ba0d42bfc06cea67c8e8b2d269efc5a +Author: Mike Gemünde +Date: Thu Jun 17 06:12:33 2010 + + Extend test generation tool + + The test generation tool now handles all namespaces from exiv2 for + Canon makernotes. + +commit 6e214001a1815f4f725b0453b97d1fc7eec1b09e +Author: Mike Gemünde +Date: Mon Jun 14 03:28:13 2010 + + Extend the ParsePhoto example to also show the image size + + https://bugzilla.gnome.org/show_bug.cgi?id=621508 + +commit b664ec978484b78805e71a88c6fdf8d589564039 +Author: Mike Gemünde +Date: Mon Jun 14 03:13:22 2010 + + Add support for Canon CR2 raw files + + This commits adds support to parse Canon CR2 RAW files. Since this + format is based on the TIFF structure, reading is mostly based on + this code. + + https://bugzilla.gnome.org/show_bug.cgi?id=621508 + +commit e43bf7115c00f0f81f086e11b4eef69d9cd47143 +Author: Mike Gemünde +Date: Mon Jun 14 03:05:03 2010 + + Add Property Writeable to Image.File + + Since we start supporting some file formats just for reading + (at least for now) the property Writeable is added to Image.File + to indicate if a file can be written back or not. + + https://bugzilla.gnome.org/show_bug.cgi?id=621508 + +commit c8832c3dcaa62098e120eb52bb2a8b0394f6b412 +Author: Mike Gemünde +Date: Mon Jun 14 03:03:24 2010 + + Introduce the class BaseTiffFile as base for all Tiff-based file formats + + The class BaseTiffFile is introduced to factor out some behavior which is + common for all Tiff-based file formats. + + https://bugzilla.gnome.org/show_bug.cgi?id=621508 + +commit aa090622f9d0221af5014570b4e0bb1ccf98372e +Author: Ruben Vermeersch +Date: Fri Jun 18 12:01:48 2010 + + Add XMP node replacement, which will be used for sidecar support. + +commit 3dd2d467cbbb6556a26e8673f5161124c8554dbd +Author: Ruben Vermeersch +Date: Mon Jun 14 17:50:51 2010 + + Add stubs for hooking in RAW tests. + +commit b19bac3b7ed4e3ed258d4da55215b492a90d1b7c +Author: Ruben Vermeersch +Date: Mon Jun 14 17:36:06 2010 + + Only enable "make test" for git builds. + +commit e849883343b2b7c1f77af696946a6aed40ca4a2a +Author: Ruben Vermeersch +Date: Mon Jun 14 17:31:19 2010 + + Don't ship test suite in tarball. + + Only built from git. + +commit 83693068bcf0c98d6b27c2244f6eae41ea8325e4 +Author: Ruben Vermeersch +Date: Sat Jun 12 09:43:00 2010 + + Fix XMP initialization and fixture test. + +commit 00f130e287724be3dbe806136c6989b610854cb1 +Author: Ruben Vermeersch +Date: Sat Jun 12 09:18:55 2010 + + Add prism namespace. + +commit d460c17c4edf90b8d08ac2fb4db669c2d59a0c9f +Author: Mike Gemünde +Date: Thu Jun 3 03:10:56 2010 + + Add support for compressed PNG chunks + + Support for compressed PNG chunks is added by using + ICSharpCode.SharpZipLib.dll. Configure and compilation + is conditional whether ICSharpCode.SharpZipLib.dll is + available or not. + + https://bugzilla.gnome.org/show_bug.cgi?id=620438 + +commit 56b2fa9e773bb39f78c34ce623b633ae37378e9e +Author: Ruben Vermeersch +Date: Sun May 30 15:51:12 2010 + + Fix some typos in the comments. + +commit b2abb6b51f8718fadb9245824c848de6ff054a14 +Author: Mike Gemünde +Date: Thu May 27 03:27:37 2010 + + Add tests for PNG support + + This commit adds a bunch of tests for the PNG support. The sample files + are created with GIMP and modified with exiftool. + + https://bugzilla.gnome.org/show_bug.cgi?id=619921 + +commit 94b8bfc406bda2231a0239782bdc0b8a819487e0 +Author: Mike Gemünde +Date: Thu May 27 03:25:04 2010 + + Introduce support for PNG files + + This commit introduces support for PNG files. A PNG file is parsed + completely and XMP metdata and PNG keywords are extracted. Additionally, + some image properties such as height and with are determined. + + https://bugzilla.gnome.org/show_bug.cgi?id=619921 + +commit d1e8903491c89c7a015c748358084ba61f15c200 +Author: Mike Gemünde +Date: Tue May 25 14:34:07 2010 + + Create class ImageBlockFile for image files organized with data blocks + + Some image file formats are organized as data blocks which can be reordered. + Those block are called 'segments' for Jpeg/Jfif files, or 'blocks' for Gif + files. Some of the blocks are metadata and handled by TagLib#. When metadata + is saved back to file, the following must be typically done: + (1) some of the blocks have to be deleted + (2) other blocks are overwritten with the new metadata + + The new class ImageBlockFile allows to mark some blocks in the file as + metadata. When metadata is written back to file, the blocks which can be reused + are overwritten, the others are deleted. The File-classes for Jpeg and + Gif can now share this functionality. + Currently, ImageBlockFile only supports saving one data block (which + may contain multiple metadata blocks) and removing all other marked + blocks in file. That is fine for the currently implemented file formats, but + may be changed in future. + + https://bugzilla.gnome.org/show_bug.cgi?id=619921 + +commit 6c5c56ca76d6bc4c976dfbf5a18eab324bcac390 +Author: Ruben Vermeersch +Date: Sun May 30 10:54:21 2010 + + Fix unused variable warning. + +commit 014eeaaaa25629aae1589f5c346bcda4dccc2375 +Author: Mike Gemünde +Date: Fri May 28 03:38:44 2010 + + Remove CommentTest for jpeg test without metadata + + It does not make sense to have that test here, because a comment + cannot be added, when no tag is present. And it is against the current + taglib policy to add tags without a request from the user. + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit 6446fd2116446e67335c0e5c21b2ceda854a7667 +Author: Mike Gemünde +Date: Thu May 27 09:05:59 2010 + + Add Function which ensures that all possible image tags for an image file are in place + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit 20c02ec406477c39edf57d90605c784e6f3e41fc +Author: Mike Gemünde +Date: Thu May 27 09:06:43 2010 + + Add Test to ensure that the ImageTag properties work correctly + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit d11b9bfe861b47e0bbfd3a999376bdeb265cb802 +Author: Mike Gemünde +Date: Thu May 27 08:46:29 2010 + + Add more flexible PropertyModificationValidator + + The new class PropertyModificationValidator allows to test modifications for + every property defined in ImageTag. This makes it more flexible to test them + all. + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit a8651759588cc587b20dad4a2cabf1a189925f8d +Author: Mike Gemünde +Date: Thu May 27 03:07:09 2010 + + Add some properties which are usefull for image tags + + The property Creator is added to ImageTag. The properties + Copyright, Comment and Title are implemented in CombinedImageTag + to reuse them from Audio/Video. + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit 2f27f26fc3aad9f256942c4ea64e4a00f6a0384c +Author: Mike Gemünde +Date: Thu May 27 08:11:04 2010 + + JpegComment need not to be terminated by 0 + + Some programs set an jpeg comment which is not terminated by a 0. Therfore, + we cannot remove the last character in every case. Rather, check for + a terminated string. + + https://bugzilla.gnome.org/show_bug.cgi?id=619920 + +commit f3309790ba158f3c0b460c87260b74876dfa2a10 +Author: Ruben Vermeersch +Date: Sun May 23 08:02:07 2010 + + Remove a bit of unreadable code. + +commit c71ae99fe735b4a07387360a561554a597a0be56 +Author: Mike Gemünde +Date: Sun May 23 07:23:38 2010 + + Add tests for GIF support + + This commit adds a bunch of tests for the GIF support. The sample files + are created with GIMP and modified with exiftool. Some sample files are + hand-edited to provide input data for some special tests. + + https://bugzilla.gnome.org/show_bug.cgi?id=619432 + +commit da6378ddd68eccc82c478f4da66399d912e413ac +Author: Mike Gemünde +Date: Sun May 23 07:21:53 2010 + + Add Validator to test removal of tags from files + + A new Validator for the image tests is added which can be used to + test if tags are correctly removed from files. + + https://bugzilla.gnome.org/show_bug.cgi?id=619432 + +commit 63ccf602c6523d1aa66b9f506b16a7d9f4c4018b +Author: Mike Gemünde +Date: Sun May 23 07:06:24 2010 + + Extend Validators to specify an own comment string for the test + + The current implementation of CommentModificationValidator and + TagCommentModificationValidator uses a fixed comment for testing. + This commit extends the Validators that the comment string can be + changed and an arbitrary comment can be used for the test. + + https://bugzilla.gnome.org/show_bug.cgi?id=619432 + +commit d731abbab07c83242fd63ddb67ebd215f02bb8a5 +Author: Mike Gemünde +Date: Sun May 23 07:03:07 2010 + + Introduce support for GIF files + + This commit introduces support for GIF files. A GIF file is parsed + completely and XMP metadata and GIF comments are extracted. Additionally, + the size of the image is extracted. Since GIF files can be used as + an animation, it would be reasonable to determine some Properties + which are related to Audio/Video files. This is currently not covered. + + https://bugzilla.gnome.org/show_bug.cgi?id=619432 + +commit 68722264132abced296ccfa049d90b6549fecddf +Author: Mike Gemünde +Date: Thu May 20 09:32:54 2010 + + Remove uneccessary if condition in CombinedImageTag + + https://bugzilla.gnome.org/show_bug.cgi?id=619200 + +commit 9c321e650273c9f890d706a5599d8c813a2b201d +Author: Ruben Vermeersch +Date: Sun Apr 11 08:17:40 2010 + + Make the initialization of XmpTag thread-safe. + +commit ecb22bf31b518a54f085b86a8f96d8a69c1d5548 +Author: Ruben Vermeersch +Date: Sat Apr 3 08:21:26 2010 + + Fix warning, add docs. + +commit d63b87f909fdb92e3cdb75d7c31d91f0b73d9269 +Author: Ruben Vermeersch +Date: Sat Apr 3 08:21:13 2010 + + Add missing Dispose () doc block. + +commit 0ef04eaab535d1baa030fef0042f766fb9ce8b61 +Author: Ruben Vermeersch +Date: Sat Apr 3 07:30:18 2010 + + Ignore monodevelop test results. + +commit 13a407f2a8e8a4731787cb7068047135bcc4d1ea +Author: Ruben Vermeersch +Date: Sat Apr 3 07:28:23 2010 + + Skip visual comparison on large TIFFs. + + Running unit tests became too slow on my netbook. Remember that you can run the + full set of validators by running: + + make run COMPARE_LARGE_FILES=1 + + Should be done before each merge/release. + +commit 3d176ca43b1dea87b6ba0e3667416909d4059d13 +Author: Ruben Vermeersch +Date: Sat Apr 3 07:26:12 2010 + + Add support for value pairs in unit test generator. + + Exiv2 has the stupid habit of printing a list of values joined by a comma. + + This means that a field that looks like this: + + [ "a, b", "c, d" ] + + Is printed as: + + "a, b, c, d" + + Fortunately we can use the length field to detect this and do the right thing. + +commit 1ea7a011e2de479320a3948a359ccf276969afe9 +Author: Ruben Vermeersch +Date: Sat Apr 3 07:24:56 2010 + + Fix exception for files without orientation entry. + + Trying to cast null to an ImageOrientation enum member throws an exception. + Fall back to TopLeft to avoid it. Unit test added to test this. + +commit eeb815ed8e04671a0a429261859d42af030cb61b +Author: Ruben Vermeersch +Date: Sat Apr 3 07:06:07 2010 + + Add aux XMP namespace. + +commit dbd404b4a025f0c6e11b2df825ab03bd5fe0e805 +Author: Ruben Vermeersch +Date: Sat Mar 20 13:05:00 2010 + + Fix XMP unit test failure. + + We disagree with exiv2 on the meaning of Struct. In Taglib#, struct is meant to + denote parseType=Resource types only, not the shorthand equivalent. Also see + XmpNode.RenderInto() + +commit dd7d2ded96bdf310b8e96f08bcf654aba2b153e5 +Author: Mike Gemünde +Date: Fri Mar 5 04:39:21 2010 + + regenerate basic tiff test with generation tool + +commit 901cab9d0d27d0428f098d49f7a8bc9775f30bda +Author: Mike Gemünde +Date: Thu Feb 11 16:17:40 2010 + + Add a bunch of new tests for tiff and jpeg + +commit 0c164d4e844aacb8b449d380b11db0b18f61c641 +Author: Mike Gemünde +Date: Thu Feb 11 16:14:13 2010 + + Extend GenerateTestFixture + +commit 8640ef4e11e9a2ba107bf98edac9b3394b364408 +Author: Mike Gemünde +Date: Thu Feb 11 16:13:11 2010 + + First implementation of tiff-writing + +commit fd87a160d8f5238db3d1ee7d4845a2a2f439b8f9 +Author: Ruben Vermeersch +Date: Tue Feb 9 09:14:13 2010 + + Replace fubar namespace + +commit 92bc4a1b40aeebf23cfdbb5fcec9da216eaface5 +Author: Ruben Vermeersch +Date: Sat Feb 20 10:17:51 2010 + + Monodevelop build fixes. + +commit 90b7c1527bedf4b738940b7e5ab4da2f1cec62a6 +Author: Ruben Vermeersch +Date: Sat Feb 20 09:41:51 2010 + + Use autotools to build src/ + +commit 32e16e3a90ef37854ed5896e78f2122f661d9b63 +Author: Ruben Vermeersch +Date: Sat Feb 20 09:41:28 2010 + + Make NamespacePrefixes public. + + Needed for the unit test generator. + +commit 40dbaee8956348bb8b7fb491e4a3985c733a521d +Author: Ruben Vermeersch +Date: Tue Feb 16 12:18:45 2010 + + Kill all warnings + + This now means we can build without any warnings! + +commit 9230695e84e8f7f414728816ab08439e63579442 +Author: Ruben Vermeersch +Date: Sat Feb 13 09:55:35 2010 + + Fix build in Monodevelop. + + This was done against a Monodevelop version from trunk, but it should work with + any reasonably new version. Unit tests are synchronized with the Makefile, the + main assembly uses a special .sources file which does not allow that trick. + Might deprecate that one at some point. + + The tests makefile was modified to allow building in Monodevelop. + +commit fd429ea366b095cf8d67294e721c2efb85b3e5e2 +Author: Ruben Vermeersch +Date: Sat Jan 23 11:26:55 2010 + + Replace JpegEmptyTest. + + This new test highlights one of the problems that CombinedImageTag currently + has: if there's no metadata tag capable of storing the field, the change will + be lost. We should try to accomodate that. + +commit 8ab09e06b6e810794681e9fc43e40fcf647ce149 +Author: Ruben Vermeersch +Date: Sat Jan 23 09:55:31 2010 + + Remove compile warning. + +commit e705fd4ecbd723efbb8e5eaf00cd4248118b4581 +Author: Ruben Vermeersch +Date: Sat Jan 23 09:53:03 2010 + + Use String.Empty as the default value for Keywords in CombinedImageTag. + +commit fc04c52a18fdcba1c58a6bff20696414c77f6acd +Author: Ruben Vermeersch +Date: Sat Jan 23 09:49:56 2010 + + Ignore three failing tests. + + This doesn't mean that we don't need to fix them, but I got tired of parsing + them every time I compile my code. + +commit 443a43c7fe516d3017396c48fb631b7d3e1282d3 +Author: Ruben Vermeersch +Date: Sat Jan 23 09:47:02 2010 + + Replace Panasonic test by much expanded version. + +commit 92995954ce437aeccc95e56bd7f0df7bee364bdd +Author: Ruben Vermeersch +Date: Sat Jan 23 09:36:02 2010 + + Add a bunch of Panasonic makernote entry tags. + +commit cb3300243013283c8f6d5ce06f9c0fefeb4363aa +Author: Ruben Vermeersch +Date: Sat Jan 23 09:28:47 2010 + + Replace the Nikon1 test with a generated one. + + This one tests all the original assumptions (including properties), but also + all the fields that weren't checked. + +commit 93fda71c1833ac30d95d7ad1471b4b4192eec88c +Author: Ruben Vermeersch +Date: Sat Jan 23 09:23:34 2010 + + Add a ton of Nikon3 IFD entry tags. + +commit 0cd061e536fc54cdee747a4a7288566eaf16292a +Author: Ruben Vermeersch +Date: Sat Jan 23 08:58:36 2010 + + Add support for generating test fixtures for Panasonic files. + +commit 33880f7723388699fc8cfd00abc62ca8aa2eedad +Author: Ruben Vermeersch +Date: Sat Jan 23 08:43:29 2010 + + Add conditional for running slow image comparisons. + + Comparing huge files is slow. Therefor, we don't do that by default. If you + want to run the full tests, you'll need to pass the COMPARE_LARGE_IMAGES flag: + + make test COMPARE_LARGE_IMAGES=1 + + It's best to do this occasionally for sanity reasons, but you probably don't + want to do this every time you compile your code. + +commit 5e4a20af289c2ed2b5148641331e25174dd3170d +Author: Ruben Vermeersch +Date: Sat Jan 23 08:42:53 2010 + + Make sure GDK is initialized. + +commit 50ffad60a1362c091a5d632b2bc13677bda5ee70 +Author: Ruben Vermeersch +Date: Sat Jan 23 07:05:39 2010 + + Implement visual validation of image data. + + This means that not only the metadata is checked pre/post write, but also the + image data itself. This is done by reading the image using GdkPixbuf (RAW + support still TODO) and then rendering it to a PNG without metadata. + This byte dump is then compared for the original and the modified file. + + This makes the tests a bit slower. I don't care. + +commit a19e70680880efbafc9853e1624fa7dcb3202779 +Author: Ruben Vermeersch +Date: Sat Jan 23 07:04:12 2010 + + Add missing Nikon3 makernote tag. + + Tons of them left to do. + +commit 9a8b89588c1dae7c1a80958feee27d32379faa7f +Author: Ruben Vermeersch +Date: Sat Jan 23 06:09:39 2010 + + Always reuse the same NoModificationValidator in unit tests. + +commit 828a6c147f6dfb38267b847063d37a36284e1a19 +Author: Ruben Vermeersch +Date: Sat Jan 23 05:25:57 2010 + + Let GenerateTestFixture use Nikon3MakerNoteEntryTag. + +commit 62f1af61fef25d02e116dda01f7b1b42e0ec3601 +Author: Ruben Vermeersch +Date: Sat Jan 23 05:25:33 2010 + + Fix wrong value for the Preview tag. + +commit aba2b7b59ca3658b00cf7ea2c25469ea7e63e6b5 +Author: Ruben Vermeersch +Date: Sat Jan 23 05:20:34 2010 + + Add missing IFD tags for ratings. + +commit 6d39456992c538993ec89cfa030eda8fab55d51f +Author: Ruben Vermeersch +Date: Sat Jan 23 05:05:30 2010 + + Add some comments to Nikon3MakernoteReader. + +commit e0ca4fe802b209fc7916f1f6e06e02c198461502 +Author: Ruben Vermeersch +Date: Sat Jan 23 05:00:16 2010 + + Add Nikon3MakerNoteEntryTag to remove hex value in Nikon3MakernoteReader. + +commit 286b1e327ed657b860c2d088c3bcdbb8eb6c7131 +Author: Ruben Vermeersch +Date: Sat Jan 23 04:49:23 2010 + + Split IFD entry types out into separate files. + + Moved these into a new namespace and updated all files accordingly (unit test + generator included). + +commit 87edb107fe6a373c44ac7102bd77bb2378caafbf +Author: Ruben Vermeersch +Date: Sat Jan 23 04:30:49 2010 + + Clean up the IFD-offset fix a bit and add some docs. + +commit f7c8f24e435268aa3430af1f60140435fc1595b4 +Author: Mike Gemünde +Date: Tue Jan 12 15:06:23 2010 + + Fix for the Nikon makernote preview image + + The jpeg file of the nikon2 contains a preview image referenced + by the makernote but not stored along with the other makernote data. + Additionally, the preview image ifd does not contain a next-ifd + pointer. This commits handles that and parses the preview image + ifd. + +commit b95dbadf74d1a7dd8ba605c52cab1dfbff869673 +Author: Ruben Vermeersch +Date: Mon Dec 28 18:38:28 2009 + + Fix XapTest naming. + +commit 5d535fc8a949b111155b24d432868927ca70382a +Author: Ruben Vermeersch +Date: Mon Dec 28 18:37:14 2009 + + Expand JpegCanonZoombrowserTest with all available values. + +commit c0f135011487ab5c297fcda9c21a4b4d27afb0ca +Author: Ruben Vermeersch +Date: Mon Dec 28 18:25:55 2009 + + Add a ton of missing IFDEntryTags, handle them. + +commit 76ef1952856d46aa5c12c7b95542503aab358bb3 +Author: Ruben Vermeersch +Date: Mon Dec 28 13:42:39 2009 + + Split out UserComment code into a separate IFD entry. + + This allows it to be tested with generated test cases. + +commit bacff80016206092652bc9c3e4c7ce2041856f78 +Author: Ruben Vermeersch +Date: Mon Dec 28 12:05:37 2009 + + Add custom exiv2 data-extraction programs. + + This adds two custom c++ programs that allow for much better data extraction. + Bad characters in the output of exiv2 caused certain keys to be missed. + +commit 5c81b09a7566d6c87799308c4984f60b8c874844 +Author: Ruben Vermeersch +Date: Mon Dec 28 08:26:45 2009 + + Fix CanonSi handling as well. + + Canon MakerNotes get validated correctly now. This means that they are + preserved when writing. Awesome. + +commit 3e2113e0d84470799e0990b974953c1293e5a756 +Author: Ruben Vermeersch +Date: Mon Dec 28 08:23:11 2009 + + Fix handling of CanonCs directories from exiv2. + +commit ce8e07334dbf7d0e7e9e42089d8fc66f99901f52 +Author: Ruben Vermeersch +Date: Mon Dec 28 05:53:45 2009 + + Trim output for empty strings. + + Due to exiv2's output not having delimiters, there is no way we can figure out + how long an empty string is (some fields in Nikon makernotes are 12 empty + spaces or 15 empty spaces). Therefor we trim the parsed value from Taglib# and + hope it equals to the empty string. This is one of those cases where generated + unit tests will not be 100% correct, yet still decently sufficient. Note that + trimming only happens if the expected output is empty. Otherwise, values are + compared as-is. + +commit 1e1238a6f9cc49559ae09c89ad743bea6333838c +Author: Ruben Vermeersch +Date: Mon Dec 28 04:58:38 2009 + + Fix MakerNote handling in unit test generator a bit. + + This includes: + * Correctly identifying the Nikon preview as a SubIFD + * Ignoring the exiv2 made-up entries. + +commit 2977064ce5625bad91e17e64ecda83cd4954df35 +Author: Ruben Vermeersch +Date: Mon Dec 28 04:57:37 2009 + + Add custom IFD reader for Nikon3 MakerNotes. + + Nikon makernotes have a special sub-ifd for previews. This reader picks up on + the relevant tag and makes sure it's parsed. + +commit 6eac0efb479d1e73f4a37f422c8da5f6c7214bdb +Author: Ruben Vermeersch +Date: Mon Dec 28 04:02:26 2009 + + Verify that simple XMP text nodes don't have children. + +commit c54627eff721c8c8114188b5e93bb7f62b608b78 +Author: Ruben Vermeersch +Date: Mon Dec 28 04:01:25 2009 + + Replace XapTest with a generated fixture. + + This version has a much better coverage of the metadata and features half a + dozen of modification tests. + +commit cd087e86d4c62f10ca6375cf1a820ef7c80113ce +Author: Ruben Vermeersch +Date: Mon Dec 28 02:45:31 2009 + + Add empty constructor for files that don't have a comment yet. + +commit 3171805c57a9078f083c905e0275c6d4d75e687b +Author: Ruben Vermeersch +Date: Mon Dec 28 02:31:07 2009 + + Ensure correct naming of GPSInfo and Thumbnail members. + +commit ec8ac47259a16e009871fb0b7427d4d14cf0850e +Author: Ruben Vermeersch +Date: Sat Dec 26 14:17:09 2009 + + Fix some exiv2 quirks. + +commit c49002b6025b69fdf8eea07d038906fabae80f27 +Author: Ruben Vermeersch +Date: Sat Dec 26 14:02:27 2009 + + Also generate XMP fixtures. + +commit 6ef39781c3389cdf6b8f35ed7de08a598e2131ff +Author: Ruben Vermeersch +Date: Sat Dec 26 11:52:52 2009 + + Add a ton of missing namespaces for XMP rendering. + +commit 5c2d5d4ecf57dc70a374e2a610716ebc84b3f29a +Author: Ruben Vermeersch +Date: Sat Dec 26 11:34:48 2009 + + Correctly test Byte arrays. + +commit 608e6912a809f284dbdddc4b50e8ff2680f59fa0 +Author: Ruben Vermeersch +Date: Sat Dec 26 11:34:25 2009 + + Fix Thumbnail test case generation. + +commit febde3d56b47b7c8804fd8ff1a1bf98dc5840ab5 +Author: Ruben Vermeersch +Date: Sat Dec 26 10:57:19 2009 + + Generate test cases for the GPS IFD. + +commit b0a8f76e54fddc1b4a4a572e8ca73b7869018662 +Author: Ruben Vermeersch +Date: Sat Dec 26 07:57:52 2009 + + Initial version of unit test generator. + + This uses data from exiv2 to create a test case. Should be taken with a grain + of salt though, I'm suspecting to have found a bug in exiv2 while testing this. + +commit 668ec86b5f3636524533d53cdab417816795fee7 +Author: Ruben Vermeersch +Date: Sat Dec 26 07:56:59 2009 + + Also test a write with no changes in JpegCanonZoombrowserTest. + +commit 092ead732bd54504a0e56197dc5784d35f5623d8 +Author: Ruben Vermeersch +Date: Fri Dec 25 07:28:52 2009 + + Validate orientation. + +commit c437c647898aa38ec2f69bb35d2c9ed1fa7784a9 +Author: Ruben Vermeersch +Date: Fri Dec 25 07:24:52 2009 + + Add a new validator based testing framework. + + This gives us a much better coverage of write/rewrite testing. + +commit 0c87736cf6c349136d794e2c697b34d24baffeed +Author: Ruben Vermeersch +Date: Thu Dec 24 11:26:22 2009 + + Register the MicrosoftPhoto namespace and correct it. + + Some files get written with an invalid namespace (according to the XMP specs, + namespaces should end with '/' or '#'). + +commit 1d7bcaa386e91e387be65338a099006dcc852af2 +Author: Ruben Vermeersch +Date: Thu Dec 24 11:14:21 2009 + + Factor out a common method. + +commit d437ce4ef8bf7571cdc041328171a197cd0d3f14 +Author: Mike Gemünde +Date: Mon Dec 7 08:15:18 2009 + + Add tests for Rational and SRational + +commit 0082efab1c5937e2b5ba93da3c2144fbfceca12d +Author: Mike Gemünde +Date: Mon Dec 7 07:20:26 2009 + + add Comments to IFD namespace and remove a bunch of warnings + +commit d52d71f52fb679babc7a73f4aca94425a00eb0dd +Author: Mike Gemünde +Date: Sun Dec 6 10:58:05 2009 + + fix Jpeg strip tool to substitue greates found data segment + +commit 1d06c80962c1140be37daa1f1594d9920bdddb26 +Author: Mike Gemünde +Date: Sun Dec 6 10:20:38 2009 + + Fix some documentation warnings + +commit 272d92e551fbe5996580247bebf387a0e0514886 +Author: Mike Gemünde +Date: Wed Dec 2 15:12:50 2009 + + do not read data in other segments even if it is referenced + + This is a quick hack to fixes the Sony makernotes, where some data + is stored in other segments than in the exif segment, but referenced + by an makernote entry. + +commit 105a95741ce0ce117506208320ac66ecda11a26f +Author: Mike Gemünde +Date: Wed Dec 2 14:10:47 2009 + + complete property tests + +commit 590907408af1618907266513ccec7edbafe8eb40 +Author: Mike Gemünde +Date: Wed Dec 2 13:17:29 2009 + + add support to read Sony makernotes + +commit 8f7b44ef7032dde19cf7834dd1964bb4a9a67eab +Author: Mike Gemünde +Date: Wed Dec 2 08:15:08 2009 + + Do not render jpeg segments if they are too big + +commit 0fb069d15f964df17ed12405097cb45c65d9ee4e +Author: Mike Gemünde +Date: Wed Dec 2 08:02:23 2009 + + add test for the case the metadata segments are too big to fit into a jpeg segment + +commit 17cfef37d3bdbc368cbfe0e2064be87c4f858aea +Author: Mike Gemünde +Date: Sun Dec 6 11:13:01 2009 + + Cleanup Jpeg related stuff + +commit 796754e6c5a685382f7c094ae233efd967cbe050 +Author: Mike Gemünde +Date: Mon Nov 30 14:14:24 2009 + + preserve existing JFIF header in jpegs + +commit 88f372927cb23c852da42f89051468110410731b +Author: Mike Gemünde +Date: Sun Dec 6 11:12:32 2009 + + Add support to write XMP data in jpegs together with some basic tests + +commit 207592ab98fd6dc5f672b5724921518fc026aef8 +Author: Mike Gemünde +Date: Sun Nov 29 05:21:55 2009 + + complete some copyright notice + +commit f7702f8b0d3159e4cbbebee039831888d77365ab +Author: Mike Gemünde +Date: Tue Dec 1 02:14:55 2009 + + Use own class for Makernotes to take care about some special things + +commit 2b8c587afde382f4cb7848777020aad11ab8b987 +Author: Mike Gemünde +Date: Sun Nov 29 04:04:06 2009 + + Add tests for File.Find and File.RFind which fail for current implementation + + The test cannot succeed for current imlementation of Find and RFind + because those methods only consider the greatest partial match and + do not take care about smaller ones. + +commit dd00c6327b28948fdb403b1c61434f7b4af591f6 +Author: Mike Gemünde +Date: Sun Nov 29 03:50:56 2009 + + Fix File.RFind partly and add a test + + RFind is fixed to do not crash when file size is smaller than the read buffer. + A test is added to take care about RFind and Find methods of the class File. + However, there is still an issue with matches spread above different buffer + reads. + +commit 5b15309936b714426715c5769ddab92d91753ecb +Author: Paul Lange +Date: Fri Dec 4 08:32:04 2009 + + Update MonoDevelop project files + + This commit updates the MonoDevelop projects files and makes it possible to build in MonoDevelop. + Furthermore it creates a project which includes all tests and runs nunit-console2 after a successful build for them. + +commit 066624c09e92fb3561d3639d7733a6289de9504e +Author: Paul Lange +Date: Sun Dec 6 09:16:31 2009 + + Fix filename in header + +commit 33cf614f999eb20a60e44b5c1c1ffe7ce6604639 +Author: Paul Lange +Date: Sat Dec 5 13:25:11 2009 + + Document ImageOrientation items + +commit ed9e22f2db4372a3bd368aee13feaa563e5790fd +Author: Paul Lange +Date: Sat Dec 5 07:13:55 2009 + + Remove ImageOrientation.Unknown value + +commit 672933310089a18b594205d4b463b854f6bde053 +Author: Paul Lange +Date: Sat Dec 5 05:59:31 2009 + + Add documentation to ImageOrientation + +commit 7d2416aa1f394dfc547a5586a35908139260b860 +Author: Paul Lange +Date: Sat Dec 5 05:56:20 2009 + + Convert the Orientation property to an enumeration. + +commit cb4c85fcb1e247f8b15e25665c963edc1fee31b3 +Author: Paul Lange +Date: Thu Dec 3 17:16:57 2009 + + Documentation fixes + +commit 063e41e52afbb71d6763f98da64564f47a439e29 +Author: Paul Lange +Date: Thu Dec 3 16:59:47 2009 + + Update test to test latest properties + +commit 7f56151dfc9e7108accdb3da57aea36f187cd558 +Author: Paul Lange +Date: Thu Dec 3 16:58:26 2009 + + Implement Orientation property + +commit a8a2f8a8888bd9dc9e90aae1e453f09268617e36 +Author: Paul Lange +Date: Thu Dec 3 10:44:06 2009 + + Add FocalLengthIn35mm Tag + +commit fd8c2f912e75d8072799f6763397fa7d9b998408 +Author: Ruben Vermeersch +Date: Sun Nov 29 17:00:27 2009 + + Register stDim namespace. + + Also fix crap spelling in unit test. + +commit aa967c6431e74d7d1feb0568dadf8ab0b693138b +Author: Ruben Vermeersch +Date: Sun Nov 29 16:48:51 2009 + + Add XMP rendering for most spec samples. + + Handles most of the spec samples correctly, except for the one I still have to fix. + + Fixed bugs in the parser along the way. This includes the fact that I'm not keeping + track of a new type of node called Struct. This is always rendered into a parseType + Resource. + +commit ad8163f097f9337e60699689a241cc239d7b0849 +Author: Ruben Vermeersch +Date: Sun Nov 29 14:18:52 2009 + + Add some documentation. + +commit b69b78b64b118fb5752a9d4faed3f3f9761fcb01 +Author: Ruben Vermeersch +Date: Sun Nov 29 14:18:39 2009 + + Fix some malformed XML comments. + +commit 5cb8ccfe8448ead95872a6b566da4e8afa10e4b9 +Author: Ruben Vermeersch +Date: Sun Nov 29 14:12:27 2009 + + Register the xmpTPg namespace. + + Makes the rendering of files that use this namespace nicer, it means they will + get xmpTPg:element nodes instead of ns1:element nodes. Off-course, all of this + doesn't matter when you use a proper namespaced-XML parser (like our code), but + I bet there are a ton of stupid implementations out there. + +commit 49f5de819a962dbcd63026cf75d71577737c8029 +Author: Ruben Vermeersch +Date: Sun Nov 29 14:09:48 2009 + + Initial XMP writing! + + Breaks a ton of stuff, since only simple values are supported for now. + +commit 559781fd057913e77cd913b56ed712bf43292582 +Author: Ruben Vermeersch +Date: Sun Nov 29 10:01:22 2009 + + Add comment from last commit message, serves as good explanation. + +commit fe9396868ad844de9aa00021ebd1964555d0cbbf +Author: Ruben Vermeersch +Date: Sun Nov 29 09:09:00 2009 + + Convert the XMP tests into idempotency tests during XMP rendering. + + This makes every test do the following: + * Parse the string and validate if all expected data is there. + * Render back into a string, parse that new string and revalidate. + + It's important to note that I'm testing for semantical idempotency: data that + was in will stay in. The representation might change though. This is okay, + nearly all XMP libraries do this. Doing the reparse and revalidate ensures + that whatever it generated is valid XMP and contains the same information. + +commit 423bc7bfbbd5bfb272039a2b0389847b51574e09 +Author: Paul Lange +Date: Sat Nov 28 13:46:59 2009 + + Remove old file + +commit 1506cb5c70aa01865583efbfe9ffc7c451f1b5af +Author: Paul Lange +Date: Sat Nov 28 13:42:00 2009 + + Add Makernote test to Sony test. + +commit f4b811a449dd66ed9eae3dde56afcec39b4ab1cd +Author: Paul Lange +Date: Wed Nov 25 17:56:41 2009 + + Create test for Sony Alpha 200. + +commit a27ea7cbc1795fb637d4daed8bac3df8a326ecfa +Author: Stephane Delcroix +Date: Wed Nov 25 10:11:47 2009 + + Guesstimate the jpeg quality from DQT tables + +commit 02e4eab345ac9fd33b1230f8a9a2f4be5e0acb23 +Author: Stephane Delcroix +Date: Wed Nov 25 04:36:37 2009 + + Define std tables + +commit b360005357e9b2b5c38ce45ce604072314be091d +Author: Stephane Delcroix +Date: Wed Nov 25 09:57:34 2009 + + unit test for image width and height + +commit 3d647645881d5f2d3ef71c4691b31a89fa2a7b12 +Author: Stephane Delcroix +Date: Wed Nov 25 09:45:39 2009 + + Read width and height from SOFn segment + + Parse SOFn segment, retrieve WxH, use them to set the properties + +commit c37b12648f7e48bfcd9aa627a171924f07e180ff +Author: Stephane Delcroix +Date: Wed Nov 25 03:48:10 2009 + + replace if/elif/elif by a switch + +commit 9728f102cd9716b27a834c6e933592d4449e7c5e +Author: Stephane Delcroix +Date: Wed Nov 25 03:45:06 2009 + + only call ReadSegmentMarker once + +commit 88c3005d9470e5df8c8a17c0b20d97727543ccb1 +Author: Stephane Delcroix +Date: Wed Nov 25 03:27:09 2009 + + complete the Marker table + + Add missing markers, use the TagLib.Jpeg.Marker type instead of byte in Jpeg.File + +commit abb724e102fff70baa5841ddb9be02d4bdea374a +Author: Ruben Vermeersch +Date: Fri Nov 20 16:32:47 2009 + + Fix a ton of warnings. + +commit 055de25226d4f1179e7b95bd5496972f3d343c91 +Author: Ruben Vermeersch +Date: Fri Nov 20 16:24:36 2009 + + Split XmpNodeType into another file. + +commit e71b79d06b6593d5a98f32e369ea60b74974c2dd +Author: Mike Gemünde +Date: Sun Nov 15 14:28:56 2009 + + ... and remove the SkipDataSegment + + We only recognize metadata segments occuring before the data segment in + the file. This is the same way exiv2 handles it. + +commit 17d4042cd39490c54e1cc97c33103395b3f52698 +Author: Mike Gemünde +Date: Sun Nov 15 13:37:38 2009 + + Substitute SkipDataSegment() with a much faster implementation + +commit 1314b55a9bae19f9e582438f1ca7ae45f47adc02 +Author: Mike Gemünde +Date: Sun Nov 15 14:16:04 2009 + + Added test for reading and writing tangled Jpeg files + + Mostly, the image metadata is stored in Jpegs in the segments at the beginning of the + file. Some tests are added for files, where the metadata segments are tangled around + the file. Also a bug for writing such files back is fixed. + + Conflicts: + + tests/Makefile.am + +commit a67c36600bf8d9a3bf08e2e3c6b8600c448bbccd +Author: Ruben Vermeersch +Date: Sun Nov 15 14:03:38 2009 + + Disable a stray debug dump. + +commit 0b21d567869b31bcdb94e83d9ce19521f996ec58 +Author: Ruben Vermeersch +Date: Sun Nov 15 13:57:12 2009 + + Add a lot of XMP spec compliance tests. + + This uncovered a bug, which is now fixed and a bug that still has to be fixed. + +commit 014a77ae24536e215d46576c91ce5d0fe5c1dfd5 +Author: Ruben Vermeersch +Date: Sun Nov 15 11:21:00 2009 + + Move the XMP test to another test file. + +commit 4d7dc8a74e9daa2c698215d5c68fafeb93d21671 +Author: Ruben Vermeersch +Date: Sun Nov 15 11:20:08 2009 + + Drop a useless parameter on XmpTag and use string instead of ByteVector. + + This will allow me to write unit tests easier. + +commit bf5747d7bf5ee86979db797eedfd3147e5fc6ce0 +Author: Ruben Vermeersch +Date: Sat Nov 14 14:03:03 2009 + + Minimize sample, using tiggers awesome tool. + +commit 43658ce3ac52183a8fc26b4604077d9e19565909 +Author: Ruben Vermeersch +Date: Sat Nov 14 13:54:57 2009 + + Implement a missing XMP dialect, additional test. + +commit 839aa430542a495a89f8bccd3de45c43753c90db +Author: Ruben Vermeersch +Date: Mon Nov 9 11:46:37 2009 + + Ignore XML comments. + +commit 255d53a969a783beced00a726a3ac05be2060c75 +Author: Ruben Vermeersch +Date: Mon Nov 9 11:46:10 2009 + + Old versions of XMP were called XAP, also look for those tags. + + Unit test will follow. + +commit 501464daa156195c2005706aa5e0373915a93438 +Author: Mike Gemünde +Date: Sat Nov 7 05:15:27 2009 + + add very rudimentary support for Olympus makernotes + +commit f5edd229d8392dffde630d42fb3404729a6f4dc6 +Author: Mike Gemünde +Date: Sat Nov 7 05:13:43 2009 + + add very basic example to substitute the image data in a jpeg file with some (very small) dummy data + +commit 05f51cc1e883a6ce61573c881613d14e87d77742 +Author: Mike Gemünde +Date: Sat Nov 7 05:12:43 2009 + + add another Nikon jpeg test + +commit e4d3394d33f1dafccf0eb4cef565a6ba7a3c114d +Author: Mike Gemünde +Date: Thu Nov 5 17:13:17 2009 + + first introduction of reading and writing of nikon makernotes + +commit eb1f30ce21194fe7c30c661ae72818562d3c5cf9 +Author: Mike Gemünde +Date: Thu Nov 5 16:43:56 2009 + + Add more information to unit tests to easier find an error + +commit 1ea38571eada751b29fd95a49942f0fb37bfc608 +Author: Mike Gemünde +Date: Wed Nov 4 16:51:48 2009 + + remove comment tags if a null is set for comment + +commit 87f3bb32953b657a01e98476082458e9ee77afdb +Author: Mike Gemünde +Date: Tue Nov 3 17:26:28 2009 + + reduce warnings by adding some comments to IFDStructure methods + +commit 7b5b2d47f8a36c1b33ec0422b2f8bf5427f8c38a +Author: Mike Gemünde +Date: Tue Nov 3 02:15:00 2009 + + remove comment property from ImageTag + + The Comment property is also included as virtual member in Tag. So we + do not need to provide another default implementation. + +commit f85e1e1829b0adc27259e00af5ed0097266ab7d1 +Author: Mike Gemünde +Date: Tue Nov 3 02:13:10 2009 + + implement Comment property for JpegComment + +commit 79bbf6dbe4d577ff6212cd7b63da4025fec7e23a +Author: Mike Gemünde +Date: Tue Nov 3 17:29:24 2009 + + Rating in ImageTag should also be a Nullable type to allow removing the rating. + +commit cadcc5e60db30887bc60e25ed5fecb6ffa55a1c2 +Author: Mike Gemünde +Date: Tue Nov 3 17:09:30 2009 + + add support for the Altitude property in IFDTag + +commit 50313af3a3395e5d21da55eb051c222cda0a83ff +Author: Mike Gemünde +Date: Tue Nov 3 16:13:24 2009 + + change plain values to Nullable in ImageTag + + For a lot of properties, a scalar value does not make sense, since the default value has also a meaning. + To allow to express that a tag is not existant, we use now nullable types. This is the case e.g. + for ExposureTime or FocalLength. + + Conflicts: + + src/TagLib/IFD/IFDTag.cs + +commit 4db7440a13a33cd6dff37ad2df6425bd57101513 +Author: Mike Gemünde +Date: Mon Nov 2 17:47:10 2009 + + fix GPS stuff to allow also negative longitude values + +commit 1b4bd6c144ed2e35a98698547c88b7607ef035b6 +Author: Ruben Vermeersch +Date: Mon Nov 2 17:26:23 2009 + + Kill two more warnings. + +commit 32629b5f3b9b3755701b6b73a397c7ba889e81c6 +Author: Ruben Vermeersch +Date: Mon Nov 2 17:24:17 2009 + + Kill warnings due to incorrect usage of keywords. + +commit 8acb7b766891c03bbcd574f2d4f51de6b71804fd +Author: Ruben Vermeersch +Date: Mon Nov 2 17:02:43 2009 + + Fix a crash at XMP parsing due to nonstandard placement of xmlns attributes. + +commit 749c14e82cb7f72e6ffef81f98fb0ebeef96c508 +Author: Ruben Vermeersch +Date: Sun Nov 1 13:37:45 2009 + + Kill two warnings. + +commit afa443e0136c3babf51c864b9d88ad8cd2d59dc0 +Author: Ruben Vermeersch +Date: Sun Nov 1 03:52:29 2009 + + Kill more warnings. + +commit 82cc9ac2d66f77900ada7ede075d6a68993e1d92 +Author: Mike Gemünde +Date: Sun Nov 1 07:35:48 2009 + + add support to read and write GPS inforamtion in exif. + +commit 521d45753525830ca9656a345cef7139453210a9 +Author: Mike Gemünde +Date: Sun Nov 1 04:53:47 2009 + + use the values directly for an IFD array entry instead + +commit 920585b928b058332cf59b411aefa63ffafcd114 +Author: Mike Gemünde +Date: Sun Nov 1 04:44:06 2009 + + add support to write makernotes of Canon and Panasonic back to file + +commit 799b2aa1daa55bc8c8f3a65777bdb40df09966ad +Author: Mike Gemünde +Date: Sun Nov 1 03:02:57 2009 + + move image tests in own namespace + + The image tests are now contained in an own namespace. This is to not + flood the existing one with a bunch of image tests comming in the future. + +commit 875779f9e5d34e19478d739a454699a62bab8947 +Author: Ruben Vermeersch +Date: Sun Nov 1 02:57:38 2009 + + Cut down on the number of warnings. + +commit 2e5e7800de5726cc7695737271b2c3f80d723e76 +Author: Mike Gemünde +Date: Wed Oct 28 15:43:18 2009 + + fix warnings on use of obsolete methods in Bytevector + +commit cbc20f221e139c5cbd0b755bde2bb7a5ea93e887 +Author: Mike Gemünde +Date: Wed Oct 28 14:07:14 2009 + + add ThumbnailIFDEntry to handle thumbnail data correctly + +commit 3a19b17396873cc253a25fe46b23358b68222135 +Author: Mike Gemünde +Date: Wed Oct 28 13:10:49 2009 + + the id of on IFD entry type is also an unsigned short + +commit a6f8d00aec73cb73d024c7871d4d4d5445d84838 +Author: Mike Gemünde +Date: Wed Oct 28 13:07:15 2009 + + a tag of an IFD Entry is an unsigned short, so take an usnigned short for representation, too + +commit 3cb1a37881778072cc74835cdfa8cf1017d0dc7e +Author: Mike Gemünde +Date: Wed Oct 28 12:59:47 2009 + + move some of the renderer code to the IFD Entries itself + +commit c32734b0f03dcb8f541014df98ab9888ada5646f +Author: Mike Gemünde +Date: Wed Oct 28 12:26:38 2009 + + add Rational and SRational struct for IFD Entries + +commit ad18345b7f417e4b59a16582c3246b60bb342cea +Author: Mike Gemünde +Date: Tue Oct 27 17:53:47 2009 + + add unit test for Panasonic file (Exif, Makernote) + +commit bce29cacf6603d39f7847dda4695633dd9130e51 +Author: Mike Gemünde +Date: Tue Oct 27 17:51:35 2009 + + add support for some other Makernotes (Panasonic, Pentax) + +commit 2724f556a6d8a73249d384cfac65889b27b55325 +Author: Mike Gemünde +Date: Tue Oct 27 17:47:56 2009 + + add support for more entry types + +commit 557f95441d25bcaee3f14411d28790380422135a +Author: Mike Gemünde +Date: Tue Oct 27 16:42:18 2009 + + take care of restart marker in data segment of jpeg + + The markers 0xFFD0 ... 0xFFD7 are used as restart marker within the data segment. + So we must keep searching for the end of data instead of returning the marker. + +commit 9f17499d32f2dbdc02f5e2f2d35cd5bed4b0d3e8 +Author: Mike Gemünde +Date: Mon Oct 26 17:02:44 2009 + + add support for reading XMP keywords + +commit 41c56e19c0eac6b396193ef1370b7be842e2d961 +Author: Mike Gemünde +Date: Mon Oct 26 15:13:05 2009 + + adding GPS support in ImageTag + +commit 655de1f5442721a192a87fd42da21608880248bd +Author: Ruben Vermeersch +Date: Sun Oct 25 09:58:24 2009 + + Add an example (and test) app for photos. + +commit fbbff6a6716ffe37a9b04629cbb1da48f3346fbf +Author: Ruben Vermeersch +Date: Sun Oct 25 09:05:42 2009 + + Cut back on the number of warnings. + +commit 6cf5ab452f9fbc42f734f0e8ec7d76b18789c50f +Author: Mike Gemünde +Date: Tue Oct 20 16:31:17 2009 + + Extend UserComment handling for undefined data + + We can now handle undefined entries in the UserComment field. Since the program + CanonZoomBrowser decides to not fill the 8 byte correctly for an undefined entry, + we have to be more liberal for parsing it. + +commit ece09bcf9cb44b7ef47574d0e105c4695b33e003 +Author: Mike Gemünde +Date: Tue Oct 20 16:29:02 2009 + + Extend Reading of ASCII text fields + + Keep Adobe practice for reading ASCII field and only read it to the first '\0'. + Since more than one value can be stored and some programs fills the fields with + '\0's, this seems to be a reasonable choice to keep trouble away. + +commit 95520e015a2d2659eae04af7e21b1c51bfa47b97 +Author: Mike Gemünde +Date: Tue Oct 20 14:23:33 2009 + + Change also Model to IFD0 instead of ExifIfd + +commit 6e47449ef9fae5b06a9b4f8c9e74a77b95663d48 +Author: Mike Gemünde +Date: Tue Oct 20 14:11:03 2009 + + ImageDescription is part of IFD0 and not the ExifIFD + +commit 7e84a12193e17714aa9ea64b910719c46ce7b76a +Author: Mike Gemünde +Date: Tue Oct 20 13:47:28 2009 + + complete IFD entry tag ids + + The tag ids are fetched from http://www.awaresystems.be/imaging/tiff/tifftags.html. + Since the GPS IFD and the Interoperability IFD uses the same tag-id (1), we take + this change to split the ids into different enums, according to the IFDs or subIFDs + they occur. + +commit 8662c7a95c1c6fe551912493e1fd974974ecb682 +Author: Ruben Vermeersch +Date: Sun Oct 18 10:58:51 2009 + + Restructure IFD. Able to represent everything now. + +commit a43b49180ff0803cfc4cae5e6e26235d5d00b3b6 +Author: Ruben Vermeersch +Date: Sun Oct 18 08:20:42 2009 + + Prevent writing empty sub-IFDs. + +commit 403c87c10f6ff215eeb78d088ea4be4b0437b210 +Author: Ruben Vermeersch +Date: Sun Oct 18 07:16:39 2009 + + Add bits of the convenience API. + + Imposes ordering: Xmp before Exif before all the rest. + +commit 8dc9997baefbb92f7ddf68e3d339a053a0e74e79 +Author: Ruben Vermeersch +Date: Sun Oct 18 05:50:30 2009 + + Split IFD reading and rendering code into Readers and Renderers. + +commit eff47010115a487deaabc6217a38ae963c269764 +Author: Ruben Vermeersch +Date: Sat Oct 17 10:57:04 2009 + + Fix a couple of warnings. + +commit 21dc3e088e5fb8c0d6de86888aa65389fdc86830 +Author: Ruben Vermeersch +Date: Sat Oct 17 10:18:26 2009 + + Only expose tag types that make sense, move stuff around. + +commit c387fdb40d86c4de06b47646ef4e31b6f51136c8 +Author: Ruben Vermeersch +Date: Sat Oct 17 04:45:11 2009 + + Add common Image.File base class for image types. + + And some cleanups. + +commit db77414ae3974a58cc73e564139382a54bce8674 +Author: Mike Gemünde +Date: Wed Oct 14 17:28:31 2009 + + add support to read write some image properties by the ExifTag class + +commit 838f7d1d596add212957aa5fb9ff9b06a2156b88 +Author: Mike Gemünde +Date: Wed Oct 14 17:27:41 2009 + + add support to merge image properties in CombinedImageTag + +commit 4fbf51e36caa72285462f54912b172fe23b81c1d +Author: Mike Gemünde +Date: Wed Oct 14 12:41:31 2009 + + possibility to add new tags (Exif, GPS, IFD) to Jpegs + +commit a3ff09e1447c05ef8651af6195953b66beeb60e9 +Author: Mike Gemünde +Date: Wed Oct 14 08:36:29 2009 + + introducing Image.ImageTag and Image.CombinedImageTag + + The both classes are used to provide a unified access to + all types of image metadata. + +commit 5c1c307318c23f0f582204bd9424b542924d7567 +Author: Mike Gemünde +Date: Tue Oct 13 18:23:31 2009 + + support to add JpegComment to Jpeg File + +commit 4827d042e87d0b7c25c89adc66adaa5105edb633 +Author: Mike Gemünde +Date: Tue Oct 13 16:42:06 2009 + + Add support for reading and writing the GPS Directory + +commit c995075b4191fe47929e96cdd0f77d64d1ecd3cc +Author: Mike Gemünde +Date: Tue Oct 13 16:38:18 2009 + + remove unused private methods from Tiff.File + +commit dc6f6196a3304e12f67874f8bdbd5f772eb9b39c +Author: Mike Gemünde +Date: Tue Oct 13 15:57:54 2009 + + fix comment + +commit a87f24e12453a3bab1e6acf49d6fc5d71cb80ca0 +Author: Ruben Vermeersch +Date: Sun Oct 11 06:09:24 2009 + + 2009-10-11 Ruben Vermeersch + + * src/TagLib/TagLib.sources: + * src/TagLib/FileTypes.cs: + * src/TagLib/Jpeg/Codec.cs: + * src/TagLib/Jpeg/File.cs: + * src/TagLib/Jpeg/JpegCommentTag.cs: + * src/TagLib/Jpeg/JpegTag.cs: + * src/TagLib/Jpeg/Marker.cs: + Jpeg support, extracts XMP and exif, initial write support. + + * tests/Makefile.am: + * tests/fixtures/TagLib.Tests.FileFormats/JpegFormatTest.cs: + * tests/samples/sample.jpg: + Jpeg parsing test cases. + + Patch written by: + Ruben Vermeersch (Initial work) + Mike Gemünde (Significant improvements) + +commit b6bd1379eca52d504bf3e1f67533c5469c4ceedd +Author: Ruben Vermeersch +Date: Sun Oct 11 06:04:13 2009 + + 2009-10-11 Mike Gemuende + + This commit adds EXIF parsing support, by reusing most of IFD. + + * src/TagLib/Exif/CanonMakerNoteTag.cs: + * src/TagLib/Exif/ExifTag.cs: + * src/TagLib/Exif/GPSTag.cs: + * src/TagLib/Exif/IOPTag.cs: + * src/TagLib/Exif/ThumbnailTag.cs: + Exif data tags. + + * src/TagLib/Tag.cs: + * src/TagLib/TagLib.sources: + * src/TagLib/IFD/IFDTag.cs: + Recognize most important special case tags. + + * tests/Makefile.am: + * tests/fixtures/TagLib.Tests.FileFormats/StandardExifTests.cs: + * tests/fixtures/TagLib.Tests.FileFormats/TiffFormatTest.cs: + Adapt test cases to handle the newly recognized Exif SubIFDEntry. + +commit 339bae5d5465d2dec2f2832e31352ed11f88e679 +Author: Ruben Vermeersch +Date: Sun Oct 11 05:59:06 2009 + + 2009-10-11 Ruben Vermeersch + + * src/TagLib/TagLib.sources: + * src/TagLib/Xmp/XmlNodeExtensions.cs: + * src/TagLib/Xmp/XmpNode.cs: + * src/TagLib/Xmp/XmpNodeVisitor.cs: + * src/TagLib/Xmp/XmpTag.cs: + XMP parser, according to the implementation notes in the XMP specification. + Uses a NameTable to speed up string comparison. Not fully finished yet, but + handles most common XMP formats. + + * src/TagLib/Tiff/TiffTag.cs: + Extract XMP blocks from the relevant IFD entry for TIFF files. + + * tests/fixtures/TagLib.Tests.FileFormats/TiffFormatTest.cs: + Test case for XMP extraction. + +commit c5b357416f1ad71befabad8272975f0abb6f3b5d +Author: Ruben Vermeersch +Date: Sun Oct 11 05:43:08 2009 + + 2009-10-11 Ruben Vermeersch + + * src/TagLib/FileTypes.cs: + * src/TagLib/TagLib.sources: + * src/TagLib/Tiff/Codec.cs: + * src/TagLib/Tiff/File.cs: + * src/TagLib/Tiff/TiffTag.cs: + Support for TIFF decoding. + + * src/TagLib/IFD/Entries/ByteVectorIFDEntry.cs: + * src/TagLib/IFD/Entries/LongArrayIFDEntry.cs: + * src/TagLib/IFD/Entries/LongIFDEntry.cs: + * src/TagLib/IFD/Entries/RationalIFDEntry.cs: + * src/TagLib/IFD/Entries/SRationalIFDEntry.cs: + * src/TagLib/IFD/Entries/ShortArrayIFDEntry.cs: + * src/TagLib/IFD/Entries/ShortIFDEntry.cs: + * src/TagLib/IFD/Entries/StringIFDEntry.cs: + * src/TagLib/IFD/Entries/SubIFDEntry.cs: + * src/TagLib/IFD/Entries/UndefinedIFDEntry.cs: + * src/TagLib/IFD/IFDEntry.cs: + * src/TagLib/IFD/IFDEntryTag.cs: + * src/TagLib/IFD/IFDTag.cs: + TIFF IFD support. This is the metadata encoding structure in TIFF, which is + also used in other formats such as EXIF and multiple RAW formats. Hence the + separate namespace. + + * tests/Makefile.am: + * tests/fixtures/TagLib.Tests.FileFormats/TiffFormatTest.cs: + * tests/samples/sample.tiff: + Add tests for TIFF reading. + + Patch written by: + Ruben Vermeersch + Mike Gemünde + +commit e2b13c97822f6f63b0aa7d26394b5acf1d7a15ec +Author: Ruben Vermeersch +Date: Sun Oct 11 04:03:58 2009 + + 2009-10-11 Ruben Vermeersch + + * src/TagLib/ByteVector.cs: + * tests/fixtures/TagLib.Tests.Collections/ByteVectorTest.cs: + Add new FromInt and ToInt methods to ByteVector, which will be used in + image metadata processing. Update unit tests with test cases. + + * src/TagLib/ICodec.cs: + Introduce a new Photo content type and IPhotoCodec, which encapsulates + photo properties such as it's width and height. + + * src/TagLib/Image/Codec.cs: + Abstract base type for image codecs, as most fields are common for all + image types. + + * src/TagLib/Properties.cs: + Extended with support for IPhotoCodec. + + * src/TagLib/Tag.cs: + Add a number of tag types related to image metadata. + + Patch written by: + Ruben Vermeersch + Mike Gemünde + +commit 680892aa0534508d687b2436576f7dbea4f996d5 +Author: Gabriel Burt +Date: Sat Mar 20 12:06:37 2010 + + 2010-03-20 Gabriel Burt + + * README: Add svn info + + svn path=/trunk/taglib-sharp/; revision=153940 + +commit 9c0969f779c01dc7c3bc4ec97890898d2f4cc5e8 +Author: Gabriel Burt +Date: Sat Mar 20 12:02:38 2010 + + 2010-03-20 Gabriel Burt + + * README: add some real, useful info + + svn path=/trunk/taglib-sharp/; revision=153939 + +commit 160841bfafef60da2d0be6830ea03a5483bebafd +Author: Gabriel Burt +Date: Sat Mar 20 11:54:05 2010 + + 2010-03-20 Gabriel Burt + + * configure.ac: + * NEWS: Update for 2.0.3.7 release + + svn path=/trunk/taglib-sharp/; revision=153938 + +commit 857c9a84b60c232e334bdd118dbd237c69f2419b +Author: Alexander Kojevnikov +Date: Sat Mar 20 02:49:42 2010 + + 2010-03-20 Alexander Kojevnikov + + * configure.ac: + * src/Makefile.am: Patch from Bertrand Lorentz adding a check + for the `al` tool (bgo#575303) + + svn path=/trunk/taglib-sharp/; revision=153935 + +commit f657f9ff312b28f52f7be93dfff4df67ee84aa7a +Author: Alexander Kojevnikov +Date: Sat Mar 20 02:34:13 2010 + + 2010-03-20 Alexander Kojevnikov + + * configure.ac: Patch from Ruben Vermeersch adding a fall back + to nunit-console if nunit-console2 is not found (bgo#593673) + + svn path=/trunk/taglib-sharp/; revision=153934 + +commit c815c88583f625ca3ab1e247a696c0a2ac87cb36 +Author: Alexander Kojevnikov +Date: Sat Mar 20 02:06:30 2010 + + 2010-03-20 Alexander Kojevnikov + + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V2Test.cs: + Don't throw an exception if RVA2 data is partially incorrect + + svn path=/trunk/taglib-sharp/; revision=153933 + +commit 01cb5415eaa5017a0b24b96fc0cf24f76fe33608 +Author: Alexander Kojevnikov +Date: Fri Mar 19 23:51:38 2010 + + 2010-03-20 Alexander Kojevnikov + + * Makefile.am: + * src/Makefile.am: Fix `make distcheck` + + svn path=/trunk/taglib-sharp/; revision=153931 + +commit 27db4ba286399349af7596f18217adc3828a315e +Author: Alexander Kojevnikov +Date: Fri Mar 19 22:10:52 2010 + + 2010-03-20 Alexander Kojevnikov + + * src/TagLib/File.cs: Make TagLib.File IDisposable + + svn path=/trunk/taglib-sharp/; revision=153929 + +commit 356094ea343dbb85de183c875672b979bd175a9d +Author: Alexander Kojevnikov +Date: Fri Mar 19 22:04:28 2010 + + 2010-03-20 Alexander Kojevnikov + + * src/TagLib/Id3v2/ExtendedHeader.cs: + * tests/fixtures/TagLib.Tests.FileFormats/Id3V2FormatTest.cs: + * tests/samples/sample_v2_3_ext_header.mp3: Fix ID3v2.3 extended + header size calculation (bgo#604488) + + svn path=/trunk/taglib-sharp/; revision=153928 + +commit b2fb500435776fe685b3dd7f894232e03403a70c +Author: Alexander Kojevnikov +Date: Fri Mar 19 21:53:58 2010 + + 2010-03-20 Alexander Kojevnikov + + * src: + * docs: + * tests: + * tests/samples: + * .gitignore: + * examples: Add svn:ignore and .gitignore + + + svn path=/trunk/taglib-sharp/; revision=153927 + +commit a589453d5e842e7e161d5cbca9721e4e9c3924fe +Author: Alexander Kojevnikov +Date: Fri Mar 19 21:31:42 2010 + + 2010-03-20 Alexander Kojevnikov + + * src/TagLib/Id3v2/Tag.cs: + * tests/Makefile.am: + * tests/fixtures/TagLib.Tests.FileFormats/Id3V24FormatTest.cs: + * tests/samples/sample_v2_4_unsynch.mp3: + * tests/tests.csproj: Patch and unit tests from Eamon Nerbonne + fixing ID3v2 unsyncing (bgo#593138) + + svn path=/trunk/taglib-sharp/; revision=153926 + +commit 9beda4fbb27e255d8eafc496a81fb49dd13fe16f +Author: Andrés G. Aragoneses +Date: Wed Mar 3 17:59:47 2010 + + 2010-03-02 Andrés G. Aragoneses + + * src/TagLib/Aac/AudioHeader.cs: Fix all warnings not related + to XML documentation. + + + svn path=/trunk/taglib-sharp/; revision=152975 + +commit df439f8529b7194b5424358fca9490e791e7a073 +Author: Andrés G. Aragoneses +Date: Tue Mar 2 05:01:39 2010 + + forgot changelog + + svn path=/trunk/taglib-sharp/; revision=152820 + +commit f175da0d302b18f2d3296da64e8f7f5ad30ccb1b +Author: Andrés G. Aragoneses +Date: Tue Mar 2 04:58:48 2010 + + * tests/tests.mdp: + * taglib-sharp.mds: + * taglib-sharp.sln: + * tests/tests.csproj: + * src/taglib-sharp.mdp: + * src/taglib-sharp.csproj: + * examples/ReadFromUri.mdp: + * examples/SetPictures.mdp: + * examples/ReadFromUri.csproj: + * examples/SetPictures.csproj: Projects/solution format migration, + deleting deprecated MD1.0 format. + + svn path=/trunk/taglib-sharp/; revision=152819 + +commit 63ff2db7fc275c88d018cc2cb751053986e7ff96 +Author: Gabriel Burt +Date: Wed Feb 24 12:57:13 2010 + + 2010-02-24 Gabriel Burt + + * configure.ac: + * NEWS: Update for 2.0.3.6 release + + svn path=/trunk/taglib-sharp/; revision=152385 + +commit 9f8664ec69ee36046be5e8070a0463e3fea403d7 +Author: Gabriel Burt +Date: Wed Feb 24 12:51:42 2010 + + 2010-02-24 Gabriel Burt + + * src/TagLib/Riff/WaveFormatEx.cs: Fix API break in 2.0.3.5. + + svn path=/trunk/taglib-sharp/; revision=152384 + +commit 6902a83d09086ac84884ff72dd99f1af9e771bdc +Author: Gabriel Burt +Date: Tue Feb 23 16:57:51 2010 + + 2010-02-23 Gabriel Burt + + * NEWS: Update for 2.0.3.5 release + + svn path=/trunk/taglib-sharp/; revision=152310 + +commit aeb2315f921fb7c854966b2f206ff67793ca7bcd +Author: Gabriel Burt +Date: Sun Feb 21 16:31:23 2010 + + 2010-02-21 Gabriel Burt + + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/ICodec.cs: + * src/TagLib/Properties.cs: + * src/TagLib/Flac/StreamHeader.cs: + * src/TagLib/Ape/StreamHeader.cs: + * src/TagLib/Aiff/StreamHeader.cs: + * src/TagLib/WavPack/StreamHeader.cs: Patch from Alexander Kojevnikov + adding BitsPerSample property to TagLib.Properties (BGO #610585) + + svn path=/trunk/taglib-sharp/; revision=152153 + +commit 0cf7cde9011e9f2d5a548f4b88198a9e8ff18c67 +Author: Gabriel Burt +Date: Wed Feb 3 19:40:03 2010 + + 2010-02-03 Gabriel Burt + + * src/TagLib/Ogg/XiphComment.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs: Patch and unit + tests from Alexander Kojevnikov adding support for COMPILATION to + Vorbis/XiphComments (eg for ogg and flac files) (BGO #586336) + + svn path=/trunk/taglib-sharp/; revision=150805 + +commit 939ae5abdb8757f438a72050bbac262a56b5f964 +Author: Gabriel Burt +Date: Mon Feb 1 18:28:56 2010 + + 2010-02-01 Gabriel Burt + + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: + * tests/fixtures/TagLib.Tests.FileFormats/Id3BothFormatTest.cs: Patch and + unit tests from Helmut Wahrmann (with assistance from Alexander + Kojevnikov) fixing bug with removing some/all tag-types from a file (BGO + #574653) + + svn path=/trunk/taglib-sharp/; revision=150687 + +commit 21458f4451b57d10e373817cbee58101f9501579 +Author: Gabriel Burt +Date: Tue Jan 26 19:07:50 2010 + + 2010-01-26 Gabriel Burt + + * configure.ac: + * NEWS: Bump to 2.0.3.5 in prep for next release + + svn path=/trunk/taglib-sharp/; revision=150265 + +commit a2a8010c2830c163af693231d7d6893c8ede4409 +Author: Gabriel Burt +Date: Wed Jan 20 18:30:16 2010 + + 2010-01-20 Gabriel Burt + + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V2Test.cs: Patch from + Alexander Kojevnikov fixing IndexOutOfRangeException (BGO #607376) + + svn path=/trunk/taglib-sharp/; revision=149945 + +commit 466e24d5340be9653e538168526557f49b0fbd96 +Author: Gabriel Burt +Date: Thu Jan 7 16:56:22 2010 + + 2010-01-07 Gabriel Burt + + * NEWS: + * configure.ac: Bump to 2.0.3.4 for upcoming release. + + svn path=/trunk/taglib-sharp/; revision=149201 + +commit df89366fb2a7365bf11767e2bf746c5c34e0c1fd +Author: Gabriel Burt +Date: Thu Jan 7 14:31:48 2010 + + 2010-01-07 Gabriel Burt + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameHeader.cs: Fix multiple issues with converting + release data metadata. Was converting (renaming) TDAT to TDRC, but + that's mapping MMDD onto YYYY which doesn't make sense. Now it will + map only TYER to TDRC, and then append the TDAT and TIME info to the TDRC + if they exist. Fixes BGO #606283 + + * tests/fixtures/TagLib.Tests.FileFormats/AiffFormatTest.cs: Fix test that + depended on the incorrect behavior above. + + svn path=/trunk/taglib-sharp/; revision=149189 + +commit 5e0e952df97bc485f5fcf4411b785c6251ae24cc +Author: Gabriel Burt +Date: Sun Dec 13 16:00:43 2009 + + 2009-12-13 Gabriel Burt + + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: Support the 'alis' handler code/track + type, found in the wild in an iTunes-ripped .m4a file (BGO #584193) + + svn path=/trunk/taglib-sharp/; revision=148357 + +commit 6f160becd6baf821b65f5f6ba6ac71d29b909f83 +Author: Aaron Bockover +Date: Wed Sep 30 18:53:22 2009 + + Fix NEWS uploading + + svn path=/trunk/taglib-sharp/; revision=143089 + +commit 28a2feb8ffdd78e687d2200c678b88a3234b9168 +Author: Aaron Bockover +Date: Wed Sep 30 18:48:14 2009 + + 2009-09-30 Aaron Bockover + + * NEWS: Update for 2.0.3.3 release + * configure.ac: Bump to 2.0.3.3 + + + svn path=/trunk/taglib-sharp/; revision=143088 + +commit 713ed6438ba96810cdcdef29d90b1b5e5f6efb95 +Author: Gabriel Burt +Date: Mon May 18 14:23:36 2009 + + 2009-05-18 Gabriel Burt + + * src/TagLib/ByteVector.cs: + * tests/fixtures/TagLib.Tests.Collections/ByteVectorTest.cs: Patch from + Alexander Kojevnikov fixing ArgumentOutOfRangeException when parsing some + comment frames (BGO #582735) + + svn path=/trunk/taglib-sharp/; revision=134348 + +commit bf2aaa4c8f68da49fe24088f4b56e9b8be58b987 +Author: Gabriel Burt +Date: Fri May 15 10:48:50 2009 + + 2009-05-15 Gabriel Burt + + * src/TagLib/Riff/File.cs: + * src/TagLib/FileTypes.cs: + * src/TagLib/Aac/File.cs: + * src/TagLib/Aac/AudioHeader.cs: + * src/TagLib/Aac/BitStream.cs: + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: + * docs/Package.en.xml.in: + * tests/tests.mdp: + * tests/fixtures/TagLib.Tests.FileFormats/AacFormatTest.cs: + * tests/Makefile.am: + * taglib-sharp.csproj: Patch from Patrick Dehne adding support for ADTS AAC + files (BGO #580553) + + svn path=/trunk/taglib-sharp/; revision=134211 + +commit 13b29dabc38a4258fbb66ca24b0ce20ed71582b3 +Author: Gabriel Burt +Date: Thu May 14 15:23:56 2009 + + 2009-05-14 Gabriel Burt + + * src/TagLib/Aiff/File.cs: + * src/TagLib/Aiff/StreamHeader.cs: + * src/TagLib/FileTypes.cs: + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: + * docs/Package.en.xml.in: + * tests/tests.mdp: + * tests/fixtures/TagLib.Tests.FileFormats/AiffFormatTest.cs: + * tests/Makefile.am: + * taglib-sharp.csproj: Patch from Helmut Wahrmann adding support for the + AIFF file format (BGO #579261) + + svn path=/trunk/taglib-sharp/; revision=134161 + +commit 2207974d1385133c910e2d352bcbd9f858ebbdf4 +Author: Gabriel Burt +Date: Mon Apr 20 14:10:43 2009 + + Correct a couple 2008s that should be 2009 + + svn path=/trunk/taglib-sharp/; revision=132204 + +commit b5d885b5ef0458fd0d2ea707ec3bbd38a60a4829 +Author: Gabriel Burt +Date: Wed Mar 25 18:15:23 2009 + + 2009-03-25 Gabriel Burt + + * src/TagLib/Ogg/XiphComment.cs: Patch from Helmut Wahrmann adding two + fallback options for the album artist getter (BGO #574652) + + + svn path=/trunk/taglib-sharp/; revision=130253 + +commit 6f22bf46936fa62d8dc4f9ea01fff8de5921e486 +Author: Gabriel Burt +Date: Thu Mar 19 23:54:24 2009 + + 2009-03-19 Gabriel Burt + + * src/TagLib/Ape/Tag.cs: Patch from Gregory S. Chudov fixing bug with + Ape.Tag's Pictures setter (BGO #575943) + + + svn path=/trunk/taglib-sharp/; revision=129858 + +commit f70f7b27b2e9bf923a8f907aa1dec61599121168 +Author: Gabriel Burt +Date: Wed Mar 18 22:21:23 2009 + + 2009-03-18 Gabriel Burt + + * tests/Makefile.am: + * examples/Makefile.am: Patch from Bertrand Lorentz fixing issue with + random files slipping into the tarball/dist (BGO #575302). make distcheck + and running ./configure && make && make test work on the tarball + + + svn path=/trunk/taglib-sharp/; revision=129762 + +commit 446b14bd5997c51d0a6edd31988058837a1fc283 +Author: Gabriel Burt +Date: Tue Mar 10 14:41:12 2009 + + 2009-03-10 Gabriel Burt + + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/AudioFile.cs: + Patch from Andy Beal adding support for m2v and m2v files (BGO #574411) + + + svn path=/trunk/taglib-sharp/; revision=129008 + +commit f9ccf65c85d4dc1f1b1924a52e8b59cb902480e7 +Author: Gabriel Burt +Date: Tue Mar 10 00:01:00 2009 + + 2009-03-09 Gabriel Burt + + * src/TagLib/Ape/Tag.cs: Patch from Bernd Niedergesaess adding support for + Sort* values in Ape tags (BGO #571421) + + + svn path=/trunk/taglib-sharp/; revision=128940 + +commit 877b873e2aa8e999a1ffd451f55c78b677c3b5ed +Author: Gabriel Burt +Date: Mon Mar 9 23:53:30 2009 + + 2009-03-09 Gabriel Burt + + * src/TagLib/Ogg/GroupedComment.cs: Patch from Bernd Niedergesaess and + Andy Beal improving code consistency (BGO #571443) + + + svn path=/trunk/taglib-sharp/; revision=128939 + +commit 96e698124f34e42b85d1c0618af1900ad156843e +Author: Gabriel Burt +Date: Mon Mar 9 23:47:07 2009 + + 2009-03-09 Gabriel Burt + + * src/TagLib/Riff/AviHeaderList.cs: Patch from Bernd Niedergesaess to not + use obsolete ctor (BGO #571452) + + + svn path=/trunk/taglib-sharp/; revision=128938 + +commit 74e848482a4adb6ea951d3ca60429295ddf33c4a +Author: Gabriel Burt +Date: Mon Mar 9 23:37:09 2009 + + 2009-03-09 Gabriel Burt + + * docs/Makefile.am: Reduce the verbosity of docs build output. + + + svn path=/trunk/taglib-sharp/; revision=128937 + +commit a5c66dedc41e14ea667da68804391f574cbb2a5a +Author: Gabriel Burt +Date: Mon Mar 9 23:25:40 2009 + + 2009-03-09 Gabriel Burt + + Patch from Andy Beal adding new properties: MusicBrainz -ArtistId, + -ReleaseId, -ReleaseArtistId, -TrackId, -DiscId, -ReleaseStatus, -ReleaseType, + -ReleaseCountry, MusicIpId, and AmazonId (BGO #563170) + + * src/TagLib/CombinedTag.cs: + * src/TagLib/Tag.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/GroupedComment.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Mpeg4Test.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/ApeTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V2Test.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/AsfTest.cs: Add and test the + new properties. + + svn path=/trunk/taglib-sharp/; revision=128936 + +commit 2822fea172a0ce858bfb96bbb4a1520f7e6c399a +Author: Gabriel Burt +Date: Wed Mar 4 10:25:48 2009 + + 2009-03-04 Gabriel Burt + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Patch from John + Millikin to be more robust in the face of tags with NULL bytes in the + middle of them by truncating the value before the first one (BGO #558123) + + * tests/samples/corrupt/null_title_v2.mp3: + * tests/fixtures/TagLib.Tests.FileFormats/Id3V2FormatTest.cs: New corrupt + file with NULL bytes in the title field, and a test that we handle it ok. + + + svn path=/trunk/taglib-sharp/; revision=128567 + +commit adfc5f7ee25c53f6a95d0849441957cb1f0a55f0 +Author: Gabriel Burt +Date: Thu Feb 19 20:37:59 2009 + + 2009-02-19 Gabriel Burt + + * src/TagLib/Flac/File.cs: Patch from Gregory S. Chudov fixing NRE thrown + when calling GetTag on a flac File (BGO #572380) + + * tests/fixtures/TagLib.Tests.FileFormats/FlacFormatTest.cs: Add a unit + test written by me that fails without Gregory's patch, passes with it. + + + svn path=/trunk/taglib-sharp/; revision=127496 + +commit 447239a8964b6637cf570635fff2071098f20430 +Author: Gabriel Burt +Date: Thu Feb 19 20:29:07 2009 + + 2009-02-19 Gabriel Burt + + * src/TagLib/Ogg/XiphComment.cs: Patch from Gregory S. Chudov fixing typo + in the Ogg DiscNumber setter that wrote the TrackCount to the DISCTOTAL + field (BGO #572381) + + + svn path=/trunk/taglib-sharp/; revision=127492 + +commit 179f20ff6731f59250b71bc95c4c58fe52fb1818 +Author: Gabriel Burt +Date: Thu Feb 19 20:25:49 2009 + + 2009-02-19 Gabriel Burt + + * src/TagLib/Tag.cs: Patch from Gregory S. Chudov fixing bug in the CopyTo + method that copied the Copyright into the Conductor tag (BGO #572382) + + + svn path=/trunk/taglib-sharp/; revision=127491 + +commit d7431fc9c8b22cac2f65317c7df44329ab5a912f +Author: Gabriel Burt +Date: Thu Feb 19 20:21:55 2009 + + 2009-02-19 Gabriel Burt + + * src/TagLib/File.cs: Patch from Félix Velasco fixing a bug in our XML + documentation (BGO #572253) + + + svn path=/trunk/taglib-sharp/; revision=127490 + +commit 9c76cd75a24589edcf63249d65b5b670412c3182 +Author: Gabriel Burt +Date: Thu Feb 19 20:18:11 2009 + + 2009-02-19 Gabriel Burt + + * configure.ac: Patch from Bertrand Lorentz using $(prefix)/lib in + GACUTIL_FLAGS instead of $(libdir) (BGO #572259) + + + svn path=/trunk/taglib-sharp/; revision=127489 + +commit 1dacd700bfe4aef4f7acbc440b59099579bac308 +Author: Gabriel Burt +Date: Thu Feb 19 13:00:12 2009 + + 2009-02-19 Gabriel Burt + + * docs/Makefile.am: Patch from Bertrand Lorentz fixing hardcoded mcs + reference (BGO #572450) + + + svn path=/trunk/taglib-sharp/; revision=127441 + +commit a17a7339518964ff719d38eb59a98b2f9c941b93 +Author: Gabriel Burt +Date: Mon Feb 16 17:07:25 2009 + + 2009-02-16 Gabriel Burt + + * NEWS: Update for 2.0.3.2 release + + + svn path=/trunk/taglib-sharp/; revision=127078 + +commit bfc0685985ad6ea2c6c84d7d83181a68cee206ed +Author: Gabriel Burt +Date: Mon Feb 16 16:39:12 2009 + + Forgot to credit Bernd in last commit + + svn path=/trunk/taglib-sharp/; revision=127077 + +commit c680ca61d0fb2056885d3c9fd3896fd8a968d119 +Author: Gabriel Burt +Date: Mon Feb 16 15:48:27 2009 + + 2009-02-16 Gabriel Burt + + * src/TagLib/Ape/Tag.cs: Patch from Andy Beal fixing our APE tag writing + from writing out all uppercase tags to writing the recommended tag casing. + But we support reading in any casing. Also, use BPM instead of TEMPO, and + use Album Artist instead of AlbumArtist, but read/write the latter for + compabibility (BGO #571563) + + + svn path=/trunk/taglib-sharp/; revision=127070 + +commit 96664cc7e3eea268fb6ec5e9ca50842323a672c4 +Author: Gabriel Burt +Date: Mon Feb 16 15:24:58 2009 + + 2009-02-16 Gabriel Burt + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Ape/Tag.cs: + * docs/Package.en.xml.in: + * docs/Makefile.am: Patch from Bertrand Lorentz fixing build issue + with docs (BGO #571368) + + + svn path=/trunk/taglib-sharp/; revision=127066 + +commit 29a97a8d909075306da240d9c96b8420afbe0ce6 +Author: Gabriel Burt +Date: Thu Feb 12 13:01:51 2009 + + 2009-02-12 Gabriel Burt + + * src/TagLib/Mpeg/AudioFile.cs: Patch from Bernd Niedergesaess with style + help from Andy Beal, adding mp1/mp2 extensions/mimetypes (BGO #571466) + + + svn path=/trunk/taglib-sharp/; revision=126743 + +commit 17b4c1e010f3c02b140d7c95dfbf0e7fb3166df1 +Author: Gabriel Burt +Date: Thu Feb 12 12:46:03 2009 + + 2009-02-12 Gabriel Burt + + * src/TagLib/Mpeg4/AppleTag.cs: Patch from Bernd Niedergesaess fixing + mpeg4 writing of BPM to file (BGO #571411) + + + svn path=/trunk/taglib-sharp/; revision=126741 + +commit 12b894385f4194df2f865c20d2b4483ddcaac698 +Author: Gabriel Burt +Date: Wed Feb 11 18:54:19 2009 + + 2009-02-11 Gabriel Burt + + Patches from Bertrand Lorentz. + + * tests/Makefile.am: fixes the typo that caused the test source files not + to be included in the tarball (BGO #569299) + + * configure.ac: remove the call to AC_CANONICAL_SYSTEM (BGO #571361) + + + svn path=/trunk/taglib-sharp/; revision=126670 + +commit fc1d68289f28ca1a02f884922eaa714c6e9f9bd2 +Author: Gabriel Burt +Date: Tue Feb 10 21:53:05 2009 + + 2009-02-10 Gabriel Burt + + * src/TagLib/Mpeg/File.cs: Patch from Andy Beal fixing issue where offset + was not being advanced when trying to read a GOP video packet inside a + video sequence (BGO #568964) + + + svn path=/trunk/taglib-sharp/; revision=126547 + +commit 2af0d2725ea1d5269b46810e2d2d712944fcf8e9 +Author: Gabriel Burt +Date: Tue Feb 10 20:54:37 2009 + + 2009-02-10 Gabriel Burt + + * configure.ac: Bump in prep for the next release. + + * examples/ReadFromUri.cs: Refactor a bit, and print out the *Sort + properties. + + + svn path=/trunk/taglib-sharp/; revision=126546 + +commit 6a1db30cd8ca012c76e7575e9adf2e44d505e1b9 +Author: Gabriel Burt +Date: Tue Feb 10 11:09:56 2009 + + 2009-02-10 Gabriel Burt + + * src/TagLib/Riff/File.cs: Patch from Andy Beal fixing bug where within a + while clause we would 'continue', but the actual counter incrementing + happened later in the while clause so the while condition was always true, + causing a freezing while writing video files (BGO #570892) + + + svn path=/trunk/taglib-sharp/; revision=126477 + +commit 11ed49d59e0f37bf1567f1dec514cd5df1fcf031 +Author: Gabriel Burt +Date: Tue Feb 10 11:07:03 2009 + + 2009-02-10 Gabriel Burt + + * tests/Makefile.am: + * tests/samples/sample.avi: + * tests/fixtures/TagLib.Tests.FileFormats/AviFormatTest.cs: Patch from + Andy Beal adding unit testing for AVI files; currently gets stuck in + infinite loop because of bug with writing to AVI files. + + + svn path=/trunk/taglib-sharp/; revision=126476 + +commit 98289c9e8c02faa9ef194108c4908fd0c7ae1931 +Author: Gabriel Burt +Date: Fri Feb 6 12:02:38 2009 + + 2009-02-06 Gabriel Burt + + * src/TagLib/Properties.cs: Patch from Andy Beal fixing VideoWidth getter, + was incorrectly returning height (BGO #570745) + + + svn path=/trunk/taglib-sharp/; revision=126082 + +commit dfa9ddd46fdcd6e486f9493e6569cfe8b9190196 +Author: Gabriel Burt +Date: Fri Feb 6 11:54:30 2009 + + 2009-02-06 Gabriel Burt + + * src/TagLib/Id3v2/Frame.cs: Patch from Andy Beal, fixing bug with not + skipping over Data Length Indicator field properly (BGO #568946) + + + svn path=/trunk/taglib-sharp/; revision=126081 + +commit ff43233d912b071852b1698754889f70a3087f29 +Author: Aaron Bockover +Date: Fri Jan 23 14:27:11 2009 + + 2009-01-23 Aaron Bockover + + * Makefile.am: Install .pc file to datadir since we're noarch + + + svn path=/trunk/taglib-sharp/; revision=124369 + +commit ddd55a94f0b8e66896e172d344386ba1da5e943a +Author: Gabriel Burt +Date: Thu Jan 22 18:17:54 2009 + + 2009-01-22 Gabriel Burt + + * src/TagLib/CombinedTag.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameTypes.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/GroupedComment.cs: Patch from John Millikin and Andy Beal + adding support for PerformerSort, AlbumArtistSort, ComposerSort, + TitleSort, and AlbumSort to TagLib.Tag, with backends for Ogg, ID3, mpeg4, + and asf (BGO #567657). + + + svn path=/trunk/taglib-sharp/; revision=124277 + +commit c47ade767d2b3d2a8f372b5c8974c727fad337da +Author: Aaron Bockover +Date: Tue Jan 20 16:32:25 2009 + + Fix tag name + + svn path=/trunk/taglib-sharp/; revision=123953 + +commit 0961c724b29468a9f5107b02286d3b614545442e +Author: Aaron Bockover +Date: Tue Jan 20 16:29:28 2009 + + Missing \ + + svn path=/trunk/taglib-sharp/; revision=123952 + +commit 8db9530ed1873d0246acb84f561176dcca8f9ee1 +Author: Aaron Bockover +Date: Tue Jan 20 16:27:07 2009 + + 2009-01-20 Aaron Bockover + + * configure.ac: Bumped version to 2.0.3.1, output bz2 and gz + + * Makefile.am: Added a push-release target + + * NEWS: Updated for 2.0.3.1 release + + + svn path=/trunk/taglib-sharp/; revision=123950 + +commit ff9b5afa5a3ef8b9a79edde5343faffa482d7f7c +Author: Gabriel Burt +Date: Tue Jan 20 15:23:25 2009 + + Update for release + + svn path=/trunk/taglib-sharp/; revision=123928 + +commit 7a518bd93334ec93a5414e4e0d0c14642cf76702 +Author: Aaron Bockover +Date: Tue Jan 20 15:21:21 2009 + + SUBDIRS tests + + svn path=/trunk/taglib-sharp/; revision=123926 + +commit 9288a468d586e88533ebd380ba0eabe71e90a254 +Author: Aaron Bockover +Date: Tue Jan 20 15:21:11 2009 + + Fix use of obsolete API + + svn path=/trunk/taglib-sharp/; revision=123925 + +commit f46fbd1bf53a1d2eeee5f6fb3604d93907c542e2 +Author: Aaron Bockover +Date: Tue Jan 20 15:18:20 2009 + + 2009-01-20 Aaron Bockover + + * configure.ac: Bumped version to 2.0.3.1 + + * NEWS: Updated for 2.0.3.1 release + + + svn path=/trunk/taglib-sharp/; revision=123923 + +commit e09402baf120df02b4aadbfff46d600f6699d640 +Author: Gabriel Burt +Date: Thu Jan 15 20:12:17 2009 + + 2009-01-15 Gabriel Burt + + * tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs: Update unit test + to reflect that we do now support writing cover art to ogg files. + + + svn path=/trunk/taglib-sharp/; revision=123568 + +commit ac160cc7839f31263fe8500fd693ff19b881dabb +Author: Gabriel Burt +Date: Thu Jan 15 20:08:16 2009 + + 2009-01-15 Gabriel Burt + + * src/TagLib/Ogg/XiphComment.cs: Patch from John Millikin adding cover art + reading and writing support to Ogg (BGO #563168) + + svn path=/trunk/taglib-sharp/; revision=123567 + +commit 48f6a94a29ae04e6adc5a514c208b890106bfbd2 +Author: Gabriel Burt +Date: Thu Jan 15 13:06:00 2009 + + 2009-01-15 Gabriel Burt + + * src/TagLib/Ape/File.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Ogg/File.cs: Add more mimetypes and file extensions including + .oga and .ogv (BGO #532561) + + * examples/ReadFromUri.cs: Avoid NRE crash + + + svn path=/trunk/taglib-sharp/; revision=123522 + +commit 21daae26e341c14c833a433f5c88533dac04f495 +Author: Gabriel Burt +Date: Thu Jan 15 13:01:15 2009 + + 2008-01-15 Gabriel Burt + + * src/TagLib/Mpeg4/file.cs: Patch from Andy Beal to recognize .m4b + files (Audiobook extention) in mpeg4 (BGO #567826) + + + svn path=/trunk/taglib-sharp/; revision=123520 + +commit 721fb8fc79715c34f7a06ced460ef7e1891888d1 +Author: Gabriel Burt +Date: Tue Jan 13 12:26:16 2009 + + 2008-01-13 Gabriel Burt + + Patch from Andy Beal adding support for Dash atoms, used primarily for + storing extra text tags, such as the MusicBrainz tags. The equivalent in + ID3 are the UserTextInfo frames. + + * src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs: Add Constructor to + enable Instantiating a new AdditionalInfoBox without reading from file. + + * src/TagLib/Mpeg4/AppleTag.cs: Add Methods for reading and writing + values to/from Dash Boxes (----) + + + svn path=/trunk/taglib-sharp/; revision=123227 + +commit b6ff6f306fcedb04acf01c18eb3689f50fb1bad1 +Author: Gabriel Burt +Date: Fri Dec 19 15:24:40 2008 + + Whoops, didn't mean to revert this, got confused about what was the new patch and what was there before + + svn path=/trunk/taglib-sharp/; revision=121890 + +commit f1b527ed4a8da14eb73e1965a37cdb9ca9e8dfd5 +Author: Gabriel Burt +Date: Mon Dec 15 19:41:48 2008 + + 2008-12-15 Gabriel Burt + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: Add an alreadyUnsynched argument to + CreateFrame that is true when the overall id3v2 Tag has the Unsync flag + set, and used to ensure we don't double-synchronize the data for a frame. + + * src/TagLib/Id3v2/FrameHeader.cs: Fix typo + + * src/TagLib/Id3v2/Frame.cs: Fix typo, use the new CreateFrame + + * src/TagLib/File.cs: Remove unnecessary (and buggy) position/length + adjustments in ReadBlock method. + + * src/TagLib/NonContainer/StartTag.cs: Fix typos, ensure that ReadTag + returns the valid start value even if there is an exception creating it, + and write any tag-creation exceptions to Console.Error. + + + svn path=/trunk/taglib-sharp/; revision=121568 + +commit d043e77cd667c924d51fe5fc252d798e30d50ca5 +Author: Gabriel Burt +Date: Thu Dec 11 17:45:44 2008 + + 2008-12-11 Gabriel Burt + + * tests/ConsoleUi.cs: + * tests/Makefile.am: + * configure.ac: Remove ConsoleUi in favor of system-installed + nunit-console2. Make the tests depend on the taglib-sharp.dll, and rename + the target 'test'. + + * Makefile.am: Add 'test' target that calls make test in tests/ + + + svn path=/trunk/taglib-sharp/; revision=121368 + +commit 96541ba2588aef666d6c9a8b09def2252e5a1161 +Author: Gabriel Burt +Date: Thu Dec 11 17:43:56 2008 + + Actually commit Jeff's patch, already mentioned in the ChangeLog + + svn path=/trunk/taglib-sharp/; revision=121365 + +commit 6da96266229c1ed419d77a23d9ddc0e446a6958b +Author: Gabriel Burt +Date: Thu Dec 11 17:24:42 2008 + + 2008-12-11 Gabriel Burt + + * src/AssemblyInfo.cs.in: remove the if #SIGN - always sign + + * tests/Makefile.am: Fix up source files list. + + * tests/tests.mdp: enable Makefile integration + + * configure.ac: Uncomment the nunit check and generate tests/Makefile + + svn path=/trunk/taglib-sharp/; revision=121363 + +commit ca2086339d75e17841227ae5045bd093630081bb +Author: Rusty Howell +Date: Wed Jul 16 20:42:11 2008 + + Fixed syntax error in xml doc strings + + svn path=/trunk/taglib-sharp/; revision=108108 + +commit dada5252ec43f0824226bb906a6a55c83d22cfd2 +Author: Jeffrey Stedfast +Date: Tue Jan 29 16:08:55 2008 + + 2008-01-16 Jeffrey Stedfast + + * src/TagLib/Mpeg/AudioHeader.cs (AudioHeader): Do a bit more + thorough bitwise examination of the second byte in the MPEG sync + header. + + + svn path=/trunk/taglib-sharp/; revision=94328 + +commit 492f1e407d1d1b6769edfabf5a20db118dff2d89 +Author: Brian Nickel +Date: Thu Jan 10 17:28:46 2008 + + 2008-01-10 Brian Nickel + + * NEWS: Updated for new release. + + * configure.ac: Now 2.0.3.0 + + svn path=/trunk/taglib-sharp/; revision=92635 + +commit 0f23f4b07d569b4a447d95b29a9a693d93f96fe4 +Author: Brian Nickel +Date: Wed Jan 9 19:30:11 2008 + + 2008-01-09 Brian Nickel + + This commit does the following: + - Finishes XML documentation. + - Makes ASF tags enumerable. + - Allows saving RelativeVolumeFrames in 2.2 and 2.3 via + semi-standard XRV and XRVA names. + - Prevents duplicates when genres are stored in "(0)Blues" + format. + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Footer.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/ListBase.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: + * src/TagLib/Ogg/Codec.cs: + * src/TagLib/Ogg/Bitstream.cs: Finish documentation. + + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/MetadataLibraryObject.cs: Make enumerable. + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: If genre index is + followed by genre text, don't store it twice. + + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V2Test.cs: Save RVA2 as + XRVA and XRV in older versions. + + * configure.ac: Now 2.0.2.22. + + svn path=/trunk/taglib-sharp/; revision=92562 + +commit e38d5652387c1225ccdd709c982f5cb43b19a3b2 +Author: Brian Nickel +Date: Thu Jan 3 01:59:47 2008 + + 2008-01-03 Brian Nickel + + * src/Makefile.am: Generate taglib-sharp.dll.xml instead. + * docs/Package.en.xml.in: Contains missing documentation and rules for + XmlInjector.exe. + + * docs/XmlInjector.cs: A new XML manager which can remove, replace, and + insert nodes into an XML document based on XPath queries. + + * docs/Makefile.am: Build XML from the slashdoc and use XmlInjector.exe + to insert missing parts into documentation as well as modify monodoc.xml + + * docs/Package.en.xml: Depreciated by docs/Package.en.xml.in. + + * docs/MonodocNodeConfig.cs: Depreciated by docs/XmlInjector.cs. + + * configure.ac: Generate docs/Package.en.xml from + docs/Package.en.xml.in + + svn path=/trunk/taglib-sharp/; revision=92157 + +commit 44578d8d281dbe301464180fcb272d0a703463df +Author: Brian Nickel +Date: Wed Jan 2 20:43:28 2008 + + 2008-01-02 Brian Nickel + + * src/Makefile.am: Generate taglib-sharp-docs.xml when building docs. + * docs/en/: Deleted. Will be replaced with autogeneration after this + update. + + * docs/Makefile.am: Add docs/Packages.en.xml do DIST_EXTRA + * docs/Package.en.xml: Contains values not in slashdocs. + + svn path=/trunk/taglib-sharp/; revision=92148 + +commit 5932a1adfb5a243de2d0f70f3ae4fa4cc8d9e583 +Author: Brian Nickel +Date: Wed Jan 2 19:05:18 2008 + + 2008-01-02 Brian Nickel + + * src/TagLib/CombinedTag.cs: + * src/TagLib/ByteVectorList.cs: + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Id3v1/StringHandler.cs: + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/AviHeaderList.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Genres.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/ExtendedHeader.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/VideoHeader.cs: + * src/TagLib/Mpeg/AudioFile.cs: + * src/TagLib/Mpeg/AudioHeader.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/SupportedMimeType.cs: + * src/TagLib/Flac/Picture.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Flac/StreamHeader.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/Ape/File.cs: + * src/TagLib/ListBase.cs: + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Picture.cs: + * src/TagLib/Tag.cs: + * src/TagLib/Mpc/File.cs: + * src/TagLib/Mpc/StreamHeader.cs: + * src/TagLib/File.cs: + * src/TagLib/WavPack/File.cs: + * src/TagLib/WavPack/StreamHeader.cs: + * src/TagLib/NonContainer/Tag.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/HeaderExtensionObject.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/UnknownObject.cs: + * src/TagLib/Asf/MetadataLibraryObject.cs: + * src/TagLib/Asf/PaddingObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/Object.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/Page.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Paginator.cs: + * src/TagLib/Ogg/PageHeader.cs: + * src/TagLib/Ogg/GroupedComment.cs: More docs, corrected some typos. + + + svn path=/trunk/taglib-sharp/; revision=92141 + +commit 6893f5fca42ac8df165a4d7147f6b7ebf62fed8c +Author: Brian Nickel +Date: Tue Jan 1 21:30:34 2008 + + 2008-01-01 Brian Nickel + + I'm working to finish up the xmldocs so I can get rid of the aging docs + directory. + + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/AviHeaderList.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/PopularimeterFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/Id3v2/ExtendedHeader.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Flac/BlockHeader.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Item.cs: + * src/TagLib/Picture.cs: + * src/TagLib/Ogg/XiphComment.cs: A little documentation and + reformatting. + + * examples/BatchSet.cs: Add support for setting the ID3v2 version. + + svn path=/trunk/taglib-sharp/; revision=92094 + +commit 7fc0f6bd46e6e34224c57a4842ca3e155e8dd4c8 +Author: Brian Nickel +Date: Sun Dec 30 03:50:36 2007 + + 2007-12-30 Brian Nickel + + This commit does the following: + - Makes Id3v2 skip iTunes settings-style comments. + - Makes ; the separator for multivalue fields in Mpeg4, rather + than storing in multiple boxes. + - Cleans up Mpeg4 genre logic. + - Uses System.Globalization to choose the default language in + Id3v2. + - Moves the comment written when Id3v2.Tag.Comment to be the + first COMM in the frame so it is the first one recognized by + other programs. + + * src/TagLib/Id3v2/Tag.cs: Move the written comment to be the first + COMM frame if it isn't. Make " " the fallback comment per instructions + on id3.org. Get the default language from CultureInfo.CurrentCulture + .ThreeLetterISOLanguageName. + + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: Skip iTunes comments if + they are set. There's no need for gibberish to show up as the comment. + + * src/TagLib/Mpeg4/AppleTag.cs: Instead of adding multiple data boxes + for multi-string values, use `;' as a separator. It wasn't working out + in iTunes. (TagLib# can still read the tags is wrote earlier just fine.) + Use `@gnr' or `gnre', but don't attempt a weird mix of both at the same + time. + + * tests/tests.mdp: Automatic changes by MonoDevelop 0.18. + + * configure.ac: Now 2.0.2.21. + + svn path=/trunk/taglib-sharp/; revision=92033 + +commit 4b09fb0a7d34cb10272090e98d982dfe29d7047e +Author: Brian Nickel +Date: Sat Dec 29 20:50:29 2007 + + 2007-12-29 Brian Nickel + + This commit introduces some powerful new tests. They add more intensive + checking of saving and rendering and have lead to the preemptive + correction of several bugs. + + * tests/tests.mdp: + * tests/fixtures/Helpers.cs: + * tests/fixtures/TagLib.FormatTests/FlacFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V1FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V2FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/IFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/AsfFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3BothFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/OggFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/MpcFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/M4aFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/FlacFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/Id3V1FormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/Id3V2FormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/IFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/AsfFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/StandardTests.cs: + * tests/fixtures/TagLib.Tests.FileFormats/Id3BothFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/OggFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/MpcFormatTest.cs: + * tests/fixtures/TagLib.Tests.FileFormats/M4aFormatTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Mpeg4Test.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/ApeTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V1Test.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/Id3V2Test.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/InfoTagTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/XiphTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/MovieIdTagTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/AsfTest.cs: + * tests/fixtures/TagLib.Tests.TaggingFormats/DivXTest.cs: Replaced unit + tests with new versions. + + svn path=/trunk/taglib-sharp/; revision=92025 + +commit 74de4b8edad100c3f460afac42aa36506f683347 +Author: Brian Nickel +Date: Sat Dec 29 19:26:31 2007 + + 2007-12-29 Brian Nickel + + This commit does the following: + - Fixes support for IsCompilation when saving as ID3v2.2. + - Makes Id3v2.Tag clonable. + - Fixes the project files. + - Fixes cloning UserTextInformationFrame. + + - CHANGES THE DEFAULT ID3v2 VERSION TO 3. While this may result + in some boos from people who consider ID3v2.4 to be the perfect + tagging format (myself included), the number of applications + that hiccup on ID3v2.4 is too astounding. This will not cause + tags already encoded at 2.4 to be reencoded at 2.3, but if new + tags are added to the file, they will be 2.3. + + * src/TagLib/Id3v2/Tag.cs: Make Tag cloneable. Make default version 3. + + * src/TagLib/Id3v2/FrameHeader.cs: Add version 2 mapping for TCMP so + IsComposer is saved in Id3v2.2. + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: If the frame + is a User*, create a User* when cloning. + + * src/TagLib/Id3v2/ExtendedHeader.cs: Make cloneable. + + * src/TagLib/Id3v2/FrameTypes.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: Add description of why these classes + exist, why they are internal, and why they aren't necessary for third + party programmers. + + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Add VBRIHeader.cs + + svn path=/trunk/taglib-sharp/; revision=92024 + +commit e93bf6fdf5d818197cfdc7518e76f2bdfea4192d +Author: Brian Nickel +Date: Fri Dec 28 15:19:09 2007 + + 2007-12-28 Brian Nickel + + This commit does the following: + - Adds IsCompilation to Id3v2. + - Adds support for deep CopyTo with Id3v2. + - Fixes support for deep CopyTo with Ape. + - Adds support for Fraunhofer VBRI headers in MPEG audio. + - Fixes a bug in reading XiphComments. + - Other trivial changes. + + * src/TagLib/Id3v2/Tag.cs: Added IsCompilation and CopyTo. + + * src/TagLib/Id3v2/FrameTypes.cs: Added TCMP. + + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/PopularimeterFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/Id3v2/Frame.cs: Made clonable. + + * src/TagLib/TagLib.sources: + * src/TagLib/Mpeg/VBRIHeader.cs: + * src/TagLib/Mpeg/AudioHeader.cs: Added support for Fraunhofer VBRI + header. This improves coverage of VBR files. (Thanks to hwahrmann for + proposing and authoring the changes.) + + * src/TagLib/Ape/Tag.cs: Fixed CopyTo to actually override + TagLib.Tag.CopyTo. + + * src/TagLib/Ape/Item.cs: Trivial formatting. + + * src/TagLib/Picture.cs: Try to make ObsoleteAttributes a bit clearer. + + * src/TagLib/Debugger.cs: Much nicer DumpHex. + + * src/TagLib/Ogg/XiphComment.cs: Don't fail when a bad comment (one + without a = is encountered, just ignore that field. (Thanks to hwahrmann + for the bug report and authoring the changes.) + + * examples/BatchSet.cs: Allow setting pictures. + + * configure.ac: Now 2.0.2.20. + + svn path=/trunk/taglib-sharp/; revision=92001 + +commit bc9aa22b56ec39127f7ff7ae9e5954d948462f42 +Author: Brian Nickel +Date: Thu Dec 27 01:11:19 2007 + + 2007-12-27 Brian Nickel + + This commit does the following: + - Adds support for .divx extension. (Just an AVI) + - Adds Tag.CopyTo to obsolete Tag.Duplicate. The difference is + that Tag.CopyTo is overridable, so tags and implement their + own, better, copying. + - Several small bugfixes correcting Mpeg4.Tag.IsCompilation, + GIF images, reading Mpeg4 pictures without flags, and + NonContainer.EndTag reading small files. + + - COMPLETE REWORK of OGG pagination to handle multipage comments + and saving that results in the creation of new pages. This + fixes a bug posted by kurros on the forum and Banshee bug + #502628. + + * src/TagLib/Riff/File.cs: Recognize the .divx extension. (Thanks to + sukhjinder for the feature request and jocker for confirming the fix.) + Use Tag.CopyTo instead of Tag.Duplicate. + + * src/TagLib/Flac/File.cs: Use Tag.CopyTo instead of Tag.Duplicate. + + * src/TagLib/Ape/Tag.cs: Add first real implementation of Tag.CopyTo. + + * src/TagLib/Ape/Item.cs: Make clonable. + + * src/TagLib/Mpeg4/AppleTag.cs: Don't check for image format flags, just + use data to identify the image type. iTunes apparently doesn't use the + flags anymore. (Thanks to DavidT@Imerge for the bug report.) Use 1 byte + rather than 4 to store the compilation setting. (Thanks to DavidT@Imerge + for the fix.) + + * src/TagLib/Picture.cs: Was setting mime-type to "image/png" for GIF. + + * src/TagLib/Tag.cs: Mark Tag.Duplicate as obsolete and replace with + overridable Tag.CopyTo. This will provide the option for better copying + from one tag to another if their types match rather than just doing the + simply copy available in Tag.Duplicate. See Ape.Tag for an + implemenation. More coming soon. + + * src/TagLib/NonContainer/File.cs: Don't read tags at the end of the + file if the tags at the start of the file are the entire file. (No + double dipping.) + + * src/TagLib/NonContainer/EndTag.cs: Don't crash if start < 128 when + reading. (Thanks to jonx for the bug report.) Use Tag.CopyTo instead of + Tag.Duplicate. + + * src/TagLib/NonContainer/StartTag.cs: Use Tag.CopyTo instead of + Tag.Duplicate. + + * src/TagLib/Ogg/File.cs: Use changes in Page and Paginator classes to + handle situations where the number of pages in the stream changes. + + * src/TagLib/Ogg/Page.cs: Add method for updating all Ogg pages after a + certain position with new page numbers. This is necessary if new pages + are inserted to avoid corrupting the file. Part of sweeping changes to + Ogg support. + + * src/TagLib/Ogg/Paginator.cs: Instead of just saving a single page, + properly paginate using a single page for the first packet in the file. + Optimally, produce the same number of pages as were in the file before, + but allow for creating more pages if the situation warrents it. + + * src/TagLib/Ogg/PageHeader.cs: Add a constructor which clones a header + but offsets page sequence by a specified number. + + * src/TagLib/Ogg/Bitstream.cs: Fix typo that was preventing multi-page + packets from reading correctly. What a difference a negation makes. + + * configure.ac: Now 2.0.2.19. + + svn path=/trunk/taglib-sharp/; revision=91915 + +commit 9f3974dc78e45cf027155302c8496535ea6e4feb +Author: Brian Nickel +Date: Tue Dec 25 06:12:52 2007 + + 2007-12-25 Brian Nickel + + * src/TagLib/Riff/File.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Ogg/File.cs: Wrap constructors and save operations in + try/finally to ensure the streams get closed. (Thanks to oliphant for + the bug report.) + + svn path=/trunk/taglib-sharp/; revision=91875 + +commit 250683919fee9b9dcc82825aba075215ed22df9a +Author: Brian Nickel +Date: Tue Dec 25 04:09:22 2007 + + 2007-12-25 Brian Nickel + + * src/TagLib/Id3v1/Tag.cs: Added constructor to create from data. Added + documentation. Fixed properties to produce correct output when empty. + Removed broken IsEmpty property. + + * src/TagLib/Riff/List.cs: Make sure fields are cleared when SetValue + is called with any type of empty result. + + * src/TagLib/Riff/DivXTag.cs: Added constructor to create from data. + Added documentation. Fixed properties to produce correct output when + empty. Make Clear() clear `title'. Resize fields after encoding rather + than before to avoid possible sizing problems. + + * src/TagLib/Riff/MovieIdTag.cs: Read genre from correct position. + + * src/TagLib/Riff/WaveFormatEx.cs: Reformat and complete codec + descriptions. + + * src/TagLib/Id3v2/Tag.cs: Add constructor to create from data. Fixed + properties to produce correct output when empty. + + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: Correct file + header. + + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: Use alignment when + searching for delimiter to avoid breakage with UTF16BE. + + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: Tidy up a bit. + Add constructor with only owner as argument. + + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: Throw NotImplementedException + when version is less than 3, rather than just outputting an empty tag. + + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: Add size + of delimiter rather than 1 to avoid breakage with UTF16. + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Use delimiter + rather than single byte in a rejection method to avoid breakage. Have + genres produce "/" separated values after first non-indexable value is + encountered. eg. {"Blues", "Country", "Foobar", "Jazz"} becomes + "(0)(2)Foobar/Jazz". This format is completely recoverable. Add + constructor for User* which accepts just a description. + + * src/TagLib/Mpeg/AudioHeader.cs: Correct some documentation. + + * src/TagLib/ByteVector.cs: Pass generated BOM to StringTypeToEncoding + to make sure the correct encoding is used. + + * src/TagLib/Flac/File.cs: Correct documentation typo. + + * src/TagLib/Ape/Tag.cs: Add support for one of each type of picture + rather than just one front cover. Allow parsing of years not 4 digits + in length. + + * src/TagLib/Mpeg4/FileParser.cs: Prevent a crash if there isn't + sufficient data for reading the first block in parsers. Fix typo which + caused UtdaTree to not be filled, resulting in written tags not being + readable. + + * src/TagLib/Mpeg4/AppleTag.cs: Allow parsing of years not 4 digits + in length. Correctly clear zeroed values. + + * src/TagLib/Tag.cs: Use semicolons, rather than commas in Joined* to + reflect behavior of WMP. + + * src/TagLib/Picture.cs: Fix documentation typo. + + * src/TagLib/WavPack/StreamHeader.cs: Add some docs. + + * src/TagLib/Asf/Tag.cs: Remove "WM/GenreID" when a new genre is stored. + + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: Loop through names + rather than descriptors first when getting descriptors. That way the + first matching name is chosen rather than the first descriptor of any + name. + + * src/TagLib/Asf/ContentDescriptor.cs: Fix rendering bug that broke + storing values. + + * configure.ac: Now 2.0.2.18. + + svn path=/trunk/taglib-sharp/; revision=91872 + +commit 38c6838456f6ca92a292f90d2cf763914a8857f0 +Author: Brian Nickel +Date: Tue Oct 2 13:27:31 2007 + + 2007-10-02 Brian Nickel + + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Flac/Picture.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Item.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Ogg/XiphComment.cs: Use ToString (StringType,int,int) + instead of ToString(StringType) + + * src/TagLib/Mpeg/AudioHeader.cs: Remove AudioHeader.position as it is + no longer needed. + + * src/TagLib/ByteVector.cs: Use ToString(StringType,int,int) in + ToStrings, mark ToString(StringType,int) as obsolete, add + ToString(StringType,int,int), add documentation. Relax exception + exception checking in ToString as it was causing unnecessary exceptions + when reading some zero byte strings. (Thanks to sambeckett for the bug + report.) + + * src/TagLib/Asf/Tag.cs: Use ContentDescriptionObject.Copyright instead + of an extended content descriptor. (Thanks to Dakuja for the bug + report.) + + * src/TagLib/Id3v2/Frames/PopularimeterFrame.cs: Add nil separator when + rendering. Was causing tag to be unreadable. (Thanks to cody for the bug + report.) + + * configure.ac: Now 2.0.2.17. + + svn path=/trunk/taglib-sharp/; revision=86763 + +commit 900eee2508821d22f9627ef7b1ad11b8468a6d6c +Author: Brian Nickel +Date: Thu Sep 20 15:54:40 2007 + + 2007-09-20 Brian Nickel + + * src/TagLib/ByteVector.cs: Fix overflow problem introduced last + release. (Thanks to hwahrmann for the bug report.) + + * src/TagLib/Asf/HeaderObject.cs: Switch the order of play_duration and + send_duration. Standard implementation is backwards from the + specification. (Thanks to hwahrmann for the bug report.) + + * src/TagLib/Asf/FilePropertiesObject.cs: Subtract preroll from + duration. (Thanks to hwahrmann for the bug report.) + + * configure.ac: Now 2.0.2.16. + + svn path=/trunk/taglib-sharp/; revision=86112 + +commit 3d7097038b0aefac9481f4c18a7528050b4830b8 +Author: Brian Nickel +Date: Tue Sep 18 15:07:18 2007 + + 2007-09-18 Brian Nickel + + * src/TagLib/Riff/BitmapInfoHeader.cs: Reformat. + + * src/TagLib/Id3v2/FrameHeader.cs: Remove 'using System.Collections' + + * src/TagLib/Mpeg/AudioHeader.cs: Don't double-count position when + counting frames. (Thanks to hwahrmann for the bug report.) + + * src/TagLib/ByteVector.cs: Add UseBrokenLatin1Behavior to emulate bad + behavior of many taggers. When true, TagLib# will read Latin1 strings as + the system default encoding. + + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Ape/Tag.cs: Documented. + + * src/TagLib/Riff/File.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Asf/DescriptionRecord.cs: + * src/TagLib/Asf/ContentDescriptor.cs: + * src/TagLib/ReadOnlyByteVector.cs: Use ToString(StringType). + + * configure.ac: Now 2.0.2.15. + + svn path=/trunk/taglib-sharp/; revision=85987 + +commit 80926fc841ac9bf4df8ff726a5c33dcc37488b39 +Author: Brian Nickel +Date: Mon Sep 17 01:44:06 2007 + + 2007-09-17 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: New logic for SetFrameText was backwards, + causing frames to disappear. (Thanks to hwahrmann for the bug report.) + + * src/TagLib/Id3v2/FrameHeader.cs: Fix the reading of version 2 and 3 + headers. They weren't being converted to the new headers. Add + FrameFlags.None. + + * src/TagLib/Id3v2/Header.cs: Add HeaderFlags.None. + + * configure.ac: Now 2.0.2.14. + + svn path=/trunk/taglib-sharp/; revision=85861 + +commit fb12bfc4ca89e46a1b3024170f3e436a4a6b28ec +Author: Brian Nickel +Date: Sun Sep 16 17:23:22 2007 + + 2007-09-16 Brian Nickel + + * src/TagLib/Id3v2/SynchData.cs: + * src/TagLib/Id3v2/FrameTypes.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Ape/StreamHeader.cs: Documentation. + + svn path=/trunk/taglib-sharp/; revision=85860 + +commit c172f173c6f06518c7323c14d43bd273b58e1392 +Author: Brian Nickel +Date: Wed Sep 5 19:25:26 2007 + + 2007-09-05 Brian Nickel + + * src/TagLib/Flac/Block.cs: Completed docs. + + * src/TagLib/Id3v2/Tag.cs: GetItemAsUInt32 was fubar and always + returning zero. (Thanks to renzska for the bug report.) Always set the + encoding to the default when setting the contents of a frame. This + should hopefully prevent bad encoding. (Thanks to evgeni for the bug + report.) + + * src/TagLib/Ape/Tag.cs: GetItemAsUInt32 was fubar and always returning + zero. + + * configure.ac: Now 2.0.2.13. + + + + svn path=/trunk/taglib-sharp/; revision=85387 + +commit 7073f245a80d975f37c51d0d21b3f5da68dd6057 +Author: Brian Nickel +Date: Tue Sep 4 02:17:55 2007 + + 2007-09-04 Brian Nickel + + Only 713 public members away from doing away with MonoDoc. + + * src/TagLib/Flac/File.cs: Completed docs. + + * src/TagLib/ByteVectorList.cs: + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Id3v1/StringHandler.cs: + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/AviHeaderList.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Genres.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Footer.cs: + * src/TagLib/Id3v2/SynchData.cs: + * src/TagLib/Id3v2/FrameTypes.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: + * src/TagLib/Id3v2/ExtendedHeader.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Properties.cs: + * src/TagLib/SupportedMimeType.cs: + * src/TagLib/Flac/Picture.cs: + * src/TagLib/Flac/BlockHeader.cs: + * src/TagLib/Flac/StreamHeader.cs: + * src/TagLib/Flac/Block.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/StringList.cs: + * src/TagLib/FileTypes.cs: + * src/TagLib/ListBase.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Picture.cs: + * src/TagLib/Tag.cs: + * src/TagLib/File.cs: + * src/TagLib/Debugger.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/HeaderExtensionObject.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/Guid.cs: + * src/TagLib/Asf/MetadataLibraryObject.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/Page.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: + * src/TagLib/Ogg/Codec.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Paginator.cs: + * src/TagLib/Ogg/PageHeader.cs: + * src/TagLib/Ogg/GroupedComment.cs: + * src/TagLib/Ogg/Bitstream.cs: + * src/AssemblyInfo.cs.in: Replaced headers and use cref="T:...`1" + instead of "...{T}" until gmcs is fixed. This reduces warnings to + strictly CS1591. + + svn path=/trunk/taglib-sharp/; revision=85255 + +commit 4721677e816f851bc30009cd35145ad4c3610c9a +Author: Brian Nickel +Date: Mon Sep 3 15:57:36 2007 + + 2007-09-03 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: Renamed private method. Tidied up Read. + + * src/TagLib/Ape/Item.cs: Fixed some documentation. + + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/HeaderExtensionObject.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/DescriptionRecord.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/UnknownObject.cs: + * src/TagLib/Asf/Guid.cs: + * src/TagLib/Asf/MetadataLibraryObject.cs: + * src/TagLib/Asf/PaddingObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/Object.cs: + * src/TagLib/Asf/ContentDescriptor.cs: Completed docs. + + svn path=/trunk/taglib-sharp/; revision=85245 + +commit e99b1e6e4727bfe7babe83c31a0a21686e356d22 +Author: Brian Nickel +Date: Fri Aug 31 12:05:20 2007 + + 2007-08-31 Brian Nickel + + * src/TagLib/Ape/File.cs: + * src/TagLib/Ape/StreamHeader.cs: + * src/TagLib/FileTypes.cs: Added support for reading APE files. (Thanks + to hwahrmann for authoring the classes.) + + * src/TagLib/Id3v2/Tag.cs: Fixed docs. + + * src/TagLib/Ape/Item.cs: Completed docs. + + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: Prevent + ArgumentOutOfRangeException when a corrupt frame is encountered. (Thanks + to jms for the bug report.) + + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Properties.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Ogg/XiphComment.cs: Removed StringCollection usage (and + replaced some collections with arrays. + + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Added files. + + * configure.ac: Now 2.0.2.12. + + svn path=/trunk/taglib-sharp/; revision=85146 + +commit aa88901e9133c8632e00673af9f1d784ea41fdb0 +Author: Brian Nickel +Date: Tue Aug 28 19:36:24 2007 + + 2007-08-28 Brian Nickel + + * src/TagLib/Ape/Tag.cs: Stop parsing when a corrupt item is detected. + + * src/TagLib/Ape/Item.cs: UTF-8 encoded length != string.Length. Was + messing up with Chinese titles. (Thanks to jms for the bug report.) + + * src/TagLib/CombinedTag.cs: Fix header. + + * src/TagLib/Id3v2/Tag.cs: Document, add generic GetFrames() + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/Mpeg/File.cs: Document. + + * src/TagLib/Mpeg/VideoHeader.cs: Fix copyright info. + + * src/TagLib/Mpeg/AudioFile.cs: Fix some typos. + + * src/TagLib/Properties.cs: + * src/TagLib/SupportedMimeType.cs: + * src/TagLib/StringList.cs: + * src/TagLib/FileTypes.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/Box.cs: Fixed generics documentation. + + * src/TagLib/Mpeg4/File.cs: Accidentally marked constructors as + protected when copy/pasting code from NonContainer.File. (Thanks to + hwahrmann for the bug report.) + + * configure.ac: Now 2.0.2.11. + + svn path=/trunk/taglib-sharp/; revision=84985 + +commit 51805c32c8855c0c1d1b8f2feaba2d96cc066b24 +Author: Brian Nickel +Date: Fri Aug 24 19:19:12 2007 + + 2007-08-24 Brian Nickel + + * src/TagLib/Mpeg/AudioHeader.cs: Restore copyright notice. + + * src/TagLib/ICodec.cs: Wording Change. + + * src/TagLib/Mpeg/XingHeader.cs: + * src/TagLib/Mpeg/VideoHeader.cs: + * src/TagLib/Mpeg/AudioFile.cs: + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoFreeSpaceBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleDataBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs: + * src/TagLib/Mpeg4/Boxes/UnknownBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/Box.cs: Document completely. + + svn path=/trunk/taglib-sharp/; revision=84838 + +commit dec5cc67b4341608e15eb276a5c42c27c9277f15 +Author: Brian Nickel +Date: Mon Aug 20 02:08:28 2007 + + 2007-08-19 Brian Nickel + + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/UnknownBox.cs: Document completely. + + * src/TagLib/Mpeg4/AppleTag.cs: Committed too soon. File didn't compile. + * src/TagLib/Mpeg4/BoxFactory.cs: Forgot a bunch of end tags. + + * src/TagLib/Mpeg4/Box.cs: Fix doc typo. + + * src/TagLib/Mpc/StreamHeader.cs: + * src/TagLib/WavPack/StreamHeader.cs: Slight change in wording. + + svn path=/trunk/taglib-sharp/; revision=84428 + +commit 858f6cfd4adbf14589d3e125b65b61196160a47e +Author: Brian Nickel +Date: Mon Aug 20 00:40:31 2007 + + 2007-08-19 Brian Nickel + + * src/TagLib/Id3v2/Frames/PopularimeterFrame.cs: Fix an exception when + saving a PopularimeterFrame with a play count of 0. + + * src/taglib-sharp.mdp: Remove BoxList.cs. It hasn't been used in + forever and is an empty file. + + * src/TagLib/Mpeg4/FileParser.cs: Started documentation. + + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/BoxList.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Mpc/File.cs: + * src/TagLib/WavPack/File.cs: Completed documentation. + + * src/TagLib/Mpc/StreamHeader.cs: + * src/TagLib/WavPack/StreamHeader.cs: Completed documentation, except + for IEquitable overrides. + + * src/TagLib/Mpeg4/AppleTag.cs: Completed documentation, except for + IEnumerable overrides. + + * configure.ac: Now 2.0.2.10. + + svn path=/trunk/taglib-sharp/; revision=84426 + +commit 9bc89ce4e9eee861e891e30621b3e74f6f9d85f5 +Author: Brian Nickel +Date: Sun Aug 19 14:07:59 2007 + + 2007-08-19 Brian Nickel + + * src/TagLib/File.cs: Fix some typos in documentation. + + * src/TagLib/NonContainer/Tag.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: Document completely. + + svn path=/trunk/taglib-sharp/; revision=84408 + +commit 72482ecc56ce43af5ec646017224da66006a30bb +Author: Brian Nickel +Date: Fri Aug 17 18:37:31 2007 + + 2007-08-17 Brian Nickel + + * src/TagLib/Mpeg/AudioHeader.cs: Go back to setting XingHeader early, + there are just too many things that depend on `this'. (Thanks to jmurphy + for the bug report.) + + * src/TagLib/Ape/Tag.cs: Support APEv2 cover pictures. (Thanks to + renzska for the feature request.) + + * src/TagLib/Picture.cs: Add new constructors, obsolete CreateFromFile + and CreateFromPath, detect GIF and BMP files. + + * src/TagLib/NonContainer/EndTag.cs: Check that the footer contains + sane values. + + * configure.ac: Now 2.0.2.9. Remove pkgconfig check for Mono. It isn't + really needed. + + 2007-08-16 Brian Nickel + + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/DescriptionRecord.cs: + * src/TagLib/Asf/MetadataLibraryObject.cs: + * src/TagLib/Asf/ContentDescriptor.cs: Added support for the ASF + Metadata Library Object. This object supports content descriptors as big + as uint.MaxValue as opposed to ushort.MaxValue. Tag.Pictures now reads + from this source as well, and large pictures are now written to it. They + were previously ignored. (Thanks to renzska for the bug report.) + + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Added new files. + + * configure.ac: Now 2.0.2.8 + + svn path=/trunk/taglib-sharp/; revision=84339 + +commit e924fe536ed5c029be3103f25fd0434ed9282635 +Author: Brian Nickel +Date: Thu Aug 16 16:28:34 2007 + + 2007-08-16 Brian Nickel + + * src/TagLib/Mpeg/AudioHeader.cs: Use non-property checks in public + constructor, assigning the XingHeader after sanity tests was causing + compiler problems on MS .NET. (Thanks to jmurphy for the bug report.) + + * configure.ac: Now 2.0.2.7 + + svn path=/trunk/taglib-sharp/; revision=84242 + +commit a2bb91062fccaf01b72f333aa5317b1291b233b2 +Author: Brian Nickel +Date: Tue Aug 14 16:50:47 2007 + + 2007-08-14 Brian Nickel + + * src/TagLib/Mpeg/XingHeader.cs: Add XingHeader.FileIdentifier to speed + things up. + + * src/TagLib/Mpeg/AudioHeader.cs: Fully document, reformat and add a + check for the Xing identifier before calling the constructor to avoid an + unnecessary exception/try/catch. + + * src/TagLib/ICodec.cs: Correct some documentation. + + * src/TagLib/Properties.cs: + * src/TagLib/SupportedMimeType.cs: + * src/TagLib/StringList.cs: + * src/TagLib/FileTypes.cs: Correct for documentation compiler warning. + + * taglib-sharp.csproj: Added PopularimeterFrame.cs + + svn path=/trunk/taglib-sharp/; revision=84123 + +commit 39f560e77794ae82c5662b9be3efec137793e1a1 +Author: Brian Nickel +Date: Sun Aug 12 21:54:49 2007 + + 2007-08-12 Brian Nickel + + * src/TagLib/Id3v2/FrameTypes.cs: Added POPM + + * src/TagLib/Id3v2/FrameFactory.cs: Added PopularimeterFrame + + * src/TagLib/Id3v2/Frames/PopularimeterFrame.cs: NEW. Supports ID3v2 + POPM (4.17) frame. (Thanks to renzska for the feature request.) + + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: Removed 'using + System.Collections; + + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: Added PopularimeterFrame.cs + + * configure.ac: Now 2.0.2.5 + + svn path=/trunk/taglib-sharp/; revision=83929 + +commit b73f68526f3f4b6387b2374a5859d0ab08f284e3 +Author: Brian Nickel +Date: Sun Aug 12 21:03:16 2007 + + 2007-08-12 Brian Nickel + + * src/TagLib/Riff/List.cs: Reordered operations. Was incrementing a + value after it would have made a difference. + + * src/TagLib/Id3v2/Tag.cs: Added static UseNumericGenres which can be + set to false to prevent genres from being stored as ID3v1 indices. + (Thanks to craig for the feature request.) + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Use a + StringBuilder instead of + operations when formatting genres. + + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: Check that a negative length + is not being passed to Mid if '\0' is not found. + + * src/TagLib/Mpeg4/BoxTypes.cs: Add Mdat. + + * src/TagLib/Riff/File.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/File.cs: Added InvariantStartPosition and + InvariantEndPosition describing the invariant/media section of the file + that should be uneffected by TagLib# write operations. (Thanks to AgentS + and kajic for their feature requests.) + + * configure.ac: Now 2.0.2.4 + + svn path=/trunk/taglib-sharp/; revision=83928 + +commit 2a9900eb9e53f4981e69d7539ad9676e97337ecd +Author: Brian Nickel +Date: Thu Aug 2 14:11:17 2007 + + 2007-08-02 Brian Nickel + + * src/TagLib/Id3v2/Frame.cs: Files were throwing ArgumentOutOfRange + exceptions after the changes on 2007-07-29. It now checks that the + ByteVector contains enough bytes and if not throws a + CorruptFileException. (Caught in TagLib.Id3v2.Tag) + + * src/TagLib/Mpeg/AudioFile.cs: Limit scanning to only the first 0x4000 + bytes of the audio stream to avoid reading bad files forever. I got no + false negatives at 0x1000 so I'm hoping this is enough. If not, I can + throttle it up more. (Thanks to its-me for the bug report.) + + * configure.ac: Now 2.0.2.3 + + svn path=/trunk/taglib-sharp/; revision=83326 + +commit 10e4154a026075bd5d71bd037f420a29632fad42 +Author: Brian Nickel +Date: Sun Jul 29 19:13:12 2007 + + 2007-07-29 Brian Nickel + + * src/TagLib/CombinedTag.cs: Fully documented and replaced the protected + constructor with a public one, as it wasn't protecting anything and + causing a compiler error in Orcas. (Thanks to jmurphy for the bug + report.) + + * src/TagLib/ByteVectorList.cs: Reformatted code. I had beautiful + documentation, but MonoDevelop crashed. :( + + * src/TagLib/ByteVector.cs: Started documenting and adding some + exceptions rather than letting them occur in the underlying methods. + + * src/TagLib/ListBase.cs: Reformatted code. + + * src/TagLib/File.cs: Added total documentation. + + * src/TagLib/Debugger.cs: Reformatted code. + + * src/Makefile.am: + * Makefile.am: Added MonoDevelop files to EXTRA_DIST. (Thanks to jopsen + for pointing this out.) + + * configure.ac: Now 2.0.2.2 + + svn path=/trunk/taglib-sharp/; revision=82949 + +commit a97b7b6cb35ddf46e50ecd2f9b780ef884cb79f7 +Author: Brian Nickel +Date: Sun Jul 22 22:10:16 2007 + + 2007-07-22 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ogg/XiphComment.cs: Parse beats per minute as floating + point numbers, round them, and then convert them to uints. Values were + showing up as 0 if a decimal point was present. (Thanks to nokturnal for + the bug report.) + + * src/TagLib/ByteVector.cs: Switch back from "_data" to "data" + + * src/TagLib/ICodec.cs: Minor reorganization. + + * src/TagLib/Genres.cs: + * src/TagLib/Properties.cs: + * src/TagLib/SupportedMimeType.cs: + * src/TagLib/StringList.cs: + * src/TagLib/FileTypes.cs: + * src/TagLib/Tag.cs: + * src/TagLib/Picture.cs: + * src/TagLib/File.cs: + * src/TagLib/ReadOnlyByteVector.cs: Documentation. + + * configure.ac: Now 2.0.2.1 + + svn path=/trunk/taglib-sharp/; revision=82456 + +commit 0e14c9adc24e5ac99750969221919deb9bf8e3c5 +Author: Brian Nickel +Date: Tue Jul 3 16:55:49 2007 + + 2007-07-03 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 2.0.2 | + +-------------+ + + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: Fix docs. + * src/TagLib/File.cs: Some doc work. + * src/AssemblyInfo.cs.in: Conditionally sign the assembly. + * src/AssemblyInfo-windows.cs: DELETED. AssemblyInfo.cs.in is all that's + necessary. + * src/Makefile.am: Add distwin target + + * windows-files/TagLibSharpDocs.chm: Added. + + * configure.ac: Don't use svn revision because it is greater than + ushort.MaxValue. + + * Makefile.am: Add distwin target. + + * NEWS: Updated for new release. + + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Use AssemblyInfo.cs. + + svn path=/trunk/taglib-sharp/; revision=81300 + +commit 79cfd2193845680ba33239ed8caebcc557baadc4 +Author: Brian Nickel +Date: Wed Jun 27 14:24:22 2007 + + 2007-06-27 Brian Nickel + + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: Fixed reading problem + with UTF-16 encoded descriptions. (Thanks to renzska for the bug + report.) + + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: Use Mono + coding guidelines. + + * src/TagLib/Asf/File.cs: Added ReadObject and detection of + HeaderExtensionObject. + + * src/TagLib/TagLib.sources: Added HeaderExtensionObject.cs + + * src/TagLib/Asf/HeaderExtensionObject.cs: ADDED. This will be used to + store large objects in the future (pictures bigger than 64k). + + * src/TagLib/Asf/Guid.cs: Added GUID's for HeaderExtensionObject. + + * src/AssemblyInfo.cs.in: Cleaned up. + * src/AssemblyInfo-windows.cs: Cleaned up. + + * src/taglib-sharp.mdp: Added HeaderExtensionObject.cs + + * configure.ac: Removed extra line. + + * taglib-sharp.csproj: Added HeaderExtensionObject.cs + + svn path=/trunk/taglib-sharp/; revision=80908 + +commit d64cabf8b151ede0344b16993c3193bdf4a03faa +Author: Brian Nickel +Date: Tue Jun 26 17:18:51 2007 + + 2007-06-26 Brian Nickel + + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: Readd ToString. + + * src/TagLib/Mpeg/XingHeader.cs: Don't throw an exception just because + the header doesn't contain everything we want. + + * src/TagLib/Mpeg/AudioHeader.cs: Prevent infinite loop. (Thanks to + sambeckett for the bug report.) Add "VBR" to the description if a Xing + header is present. + + * tests/fixtures/TagLib.FormatTests/FlacFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V1FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V2FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/AsfFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3BothFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/OggFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/MpcFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/M4aFormatTest.cs: Use Performers + instead of Artists. + + svn path=/trunk/taglib-sharp/; revision=80824 + +commit 57a64ea15651bdff2590e848019b5a5756ee620a +Author: Brian Nickel +Date: Tue Jun 26 15:03:02 2007 + + 2007-06-26 Brian Nickel + + * src/TagLib/CorruptFileException.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/UnsupportedFormatException.cs: Added XML documentation. + + * src/TagLib/Tag.cs: Started XML documentation. Artists was pointing + nowhere. Pointed at Performers. + + * src/TagLib/ByteVector.cs: ByteVector.Find was not returning -1 if + searching at (data.Count == pattern.Count + offset). Caused extra '\0' + to appear in comment frames. (Thanks to gozza11 for the bug report.) + + * src/taglib-sharp.mdp: + + * configure.ac: Work with "make distcheck" + + * Makefile.am: Include "svn-version" in dist. + + svn path=/trunk/taglib-sharp/; revision=80813 + +commit 3d8229605f78912b8bc388caead7477d10a79075 +Author: Brian Nickel +Date: Mon Jun 25 04:14:11 2007 + + 2007-06-25 Brian Nickel + + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: Set to this.data instead of + data in constructor. Thanks to pipes for the bug report.) + + * configure.ac: Make the fourth part of the assembly version equal to + the SVN revision. + + svn path=/trunk/taglib-sharp/; revision=80676 + +commit 47b75955913dfaf484f41a67cc5e4e884c6acd23 +Author: Brian Nickel +Date: Mon Jun 25 00:00:24 2007 + + 2007-06-24 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 2.0.1 | + +-------------+ + + * src/AssemblyInfo.cs.in: + * configure.ac: + * src/Makefile.am: + * src/policy.2.0.taglib-sharp.config.in: Install a policy in GAC so + assemblies compiled against older versions use 2.0.1.0. + * src/AssemblyInfo-windows.cs: Version bump. + * NEWS: Information on new release. + + svn path=/trunk/taglib-sharp/; revision=80664 + +commit 9a88cb7cb9b4eae8420bdd20027d897b2d9e0a33 +Author: Brian Nickel +Date: Sun Jun 24 13:25:16 2007 + + 2007-06-24 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: Fixed bug in commit from 2007-06-20. + TPE2 and TPE1 were being swapped when they were stored. (Thanks to + jmurphy for the but report.) + + svn path=/trunk/taglib-sharp/; revision=80640 + +commit 6d4d454d1c8b261e5727f76ef8ccdb5c2f63b194 +Author: Brian Nickel +Date: Sun Jun 24 13:09:19 2007 + + 2007-06-24 Brian Nickel + + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: Split the string into 3 + pieces instead of 2. This way nil delimiters and badly formatted strings + don't mess up the value. (Thanks to gozza11 for the but report.) + + svn path=/trunk/taglib-sharp/; revision=80639 + +commit 9822af3a64b57f64c4371657a27a7d9aac65182d +Author: Brian Nickel +Date: Fri Jun 22 13:55:23 2007 + + 2007-06-22 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: Remove picture frames if Picture is set to + null or an empty array. (Thanks to wilson for the but report.) + + svn path=/trunk/taglib-sharp/; revision=80569 + +commit c93afd260939a6fd9616e7ba22a186c0e13e3514 +Author: Brian Nickel +Date: Wed Jun 20 16:12:06 2007 + + 2007-06-20 Brian Nickel + + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Asf/Tag.cs: Don't return Performers if AlbumArtists is not + found. This, provided with the second to last commit should resolve + inconsistancies in the behaviour. (Thanks to JustinC for the bug + report, otherwise that travesty that is the previous implementation may + have gone on forever.) + + * src/TagLib/Tag.cs: Fix typos. + + svn path=/trunk/taglib-sharp/; revision=80366 + +commit aebd6b8ec644a70946a1d880ffc2cd16f0752004 +Author: Brian Nickel +Date: Wed Jun 20 15:49:35 2007 + + 2007-06-20 Brian Nickel + + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Use + ByteVector.TextDelimiter instead of Frame.TextDelimiter. + + * src/TagLib/Id3v2/Frame.cs: Mark TextDelimiter as obsolete. + * src/TagLib/ByteVector.cs: Add TextDelimiter method. + + * src/TagLib/Asf/Tag.cs: Discard new pictures if their rendered size is + greater than 64KB to avoid corrupting files. (Thanks to renzska for the + bug report.) + + svn path=/trunk/taglib-sharp/; revision=80364 + +commit 0825a9eff914087b1140c62510af9d5e52233ad6 +Author: Brian Nickel +Date: Wed Jun 20 13:53:22 2007 + + 2007-06-20 Brian Nickel + + * src/TagLib/Id3v1/Tag.cs: Rework to match Picard specs. + + * src/TagLib/Riff/DivXTag.cs: Rework to match Picard specs. + + * src/TagLib/Riff/MovieIdTag.cs: Rework to match Picard specs. + + * src/TagLib/Id3v2/Tag.cs: Rework to match Picard specs. + + * src/TagLib/Ape/Tag.cs: Rework to match Picard specs. + + * src/TagLib/Ogg/XiphComment.cs: Rework to match Picard specs. + + * src/TagLib/Tag.cs: Added JoinedAlbumArtists and FirstAlbumArtist. + Changed JoinedArtists and FirstArtist to point to Performers (marked as + obsolete), and added Artists which points to Performers (also obsolete). + This should aleviate confusion. + + svn path=/trunk/taglib-sharp/; revision=80346 + +commit 53d5e285be01c51179b2efdd3043c096d5b7aa12 +Author: Brian Nickel +Date: Tue Jun 12 22:06:22 2007 + + 2007-06-12 Brian Nickel + + * src/TagLib/Mpeg4/File.cs: Fix support for writing files that don't + have UTDA tags. (Thanks to renzska for the bug report.) + + * src/TagLib/Mpeg4/Box.cs: Fix support for clearing boxes. (Thanks to + maciej for the bug report.) Calculate padding size based on DataSize + rather than header.DataSize. Fixes problem where 4 bytes are added on + every save. (Discovered in bug report by lindea.) + + * src/TagLib/Riff/WaveFormatEx.cs: Recognize WMA Lossless. (Thanks to + JustinC for the patch.) + + * ALSO: Thanks to JustinC for reminding me to credit people for their + contributions. With the countless audio and video files in existence, + TagLib# would be far less complete and considerably buggier if not for + everyone's contributions. Thank you! + + svn path=/trunk/taglib-sharp/; revision=79373 + +commit ade972de4e7356cdc8cf795f7ba53e50362cc556 +Author: Brian Nickel +Date: Mon Jun 11 11:25:26 2007 + + 2007-06-11 Brian Nickel + + * src/TagLib/Ogg/Paginator.cs: Fix save support in OGG. Thanks to + maciej for pointing this out. + + * NEWS: Added NEWS file. + + svn path=/trunk/taglib-sharp/; revision=79189 + +commit c0ddc28818c88bf1233c08f5b3eec7636b457fcb +Author: Brian Nickel +Date: Sun Jun 10 23:17:48 2007 + + This one got away. + + svn path=/trunk/taglib-sharp/; revision=79141 + +commit 2d1b94fdcae2bb96ae99b8d92ede76785be36a16 +Author: Brian Nickel +Date: Sun Jun 10 23:16:26 2007 + + 2007-06-10 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 2.0.0 | + +-------------+ + + The official announcement, tarballs, and excessive drinking will come + tomorrow after I get Windows documentation in order. In the mean time + I'll tidy up the site a bit. + + * src/TagLib/Id3v2/Tag.cs: Combine TYER, TDAT, and TIME into a single + TDRC, rather than discarding TDAT and TIME. + + * src/TagLib/Id3v2/FrameTypes.cs: Add some more types. + + * src/TagLib/Id3v2/FrameFactory.cs: Change for renamed frames. + + * src/TagLib/Id3v2/FrameHeader.cs: Don't discard TIME and TDAT. + + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: Remove SetText. + It is redundant and identical to set_Text. + + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: Remove SetText. It is + redundant and identical to set_Text. + + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: Rename + MusicCdIdentifier to MusicCdIdentiferFrame. I don't know how I made that + mistake. + + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: Remove SetText. It is + redundant and identical to set_Text. + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Rename to + TextInformationFrame to better reflect specification. (Text + Identification frame is a subset of Text Information Frame). Split TDRC + into TYER, TDAT, and TIME if saving as version 2.3. + + * src/TagLib/Id3v2/Frame.cs: Make Render virtual to allow for more + robust features. (Applied in TextInformationFrame.) + + * src/TagLib/ByteVector.cs: Fix typo. + + * src/TagLib/Ape/Tag.cs: Make enumerable. + + * src/TagLib/Mpeg4/Box.cs: Remove GetChild(System.Type), as all other + System.Type based functionality has been removed. + + * src/AssemblyInfo-windows.cs: Version bump. + + * configure.ac: Version bump. Remove unit tests to shrink tarball. + + * Makefile.am: Remove unit tests to shrink tarball. + + svn path=/trunk/taglib-sharp/; revision=79140 + +commit 431bae630b26d16cf932513a1ecb6363c13ee3d8 +Author: Brian Nickel +Date: Sun Jun 10 23:03:03 2007 + + 2007-06-10 Brian Nickel + + * docs/*: Get 100% caught up. + + svn path=/trunk/taglib-sharp/; revision=79138 + +commit c64d9fe099276baf58844658bf55b24cf00d39a9 +Author: Brian Nickel +Date: Thu Jun 7 16:35:01 2007 + + 2007-06-07 Brian Nickel + + * src/TagLib/CombinedTag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Id3v1/Tag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Riff/File.cs: Use ReadOnlyByteVector. + * src/TagLib/Riff/DivXTag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Riff/ListTag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Footer.cs: + * src/TagLib/Id3v2/FrameTypes.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/Id3v2/Frame.cs: Use TagLib.Id3v2.FrameType instead of hard- + coding. Cuts out a lot of read time. + * src/TagLib/Flac/File.cs: Use ReadOnlyByteVector. + * src/TagLib/Flac/Block.cs: BlockSize instead of Size. + * src/TagLib/Ape/Tag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Ape/Footer.cs: Use ReadOnlyByteVector. + * src/TagLib/Ape/Item.cs: Use ReadOnlyByteVector. + * src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs:Don't parse text + before its needed. + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: Don't do extra seeks. + * src/TagLib/Mpeg4/FileParser.cs: Use do/while instead of for. Was doing + extra reading. + * src/TagLib/Mpeg4/AppleTag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Mpeg4/BoxTypes.cs: Make internal. + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/Box.cs: Rename "BoxTypes" to "BoxType" + * src/TagLib/Mpc/StreamHeader.cs: Use ReadOnlyByteVector + * src/TagLib/Tag.cs: Add Tag.Clear + * src/TagLib/File.cs: Do away with ReadBlock(uint) + * src/TagLib/WavPack/StreamHeader.cs: Use ReadOnlyByteVector. + * src/TagLib/Asf/Tag.cs: Add Tag.Clear, Tag.IsEmpty + * src/TagLib/Asf/ContentDescriptionObject.cs: Add IsEmpty + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: Add IsEmpty + * src/TagLib/Ogg/XiphComment.cs: Add Tag.Clear + * src/TagLib/Ogg/PageHeader.cs: Use ReadBlock(int) + * src/TagLib/Ogg/GroupedComment.cs: Add Tag.Clear + * docs/en/TagLib.Riff/DivXTag.xml + * docs/en/TagLib.Riff/File.xml + * docs/en/TagLib.Id3v1/Tag.xml + * docs/en/TagLib.Id3v2/Header.xml + * docs/en/TagLib.Id3v2/Frame.xml + * docs/en/TagLib.Id3v2/Footer.xml + * docs/en/TagLib.Id3v2/FrameHeader.xml + * docs/en/TagLib.Mpeg/AudioFile.xml + * docs/en/TagLib.Mpeg/File.xml + * docs/en/TagLib.WavPack/StreamHeader.xml + * docs/en/TagLib.WavPack/File.xml + * docs/en/TagLib/Tag.xml + * docs/en/TagLib/File.xml + * docs/en/index.xml + * docs/en/TagLib.Flac/Metadata.xml + * docs/en/TagLib.Flac/Block.xml + * docs/en/TagLib.Flac/File.xml + * docs/en/TagLib.Ape/Tag.xml + * docs/en/TagLib.Ape/Footer.xml + * docs/en/TagLib.MusePack/StreamHeader.xml + * docs/en/TagLib.MusePack/File.xml + * docs/en/TagLib.Asf/ContentDescriptionObject.xml + * docs/en/TagLib.Asf/ExtendedContentDescriptionObject.xml + * docs/en/TagLib.Asf/Tag.xml + * docs/en/TagLib.Asf/File.xml + * docs/en/TagLib.Ogg/GroupedComment.xml + * docs/en/TagLib.Ogg/XiphComment.xml + * docs/en/TagLib.Ogg/File.xml + * docs/en/TagLib.Mpeg4/Box.xml + * docs/en/TagLib.Mpeg4/AppleTag.xml + * docs/en/TagLib.Mpeg4/BoxTypes.xml + * docs/en/TagLib.Mpeg4/File.xml: Synched docs. + + svn path=/trunk/taglib-sharp/; revision=78896 + +commit 781f167791ed0fcb5ebae418ca57b1721b66a847 +Author: Brian Nickel +Date: Mon Jun 4 13:12:47 2007 + + 2007-06-04 Brian Nickel + + * src/TagLib/Mpeg/File.cs: Prevent overflow. + * src/TagLib/Mpc/File.cs: Add support for "mpp" extention. + + svn path=/trunk/taglib-sharp/; revision=78577 + +commit f912417fdc8ba070b5ab92bf17e7432cf3140fd9 +Author: Brian Nickel +Date: Fri Jun 1 19:32:07 2007 + + 2007-06-01 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 1.9.99995 | + +-------------+ + + * examples/SetPictures.cs: Fix for API changes. + * src/TagLib/ByteVector.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/TagLib.sources: + * src/TagLib/ReadOnlyByteVector.cs: + * src/taglib-sharp.mdp: + * docs/en/TagLib/ReadOnlyByteVector.xml: + * docs/en/TagLib/ByteVector.xml: + * docs/en/index.xml: + * docs/en/TagLib.Mpeg4/BoxTypes.xml: + * taglib-sharp.csproj: Add immutable ReadOnlyByteVector. + + svn path=/trunk/taglib-sharp/; revision=78468 + +commit 080958d362c0a7da9fe1dea205f7d38a5e87bf34 +Author: Brian Nickel +Date: Wed May 30 23:38:18 2007 + + 2007-05-30 Brian Nickel + + Redid a lot of the internals of FLAC to make them cleaner. Reverted the + change to TagLib.Mpeg4.BoxTypes. The change was safer but slowed things + down by 1.7329ms. Perhaps the addition of a superclass, + ImmutableByteVector, would help. + + * src/TagLib/Flac/Picture.cs + * src/TagLib/Flac/File.cs + * src/TagLib/Flac/BlockHeader.cs + * src/TagLib/Flac/Block.cs + * src/TagLib/Mpeg4/BoxTypes.cs + * docs/en/index.xml + * docs/en/TagLib.Flac/Metadata.xml + * docs/en/TagLib.Flac/BlockHeader.xml + * docs/en/TagLib.Flac/Block.xml + * docs/en/TagLib.Mpeg4/BoxTypes.xml: + + svn path=/trunk/taglib-sharp/; revision=78296 + +commit 0f13f9425a1cbb030e8bdf295fe4c580adb71eee +Merge: 9bb2e24 ca311e4 +Author: Brian Nickel +Date: Wed May 30 18:47:16 2007 + + 2007-05-30 Brian Nickel + + Major API changes. The API has been changed a bunch to accommodate + Microsoft naming rules, globalization rules, etc. Hundreds of issues + brought to light by FxCop. Nothing like throwing a hundred + ArgumentNullExceptions, changing "h" to "Header", + "last_absolute_granular_position" to "lastAbsoluteGranularPosition", + "StringList" to "StringCollection", etc. + + Another major change is the dropping of + TagLib.File.{Push|Pop|Set|Default}FileAbstractionCreator. Now if you + want to create a local file, use TagLib.File.Create (string) and if you + want to use a stream, or a VFS, or whatever, use + TagLib.File.Create(File.IFileAbstraction). This should save a lot of + headache and make things a lot safer and cleaner. Sorry to those of you + who were using the old API. + + I've got a few hundred docs to fill in, but then it's 2.0 RC2. + + * src/TagLib/Mpc/File.cs + * src/TagLib/Mpc/StreamHeader.cs + * src/TagLib/Tag.cs + * src/TagLib/Picture.cs + * src/TagLib/CombinedTag.cs + * src/TagLib/CorruptFileException.cs + * src/TagLib/File.cs + * src/TagLib/UnsupportedFormatException.cs + * src/TagLib/TagLib.sources + * src/TagLib/ByteVectorList.cs + * src/TagLib/Id3v1/Tag.cs + * src/TagLib/Id3v1/StringHandler.cs + * src/TagLib/Riff/List.cs + * src/TagLib/Riff/AviStream.cs + * src/TagLib/Riff/File.cs + * src/TagLib/Riff/BitmapInfoHeader.cs + * src/TagLib/Riff/AviHeaderList.cs + * src/TagLib/Riff/DivXTag.cs + * src/TagLib/Riff/ListTag.cs + * src/TagLib/Riff/InfoTag.cs + * src/TagLib/Riff/MovieIdTag.cs + * src/TagLib/Riff/WaveFormatEx.cs + * src/TagLib/Genres.cs + * src/TagLib/Id3v2/Tag.cs + * src/TagLib/Id3v2/Footer.cs + * src/TagLib/Id3v2/SynchData.cs + * src/TagLib/Id3v2/FrameFactory.cs + * src/TagLib/Id3v2/FrameHeader.cs + * src/TagLib/Id3v2/Header.cs + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs + * src/TagLib/Id3v2/Frames/CommentsFrame.cs + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs + * src/TagLib/Id3v2/Frames/PrivateFrame.cs + * src/TagLib/Id3v2/Frames/MusicCdIdentifierFrame.cs + * src/TagLib/Id3v2/Frames/TermsOfUseFrame.cs + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs + * src/TagLib/Id3v2/Frames/UnknownFrame.cs + * src/TagLib/Id3v2/ExtendedHeader.cs + * src/TagLib/Id3v2/Frame.cs + * src/TagLib/Debugger.cs + * src/TagLib/Mpeg/XingHeader.cs + * src/TagLib/Mpeg/File.cs + * src/TagLib/Mpeg/VideoHeader.cs + * src/TagLib/Mpeg/AudioFile.cs + * src/TagLib/Mpeg/AudioHeader.cs + * src/TagLib/ByteVector.cs + * src/TagLib/IntList.cs + * src/TagLib/ICodec.cs + * src/TagLib/WavPack/File.cs + * src/TagLib/WavPack/StreamHeader.cs + * src/TagLib/NonContainer/File.cs + * src/TagLib/NonContainer/EndTag.cs + * src/TagLib/NonContainer/StartTag.cs + * src/TagLib/Properties.cs + * src/TagLib/SupportedMimeType.cs + * src/TagLib/Ape/Tag.cs + * src/TagLib/Ape/Footer.cs + * src/TagLib/Ape/Item.cs + * src/TagLib/Flac/Picture.cs + * src/TagLib/Flac/File.cs + * src/TagLib/Flac/BlockHeader.cs + * src/TagLib/Flac/StreamHeader.cs + * src/TagLib/Flac/Block.cs + * src/TagLib/StringList.cs + * src/TagLib/Asf/Tag.cs + * src/TagLib/Asf/File.cs + * src/TagLib/Asf/HeaderObject.cs + * src/TagLib/Asf/StreamPropertiesObject.cs + * src/TagLib/Asf/FilePropertiesObject.cs + * src/TagLib/Asf/ContentDescriptionObject.cs + * src/TagLib/Asf/Object.cs + * src/TagLib/Asf/UnknownObject.cs + * src/TagLib/Asf/ContentDescriptor.cs + * src/TagLib/ListBase.cs + * src/TagLib/Mpeg4/Boxes/FullBox.cs + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs + * src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs + * src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs + * src/TagLib/Mpeg4/Boxes/IsoFreeSpaceBox.cs + * src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs + * src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs + * src/TagLib/Mpeg4/Boxes/AppleDataBox.cs + * src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs + * src/TagLib/Mpeg4/Boxes/UnknownBox.cs + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs + * src/TagLib/Mpeg4/FileParser.cs + * src/TagLib/Mpeg4/AppleTag.cs + * src/TagLib/Mpeg4/BoxTypes.cs + * src/TagLib/Mpeg4/File.cs + * src/TagLib/Mpeg4/BoxFactory.cs + * src/TagLib/Mpeg4/BoxHeader.cs + * src/TagLib/Mpeg4/BoxList.cs + * src/TagLib/Mpeg4/Box.cs + * src/TagLib/Ogg/XiphComment.cs + * src/TagLib/Ogg/Page.cs + * src/TagLib/Ogg/Codecs/Theora.cs + * src/TagLib/Ogg/Codecs/Vorbis.cs + * src/TagLib/Ogg/Codec.cs + * src/TagLib/Ogg/File.cs + * src/TagLib/Ogg/Paginator.cs + * src/TagLib/Ogg/PageHeader.cs + * src/TagLib/Ogg/GroupedComment.cs + * src/TagLib/Ogg/Bitstream.cs + * src/AssemblyInfo.cs.in + * src/AssemblyInfo-windows.cs + * src/taglib-sharp.mdp + * docs/en/TagLib.Riff/BitmapInfoHeader.xml + * docs/en/TagLib.Riff/AviHeaderList.xml + * docs/en/TagLib.Riff/DivXTag.xml + * docs/en/TagLib.Riff/ListTag.xml + * docs/en/TagLib.Riff/WaveFormatEx.xml + * docs/en/TagLib.Riff/AviStream.xml + * docs/en/TagLib.Riff/List.xml + * docs/en/TagLib.Riff/File.xml + * docs/en/TagLib.Id3v1/StringHandler.xml + * docs/en/TagLib.Id3v1/Tag.xml + * docs/en/TagLib.Id3v2/UniqueFileIdentifierFrame.xml + * docs/en/TagLib.Id3v2/AttachedPictureFrame.xml + * docs/en/TagLib.Id3v2/PrivateFrame.xml + * docs/en/TagLib.Id3v2/Header.xml + * docs/en/TagLib.Id3v2/PlayCountFrame.xml + * docs/en/TagLib.Id3v2/Frame.xml + * docs/en/TagLib.Id3v2/MusicCdIdentifier.xml + * docs/en/TagLib.Id3v2/Footer.xml + * docs/en/TagLib.Id3v2/CommentsFrame.xml + * docs/en/TagLib.Id3v2/TermsOfUseFrame.xml + * docs/en/TagLib.Id3v2/GeneralEncapsulatedObjectFrame.xml + * docs/en/TagLib.Id3v2/UserTextIdentificationFrame.xml + * docs/en/TagLib.Id3v2/SynchronisedLyricsFrame.xml + * docs/en/TagLib.Id3v2/TextIdentificationFrame.xml + * docs/en/TagLib.Id3v2/UnknownFrame.xml + * docs/en/TagLib.Id3v2/Tag.xml + * docs/en/TagLib.Id3v2/UnsynchronisedLyricsFrame.xml + * docs/en/TagLib.Id3v2/RelativeVolumeFrame.xml + * docs/en/TagLib.Mpeg/Marker.xml + * docs/en/TagLib.Mpeg/AudioFile.xml + * docs/en/TagLib.Mpeg/Version.xml + * docs/en/TagLib.Mpeg/AudioHeader.xml + * docs/en/TagLib.Mpeg/XingHeader.xml + * docs/en/TagLib.Mpeg/VideoHeader.xml + * docs/en/TagLib.Mpeg/File.xml + * docs/en/TagLib.WavPack/StreamHeader.xml + * docs/en/TagLib.WavPack/File.xml + * docs/en/TagLib.NonContainer/File.xml + * docs/en/TagLib/UnsupportedFormatException.xml + * docs/en/TagLib/Genres.xml + * docs/en/TagLib/IntList.xml + * docs/en/TagLib/ListBase`1.xml + * docs/en/TagLib/SupportedMimeType.xml + * docs/en/TagLib/File+LocalFileAbstraction.xml + * docs/en/TagLib/ByteVectorCollection.xml + * docs/en/TagLib/MediaTypes.xml + * docs/en/TagLib/Picture.xml + * docs/en/TagLib/File.xml + * docs/en/TagLib/ByteVectorList.xml + * docs/en/TagLib/StringCollection.xml + * docs/en/TagLib/ByteVector.xml + * docs/en/TagLib/TagTypes.xml + * docs/en/TagLib/StringList.xml + * docs/en/TagLib/PictureType.xml + * docs/en/TagLib/CorruptFileException.xml + * docs/en/TagLib/File+FileTypeResolver.xml + * docs/en/index.xml + * docs/en/TagLib.Flac/BlockHeader.xml + * docs/en/TagLib.Flac/StreamHeader.xml + * docs/en/TagLib.Flac/Block.xml + * docs/en/TagLib.Flac/BlockType.xml + * docs/en/TagLib.Flac/File.xml + * docs/en/TagLib.Ape/Tag.xml + * docs/en/TagLib.Ape/FooterFlags.xml + * docs/en/TagLib.Ape/Footer.xml + * docs/en/TagLib.Ape/Item.xml + * docs/en/TagLib.MusePack/StreamHeader.xml + * docs/en/TagLib.MusePack/File.xml + * docs/en/TagLib.Asf/Object.xml + * docs/en/TagLib.Asf/ContentDescriptor.xml + * docs/en/TagLib.Asf/StreamPropertiesObject.xml + * docs/en/TagLib.Asf/HeaderObject.xml + * docs/en/TagLib.Asf/File.xml + * docs/en/TagLib.Ogg/PageHeader.xml + * docs/en/TagLib.Ogg/GroupedComment.xml + * docs/en/TagLib.Ogg/Bitstream.xml + * docs/en/TagLib.Ogg/XiphComment.xml + * docs/en/TagLib.Ogg/Page.xml + * docs/en/TagLib.Ogg/Codec.xml + * docs/en/TagLib.Ogg/File.xml + * docs/en/TagLib.Mpeg4/BoxFactory.xml + * docs/en/TagLib.Mpeg4/IsoFreeSpaceBox.xml + * docs/en/TagLib.Mpeg4/BoxList.xml + * docs/en/TagLib.Mpeg4/AppleItemListBox.xml + * docs/en/TagLib.Mpeg4/Box.xml + * docs/en/TagLib.Mpeg4/IsoUserDataBox.xml + * docs/en/TagLib.Mpeg4/FileParser.xml + * docs/en/TagLib.Mpeg4/AppleTag.xml + * docs/en/TagLib.Mpeg4/AppleDataBox+FlagTypes.xml + * docs/en/TagLib.Mpeg4/IsoAudioSampleEntry.xml + * docs/en/TagLib.Mpeg4/BoxHeader.xml + * docs/en/TagLib.Mpeg4/IsoHandlerBox.xml + * docs/en/TagLib.Mpeg4/IsoVisualSampleEntry.xml + * docs/en/TagLib.Mpeg4/AppleElementaryStreamDescriptor.xml + * docs/en/TagLib.Mpeg4/IsoChunkOffsetBox.xml + * docs/en/TagLib.Mpeg4/AppleDataBox.xml + * docs/en/TagLib.Mpeg4/AppleAnnotationBox.xml + * docs/en/TagLib.Mpeg4/UnknownBox.xml + * docs/en/TagLib.Mpeg4/IsoSampleDescriptionBox.xml + * docs/en/TagLib.Mpeg4/IsoMetaBox.xml + * docs/en/TagLib.Mpeg4/FullBox.xml + * docs/en/TagLib.Mpeg4/AppleDataBox+FlagType.xml + * docs/en/TagLib.Mpeg4/IsoMovieHeaderBox.xml + * docs/en/TagLib.Mpeg4/IsoSampleTableBox.xml + * docs/en/TagLib.Mpeg4/BoxTypes.xml + * docs/en/TagLib.Mpeg4/IsoChunkLargeOffsetBox.xml + * docs/en/TagLib.Mpeg4/IsoSampleEntry.xml + * docs/en/TagLib.Mpeg4/AppleAdditionalInfoBox.xml + * docs/en/TagLib.Mpeg4/File.xml + * tests/tests.mdp + * tests/fixtures/TagLib.CollectionTests/ByteVectorListTest.cs + * tests/fixtures/TagLib.CollectionTests/StringListTest.cs + * tests/fixtures/TagLib.CollectionTests/ByteVectorCollectionTest.cs + * tests/fixtures/TagLib.CollectionTests/StringCollectionTest.cs + * tests/fixtures/TagLib.CollectionTests/ByteVectorTest.cs + * configure.ac + * taglib-sharp.csproj + * examples/ReadFromUri.cs + * examples/muine-use-taglibsharp.patch: Aye Aye Aye! + + svn path=/trunk/taglib-sharp/; revision=78279 + +commit 9bb2e24e3d665c8bb5e258104148765603f650fd +Author: Brian Nickel +Date: Fri May 25 15:20:09 2007 + + 2007-05-25 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 1.9.99994 | + +-------------+ + + * src/TagLib/TagLib.sources: Remove debugger. + * src/TagLib/Mpeg/AudioHeader.cs: Compile on Windows. + * docs/en/TagLib.Riff/File.xml: + * docs/en/TagLib.Mpeg/AudioFile.xml: + * docs/en/TagLib.Mpeg/File.xml: + * docs/en/TagLib.WavPack/File.xml: + * docs/en/index.xml: + * docs/en/TagLib.Flac/File.xml: + * docs/en/TagLib.MusePack/File.xml: + * docs/en/TagLib.Asf/File.xml: + * docs/en/TagLib.Ogg/File.xml: + * docs/en/TagLib.Mpeg4/File.xml: Fixed tpos. + * docs/Makefile.am: Change target. + * configure.ac: Version bump. + * taglib-sharp.csproj: Add missing files. + + svn path=/trunk/taglib-sharp/; revision=77970 + +commit 0a1d5a196b71588470cc829bd8d91ceae7b35c63 +Author: Brian Nickel +Date: Fri May 25 06:03:46 2007 + + 2007-05-25 Brian Nickel + + There were changes to 153 files in the last three days. I can't vouch for + everything that happened, as I may have blacked out for some portions, but tags + now have an abstract Tag.TagTypes property, Everything that should be a struct + is, there were a bunch of tiny cleanups, "private Flac.File+PictureTag" is now + "public Flac.Metadata"... And as of 3:55 AM (Arizona Time), THERE IS NOT ONE + FREAKIN' INSTANCE OF "To be added." IN THE ENTIRE docs/en DIRECTORY. I really + must love you guys, 'cause that was really, really painful. + + * src/TagLib/Tag.cs: + * src/TagLib/CombinedTag.cs: + * src/TagLib/File.cs: + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/Id3v2/ExtendedHeader.cs: + * src/TagLib/Mpeg/XingHeader.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/AudioFile.cs: + * src/TagLib/Mpeg/AudioHeader.cs: + * src/TagLib/NonContainer/Tag.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Flac/Picture.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Flac/StreamHeader.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleDataBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/BoxList.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/Page.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: + * src/TagLib/Ogg/Codec.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Paginator.cs: + * src/TagLib/Ogg/GroupedComment.cs: + * src/TagLib/Ogg/Bitstream.cs: + * src/taglib-sharp.mdp: 53 C# files changed. + * docs/en/*: 100 XML files filled in. + + svn path=/trunk/taglib-sharp/; revision=77938 + +commit ac6636ace1213b12802e5e72f1ccf16024712c11 +Author: Brian Nickel +Date: Tue May 22 18:54:32 2007 + + 2007-05-22 Brian Nickel + + * src/TagLib/Tag.cs: Make abstract. + * src/TagLib/Mpc/File.cs: Make namespace "MusePack". + * src/TagLib/Mpc/StreamHeader.cs: Convert to struct. + * src/TagLib/File.cs: Store TagTypes as uint. Remove unused read styles. + Add File.TagTypes and File.TagTypesOnDisk. Add CloseStream to + IFileAbstraction for SilverLight support. + * src/TagLib/Riff/File.cs: Add TagTypes. + * src/TagLib/ByteVectorList.cs: Remove ToByteVector() + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Footer.cs: + * src/TagLib/Id3v2/SynchData.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/Id3v2/Frames/PlayCountFrame.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: + * src/TagLib/Id3v2/Frame.cs: Significant refactoring. Use byte for + version. Use enums for header and frame flags. Use string for language. + Unsupported frames and frame properties throw NotImplementedException. + Added PlayCountFrame. + * src/TagLib/Mpeg/XingHeader.cs: Make struct. + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/VideoHeader.cs: Make struct. + * src/TagLib/Mpeg/AudioFile.cs: + * src/TagLib/Mpeg/AudioHeader.cs: Make struct. + * src/TagLib/Debugger.cs: Make internal. + * src/TagLib/ByteVector.cs: Clean up constructors. + * src/TagLib/IntList.cs: Clean up constructors. + * src/TagLib/WavPack/StreamHeader.cs: Convert to struct. + * src/TagLib/NonContainer/Tag.cs: Add TagTypes. + * src/TagLib/NonContainer/File.cs: Add TagTypes. + * src/TagLib/NonContainer/EndTag.cs: Add TagTypes. + * src/TagLib/NonContainer/StartTag.cs: Add TagTypes. + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: Make struct. Use enum for flags. + * src/TagLib/Flac/File.cs: + * src/TagLib/Flac/BlockHeader.cs: Make struct. + * src/TagLib/Flac/StreamHeader.cs: Make struct. + * src/TagLib/StringList.cs: Clean up constructors. + * src/TagLib/FileTypes.cs: Add support for registering types. + * src/TagLib/Asf/File.cs: Add TagTypes. + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/Object.cs: + * src/TagLib/Asf/Guid.cs: Use System.Guid. + * src/TagLib/Asf/ContentDescriptor.cs: Use unsigned types. + * src/TagLib/ListBase.cs: Clean up constructors. + * src/TagLib/Mpeg4/File.cs: Add TagTypes. + * src/TagLib/Ogg/GroupedComment.cs: Add IsEmpty. + * src/TagLib/Ogg/File.cs: Add TagTypes. + * src/TagLib/Ogg/Page.cs: + * src/TagLib/Ogg/Paginator.cs: + * src/TagLib/Ogg/Bitstream.cs: + * src/TagLib/Ogg/PageHeader.cs: Make PageHeader a struct and add + PageFlags. + * docs/en/*: Thousands more docs filled out. + + svn path=/trunk/taglib-sharp/; revision=77818 + +commit ca311e4c9a676b7e8169eb9f831acfe2eff3ef05 +Author: Brian Nickel +Date: Sun May 20 05:38:01 2007 + + 2007-05-20 Brian Nickel + + * src/TagLib/ByteVector.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: Remove accidental + System.Console.WriteLine lines. + * src/TagLib/File.cs: Make constructor protected. + * src/TagLib/Ogg/File.cs: + * src/TagLib/Riff/File.cs: Add File(string) constructor. + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/WaveFormatEx.cs: Tidy up. + * src/TagLib/Id3v2/Frame.cs: Parse was redundant. + * src/TagLib/Mpeg/AudioHeader.cs: Make stream_length private. + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: Make constructors private. + * docs/en/TagLib.Mpc/StreamHeader.xml: + * docs/en/TagLib.Mpc/File.xml: + * docs/en/TagLib.Riff.xml: + * docs/en/TagLib.Riff/BitmapInfoHeader.xml: + * docs/en/TagLib.Riff/InfoTag.xml: + * docs/en/TagLib.Riff/ListTag.xml: + * docs/en/TagLib.Riff/AviHeader.xml: + * docs/en/TagLib.Riff/MovieIdTag.xml: + * docs/en/TagLib.Riff/WaveFormatEx.xml: + * docs/en/TagLib.Riff/List.xml: + * docs/en/TagLib.Riff/File.xml: + * docs/en/TagLib.Id3v2/UniqueFileIdentifierFrame.xml: + * docs/en/TagLib.Id3v2/AttachedPictureFrame.xml: + * docs/en/TagLib.Id3v2/PrivateFrame.xml: + * docs/en/TagLib.Id3v2/Frame.xml: + * docs/en/TagLib.Id3v2/CommentsFrame.xml: + * docs/en/TagLib.Id3v2/UserTextIdentificationFrame.xml: + * docs/en/TagLib.Id3v2/GeneralEncapsulatedObjectFrame.xml: + * docs/en/TagLib.Id3v2/SynchronisedLyricsFrame.xml: + * docs/en/TagLib.Id3v2/TextIdentificationFrame.xml: + * docs/en/TagLib.Id3v2/UnknownFrame.xml: + * docs/en/TagLib.Id3v2/UnsynchronisedLyricsFrame.xml: + * docs/en/TagLib.Id3v2/RelativeVolumeFrame.xml: + * docs/en/TagLib.Mpeg/AudioFile.xml: + * docs/en/TagLib.Mpeg/AudioHeader.xml: + * docs/en/TagLib.Mpeg/VideoHeader.xml: + * docs/en/TagLib.Mpeg/File.xml: + * docs/en/TagLib.WavPack/StreamHeader.xml: + * docs/en/TagLib.WavPack/File.xml: + * docs/en/TagLib.NonContainer/File.xml: + * docs/en/TagLib/ICodec.xml: + * docs/en/TagLib/Properties.xml: + * docs/en/TagLib/IAudioCodec.xml: + * docs/en/TagLib/IVideoCodec.xml: + * docs/en/TagLib/File.xml: + * docs/en/TagLib.Flac/StreamHeader.xml: + * docs/en/TagLib.Flac/File.xml: + * docs/en/TagLib.Asf/File.xml: + * docs/en/TagLib.Ogg.Codecs/Theora.xml: + * docs/en/TagLib.Ogg.Codecs/Vorbis.xml: + * docs/en/TagLib.Ogg/Codec.xml: + * docs/en/TagLib.Ogg/File.xml: + * docs/en/TagLib.Mpeg4/IsoAudioSampleEntry.xml: + * docs/en/TagLib.Mpeg4/IsoVisualSampleEntry.xml: + * docs/en/TagLib.Mpeg4/IsoMovieHeaderBox.xml: + * docs/en/TagLib.Mpeg4/File.xml: Filled out some docs, baby. + + svn path=/trunk/taglib-sharp/; revision=77712 + +commit 8006975cc50d25c3e256d64b9778c6eb76840231 +Author: Brian Nickel +Date: Sat May 19 01:39:32 2007 + + 2007-05-18 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 1.9.99993 | + +-------------+ + + * src/TagLib/TagLib.sources: Fixed typo. + * src/TagLib/ByteVector.cs: Fix for reading nil-separated UTF-16 + strings. Now StringTypeToEncoding assumes the previously used UTF-16 + endianness if a BOM is not found. Additionally, Find and RFind now base + byte align on distance from the original offset, not offset from start. + * src/TagLib/WavPack/File.cs: + * src/TagLib/WavPack/StreamHeader.cs: Reformat code. + * src/TagLib/NonContainer/StartTag.cs: Make sure APE tags have headers + when placed at the front of a file. + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/Ape/Item.cs: API changes to improve clarity and + functionality. + * docs/en/TagLib.Riff/WaveFormatEx.xml: + * docs/en/TagLib.WavPack/StreamHeader.xml: + * docs/en/TagLib.WavPack/File.xml: + * docs/en/TagLib.Ape.xml: + * docs/en/TagLib.Ape/ItemType.xml: + * docs/en/TagLib.Ape/Tag.xml: + * docs/en/TagLib.Ape/Footer.xml: + * docs/en/TagLib.Ape/Item.xml: + * docs/en/TagLib.Ogg.Codecs/Vorbis.xml: Some solid documentation. + TagLib.Ape and TagLib.WavPack namespaces are 100% documented. + * docs/Makefile.am: docdir is a bad name, using monodocdir. + * configure.ac: Version bump. + * taglib-sharp.csproj: Fixed typos. + + svn path=/trunk/taglib-sharp/; revision=77682 + +commit 211aa93107e3e49839e40f49a648a696e922107b +Author: Brian Nickel +Date: Fri May 18 16:52:18 2007 + + 2007-05-18 Brian Nickel + + * src/TagLib/File.cs: Reprivatize file_stream. + * src/TagLib/Id3v2/Footer.cs: Remove SetData. + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: Don't load compressed or encrypted + frames rather than corrupting them. + * src/TagLib/Id3v2/FrameHeader.cs: Handle flags properly. + * src/TagLib/Id3v2/Header.cs: Remove SetData. + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: Tidy up source. + * src/TagLib/Id3v2/ExtendedHeader.cs: Replace SetData with constructor. + * src/TagLib/Id3v2/Frame.cs: Improve support for frame flags. + * src/TagLib/ByteVector.cs: Privitize SetData. + * src/TagLib/Asf/Tag.cs: Provide easy access to multi-string + descriptors. + * src/TagLib/Mpeg4/AppleTag.cs: If AlbumArtists is empty, use + Performers. (The aART data box is pretty new and underused.) + * docs/en/*: Updated docs. Stripped duplicates. Filled some out. + + svn path=/trunk/taglib-sharp/; revision=77671 + +commit 1801717875bb1f8ac8610324224c0c8a121085cb +Author: Aaron Bockover +Date: Tue May 15 19:28:35 2007 + + Fix filename spelling error + + svn path=/trunk/taglib-sharp/; revision=77447 + +commit e3e4085b2579a64f68112bc86c125307151cd7c3 +Author: Brian Nickel +Date: Tue May 15 16:19:18 2007 + + 2007-05-15 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: Fix BPM storage. + * src/TagLib/Tag.cs: + * src/TagLib/CombinedTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/GroupedComment.cs: Rename BPM to BeatsPerMinute. + * examples/ReadFromUri.cs: Push/Pop abstractor. Add new tags to output. + + svn path=/trunk/taglib-sharp/; revision=77441 + +commit f8bd361bf79fc32e15fb624881e909121ffd96e0 +Author: Brian Nickel +Date: Tue May 15 02:46:59 2007 + + 2007-05-15 Brian Nickel + + * src/TagLib/Tag.cs: + * src/TagLib/CombinedTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Id3v2/Tag.cs + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/GroupedComment.cs: Added support for Copyright, BPM, + Composer, and Grouping. + + svn path=/trunk/taglib-sharp/; revision=77393 + +commit 1621bd2f4bcb7886eea116cfeb273b7ae7c3cd8b +Author: Brian Nickel +Date: Tue May 15 00:50:19 2007 + + 2007-05-14 Brian Nickel + + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: Include TextType + in Get, GetPreferred, and constructors. + + svn path=/trunk/taglib-sharp/; revision=77389 + +commit 11d59b0b728dcbc78088cebc0808582bc2f133d2 +Author: Brian Nickel +Date: Tue May 15 00:25:31 2007 + + 2007-05-14 Brian Nickel + + Feature Request: http://forum.taglib-sharp.com/viewtopic.php?f=4&t=12 + + * src/TagLib/File.cs: Support pushing and poping file abstractors. + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Tag.cs: Be a little bit smarter when storing lyrics + and comments. GetPreferred shouldn't be used for storing, because we + want to store in exactly what we want, not a best guess. + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Frames/SynchronizedLyricsFrame.cs: Support + synchronized lyrics. + * src/TagLib/TagLib.sources: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Added file. + + svn path=/trunk/taglib-sharp/; revision=77388 + +commit 1c35339ce18bfe692bd084957935d727456ccfd2 +Author: Brian Nickel +Date: Thu May 10 16:51:32 2007 + + 2007-05-10 Brian Nickel + + * src/TagLib/Mpeg/Properties.cs: + * src/TagLib/Asf/Properties.cs: + * src/TagLib/Ogg/Properties.cs: + * src/TagLib/Ogg/Vorbis/File.cs: + * src/TagLib/Ogg/Flac/File.cs: + * src/TagLib/Mpeg4/Properties.cs: Deleted. I thought MonoDevelop did + this automatically. My bad. + + svn path=/trunk/taglib-sharp/; revision=77167 + +commit 8231c1b7d8f99e3b19ff8ecd820f5ad9e8668b19 +Author: Brian Nickel +Date: Wed May 9 22:21:15 2007 + + 2007-05-09 Brian Nickel + + * src/TagLib/Mpeg/AudioFile.cs: Throw a proper CorruptFileException if + AudioHeader isn't found. + * src/TagLib/File.cs: + * src/TagLib/ICodec.cs: Use FlagsAttribute for sexy output. + * docs/taglib-sharp-docs.source: + * docs/Makefile.am: + * docs/MonodocNodeConfig.cs: Doc stuff mysteriously vanished from SVN + a while back. Returning. + * examples/ReadFromUri.cs: Cleaned up a bit. + * examples/ReadFromUri.boo: First boo example. Would have an IronPython + one, but I'm having some issues with inheritance. + + svn path=/trunk/taglib-sharp/; revision=77104 + +commit dec6901184e786c5e50fb1f350cce4eedfee404c +Author: Brian Nickel +Date: Wed May 9 12:58:56 2007 + + 2007-05-09 Brian Nickel + + +-------------+ + | VERSON BUMP | + | 1.9.99992 | + +-------------+ + + * src/TagLib/Id3v2/Tag.cs: Use new TextIdentificationFrame.Get + * configure.ac: Version bump. + + + svn path=/trunk/taglib-sharp/; revision=77072 + +commit eb8e3555c05797ad4330e7e348cff509f941ca8f +Author: Aaron Bockover +Date: Tue May 8 13:17:50 2007 + + Removed + + svn path=/trunk/taglib-sharp/; revision=76955 + +commit 22ef266a4a8fc1d98e54da8be504cb89afaf68c0 +Author: Aaron Bockover +Date: Tue May 8 13:16:30 2007 + + 2007-05-07 Aaron Bockover + + * src/TagLib/TagLib.sources: Added a separate file to define what sources + to build so that applications bundling TagLib don't have to worry about + keeping the list in sync - they can just include the file in their build + + * src/Makefile.am: Include TagLib/TagLib.sources + + * docs/Makefile.am: Added an empty/stub file to fix the build for now + + + svn path=/trunk/taglib-sharp/; revision=76954 + +commit dfe9c553fe1bb09b1410b9b30c595e8c33fb3a5b +Author: Brian Nickel +Date: Mon May 7 04:11:30 2007 + + 2007-05-07 Brian Nickel + + * src/TagLib/Riff/File.cs: Add support for WAVE files. Better improve + "Read ()" to handle other extensions. (Still pretty ugly.) + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/AviHeaderList.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: De-stupidify. Make + WaveFormatEx and BitmapInfoHeader inheric I*Codec and remove excess + formats. + + svn path=/trunk/taglib-sharp/; revision=76811 + +commit 5d72c831f294e17dfd10747dca4380b97ce4a562 +Author: Brian Nickel +Date: Sun May 6 22:25:10 2007 + + 2007-05-04 Brian Nickel + + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Added better type + checking in "Get" + * src/TagLib/ByteVector.cs: Fixed ToStrings align problem from previous + revision. + * docs/en/*/*.xml: Updated. + + svn path=/trunk/taglib-sharp/; revision=76805 + +commit 35595c85aac187b4fd0e3663d4ad4e6316fb0059 +Author: Brian Nickel +Date: Fri May 4 04:28:34 2007 + + 2007-05-04 Brian Nickel + + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/VideoHeader.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/WavPack/StreamHeader.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/Asf/PaddingObject.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/Object.cs: + * src/TagLib/Asf/Guid.cs: + * src/TagLib/Asf/ContentDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/PageHeader.cs: Goodbye, short and long, hello ushort + and ulong. This should avoid those pesky OverflowExceptions. + + svn path=/trunk/taglib-sharp/; revision=76662 + +commit efa333489ab79f3ca9d5057fdafde428c97d7c5e +Merge: ef7278e 50c43d0 +Author: Brian Nickel +Date: Thu May 3 14:16:40 2007 + + 2007-05-03 Brian Nickel + + Revamped TagLib.Properties by making it non-overridable and having it read + ICodec, IAudioCodec, and IVideoCodec items. This provides support for reading + information strictly from an audio or video stream property, decreasing the + abstraction. + + * src/TagLib/Mpc/File.cs: + * src/TagLib/Mpc/StreamHeader.cs: + * src/TagLib/File.cs: + * src/TagLib/ByteVectorList.cs: + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/AviStream.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/BitmapInfoHeader.cs: + * src/TagLib/Riff/AviHeaderList.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: + * src/TagLib/Riff/WaveFormatEx.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/VideoHeader.cs: + * src/TagLib/Mpeg/AudioFile.cs: + * src/TagLib/Mpeg/AudioHeader.cs: + * src/TagLib/ICodec.cs: + * src/TagLib/WavPack/File.cs: + * src/TagLib/WavPack/StreamHeader.cs: + * src/TagLib/Properties.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Flac/StreamHeader.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/ListBase.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: + * src/TagLib/Ogg/Codec.cs: + * src/TagLib/Ogg/File.cs: + * examples/ReadFromUri.cs: Add support for new ICodec derivatives. + * src/TagLib/ByteVector.cs: Fix reading of UTF16 in certain cases. + * src/taglib-sharp.mdp: + * src/Makefile.am: + * taglib-sharp.csproj: New files. + * docs/en/*/*.xml: Updated docs. + + svn path=/trunk/taglib-sharp/; revision=76641 + +commit ef7278e7ac8544619e423fa14cea88ebe8eb3f6e +Author: Brian Nickel +Date: Thu Apr 26 04:41:21 2007 + + 2007-04-26 Brian Nickel + + * docs/en/*/*.xml: Updated docs. Removed bad files. + + + svn path=/trunk/taglib-sharp/; revision=76304 + +commit f965e2da293e9d5b756aed6bbe798f6bd4f39fab +Author: Brian Nickel +Date: Thu Apr 26 04:34:56 2007 + + Removing docs temporarily. + + + svn path=/trunk/taglib-sharp/; revision=76302 + +commit b5eca1f4a46f1a198e7108d14b998413f6228c1d +Author: Brian Nickel +Date: Wed Apr 25 18:25:33 2007 + + 2007-04-25 Brian Nickel + + taglib-sharp-1.9.99991 (2.0 beta 1) + + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/File.cs: RIFF abhors odd byte counts. + * src/TagLib/Asf/Tag.cs: Removed random extra Console.WriteLine. + * docs/en/*/*.xml: Synced + * configure.ac: Version bump + + + svn path=/trunk/taglib-sharp/; revision=76294 + +commit 50c43d0fc876694dfc582d3e8b835d6fe7e088b4 +Author: Brian Nickel +Date: Tue Apr 24 01:54:01 2007 + + 2007-04-23 Brian Nickel + + Added support for AVI video files! Revamped the GenreList for video genres. + + * src/TagLib/File.cs: New tag types. + * src/TagLib/Id3v1/Tag.cs: Clean up. + * src/TagLib/Riff/List.cs: + * src/TagLib/Riff/AviProperties.cs: + * src/TagLib/Riff/File.cs: + * src/TagLib/Riff/DivXTag.cs: + * src/TagLib/Riff/ListTag.cs: + * src/TagLib/Riff/InfoTag.cs: + * src/TagLib/Riff/MovieIdTag.cs: AVI support! + * src/TagLib/Genres.cs: Refactored GenreList. + * src/TagLib/Id3v2/Tag.cs: Clean up rendering. + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: Expand support. + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: Id3v2 changes. + * src/TagLib/FileTypes.cs: Added Riff type. + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: IEnumerable. + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/AppleTag.cs: Use BoxList and IEnumerable. + * src/TagLib/Ogg/File.cs: AccessMode should be Write, not read. + * src/taglib-sharp.mdp: + * src/Makefile.am: + * taglib-sharp.csproj: New files. + + svn path=/trunk/taglib-sharp/; revision=76161 + +commit 1a6210a60dbf350488095ea0a234ba9ee808e133 +Merge: 545c1a4 e89151f +Author: Brian Nickel +Date: Tue Apr 17 20:57:51 2007 + + 2007-04-17 Brian Nickel + + Added support for MPEG-1/2 video files! Major API changes in TagLib.Mpeg + namespace. + + * src/TagLib/File.cs: Make BufferSize public. + * src/TagLib/Id3v2/Tag.cs: Accidentally accounted for footer twice. + * src/TagLib/Mpeg/Properties.cs: Support video, refractor code. + * src/TagLib/Mpeg/File.cs: Support complete MPEG-1/2 file. + * src/TagLib/Mpeg/VideoHeader.cs: Parses the content of a mpeg box. + * src/TagLib/Mpeg/AudioFile.cs: Renamed from File.cs as it is simply an + implementation of the audio stream rather than a complete file. + * src/TagLib/Mpeg/AudioHeader.cs: Renamed from Header.cs + * src/TagLib/NonContainer/EndTag.cs: Fix rendering of Id3v1 tags. Fix + prioritizing of tags. + * src/TagLib/FileTypes.cs: New file type Mpeg.AudioFile + * src/Makefile.am: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: New files. + + svn path=/trunk/taglib-sharp/; revision=75856 + +commit 545c1a48a735d8baf7650e6bc92a469d988aef55 +Author: Brian Nickel +Date: Sun Apr 15 21:16:12 2007 + + 2007-04-15 Brian Nickel + + Added support for MPEG-4 video! + + * src/TagLib/Tag.cs: + * src/TagLib/File.cs: + * src/TagLib/Mpeg/XingHeader.cs: + * src/TagLib/Properties.cs: Removed obsolete properties and methods. + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ape/Footer.cs: + * src/TagLib/Ape/Item.cs: Cleaned up formatting a bit. + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoAudioSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/IsoVisualSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/Properties.cs: + * src/TagLib/Mpeg4/FileParser.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxFactory.cs: Added visual support. + * src/Makefile.am + * src/taglib-sharp.mdp + * taglib-sharp.csproj: Added new files. + * tests/fixtures/TagLib.FormatTests/AsfFormatTest.cs: The test did not + represent the field interpretation. + + svn path=/trunk/taglib-sharp/; revision=75741 + +commit 7f1c6a59af367729df95412be794af386878db94 +Author: Brian Nickel +Date: Sun Apr 15 15:57:03 2007 + + 2007-04-15 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: Removed DefaultEncoding stuff from + FrameFactory and put it in Tag. Additionally, instead of enforcing the + default encoding at read time, it is enforced at render time. It has + also been changed so the tags save in the same version they were read in + by default. This should avoid the greatest number of problems without + the need for developer intervention. + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Replace Find with + Get (Tag tag, ..., bool create). This new method will find a specified + frame if it exists, and can create it and append it if it doesn't. + * src/TagLib/Id3v2/Frame.cs: Enforce ForceDefaultEncoding. + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: All generic. + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/Box.cs: AppleTag wasn't getting attached to .Tag + * tests/tests.mdp: Removed ApeFormatTest as it was unsupported. + * tests/fixtures/TagLib.FormatTests/FlacFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V1FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3V2FormatTest.cs: + * tests/fixtures/TagLib.FormatTests/AsfFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/Id3BothFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/OggFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/MpcFormatTest.cs: + * tests/fixtures/TagLib.FormatTests/M4aFormatTest.cs: Updated for new + API. + * configure.ac: Version bump. + + svn path=/trunk/taglib-sharp/; revision=75736 + +commit e89151f9fab8c2b1d1f2160c708319025dc91757 +Author: Brian Nickel +Date: Mon Apr 9 18:11:58 2007 + + 2007-04-09 Brian Nickel + + * src/AssemblyInfo-windows.cs: + * configure.ac: + * taglib-sharp.csproj: Apply version bump. Now 1.9.* + + + svn path=/trunk/taglib-sharp/; revision=75556 + +commit 6728903ef66fa53592b1cb9f993fd97cc66217a6 +Merge: 4183fba e7de1a7 +Author: Brian Nickel +Date: Fri Apr 6 04:54:26 2007 + + 2007-04-06 Brian Nickel + + MAJOR API CHANGES! COMPLETE NEW OGG BACKEND! VIDEO SUPPORT IN OGG AND ASF! + + * src/TagLib/Mpc/Properties.cs: + * src/TagLib/Mpc/File.cs: Support new "Properties". + * src/TagLib/File.cs: Support new "Properties". + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: Better error + handling. + * src/TagLib/Mpeg/Properties.cs: Support new "Properties". + * src/TagLib/Mpeg/XingHeader.cs: Mark IsValid as obsolete. + * src/TagLib/Mpeg/File.cs: + * src/TagLib/WavPack/Properties.cs: + * src/TagLib/WavPack/File.cs: Support new "Properties". + * src/TagLib/NonContainer/File.cs: Support new "Properties". + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: Better error handling. + * src/TagLib/Properties.cs: Abolish overly specific "AudioProperties" + * src/TagLib/Ape/Item.cs: Replace Debugger with Exception + * src/TagLib/Flac/Properties.cs: + * src/TagLib/Flac/File.cs: Support new "Properties". + * src/TagLib/FileTypes.cs: Remove dead file types. + * src/TagLib/Asf/Tag.cs: Allow tag clearing. + * src/TagLib/Asf/Properties.cs: + * src/TagLib/Asf/File.cs: Support new "Properties". Support video. + * src/TagLib/Asf/Guid.cs: Fix typo in GUID plain text. + * src/TagLib/Mpeg4/Properties.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/File.cs: Move saving out of the AppleTag. Will allow + future implimentation of ID3v2 boxes. + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/Page.cs: + * src/TagLib/Ogg/Codecs/Theora.cs: + * src/TagLib/Ogg/Codecs/Vorbis.cs: + * src/TagLib/Ogg/Properties.cs: + * src/TagLib/Ogg/Codec.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Paginator.cs: + * src/TagLib/Ogg/PageHeader.cs: + * src/TagLib/Ogg/GroupedComment.cs: + * src/TagLib/Ogg/Bitstream.cs: Recoded for multistream files. + * src/Makefile.am: + * src/taglib-sharp.mdp: Updated for new files. + * docs/en/*: Updated docs to new API. + * examples/ReadFromUri.cs: Added video support. + + svn path=/trunk/taglib-sharp/; revision=75474 + +commit 4183fbac47082a49488a4d24369525b27c631fb9 +Author: Brian Nickel +Date: Fri Mar 23 16:56:30 2007 + + 2007-03-23 Brian Nickel + + * src/TagLib/File.cs: Don't catch exceptions on mode change. + * src/TagLib/Id3v1/Tag.cs: Use TryParse rather than try{Parse}. + * src/TagLib/Id3v2/Tag.cs: Remove "0" values rather than storing "0". Use + TryParse rather than try{Parse}. + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Use TryParse rather + than try{Parse}. + * src/TagLib/Ape/Tag.cs: Remove "0" values rather than storing "0". Use + TryParse rather than try{Parse}. + * src/TagLib/Asf/Tag.cs: Remove "0" values rather than storing "0". Use + TryParse rather than try{Parse}. + * src/TagLib/Asf/ContentDescriptor.cs: Use TryParse rather than try{Parse}. + * src/TagLib/Mpeg4/AppleTag.cs: Use TryParse rather than try{Parse}. + * src/TagLib/Ogg/XiphComment.cs: Remove "0" values rather than storing "0". + Use TryParse rather than try{Parse}. + * src/TagLib/Ogg/Vorbis/File.cs: Don't catch exceptions on mode change. + + svn path=/trunk/taglib-sharp/; revision=74925 + +commit 2fa8af7af3c6de35cb9e1ce913bbf326bdaecedb +Author: Brian Nickel +Date: Thu Mar 22 19:12:55 2007 + + 2007-03-22 Brian Nickel + + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Remove null termination + in ID3v2.3 and below. + * src/TagLib/WavPack/File.cs: + * src/TagLib/Mpc/File.cs: + * src/TagLib/Mpeg/File.cs: Include sane default tags. + * docs/en/*: Synched docs. + + + svn path=/trunk/taglib-sharp/; revision=74861 + +commit a19253ce77d06f7a4681faf5cefa16d6b7b02e45 +Author: Brian Nickel +Date: Wed Mar 14 16:23:42 2007 + + 2007-03-14 Brian Nickel + + * docs/en/*: Synced docs. + + + svn path=/trunk/taglib-sharp/; revision=74308 + +commit e7de1a714ef4336295c85bb0ca0e73b96c4a6b47 +Author: Brian Nickel +Date: Wed Mar 14 02:15:31 2007 + + 2007-03-13 Brian Nickel + + Lyrics support! Fixed write support in MPEG-4 and ASF. + + * src/TagLib/Tag.cs: + * src/TagLib/CombinedTag.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Frames/UnsynchronisedLyricsFrame.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxTypes.cs: + * src/TagLib/Mpeg4/Box.cs: + * src/TagLib/Ogg/XiphComment.cs: Lyrics support. Special thanks to Patrick + Laplante. + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/ByteVector.cs: Fix up UTF16 handling. + * src/TagLib/Asf/HeaderObject.cs: Fix writing. Wasn't writing header GUID! + * src/Makefile.am: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Update project files. + * examples/BatchSet.cs: + * examples/ReadFromUri.cs: Support lyrics. + + svn path=/trunk/taglib-sharp/; revision=74237 + +commit f294436840eb53c3d2b28b7d62373af83cba478b +Merge: 720db6c 50d6746 +Author: Brian Nickel +Date: Tue Mar 13 21:13:29 2007 + + 2007-03-13 Brian Nickel + + Performance enhancement for MPEG-4 files. Stole an idea from Entagged#. + + * src/TagLib/Mpeg4/FileParser.cs: ADDED + * src/TagLib/Mpeg4/BoxTypes.cs: ADDED + * src/TagLib/Mpeg4/BoxFactory.cs: ADDED + * src/TagLib/Mpeg4/BoxList.cs: ADDED + * src/TagLib/Mpeg4/Box.cs: ADDED + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleTableBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/AppleAdditionalInfoBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoFreeSpaceBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleItemListBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoUserDataBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleElementaryStreamDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleDataBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleAnnotationBox.cs: + * src/TagLib/Mpeg4/Boxes/UnknownBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMetaBox.cs: + * src/TagLib/Mpeg4/Properties.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: Adapted to new parser. + * src/TagLib/Mpeg4/Boxes/IsoTrackBox.cs: DELETED + * src/TagLib/Mpeg4/Boxes/Box.cs: DELETED + * src/TagLib/Mpeg4/Boxes/FileBox.cs: DELETED + * src/TagLib/Mpeg4/Boxes/IsoMovieBox.cs: DELETED + * src/TagLib/Mpeg4/Boxes/IsoMediaBox.cs: DELETED + * src/TagLib/Mpeg4/Boxes/IsoMediaInformationBox.cs: DELETED + + * src/TagLib/File.cs: Make ReadBlock make a a little more sense. + * src/TagLib/Id3v2/Tag.cs: Support tag-wide unsynchronization. + * src/TagLib/Id3v2/SynchData.cs: Add support for unsynching a bytevector. + * src/TagLib/Id3v2/FrameHeader.cs: We don't actually support frame tags. + Don't pretend that we do. + * src/TagLib/Debugger.cs: Fix typo and crasher in code timer. + * src/TagLib/ByteVector.cs: Make Mid a little faster. + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: End tags should be at least version 4 + * src/Makefile.am: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Update for new files. + + svn path=/trunk/taglib-sharp/; revision=74224 + +commit 720db6c2ce8a78239a0bb0733d8506106ba3b097 +Author: Brian Nickel +Date: Fri Mar 9 12:13:38 2007 + + 2007-03-09 Brian Nickel + * configure.ac: Fixed version information. + + svn path=/trunk/taglib-sharp/; revision=74020 + +commit 5e0401e40accf5da245ce7f8359f2ad05b00016b +Author: Brian Nickel +Date: Fri Mar 9 05:29:53 2007 + + 2007-03-09 Brian Nickel + + "I do not regret the things I've done, but those I did not do." + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Header.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: + * src/TagLib/Id3v2/Frame.cs: Reworked reading/writing code to better support + writing Id3v2.2 and Id2v2.3. This is the first go at it, and there is room + for cleanup in the code, but it works, and it works and it works well. + + svn path=/trunk/taglib-sharp/; revision=73998 + +commit 50d67469ce05d4ce7d17fce881439cc02508f0e8 +Author: Brian Nickel +Date: Thu Mar 8 19:54:47 2007 + + 2007-03-08 Brian Nickel + * src/TagLib/Mpc/File.cs: Inherit NonContainer.File + * src/TagLib/CombinedTag.cs: Add some useful features for NonContainer.* + * src/TagLib/Id3v1/Tag.cs: Add Tag.Size instead of repeated hardcoding of + 128. + * src/TagLib/Id3v2/Footer.cs: + * src/TagLib/Id3v2/Header.cs: Throw proper CorruptFileExceptions + * src/TagLib/Mpeg/File.cs: Inherit NonContainer.File + * src/TagLib/WavPack/File.cs: Inherit NonContainer.File + * src/TagLib/NonContainer: + * src/TagLib/NonContainer/Tag.cs: + * src/TagLib/NonContainer/File.cs: + * src/TagLib/NonContainer/EndTag.cs: + * src/TagLib/NonContainer/StartTag.cs: New generic abstracts for files + that can start/end with an assortment of tags. (FLAC, WV, MPC, MP3) + * src/TagLib/Ape/Tag.cs: Read backwards if a footer is found and forwards if + a header is found. + * src/TagLib/Ape/Footer.cs: FooterPresent and IsHeader were read + incorrectly. Also throw proper exceptions while reading. + * src/TagLib/Flac/File.cs: Inherit NonContainer.File + * src/TagLib/Flac/BlockHeader.cs: + * src/TagLib/Flac/Block.cs: Removed from Flac.File, made public. + * src/TagLib/Mpeg4/File.cs: Remove old commented code. + * src/Makefile.am: + * src/taglib-sharp.csproj: + * src/taglib-sharp.mdp: + * taglib-sharp.mds: + * tests/tests.mdp: + * examples/SetPictures.mdp: + * examples/ReadFromUri.mdp: Updates. + + svn path=/trunk/taglib-sharp/; revision=73980 + +commit 638a8773ef6babb4207fc17129b95da3c27d9c89 +Author: Brian Nickel +Date: Sun Mar 4 18:59:31 2007 + + 2007-03-04 Brian Nickel + + * src/TagLib/File.cs: We don't use file.file_types. Comment it out to avoid + the warning. + * src/TagLib/Tag.cs: + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Debugger.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Ogg/XiphComment.cs: + * docs/MonodocNodeConfig.cs: + * tests/fixtures/TagLib.CollectionTests/StringListTest.cs: + * tests/fixtures/TagLib.CollectionTests/IntListTest.cs: + * examples/ReadFromUri.cs: Use string.Empty instead of "". + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: Support broken COMM frames that + don't contain a comment description string. + + svn path=/trunk/taglib-sharp/; revision=73697 + +commit 7edb701b614ced81d2cee17180197efb2e88c32c +Author: Brian Nickel +Date: Wed Feb 21 14:17:39 2007 + + 2007-02-12 Brian Nickel + + * src/TagLib/File.cs: Added support for read sharing in ReadStream. This + should eliminate a problem in Windows where files couldn't be read while + they were playing. Solution by Ion Todirel. + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: Strip all empty + strings from the end of the FieldList. This should fix strings that were + badly tagged, with either a nil character or the sum total of the ID3v1 + string attached. May fix banshee bug #410116. + * tests/Makefile.am: Removed line blocking distcheck + + svn path=/trunk/taglib-sharp/; revision=73276 + +commit 815bd6d7ac68b1629fd0be0b86194205fe2ef1cb +Author: Brian Nickel +Date: Mon Feb 12 21:56:10 2007 + + 2007-02-12 Brian Nickel + + * src/TagLib/ByteVector.cs: Fix support for Latin1. + * taglib-sharp.csproj: Work on Windows. + + svn path=/trunk/taglib-sharp/; revision=72728 + +commit 8756a473fa6c667fc55bfdf56b9eacab54c39b99 +Author: Brian Nickel +Date: Mon Feb 12 14:07:50 2007 + + 2007-02-12 Brian Nickel + + * src/TagLib/File.cs: Remove ReadOnly checking. This is to add compatability + with the .NET Compact Framework and to remove some ugly code. Libraries + using TagLib# should check file writability for themselves if they want + the writable status before Save() is called. Also use more compatable + Array.Copy(). + * src/TagLib/Mpeg/File.cs: Comment out unused method. + * src/TagLib/ByteVector.cs: Use more compatable Array.Copy() + * src/TagLib/ReadOnlyException.cs: Removed because unused. + * src/AssemblyInfo.cs.in: Update copyright. + * src/AssemblyInfo-windows.cs: Update version and copyright. + * src/Makefile.am: + * src/taglib-sharp.mdp: + * taglib-sharp.csproj: Update files. + + svn path=/trunk/taglib-sharp/; revision=72686 + +commit 3d0a431324e1913d77e79835a120b7f35b7b2b18 +Author: Brian Nickel +Date: Sun Feb 11 19:10:41 2007 + + 2007-02-10 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Id3v2/Frames/CommentsFrame.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/Id3v2/Frames/UniqueFileIdentifierFrame.cs: + * src/TagLib/Id3v2/Frames/PrivateFrame.cs: + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Id3v2/Frames/UnknownFrame.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/ByteVector.cs: VASTLY improved the loading of ID3v2 tags by + breaking API compatability. (This isn't a major concern at the moment.) + Removed a major piece of code which was causing about 80% of the read time. + * src/TagLib/Debugger.cs: Added new way to test for slow code blocks. + + + svn path=/trunk/taglib-sharp/; revision=72636 + +commit 316a7c6ca649172d5c4056462b57b0de5f0ddb0e +Author: Brian Nickel +Date: Sat Feb 10 13:09:52 2007 + + 2007-02-10 Brian Nickel + + * src/TagLib/Mpeg/File.cs: Fix bug introduced on 2007-01-26. If a file + lacked an Id3v2 tag, TagLib read the whole file. Initial analysis shows this + being marginally faster than the even older version. + * src/TagLib/Id3v2/Frames/RelativeVolumeFrame.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Ogg/XiphComment.cs: + * src/TagLib/Ogg/File.cs: Abolish Hashtable. ArrayList is next. + + svn path=/trunk/taglib-sharp/; revision=72582 + +commit 46b8662f783314ca5821473484137f04eb93c6cc +Author: Brian Nickel +Date: Mon Jan 29 13:41:33 2007 + + 2007-01-29 Brian Nickel + + * examples/ReadFromUri.cs: Remove accidental commenting out. + + svn path=/trunk/taglib-sharp/; revision=71907 + +commit 745e88d2b9f894d23ef22f285fafe10c285c9f42 +Author: Brian Nickel +Date: Sat Jan 27 00:11:01 2007 + + 2007-01-26 Brian Nickel + + CLEANUPS! For the most part, internal code has been cleaned up to be less + hackish. One major feature is the obsoleting of SetValid and IsValid. If + a file is invalid, it will now throw a CorruptFileException. + + * src/TagLib/Mpc/Properties.cs: + * src/TagLib/Mpc/File.cs: Better search functions. + * src/TagLib/File.cs: Clean out and Obsolete bad code. + * src/TagLib/Id3v1/Tag.cs: Cleaner functions. + * src/TagLib/Mpeg/Properties.cs: + * src/TagLib/Mpeg/XingHeader.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/Mpeg/Header.cs: Better search functions, calculations, and + exceptions. + * src/TagLib/WavPack/Properties.cs: + * src/TagLib/WavPack/File.cs: Use better search functions. + * src/TagLib/Ape/Footer.cs: Throw better exception. + * src/TagLib/Flac/File.cs: Fix padding calculation. + * src/TagLib/Asf/PaddingObject.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: Throw better + exceptions. + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoMovieHeaderBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleEntry.cs: + * src/TagLib/Mpeg4/Boxes/FileBox.cs: + * src/TagLib/Mpeg4/Boxes/Box.cs: + * src/TagLib/Mpeg4/Boxes/IsoSampleDescriptionBox.cs: + * src/TagLib/Mpeg4/File.cs: Read bigger blocks and less often. + * src/TagLib/Ogg/XiphComment.cs: Support "XX/XX" values in Track and Disc. + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Vorbis/Properties.cs: + * src/TagLib/Ogg/Vorbis/File.cs: + * src/TagLib/Ogg/Flac/File.cs: Obsolete Set/IsValid and throw useful + exceptions. + * docs/en/TagLib.Id3v1/Tag.xml: + * docs/en/TagLib.Id3v2/FrameFactory.xml: + * docs/en/TagLib.Mpeg/Header.xml: + * docs/en/TagLib.Mpeg/Properties.xml: + * docs/en/TagLib.Mpeg/File.xml: + * docs/en/TagLib/UnsupportedFormatException.xml: + * docs/en/TagLib/ByteVector.xml: + * docs/en/TagLib/ReadOnlyException.xml: + * docs/en/TagLib/SupportedMimeType.xml: + * docs/en/TagLib/AudioProperties.xml: + * docs/en/TagLib/File.xml: + * docs/en/index.xml: + * docs/en/TagLib.Asf/FilePropertiesObject.xml: + * docs/en/TagLib.Asf/StreamPropertiesObject.xml: + * docs/en/TagLib.Mpeg4/Box.xml: + * docs/en/TagLib.Mpeg4/Properties.xml: + * docs/en/TagLib.Mpeg4/IsoMovieHeaderBox.xml: + * docs/en/TagLib.Mpeg4/File.xml: Doc updates. + * examples/ReadFromUri.cs: Add timer, clean output, and avoid crash. + + svn path=/trunk/taglib-sharp/; revision=71776 + +commit 3d6a2ae571c6d109d0e9ee1815cb5adddac694c6 +Author: Brian Nickel +Date: Mon Jan 8 00:10:51 2007 + + 2007-01-07 Brian Nickel + + * src/TagLib/File.cs: Throw ReadOnlyException when it makes sense. + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: Fix for UTF16. + * src/TagLib/Id3v2/Frames/GeneralEncapsulatedObjectFrame.cs: + * src/TagLib/Id3v2/FrameFactory.cs: + * src/TagLib/Id3v1/Tag.cs: + * src/TagLib/Id3v2/Frames/TextIdentificationFrame.cs: + * src/TagLib/Mpeg/XingHeader.cs: + * src/TagLib/Mpeg/Header.cs: Improvements from TagLib. + * src/TagLib/Flac/Picture.cs: + * src/TagLib/Flac/File.cs: Massive code rewrite. Added support for Picture + Block. + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: Fix typo. + * src/Makefile.am: Add new files. + * examples/ReadFromUri.cs: Update for changes in TagLib.Tag + + + svn path=/trunk/taglib-sharp/; revision=70624 + +commit ec64c4c5a5d703015c47f374e8fa07de824ca1ab +Author: Miguel de Icaza +Date: Sun Dec 31 15:21:07 2006 + + Ran through the Monodoc updater, and exclude compiler generated types + + svn path=/trunk/taglib-sharp/; revision=70295 + +commit 40e8172b550e081a5279855a26a3caa8a6d88f06 +Author: Aaron Bockover +Date: Tue Dec 26 17:28:45 2006 + + 2006-12-26 Aaron Bockover + + * src/TagLib/CorruptFileException.cs: Added new exception + + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Ogg/Vorbis/File.cs: Guard against nullrefs, if necessary + parts are null, throw a CorruptFileException instead to avoid seg violation + + * tests/fixtures/TagLib.FormatTests/IFormatTest.cs: Added interface for + the format test + + * tests/fixtures/TagLib.FormatTests/*.cs: Implement IFormatTest, + added TestCorruptionResistance + + * tests/samples/corrupt/*: Added some 'corrupt' samples + + + svn path=/trunk/taglib-sharp/; revision=70098 + +commit 47a28d7d84a4a070ff8f52a66de345927d5de489 +Author: Brian Nickel +Date: Fri Dec 15 10:51:10 2006 + + 2006-12-15 Brian Nickel + + * src/TagLib/Mpeg/Properties.cs: + * src/TagLib/Mpeg/Header.cs: Made some changes based on KDE bug 135459, + which should hopefully improve the accuracy of length reporting. + + svn path=/trunk/taglib-sharp/; revision=69535 + +commit 37f793eeeec12ac5c8f75bcd370bac0a7a1e9804 +Author: Brian Nickel +Date: Thu Dec 14 14:44:42 2006 + + 2006-12-14 Brian Nickel + + * src/TagLib/Mpeg/Header.cs: Fixed typo causing MP3 channels to always + equal 1. + + + svn path=/trunk/taglib-sharp/; revision=69510 + +commit b684f5efafcc62372b175ff517d50c278ca9dbe1 +Author: Aaron Bockover +Date: Mon Nov 13 23:04:04 2006 + + 2006-11-13 Aaron Bockover + + * src/TagLib/SupportedMimeType.cs: Load mime types in static constructor + + * src/TagLib/FileTypes.cs: File type loader that initializes the + SupportedMimeType support + + * src/TagLib/File.cs: Use FileTypes.AvailableTypes + + * src/Makefile.am: Added src/TagLib/FileTypes.cs + + + svn path=/trunk/taglib-sharp/; revision=67813 + +commit b4024f8550657e7dffbac1b9a736b7b76c086228 +Author: Brian Nickel +Date: Mon Nov 6 14:15:19 2006 + + 2006-11-06 Brian Nickel + + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/FrameHeader.cs: + * src/TagLib/Id3v2/Frame.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Ape/Tag.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Asf/Tag.cs: + * src/TagLib/Asf/HeaderObject.cs: + * src/TagLib/Asf/StreamPropertiesObject.cs: + * src/TagLib/Asf/FilePropertiesObject.cs: + * src/TagLib/Asf/ContentDescriptionObject.cs: + * src/TagLib/Asf/ExtendedContentDescriptionObject.cs: + * src/TagLib/Asf/Object.cs: + * src/TagLib/Asf/Guid.cs: + * src/TagLib/Asf/ContentDescriptor.cs: + * src/TagLib/Mpeg4/Boxes/FullBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/Box.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/BoxHeader.cs: Improve performance by not using plus + operator so much. Less allocations. + * tests/fixtures/TagLib.FormatTests/Id3BothFormatTest.cs: Fixed multiformat + tests. Removed Tag Count test. + + + svn path=/trunk/taglib-sharp/; revision=67413 + +commit 34d49ce11c840b8b90abcd73b424943b17e47baa +Author: Brian Nickel +Date: Fri Nov 3 18:21:47 2006 + + 2006-11-03 Brian Nickel + + * src/TagLib/ByteVector.cs: Use Boyer-Moore String Searching Algorithm + to speed things up a little. (Very little.) + + + svn path=/trunk/taglib-sharp/; revision=67335 + +commit 503227407e544c3d58c5ffb4afa88ad73f026fbe +Author: Aaron Bockover +Date: Mon Oct 30 20:17:59 2006 + + 2006-10-30 Aaron Bockover + + * src/TagLib/IntList.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/StringList.cs: + * src/TagLib/ByteVectorList.cs: Use generics, refactored code, massive + optimizations; all collections except ByteVector derives new ListBase + + * src/TagLib/ListBase.cs: New generic base collection + + * src/Makefile.am: Updated + + * tests/fixtures/PerformanceTest.cs: Updated + + + svn path=/trunk/taglib-sharp/; revision=67170 + +commit 342ba48b943df40d1fdbacb6f0e9388cb0d33e8e +Author: Brian Nickel +Date: Mon Oct 30 18:04:23 2006 + + 2006-10-20 Brian Nickel + + * src/TagLib/Mpc/Properties.cs: Fix property reading. + * src/TagLib/Mpc/File.cs: Fix total brokenness. + * src/TagLib/Mpeg/File.cs: Fix reading with no ID3v2 Tag. + * src/TagLib/Mpeg4/AppleTag.cs: Fix reading of ID3v1 Genres. + * tests/fixtures/TagLib.FormatTests/MpcFormatTest.cs: Fixed test. (I think.) + + + svn path=/trunk/taglib-sharp/; revision=67165 + +commit 63599534be2ed6e644bea1706c887c660e19a718 +Author: Aaron Bockover +Date: Sun Oct 29 14:33:01 2006 + + Updated + + svn path=/trunk/taglib-sharp/; revision=67109 + +commit 764ea91e974856e2c8661019df9ee7ed7c8695d2 +Author: Aaron Bockover +Date: Sun Oct 29 14:31:02 2006 + + 2006-10-29 Aaron Bockover + + * tests/: Added more tests (IntList, StringList), restructured layout + + + svn path=/trunk/taglib-sharp/; revision=67108 + +commit fb2068e7b1366a1bd18fb47ed2ec8535a5f79b6d +Author: Aaron Bockover +Date: Sun Oct 29 14:13:34 2006 + + Updated header + + svn path=/trunk/taglib-sharp/; revision=67104 + +commit 64de9fb6c4ad4d1603d6ae357e69e59a1e5c79d7 +Author: Aaron Bockover +Date: Sun Oct 29 10:52:30 2006 + + 2006-10-29 Aaron Bockover + + * src/TagLib/File.cs: Do not use reflection (Assembly.GetTypes) to find + file formats, instead use a static type table. Assembly.GetTypes leaks + types on the heap that will never be GCed (saves about 200KB of heap); + this means that if a new type is added, it must be entered in the static + type table for it to be available. Also this improves startup time. + + * src/TagLib/Asf/Properties.cs: Suppress unused variable warning + + + svn path=/trunk/taglib-sharp/; revision=67099 + +commit 63e440b62f8d11a35d2323de13c563793869828b +Author: Aaron Bockover +Date: Sun Oct 29 10:46:18 2006 + + 2006-10-29 Aaron Bockover + + * tests/samples: Organized into supported and unsupported formats, added + vector.bin as data for a checksum test of ByteVector + + * tests/Makefile.am: Set up NUnit console test driver, can be + run with 'make run-test' + + * tests/AssemblyInfo.cs: + * tests/ConsoleUi.cs: NUnit console test driver + + * tests/CodeTimer.cs: Timing utility + + * tests/fixtures/*FormatTest.cs: File format reading test fixtures + + * tests/fixtures/ByteVectorTests.cs: Extensive tests for ByteVector + + * tests/tests.mdp: MonoDevelop project for tests that allows running + NUnit tests with in the IDE for graphical results, recommended for + running tests as history is logged here (preferred over 'make run-test') + + * configure.ac: NUnit detection, optional + + * examples/tangerine-use-taglibsharp.patch: Removed, tangerine now + uses taglib-sharp instead of entagged-sharp + + * examples/Makefile.am: + * examples/ListSupportedMimeTypes.cs: New example + + * taglib-sharp.mds: Restored MonoDevelop solution + + + svn path=/trunk/taglib-sharp/; revision=67098 + +commit a387cfa83f5b0122408d9e77df076c5712d333b1 +Author: Brian Nickel +Date: Fri Oct 20 17:08:05 2006 + + 2006-10-20 Brian Nickel + + * src/TagLib/File.cs: Include the name of the file throwing the exception + in LocalFileAbstraction. + * src/TagLib/Mpeg/Header.cs: Make frame length logic match Lame (from + TagLib Devel List). + * examples/ReadFromUri.cs: Read multiple files. + + + svn path=/trunk/taglib-sharp/; revision=66851 + +commit 7c65b1e3359c80ae3e00f165a9457c7fa3725b42 +Author: Brian Nickel +Date: Thu Oct 12 14:45:23 2006 + + 2006-10-12 Brian Nickel + + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: + * src/TagLib/Mpeg4/AppleTag.cs: Fixed a bug where changing tag size would + devalidate offsets for data before the tag. + * examples/BatchSet.cs: + * examples/Makefile.am: Add a simple program to update tags on multiple + files. + + + svn path=/trunk/taglib-sharp/; revision=66637 + +commit 4968b78314405e4b878faf0a9d5b47a771714e48 +Author: Aaron Bockover +Date: Sun Oct 8 11:32:19 2006 + + Marked as static, whoops + + svn path=/trunk/taglib-sharp/; revision=66417 + +commit 026beee347579dc34c26e516125f96ff052e01f5 +Author: Aaron Bockover +Date: Sun Oct 8 11:31:27 2006 + + Marked as static, whoops + + svn path=/trunk/taglib-sharp/; revision=66416 + +commit 127da072a6b41f50bb93fdddbbab6ba20bd1c4fa +Author: Aaron Bockover +Date: Sun Oct 8 11:30:59 2006 + + Marked as static, whoops + + svn path=/trunk/taglib-sharp/; revision=66415 + +commit 7f2a0783af2cbec5e268214e61ee64c59734da68 +Author: Aaron Bockover +Date: Sun Oct 8 11:12:14 2006 + + 2006-10-08 Aaron Bockover + + * src/TagLib/SupportedMimeType.cs: Added extension support + + + svn path=/trunk/taglib-sharp/; revision=66413 + +commit 6b20faff04a2c0689dc5ac4c7b0b2c8bcc46f263 +Author: Aaron Bockover +Date: Sun Oct 8 10:54:08 2006 + + 2006-10-08 Aaron Bockover + + * src/TagLib/SupportedMimeType.cs: Added AllMimeTypes static enumerator + + + svn path=/trunk/taglib-sharp/; revision=66411 + +commit 987e2f6423e6299e3f99a7ba2385f7d7889faec5 +Author: Brian Nickel +Date: Mon Sep 25 14:38:15 2006 + + 2006-09-25 Brian Nickel + + * src/TagLib/CombinedTag.cs: Fixed a bug in CombinedTag.get_Pictures + * configure.ac: Don't break the gac on binary compatable versions. + + + svn path=/trunk/taglib-sharp/; revision=65890 + +commit 38c1059d8556f642d33c5f90726b6d062a4efdaf +Author: Brian Nickel +Date: Wed Sep 20 14:49:25 2006 + + 2006-09-20 Brian Nickel + + * src/TagLib/Mpc/File.cs: Added mime types. + * src/TagLib/Wavpack/File.cs: Added mime types. + + + svn path=/trunk/taglib-sharp/; revision=65739 + +commit 32df28a7eb4dd136b60ec5f1e0289eca88a9bde8 +Author: Brian Nickel +Date: Wed Sep 20 14:23:29 2006 + + 2006-09-20 Brian Nickel + + * src/TagLib/ByteVector.cs: Fixed big endian StringType.UTF16 + not to fail on big endian. (Confusing naming scheme by Microsoft.) + + + svn path=/trunk/taglib-sharp/; revision=65737 + +commit dfc58a4e6b53aca6e7b4c6b000f53703bf9d10e4 +Author: Brian Nickel +Date: Sun Sep 17 18:51:09 2006 + + 2006-09-17 Brian Nickel + + * src/TagLib/Asf/Tag.cs: Added generic picture support. + * docs/en/*: Updated docs. + + + svn path=/trunk/taglib-sharp/; revision=65556 + +commit 41b7226a730f12a5852ca0507ab4e7dcff1fcc23 +Author: Brian Nickel +Date: Fri Sep 15 04:15:08 2006 + + 2006-09-15 Brian Nickel + * src/TagLib/Picture.cs: + * src/TagLib/Tag.cs: + * src/TagLib/CombinedTag.cs: + * src/TagLib/File.cs: + * src/TagLib/Id3v2/Tag.cs: + * src/TagLib/Id3v2/Frames/AttachedPictureFrame.cs: + * src/TagLib/ByteVector.cs: + * src/TagLib/Mpeg4/Boxes/Box.cs: + * src/TagLib/Mpeg4/Boxes/IsoHandlerBox.cs: + * src/TagLib/Mpeg4/Boxes/AppleDataBox.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Ogg/XiphComment.cs: Add generic picture support to TagLib#. This + currently supports MP3 and M4A tags although support can and will be added + for other tag types in the future. + * src/Makefile.am: + * taglib-sharp.mds: + * taglib-sharp.csproj: + * examples/ReadFromUri.cs: + * examples/Makefile.am: + * examples/SetPictures.mdp: + * examples/SetPictures.cs: + * examples/ReadFromUri.mdp: New examples from Aaron Bockover. + * src/TagLib/Mpeg4/Boxes/IsoChunkLargeOffsetBox.cs: + * src/TagLib/Mpeg4/Boxes/IsoChunkOffsetBox.cs: Eliminate a nasty bug where + changes to 'mdat' offsets, ie. any file size change, broke MP4 files. + + svn path=/trunk/taglib-sharp/; revision=65440 + +commit 958b10a1f238c8dc931f236a708178d5eb9b3e34 +Author: Brian Nickel +Date: Mon Sep 11 17:45:30 2006 + + 2006-09-11 Brian Nickel + + * src/TagLib/Mpeg4/File.cs: Added "audio/mp4" to types. + + + svn path=/trunk/taglib-sharp/; revision=65256 + +commit eb2bb5eb1d9a79c3e8939509b854bac2fb9ebc9e +Author: Aaron Bockover +Date: Fri Sep 1 22:27:10 2006 + + 2006-09-01 Aaron Bockover + + * examples/covers/: Added sample cover art files + + + svn path=/trunk/taglib-sharp/; revision=64751 + +commit f4b2d423ddd4a78e991606b7d557003fb9df7fa7 +Author: Aaron Bockover +Date: Fri Sep 1 22:25:24 2006 + + 2006-09-01 Aaron Bockover + + * tests/: Added test sample audio files + + + svn path=/trunk/taglib-sharp/; revision=64750 + +commit f61e41ec8ef34c86017b2a51acdde203769c3cc3 +Author: Aaron Bockover +Date: Fri Sep 1 12:56:56 2006 + + 2006-09-01 Aaron Bockover + + * configure.ac: Added ASM_VERSION; added DISTCHECK_CONFIGURE_FLAGS so + distcheck target works properly as user (--disable-docs is passed on + distcheck now) + + * src/AssemblyInfo.cs.in: Use ASM_VERSION instead of VERSION to get + build revisions in version string + + * examples/Makefile.am: Added EXTRA_DIST, fixed distcheck build bug + + + svn path=/trunk/taglib-sharp/; revision=64730 + +commit e1eba14cc33103bbe9e7a2710355b3a02ab3b3a7 +Author: Brian Nickel +Date: Thu Aug 31 17:22:26 2006 + + Corrected an invalid frame conversion and attempting a better method for + populating ByteVectors. + + + svn path=/trunk/taglib-sharp/; revision=64669 + +commit 9126fb7e24dabaabdf2b86bdb8a8d0ba50b75594 +Author: Brian Nickel +Date: Mon Aug 28 21:48:25 2006 + + Fixed up the reading of WM/PartOfSet to avoid crashes. + + svn path=/trunk/taglib-sharp/; revision=64505 + +commit cc7f29b882471f8c31bb430af7b95f61b28cd2c9 +Author: Aaron Bockover +Date: Sun Aug 27 21:12:07 2006 + + 2006-08-27 Aaron Bockover + + * src/TagLib/ReadOnlyException.cs: New exception + + * src/TagLib/File.cs: + * src/TagLib/Mpc/File.cs: + * src/TagLib/Mpeg/File.cs: + * src/TagLib/WavPack/File.cs: + * src/TagLib/Flac/File.cs: + * src/TagLib/Asf/File.cs: + * src/TagLib/Mpeg4/AppleTag.cs: + * src/TagLib/Mpeg4/File.cs: + * src/TagLib/Ogg/File.cs: + * src/TagLib/Ogg/Vorbis/File.cs: + * src/TagLib/Ogg/Flac/File.cs: Save is now void, throws exceptions + when a problem has arisen instead of eventually returning false, masking + the source of the problem + + * taglib-sharp.csproj: + * src/Makefile.am: Updated + + + svn path=/trunk/taglib-sharp/; revision=64456 + +commit 42bdfaa70eeca125a269416619dd8d6f7ebe0b92 +Author: Aaron Bockover +Date: Fri Aug 25 19:33:46 2006 + + 2006-08-25 Aaron Bockover + + * examples/Makefile.am: Added Makefile.am, was missing from forge + repository + + + svn path=/trunk/taglib-sharp/; revision=64396 + +commit ed83b1cacfd4339faaeb9bba0a7052695708d38b +Author: Aaron Bockover +Date: Fri Aug 25 19:25:52 2006 + + Initial import of taglib-sharp; moved from forge + + svn path=/trunk/taglib-sharp/; revision=64394 diff --git a/taglib-sharp/Makefile.am b/taglib-sharp/Makefile.am new file mode 100644 index 0000000..e1d95a4 --- /dev/null +++ b/taglib-sharp/Makefile.am @@ -0,0 +1,76 @@ +SUBDIRS = \ + src \ + examples \ + docs + +if !IN_DIST +SUBDIRS += tests +endif + +DIST_SUBDIRS = \ + src \ + examples \ + docs + +pkgconfig_in_files = taglib-sharp.pc.in +pkgconfigdir = $(datadir)/pkgconfig +pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=.pc) + +EXTRA_DIST = \ + $(pkgconfig_in_files) \ + taglib-sharp.snk \ + taglib-sharp.sln + +DISTCLEANFILES = taglib-sharp.pc + +MAINTAINERCLEANFILES = \ + compile \ + INSTALL \ + config.h.in \ + aclocal.m4 \ + ltmain.sh \ + Makefile.in \ + depcomp \ + missing \ + install-sh \ + configure \ + config.sub \ + config.guess \ + mkinstalldirs + +if !IN_DIST +test: + cd tests; make test; cd ..; +endif + +distwin: all + mkdir -p $(srcdir)/$(WINDIR) + cp $(srcdir)/NEWS $(srcdir)/$(WINDIR)/NEWS.txt + cp $(srcdir)/ChangeLog $(srcdir)/$(WINDIR)/ChangeLog.txt + cp $(srcdir)/COPYING $(srcdir)/$(WINDIR)/COPYING.txt + cp $(srcdir)/README $(srcdir)/$(WINDIR)/README.txt + cp $(srcdir)/AUTHORS $(srcdir)/$(WINDIR)/AUTHORS.txt + if [ -e $(srcdir)/windows-files ]; \ + then cp -r $(srcdir)/windows-files/* $(srcdir)/$(WINDIR); \ + fi + cd $(srcdir)/src && make distwin + zip -9 -r $(srcdir)/$(WINDIR).zip $(srcdir)/$(WINDIR) + rm -rf $(srcdir)/$(WINDIR) + +UPLOAD_HOST = "$$BANSHEE_USER@banshee.fm" +UPLOAD_PATH = "web/download.banshee.fm/taglib-sharp" +push-release: distcheck distwin + [[ -z "$$BANSHEE_USER" ]] && { echo "Set BANSHEE_USER"; exit 1; } || true + [[ -z "$$MONO_USER" ]] && { echo "Set MONO_USER"; exit 1; } || true + mkdir -p release + mv $(WINDIR).zip release + mv $(PACKAGE)-$(VERSION).tar.* release + cp ChangeLog release/$(PACKAGE)-$(VERSION).changes + cp NEWS release/$(PACKAGE)-$(VERSION).news + pushd release; sha256sum * > $(PACKAGE)-$(VERSION).sha256sum; popd + scp -r release $(UPLOAD_HOST):$(UPLOAD_PATH)/$(VERSION) + rm -rf release + ssh $(UPLOAD_HOST) rm -f $(UPLOAD_PATH)/LATEST-IS\* + ssh $(UPLOAD_HOST) touch $(UPLOAD_PATH)/LATEST-IS-$(VERSION) + git tag -a -m "Tag for taglib-sharp release ${VERSION}" taglib-sharp-${VERSION} || bail "Could not create tag" + git push origin taglib-sharp-${VERSION} || bail "Failed to push tag to remote" diff --git a/taglib-sharp/NEWS b/taglib-sharp/NEWS new file mode 100644 index 0000000..a008b5f --- /dev/null +++ b/taglib-sharp/NEWS @@ -0,0 +1,333 @@ +Version 2.0.4.0 +April 13, 2011 + +Fixes and Features in this release include: + * Support for Photo metadata + + read/write for EXIF, XMP, PNG, JPEG, TIFF + + read support for many RAW formats + + see examples/ParsePhoto.cs + * Support for Matroska metadata reading (eg WebM and .mkv) + * Fix File.ReadBlock for slow connections (bgo#639817) + +Contributors to this release: + Alexander Kojevnikov, Colin Turner, Gabriel Burt, Jeroen Asselman, + Julien Moutte, Marek Habersack, Mike Gemünde, Paul Lange, + Ruben Vermeersch, Stephane Delcroix, Tim Howard + +-------------------------------------------------------------------------------- + +Version 2.0.3.7 +March 20, 2010 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Fixes and Features in this release include: + * Solution/projects migrated to VS format + * Fix ID3v2 unsyncing (bgo#593138) + * Fix ID3v2.3 exetended header size calculation (bgo#604488) + * Make TagLib.File IDisposable (closes any open streams) + * Don't throw an exception if RVA2 data is partially incorrect + * Fall back to nunit-console is nunit-console2 not found (bgo#593673) + * Add build check for `al` tool (bgo#575303) + +Contributors to this release: + Alexander Kojevnikov, Andrés G. Aragoneses, Bertrand Lorentz, + Eamon Nerbonne, Ruben Vermeersch + +-------------------------------------------------------------------------------- + +Version 2.0.3.6 +February 24, 2010 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Fixes and Features in this release include: + * Reverse small API break introduced in 2.0.3.5 + +Contributors to this release: + Gabriel Burt + +-------------------------------------------------------------------------------- + +Version 2.0.3.5 +February 23, 2010 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Fixes and Features in this release include: + * Add BitsPerSample property (bgo#610585) + * Support COMPILATION in ogg (bgo#586336) + * Fix removing some/all tag-types (bgo#574653) + +Contributors to this release: + Alexander Kojevnikov, Helmut Wahrmann + +-------------------------------------------------------------------------------- + +Version 2.0.3.4 +January 26, 2010 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Get releases from http://download.banshee-project.org/taglib-sharp/ + +Fixes and Features in this release include: + * Fix IndexOutOfRangeException (bgo#607376) + * Fix issue with converting/parsing year (bgo#606283) + * Support the 'alis' handler code/track type (bgo#584193) + +-------------------------------------------------------------------------------- + +Version 2.0.3.3 +September 30, 2009 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Get releases from http://download.banshee-project.org/taglib-sharp/ + +Fixes and Features in this release include: + * Be more robust with tags with NULL bytes in the middle (bgo#558123) + * Support AIFF file format (bgo#579261) + * Support ADTS AAC files (bgo#580553) + * Support for m2v files (bgo#574411) + * Support for Sort* values in Ape tags (bgo#571421) + * Add new properties: MusicBrainz, ArtistId, ReleaseId, ReleaseArtistId, + TrackId, DiscId, ReleaseStatus, ReleaseType, ReleaseCountry, MusicIpId, + and AmazonId (bgo#563170) + * Add fallback options for album artist getter (bgo#574652) + * Fixed bug with Ape.Tag's Pictures setter (bgo#575943) + * Fix crashing when parsing some comment frames (bgo#582735) + * Fixed CopyTo method (bgo#572382) + * Fixed typo in Ogg DiscNumber setter that wrote TrackCount + to the DISCTOTAL field (bgo#572382) + * Fixed NRE when calling GetTag on FLAC file (bgo#572380) + * Build improvements + * API documentation fixes + +Contributors to this release: + Alexander Kojevnikov, Andy Beal, Bernd Niedergesaess, Bertrand Lorentz, + Félix Velasco, Gabriel Burt, Gregory S. Chudov, Helmut Wahrmann, + John Millikin, Patrick Dehne + +-------------------------------------------------------------------------------- + +Version 2.0.3.2 +February 16, 2009 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Get releases from http://download.banshee-project.org/taglib-sharp/ + +Contributors to this release: + Aaron Bockover, Andy Beal, Bernd Niedergesaess, + Bertrand Lorentz, Gabriel Burt, John Millikin + +Fixes in this release include: + * Fix infinite loops when reading/writing video files + * Fix parsing ID3v2 with Data Length Indicator set + * Fix install/build issues with the docs + * Fix casing of APE tags + * Add support for *Sort values for artist, album, etc + * Install .pc file to datadir since we're noarch + * New unit tests for AVI files + * Recognize mp1/mp2 extensions and mimetypes + +-------------------------------------------------------------------------------- + +Version 2.0.3.1 +January 20, 2009 + +TagLib# bugs are now tracked at http://bugzilla.gnome.org. + +Contributors to this release: + Andy Beal, Gabriel Burt, Jeffrey Stedfast, John Millikin + +Fixes in this release include: + * Add support for artwork in ogg files + * Recognize .oga, ogv, .m4b, and some other mimetypes + * Add support for Mpeg4 dash atoms + * Fix bug with parsing ID3v2 w/ the tag-wide Unsync flag set + +-------------------------------------------------------------------------------- + +Version 2.0.3.0 +January 10, 2008 + +This release of TagLib# features many bug fixes and a complete rework of the +documentation to better serve the Windows community. Fixes include: + * Make Asf.Tag enumerable. + * Don't duplicate genres stored in "(0)Blues" format. + * Save Id3v2.RelativeVolumeFrame as XRVA and XRV in ID3v2.3 and ID3v2.2. + * Insert new comments before other comment frames in Id3v2.Tag + * Use CultureInfo.CurrentCulture to get the correct comment language in + Id3v2.Tag. + * Skip iTunes comments in Id3v2.CommentsFrame. + * Save multi-string values as a single box with a semicolon separator + in Mpeg4.AppleTag to improve compatability with iTunes. + * Make the Id3v2.Tag.DefaultVersion = 3 because most commercial programs + have some crippling ID3v2.4 problem. + * Added Id3v2.Tag.IsCompilation + * Don't crash on misformatted field in XiphComment. + * Recognize the .divx extension as a RIFF file. + * Use one byte rather than four to store compilation in Mpeg4.AppleTag. + * Don't check the image format flags anymore in Mpeg4.AppleTag, just use + the file contents. + * Don't crash in NonContainer.EndTag when the file is less than 128 + bytes. + * Allow saving of multi-page comment packets in Ogg through massive + rewrite of pagination. + * Allow correct reading of multi-page comment packets in Ogg.Bitstream. + * Use try/finally on all load and save operations to prevent files from + being left open. + * Produce correct output on empty ID3v1 tag. + * Remove broken Id3v1.Tag.IsEmpty. + * src/TagLib/Riff/List.cs: Make sure fields are cleared when SetValue + * Clear value when null is passed in Riff.List.SetValue. + * Make Riff.DivXTag.Clear clear the title. + * Read genres correctly in Riff.MovieIdTag. + * Complete codec descriptions for RIFF and ASF files. + * Fix reading of UTF16-BE Id3v2.SynchronizedLyricsFrames. + * Throw NotImplementedException for private frames in ID3v2.2. + * Fix writing Id3v2.GeneralEncapulatedObjectFrame in UTF16. + * Added support for multiple non-indexed artists in ID3v2.3 + * Correctly parse nil separated UTF-16BE strings. + * Allow parsing of variable length years in Ape.Tag. + * Fix writing of Mpeg4 files by correctly reading in values to + Mpeg4.FileParser.UtdaTree. + * Allow parsing of all year lengths in Mpeg4.AppleTag and correctly + clear zeroed values. + * Use Semicolons rather than commas in Tag.Joined* to reflect the + behavior of Windows Media Player. + * Remove "WM/GenreID" from Asf.Tag when storing a new genre. + * Switch ordering of check in looking for ASF content descriptors to + emphasize name rather than order. + * Don't throw exception on zero byte strings in ByteVector.ToString (). + * Use ContentDescriptionObject.Copyright in Asf.Tag. + * Switch order of play_duration and send_duration in Asf.HeaderObject. + This is backwards from the specification but conforms to actual files. + * Don't count preroll in ASF durations. + * Don't double-count position when counting frames. + * Ensure Id3v2.FrameHeader is converting headers from versions 2 and 3. + * Always set the encoding to default in Id3v2.Tag when writing a frame + to prevent misencoding. + * Stopped ArgumentOutOfRangeExceptions from occuring when corrupt + RelativeVolumeframe is encountered. + * Fixed rendering of Ape.Item on non-latin characters. + * Added new constructors to Picture to obsolete CreateFromFile, + CreateFromPath. + * Changed Asf.Tag to write large pictures to the ASF Metadata Library + Object rather than ignoring them. + * Changed the way Mpeg.AudioHeader checked for Xing identifier to + prevent first change exception if none was found. + * Use StringBuilder instead of string addition. + * Don't crash if Mpeg4.IsoHandlerBox does not contain a nil delimiter. + * Limit scanning in Mpeg.AudioFile to 4096 bytes of audio stream to + prevent reading whole file if corrupt. + * Replace protected CombinedTag constructor with public one to allow + compiling in Orcas. + * Include MonoDevelop files in distributed package. + * Correctly parse beats per minute when they contain floating point + numbers. + +Added features: + * Added support for Fraunhofer VBRI header. (Authored by hwahrmann.) + * Obsoleted Tag.Duplicate in favor of Tag.CopyTo which can be extended + to provide better support for copying between matching tag types. + * Added ByteVector.UseBrokenLatin1Behavior that when true reads tags + from the system encoding instead of Latin1. + * Added support for reading APE files. (Authored by hwahrmann.) + * Added generic Id3v2.GetFrames() to reduce casting. + * Added support for one of each type of cover image in Ape.Tag + * Added recognition of BMP and GIF images in Picture. + * Added Id3v2.PopularimeterFrame capable of handling ratings from + Windows Media Player. + * Added Id3v2.Tag.UseNumericGenres which can be disabled to prevent + genres from being written as indices. + * Added File.InvariantStartPosition and File.InvariantEndPosition to + mark the edges of the media portion of the file. + +Special thanks to those who contributed since the last release: + AgentS, codi, craig, Dakuja, DavidT@Imerge, evgeni, hwahrmann, jms, + jmurphy, jocker, jonx, jposen, kajic, kurros, nokturnal, oliphant, + renzska, sambeckett, sukhjinder, and anyone else who I may have + forgotten. + +-------------------------------------------------------------------------------- + +Version 2.0.2.0 +July 3, 2007 + +This is the second bug fix release for TagLib#. Fixes include: + * Read AttachedPictureFrame correctly when UTF-16 encoded. + * Stop infinite recursion with rare Xing header. + * Add "VBR" to the MPEG Audio description if a Xing header is present. + * Update unit tests for changes in 2.0.1. + * Fix Artists (added in 2.0.1) to point to Performers. Was pointing + nowhere. + * Make ByteVector.Find return correctly if (data.Count == pattern.Count + + offset). + * Set to this.data instead of data in PrivateFrame constructor. + +Outstanding bugs: + * MPEG-4 tags do not show up in Nokia N95 Phone. + * Large pictures should be stored in the ASF HeaderExtensionObject. + +Outstanding feature requests: + * Add slow read support to get correct information from VBR MP3's + lacking Xing headers. + * Add TagLib.Tag.Key + * Add TagLib.Id3v2.PopularimeterFrame + * Support ID3v2 chapters. + * Return invariant data sections for a file. + +Special thanks to those who contributed in some way to the project over the past +year: + Aaron Bockover, Alan, Alexander Hixon, Andrés Gómez Aragoneses, + Clint Banzhaf, D Bera, David Wu, Da_FileServer, Dennis Cranston, + Fabrice Deshayes aka Xtream, Gabriel Rosenhouse, gozza11, Gustavo Rubio, + Herman Mahone, HugoPalma, Ilya Konstantinov, Ion Todirel, jc BAUDHUIN, + jmurphy, JustinC, lindea, Michael Monreal, maciej, mikec, mtampe, + Patrick Laplante, pipes, renzska, sambeckett, Sebastian Dröge, + Timm Preetz, wilson, and anyone else who I may have forgotten. + +-------------------------------------------------------------------------------- + +Version 2.0.1 +June 24, 2007 + +This is the first bug fix release for TagLib#. Fixes include: + * Use Picard Tag mapping for all tags to improve constistency. + * Add JoinedAlbumArtists and FirstAlbumArtist for clarity. + * Add Artist pointing to Performers with an ObsoleteAttribute. + * Handle ID3v2 comments ending with text delimiters better. + * Clear ID3v2 pictures when Pictures is set to null. + * Don't try storing pictures larger than 64K in ASF files. + * Don't throw an exception when saving MPEG-4 files without UTDA boxes. + * Fix the clearing of MPEG-4 boxes. + * Use Box.DataSize instead of Header.DataSize when calculating the + MPEG-4 padding. + * Recognize WMA Lossless in the codec description. + +Outstanding bugs: + * MPEG-4 tags do not show up in Nokia N95 Phone. + +Special thanks to those who contributed in some way to the project over the past +year: + Aaron Bockover, Alan, Alexander Hixon, Andrés Gómez Aragoneses, + Clint Banzhaf, D Bera, David Wu, Da_FileServer, Dennis Cranston, + Fabrice Deshayes aka Xtream, Gabriel Rosenhouse, gozza11, Gustavo Rubio, + Herman Mahone, HugoPalma, Ilya Konstantinov, Ion Todirel, jc BAUDHUIN, + jmurphy, JustinC, lindea, Michael Monreal, maciej, mikec, mtampe, + Patrick Laplante, renzska, Sebastian Dröge, Timm Preetz, wilson, and + anyone else who I may have forgotten. + +-------------------------------------------------------------------------------- + +Version 2.0.0 +June 11, 2007 + +This is the first stable release of TagLib#. TagLib# is a .NET 2.0 library for +reading and writing tagging data from audio and video files. In addition it +supports the reading of audio and video properties and can be used for media +validation. Special thanks to Aaron Bockover and Da_FileServer their help, and +everyone who has submitted a bug report or feature request. diff --git a/taglib-sharp/README b/taglib-sharp/README new file mode 100644 index 0000000..a82af0c --- /dev/null +++ b/taglib-sharp/README @@ -0,0 +1,29 @@ +TagLib# (aka taglib-sharp) is a library for reading and writing +metadata in media files, including video, audio, and photo formats. + +It is API stable, with only API additions (not changes or removals) +occuring in the 2.0 series. + + * Bugs: http://bugzilla.gnome.org/browse.cgi?product=taglib-sharp + * Tarballs: http://download.banshee.fm/taglib-sharp/ + * IRC: Several TagLib# developers are often in #banshee on irc.gnome.org + * Git: http://github.com/mono/taglib-sharp + git://github.com/mono/taglib-sharp.git + +TagLib# is free/open source software, released under the LGPL. +We welcome contributions! Please try to match our coding style, +and include unit tests with any patches. Patches can be submitted +by filing a bug and attaching the diff to it. + +To Build From Git: +git clone git://github.com/mono/taglib-sharp.git +cd taglib-sharp +./autogen.sh && make + +To Build From Tarball: +./configure && make + +You can also build from MonoDevelop or Visual Studio using taglib-sharp.sln + +To Test: +make test diff --git a/taglib-sharp/autogen.sh b/taglib-sharp/autogen.sh new file mode 100644 index 0000000..bce3a51 --- /dev/null +++ b/taglib-sharp/autogen.sh @@ -0,0 +1,136 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# Ripped off from GNOME macros version + +DIE=0 + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +if [ -n "$MONO_PATH" ]; then + # from -> /mono/lib:/another/mono/lib + # to -> /mono /another/mono + for i in `echo ${MONO_PATH} | tr ":" " "`; do + i=`dirname ${i}` + if [ -n "{i}" -a -d "${i}/share/aclocal" ]; then + ACLOCAL_FLAGS="-I ${i}/share/aclocal $ACLOCAL_FLAGS" + fi + if [ -n "{i}" -a -d "${i}/bin" ]; then + PATH="${i}/bin:$PATH" + fi + done + export PATH +fi + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`autoconf' installed to compile Mono." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +if [ -z "$LIBTOOL" ]; then + LIBTOOL=`which glibtool 2>/dev/null` + if [ ! -x "$LIBTOOL" ]; then + LIBTOOL=`which libtool` + fi +fi + +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && { + ($LIBTOOL --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`libtool' installed to compile Mono." + echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +grep "^AM_GNU_GETTEXT" $srcdir/configure.ac >/dev/null && { + grep "sed.*POTFILES" $srcdir/configure.ac >/dev/null || \ + (gettext --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`gettext' installed to compile Mono." + echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`automake' installed to compile Mono." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + NO_AUTOMAKE=yes +} + + +# if no automake, don't bother testing for aclocal +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing \`aclocal'. The version of \`automake'" + echo "installed doesn't appear recent enough." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "**Warning**: I am going to run \`configure' with no arguments." + echo "If you wish to pass any to it, please specify them on the" + echo \`$0\'" command line." + echo +fi + +case $CC in +xlc ) + am_opt=--include-deps;; +esac + + +if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then + if test -z "$NO_LIBTOOLIZE" ; then + echo "Running libtoolize..." + ${LIBTOOL}ize --force --copy + fi +fi + +echo "Running aclocal $ACLOCAL_FLAGS ..." +aclocal $ACLOCAL_FLAGS || { + echo + echo "**Error**: aclocal failed. This may mean that you have not" + echo "installed all of the packages you need, or you may need to" + echo "set ACLOCAL_FLAGS to include \"-I \$prefix/share/aclocal\"" + echo "for the prefix where you installed the packages whose" + echo "macros were not found" + exit 1 +} + +if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then + echo "Running autoheader..." + autoheader || { echo "**Error**: autoheader failed."; exit 1; } +fi + +echo "Running automake --gnu $am_opt ..." +automake --add-missing --gnu $am_opt || + { echo "**Error**: automake failed."; exit 1; } +echo "Running autoconf ..." +autoconf || { echo "**Error**: autoconf failed."; exit 1; } + + +conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c + +if test x$NOCONFIGURE = x; then + echo Running $srcdir/configure $conf_flags "$@" ... + $srcdir/configure $conf_flags "$@" \ + && echo Now type \`make\' to compile $PKG_NAME || exit 1 +else + echo Skipping configure process. +fi diff --git a/taglib-sharp/configure.ac b/taglib-sharp/configure.ac new file mode 100644 index 0000000..4114783 --- /dev/null +++ b/taglib-sharp/configure.ac @@ -0,0 +1,153 @@ +AC_INIT([taglib-sharp], [2.0.4.0]) +AM_INIT_AUTOMAKE([1.9 dist-bzip2 tar-ustar]) +AM_MAINTAINER_MODE + +ASSEMBLY_NAME="$PACKAGE" +ASSEMBLY_VERSION="$VERSION" + +POLICY_2_0_VERSIONS="2.0.0.0-$ASSEMBLY_VERSION" +AC_SUBST(POLICY_2_0_VERSIONS) + +AC_SUBST(VERSION) +AC_SUBST(ASSEMBLY_VERSION) +AC_SUBST(ASSEMBLY_NAME) + +AC_PROG_INSTALL +AC_PROG_GREP + +MONODOC_REQUIRED=1.1.9 + +WINDIR="$ASSEMBLY_NAME-$VERSION-windows" +AC_SUBST(WINDIR) + +DISTCHECK_CONFIGURE_FLAGS="--disable-docs" +AC_SUBST(DISTCHECK_CONFIGURE_FLAGS) + +dnl Check for Mono +AC_PATH_PROG(MCS, gmcs) +if test x$MCS = x; then + AC_MSG_ERROR(You need mcs) +fi + +AC_PATH_PROG(MONO, mono) +if test x$MONO = x; then + AC_MSG_ERROR(You need mono) +fi + +MCS_FLAGS="-codepage:utf8 -debug" +MONO_FLAGS= + +if test $USE_MAINTAINER_MODE = yes; then + MONO_FLAGS="$MONO_FLAGS --debug" +fi + +AC_SUBST(MCS_FLAGS) +AC_SUBST(MONO_FLAGS) + +AC_PATH_PROG(AL, al) +if test "x$AL" = "x"; then + AC_MSG_ERROR([No al tool found. You need to install mono]) +fi + +dnl GAC +AC_PATH_PROG(GACUTIL, gacutil) +if test x$GACUTIL = x; then + AC_MSG_ERROR(You need gacutil) +fi + +GACUTIL_FLAGS='/package $(ASSEMBLY_NAME) /gacdir $(prefix)/lib /root $(DESTDIR)$(prefix)/lib' +AC_SUBST(GACUTIL_FLAGS) +GACUTIL_POLICY_FLAGS='/gacdir $(prefix)/lib /root $(DESTDIR)$(prefix)/lib' +AC_SUBST(GACUTIL_POLICY_FLAGS) + +AC_ARG_ENABLE(docs, AC_HELP_STRING([--disable-docs], [Do not build documentation]), with_docs=no, with_docs=yes) + +PKG_PROG_PKG_CONFIG + +dnl Monodoc +if test "x$with_docs" = "xyes"; then + AC_PATH_PROG(MONODOCER, monodocer, no) + if test "x$MONODOCER" = "xno"; then + AC_MSG_ERROR([You need to install monodoc, or pass --disable-docs to configure to skip documentation installation]) + fi + + AC_PATH_PROG(MDASSEMBLER, mdassembler, no) + if test "x$MDASSEMBLER" = "xno"; then + AC_MSG_ERROR([You need to install mdassembler, or pass --disable-docs to configure to skip documentation installation]) + fi + + DOCDIR=`$PKG_CONFIG monodoc --variable=sourcesdir` + AC_SUBST(DOCDIR) + AM_CONDITIONAL(BUILD_DOCS, true) +else + AC_MSG_NOTICE([not building Banshee API documentation]) + AM_CONDITIONAL(BUILD_DOCS, false) +fi + +# checking for ICSharpCode.SharpZipLib.dll +AC_MSG_CHECKING([Mono GAC for ICSharpCode.SharpZipLib.dll]) +if $GACUTIL -l | $GREP -q ICSharpCode.SharpZipLib; \ + then \ + AC_MSG_RESULT([found]) + AM_CONDITIONAL(HAVE_SHARPZIPLIB, true) +else + AC_MSG_RESULT([not found]) + AM_CONDITIONAL(HAVE_SHARPZIPLIB, false) +fi + + +PKG_CHECK_MODULES(GNOME_SHARP, gnome-sharp-2.0, have_gnome_sharp=yes, have_gnome_sharp=no) +if test "x$have_gnome_sharp" = "xyes"; then + AC_SUBST(GNOME_SHARP_LIBS) + AM_CONDITIONAL(HAVE_GNOME_SHARP, true) +else + AM_CONDITIONAL(HAVE_GNOME_SHARP, false) +fi + +PKG_CHECK_MODULES(EXIV2, exiv2, have_exiv2=yes, have_exiv2=no) +if test "x$have_exiv2" = "xyes"; then + AC_SUBST(EXIV2_LIBS) + AM_CONDITIONAL(HAVE_EXIV2, true) +else + AM_CONDITIONAL(HAVE_EXIV2, false) +fi + +PKG_CHECK_MODULES(MONO_NUNIT, mono-nunit >= 1.0, do_tests="yes", do_tests="no") AC_SUBST(MONO_NUNIT_LIBS) +AM_CONDITIONAL(ENABLE_TESTS, test "x$do_tests" = "xyes") +if test "x$do_tests" = "xno"; then + AC_MSG_WARN([Could not find mono-nunit: tests will not be available.]) +else + AC_PATH_PROG(NUNIT_CMD, nunit-console2, nunit-console) + AC_SUBST(NUNIT_CMD) +fi + +AC_ARG_ENABLE(raw-tests, AC_HELP_STRING([--enable-raw-tests], [Enable RAW image files NUnit tests]), + enable_raw_tests=$enableval, enable_raw_tests="no") +if test "x$enable_raw_tests" = "xno"; then + AC_MSG_WARN([RAW image file tests disabled.]) + AM_CONDITIONAL(ENABLE_RAW_TESTS, false) +else + AM_CONDITIONAL(ENABLE_RAW_TESTS, true) +fi + +AC_CONFIG_FILES([ +Makefile +taglib-sharp.pc +src/Makefile +src/AssemblyInfo.cs +src/policy.2.0.taglib-sharp.config +examples/Makefile +docs/Makefile +docs/Package.en.xml +]) + +# Test suite is not shipped, only builds from git. +if test -d tests; then + AC_CONFIG_FILES([tests/Makefile]) + AM_CONDITIONAL(IN_DIST, false) +else + AM_CONDITIONAL(IN_DIST, true) +fi +AC_OUTPUT + +echo "TagLib# ($ASSEMBLY_NAME-$ASSEMBLY_VERSION) is ready to be compiled." diff --git a/taglib-sharp/docs/Makefile.am b/taglib-sharp/docs/Makefile.am new file mode 100644 index 0000000..67cdbb5 --- /dev/null +++ b/taglib-sharp/docs/Makefile.am @@ -0,0 +1,66 @@ +DOC_UPDATER = @MONODOCER@ -delete -pretty +DOC_ASSEMBLER = @MDASSEMBLER@ --out taglib-sharp-docs --ecma + +ASSEMBLY = $(top_builddir)/src/$(ASSEMBLY_NAME).dll +SLASHDOC = $(ASSEMBLY).xml + +if BUILD_DOCS +all: XmlInjector.exe + +XmlInjector.exe: XmlInjector.cs + $(MCS) -out:$@ -r:System.Xml $< + +monodocdir = $(DOCDIR) +monodoc_DATA = \ + taglib-sharp-docs.zip \ + taglib-sharp-docs.tree \ + taglib-sharp-docs.source + +en/index.xml: $(ASSEMBLY) $(SLASHDOC) XmlInjector.exe Package.en.xml +# monodocer will create duplicate tags if run multiple times. Delete the whole +# directory and start over. + if [ -d en ]; then \ + rm -rf en; \ + fi + $(DOC_UPDATER) -assembly:$(ASSEMBLY) -importslashdoc:$(SLASHDOC) -path:en > /dev/null + $(MONO) XmlInjector.exe Package.en.xml InsertMissingValues + +update-html: en + if [ -d taglib-sharp-web-docs ]; then \ + rm -rf taglib-sharp-web-docs; \ + fi; \ + mkdir taglib-sharp-web-docs; \ + monodocs2html -o taglib-sharp-web-docs en; + +taglib-sharp-docs.tree: taglib-sharp-docs.zip + +taglib-sharp-docs.zip: en/index.xml + $(DOC_ASSEMBLER) en + +install-data-hook: XmlInjector.exe Package.en.xml + $(MONO) XmlInjector.exe Package.en.xml InjectMenuItem + +uninstall-hook: XmlInjector.exe Package.en.xml + $(MONO) XmlInjector.exe Package.en.xml RemoveMenuItem + +clean-local: + if [ -d en ]; then \ + rm -rf en; \ + fi + +endif + +EXTRA_DIST = \ + taglib-sharp-docs.source \ + XmlInjector.cs \ + Package.en.xml.in + +DISTCLEANFILES = \ + taglib-sharp-docs.zip \ + taglib-sharp-docs.tree + +MAINTAINERCLEANFILES = \ + Makefile.in + +CLEANFILES = \ + XmlInjector.exe diff --git a/taglib-sharp/docs/Package.en.xml.in b/taglib-sharp/docs/Package.en.xml.in new file mode 100644 index 0000000..381af56 --- /dev/null +++ b/taglib-sharp/docs/Package.en.xml.in @@ -0,0 +1,221 @@ + + + TagLib# + This package provides support for reading and writing + the tagging information for a large number of tagging formats, + as well as reading media properties for many standard audio and video formats. + Copyright (C) 2007-2008 Brian Nickel + + + + TagLib provides a generic interface for reading + media properties and editing tags on different audio and + video files. + The most straightforward way to read a file is + through , which does type detection to create the correct . + + + + + The TagLib.Aac namespace contains classes + for handling the AAC file format. + See + http://www.hydrogenaudio.org/forums/lofiversion/index.php/t21617.html + for the complete specification. + + + + + The TagLib.Aiff namespace contains classes + for handling the AIFF file format. + See + http://en.wikipedia.org/wiki/Audio_Interchange_File_Format for + the complete specification. + + + + + The TagLib.Ape namespace contains classes + for reading APE tags. + See + http://wiki.hydrogenaudio.org/index.php?title=APEv2 for + the complete specification. + + + + + The TagLib.Asf namespace contains classes for + handling the Microsoft Advanced Systems Format file + format. + See + http://www.microsoft.com/windows/windowsmedia/forpros/format/asfspec.aspx + for the complete specification. + + + + + The TagLib.Flac namespace contains classes for + handling the Xiph FLAC file format. + See http://flac.sourceforge.net/format.html for + the complete specification. + + + + + The TagLib.Id3v1 namespace contains classes for + handling the ID3v1.1 tagging format. + See http://www.id3.org/ID3v1 for the complete + specification. + + + + + The TagLib.Id3v2 namespace contains classes for + handling the ID3v2 tagging format. + See http://www.id3.org/Developer_Information + for the complete specification. + + + + + The TagLib.Mpeg4 namespace contains classes for + handling the MPEG-4 file format. + See + http://standards.iso.org/ittf/PubliclyAvailableStandards/c041828_ISO_IEC_14496-12_2005(E).zip + for the complete specification. + + + + + The TagLib.Mpeg namespace contains classes for handling + MPEG-1/2 files and MPEG audio files. + + + + + + The TagLib.MusePack namespace contains classes for + handling the MusePack file format. + See http://www.musepack.net/ for the complete + specification. + + + + + The TagLib.NonContainer namespace provides + classes for dealing with files that do not have a + standardized tagging mechanism and may have any number + of tags at their beginning or end. + The FLAC file format is included in this + because despite having a standard tagging mechanism, ID3 + and APE tags are not uncommonly attached to the + file. + + + + + The TagLib.Ogg.Codecs namespace contains + standard codecs used in Xiph Ogg files. + + + + + + The TagLib.Ogg namespace contains classes for + handling the Xiph OGG file format. + See http://www.xiph.org/ogg/ for the complete + specification. + + + + + The TagLib.Riff namespace contains all classes + relevant to the reading of Microsoft RIFF files. These + files include namely the WAV and AVI file + formats. + See + http://msdn2.microsoft.com/en-us/library/ms779636.aspx + for information on the RIFF AVI format. + + + + + The TagLib.WavPack namespace contains all + classes relevant to the reading of WavPack + files. + See http://www.wavpack.com/ for the complete + specification. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/taglib-sharp/docs/XmlInjector.cs b/taglib-sharp/docs/XmlInjector.cs new file mode 100644 index 0000000..94a3587 --- /dev/null +++ b/taglib-sharp/docs/XmlInjector.cs @@ -0,0 +1,191 @@ +/*************************************************************************** + * XmlInjector.cs + * + * Copyright (C) 2008 Brian Nickel + * Written by Brian Nickel (brian.nickel@gmail.com) + ****************************************************************************/ + +/* THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +using System; +using System.Xml; + +public static class XmlInjector +{ + public static int Main (string [] args) + { + if (args.Length != 2) { + Console.WriteLine ("XmlInjector.exe ACTIONFILE.XML ACTION_NAME"); + return 1; + } + + XmlDocument doc = new XmlDocument (); + try { + doc.Load (args [0]); + } catch { + Console.WriteLine ("Could not open {0}.", args [0]); + return 1; + } + + string dir = System.IO.Directory.GetParent (args [0]).FullName; + Console.WriteLine ("Setting working directory to {0}.", dir); + System.IO.Directory.SetCurrentDirectory (dir); + + string path = string.Format ("//ActionSet[@Name='{0}']/File[@Path]", args [1]); + foreach (XmlNode node in doc.SelectNodes (path)) + if (!RunFileAction (node)) + return 1; + + return 0; + } + + private static bool RunFileAction (XmlNode fileElement) + { + string path = GetAttribute (fileElement, "Path"); + XmlDocument doc = new XmlDocument (); + try { + doc.Load (path); + } catch { + Console.WriteLine ("ERROR: Could not open {0}.", path); + return false; + } + + Console.WriteLine ("Processing {0}...", path); + + foreach (XmlNode element in fileElement.SelectNodes ("Replace")) + if (!ReplaceNode (fileElement.OwnerDocument, doc, element)) + return false; + + foreach (XmlNode element in fileElement.SelectNodes ("Insert")) + if (!InsertNode (fileElement.OwnerDocument, doc, element)) + return false; + + foreach (XmlNode element in fileElement.SelectNodes ("Remove")) + if (!RemoveNodes (doc, element)) + return false; + + doc.Save (path); + Console.WriteLine ("{0} saved.", path); + return true; + } + + private static bool ReplaceNode (XmlDocument sourceDocument, + XmlDocument targetDocument, + XmlNode replaceElement) + { + string sourcePath = GetAttribute (replaceElement, "Source"); + string targetPath = GetAttribute (replaceElement, "Target"); + + if (OperationNotNeccessary (targetDocument, replaceElement)) { + Console.WriteLine (" Skipping replacement of {0}.", targetPath); + return true; + } + + Console.WriteLine (" Replacing {0}.", targetPath); + XmlNode sourceNode = sourcePath == null ? null : sourceDocument.SelectSingleNode (sourcePath); + XmlNode targetNode = targetPath == null ? null : targetDocument.SelectSingleNode (targetPath); + + if (sourceNode == null) + sourceNode = replaceElement.FirstChild; + + if (sourceNode == null) { + Console.WriteLine ("ERROR: Could not find source node: {0}", sourcePath); + return false; + } + + if (targetNode == null) { + Console.WriteLine ("ERROR: Could not find target node: {0}", targetPath); + return false; + } + + targetNode.ParentNode.ReplaceChild (targetDocument.ImportNode (sourceNode, true), targetNode); + return true; + } + + private static bool InsertNode (XmlDocument sourceDocument, XmlDocument targetDocument, XmlNode insertElement) + { + string sourcePath = GetAttribute (insertElement, "Source"); + string targetPath = GetAttribute (insertElement, "Target"); + + if (OperationNotNeccessary (targetDocument, insertElement)) { + Console.WriteLine (" Skipping insertion into {0}.", targetPath); + return true; + } + + Console.WriteLine (" Inserting into {0}.", targetPath); + XmlNode sourceNode = sourcePath == null ? null : sourceDocument.SelectSingleNode (sourcePath); + XmlNode targetNode = targetPath == null ? null : targetDocument.SelectSingleNode (targetPath); + + if (sourceNode == null) + sourceNode = insertElement.FirstChild; + + if (sourceNode == null) { + Console.WriteLine ("ERROR: Could not find source node: {0}", sourcePath); + return false; + } + + if (targetNode == null) { + Console.WriteLine ("ERROR: Could not find target node: {0}", targetPath); + return false; + } + + targetNode.AppendChild (targetDocument.ImportNode (sourceNode, true)); + return true; + } + + private static bool RemoveNodes (XmlDocument targetDocument, + XmlNode removeElement) + { + string targetPath = GetAttribute (removeElement, "Target"); + + if (OperationNotNeccessary (targetDocument, removeElement)) { + Console.WriteLine (" Skipping removal of {0}.", targetPath); + return true; + } + + Console.WriteLine (" Removing {0}.", targetPath); + + while (true) { + XmlNode targetNode = targetDocument.SelectSingleNode (targetPath); + + if (targetNode == null) + return true; + + targetNode.ParentNode.RemoveChild (targetNode); + } + } + + private static bool OperationNotNeccessary (XmlDocument targetDocument, XmlNode actionElement) + { + string ifMissingPath = GetAttribute (actionElement, "IfMissing"); + if (ifMissingPath != null && targetDocument.SelectSingleNode (ifMissingPath) != null) + return true; + + return false; + } + + private static string GetAttribute (XmlNode node, string attribute) + { + XmlAttribute xmlAttr = node.Attributes [attribute]; + return xmlAttr == null ? null : xmlAttr.Value; + } +} diff --git a/taglib-sharp/docs/taglib-sharp-docs.source b/taglib-sharp/docs/taglib-sharp-docs.source new file mode 100644 index 0000000..ab765cd --- /dev/null +++ b/taglib-sharp/docs/taglib-sharp-docs.source @@ -0,0 +1,4 @@ + + + + diff --git a/taglib-sharp/examples/.gitignore b/taglib-sharp/examples/.gitignore new file mode 100644 index 0000000..b6d1beb --- /dev/null +++ b/taglib-sharp/examples/.gitignore @@ -0,0 +1,2 @@ +extractKey +listData diff --git a/taglib-sharp/examples/BatchSet.cs b/taglib-sharp/examples/BatchSet.cs new file mode 100644 index 0000000..bdc5279 --- /dev/null +++ b/taglib-sharp/examples/BatchSet.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using TagLib; + +public class BatchSet +{ + private enum Mode { + Tag, Value, File + } + + public static void Main(string [] args) + { + if(args.Length < 3) { + Console.Error.WriteLine ("USAGE: BatchSet.exe -tag value [-tag2 value ...] File1 [File2 ...]"); + return; + } + + Mode mode = Mode.Tag; + List files = new List (); + Dictionary tags = new Dictionary (); + + string tag = null; + + foreach (string str in args) { + if (mode == Mode.Tag) { + if (str [0] == '-') { + if (str == "--") { + mode = Mode.File; + } else { + tag = str.Substring (1); + mode = Mode.Value; + } + + continue; + } + mode = Mode.File; + } + + if (mode == Mode.Value) { + if (!tags.ContainsKey (tag)) + tags.Add (tag, str); + mode = Mode.Tag; + continue; + } + + if (mode == Mode.File) + files.Add (str); + } + + foreach (string filename in files) { + TagLib.File file = TagLib.File.Create (filename); + if (file == null) + continue; + + Console.WriteLine ("Updating Tags For: " + filename); + + foreach (string key in tags.Keys) { + string value = tags [key]; + try { + switch (key) { + case "id3version": + byte number = byte.Parse (value); + if (number == 1) { + file.RemoveTags (TagTypes.Id3v2); + } else { + TagLib.Id3v2.Tag v2 = + file.GetTag (TagTypes.Id3v2, true) + as TagLib.Id3v2.Tag; + + if (v2 != null) + v2.Version = number; + } + break; + case "album": + file.Tag.Album = value; + break; + case "artists": + file.Tag.AlbumArtists = value.Split (new char [] {';'}); + break; + case "comment": + file.Tag.Comment = value; + break; + case "lyrics": + file.Tag.Lyrics = value; + break; + case "composers": + file.Tag.Composers = value.Split (new char [] {';'}); + break; + case "disc": + file.Tag.Disc = uint.Parse (value); + break; + case "disccount": + file.Tag.DiscCount = uint.Parse (value); + break; + case "genres": + file.Tag.Genres = value.Split (new char [] {';'}); + break; + case "performers": + file.Tag.Performers = value.Split (new char [] {';'}); + break; + case "title": + file.Tag.Title = value; + break; + case "track": + file.Tag.Track = uint.Parse (value); + break; + case "trackcount": + file.Tag.TrackCount = uint.Parse (value); + break; + case "year": + file.Tag.Year = uint.Parse (value); + break; + case "pictures": + List pics = new List (); + if (!string.IsNullOrEmpty (value)) + foreach (string path in value.Split (new char [] {';'})) { + pics.Add (new Picture (path)); + } + file.Tag.Pictures = pics.ToArray (); + break; + } + } catch (Exception e) { + Console.WriteLine ("Error setting tag " + key + ":"); + Console.WriteLine (e); + } + } + + file.Save(); + } + } +} diff --git a/taglib-sharp/examples/GenerateTestFixture.cs b/taglib-sharp/examples/GenerateTestFixture.cs new file mode 100644 index 0000000..97e59f2 --- /dev/null +++ b/taglib-sharp/examples/GenerateTestFixture.cs @@ -0,0 +1,924 @@ +// +// This application parses a photo and compares the output to the output of exiv2. +// +// It can be used to make test fixtures. Manual validation is always required. +// +// You need the exiv2 app for this to work. +// + +using GLib; +using System; +using System.Text; +using System.Collections.Generic; +using System.Security.Cryptography; +using TagLib; +using TagLib.IFD; +using TagLib.IFD.Tags; +using TagLib.Xmp; + +public class GenerateTestFixtureApp +{ + private static MD5 md5 = MD5.Create (); + + public static void Main (string [] args) + { + if(args.Length != 2) { + Console.Error.WriteLine ("USAGE: mono GenerateTestFixture.exe NAME PATH"); + return; + } + + string name = args[0]; + string path = args[1]; + + EmitHeader (name, path); + GenerateIFDFixture (name, path); + GenerateXMPFixture (name, path); + EmitFooter (); + } + + static Dictionary sub_ifds = new Dictionary (); + static Dictionary sub_ifds_emitted = new Dictionary (); + + static void GenerateIFDFixture (string name, string path) + { + // First run exiv2 on it. + string output, err; + int code; + var result = GLib.Process.SpawnCommandLineSync (String.Format ("./listData e {0}", path), out output, out err, out code); + if (!result) { + Console.Error.WriteLine ("Invoking listData failed, are you running from the examples folder?"); + return; + } + + Write ("// ---------- Start of IFD tests ----------"); + + foreach (string line in output.Split ('\n')) { + string[] parts = line.Split (new char[] {'\t'}, 5); + if (parts.Length == 0 || line.Trim ().Equals (String.Empty) || parts.Length != 5) + continue; + string tag_label = parts[0]; + ushort tag = ushort.Parse (parts[1].Substring(2), System.Globalization.NumberStyles.HexNumber); + string ifd = parts[2]; + string type = parts[3]; + uint length = uint.Parse (parts[4]); + + if (ifd == "NikonSi02xx" || ifd == "NikonVr" || ifd == "NikonPc" || ifd == "NikonWt" || ifd == "NikonIi" || ifd == "NikonLd3") { + continue; // Exiv2 makes these up. + } + + string val = ExtractKey (path, String.Format ("Exif.{0}.{1}", ifd, tag_label)); + + if (tag_label == "SubIFDs") { + for (int i = 0; i < val.Split (' ').Length; i++) { + var sub_ifd = String.Format ("SubImage{0}", sub_ifds.Count + 1); + sub_ifds.Add (sub_ifd, sub_ifds.Count); + } + continue; + } + + EnsureIFD (ifd); + + if (tag_label.Equals ("ExifTag")) + type = "SubIFD"; + if (tag_label.Equals ("MakerNote")) { + type = "MakerNote"; + val = String.Empty; // No need to echo. + } + if (tag_label.Equals ("InteroperabilityTag")) + type = "SubIFD"; + if (tag_label.Equals ("GPSTag")) + type = "SubIFD"; + if (tag_label.Equals ("JPEGInterchangeFormat")) + type = "ThumbnailDataIFD"; + if (tag_label.Equals ("Preview") && ifd.Equals ("Nikon3")) + type = "SubIFD"; + if (tag_label.Equals ("UserComment") && ifd.Equals ("Photo")) + type = "UserComment"; + if (tag_label.Equals ("StripOffsets")) + type = "StripOffsets"; + if (tag_label.Equals ("IPTCNAA")) + type = "IPTCNAA"; + if (tag_label.Equals ("XMLPacket")) + type = "XMLPacket"; + + if (ifd.Equals ("MakerNote")) + continue; // Exiv2 makes these up. + + Write ("// {1}.0x{0:X4} ({2}/{3}/{4}) \"{5}\"", tag, ifd, tag_label, type, length, length > 512 ? "(Value ommitted)" : val); + + if (ifd.Equals ("Image")) { + EmitTestIFDEntryOpen ("structure", 0, tag, ifd); + } else if (ifd.Equals ("Thumbnail")) { + EmitTestIFDEntryOpen ("structure", 1, tag, ifd); + } else if (ifd.Equals ("Image2")) { + EmitTestIFDEntryOpen ("structure", 2, tag, ifd); + } else if (ifd.Equals ("Image3")) { + EmitTestIFDEntryOpen ("structure", 3, tag, ifd); + } else if (ifd.Equals ("Photo")) { + EmitTestIFDEntryOpen ("exif_structure", 0, tag, ifd); + } else if (IsPartOfMakernote (ifd)) { + EmitTestIFDEntryOpen ("makernote_structure", 0, tag, ifd); + } else if (ifd.Equals ("NikonPreview")) { + EmitTestIFDEntryOpen ("nikonpreview_structure", 0, tag, ifd); + } else if (ifd.Equals ("Iop")) { + EmitTestIFDEntryOpen ("iop_structure", 0, tag, ifd); + } else if (ifd.Equals ("GPSInfo")) { + EmitTestIFDEntryOpen ("gps_structure", 0, tag, ifd); + } else if (ifd.Equals ("CanonCs")) { + EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.CameraSettings, ifd); + } else if (ifd.Equals ("CanonSi")) { + EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.ShotInfo, ifd); + } else if (ifd.Equals ("CanonCf")) { + EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.CustomFunctions, ifd); + } else if (ifd.Equals ("CanonPi")) { + EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.PictureInfo, ifd); + } else if (ifd.Equals ("CanonFi")) { + EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) 0x93, ifd); + } else if (ifd.Equals ("PanasonicRaw")) { + EmitTestIFDEntryOpen ("pana_structure", 0, tag, ifd); + } else if (sub_ifds.ContainsKey (ifd)) { + EmitTestIFDEntryOpen (String.Format ("{0}_structure", ifd), 0, tag, ifd); + } else { + throw new Exception (String.Format ("Unknown IFD: {0}", ifd)); + } + + if (ifd.Equals ("CanonCs") || ifd.Equals ("CanonSi") || ifd.Equals ("CanonCf") || ifd.Equals ("CanonPi")) { + // This are a made-up directory by exiv2 + EmitTestIFDIndexedShortEntry (tag, val); + } else if (ifd.Equals ("CanonFi")) { + // This are a made-up directory by exiv2 + // And the fist both entries are combined to a long by exiv2. + if (tag == 0x0001) { + string val1 = ((ushort) UInt32.Parse (val)).ToString (); + string val2 = ((ushort) (UInt32.Parse (val) >> 16)).ToString (); + EmitTestIFDIndexedShortEntry (tag, val1); + EmitTestIFDIndexedShortEntry (tag + 1, val2); + } else { + EmitTestIFDIndexedShortEntry (tag, val); + } + } else if (type.Equals ("Ascii")) { + EmitTestIFDStringEntry (val); + } else if (type.Equals ("Short") && length == 1) { + EmitTestIFDShortEntry (val); + } else if (type.Equals ("Short") && length > 1) { + EmitTestIFDShortArrayEntry (val); + } else if (type.Equals ("SShort") && length == 1) { + EmitTestIFDSShortEntry (val); + } else if (type.Equals ("SShort") && length > 1) { + EmitTestIFDSShortArrayEntry (val); + } else if (type.Equals ("Rational") && length == 1) { + EmitTestIFDRationalEntry (val); + } else if (type.Equals ("Rational") && length > 1) { + EmitTestIFDRationalArrayEntry (val); + } else if (type.Equals ("SRational") && length == 1) { + EmitTestIFDSRationalEntry (val); + } else if (type.Equals ("SRational") && length > 1) { + EmitTestIFDSRationalArrayEntry (val); + } else if (type.Equals ("Long") && length == 1) { + EmitTestIFDLongEntry (val); + } else if (type.Equals ("Long") && length > 1) { + EmitTestIFDLongArrayEntry (val); + } else if (type.Equals ("SLong") && length == 1) { + EmitTestIFDSLongEntry (val); + } else if (type.Equals ("Byte") && length == 1) { + EmitTestIFDByteEntry (val); + } else if (type.Equals ("Byte") && length > 1) { + EmitTestIFDByteArrayEntry (val); + } else if (type.Equals ("SByte") && length == 1) { + EmitTestIFDSByteEntry (val); + } else if (type.Equals ("SubIFD")) { + EmitTestIFDSubIFDEntry (val); + } else if (type.Equals ("ThumbnailDataIFD")) { + EmitTestIFDThumbnailDataIFDEntry (val); + } else if (type.Equals ("MakerNote")) { + EmitTestIFDMakerNoteIFDEntry (val); + } else if (type.Equals ("UserComment")) { + EmitTestIFDUserCommentIFDEntry (val); + } else if (type.Equals ("Undefined")) { + EmitTestIFDUndefinedEntry (val); + } else if (type.Equals ("StripOffsets")) { + EmitTestIFDStripOffsetsEntry (val); + } else if (type.Equals ("IPTCNAA")) { + EmitTestIFDIPTCNAAEntry (val); + } else if (type.Equals ("XMLPacket")) { + EmitTestIFDXMLPacketEntry (val); + } else { + throw new Exception ("Unknown type: " + type); + } + + EmitTestIFDEntryClose (); + } + + Write (); + Write ("// ---------- End of IFD tests ----------"); + Write (); + } + + static Dictionary xmp_prefixes = new Dictionary (); + + static void GenerateXMPFixture (string name, string path) + { + // First run exiv2 on it. + string output, err; + int code; + var result = GLib.Process.SpawnCommandLineSync (String.Format ("./listData x {0}", path), out output, out err, out code); + if (!result) { + Console.Error.WriteLine ("Invoking exiv2 failed, do you have it installed?"); + return; + } + + if (output.Trim ().Equals ("")) + return; + + Write (); + Write ("// ---------- Start of XMP tests ----------"); + Write (); + + Write ("XmpTag xmp = file.GetTag (TagTypes.XMP) as XmpTag;"); + + // Build prefix lookup dictionary. + Type t = typeof(XmpTag); + foreach (var member in t.GetMembers()) { + if (!member.Name.EndsWith ("_NS")) + continue; + string val = (member as System.Reflection.FieldInfo).GetValue (null) as string; + string prefix = XmpTag.NamespacePrefixes [val]; + xmp_prefixes [prefix] = member.Name; + } + + foreach (string line in output.Split ('\n')) { + string[] parts = line.Split (new char[] {'\t'}, 3); + if (parts.Length == 0 || line.Trim ().Equals (String.Empty)) + continue; + string label = parts[0]; + string type = parts[1]; + uint length = uint.Parse (parts[2]); + string val = ExtractKey (path, label).Trim (); + + EmitXmpTest (label, type, length, val); + } + + Write (); + Write ("// ---------- End of XMP tests ----------"); + Write (); + } + + static void EmitXmpTest (string label, string type, uint length, string val) + { + if (label.Equals ("Xmp.xmpMM.InstanceID")) + return; // Continue this, exiv2 makes it up from the about attr + if (label.Equals ("Xmp.tiff.Orientation")) + return; // exiv2 destroys this value + + var node_path = label.Split ('/'); + Write ("// {0} ({1}/{2}) \"{3}\"", label, type, length, val); + Write ("{"); + Write ("var node = xmp.NodeTree;"); + + // Navigate to the correct node. + foreach (var node in node_path) { + var parts = node.Split ('.'); + var partscolon = node.Split (':'); + if (parts.Length == 3) { + // Plain node + int index = 0; + string name = parts[2]; + if (parts[2].EndsWith("]")) { + int index_start = parts[2].LastIndexOf ("["); + string index_str = parts[2].Substring (index_start+1, parts[2].Length-index_start-2); + index = int.Parse (index_str); + name = parts[2].Substring (0, index_start); + } + string ns = GetXmpNs (parts[1]); + Write ("node = node.GetChild ({0}, \"{1}\");", ns, name); + Write ("Assert.IsNotNull (node);"); + + if (index > 0) { + Write ("node = node.Children [{0}];", index - 1); + Write ("Assert.IsNotNull (node);"); + } + } else if (partscolon.Length == 2) { + string ns = GetXmpNs (partscolon[0]); + string name = partscolon[1]; + Write ("node = node.GetChild ({0}, \"{1}\");", ns, name); + Write ("Assert.IsNotNull (node);"); + } else { + throw new Exception ("Can't navigate to "+node); + } + } + + if (length > 0 && type.Equals ("XmpText")) { + Write ("Assert.AreEqual (\"{0}\", node.Value);", val); + Write ("Assert.AreEqual (XmpNodeType.Simple, node.Type);"); + Write ("Assert.AreEqual (0, node.Children.Count);"); + } else if (type.Equals ("XmpBag") && length == 1) { + Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);"); + Write ("Assert.AreEqual (\"\", node.Value);"); + Write ("Assert.AreEqual ({0}, node.Children.Count);", length); + Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", val); + } else if (type.Equals ("LangAlt") && length == 1) { + var langparts = val.Split (new char [] {' '}, 2); + string lang = langparts[0].Substring (langparts[0].IndexOf ('"')+1, langparts [0].Length - langparts[0].IndexOf ('"')-2); + Write ("Assert.AreEqual (\"{0}\", node.Children [0].GetQualifier (XmpTag.XML_NS, \"lang\").Value);", lang); + Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", langparts[1]); + } else if (type.Equals ("XmpSeq") && length == 1) { + Write ("Assert.AreEqual (XmpNodeType.Seq, node.Type);"); + Write ("Assert.AreEqual (\"\", node.Value);"); + Write ("Assert.AreEqual ({0}, node.Children.Count);", length); + Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", val); + } else if (type.Equals ("XmpSeq") && length > 1) { + string [] vals = val.Split (','); + Write ("Assert.AreEqual (XmpNodeType.Seq, node.Type);"); + Write ("Assert.AreEqual (\"\", node.Value);"); + Write ("Assert.AreEqual ({0}, node.Children.Count);", length); + var per_iter = vals.Length / length; + for (int i = 0; i < length; i++) { + var builder = new List (); + for (int j = 0; j < per_iter; j++) { + builder.Add (vals[per_iter*i + j].Trim ()); + } + Write ("Assert.AreEqual (\"{0}\", node.Children [{1}].Value);", String.Join (", ", builder.ToArray ()), i); + } + } else if (type.Equals ("XmpBag") && length > 1) { + string [] vals = val.Split (','); + Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);"); + Write ("Assert.AreEqual (\"\", node.Value);"); + Write ("Assert.AreEqual ({0}, node.Children.Count);", length); + Write ("var children_array = new System.Collections.Generic.List ();"); + Write ("foreach (var child in node.Children)"); + Write ("{"); + Write ("children_array.Add (child.Value);"); + Write ("}"); + var per_iter = vals.Length / length; + for (int i = 0; i < length; i++) { + var builder = new List (); + for (int j = 0; j < per_iter; j++) { + builder.Add (vals[per_iter*i + j].Trim ()); + } + Write ("Assert.IsTrue (children_array.Contains (\"{0}\"));", String.Join (", ", builder.ToArray ())); + } + } else if (type.Equals ("XmpText") && length == 0 && val.StartsWith ("type=")) { + if (val.Equals ("type=\"Bag\"")) { + Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);"); + } else if (val.Equals ("type=\"Struct\"")) { + // We disagree with exiv2 on the meaning of Struct. In Taglib#, + // struct is meant to denote parseType=Resource types only, not + // the shorthand equivalent. Also see XmpNode.RenderInto() + //Write ("Assert.AreEqual (XmpNodeType.Struct, node.Type);"); + } else { + throw new Exception ("Unknown type"); + } + } else { + throw new Exception (String.Format ("Can't test this (type: {0}, length: {1})", type, length)); + } + Write ("}"); + } + + static string ExtractKey (string file, string key) + { + string output, err; + int code; + var result = GLib.Process.SpawnCommandLineSync (String.Format ("./extractKey {0} {1}", file, key), out output, out err, out code); + if (!result) { + Console.Error.WriteLine ("Invoking extractKey failed, are you running from the examples folder?"); + return String.Empty; + } + + return output; + } + + static string GetXmpNs (string prefix) + { + string result; + if (prefix.Equals ("xmpBJ")) + prefix = "xapBJ"; + if (prefix.Equals ("xmpMM")) + prefix = "xapMM"; + if (prefix.Equals ("xmpRights")) + prefix = "xapRights"; + if (prefix.Equals ("MicrosoftPhoto_1_")) // We correct this invalid namespace internally + prefix = "MicrosoftPhoto"; + if (xmp_prefixes.TryGetValue (prefix, out result)) + return String.Format ("XmpTag.{0}", result); + throw new Exception ("Unknown namespace prefix: "+prefix); + } + + static bool IsPartOfMakernote (string ifd) { + return ifd.Equals ("MakerNote") || + ifd.Equals ("Canon") || + ifd.Equals ("Sony") || + ifd.Equals ("Nikon1") || + ifd.Equals ("Nikon2") || + ifd.Equals ("Nikon3") || + ifd.Equals ("Panasonic") || + ifd.Equals ("Olympus") || + ifd.Equals ("Pentax"); + } + + static void EmitHeader (string name, string path) + { + int start = path.LastIndexOf ('/'); + string filename = path.Substring (start+1); + Write ("// TODO: This file is automatically generated"); + Write ("// TODO: Further manual verification is needed"); + Write (); + Write ("using System;"); + Write ("using NUnit.Framework;"); + Write ("using TagLib.IFD;"); + Write ("using TagLib.IFD.Entries;"); + Write ("using TagLib.IFD.Tags;"); + Write ("using TagLib.Xmp;"); + Write ("using TagLib.Tests.Images.Validators;"); + Write (); + Write ("namespace TagLib.Tests.Images"); + Write ("{"); + Write ("[TestFixture]"); + Write ("public class {0}", name); + Write ("{"); + Write ("[Test]"); + Write ("public void Test ()"); + Write ("{"); + Write ("ImageTest.Run (\"{0}\",", filename); + level++; + Write ("new {0}InvariantValidator (),", name); + Write ("NoModificationValidator.Instance"); + level--; + Write (");"); + Write ("}"); + Write ("}"); + Write (); + Write ("public class {0}InvariantValidator : IMetadataInvariantValidator", name); + Write ("{"); + Write ("public void ValidateMetadataInvariants (Image.File file)"); + Write ("{"); + Write ("Assert.IsNotNull (file);"); + } + + static void EmitFooter () + { + Write ("}"); // Method + Write ("}"); // Class + Write ("}"); // Namespace + } + + static bool is_panasonic_raw = false; + + static bool structure_emitted = false; + static bool exif_emitted = false; + static bool makernote_emitted = false; + static bool makernote_is_canon = false; + static bool makernote_is_nikon1 = false; + static bool makernote_is_nikon2 = false; + static bool makernote_is_nikon3 = false; + static bool makernote_is_panasonic = false; + static bool nikonpreview_emitted = false; + static bool iop_emitted = false; + static bool gps_emitted = false; + + static void EnsureIFD (string ifd) { + if (ifd.Equals ("PanasonicRaw")) { + if (is_panasonic_raw) + return; + + Write (); + Write ("var tag = file.GetTag (TagTypes.TiffIFD) as IFDTag;"); + Write ("Assert.IsNotNull (tag, \"IFD tag not found\");"); + Write (); + Write ("var pana_structure = tag.Structure;"); + Write (); + Write ("var jpg_file = (file as TagLib.Tiff.Rw2.File).JpgFromRaw;"); + Write ("Assert.IsNotNull (tag, \"JpgFromRaw not found!\");"); + Write ("var jpg_tag = jpg_file.GetTag (TagTypes.TiffIFD) as IFDTag;"); + Write ("Assert.IsNotNull (tag, \"Jpg has no Exif tag!\");"); + Write ("var structure = jpg_tag.Structure;"); + + is_panasonic_raw = true; + } + + if (ifd.Equals ("Image") && !is_panasonic_raw) { + if (structure_emitted) + return; + Write (); + Write ("var tag = file.GetTag (TagTypes.TiffIFD) as IFDTag;"); + Write ("Assert.IsNotNull (tag, \"IFD tag not found\");"); + Write (); + Write ("var structure = tag.Structure;"); + Write (); + structure_emitted = true; + } + + if (ifd.Equals ("Photo")) { + if (exif_emitted) + return; + EnsureIFD ("Image"); + Write (); + Write ("var exif = structure.GetEntry (0, (ushort) IFDEntryTag.ExifIFD) as SubIFDEntry;"); + Write ("Assert.IsNotNull (exif, \"Exif tag not found\");"); + Write ("var exif_structure = exif.Structure;"); + Write (); + exif_emitted = true; + } + + if (ifd.Equals ("MakerNote")) { + if (makernote_emitted) + return; + EnsureIFD ("Photo"); + Write (); + Write ("var makernote = exif_structure.GetEntry (0, (ushort) ExifEntryTag.MakerNote) as MakernoteIFDEntry;"); + Write ("Assert.IsNotNull (makernote, \"MakerNote tag not found\");"); + Write ("var makernote_structure = makernote.Structure;"); + Write (); + makernote_emitted = true; + } + + if (ifd.Equals ("Canon") || ifd.Equals ("CanonCs") || ifd.Equals ("CanonSi")) { + if (makernote_is_canon) + return; + EnsureIFD ("MakerNote"); + Write (); + Write ("Assert.AreEqual (MakernoteType.Canon, makernote.MakernoteType);"); + Write (); + makernote_is_canon = true; + } + + if (ifd.Equals ("Nikon1")) { + if (makernote_is_nikon1) + return; + EnsureIFD ("MakerNote"); + Write (); + Write ("Assert.AreEqual (MakernoteType.Nikon1, makernote.MakernoteType);"); + Write (); + makernote_is_nikon1 = true; + } + + if (ifd.Equals ("Nikon2")) { + if (makernote_is_nikon2) + return; + EnsureIFD ("MakerNote"); + Write (); + Write ("Assert.AreEqual (MakernoteType.Nikon2, makernote.MakernoteType);"); + Write (); + makernote_is_nikon2 = true; + } + + if (ifd.Equals ("Nikon3")) { + if (makernote_is_nikon3) + return; + EnsureIFD ("MakerNote"); + Write (); + Write ("Assert.AreEqual (MakernoteType.Nikon3, makernote.MakernoteType);"); + Write (); + makernote_is_nikon3 = true; + } + + if (ifd.Equals ("NikonPreview")) { + if (nikonpreview_emitted) + return; + EnsureIFD ("Nikon3"); + Write (); + Write ("var nikonpreview = makernote_structure.GetEntry (0, (ushort) Nikon3MakerNoteEntryTag.Preview) as SubIFDEntry;"); + Write ("Assert.IsNotNull (nikonpreview, \"Nikon preview tag not found\");"); + Write ("var nikonpreview_structure = nikonpreview.Structure;"); + Write (); + nikonpreview_emitted = true; + } + + if (ifd.Equals ("Panasonic")) { + if (makernote_is_panasonic) + return; + EnsureIFD ("MakerNote"); + Write (); + Write ("Assert.AreEqual (MakernoteType.Panasonic, makernote.MakernoteType);"); + Write (); + makernote_is_panasonic = true; + } + + if (ifd.Equals ("Iop")) { + if (iop_emitted) + return; + EnsureIFD ("Photo"); + Write (); + Write ("var iop = exif_structure.GetEntry (0, (ushort) IFDEntryTag.InteroperabilityIFD) as SubIFDEntry;"); + Write ("Assert.IsNotNull (iop, \"Iop tag not found\");"); + Write ("var iop_structure = iop.Structure;"); + Write (); + iop_emitted = true; + } + + if (ifd.Equals ("GPSInfo")) { + if (gps_emitted) + return; + EnsureIFD ("Image"); + Write (); + Write ("var gps = structure.GetEntry (0, (ushort) IFDEntryTag.GPSIFD) as SubIFDEntry;"); + Write ("Assert.IsNotNull (gps, \"GPS tag not found\");"); + Write ("var gps_structure = gps.Structure;"); + Write (); + gps_emitted = true; + } + + if (sub_ifds.ContainsKey (ifd) && !sub_ifds_emitted.ContainsKey (ifd)) { + Write (); + Write ("var {0}_structure = (structure.GetEntry (0, (ushort) IFDEntryTag.SubIFDs) as SubIFDArrayEntry).Entries [{1}];", ifd, sub_ifds[ifd]); + Write ("Assert.IsNotNull ({0}_structure, \"{0} structure not found\");", ifd); + Write (); + sub_ifds_emitted.Add (ifd, true); + } + } + + static void EmitTestIFDEntryOpen (string src, int ifd, ushort tag, string ifd_label) + { + Write ("{"); + Write (String.Format ("var entry = {0}.GetEntry ({1}, (ushort) {2});", src, ifd, StringifyEntryTag (ifd_label, tag))); + Write (String.Format ("Assert.IsNotNull (entry, \"Entry 0x{0:X4} missing in IFD {1}\");", tag, ifd)); + } + + static void EmitTestIFDEntryClose () + { + Write ("}"); + } + + static void EmitTestIFDStringEntry (string val) + { + Write ("Assert.IsNotNull (entry as StringIFDEntry, \"Entry is not a string!\");"); + Write ("Assert.AreEqual (\"{0}\", (entry as StringIFDEntry).Value{1});", val, val == String.Empty ? ".Trim ()" : ""); + } + + static void EmitTestIFDShortEntry (string val) + { + Write ("Assert.IsNotNull (entry as ShortIFDEntry, \"Entry is not a short!\");"); + Write ("Assert.AreEqual ({0}, (entry as ShortIFDEntry).Value);", val); + } + + static void EmitTestIFDSShortEntry (string val) + { + Write ("Assert.IsNotNull (entry as SShortIFDEntry, \"Entry is not a signed short!\");"); + Write ("Assert.AreEqual ({0}, (entry as SShortIFDEntry).Value);", val); + } + + static void EmitTestIFDShortArrayEntry (string val) + { + val = String.Format ("new ushort [] {{ {0} }}", String.Join (", ", val.Split(' '))); + Write ("Assert.IsNotNull (entry as ShortArrayIFDEntry, \"Entry is not a short array!\");"); + Write ("Assert.AreEqual ({0}, (entry as ShortArrayIFDEntry).Values);", val); + } + + static void EmitTestIFDSShortArrayEntry (string val) + { + val = String.Format ("new short [] {{ {0} }}", String.Join (", ", val.Split(' '))); + Write ("Assert.IsNotNull (entry as SShortArrayIFDEntry, \"Entry is not a signed short array!\");"); + Write ("Assert.AreEqual ({0}, (entry as SShortArrayIFDEntry).Values);", val); + } + + static void EmitTestIFDRationalEntry (string val) + { + Write ("Assert.IsNotNull (entry as RationalIFDEntry, \"Entry is not a rational!\");"); + string[] parts = val.Split('/'); + Write ("Assert.AreEqual ({0}, (entry as RationalIFDEntry).Value.Numerator);", parts [0]); + Write ("Assert.AreEqual ({0}, (entry as RationalIFDEntry).Value.Denominator);", parts [1]); + } + + static void EmitTestIFDRationalArrayEntry (string val) + { + var parts = val.Split(' '); + Write ("Assert.IsNotNull (entry as RationalArrayIFDEntry, \"Entry is not a rational array!\");"); + Write ("var parts = (entry as RationalArrayIFDEntry).Values;"); + Write ("Assert.AreEqual ({0}, parts.Length);", parts.Length); + for (int i = 0; i < parts.Length; i++) { + var pieces = parts[i].Split('/'); + Write ("Assert.AreEqual ({0}, parts[{1}].Numerator);", pieces[0], i); + Write ("Assert.AreEqual ({0}, parts[{1}].Denominator);", pieces[1], i); + } + } + + static void EmitTestIFDSRationalEntry (string val) + { + Write ("Assert.IsNotNull (entry as SRationalIFDEntry, \"Entry is not a srational!\");"); + string[] parts = val.Split('/'); + Write ("Assert.AreEqual ({0}, (entry as SRationalIFDEntry).Value.Numerator);", parts [0]); + Write ("Assert.AreEqual ({0}, (entry as SRationalIFDEntry).Value.Denominator);", parts [1]); + } + + static void EmitTestIFDSRationalArrayEntry (string val) + { + var parts = val.Split(' '); + Write ("Assert.IsNotNull (entry as SRationalArrayIFDEntry, \"Entry is not a srational array!\");"); + Write ("var parts = (entry as SRationalArrayIFDEntry).Values;"); + Write ("Assert.AreEqual ({0}, parts.Length);", parts.Length); + for (int i = 0; i < parts.Length; i++) { + var pieces = parts[i].Split('/'); + Write ("Assert.AreEqual ({0}, parts[{1}].Numerator);", pieces[0], i); + Write ("Assert.AreEqual ({0}, parts[{1}].Denominator);", pieces[1], i); + } + } + + static void EmitTestIFDLongEntry (string val) + { + Write ("Assert.IsNotNull (entry as LongIFDEntry, \"Entry is not a long!\");"); + Write ("Assert.AreEqual ({0}, (entry as LongIFDEntry).Value);", val); + } + + static void EmitTestIFDLongArrayEntry (string val) + { + val = String.Format ("new long [] {{ {0} }}", String.Join (", ", val.Split(' '))); + Write ("Assert.IsNotNull (entry as LongArrayIFDEntry, \"Entry is not a long array!\");"); + Write ("Assert.AreEqual ({0}, (entry as LongArrayIFDEntry).Values);", val); + } + + static void EmitTestIFDSLongEntry (string val) + { + Write ("Assert.IsNotNull (entry as SLongIFDEntry, \"Entry is not a signed long!\");"); + Write ("Assert.AreEqual ({0}, (entry as SLongIFDEntry).Value);", val); + } + + static void EmitTestIFDByteEntry (string val) + { + Write ("Assert.IsNotNull (entry as ByteIFDEntry, \"Entry is not a byte!\");"); + Write ("Assert.AreEqual ({0}, (entry as ByteIFDEntry).Value);", val); + } + + static void EmitTestIFDByteArrayEntry (string val) + { + EmitByteArrayComparison (val, "ByteVectorIFDEntry", "a byte array"); + } + + static void EmitTestIFDSByteEntry (string val) + { + Write ("Assert.IsNotNull (entry as SByteIFDEntry, \"Entry is not a signed byte!\");"); + Write ("Assert.AreEqual ({0}, (entry as SByteIFDEntry).Value);", val); + } + + static void EmitTestIFDIPTCNAAEntry (string val) + { + Write ("Assert.IsNotNull (entry as ByteVectorIFDEntry, \"Entry is not a byte array!\");"); + } + + static void EmitTestIFDXMLPacketEntry (string val) + { + Write ("Assert.IsNotNull (entry as ByteVectorIFDEntry, \"Entry is not a byte array!\");"); + } + + static void EmitTestIFDUndefinedEntry (string val) + { + EmitByteArrayComparison (val, "UndefinedIFDEntry", "an undefined IFD entry"); + } + + static void EmitByteArrayComparison (string val, string type, string type_desc) + { + Write ("Assert.IsNotNull (entry as {0}, \"Entry is not {1}!\");", type, type_desc); + Write ("var parsed_bytes = (entry as {0}).Data.Data;", type); + var parts = val.Trim ().Split(' '); + if (parts.Length < 512) { + Write ("var bytes = new byte [] {{ {0} }};", String.Join (", ", parts)); + Write ("Assert.AreEqual (bytes, parsed_bytes);"); + } else { + // Starting with 512 byte items, we compare based on an MD5 hash, should be faster and reduces + // the size of the test fixtures. + byte [] data = new byte [parts.Length]; + for (int i = 0; i < parts.Length; i++) { + data [i] = Byte.Parse (parts [i]); + } + var hash = md5.ComputeHash (data); + + StringBuilder shash = new StringBuilder (); + for (int i = 0; i < hash.Length; i++) { + shash.Append (hash[i].ToString ("x2")); + } + + Write ("var parsed_hash = Utils.Md5Encode (parsed_bytes);"); + Write ("Assert.AreEqual (\"{0}\", parsed_hash);", shash.ToString ()); + Write ("Assert.AreEqual ({0}, parsed_bytes.Length);", parts.Length); + } + } + + static void EmitTestIFDSubIFDEntry (string val) + { + Write ("Assert.IsNotNull (entry as SubIFDEntry, \"Entry is not a sub IFD!\");"); + } + + static void EmitTestIFDThumbnailDataIFDEntry (string val) + { + Write ("Assert.IsNotNull (entry as ThumbnailDataIFDEntry, \"Entry is not a thumbnail IFD!\");"); + } + + static void EmitTestIFDMakerNoteIFDEntry (string val) + { + Write ("Assert.IsNotNull (entry as MakernoteIFDEntry, \"Entry is not a makernote IFD!\");"); + } + + static void EmitTestIFDUserCommentIFDEntry (string val) + { + Write ("Assert.IsNotNull (entry as UserCommentIFDEntry, \"Entry is not a user comment!\");"); + if (val.StartsWith ("charset=\"Ascii\"")) + val = val.Substring (15).Trim (); + Write ("Assert.AreEqual (\"{0}\", (entry as UserCommentIFDEntry).Value.Trim ());", val); + } + + static void EmitTestIFDStripOffsetsEntry (string val) + { + // The offsets may change after writing. Therfore we cannot compare them directly. + string offset_count = String.Format ("{0}", val.Split(' ').Length); + //val = String.Format ("new long [] {{ {0} }}", String.Join (", ", val.Split(' '))); + Write ("Assert.IsNotNull (entry as StripOffsetsIFDEntry, \"Entry is not a strip offsets entry!\");"); + //Write ("Assert.AreEqual ({0}, (entry as StripOffsetsIFDEntry).Values);", val); + Write ("Assert.AreEqual ({0}, (entry as StripOffsetsIFDEntry).Values.Length);", offset_count); + } + + static void EmitTestIFDIndexedShortEntry (int index, string val) + { + Write ("Assert.IsNotNull (entry as ShortArrayIFDEntry, \"Entry is not a short array!\");"); + var parts = val.Trim ().Split (' '); + Write ("Assert.IsTrue ({0} <= (entry as ShortArrayIFDEntry).Values.Length);", index + parts.Length); + for (int i = 0; i < parts.Length; i++) + Write ("Assert.AreEqual ({0}, (entry as ShortArrayIFDEntry).Values [{1}]);", parts [i], index + i); + } + +#region IFD tag names lookup + + static Dictionary> tag_names = null; + + static string StringifyEntryTag (string src, ushort tag) + { + if (tag_names == null) + BuildTagNamesTable (); + Dictionary table; + string result; + if (tag_names.TryGetValue (src, out table)) { + if (table.TryGetValue (tag, out result)) + return result; + } + Write ("// TODO: Unknown IFD tag: {1} / 0x{0:X4}", tag, src); + return String.Format ("0x{0:X4}", tag); + } + + static void BuildTagNamesTable () + { + tag_names = new Dictionary> (); + + IndexTagType ("Image", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("Image2", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("Image3", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("SubImage1", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("SubImage2", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("Thumbnail", typeof (IFDEntryTag), "IFDEntryTag"); // IFD1, for thumbnails + IndexTagType ("Photo", typeof (IFDEntryTag), "IFDEntryTag"); + IndexTagType ("Photo", typeof (ExifEntryTag), "ExifEntryTag"); + IndexTagType ("Image", typeof (ExifEntryTag), "ExifEntryTag"); // Also put exif into Image, for DNG + IndexTagType ("GPSInfo", typeof (GPSEntryTag), "GPSEntryTag"); + IndexTagType ("Iop", typeof (IOPEntryTag), "IOPEntryTag"); + IndexTagType ("Canon", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("CanonCs", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("CanonSi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("CanonCf", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("CanonFi", typeof (CanonFileInfoEntryTag), "CanonFileInfoEntryTag"); + IndexTagType ("CanonFi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("CanonPi", typeof (CanonPictureInfoEntryTag), "CanonPictureInfoEntryTag"); + IndexTagType ("CanonPi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag"); + IndexTagType ("Sony", typeof (SonyMakerNoteEntryTag), "SonyMakerNoteEntryTag"); + IndexTagType ("Olympus", typeof (OlympusMakerNoteEntryTag), "OlympusMakerNoteEntryTag"); + IndexTagType ("Pentax", typeof (PentaxMakerNoteEntryTag), "PentaxMakerNoteEntryTag"); + IndexTagType ("Nikon3", typeof (Nikon3MakerNoteEntryTag), "Nikon3MakerNoteEntryTag"); + IndexTagType ("NikonPreview", typeof (NikonPreviewMakerNoteEntryTag), "NikonPreviewMakerNoteEntryTag"); + IndexTagType ("Panasonic", typeof (PanasonicMakerNoteEntryTag), "PanasonicMakerNoteEntryTag"); + IndexTagType ("PanasonicRaw", typeof (IFDEntryTag), "IFDEntryTag"); + } + + static void IndexTagType (string ifd, Type t, string typename) + { + if (!tag_names.ContainsKey (ifd)) + tag_names[ifd] = new Dictionary (); + foreach (string name in Enum.GetNames (t)) { + ushort tag = (ushort) Enum.Parse (t, name); + tag_names[ifd][tag] = String.Format ("{1}.{0}", name, typename); + } + } + +#endregion + +#region Code emission + + static int level = 0; + + static void Write (string str, params object[] p) + { + Console.Write (new String ('\t', level)); + Console.WriteLine (str, p); + } + + static void Write () + { + Console.WriteLine (); + } + + static void Write (string str) + { + if (str.Equals ("}")) + level--; + Console.Write (new String ('\t', level)); + Console.WriteLine (str); + if (str.Equals ("{")) + level++; + } + +#endregion +} diff --git a/taglib-sharp/examples/ListSupportedMimeTypes.cs b/taglib-sharp/examples/ListSupportedMimeTypes.cs new file mode 100644 index 0000000..2149b1a --- /dev/null +++ b/taglib-sharp/examples/ListSupportedMimeTypes.cs @@ -0,0 +1,13 @@ +using System; +using TagLib; + +public class ListSupportedMimeTypes +{ + public static void Main() + { + foreach(string type in SupportedMimeType.AllMimeTypes) { + Console.WriteLine(type); + } + } +} + diff --git a/taglib-sharp/examples/Makefile.am b/taglib-sharp/examples/Makefile.am new file mode 100644 index 0000000..4599758 --- /dev/null +++ b/taglib-sharp/examples/Makefile.am @@ -0,0 +1,61 @@ +READ_FROM_URI = ReadFromUri +SET_PICTURES = SetPictures +LIST_TYPES = ListSupportedMimeTypes +BATCH_SET = BatchSet +PARSE_PHOTO = ParsePhoto +STRIP_IMAGE = StripImageData +GENERATE_TEST_FIXTURE = GenerateTestFixture + +REFERENCES = -r:taglib-sharp.dll +EXAMPLES_BUILD = taglib-sharp.dll $(SET_PICTURES).exe $(LIST_TYPES).exe $(BATCH_SET).exe $(PARSE_PHOTO).exe $(STRIP_IMAGE).exe + +if HAVE_GNOME_SHARP +EXAMPLES_BUILD += $(READ_FROM_URI).exe +if HAVE_EXIV2 +EXAMPLES_BUILD += $(GENERATE_TEST_FIXTURE).exe +endif +endif + +all: $(EXAMPLES_BUILD) + +taglib-sharp.dll: + if [ ! -e $@ ]; then ln -s $(top_builddir)/src/taglib-sharp.dll $@; fi + +if HAVE_GNOME_SHARP +$(READ_FROM_URI).exe: $(READ_FROM_URI).cs + $(MCS) -out:$@ -debug $(REFERENCES) $(GNOME_SHARP_LIBS) $< + +if HAVE_EXIV2 +$(GENERATE_TEST_FIXTURE).exe: $(GENERATE_TEST_FIXTURE).cs listData extractKey + $(MCS) -out:$@ -debug $(REFERENCES) $(GNOME_SHARP_LIBS) $< + +listData: listData.cpp + g++ -o $@ $(EXIV2_LIBS) $< + +extractKey: extractKey.cpp + g++ -o $@ $(EXIV2_LIBS) $< +endif +endif + +$(SET_PICTURES).exe: $(SET_PICTURES).cs + $(MCS) -out:$@ -debug $(REFERENCES) $< + +$(LIST_TYPES).exe: $(LIST_TYPES).cs + $(MCS) -out:$@ -debug $(REFERENCES) $< + +$(BATCH_SET).exe: $(BATCH_SET).cs + $(MCS) -out:$@ -debug $(REFERENCES) $< + +$(PARSE_PHOTO).exe: $(PARSE_PHOTO).cs + $(MCS) -out:$@ -debug $(REFERENCES) $< + +$(STRIP_IMAGE).exe: $(STRIP_IMAGE).cs + $(MCS) -out:$@ -debug $(REFERENCES) $< + +EXTRA_DIST = $(READ_FROM_URI).cs $(SET_PICTURES).cs $(LIST_TYPES).cs $(BATCH_SET).cs $(PARSE_PHOTO).cs $(STRIP_IMAGE).cs $(GENERATE_TEST_FIXTURE).cs \ + $(srcdir)/covers/sample* + +DISTCLEANFILES = *.pidb +CLEANFILES = *.dll *.exe *.mdb +MAINTAINERCLEANFILES = Makefile.in + diff --git a/taglib-sharp/examples/ParsePhoto.cs b/taglib-sharp/examples/ParsePhoto.cs new file mode 100644 index 0000000..75a5936 --- /dev/null +++ b/taglib-sharp/examples/ParsePhoto.cs @@ -0,0 +1,82 @@ +using System; + +public class ParsePhotoApp +{ + public static void Main (string [] args) + { + if(args.Length == 0) { + Console.Error.WriteLine("USAGE: mono ParsePhoto.exe PATH [...]"); + return; + } + + foreach (string path in args) + ParsePhoto (path); + } + + static void ParsePhoto (string path) + { + TagLib.File file = null; + + try { + file = TagLib.File.Create(path); + } catch (TagLib.UnsupportedFormatException) { + Console.WriteLine ("UNSUPPORTED FILE: " + path); + Console.WriteLine (String.Empty); + Console.WriteLine ("---------------------------------------"); + Console.WriteLine (String.Empty); + return; + } + + var image = file as TagLib.Image.File; + if (file == null) { + Console.WriteLine ("NOT AN IMAGE FILE: " + path); + Console.WriteLine (String.Empty); + Console.WriteLine ("---------------------------------------"); + Console.WriteLine (String.Empty); + return; + } + + Console.WriteLine (String.Empty); + Console.WriteLine (path); + Console.WriteLine (String.Empty); + + Console.WriteLine("Tags in object : " + image.TagTypes); + Console.WriteLine (String.Empty); + + Console.WriteLine("Comment : " + image.ImageTag.Comment); + Console.Write("Keywords : "); + foreach (var keyword in image.ImageTag.Keywords) { + Console.Write (keyword + " "); + } + Console.WriteLine (); + Console.WriteLine("Rating : " + image.ImageTag.Rating); + Console.WriteLine("DateTime : " + image.ImageTag.DateTime); + Console.WriteLine("Orientation : " + image.ImageTag.Orientation); + Console.WriteLine("Software : " + image.ImageTag.Software); + Console.WriteLine("ExposureTime : " + image.ImageTag.ExposureTime); + Console.WriteLine("FNumber : " + image.ImageTag.FNumber); + Console.WriteLine("ISOSpeedRatings : " + image.ImageTag.ISOSpeedRatings); + Console.WriteLine("FocalLength : " + image.ImageTag.FocalLength); + Console.WriteLine("FocalLength35mm : " + image.ImageTag.FocalLengthIn35mmFilm); + Console.WriteLine("Make : " + image.ImageTag.Make); + Console.WriteLine("Model : " + image.ImageTag.Model); + + if (image.Properties != null) { + Console.WriteLine("Width : " + image.Properties.PhotoWidth); + Console.WriteLine("Height : " + image.Properties.PhotoHeight); + Console.WriteLine("Type : " + image.Properties.Description); + } + + Console.WriteLine (); + Console.WriteLine("Writable? : " + image.Writeable.ToString ()); + Console.WriteLine("Corrupt? : " + image.PossiblyCorrupt.ToString ()); + + if (image.PossiblyCorrupt) { + foreach (string reason in image.CorruptionReasons) { + Console.WriteLine (" * " + reason); + } + } + + Console.WriteLine ("---------------------------------------"); + } +} diff --git a/taglib-sharp/examples/ReadFromUri.boo b/taglib-sharp/examples/ReadFromUri.boo new file mode 100644 index 0000000..030e949 --- /dev/null +++ b/taglib-sharp/examples/ReadFromUri.boo @@ -0,0 +1,136 @@ +import TagLib from "taglib-sharp.dll" +import Gnome.Vfs from "gnome-vfs-sharp" +import System +import System.IO + +def ReadFromUri(argv as (string)): + + if len(argv) < 1: + print "Usage: booi ReadFromUri.boo PATH [...]" + return + + Vfs.Initialize() + + TagLib.File.SetFileAbstractionCreator(TagLib.File.FileAbstractionCreator(CreateFile)) + + start = DateTime.Now + songs_read = 0 + + try: + for path as string in argv: + print path + + file_info as System.IO.FileInfo = System.IO.FileInfo(path) + uri as string = Gnome.Vfs.Uri.GetUriFromLocalPath (file_info.FullName) + file as TagLib.File = null + + try: + file = TagLib.File.Create(uri) + except UnsupportedFormatException: + print "UNSUPPORTED FILE: ${path}" + print string.Empty + print "---------------------------------------" + print string.Empty + continue + + print "Title: ${file.Tag.Title}" + + if file.Tag.AlbumArtists is null: + print "Artists:" + else: + print "Artists: ${string.Join ('\n ', file.Tag.AlbumArtists)}" + + if file.Tag.Performers is null: + print 'Performers:' + else: + print "Performers: ${string.Join ('\n ', file.Tag.Performers)}" + + if file.Tag.Composers is null: + print 'Composers:' + else: + print "Composers: ${string.Join ('\n ', file.Tag.Composers)}" + + print "Album: ${file.Tag.Album}" + print "Comment: ${file.Tag.Comment}" + + if file.Tag.Genres is null: + print 'Genres:' + else: + print "Genres: ${string.Join ('\n ', file.Tag.Genres)}" + + print "Year: ${file.Tag.Year}" + print "Track: ${file.Tag.Track}" + print "TrackCount: ${file.Tag.TrackCount}" + print "Disc: ${file.Tag.Disc}" + print "DiscCount: ${file.Tag.DiscCount}" + print "Lyrics:\n${file.Tag.Lyrics}" + print string.Empty + + print "Media Types: ${file.Properties.MediaTypes}" + print string.Empty + + for codec as ICodec in file.Properties.Codecs: + + if codec.MediaTypes & MediaTypes.Audio: + print "Audio Properties : ${(codec as IAudioCodec).Description}" + print "Bitrate: ${(codec as IAudioCodec).AudioBitrate}" + print "SampleRate: ${(codec as IAudioCodec).AudioSampleRate}" + print "Channels: ${(codec as IAudioCodec).AudioChannels}" + print string.Empty + + if codec.MediaTypes & MediaTypes.Video: + print "Video Properties : ${(codec as IVideoCodec).Description}" + print "Width: ${(codec as IVideoCodec).VideoWidth}" + print "Height: ${(codec as IVideoCodec).VideoHeight}" + print string.Empty + + if file.Properties.MediaTypes: + print "Length: ${file.Properties.Duration}" + print string.Empty + + print "Embedded Pictures: ${file.Tag.Pictures.Length}" + + for picture in file.Tag.Pictures: + print picture.Description + print " MimeType: ${picture.MimeType}" + print " Size: ${picture.Data.Count}" + print " Type: ${picture.Type}" + + print "" + print "---------------------------------------" + print "" + + songs_read = songs_read + 1 + + ensure: + Vfs.Shutdown() + + end as DateTime = DateTime.Now; + + print "Total running time: ${end - start}" + print "Total files read: ${songs_read}" + print "Average time per file: ${TimeSpan ((end - start).Ticks / songs_read)}" + +class VfsFileAbstraction(TagLib.File.IFileAbstraction): + + _name as string + + def constructor(file as string): + _name = file + + Name: + get: + return _name + + ReadStream: + get: + return VfsStream(_name, FileMode.Open) + + WriteStream: + get: + return VfsStream(_name, FileMode.Open) + +def CreateFile(path): + return VfsFileAbstraction(path) + +ReadFromUri(argv) diff --git a/taglib-sharp/examples/ReadFromUri.cs b/taglib-sharp/examples/ReadFromUri.cs new file mode 100644 index 0000000..cc5c9e4 --- /dev/null +++ b/taglib-sharp/examples/ReadFromUri.cs @@ -0,0 +1,171 @@ +using System; +using TagLib; +using Gnome.Vfs; + +public class ReadFromUri +{ + public static void Write (string name, object value) + { + Console.WriteLine ("{0,20}: {1}", + name, value == null ? "" : value + ); + } + + public static void Write (string name, string [] values) + { + Console.WriteLine ("{0,20}: {1}", + name, + values == null ? "" : String.Join ("\n ", values) + ); + } + + public static void Main(string [] args) + { + if(args.Length == 0) { + Console.Error.WriteLine("USAGE: mono ReadFromUri.exe PATH [...]"); + return; + } + + Gnome.Vfs.Vfs.Initialize(); + + DateTime start = DateTime.Now; + int songs_read = 0; + try { + foreach (string path in args) + { + string uri = path; + Console.WriteLine (uri); + TagLib.File file = null; + + try { + System.IO.FileInfo file_info = new System.IO.FileInfo(uri); + uri = Gnome.Vfs.Uri.GetUriFromLocalPath (file_info.FullName); + } catch { + } + + try + { + file = TagLib.File.Create(new VfsFileAbstraction (uri)); + } + catch (TagLib.UnsupportedFormatException) + { + Console.WriteLine ("UNSUPPORTED FILE: " + uri); + Console.WriteLine (String.Empty); + Console.WriteLine ("---------------------------------------"); + Console.WriteLine (String.Empty); + continue; + } + + Console.WriteLine("Tags on disk: " + file.TagTypesOnDisk); + Console.WriteLine("Tags in object: " + file.TagTypes); + Console.WriteLine (String.Empty); + + Write ("Grouping", file.Tag.Grouping); + Write ("Title", file.Tag.Title); + Write ("TitleSort", file.Tag.TitleSort); + Write ("Album Artists", file.Tag.AlbumArtists); + Write ("Album Artists Sort", file.Tag.AlbumArtistsSort); + Write ("Performers", file.Tag.Performers); + Write ("Performers Sort", file.Tag.PerformersSort); + Write ("Composers", file.Tag.Composers); + Write ("Composers Sort", file.Tag.ComposersSort); + Write ("Conductor", file.Tag.Conductor); + Write ("Album", file.Tag.Album); + Write ("Album Sort", file.Tag.AlbumSort); + Write ("Comment", file.Tag.Comment); + Write ("Copyright", file.Tag.Copyright); + Write ("Genres", file.Tag.Genres); + Write ("BPM", file.Tag.BeatsPerMinute); + Write ("Year", file.Tag.Year); + Write ("Track", file.Tag.Track); + Write ("TrackCount", file.Tag.TrackCount); + Write ("Disc", file.Tag.Disc); + Write ("DiscCount", file.Tag.DiscCount); + + Console.WriteLine("Lyrics:\n" + file.Tag.Lyrics + "\n"); + + Console.WriteLine("Media Types: " + file.Properties.MediaTypes + "\n"); + + foreach (TagLib.ICodec codec in file.Properties.Codecs) + { + TagLib.IAudioCodec acodec = codec as TagLib.IAudioCodec; + TagLib.IVideoCodec vcodec = codec as TagLib.IVideoCodec; + + if (acodec != null && (acodec.MediaTypes & TagLib.MediaTypes.Audio) != TagLib.MediaTypes.None) + { + Console.WriteLine("Audio Properties : " + acodec.Description); + Console.WriteLine("Bitrate: " + acodec.AudioBitrate); + Console.WriteLine("SampleRate: " + acodec.AudioSampleRate); + Console.WriteLine("Channels: " + acodec.AudioChannels + "\n"); + } + + if (vcodec != null && (vcodec.MediaTypes & TagLib.MediaTypes.Video) != TagLib.MediaTypes.None) + { + Console.WriteLine("Video Properties : " + vcodec.Description); + Console.WriteLine("Width: " + vcodec.VideoWidth); + Console.WriteLine("Height: " + vcodec.VideoHeight + "\n"); + } + } + + if (file.Properties.MediaTypes != TagLib.MediaTypes.None) + Console.WriteLine("Length: " + file.Properties.Duration + "\n"); + + IPicture [] pictures = file.Tag.Pictures; + + Console.WriteLine("Embedded Pictures: " + pictures.Length); + + foreach(IPicture picture in pictures) { + Console.WriteLine(picture.Description); + Console.WriteLine(" MimeType: " + picture.MimeType); + Console.WriteLine(" Size: " + picture.Data.Count); + Console.WriteLine(" Type: " + picture.Type); + } + + Console.WriteLine (String.Empty); + Console.WriteLine ("---------------------------------------"); + Console.WriteLine (String.Empty); + + songs_read ++; + } + } finally { + Gnome.Vfs.Vfs.Shutdown(); + } + + DateTime end = DateTime.Now; + + Console.WriteLine ("Total running time: " + (end - start)); + Console.WriteLine ("Total files read: " + songs_read); + + if (songs_read > 0) + { + Console.WriteLine ("Average time per file: " + new TimeSpan ((end - start).Ticks / songs_read)); + } + } +} + +public class VfsFileAbstraction : TagLib.File.IFileAbstraction +{ + private string name; + + public VfsFileAbstraction(string file) + { + name = file; + } + + public string Name { + get { return name; } + } + + public System.IO.Stream ReadStream { + get { return new VfsStream(Name, System.IO.FileMode.Open); } + } + + public System.IO.Stream WriteStream { + get { return new VfsStream(Name, System.IO.FileMode.Open); } + } + + public void CloseStream (System.IO.Stream stream) + { + stream.Close (); + } +} diff --git a/taglib-sharp/examples/ReadFromUri.csproj b/taglib-sharp/examples/ReadFromUri.csproj new file mode 100644 index 0000000..ff50d8c --- /dev/null +++ b/taglib-sharp/examples/ReadFromUri.csproj @@ -0,0 +1,55 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {AB35577D-31CB-4848-AC41-13F00A5171A6} + Exe + ReadFromUri + ReadFromUri + v3.5 + + + true + full + true + . + prompt + 4 + ../tests/samples/sample.ogg + true + + + + + + none + true + . + prompt + 4 + ../tests/samples/sample_v2_only.mp3 + true + + + + + + + + + + {6B143A39-C7B2-4743-9917-92262C60E9A6} + taglib-sharp + + + + + False + + + + + \ No newline at end of file diff --git a/taglib-sharp/examples/SetPictures.cs b/taglib-sharp/examples/SetPictures.cs new file mode 100644 index 0000000..798c638 --- /dev/null +++ b/taglib-sharp/examples/SetPictures.cs @@ -0,0 +1,28 @@ +using System; +using TagLib; + +public class SetPictures +{ + public static void Main(string [] args) + { + if(args.Length < 2) { + Console.Error.WriteLine("USAGE: mono SetPictures.exe AUDIO_PATH IMAGE_PATH_1[...IMAGE_PATH_N]"); + return; + } + + TagLib.File file = TagLib.File.Create(args[0]); + Console.WriteLine("Current picture count: " + file.Tag.Pictures.Length); + + Picture [] pictures = new Picture[args.Length - 1]; + + for(int i = 1; i < args.Length; i++) { + Picture picture = new Picture(args[i]); + pictures[i - 1] = picture; + } + + file.Tag.Pictures = pictures; + file.Save(); + + Console.WriteLine("New picture count: " + file.Tag.Pictures.Length); + } +} diff --git a/taglib-sharp/examples/SetPictures.csproj b/taglib-sharp/examples/SetPictures.csproj new file mode 100644 index 0000000..84ac473 --- /dev/null +++ b/taglib-sharp/examples/SetPictures.csproj @@ -0,0 +1,52 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {0C4645BE-7413-43FC-8856-1ECF1A790FF8} + Exe + SetPictures + SetPictures + v3.5 + + + true + full + true + . + prompt + 4 + ../tests/samples/sample_v2_only.mp3 covers/sample_a.png covers/sample_b.jpg + true + + + + + + none + true + . + prompt + 4 + ../tests/samples/sample_v2_only.mp3 covers/sample_a.png covers/sample_b.jpg + true + + + + + + + + + + {6B143A39-C7B2-4743-9917-92262C60E9A6} + taglib-sharp + + + + + + + \ No newline at end of file diff --git a/taglib-sharp/examples/StripImageData.cs b/taglib-sharp/examples/StripImageData.cs new file mode 100644 index 0000000..63aa740 --- /dev/null +++ b/taglib-sharp/examples/StripImageData.cs @@ -0,0 +1,117 @@ + +using System; +using TagLib; + +public class StripImageData +{ + private static byte[] image_data = new byte[] { + 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, + 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, + 0x8C, 0x80, 0x07, 0xFF, 0xD9 + }; + + public static void Main (string [] args) + { + if (args.Length != 1) { + Console.Out.WriteLine ("usage: mono StripImageData.exe [jpegfile]"); + return; + } + + ImageFile file = new ImageFile (args [0]); + + file.Mode = File.AccessMode.Write; + + long greatest_segment_position = 0; + long greatest_segment_length = 0; + + // collect data segments + while (true) { + + long sos = file.Find (new byte [] {0xFF, 0xDA}, file.Tell); + + if (sos == -1) + break; + + file.Seek (sos); + + long segment_length = SkipDataSegment (file); + + if (segment_length > greatest_segment_length) { + greatest_segment_length = segment_length; + greatest_segment_position = sos; + } + } + + if (greatest_segment_length == 0) + { + Console.Out.WriteLine ("doesn't look like an jpeg file"); + return; + } + + System.Console.WriteLine ("Stripping data segment at {0}", greatest_segment_position); + + file.RemoveBlock (greatest_segment_position, greatest_segment_length); + file.Seek (greatest_segment_position); + file.WriteBlock (image_data); + file.Mode = File.AccessMode.Closed; + } + + private static long SkipDataSegment (ImageFile file) + { + long position = file.Tell; + + // skip sos maker + if (file.ReadBlock (2).ToUInt () != 0xFFDA) + throw new Exception (String.Format ("Not a data segment at position: {0}", position)); + + while (true) { + if (0xFF == (byte) file.ReadBlock (1)[0]) { + byte maker = (byte) file.ReadBlock (1)[0]; + + if (maker != 0x00 && (maker <= 0xD0 || maker >= 0xD7)) + break; + } + } + + long length = file.Tell - position - 2; + + System.Console.WriteLine ("Data segment of length {0} found at {1}", length, position); + + return length; + } + + private class ImageFile : File { + + // Hacky implementation to make use of some methods defined in TagLib.File + + public ImageFile (string path) + : base (new File.LocalFileAbstraction (path)) {} + + public override Tag GetTag (TagLib.TagTypes type, bool create) + { + throw new System.NotImplementedException (); + } + + public override Properties Properties { + get { + throw new System.NotImplementedException (); + } + } + + public override void RemoveTags (TagLib.TagTypes types) + { + throw new System.NotImplementedException (); + } + + public override void Save () + { + throw new System.NotImplementedException (); + } + + public override Tag Tag { + get { + throw new System.NotImplementedException (); + } + } + } +} \ No newline at end of file diff --git a/taglib-sharp/examples/covers/sample_a.jpg b/taglib-sharp/examples/covers/sample_a.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad0c88d67f4b721c0a008d04cc1d0597627bba4a GIT binary patch literal 31212 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� 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 literal 0 HcmV?d00001 diff --git a/taglib-sharp/examples/covers/sample_a.png b/taglib-sharp/examples/covers/sample_a.png new file mode 100644 index 0000000000000000000000000000000000000000..1bbadec94e886a6fd1c7810de8e52c289f6e940c GIT binary patch literal 14318 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI&4kiW$hHvtcN(>APoCO|{#S9GG!XV7ZFl&wk z0|NtliKnkC`!!BRQAy=_Q(u-dFfhoLxJHyX=jZ08=9Mrw7o{eaq^2m8XO?6rgk+>D zxO@5ryiZZhV_;BV@N{tuskrra@5^Ep_p%2s9~P#%q&=D2d1RsnL#x)6gH|45vwh8W zAI;0WvR3l!irZUm#h&dsJ0mJ>w|x5l$y@(!$=43EAj8hCICG<*+Gj(fdP-E=~R5Iw` zKO-%0PsyO;eaQ^-FAD17jgB=94RS}KS=z$5IbJyKaZR{juE6k6m#KLP10zSipo9u5 zheJj80R>G5hC|UTY@UovApKCo6DNy>dn#Qq1-CJhWN&pCP$CX3G! zQLu4M5Rm_(0P+{eqJ|rLT^*bx91gG?OlDDOVPyHDAg64g!3=WK!GhbV&u`3`f8Tr@81HP~93nr1v(i=A1^Rgg<|@0WY4rAuPPrfnBC zm-k)!?#OqaLWQjf4)+@@d^!3I^?Y*o)_(mLv89nMu!`-BVVaee`k}cmL;mjFy?Orn zlqlJ{fUThLn4{*Rb*UyZtvEpJhtI-|Q+>_%RVV*EmD8Ah_F>!F#(j*1PJ)j&zH-^q z))qNw;s>qi-E6aQ^3ntc*?EF_Q3z=8XL!#4$-c^ur$d(P`(D4;(Nb!PaFDQKNqViD@f|)15v6Zp9s*j| zmUwCJ_7xZ`vT+R5rGwI3ar)TCK&kS8&{m|sN zxCpZ^m%v}UlnsiXx>QVp9~MPS$UGIW#UZrs&9&oFZxvqt4{6c3Z{gw@)v7_AW0bqok=; z(dgo*ltm>kmc=Zxkz1cP^|9W4GqJVGr}EYxGWb|#`Q};fD!+UYCF#}^iD6a(u?82i z7$5#ioRGi2_T}E`o4Tvd&p-1>!~2QI#NbImxjI2r^&hu7DL<5($aCHG-v!w+!wbIc z((mqzO~3W6dso?X?JKJPUo-kkU90-PwvNeRCu6ZS!cB5-=W&1fB>miO zr@_yTgKgFJ|9Urn&s!JwDr?W|s0%j^=49L|i8p1N{Vm_y^-2B5uhou@cctr0=iXe| z@;-lwedHXyYexlNH#JK1iQn9leDKxIGneYP?`U@hq$d6mZ0^1O+`hY`c0Lam_os?A zUv?NgT_)D2IRDA&=S6Q>Q=@MD%T;`Mlb2_nX`1m>pEarl$L`ndxe$0W@KsY|;*%p^ z6=rO5**9-mSyGarQbuR5>!O`fO5;?AzI_arKpTzb}S8>YjQ=3*&|0n6= z{PK{48^w5X7c3N=R`&YRmN{;R;xuMTm%1PEGr1udBI>sJNWy_{eLW9eKCAd~Fyx7! z$p+;wJpt3RPPweBD_vd~c(K{tE#cIxKHG}VZ~R%q?3^yo^wo`DbAR9VuSMa{-)1{n zTMDsX>X2Ri{)c46{eaB>+l-S%`)sSuFOn|VCniZL@E# z-!)^khkK3Q3xv<;t=)E?>AUV0t>=^EPi7@8FMOx*%r{%yXufO9slr+N50r`>d;d&& z<}#tJD_NKIy*vEl)Zd-QC3u+U+>5ro6|o?12iIFK_vql0vljP1H%MQzXw!Usf1O-a zw>yg@}P9BO%20v$B=nro6&+z)Y>b$_l2tSs0Y%jQ!RPO(rl~}lV{n3aQg1!8ulLI<@ zj=wAWa^m?;djp+y^7TDd^Y`f%t$lo+wRz8+DO~-Z#B+AI7x&uTnpyq)+xtH^xBri~ zu2*v^3NKNo*)3;9!KKUzRjVQO~-VIxw zba#aE<%=!OJ=$FC+Os|<|9xb`JzM#I_K*L>?shx&ZpqPT-`rIz&-UyP6G=VFFVFV< zRO^@DU2;)+d)H;;%{565%G28Aw2)EfhDKM9dznG%%=X=4Ywg^foL2Zxi~o1_(e*=4 z-dtPW9-rf7{3asaCvy6x+22-MoJ}$F_B6l5-QD%~ySCKsJ#+8qxP71R=j3j?%w&aF z>tAs-r=~OCB466yjD8?I-FCNT;m(WS6_ld64c6^Z(@(9N+Iuf`!!x#v(rm1LZp>PO z8^s<;mziBiFYsJAanH^w*C)H~@BSx!JkTWG-=fPzC}%mp)#=^)r$|3ciY;2K&}XRG zo~auz(f9eYMgHM^vpRx0I(+KPzAR38uxz&3!ONxd@_P2McXH1@ao449>DAUR>MJj_ zNgrWoKe+szWU9`j@|7;;PY+((xk2Oq_WXZubE;0Cyng=8wMl(#5zfvuI z^WI%Cy)Z++bN;R2rT2e2)=U*>YuV|}{qVo-i5%X1?<@s*8R6o0zN%_(&Z+Iw*tYC# zxsF7X_3T~B8{RVJ2^vKBx14IewMd~QXv=}`asNuK-n`kVYnm)OwOFLuDrz&oj498v z#JoF8n{<|2WwO0JzFEia=ETLCm0CaeZ$9vs@G88o6JmVJRB5qzyw;B$^S914m5b}` z{F$Vk-Q2j(OgQx61XfB?2wCS9>7KhX7-NAX! z6g*EV=B>LYwtDRZ@3TQuX8V7h&VT8u*wKL8egP*%<0E-KT<@1K%O|bcAJIN-T5je| z!S4QJRTEZ!`#M+Y`ivf(sZUSN>wn_l5_O7oXIlLFSlzf89nYK?ckh3cadugj*vrF) zhmCeU(W`R^WZvm@t5>gLdG4=iLIEY`o(dh_=xu2n_P^Zz#{m<~E~jO#ww7})O1rLA zuXK`}C84%;x_Zg^B2#AbTQ&Q%o^>t!TC?MCiTdLox?PU*+!iHx@o(;b=JY=>Dg1XV z_tvi;Yo1@-HczsU|B$hf|9A7uBU7ewuD3n0KQpTRSaF}{>{`}|l4`#no+{s0{dE1? z-U-K!Ic(G5Sje>I_H3KaUn|y`JaZHOHd~lO@$#W%FU#&etWfb1y3&35=;E_)t8GFT zZ}+-%_ju>`_kH5oj{^Lz^&k5-&&2nNEcYIB;a`I7zoi&8?g~l2y5slz>!hNs+dVB# zMR~+bJXY(je(Xq1LuTpM!|P%y^{K&ry4=Z-dI+@9_t$W<{MjmcQtq>vv6SV|Kse}<=*=2{@QL`UoU@o&O_PLRb{mYrPs%5 z=;XQO>n`oTzi5WwZ8=4j;Hs|w1$tk^W%9mUoyF@NlUZYby{dYJ;^J>x1!nw8dGhb# zuZuf&%w9duUO;h!?6sqYs!kerpLDJL=zo3R)mLsYvP?x2n~DOK-kWAuQ}OlOu{mj9 z3Uj+AU)uOPvoA5pWR(!l3;pxcK{n=#^GFr0(YosSY5p1S|Nmwtm>gd;^WoNK^6$3X zzp?qi#r}IO6I#Di%dD00%vRBRC)dXDv2>Qv+q3I$%*xQZ=u}*^wPN2&m-#WJ54UjL zvcF~$be_U(I}%cXr=B)F{%o^_Xz3y;{r0|GaK< z*ZeRKe&qk_Ym=5+*3ys7HNV?DEBtfbpHykdJ#*CF(fzKEe``^@qR>Iv-z%r2eX`&A zclmjJ&AV?5Wx_5q+~#Fv6P_D9^>F>i+3!WAFYY^X&d^Qg$%98(TU@_;tvQ|a-mTz? ztL3Ix1LfPhQ&#+%`5@kx!~S))V26N~cDVeNf4xad*d-p6Z;6UI_h(LepIr&d&$NbI z?O8u;lmyS*zP)Wx=d6SBiE-|H`5MU+l}^7no?mm+?T`BWy`fphe)&$A#B-hXT%u6i z3eR_zla zAb30O{r$qiY`uS)R&G9$%hr@+Ja%wV+w{^vLF41z$2;A*$}Au72S1$jSLVi3i64{C z-@B#JEAJ>S{Bf1@7x{(TzNh{vamkswNc!lHjAMJZ9l96i$(NGM)4xE|c#4hgpQ~Gb zg#V3DxN3H6`m6t1>igG5PI@jbW)x9d`e}XU8;iUf>)k!PZdJ)0G(KgVc#XZs>}+Rq zzoW(5ZNg5nRV-#PcF)eNHRry&`9NLi#6FX`HEVM=%9X9ZS)=>o=&6+a4>DOVSDabS zf4N)w;^P}~Qjty)V&-a0?|ZoSADD7`Cck5dv+edfKPE?&&r`T{*!96>L7(~lb#u5Z z?;lwC!tuAYrkc{~mOpY;@5G#s_a09w{&PUz=96uz&RX@uPZ`fT^=o|dxRB@=k=t68 zSrw~fGI!_xd5$f2EcTbCtx@}AwdllxKPJD;UOShE3BSKD`#x7lZoejh*zq&yS$bdmy{pYXuid=)W4hV?&Mw!s zYdn*0_j|N%t1fSs`xd^;^}U%I{~xF6<>B`K+dBhvZ~fnUYk%yjtHSnszg~0GES8DA zv3!98$4RdH>(ge-zWY4& zn-V+ic1n9aIwgL2|D%lOS|ZV#70*3v67IXU$Z6-5U#B)Ue0;I%Z_wt2N2=bt!*8#KP)d@ zN;}UnKWgHvNo8;Tr!2OqzrjBH-0ZLH?Q4D2xBZG0C@ZZqwf}nbmeaa9fhJ`Ny9$hZ z`hD)kDb9Fk$Wmo}MsH`~F#(tSllLRDYvWB1?VA*0_U-A;C+&GY+`CJSCw)Be__y`? z_liajbsI}1(mtO(dD!kpMq)P4wPVSZ$MdiHs)fr<-`#YFH!S+0lWpL87VEnWiM(pD zyOS@-^sW_uIL$Y$qDNux!HcHidu8`t{dafjv-uL!8U#M}FLA1Qdg_P$j+q_bLW35{ zO0C|Ts_2~k`Q`3!#eq&Ml0IMHWw^X(ZdyOPi-h`;S+gT%eix7bTkvvM;-%wzx}R>i zzr)k9uq*d{gKk%&u|>?{mFq62bVg?XO<4Q0_OMWms^+}RJ$8TRJH@c_?&6puBdYb{ zq~pC)6-OQ(TG1z#quG9MLsHGxE&mwZDlY78etePXbqV9XJfrU0o2%O;+8$Y!TOGe5 z{oMcW+e>ExB>SRoFMZdm`_p=s=r^w*lcipbPBC|SK3FquI~gG5Dk!x&ao-8!T$2{3 zWM$!-8e5Gx7H-+{wqnBe3v+JBxBT_djfy>~7SJuQ>gv>a;!|ete37Rco9o)PoV(AE zC9e3D;|I-cw&B@_lI^ankx=AG-EF%fdQn=d?L?90tt~$+q<2o`TGx^D_@&#Q3y1kM zUDOt5mv4`A=Q!HT`g@9w*ukBrdVFMxTX&Ac}AMS8fg{k+avt&gfw z*?Vi)GgMS{bHCRJ^=+44wQIxe4ZHU*z9Dnk+^D^(hPM)&2N{Jrz% z!dFVOb*x$XgjVTsFTe4PFG85lhHFi-&z9abhxbY5sWNYO)6tw2bbKj0_saRlTXcP9 zW;}6Cxb3*_;jzg3uiCQTw)kFMRrDsXZlRX?y#KemWa4jGhEGjC|L37gPJ7`-g&fU; z3tuS-ufKhN+S=JW0=VZV-F8;?;7As#3$L_3WxGW-@kGdn>#XJBH~GDSf)*Hv{wtF3 z6TcoDG>I$MeCmottsEP7E3dgCb$j+C*$C6SDe~ga1r(nfonBdBcw)PtQ?6-5&Jww| z=hlm*mwvu^ps!@dn~Isf(V}g4vko^M-gsu+vE1-Qhco6&2sd6nv}jsKiJEYc(xpze z(6((7w~Tas0*`Fb`1SG|r{f7Fkyeh=5uF9*LYG+1tvP*1{B-C3zZqGpC2aOBXsZ^? zirl*}a?)Q>Bcbhr52tD0J+1tDmr~NAGZJF(u)(my`5gZ|L>=F z|3Ag+)fSkyx=C)kwmwlJY{QB@mZE>Et@9O^`nJ}EhCk0`JABZriQ)2#r(a|$Hga4$ z>)<)Bhij=o{^e_)E-M6_y4H3kWhYtftLlg^*>j_Q}&&cHN>5&$s_y{@%~Ux#~o=PHvLViOUw>FUBN1-1KL&`L=)8 z<>$LQb45#^Sg>Tq<4tz5&%$z7HEJf?{kop39Q^B1P{30&eyTWr)XFw0w4&6#!LWI-oc-H@!_ zwPNDeP8YMEQ}2(gee|y2{D$9-J0BNBDj%P5Gvw{eOq)+LS(RGi?80rA`OHwfdGB8R ztF#4+;->E?{jCr*>yqB_|A%cqrK>*mde64;VP(&&yPZ|#k22hDge`Xc>En5B+LN4U zUhS$ATlij_kU4)V>dDC&>oX2cJ#@54dn$)$)0`fGNmm10{lcIAn8(U@&EU?F-1n}f zeCKl`vf9=jp8Ray0-?!Ul25frZc}bi*tIB5TD)F%f$W}%Hg|Uj{660@VNy|PK69~z z+~PFzy;pZ=6+SIcxIcZz>r*#&d)HsP=(OyqhWYc&+p6o=&CXeA8kdvi_SnDN^c??A zc^8hiAxf*xb?hm-)Vtx@qrTT`WgC^3EcFe&I{n-HiS}z)ZvMG?<^M*3-|GeQT9;i> ztnA_GzMUHvrBj!_`(sdacVvqi%WJj$=2o(=)?GNXN$PffW4mJ2{*9XFS>md*=>;UyU9QB_LK4I9V(e{?Zk;8OLarCG1bMF5S-JQF?<)D|% z2APM~)t%6^Y6Xcf&b+;O~fMO(CgNi^^6W1-5C zyw#$I7fSOjHmQ7P?)>SVt=^J#=buI#v)L*3!~XvZr*#@~!2vu{o@e?J3tgYK9S})d zGJn_iKbNOW6ME17;@II+@}kz$=goY~`>k2|5MOs_b-0)Q{O*A~B)y@IoB!Ti)G{k-%h|kzc}7puN>~JEv_@r=nu|`q zrTlrKUGDTNml@^DO_$wFyB!;5T=3pbqh&&B;E(N_B`$GC8|&N&dr=d5<3zjM()~|a)@;J_#-98;#ct(1DpZOV@gu$?mxxu(|)see<;oRay>Cc~~I0SI>4b&xNwPNAtqYDYv8vcXtLT zp4ckjl&c#u%{Y50_v@#d+ut(wJ#c$GH|o>Hb3Qs(EIt&}y7S(Nv=7g7b9-zUb^5sd zj{0xke_QMAMTw#Q><0fNnnwop^umO3%A+&<}Gu*R)mPp zl3jN>wTg2Rds5)x843oA*{|>3%%5HVE9lYvZXbEeV8hgToqMi_9N!+jo-f^?MdHSqxZ};&W&R$sJOU(i}S8bRmg<1`Mae4AN}Rp_&V;?x=(AiZP(8i zjLC1$TNkrux8?5tFOGd!_sf|h)2jIS$0d1>vWuf{rs(RFY5E8(_9Qf4cI| zRa;{D!lN6*+OPB6dGGNwRBW$e+ge$9AA#8L=i;mXf2#Sizio%^_sC7mKCiugxic=? zc6-;gYmfIHp3p2b|8e@4b-J&)7tX$8y!(UQ%ZAl!KkP2wzb|gqjybWOt*cG8-C8w4 zd%1Y==G#|G-d}n>F?YU+^&j!o!PZkxxa^VRD-%@g^-I_-bM|`EtbaAXRh(xj^cbx^ zWXwNPQ2OuX+eR}d6&>BcR6KG1F=lU*rMsh*CNW&D(EJU%{Mfzb zOMhbC zGK5St9e9`z{#Yob_AvYI&RtfQ1Ju{6{GYV+?tN1ai8W_k?70kjt6S~YXij!t=el?D zMV^NnWERX)ykeDnVF`m_&-TRsA%{1usQLZ$?lr;y7ye2i)jzonG>sKX4{i%8!{q@}&!EG6f8{g)i{ga=(@aW%0{dfD< zE>w{ZUuQn$%IExb+AFty+UjP`>B}W>*x`cxpNIVJj}MprY+oh$PHN+h4Tmmy?JqlV zac)S#)eRMqzB88Wzgy6KLDqK73q>wPDQOckj)StgbMnvXiN@VtHMe|!F#lRHfm+2C z{B}PWWR=sNpQv7DwtwM-X+qQ2E%|SBVp@NJ;`%%;{;vNiYkyUR^MCuD%X95eV^Yi+ z?igXgD;Jk|?JV8K%D^BV0a^=SeffnN@8r*6Y7G`gIbJpM+kHs9t8vPUt6N;izLTYB z%WIq4zfY(AeHwk+KEUMUbE&2=1 z+3%UX>}cq%$<>{U4}N2KxLU5|-$VZT3a2TKFQ-KWZ_>@xQG0Sn{ld{HGbc`qjM6=o zUTr-AGz+QCVi$RJ1IOm8JHFlgw*Q{>-PfCRmfYVz;h%5A#D$)Whw?dUgjNUU&9AM0 zT(5CL+{6C5Vf?8-X-2zFB=F7>QK)G>puR;)*R(eK_x@1X3^?}Gat?UBVV`c>+&wS!kw8P zeS%ED3l9#?`J*c}XLWq$>WkekCndP=(meIS_ax7803Li38%|0^qZM)-Ho;UkTujg-V z(AXd@+~^;CS7l#H{TI)${r)xAl^mS4%^gZZo&6uM&7>qS>4* zli#7FAF}%B6wwDJjc<*5961bqmfd~2TPmB^SkP!j`F@UPM?#wy=}cUEwDqiqg8ZXy zov_TD2(e`w<;1tW@h#Bbd8>Otew*3liLY8ue*G*wdu4&FVn~+T^lh8FcN+h!x?+%N zz%yTAhHxNn*QSU&oP|?E3M!3?^v^txj9RKO*=fc6-})MNpTrB)2A?>i#(jV1r<*fF z>fS$e*<&N9pFX)Y{{G&5aWckpKdoze+sk(F$6o8>Q7RiIbK0Kp;8$*xWy^NoQTptp zwP04+Wc`kP$%;Q`i|4=JeqgVW{l3d@SXLKpQ1ecZsBy8a(vU@GXqJ(C! zxyqXNFG=GtO?~5f!Mydt(Ur$HC*N-GOtK1{<25CF6HD7ec9zG7vo`FoRlGa5w^l-Q zTc7b4+x_-|6V>BcYCo^}cj{)l*~|Rog<(1>&51u)9-1kh`LN0{*y^|m>o&1x+f~;I zaOb!&S?k=Do$}VU^yG$}w_GE8=Ty}ObNC+X_FS2$%qtarCfvBCDY2sCgOMVS|LK)P2& z|4|uJapr-ZR8e5b%fyFY!^|7~s%LPt2B<|v&A3tWC2*=#AUOChHfMVIv%im*{XOwS z*u@XsiG}fb_0_A(?kWAaV$Rg~eqY@`yVDkDGOMO5N%#a#JMuox>+e|( zoe2tFSC3Zjz8|FiSzJ{8PCIVpsr6L?X-6g{ zZJfh-SGr@Pq}c6?O0mi*kv*OnEfZ2NwjJHJ)x+5{)LQtf-=z&Z#Fuy$_7s+;rT$uQ z_vdq&qZNkctlOT;vlu_hx)3pW#~;Jo^*4Q=z6vjs5|7G?F=n3Ts^l zX0OU?*+63nkYcyBJeMCu-HI@o@H+d;sy4gA}e$Q;@o;*7}sB*fv z;%X`Owujmv2d!w^aeLRL>4IWUZ|>e*A21>PB=?5n1ugB2+p3?Q;X0m`w|mRtI7{|z z<~rNIb*x?(eJJmB*2da{soj}n$FFIvpME>?6BEmB8QzJ$V(O1lzyDP*{r{i3pFp=(MuyKMggj)ft{5t;taUxk;?nqDP-xMAN#$LDP6m#mfU zyI;BZufxoM$6jH^#b)0l)2!2PN9m~Lxc!(b5S~;Zp4=?ZBd}5D*oGT@a=B&4vrf5e zo-OxA>BE$l(GRxX+!*Wg_2I`&I$S)5!#R!#Z%7Ty)m2>mQD#@)9o2u|_P5z^3U{(b zzw}tEZ~xg?jJxfjB~$YcKa(W2y@!pgUhQ{SFtc7jg6HuQC4*F5pS&RVtp|dYS4>_P z$%emZVwKnPbRXa%p9ODoup7}QXoZe1L=GRC*(owPE=e4EQKP0|SyxqRGQO~Xa!}~KVNfvxHKi+E3=l-)%uhYgLhnMHD zGYi|txeA~A+Gpwe+Aq7nz?E^$o`dI+wPQzq{Lecd{Q@7|VoKzDB+SBg*g~`8p23TZ zgjwhIooIgOc|`{##9@9oAv|4M_vArCXMq=o!k_gzN~$wGERy*1=Hkw>>E*W;F~t7h zZgdP%XL^_>vF7B$Xzg^<=8f@Umu@h{{@`kK4EpE3Lx#=1YDYkh%Py((_jbK()(g1f z6%9O2{qJ}mv-hb5PgwM&!)rb79$4yjqfVu#?UvH|M!i4H4YO_j_Ib2sPhWmrw*6rL z^mEgtgq$?uyKnuUlzL`m3UA3nc@{R$pOTH5uV+u+pOO)NI6?pCl`6%|$Q$Pjn*+>3 z8DoF28=jc_bwN*~@}q^v4!QId+43m0Jjq+2#{RaxzHAT2t`C9Xznk(e{@BUBa6)Bn zS?H6{?}roK^G`1~`c`i=ch$Fd8O(=2Ff%p(sL8&^x$@_wFUhA~GIj4wEO^gD@$eicc(q(&DPu)Fm_>N1y#GUHfRfe7&cV(t6I+3!7uUKHd zf`LSvz2M%&3m=)f+jp)EGX8Vs_N%uE$2IfPbgng6cK8cO@EmUE@QKW8b98oJi2+w{>R(F}{rX_b!`^Mpf^N-SA_0!#bv_)-lRn8j ztdj7tJK-z)ZCjA@rkq;igAG!Xtrl?GD;Rj33g`HK_`&nl>7rAu-{kJTx*}8FyxG$% zls)zbW20lxJ|~$(37ZeOJA-_#N>+ROxkW*>xu06F=5_IDz4n8C)3-X7gse+_J$s?R ztGCyi^=#aEv=wbjtoVBC%&OCg7X&Z9V0qJPsi%1;e6m%eo{eL|jmEE@{D%yW zWquKJRq?_|z zfw$n-p9)r!*Op8|hkh^}G(7h8rl@DY9cx!v!RVveTmITJZ{PA-DW$aT z-#cq-z54l=$%c|8;8mVB?mo-A^4bo5b=vh@q_qD>QSPNpGUuN9FJHZ&TX=#1n~JGT z%jv{`z@PnM=k4uzZYgJNx)CB{rlltAd!ZGyVDppM!z>AvD~H#fyth=eR#B&Wm6`0j z*_|xA7jWkbN~ka}8dg$rB1aHB-wP)V(Hs=X2El&&H+F4;MI(7M^(%;|T z-@m|KTHTb8zggJF|N3SD$BsicHtBRF_iVVq z%XWn!JKea+TtoowaSN*$#gYIN0#Rt)GK! z*ZTSO6_r(YKl)u16!8pk+$Me9P}C(S}UFAAm|jb>qP zGgM*metojQR#;d4@Yjq0KGrEauJEvm9AE9?9>cWe^AxO!zDt&X~oil1$m&bHZ3?3v1L|g=mk#Ax9jEpu$K1AH97_{yL&jPKiR_gVt!JT z$co#bMZCQH57+K)74S07IDF*W{yXg^a0Y^prCJ)^BLqm(65aFJuB!n2eaCB9;> zb1!aM5jSUfYT(}A3pid~)Z`Lu5jb{aiw2kA;U%Wc>rOiDldAfB>DSH9RcC**i*94v zR{o^@%*vaKKK2`Z`dYDXnnj;rl-SZ&Z~RPuoxF7CZ|}-;;hXo#Xq-7Lx6fw(V}mpy zmbQnwO_rvmpU?BD6y~q{vw(K_wZJ4-;aXqr2VXN`^BaNuQ(US&RD*v zx;5dzx3-oGJZZ~kX)DnFR;WHuI1p zPv0Di7Jt9n(m+wWQ9mr*q**dYH$(mL@fi)f_PQoaxbi_@(uJSzw6|A;m2Z}cxg}RW z$DePHn7{Itx3WtXyc3=+z&0gu`>kbXx9i>QZ;i@}G1|TL#@eSh?-^M1MD5UD@b03r zfk&1E2iHvFmxrXeyYp_qJZc=T4iPd~A~jDD|+Zm=?I$T={c%_4dgRmn~+MQu}-I@Xz~q_FgC~ z-~V^wv6S|M6MnrCV_i}Gh2yy{*MyLG4k_vU_@6~-I`7}~C|=pUJ^t5=hdcXr*EGBT zPH38A#?>ycjcwcY>(2VZhvs;t#+=KGnH^gytW;cH`)hIg^C;Q66v zD42ff=*^8ypDj7Nf6eZXuias4cPeU%RMPL&i{E|z-4dRr&6MA;YcEKxp`c^j&s#rL z8-r!r4@R%v+`ZHD@DlgP?y&aTTHfE}r}=K5G?8z`ZEY4dPub`Etm}RsYh~x29KCK@ zlll5`)3PI5U#xf&r018DzCwA zw!X;v@%gD?^?JecGsTx>bMPGIW~n>4J)`fNfneUgeIEjf%CG-D<(IZw>U-Gza{1*Z zbGQBU@R_)}SahE8K?Aq`h8BZb`y*3IbJI*`>nN5#eV-S1e|OeB?U_?vIjwu~K-t#% z<_xcs96ZTSI6OEme?J_uq^vaUZ0e@h`*&B?u9o>;^Cc|g*}bYu_uREU9b3(<+Gl#u zz^w;ls#@sMv-xqm=1-WD-)HFaYwqmp|3BViwZC#`%L?n&o}uL&&-NAW6XDGiaJPE& zt@GfwUsV;ES$|KRnU!47lXz+WuHu)Em;T(ld$!H`qhX$>!kfR%w-tMz@<=w|dq=eZ z&$j3P5}mUCU6!72Rpr9Da9>T$v%S^gsj3g=N3F2>`!eZRom-b-Xa z*m32L`1*PYG3!3zi))Mi%$t;JXH>resqrcy;}p z?VR&(ETR&2pRV6gu}_V?HljO9dqZTwhlzemZ|BFJ{9bxUAm{xI4xULx%{#0<|2XzX z`S?-=#~1(7zP)q1w!LZB=4o5jGxwf+U!VIsTl}<%T0-?=$Ak$}9=qN$etF1T|E^%= z^J1aas4th7Za$?b9B9vxm1@08n$Paij3xhOzt{VJa{G04q1<0PeMA$gncWj6OgWoh z;bv>U@$2#Yed6UC)f1zBq|c8(IrVX!*p;fdRa+~5cLi{GF8X(V-@M<~@5k;o39e6b z7s<(g!11Rk|Kg25ZO4vXow-$h&&N8aqJ7826~7#P_2$yImc&bS*S4=Q*gidYnX6@3 zd-B@w^Wpz~l$&jSdG6lM>J57n75>Z+IHo>(PjKg_+u{3oKE;}g%~yG`} z@A>!5vy#<^mCB!9^7*@!`{`ckn+LwNH8!*uw5OF+em+!dE-l2N7|Hpke*T_IyANIX zpQ!XR>%sB&=XXl-R6m{Cx=KYVq5811gVT&=`M%?;KMUXPTV5*Yw9B*pQ$}57`X3g~ zS9|r3=iB)RK03vxK3TSJ~=U!$$3zVH+Y2|qmF*5~4kKbO}( zzhroH+3}rQMQ*=8(b)OofV`2y%IET4PVLFEd3}K)@AT_G_x2_|dcw8p=CiuLuFLK` zsDFQTF8AeLhV+2*Hy_Qt`Xar%({DQ4ZE3kCMo-xv69iHw-|#n|G5=mos-gMK)9=cQ zSeL%~vUcf{M{ZB9ex7O`ujRAUDlzbRM6h|mM!ATalj?p}R&CahQe%P`Vf%l>RlyY3 z4wl>P7V0aW&OI}||NI;&$E~8z%(q`QpZ=)$@!HN5brp$Oexk1%r>;#{dT_Sb(;L?t z-paBcY*;d{en)h7ez`fx5}SL*PM6+vSWnGZDHyiD zs!`oU(?RAlzofwZ#Qhg}(soa}u})>)Z|5cj9~ObdJkiV__s-y$aPow}1OYaI37-xm z&rHYwZ(0KND={}O6*@^wfNWwy-AN@;<0KKlroeFV{wx8r%7yHVE!#OfIGAlYGOi)^ zFexbVC@f(A_@mkIg|tA!hiiKbA)A^S!P}(dg%33>VPNc-2;bxd76!EoA-kt;G_rzr zQ9TfjGVgfEaAc(;c-IuD(v&#D4&LSE;3VPT!2igQsd*nGBL}GMh)p@U}rpA1uBCZ8sv^3`~u#OWpR@;(Lu6-;fNv1 rjBm<7<_#hv=|r|I2gd-|33zC=c3fa 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 uJwI_q$pZdN2`MmwflGQQ4T;7;(=Uu6G^IQAo z9rHB%m$z;{*!6PW#m5mr@f(s>Po1rzJHy72?<3#a16_O1?+X@S8OgeP+z@Vl!YV z-dwk2zULCo*|{6<#eZxG62RW^3wl%OuZDueh^3?`U+IJjtDFy|3wVnYq-H9eqFUdrX_8 zSj4BK)wNqJQqk;n?GgI`MXpsJ_UP~bm4CVTrNw`SyBj0Ew*P0Se(Mo$|L0Wo=BW&- znhmGczg+xf%1WO2AI2HMh7ArPYIkzoYZjRaHO*+eET|XzNy7dPv;5+^rT0Ca{Cm6o zc+>R%42|2?{|V-q^LENA(azAnesvQrDfa$nkj@o66ClWPa>MT6`xdQTfp#)32Yjd3 zI*I>1#&znS|8Mu5a`v|l&kOE*f6ra!)1311>cU^&s|(MUZ@2XN&v4}azXkspzQzA% zkX*Tb{r<%|@-L_Q&b;-u{m4i5-<(@3ntLQ9lU|9I|4=iUoH}3OiX4OZ_ujdi@?N@J z4QLHD-WI}dV991W>0$JB&$3$7|TrY@fM^^SIJ(48IrC6GCFP{(cQq3u`yGuVYN@PJlBKsrO< ziSVzVf6h4KbKPe~v-2v&ZwC)rA2Q?YX>coJkmPl15d2iI7TR9|t$XMPEqM{qUDUaD zapaAyD~05`jvaN)clom7^^uOV(brF`FLLHSRq$C+VNPbHACLQ8yPvO`H5Qz0H(~I3 zc&cB+VgHm<)(1W`)?f1C=>98Oyjywow!g2ROv}6Aqmr;lVWq=nhRC2fM*~Dntq;v8 zXW2#(0m#&(N9?DMCJT1FE<8N<$Mi{m>a#Uw*7}5l{r7!&t<~-HOnYFveGJ0Oue}*@ICX44J9^KHv zyQ_D}wNS>-4KEihD){Z?`%RFe#$lV@Dzo+(PoT*Nw9Y9$@LFVuOHsSw9AlwFB1ZYQ z^zQ%U^jLU8scY}WUD+&`0@#ZGshhf}%eX>Uxs_b@E%)7c&1Kj1x2yBD)VK6IZCN>6 z>e#+$*Kb8OC;F@oAO5M;+8^?c!fY=L(Gs0^; zTwCq;?4GF6AS2-8|i( z@qM!BWZxYcMFJ1lf5#Va6>54dueJNg`}NK0oDJgA28X#KKfC#VIC7@xgk_`&t5ai7 z(Yj!bq$vjyOxiYcGVr{VJuqpd-mGk;g`%E8qApi`j#_029AFBb@KjKOM(ZZ5y2*|%ZQsz+KH8&8E?Vp2&E zW(+Z}@M3Ue6y%Ay#lK2+QH+Q`!+{THG};)M^uD@oRCl?P)abZ4L4fPT3oWsaeRpNP zv|jJq6?*)}me?T6tWBvWTC82KUX2a)KjKn;Si^DqlDS)!^t~^z3RtbmF=Il}vM$St zoLZ-=rRnEnmwfhoaKmClvRmy>**^Z_tR)H)5AUf6bdS%U5)!{H?N8GCE5}YR?b&ui z#^wGI?yb3HrMDVHwQXun{%2T`_@5!mYva2qE-AqllHPk|r{7q2@zL+_4H9+ceKy8# zJWs!g=-y$JvDj#Fhu$m|Ef2LxE?Su)Et(zMwG(*8n z|6h}1Z9?}KJdx=M5DsCn@0hidw|t?fw7dJ>q?f-UZXA)F)xPp_Ri@dgE%(dzrrfr* z_SiUGV97=)=L<)2JXS8atF)*qm0^KM=Y*vU z+zbqE`~Gb&3n|g&$YneQ{6kRd|r;?X@17 zFH)t?N9^QH+5F+X@rQ}Z5}si(>I{rBpSK)PFmcmjdVclx@$$4<)3OVt3cjeSo zYob>D((T)!dFX7;>($G=CLP|oDXhk2{TyGPD$Ut%&LlS`Udi9VBeSWbZ{>;0D^sti zM)<#<@MVR+PHUn><+IyN;>|}M?YShJ@kl|~_0)uw1uGVx`H;x9>L(x;e>TozK&@&?uo|VVBJTFD7Oy4|a>YUmWKjjXHQ^uk%a3DW@h}&aO4D zI<#}Csw#W#dex8N=my`SkH`u<6vV&u>k;kZ|MQ@i%JcA6snWnpL6o+qZjVYZBiK$q$eGV;;^ZEEE>pdA+A-_tJAp>XD~T>8(8C;^J~jD_Q2UWJkvg zw@0QDXZ_c=x>y(F1se31CvITS@c-=)pPV)!B!x*$kc-tP@sWiJs0IQpij+3{;=3v^ zyKZKc)6>uri%V;_x~+S&%v^TiOtaEEC(9sEBmtmRk ztCXL?<+&~Km51|eKJ}dTN`0KU;_SA=8N8ow*>sc(btz4pDD=r?^<>bJq5llgagK~T z!hWsDE`4U{>Idx6N(q-$nx*616JUw^z%`cuacBD*G z?zA-cpjFWvp!dMweeaCib4s__Z>(K+G;T#mRN`*qzP&{&+gz1&HyroYNR(_@62zAn z^EmqcGPR4Fqf>VW-t_yyrf@o=pm*W#WM|oV>TP|p_ca1sgyXp;K4HEq+QF>%F@4kB z6*u=N=ad!8-n6ORdG|rJd#l~S!nBp^c8AI&-smos+U?R8tueWUXA#$&1*^E!Rwda! zl3B(e@vQvXo8!XQ;sc(%d3!2}CHk+foJY>KpzCp+YqB*iU$|X*EUM0V>%yn$CqC!y z_^B{^ZNG|f^fKS&?;g!jSe^2EqR#G`mKFDp?ljAquwzk+6Vs<}^D`zbSgxV9N9m_D z=CV@3SIn%xOnxODn8Y&coBd|KLqVd38;@*j4Gv&RT4wQ|LBPN-l&RdgfW^$-E8e$F zvOh_7c3PIZ*53A(lA>sS8^Gng74~*=n2dPqCx@-2+jX% zd|aW-_BQhtuZPQ1W0zVvI(_fhT-$o9b&{o95}Ve_hiQsU4oXaH0)q2i$t_R(yIrSf zS%31}Ra%SMm?oP1w!QUu&NEYnC7K0|!V+!{3;}{tryk0kP5z~m{3qJ%YtY9p$f5Zf``(=D_weNGyD;N6n_E#3!xWzst^%D?Oo|q- zzQg7*`V;;$#NJRl`ncXRcE^8)D>vWBN?v&@d$#23&yk&m zueoNP3Q&sJsKzt>@$t&-jw>^+oY1R0Wz{Vtc%6~M3&t4}R+=rjz4As&m*b7DTN6PWFTg8$53&cPN%mbcvvB-1+huglr zaaE#Azj9lcueG|yHuuW1B$a6Pr$-82nmtqA*2t0Pr=&9@ERey?Se$30$vKJbLLuRe z9eqbn*V?|CGS_wK>WzuFrGg4$GNKEGLMvx|dUfnmE#HPmt7f_>O5?(GqaLWM1SSXeX^%r(1o!09tN>pj zF6n#AJeBnb$2#LpCnkz7W!8Al<+H$L?lY~;3=@M2|K5GVVBOuh%rG62JYOU# zKj~`vjtlXxi(_0L&ir^_s$9pX&MDj;cRwuKrqYmmGRr68qkZ-jJ(J(8t!d|VEtYI} zzNKZO+Lk%BzEX?IcGxVkI{4wW%gR$40u}{3!oFSw&*|tK3R02?lj=%kS~i(2bHV~4 zrU|{5H61J&Sh6``J~R$a`kjB{c(mP#8SixZ1UolnOfL7>rFkl}uPI@M)}5!CjSc~v zc5hjD4WvAhMCvqRjbHKoUioF&Y0qo=W;15py?5d26WcnL-H{u;-l^hEn0QxXSe0Xgq>z4LS0X`&+faqBwSVd?c#G2nxqz= zm13Htxj<-H+6kbARv-sWtG>1IHOt+6*~Z7*|YbP}V$U#R%H26ffQJ zt~36{Wv5*)w=X+47e4Rdb&_4VZtPTa0K`QeFo zOvg=xGF^4#7T-Fy>#pAOLlY(~oP6;{&yV%RX@ZHzd%Q0F?Oa;AoP*Q0CzMw-U}wzq zH^JL$j1vm3OPg<5dsm**c&VIG*_rvZVXO2NW0e;gb#<;tV4mWkppf^W!y{qdee0UT z)((dPZuZX1duyYzZgSPn$A@aC%C2bW*zVK&Oid|shO0B@u{4vV2|Y;#YhS;;6q9=n zRL+2R8uY*aJJCw@_v^p^YPt@8d;QGb`eV(-`#1kH+~Sw-fBv6A^W%SpBfs|_DX;NA zRFnSWe#?)2a_7(A<2(D?__yXqpFislf7pAE@yGs_=kr^B^u7PxC%n1uyn6qSIDh%e zpoS87DL?X7gnzcSy5NQUo3Fh;7cwDTC|_p|Xm=7gudo!X{p0-jg65v2uO2c7I!+m~3mdv!xqfZ@0Rmu4QM|@cQ&KlXc!jMGlj$ws<<+ zp7_*O^Two^Z^QQKIqW$zC2ZoF)@7wqkG=ZMR3t7ubDQzVwQ+my=xCUSM~96Y&m3*v@Y(^@xvP~&FRxzk!y8Lbk(!hgABHG=pboxBE*oyl;%ru6kX+cD+LP zbeqVD{~5e(_pv9~t~9?D<0yLf%{jdjKg2F?&Hpp~-<(}1^(J2tp25@?Vd1fALYqPD zA<2|yvM-Olm{(g=tGD4$@X{Oj*sWR<`2@3{V6+U4)+_`Us1wy|@1!%}17 z=N@cx+i)r4R>-YwLW{ONbkB?CZEls6PQ7T7IF+Y&KziZ{cbT%fZu9p4tyNr|H zztMbq)brey_ikCvT6>qoZ_d4Lu)zMJ=+%<{3_p6N|9bYWZ2H%_o8Rs}dNV(1#xX_5 zck8!AC!FS-E^KpwXJ4P}$KC0j&l=bNrz8O!u?N7wnh3GRcg3Y2z(E>uKokz1_Ln z!b5}mVte&|JP`jP*rCwxj}D%MH!oU3`n#Zu^gk@JzJIUK9|CW>b) z-_UQnXx^cYc{kx}g^6w;Q^lh!;K>{s>gkLXsgU zmce^rzPLKMD?ydUy=S+e*Y^!RUQ99Q>@bV+jR!hj1Q_a}u>oFBS z?o>GRL5AfMd;T*79l7`Lbn`U6JH`c(jbS+(FIuo3S(GHf;$gJX#bptrBIBI0cSpV* zC|c)ZoE^rjvY;{g(ceQ;0!0W~JB@?mn+bZ?;sY$-Er#2KhL>5-}aliUovhZD2Nce13pPgIR?)n@$ zJGACJJMK}W;iNJ1)S`4vKj#St zl4RN#gl4p9bovA{G)y_5#KgqJtno_jO0{9))*sb#y!m~4&3adcU7WZLm zS%5}oU(ysu)^GS&ly}@VRy*F6u&>S19A7N5gSFN4B`p?l#@4^BY1Ow7E z7bU5z=u)sfXwZ0IfwAC8(WzP-t2Q>ctXQ&W8N-gLMx95Pdm2(@-sFkwb^H?lN-tGy z>5i7Qll^9ge2LClP^Xip=i?s#%z(Zg~>)l0cEnGLd+ zTq#xd&+~09+Rk-!`N0$KS4bY6D0y6>@W=UnmafxhXBzzCc3U(*f=iI;)!YYjMMXUw zgfu3enbj))PV+>f;wc-41FF(t)eFQyOUh1E-mo|nvG}n~+1r~3xYGT?i;`L!!b4t3 zES%Edqad<@uoHXfj>b=`VoEyVuGyP{UVD55K{n@4T zuad2ok>`S_hd?L8REtoS(6^!fCqpel{ZAHwA|7RXE_jn|ZGG37B5>^o+RWa+uijF- zH9s~VWoH9q&nsl-`MwoaclQ*xffmkzTNR+Gpj}{NL0gV@))g%QZ76*G{#s4`DbNno zdbxSi!25F}AsZn<9lGBjt3Y;wH$pD#nF(qbqU>W|d1(7b{(gsL;0^Gv?Z7)@ryknA zX6x?HbHN+n_m+S8!Z__CsM`mwwm~~+!Nx-J6nKjxXtn~pJsvcFu{ChPHAhe%5vdNP8CXs$68k#Lys*R|*pwG7}3m8}%m=!p#eP4S%>bL)L+xGYiUu=`+9ZuSH{dmgE>dmHB zz9AAq>Sxz>im`AQz3xl-RJAMml5ADMM#259qTPxqT3csUrC#>1?y)S}wt0y$pUKvi zI}t7y>|QUp>~E28^*UcUw`|XihUVCF;uC8cZyrp(#(JZGvuod_N3IqO=f7Db%-@x; zgQ;K4r|tedt=#viZozW54{cLU`4BY4;14^$&(rC@UMqy>xj2Q2>+Sn=FkntsfdNIxXU@s)ms>kL zXj0HpN!on)fK&air5=k`c?JJx@ZH#NaQR`*}%Ucgke`U+w$yey&gm5;!KsaLj7wuenFMf}5n( z4zy4B&a+PKVNk=eGFsRzd=FA}arqv4{-ThQqhOFyoPevSXK3AtjybDV{p)Po0Xo;!rKa@{=CbILb`z*8HJAQw>r+i+1zNB(%KD1H*)dk>U98^1iD+T!O_>j$y zK^rG&u|FQtsRr$j55~7Yp1EKxbbmbP$QRK5ct~aQaRc8E=wTVq^Hv}Om7?(34N!9s z)aZxQmWU=Icwh*nwkdx-qj<*$aNPyo+9}-%-Tnz`G}dmNR>BBA+GCSk;|@jeQ6zth zA;*M3*JyzHv7k{;(0mHyUhXx(&a<1?kzpu-+R18sC55?D;6;| zTjv!VtG-sS_Vxal!*h?ffDT@`U^=aYQ3lkeg*hZP9el6`XeYd) z4^=NSI9BtYp<;9D6);z z&GMc2F0P#^$y%9S%Z>a5nWZZ_d|c{}M}Ptl`6LU&dp|GP&G_n&usq<4Z*pPOd985k z+F-Gg4yR9DdjwN-Row|1Fk^b&2bF~inXEE98KCZYR7#hIp8@@#_ zG?b-6BsBE#)R?JUr!%9cnlQKpc67c$q5_-u{-@wg4_innFpt-evi=$7v*wOjht&a*T zUUS^c>bfgq(ZU9wnLf6USFi{Ob2Rj_1+KZybq~_2JO7_y(b>Je_hh%o&a?cd{qU4@ z#)i#)U0X^P`EF!!U~^!1Jh44wfw1tz;#ns%t>++`ANvjjD>wIf_ zWR+{F9+Bt#QPu3hwnhGKS*KEcPWo0i8HygC*(ACX?EFY=eu1OB>s-FWcjo!^GZTPwa^dXsqnj%BFgiD`absVfZ{6i$2U zZ1@tI6}hPW@SKhgkNpDNlj^hXyfS&v^7eq=M?dq~sV62*{2(sjcB1iWc=Q`3aqHRs zbzj&;?I#xJEMiblP+(#b5|CU}0X!DT{W&NGsFKbU0Yblv=!kN7+|MlxFG4>)JzoR$rHtu_HOh9|uk08De zIi5xxEmw11hRvD`$K)7K-ztr5a5)_uE0n^MKgF0A7_ zHOp}J0%fKji@8&dl+O*D74iM*;c%Nf5^tw03d+^Ex;w4&irSo&s{ICMIqM>`B_$_h zbiR8NVj7|>_+>`c%0}{B^7= z7Hr^{6KSvLzNf5PLrq{-$IOrheu;YzqpyQc4yww#UE6+h-bJ%)p_{gA4+|VE$nh0c zTcy>&wD#(|87pm4cCg>c__<+*-`!J6p~5DI(iHogGm>A~zg(aFoBimShXrQF8zs6o zFKx`#QZW#zK9K6!{%A!5htZMAKFj_oBr84XFIiD~Lwu#I!Nk=&%C4N< zs~ulhSrESS`m5eh;fHS*iVdXdclMu4$#a4pM!#CP_WF#c;6ev< z-VyjTo7gzybGShLDsaC7G{^xx`U_mw!JV-VTu*^|Y2d?AK<0xM3xW^!fsBfPchrN| z1Y!OX_xnmtxO3Z~S?z!oNQSnWTNWhccOBmtf`tYwZ&cMt>*%!AJv z1BDv+lpK()kg6GcjuGk@49IQ2*g%Id%>h+xpkFd@HvaQd2ZnRtrH|mcfu&&W*XZJhwx1=ImgdJ6K876D1fE<4SLu*q9Ha_za1kin zKvg;TpegXCG;pYaigD1%OyEEUpLzy6`3rLH8>G`3cn!2LuqFK{FXbBsrbpHPg zyOX2aZ8mYXM9TWCXso|H_uHgP7GCSNT`tS|x$%yOVwuUR%${8~`agI3hH%;~G!YVY zatT=#)_VQ{7Tv_!u2`d*X2mGZl9XEECUo!D@`;oo=3 z$Gg5Qc^TQ)_Md@!HD{r%#|`JiOB~ncn%-P|Hv6vQv&T1IUyclw-y~h6Y__1LoMUoB zSI0x8Q}cFgx;-n|Phin(@qpe%e~$Wg_KN?~kXp3-W_auGMQPy1)_;cRC`X7z(B?fnqh zynB|%9m}?cPTx9BWP5;8)Rm~i6XR2(?W~Iy`n75foF|<5Og`h}cIg5S56{40 zC6`M6qqQpy=N5MISnzH7?B=`c^4duP7B{;Va&{_dOw!WQN?*8s`Mvw!(znl@Zl~PV zkoeoXdD%tXl{Y_kbbk2m$F)N3>B2K=;u6W1x5u0neb2SBkyV@_lwn!$q_U42dUt!g zY2U&-F>z_4_X$ z-#qW)hS;UIYIhwiP`_bzBsp3y#&GhQP*zFJ-u*J3&DZ=2ww-Ru-kH>#a<6=&(9++= zT~A$Erv`{>RmYj^UVLwQne)B5OSR6otd}|XtM8g=T*I%KTY4{XA6s@MD}2_svrZdz zZf`D*+n$;fwcp{*k7q7>K$`HqclU#64iMK&^AoQDxxL4^+TG%5+fq7CwLNb{0cWj|y@0;#<%Z3aFz2 zEgA1Yif>5YrhP#k_`EvMKGz`d`~dU>yQ{jVTfX~%4@QKo3U6L%%vWcdy}zdxlxGxQ zNH>9tXgS*w<2LZfIk;p4RTkhv9aIbwtUf3mwR#Qe7BRs#FjMO&y06nh1wqyK)%|j% z0z9xbxB)oyA*YXeC&e#1owrT*adV^emRon{lUBtky zXlV;u0%$Cpi8(-EL&F^ww!>a$in?mIRz!zJUfq#$yDao`_ML)2k=dLR=k&N~>^tS4 zr>UgBX;u0y>(g@1{EHN|`At4?{Z?9?rq;3gmsY>zOB3kQ4Hgz11ye>oCc)+BugJ4S z_GeX__RYAQ-+U6wxt{wHi@^4EY@5w#PY&qp%LGuikV|L>0bB-CDIc7LZ zMM=qsv!kP<CHPf|)!EdKbXAWjbzv;DykdyXN2)l)Xv&$?@>JVKZ6T51;Xq z;+&r0R`~RRLr13|OK649rSC~|8*=yO&3GC4!1p-+&1-!@YPMVTISLZn7Adg>nmu4N zzcF*t`?|Z6-1IA*Mb3%lwO0nc%ieT<*}Rk1>RC4mY-c2QCU;CVjLzJ6MCi!I*69i? z*BrxD18po86}+D+#^TT-8FGy8OWD7(ImgbwDdRexUKY=h-1uNdQGMn-+4e;t(My#y(T zXB(;Lt~;Q%XU*GfA>z`U$JRETs59>4^=c2wW8uJ{rfjXtn2^y$wm)dY-G46uvVv-YabS&k%7x^tSDdf2Wdei*LHI+Q)q> zPi6BQTeY4TwOzB7Za!j~_^~D;$nZZyW(Sj3*9>pg-Rnf{3m>hVx-wW?>iyg3*Wb6j z-RpTzvccl;ZtDZre|P?!J5%Y{anZcOiC(WWWLK?jTERNgHZplLJm-8P^FAm>uId5*w z#+5(3W(K}l^yS^e{|vKqeiojIOI$nefr~IuSw7bD;JQ`)RA%*wO``d3T*MZI%0{2Zg9!6h_y8H9oCZ0vhx$Z&NW55e> zo|JXagL*;7t%95Mpf)Ld`3SU04=ywi$Nz##_@jR48X=8M&^iH70~EZN0AwZ73J*|| z9-;~~UGl&kG-!Fo@=gV4Wi7b208c3X{Bs6eWUpV4t@DD(65RT({B^qkr7DU21)5%0 z1kcNW%6-K728Eze2E>Vn;MOm=`v5s{SK(EIMD9;{{f|FErzn66d70PsiYtCFRJ{sn zGro7Y6>@+t@e!z81D#V%8sGMA3gI}P7IwPScG=QB5>LtBK8DI&4O{ak7 zWg*9uf_#a7Dsa+tu6yuCJLs5FaEAqQP;|=l%l?-a?cI@7(Wl+BH=gIl+Ic0-Ij(67 zh?$-R<2Q(%bD1UoTtGHNw$u~2EXU@XXou|>gsap6VLYAW3ghl ze_oSsfa50BcZ=?dT=3W|_-;uj*R0eTS5kr+e6ozz)Gq#`*;O>S?)of)YcXyu|(d;cA zD`p;2NVc?M6|^X4xn#1l`uf+kvy1oiI<5}5`&L?X;=YZUFIK1Bi9Tx1jYllS zyZXRkf6qxt7nOBPUcXzh?dB{$&f>(dqn5=>-I{r)uoSs0pVce7L`m$nQ|TqP<2z0` z2zpv~w75?V@p*fhq0@!oP@sSSv-mDGjlRTtn%xFF%DWQg9&no2yW>B@rT8T4_^o{3 z4(EKU7r*tV^wa#p!@Ub{?OjsU(CC)ApxY=Z!!+ljz&{P6yh%P6{QsIvP)cCs{7oR)rBZ2f z6Q8upk4?*%(&jX2+%l6^_j_|YN9WzvXto*l+POY6V|6za3I@uE#hSCmxP-c>u`uGTvIj5TTuuyGnEZF*@vDYh*$onZ-@Wx=FzIRgRrYJ|oBOZa1&?pAoqE`8 zI^*%O$|i}`YpgS+A7=jh%olt9E#GUtc%Gw%3^8kEWOw;$-B{N z?XTxAD=9Yr+xc#Lw#k(PM^=76z2{DO_;%HA$=kjxY~Qfgbb|W*%9AO50Lzp>?x~MoJgqoe{x`LjBWHT* z-uX$gE6akOi+S_j{2DEt@vU5>Y?=BugX`JLuI!jBe(FENnGUm(T`aMzM;%$F{ywna z@8V+%VxY&v_b1F<@+RBv!f*TAzOD6l*>*>6wm8RBJY()d&S*D$w#`D6!q@k!fbIX{o%puZ?~_p zwZF6V+=857v)t7#yVjfOu9b0LtNOb9V_XEIQP3i5+ZSb~WoxHw?>s5TzR2w7qz=J^ zb(^wEf4$wBb81HJq2_GKCl+tivw6?7CG@R!{Iiz3XWya4NgcM29&)K`bvVNg4d-|m z{iFT(g5U~J5ez==8nQvdyLacY#;?E?7$(klWt44{2E z=+V5O6NeyGBFMquL%l(*jJ@Tr=l6o=Zy@t9piU;ZYD272LOEF+dK6MuIB2nzow*#i zO9nbW9^B^xpLn0(4%?3mo|6N0=0F2jkYO&A8WTL51&UAj(c+LA&~V=TZFTh*3Ow)s za+9{J-{js<$*$1r_iwrSyT^AYMeQ)V9{!)<+=K81!N+TvZCAXpQ@bv8WADVHH&%qs zd{k}RXrHx`hfVWBX`5-JF=K-Z`;R&5ic;q`uGxR(ciQ~X$TvF_BGc4a?ZS>WF z;oXAoBCdU!ZH=q#f3_6N32<=O#F(qh!FhuDZ2Ce?p3A?^UA(#3u<2z)Dbwmr?jNS) z#9!G~vF5Ofo^^bgzu@fLxeg@69fzJg8O}~Lp9|eui#)HnSFT6C*>CeiHAc48-Mc>|J~4$O03C?K!ul^()llUL>*!%=ynSq2ttK9yZu8anGt>oJY8d5D2^`U0oznCveru=94C8Jk-c}~Ue zU(GHv>htDqHSn=sx$$lKmbA`kK@+8O+l)G$!WbD8g0@abl{=_>GXL5(fobP!gTFm* zU!45ooLf+^W`st$qegp6vp!eE}y`XiHle zdVV@Mx==KN%L{nU1-Gif*BLzhd2SPE_~WWGXt^w?4OsQN1T^t03W?fJ9H2oAaMK>% zYXF-C8s$Ea2O4aW?_>kFnse)C`G7AA0T(Xd0pHzUK@D_JyBs=p4RRQ0yaF^c4K9`- zgYKZFr6Z{50q>Im-6jEHtHGmq;g z-7X`RTg$p!85FriYm0LxyiLEHc9$zvW9QBJFL%e>aZ$g^Bl?i_W%qxEf`@tX6WISf zoU1Nz@K;K1lh?z)%in0N>c8*!PH=0^B*A}AViwdW3t2kk-m%WnVGH@s5TfZQann9y zx7xJ3Z}@J#2|E5e^KIPeL-mR^F z&!%b~k+G|Tk6A-^ZS2?Hw1#jVTVF?}BY&S`gC<2S7mtF(ZQ`h#K?w8AaQkt^x!^~3XR58o9CE;)F4 znqRO1hotGPH6>w+4OxL&oii3O88hg#Z9E1Vz5`7zFJ78o?F0_WJ#xZ619;e>ojL*-#r; zCiBx_W=vUg(}PKOYL^E5wwUp5;m4rfH^MuPSy_ZZu2!&)f4O&>dBKgg&39Z>hNpnZ6%yebDtfzexP>5+UlnGDeqZ* ze$0*&zOT0U8ZVb*ADW{oqyFl&MAh`~Z`BUx#F;$*&#>Kb^4xj){~3-S2sn4Z`mvjR zYwZN*uc8|d7kdAFd#SfeTWNmkMETUqIV|13crqqU6#uH?e_oY8HZt7gN8WPzhwm5e z@cz%>cxYp4p#9DrxBfGv#9X^g%qp1@>50mq8(F}mAgCmQlz5N;K|DSud`2p7V(3N2a;Pw>{jwLEx!GaKR5L2SGsuEha&YG3f9Jq`3<5C}=Vh zqza>W#j<@7JfQvqI!J@85fn?PV+*d@tE*lVJ@pgeGth>eZV72K-v-?Q1oC6~>*>AC zpwbof!mMQT)4%G=9NXXcr{wN-DCrcr6?ciN#^GE~!22yXkA#bCIAg0E!|~vSv|!xb zuVNlswNwO8zq?fJe6#P=Hf{OaXV=%cNywew7BZ(HOp1i zDZabUUA*-7l&is%?&jRt$3t9JO<}Qq>g!y4fZ1n30kiiWR)J@BzAEQ~?6&2U&OLW8 z!g%}Fyid~(MRT<(sqJ>OIyfy`dryb&hBbkgw@0#^kYVFL_Pf_+QPPuJoVqXP8mHyv zlwDc<^~a{DoXHJEDa&Rm)xNU`em7MyzEm*K*OEo?si;ZuR*Rb-|J2JK5AhKUmO5r= z6Y0`r%+lYnH}>UZ#tA;cqAd#*xENTPERtLE;~_Jypnd^(Y1(3wx`}q(Ws_gI3(GFL zB^v+cc&bJ8M0bJX0!k@IHa_=c^jRjjdH+t|kh+HsPuOS7TA_1wBA@Lgiy{@5D#QD` z8W(>l_ME*vZ`#MLZ=>ToPTPft+^M|8c5y}M)Qj%>e13Dr zBq}TpmPxZm8t3NS)VT7>Bw z=cRyShOJ^5J0ezz+SUI0`O1IwyiLD)`IrB-UB5rse}3Ypzs}1`*H=8bE1cr@=Y6i4 zoJW!Bk6D`iDl6H&*B#C{Ar~)l+p_3($Ys-ibAl~%3*IZboV(b+^ z8TUPPI~vV0+3=8``>V{hPszeZKD-gNaVc?eEO8`P}($`pzv?WT5ubb+xj$bFe3m_&IDb*3JAy`7YDs=H;Z93fJsvPTv<3Fjb|hs>M8O z>kMO+qcd%|j$UEfyt!uK(S&=6ZHh;8R7?&}cKtHJB6{Uq-}L;{RaGm_Z48wQ^0YJ( zW&OEs8{2KIo_>wP3VjwCYAFv_H42$6TCmw7>??Q<5>y_7mtBIIe)lh5V2eHms#$FF z{(vs%+PLO0==vK-R}ar90i*>BUP1_}HtvJ2xeJ01o5PoRf_vg%+dxGpckvJ=_b_e zAn$`041zO!%`@7}M@7#qqc$XdC*fPb_*yga;L#1R3=jI7~WfkirlK(wj z^s?uaQWBR|xyy@Hi;7H&7r*+?ut3)P%iU|0cjGV1ZsQI6oIQJIwsfzB{nM-Y>NhNt z{;KXi+sLB6`1FL=rSCjLJM*KQF0Jn8d9l{VZeH$|-P5*R+nZu|ttNsu?CiQp&PRTn z*`(95;*nR^i`fY(AKE`E@9WxkXst!m%Qx9yHs7=n7m!Kbc6XWVW)|^)$T!Q*tohA( z;Er0Ti(s_G(UxArN1|MV7n{B*pZ@!&N%qj5UXU~`{ zW6X6pdfC;*`}or` zYvZ;Z6DNyHXd4Qz?pt-Iepc2l-+eNv44Zu)DJkTn@c&xz_2dpi)|278cU|Abeyh$Z zmOUW%pOj|5$pN<|Yf5gpy32~q-@P$&Y3`Oex!sx30T->}WAYZbuKCQhT=TBlt%J^Y zrG-o_{kz0vxF)!!bnlqDL{;@<{u=wWXZwF89&%3z># z`pfPXE^RwgeQ(h%$K18c%W9|o=w!*_w+;5-`?R%0XOHrY(;h-PoYR&@TD)$QU2(Cx z^8Q+L%ho5#-F}Bx1!S{K-XJLG5U6&aP{;9UFHeeu>dZ}n9xF> z=vx_WpOG;mc5ne7Di`9L$GpwShamomB^Y`gF{f_X!IW3t3Djvot^_8u~1ugKoi z@?2?W+9quVAEx6B@541fE80<($rygBZA;nmq*7$G(BJY_)z0ce{-I| z_TE9Z2jw0VwE$gX3p&polu^K$tv|2k6X=Fra25oKg1hCQ!7;~cZy$r#nMVK3&13;b z%QfhgzOWsQpoyceA9wVHA0f|_FuO?ae&$% z&e7`)!B(OU8$eXS$4DVVm!L^_aAOU$wg9})7-A!24KD{|WiQ7s(B4eYED`kFp!NL{ z$+oXyf}r#bcA{$^kLkLPe;9uDPvP3xw#WAAI%S>|(1BvRK+Xnb46s!ZJKGkoYWaGI zr66%_dHWOF=jS9&+`+i0cxy5L&*|&8EO2L&`XmT4^MPVdC-^E9zH;zH33Q=zcZ@`u z>6NGJlo{70u6VW3wxG=jblEZJG6_(~f(C$(g534tPy3#q2l{x71s>}geB!rAR>B-4 z?T(Sij%okEVD&^mxtZtKt~pzeB!VnOxxZR4>6ujDD&gxKf(KjF*WUZQuHcy4!{}F# z<`!rm6}(zl%);PYjEjx-+n*AG2ivxusApha=g5-+9*PECHZ9$n55Dhr>%q3UEuw7gzbeg2O_9*^;KL4K~^b#9F{abcA^zkTKy_)y= zKZ5|s7uUi40?;+ew?WrmM?5%eSt#&f{q`pbu4hcI1z*|jED0XO2Hj%}>TH1S#s&pi z?8Be@m7g2#NTetqzJDubVNWmUNFC4>yr66cPKP=LiJaF%zR&;BC@#3dKY04|8HXi> zp&RW$*(tW@&+|x@C@g6Meu*_GKY=F`HXdwqva$WU^b|M=^*>-gQvAPoCO|{#S9GG!XV7ZFl&wk z0|NtliKnkC`!!BRQ7IOIP5k#67#L(rTq8=H^K)}k^GX<;i&7IyQd1PlGfOfQLNZbn z+&z5*-lwSMF)%1Fc)B=-RNQ*IH*>Pg@tMzGK73f1=JsT6Y4}1ebB+cE&aUY$6Rq4X zZP^t)>)yS)@1~Zmxtg~7ec7|wJ#SabZr=EI?#7$<=3UE(dKH#kGC@i89*ZNxkx&QG zRSmm7+bJ8p`%pX4WhF<5t4o-hTxf~8)LDr&J@G$2|G0nt_}!ITx0*6AFfb(lxv~Fn zt%m@Mqrh&Z2kZQuYb4&?=4evjlV=k07G!bc5o4@oc^7N;t3koFOW{{%!;u=7dn|?# zEGo~eWj?8yo;c|0kYv}SV0t1!aKe-*DC5U$1&*W*93DEZ0${b%lsK9sbl@g-F6C%a zVC!x;62#&t(Cq54>4Y~}-Jd4?ixZSw1(@9(lI((-1&$;LPMFbuMd8SsW{54aEeDkp zG=o?ivnCu=Qut`@2v!o&MU-vvA5^896gnD}6%@MnEb$OL;s7xn?80ZtrW}U969k_) zNi-?QwlFH6Xf*&?!>FuK$Og8iBce-zPrk{uENY$q60MmLwsM(%X zeEKzb^6Te)Yy48Z1n(`-@M-+J{9Co|>~)%l9=W|bb?C{Zw4&&)g-@6S>xGXbI&C;% zXS(y>tDm=(KU#4pZ)H8Bq%IvERFrKMT>bmmo2$PUpA{1i(*p&HjGBwuHH+#LQyo^j zX&Ep4QeWTSwWT7@?7X30{^4sK`#B#qC>;};`Y}cHi_y~LS4S5|D|4!@iTR-)C{Qna zgwe@kks7Dfi^5rFOw=xY-B4tBf;;hqlD^{?ri<+&-7h|N$c5>hXf;^EW*O3v=ADsM zQ@=z4E@FBjO?6+S-0Nmey*k+4txNFUi@6-vyElHFBs0xdKr@KNkf(!V{alG?TjQ?Q&zY5cq-{?u4W0XXE{FN)OIMFxj8T;eV`rQQPCy$@*ctBoHuduS zw4|+X|4a94eC(JsNs6ICn!kTW*#)*{rW?_X5)DqFTIR~P{bQyt(%@lexKJ9q>Tipy zpNoOY!6y>4UHRBTVxL~)+PJ!VvAJ9dZ+Bk%<&u02mo5>m zij{UAykK@r#5Gae`R=2vRW8THOT0}ZMR3J z4wY*|Z}8pGIO%vVE#ixp-L^^nZ?UwO{2S2MSt_dA5X&P6c-$91eRak-yEV8@FOss!p0py+j+>_`bK%2}tV&D2arX&Gl$vcW$w^UE7FU|X#SqZz zv2bGK8QFNfGb?v7FidFu6+F58od5l<&R&Jj?Z@51_0FB!U;ce&!_I^WZxyAv7{qQK z+}xIN{X2KO&EEu-dp+*aBCVlwb+0UvR;}DRA>b?H8|_y)olR42Ik!1nm~&Rg*8F>* zQPjPE@tZD8XmwKxIxL}+Bimnas{6RTmFdQY1+q1A|1VvP4xe`Jg_^jExXG7^yuQ{4 zH@7W#{CAs=&(F!?d9EzUyMLPMZi$?hzdpr&)_lDyN9=wxO_b=<-?T?~;;D}ptF1+M z%niEu>EuRMmbcIQYh{G3?@6j~pNd%YL&08BMSP#){2!lx7wzSJy5qv{+`xw)S$X<4 zrn_q|?p$`@*8e{bPfk1d<+6B(i8A{-w#F&iMO)WwnJK_+xX{P>cF~O}?a(lzoxeg( zi!>>3DylP?c6;>(zvb8a`gEFWRl5!;Z~Ro0r*tCy$M%*Byze48?*6Uad>~T1KUZhX z@^yFR-=_a`aj9nKp4gXXTmGc?;}2(+wX)4>Z+4W#dgq0t=dFuhwPI#NN6HqZ4Quyu zsX9k5=$_JZjj66J|Mt@zj{3fh0_>8)@1`p4Da|vxE|z%Trn|$SP0W$eT}*59%iEh* z-Y#6o!f-(+@X`F3i+TL3=cFvT@$b3$_J1LUPZT;dt}j>-m-|1{eLm}{mG{ka{x{~! zyCj^=`zCC3Lef{GR_>^RQcs?MNvcPU;<@|}KFkaYW(N7nug{j0-W;oxk>RiYZ2sJT zxiNnZYi)Cxz3*s-(#B7(R>uD;`_~`c_Fy)*%k2f}oeP`&GI!PKCR$I?>DZl|q%D`( zI<@s5kD1f|jJ}iQ=Th!Z*l|eSO(e(kP}t)dzMyN(pEgfB{Dyy`i23}vb;b2uIm^@2 z>~bhET0NVYFLdtCjW(B_3$?bzNSLH@ zd}%wQ=YCO&JDY*waHr)gjTvyH-xXRPji{QX*RtzKY8hqUVS<=&D17W4csWLbOp!{!JTo`$z>QqSIm zy*|3A>|V)}#w!XlPZW8@+&q1mv+#4pufI;kY1fZkke=AP&QDc*h2E2oH>;Q2>DUvR zf7E8jzRQ!Umv#vqpW)>hs{hoYan%o(C5qj4i+8wn^C#_{nRBx`jE#9iT$gD`UfL2V z(KB+?U0jP6-;;Eg}b)PRVxu(>Yx45`66Wa~?+KsUr20m!D>M z9P`?H+v#ui;>s6UrQTWkIx*VJ-EnhMQuy_K$-8sZKN}v~_@;DXZrOeDo&v9^Q~FQ* zDhs}wo9^0R`Tg|k_`j>K|66^%Mvb9MkInGqn-^k>_8x1wv9#!Fg~01xwbvY#druWU zIR1T^nE9p2FK>A)n%R-{cEi>h(@k-c!nq4Wr4Q^=G6}hLyYATKX!R%m)lc62qLp$c zE$q*dL_f1L%C+ZMU3Z?`JNw|<60P6s(p<&6&u6Dy@SG)>nQK%xpGlGDh6Y#vQ8UG- zR@MHxyJWYuNCeC4#{K#GXL`y)&5x_fX9wq<*!Qz_N_AS+)oPJ+tBkEP_>ycRuk6_$ zZ#?s8@0TpaeZ}QMH{P2q-QXo6v(G?K#!=dR>HkM-51e22W@cz-?CW}7C8JO|)>)>O z*1xWW{84L46L8rrDH6fjG9@X=^wib8CKnP5JonApx2eQ0{b8FGPsF_*wa|IJb9-IGMS=eS;@>#*TRFP-e&DP1E>N^&Ey{GHh z`spBNq3(_lp+nblUPUdme7iTPG2?T_v$g{(6!ioZGL|k{x?!4z!7`J{|Gyo*pPKrA z=Itcqi$)Rgo6{eMzCRFn+pYZiF(#`MUr$fYynJ}a^i+?qCmCKdd;U~ueJXazJlNg( z@JOlkwffJgO8i!mvv($c3UWFlIxASNV@H5gx9y9Jpeu!$JR1G7ZX&IZCw5K$W;Joq zBKJ6}pPovO_Ah2)-mt|~atZ&WX*G|YWvz4_Ewx~rfR(>-$CQ`8I z%&C?Sr*;0@EwSn@&6pMJTfFN0v&9QV6SZY)m!G(%p7h=8luLDAO1Mi{RQHD7zPQ~X z7N&CX-Jjz2CuLq%&enUEkksZlO+=^8!T874BC`&Ci~Xs;mL1C$lP>6Z7`^mN&y{~? zzuzyG=~~qAIB0(Exs2_L-lczUQIfjNx3$*)#kL|}>1&~S;eyw>F1A}n)^3?}v9{AG zVZlU=37b;V67_!l_dFA{JX!Io)akABLf2ljyRIM;WU*_rpYoDBft5e~-l-nHYdo*m zCF-q4$CjZ+#L~sM4XoM_iqOp^sZu{l$*M z<=#_NB$hAd{{8y)_R2QT_2Nrs^9Q}ZC!-y5bl#ga@B6>mY0q+ye|X zY0=lm?kxLN6KH)uPUTIyp2{|d!+nc|g_HW+eed3SeM8h-@MN>!s)f6E7W>+!Mc94U z+cASLHB4>IgEPqSG+Y1N1uk1_aXNm;%h0a?YSIc^w>6-9%{$A_l zEgRQ$u!%NGE|iy<`tQC)bvu)6$bUVz(8nq3zQ*{@4_zC`UTn>u@YY{1ZF0E7bKw~} zmloA*U6%TN#?*~gQ493V+}GJuSaz6cJgBP5jjWbP_K1{x_jl)u`swHjz9^S8ZbnVttow0&Umy?)sf)CBuB(v>;%G=d!lR#i zJC`2nY!mzcW(D{DzzgTLy*oL_ZAVxK*PpLn#l_5)Z4;F^a%kVe+p>GlZpn~I*lIB4 zh|#+UFWF<zXqkr2 z;n>^U6T5P%%9r}I|Ni-Pe?^gpWJ+)1`Z=F^&)5fnaTb{2DDqw$_HEGetO&MPtioC|Y@XUi5D9U26~c)lTd+{qrnprjsw(=Lk4XdP&i@&aqyV{@V zz+WKnV+HHxzNPkOT>kn$xU#0>`%IC?8&!MuGtRR(dZGN`#tRa+zjA-C^^Wt>3kVtz~N3mRjF@hnCERxB1-}k4^VmbG|3U^&FE3U-rDT<4Lt&js?BCJ3INU z>!EkuN%{IM3pJI`#?2F`=VU(Lx@*SGfc?Af{FwLfh=Ifh1px+zhRGt~=llL0`+mAq zds4RCT;IA^AI%FlHe_5byD_)Jr(|($*^9XSMKM*Y?KZv^XS3P;>!kd$MOQ1HKhOG~ zxFXE^@1x23>qXpme{B6OD#F0v`q=7g&f=qSd+j#{_W7o33$JXGxfuB*fMNHHMH&nS zZ35PMu7L*%%Q&N%87{oFXSi{bFZy?mfX8(awRq9+PZ!&xC#^D8Sn}!SZSKUBXZL1& zuv*mQm!@&;%im-3L%#%X)8;#QGe9WXYHn@!(!ZMnGS0b0&S&?_8yk_?G`dt(&v29h($=@bCpY`+(*7YvumF?R|dx^R&CJ4|h3A&G!>* zYrQp{tLptt-j9jXp9+6|0S?2}jDbM02oRr{sQTjCd^x5~4+iXIn&GM?LviVyl zka=*y<(>+iZx6mb`+U12urfBGX4cJ^_xm)Cg)H3ooT=gQrMkVxW0iV>gG@cvoZ0>P z{J#44O>Zy6&O5s4`hAw2O^*b!^QWtJU69mSb7{)E>yb{U&%W0;-DQ*NpSjLP!~5bC#g9Li?2vkFR=KQE zWAY*cUf!A71s<%n9wuAdleLdN(_m20&i#@1HlEm82E>iBslih_4{u#&2bk!fkS_*ESswtv;20m&fe#ANAU8 zBEFKzm*!5Md0qIB)e@Nt-&G8_~Gn{AQ)R=7!A8caz@EGCiFrC-RKp*l~Ap z<08dFD;XHBc8I*1*}68_yEXE3rOgIq?ddiAn*(_lUSAp}Rs3A&Gua~C1j0gzeGow;9D!bB^qybi2Tj?$-?{~sf%fbW1iQwt^3kPA8rqSE zpH-%Pf3zansjh#*#ku^U&O5f3Zn|-1$x^2&!G;IA9 z{W$RR*6!%_v3Gvi*B3q8J6rO?`3+nBS`&9qZ2ER7b5dA!?7D3{O=~DU}gECGps)c+Uly`F?tD4fU<2t!KCTeywOmjPC5! zwswDR|ING1a4}1_nRzeg#a9}MJ%VrDDr^OFeV4q-jGU+}bv}yY-@_UA&nMX#F35bd zt08&LiUb$e$>}-2E?nH zF9d`Jb4RDI%F=R)w~10NY`UVhSI%x`-}yihPS3yF?^kPUNhqZoZDCeC*8k|v@8Sm6 z17F&;%LpKovzvkad3D*0}OK?)ZOLyS$_%S&o2 z+;83f=YRU)>0_*&wJ&5{yn>$vpZs6J{XaC&`nsLtnsQ?|)7m}D`rrGvtP<4MFm_E{ zwZdm*+nUJ0<9C-TeZHIh`qBAYHD`P7oS&~}YP>ST?vNG(!_kguQ*&HB^Rx|O5?MNL z-|Ktz=I)lnjf%Ug<7ZVj1UVV)-op9ns|yEP$<2x?pFgtxzt6Z8mHZ8P^xp88>)Suy zn9}sqdZen#_SVHEc^l1ted3O3?vvi?`m08Z`(9_8|KGdqw*7XQWjAEBP27GP&zD;< z_kE!)2g41W<2>A*b1E;mM&xd~d+yq|M5QH}eqlYEt-qgmKUK-+UCp!qb~AtE8-BC% zm9(8@xGA=5bz$1R4_kYGMPBvUG2@s-6yNr{R&On16Hj$bys`4YUV*p!KYH}D#_?zA zo?hJdV&b=L|I_wP$=SkE@Zs{-qbbwdUb#n1XxI4eSpV&opC6^&5i7;jxbMiD8+y?f^f)!@ zU4FTKm{~u|$oNt2ymj|=|7R{NeYVjqZil>#u$g2=h5ynm`I9(4ZHv-g8~rG5;lf#} zVOLA$Z~flBQ}yn8;f|G6+DujQtlOeIu7(&2XUlQy-I_f6)_*gfU%&nyxxc?M#Z%c zoxf}rh_I;I{%iV#O_%{+a;ARyM@0$@3U<6 z`4EWoP^Xy zIraCld3btx-rW~>1M3+WE<2ga`9$#5ROQub#ZGmd+a!^|#eCt?&9hy50=u4SU2^kW zXYw+!<2I}EOy`HK zO{q3ciFo$;Z_l@lsj`YX?X@|gbsky|yn^clS*G%2?IeWA8 z)STZJUhmVLZxVH9>(Y~Fi*jrtCo5YW*m3WXx!1=S)1)Z>Y5sQ>^Euh)hgQ5%e6{(7 z{M>1sUAHW6KYgCG-{aHwj8j}@E=O!u%|H9^@X0IdwQfzE`m3Au>5`Wn3#Z&-_~Bg2 zwk)s6JiPC2jHTF~vKO&>KHO`?9<6Tu5%5*$cbh}=DYj!Jk=8d2)HXlbs`*lOW~}Q4 zjzz3oJ9O6exaFrSm%l#tWACNy=F!;o(No~B`+|dMhl`Y7pPjya zinq{iJE@&ky8F)_Xh@%v=y8*??(L-?^)cNx<=cPw9`z|VO-?x}SDj+Opc|~@+NDs{ z=x}%fFMDxl?YcCXmD0k`FV!EvaPYj;5sq2zkK{kBsMG#`ca_=3_c2$Z7BAC%Q_8*~ zll$s54$UBzi{0A~K0Mj>I>_?tqiMf-@)f>5wsk!vJ2}tR{O5dCz5VZFrd(OM$!e$g zq7^;(A@iyKZO3=eiil0@uySl zX`7$VW=)IKvyHue88msOFYu+m?#tqTXCAWsS@`h8uDKpu-zB47hqUY5J>@bjXL@kY zlxFK_-g3jcn^Mkp1uuxw$kVb08=b(Yoo|L;_Nb@?#0DkzI{kuuBId)4n7^^(fI z?M-|2(Oks9_|e|toBO*Bme$Ig$hJH*_mKH??enk0mR!zvzA)vdQ_vaC9Oi@zMoTwY zMP0wV?J(apHI~8-!7J78_nNm^-^F6D$;xOf9_4K>Rn#Z2IE&5&>ofTQA z-g8*0>WZ=CISIZ?&)=v&`e^tt;OW_-pFyvWWc}T_sqD&zRI!yhce(ZnMkmbTEWBHo zdDZ8ZtXtirBDbsw`xNbj9~wMAd$cDjjr-Nfn9nt*y;NF5rP$ssDDse4vhnxMJ&4T=vO&$xNo{(5)n|Fm$whkkv@cE-Pc zcmA+xQqv4#F%03TaM*m&WYhedKmOfI!<&xp*to?^bie9n*PtaFAk!bDEzVq$_k4fx z`X8$v8!?v75V|h>NDQiV!RAD(N4#~TbxppbE@iOus6zY9!wDj7K!Bb+`B{^d8C9jIFOSk9L5j z;}5q_?Md2l#mwEqwE}O@s;?u&B{6k>H|AbkaHch{P(!GLqqq%rvcX$fe3gL1(9&5q8&NyV{Q>ldb9%X)71digB3 zOC=T8mp0sADs$vMi{TcIEB|xe6gRXdp6+@&>$rT_JWVa*MAJf0Za5&g;{45mm~EMT zM}BVYi?ToJVYedg)|&aNGLxqr7632*SYVfac*D`P&vy2?L7BL)aXqxgkX%^GE?nG;gYnx^+(-V_k zdA4ZVk|Vy{6N9Q>fUMsTleoIlPE{{mxx86p!@_=@>GSnh23JHh$FjK1J*y)tz0+Fi zG-potqFue)4$m;kU3SAmH%E46{QT8gn?C<^)YshF&g1z1L%aQ(_cD5^x0l-OIOH{laAbD^7~;$QnRC&YvVg%S4J1>O)Ji% zm_2v9R(UL-)N#8-k7iI7zbeyL`8N#9u2`*_)!DK^>ap4496?7}C+TDkhO*d{-9D$g z%)d-rWp?kv=7)SthfCd*g6ym|P3W0cz3~yJrnz$XzN%-Ze$H%_)>dCW(M^Z73OnCEek?3F=f-^Iy>pdgy?mlNI_VMUJSB0dN zc>+t*mSuWq9!sCQVbPK7tUZ5&85+7*mZ?u$6!XT3VMDiK_nC?%nw(m1o)oxC?K(ey z2D`-m%EwKMKD$V;3pREv-Q^fED)B zj%|p1zdh1yZ{*o~QPy$6Dv>#zbNHIi{&L_tpTfmcbj>^Sw4;jzJNL(#94EQn?33T- zW2kq{?Q!LMzr}eQS1&!Oz;Sxn_Ej^Fp4B{^_GqHo@mY@792AZSuPk!Qn=(7l_4)0_ zWiArzOpgB_u-hxR*Oq)X6KB5dx?KHT)%sAEAJ^V)4L<0<`=V~yR*PLh62cbBs#lv$ zIwu@@8BuEzn7v}+EUmKoT{0Kr>IEjuSpR$b)u@kMlfHy`_~i5*`7HabbY-vCv-x`a ziz+|%yuHNud#U@T*7r8QPiE|4Q&gL0E5PA#=K5dfP;s&1%k6#2O(!8Hhr49{9VBb29>@q3JMArGFO{wBjA&WsZE}?EL0b8IiTjOiS2~H)PKNh3tBcQ1Q6`UoN?G zFK6D?Zc;Mex^8|+F<;9b#X>g?j>Adsp7&L8J12Y%*|IIaCC@1T?w$|V&T_xKDSN-9 zCaK%i?Bcx-$_g7pB0AWQzI@x-xVLIaa%YS=N2s`-{+wNVDo$;hxSm6K&%9344udv% z#?GZq-O8b=cOUI-oj6rH_Lfp-yzB5De4tx3eKd)YGzW3Oft06hLQmN;m`-Izv4!LA3^Y=b+p-f|EM%Eqm@BQni zU%I#BWJzjughz|v77h;`QKds)x@}=wckLmY z@_DkiY_|t=Gy5wwopV{`)nfRhqq(sCw`1qS54NwG79Bd{x=_y8X1S+k$L5c0g2yH( zD;UPl$p75E>EB`bwvPu(Lvvo*Exs^gh0u9EOD3Vutveq)-Y&d-Z>YJB-uYP_WqUf` z8srtpy);l(xER;Lab15|&htf1(_`AU#aUGP3z@tRy^1~ zJx`tT*hPZuRk z^?UvA^_h#!*UkS~QrX4v*g@e!WAq})wDg>Ki5=mOB#KSqa=Jg9+`bXCSnt={bUpP& zTrZUN*1bJ5^{C`!H|yDsN<9l*6*e(RD=k`cBv!oY$XSJ3ey6v_-WLgo;^wRfA=hl^bepZDv_&E)Sh zYR?|rayiQI=i~ByTf%$<5@mE)b_%HZ90}9CY*fK7807!v^-&4+#b@ikKDxbGIr{gs z_@I_qp8U}eqTn7(Y<{f5dvgpPAn7to9KAN-W;}P+8(Z-IYRqZc~UaI|`o$X&=^1j0Q!R#N8HYf>1Hu4HG zYEE|z)8IOD{gHj;`_`#7*N#eD>^t#t(}JbRXLHufn-Vh5Q1ER6gTXQlu4JE!7q;fC zi1yhic6Zf@)kjm7YVOc;Z87}AQL^B(S%@iz^K5tb>&6?srhh6nyn2Nt^!dKZhr!2N zJIW$cJe%}5rJVc@+>|}u=sQbY`g$_PgrZd`4UH>>Qipsw6S28MOsQ)fTAl=iFn=S%iz&&zE`HaoXE z9I3gh?DpvC`uV>T@>1@WFRfGHbehw-a^{R#Q=;rEpTDWn+*W%}q*Gb8E0E`6+;onK zm-iL^`};U~_2HEV=Ds|V^3hxUI?FYs!X?hF3bvE;>MOEpe%^Q?WufqL=HuBPGrD(F zuMn6JvFh~p*cp4-`TV?Gww^3$-tjvjp2K<0#~X(yR{Uh>oUrJ_#f@BFe|9iEdUsF> zR4DWFd(Dzv&9TPyPHlo-i{i9TwGmlI_@{AfE>xAx7A)uIXA<%*?VJ%m-!?)iMe_NR zl+GR16#_4~_qklQee~_t#n0|y#zk9~pUMp0=zUXfZAOf*C=Yky9lmI0hGY&y-n%6} zy`53N{SMi-w=&q&ntcCtb?3WqZcrU_<2`pG-+bd$U0xrbhY1 zib~IVvExFirbi;rHeZ)OhGd3}4%z987`DmY+VXOi*0a@@sx&9AclCY!F<|*yeIKt^ z|3B{CZfv-|U((xj@}#geoGucF8!T+Z5AkHNUMpN#Ep6QAytm-fwTwMVMZ2~$6<%99&i{CC zzTzjb!tWEVC``!Ek7;?Ince@_QNQS+#e$`q@68u{==|+^?dK|xFBzqxoUkx?(*UV{5u2w9&0fM6XF<7@dZ#JVxWouh$$<=(eTvUm=}Ep}qtsqVt*KX)cGrBi1o1tOK8bOdgq0g<|1u-wyI?Xf8 z%=o^GtxzT*YRmUGFG{xg*;w;%c$^W}b25)Swft|OisO4{y^!-eC3zgo?lH9+a=keq zD(A69TyN2p2^*hp2zb)d8M2grXU2WiSB7dmuDp-lC9ZH(xEQyiBgXWhwB4^yGh6MR zI2lhU_dan!ukgEpg2Kj-9UbkhJ&S(7Nw6>q64^2Dyid~k?Bo^hzb!j`!8f-EU5oEWN&SgY15dYkGMZO7Hjt89SFc)!)9o{aghwnJSu#sACyyfcU zn2_0a&X+m-&pnjma!L0VIU>m@sC#(1XqS8R&5F&-cb*7cWOq04nA#x;HWrn}w7msx zv7&n)FK4|r=iIdFtZ!$Fj{KI6IHn4c-YKw5{gd96@9xeB&T zm$rC=!n8=y$6r8tX-nEKmNhDivizgpPdoU-=TZ{aMZJ%24hTMRnlVqIt2FW=%X`Jh zkPFqbxQ{bl*sR(jGR>u#$B-?qLg8YZzQD3xFW&i;f{|BlPcQwZCw}ksSBc<_9iDe= zKS;3%z5U8DasAN^=eZgu_N=l!+xl?lY|elRlbcHKYTmi~N4Z%FB0WC_ZCyvYDH^r!4X5qm51>CYtuFuhe{73=3F( zHR)gca!%6t=A)&L`D^$TSs8*X<{WNPICpI7^m(@`9)3v+y0-BC$?mrynFTHq%&Y6<`1CVYawcm;yt>T7kb0%C2q5c=WFEx-gtXu$n*O@Qfd-)-9V*|i;k$3l5lp_ z{p;O~KT0wmU7tVaj(L;oxA}XEzDu9Cc@t8%jd}X^CHG^c|EDN!y~`t1&M(&3vDC@k zqsiZRh4dNg?R~SvZrv2*?VI5GSo?XHb?Acbm1{RuJk5JHx%Eqy-KE8S8W-=`33Nng zm9RADyk|`G6`fXm@~@)Bv7e`QUbU~xG~DsWfZ;0J_uc;L_jX$bt>F6h{CNM7yPyzW zc~9|Mob(g>aeh()7VNlr9FSL z%j2iZul;*+wDp_rXU9oT51jt2{QqnD@h;Q8A4w+!Ichde&v3~9=Ko_$%Z_GdUZp)> zw{r9E`+BG7!%>IZjr)H*II&*O-#og5Bl(A5#|-^1+kdk8U!EfUA$L;7pNpTn*UyQ5 zn_>BH`TH|_OKTUcb$E31At<4Jn0<|5HLK%2wa#PV=hyG~^~KBm^vC@_D_(_9U(Vb8 zu866vVp~3k%Ng-s&i8k`U6Jr(pKrq3_xm>dcy*aSQ=;VB@v;Z!@6G-F)ctbe+C!5S z-Rg6gI=?x&-`IBk?VQIek9}SqW_j%9>)e+!KCR#X^<}oWRe%D+gY@_3_EzRD`W;&F z=$+kZX~FcCz6-kZo7p0t{8_Dk|54=YQ->;wkJmZ%e5_dYbMN%$=jAjFR&4ILAiux# z&vkkKw>BA5emq*BAh0pyMMskFp&5&8mZzr#{+}Md>$Sxd_wwaFvxO|R1+T{0?f&(( z`}BgtTLQcO{jRtAZJ_=>UvIa}^r&ZEwrEE3jUvJf?xIVspUiSvy*2rmkb8l3< zd*WuZs$9kXcH{otc0c{!pAVZY10CDAAh`Ny%0{`lC&Ow&r%Z~j|G8DV&->$=yP3=x zH$SX>9sK|A;hDLtLh&*Ipzf$_U?!LOwBx?}Cnj1Op19f0l*_)aGWXT;_h+U`+k8Cg z=Kh?ik<`5}HtAf16>mG8gn;eMi7 z7vnTOoLwE9A3J;1Y97I34;>EZ{}A$hFK~M2mHYqSCG8aC3~ZdnTmSLl8~=ND_rerF zN+xh8R<#z$6x17kEzghDxU$HChgB^5Q2mdiJOBTCxF${E61$}jN0Firzu+|I^XpUV z3x9^}R4h~8pVs}ipzck6UFEk^dvi`ZEa5LY!NtE*VA*z#o|XR7k42{Z|H%D$Q$~rF z{q4rj+AFu```n53o#gl+ajLn}t=Fbb<}Y7+Kb}yu|Kph;t7Sn4pFH1nciN9f0-%`x!gw*KQ2x%$m1al7&)Hkp1wQ&?b|RZ?SDF3qYhPbZo%1EdLgV96 zMQ4SimH!lYy7%of*|cF|&9fWNxR+l)Hp$DyK(W=3;q5j-<_5#1TW+xLym9=yTfR=} zHfe`P-G_S}js*R6*;4Xs?(ECgr@K9K)1Evt&1_-E99QQY>nWKRr>gA_?OP|dWNlH4 zOu&EEy#j3!tL!_{x_9q0sjAJ~@_+J#BjU~-@a=<1noSBF2bB~e8&x?#+YIF{?3pOR z*JNSB;c>=2OW@JXgGvg9@{SXvQZ{gScBm<7<_#hv=|r|I2gd-|33zC=c3fa zlGGH1^30M9g^-L?1$R&1fd97{oI%~`u(GgovT<-RGckbVy#yE-SXh`@*;yEwnVFc_xEUCkm{}ME z6%AP(Kd=QR7Jg(GYTS76;zJH$rG=a#q7#*kg2bG}lO$DCjZIxl+=7!+(~3%)+O~k~ z0$Ihx#LNh_iGhKEor8^&m5Yg)1!R}2AOj-{6C)D~Gb<}I2R9=F0}~@N3o8SgAiEHU zu!y3lk|C$EV_>3~xQdaJabcr`nu%#pQqe(4b#s@HwBpu@la_A!e~W>KnUR4>kXewy zp5Ytc!|3bFryn`SQn2>*n)U^G94kxnV+$WXPI$~@5%z2Q>vM}3rx;G!5%z2C&JXi` z_HaCmzFxPJ-7niG{q;M+B9Z(KcLa|4JdC~``Qhh;RK^`)Utd1`XxKGJyXsfp zrc;ZQry%qts}`(%z54vM+f5)V->?4|*%uhxnjf2f_?hDrHmGYPPR`M;`du0I}A-G80!p%Bh>Z{OdVJmp;yCu6j014?&SJZG{9`+8mfUdRMjJ<+|j zyS#gM9_SO@TRNYACR+g5UH8}gxDPh{_L3d9=Y%|r{_*9@wvQmg&qwdC404Q{mDe0WegvD^W(0EKUDacE9)xq<+jZ5gIg%v^6gD4!Oh^a0^!sZ&^QSy1=S26d zlDb>j7a$Gt{_#hSAa`BAy}Y-f9PIl2*RD@+meg*|kFVSOxGq4sH9y|rTI2&wb?2h~E z>dfT?L4hAvx9yIAa%+CvzItN`Pz-(bE_!HtSwis8_H~=&8h0p7=ei&M_h$eD*yHc7 z+e`OzfCB?$6Ua;V*TtFf8G5(ouZo_|`ECZ-{S&_M9t8Vx?XS-(8jw>(ZP=Y3{x#q< zw?Af2j!a_DRH#J??p*iwEnc%}MaNT7c=|(074NSrK2LbeA{+RgXZgR>CsNx2zrqp} zM_~MkEIH-R3+EWl`+7&a>b2qvX;3Qr8eRO*_OrxNP|AM%xbPv!!JzcnW|Yo#Z}->J z#}0y=@-_eZTo-1Ir3jbY58ZAjeBTfppL=cgsTnA@=Es793LIv?p4hyRNpJ_nK>L|y z4N$1Per0u9tD_GTRk2{{r0HDuP;?^Y5>WnH@Ve~dIn9E#ufh2Mq%S^i(&IcxJVpP_ z&1B(v7=8Wz`raeupp*?s(8{g(tN6C(%RB^y8YE$Y;%W24&kCos3f8_}7r$qv0z83& zTz~)g@}=8BIrUoA-QTAs@jRN&b#EUyfg+p_O4{$Q)#RUIE?E2e?WLI9b6N#!|2RLs zpt%R)NpLa)WnSI9zt1DtK#q<5Ys-+jCuun-L#7}514@oyV;}a+JhXk?=Eolu&Vdpi z*jSLu)`n!5PH^ahrF(E{L{9Iwn?PZ)1|@@mBWZ8Vzcd4sY;wVLS_z}f1Caao{LS5= z2nvgJe~bCb+erxV73q}&5vb^d3|j0A&^<%@=@^6_Vw}hGkd@V1}GJQLK>XX zKuW;LIl-Ole%Rm2D-K5Bz=xzFkTOWx1?5Z>jo{J_T*xhGUi*{Rx%K$z$mjB)LIjc% zSY+c*Wb5Bw@S~v3_}*@4E(JLaTuzJZ2>Z2kXTiLepa{MWFN$B?UvJgH1}apxcplrSH=fU|KM^O zRGfv+U%Q#~pny;HB!yL))*iM{n;d z07Y>A*R4xXGs!<&TU}@x0~Px4hAAzn|Kz2LSsF+Rsbc0 z?f%jX??F|-`!n9LSlAoeQiUNnritew@twzV33l&@^ngy>~aiwC- zj^F3B)U|KjPIB9$uC=Q3kdoGV&KWC_v*`Yq!*h?fl&RlbUB$ep70S+%GH5E@;Xz^Mbnid~#x%=Dmm26~e#_Y8H+plc< z=~h;^H=FO8wUA4|DVyfD&->AL#yk{wJ-(%_O_wY%jt6!z7&(uTP*DuJ{dBJ1}u1+d{-7auiJKN&ON4AJ;r|)-@ z_@xbV{C}={n`G`WWyU`*jew^L=gdxTmUoby)ppvhgQg5YYZlw3sul1dNv%K9_h$-na zcU7>)*@GtynKY6_jsz@FVzo-2lCYfX-mVi>Y!5o8N8Nb2?QhlOtm|ppQ(ZTP9@@EL z-X)2aUB5Zrp6dF=+{9~zzT+YNeVG0jbCDxH14?P|MHW(Z4#r8?K%xFn?~8eKU# z!0@SPV1-JYsA$0CR@ab_n0wa~>fQeKC;VpIJY(I>oMn>RW_$M~>TC>uxADqTNl|F!v+*qN*J;IUw7!<-}GyYE^&JekBV{V={H&GsuhpXJp8dt=i)P~(+rvI35U-A`g+eM=j;8NhM%WH>@M-%um}wlbvVEvd#R(R zwEMn!yr6V@?6$v3+gI#w9$-+0-M+tS<{>rHZY#_o(fKjrq`lTT;3ue-6-Q$_Ugo{5tfyW-=!u6$>Pr@=4go>;a2^!r(}ejWW)&cE#6rOP+Z z*bBr9-|VSv+_-jD*&8l?t}|jHF-B!cCst{ltyIw#;o_RWRj481qP*;#=)Se!7M<+2 zUq^mTkzZ+dDe#tCMAi+rvk4Xj4{lqWym_j8{w2x$eGe}$)PE2fyIz%5$!BGQ$Y#Mg zC3g>PhtxyK^|8EuiW$dx_5T@GUQ7JNCorLA9sBOn&OiUmH{XBq{m(t?&eeVjhc>nxul{LU z{BXfl@iVQd~Edf zn2L%U76aI!@hw0i-q zSCi*Hw6>^mSn%}4T(M^pmdwmpb?`rfX8&(tnYP%+JVzLq+*%4{yAFrtE&ozq$<7eW zm83N@Nalbr)12jk6Qmr3HCncNX|{cSeE;yg#w*M(?`}JspO`LG5f*bNFr;_hc4yld zw|Tv(DaMkem)o*$TV^HR>~Uwk7N=M{eO8{w>X&Yh^Mj@fK5|cOmkM9(HeE4dw&ptP zmYb>3iXw%!w?5xVjS&?R2~bo$%qP0H6jbzrT1>TH|7jbZ(yd5VS=2eJ&F8sdb74oK zW^?J`-V{j(K1h2Z>FJi&`CD$EnX%*Y+2*wtTrGTN4;D6ds&DG#TFAA0)1pOB3Y->s zsdTkyE%MlRs;m3ZqUF!J-|RGQ&4)C7l|h{$P+t&KUxJ$v@FuYPW_zP>uKOXfdG{<2 zF1q`8f#qzIq9;pMo@wG*!^-{7X(sR8Ew8m0Sn94CPO%JD;Otx2l%(5 zYVt3?#eMtC%7?G_$@6Vp=K1|%f51a))mS&F+^vNRzq`pAtJ+Ux6=V&$7#ySLmn3o2 zKw_Cjhr}{QW`=Wzm;(f)8&2(6pbl-EKi*!uqbx~Jdga#NHg}Cy+%)DhIVf_VX_YEx z^A`?>cb%6wr=DckY{Bqb?o_(`NObYJ#ChB~S940G%U3;LUa_ch!!wQ* zo6QXCwa+T8EL)|o@H)%O*GffemF<$C9ne(lu5r*>=PiG>WPRa*vc%WN)aKtVS@ovi zOBlm~?&3#&Gn*$c&a6Ir(1CHzv67Z*{TolsKIaAd#z*!{(|JRv$q#qWr;TPG?Cu!(XpV*l}T-qrwGTa%n1t^f&><@YC5Pe zFbIbI$*j0H`{Aia?d}&|n*Qyt*w{3Ey6Q%q@2@hnWGim0Pkj*@{95(IrY&kIdv2`l zNo*Hwn_oCn*>noe>t%ZlvkUw6E?x84QJS;+W%3ex6&3FZN^LK>H%ZlQNNrINjaRvP zoTtS@bkXyL7U`GjZtTx;{aCx;U_t5?1^Hhlmy0{sbha?mU2YW;d)x3-N+NpQQ-kS` z79L2K(BA5IvTXIH@4Uw)l>800AG6BYI8CA0Bs7S<;_NkM_S((!UVJ|>=@8RO>*GE? zoO3w0OFXPy_-3-~_8V`?)8iFf8y}0FIdfctbM_-nmEuhW6I)n<15KC2{mi~&c{*su z0Tb_~_cNzQOS}rTnYYYy!OoX|=gu~G_cFWmhp1mr_?b#6YpKXLN;fUu##fy9@@;dD zQ%YG(kK5&QE!$G9&vj+1`zr2om@aj98s~{kanoMERDE`Qr{tuIwWqlMXq0cbt#xyf zlp@FK)TQFE#FtR-`FGlz-EaHN?j}b>+e8Z=*(km?qWOu(Q#Id$udO?enuIW`eix5e zE-Z1>pwWw!izj>U`#X-Ifgy`#tyobq)#rdhlE%!IE`fsuLNgXIF>8879=mQg>Fm8X z-s#8xGaUKWef&Q|uFWIU6S)D~lI!d)?cMgDA>zZG)3dIgxi#rV`P-tdW1%U_llE)P zat%A0@x^7b%)u-DYOXP+6%H5TQ#_|z&nh^usINQx$lRT?e0#36bOsv*>+ZX;L-z!y zzzuP0UXkhp^2J+2MIEMcS}3}@n0T-c=2ZE);%WBsL! z2VU{p?zD!v1%?EQ`t{ceak&|W`I{%qkQ3Zok?bSQba>Xoh-i_6YHMaL37P1zu<+fq zWtQ!q0-Zaj1RPSc>`4@CO_sI0eVIMOB0l|w8P|8w(!Y`)b5|YnlF#S38Kd)dt~{Ue z(kDuf#g54?=q`&Wv~E)lopMCPVoCpPyN;B1vJtOJMa$-=Z+RoFwtYeHo!EnGw(SgE zwP00S-uiR$G)M!sp6SAT+04 zvB4`zVv(w$4-*@sfPjF+=ZClNo!xX}-}T*&H`kadZ9iP_c5zva?Z)~WH@iPA?=;Er z|I>SWw=WaJ8Hdi6*A`z?&)}c+bH?(Wb+K( zD_!KowMbLx$lRLD)&)x{T53IFgnfk;l`rNyG$FrZz09}Oy>3B%6;GU}#OE2FPkY6< z+xyLjWfP{{F5Tp6z}v!}Ves=@5@Y1Gn=FTHRo&W5RbM zy9-P1RH(&Iw0UaseroN7D4~!Ct>ITMXuNAR{j*5aEpAiK>GXdWkM}HlrT#)wb$$JE zm6cyz&x+S8En_PC)3SsqxAEp->5l&lv3+8jX7oP_dbfa~P`1_rG)4y+gu7e6{_gVB z{=crtZ*OXZdT)*pW89nRl7+dDB645 zY~{_XXL$74ZnJi@#jDnilVWx6iy_!lI4U);Eji8nd)4*e7T8qucLJ zf8*XNR*@!si|x$A+o5d_B^n;BDR>iVtasAJAzJ6cI=?$SK{`d|1-nvM9gZ-BJiaR^ zAn?qhm~BUx++psdi2DOBvA-*r-aC6=%HlJQpUpa!O+GBR>4;U1SjdCaU<=O46C2d+ zc0|q954Jjajr-?bg>~DDOSf&gZEp2VGgo@W)@C7}mBncy(dKFnZnBx3uO&rPO&%Y4 zWpr!ej;8HOHM3%iV>_-L`cksC?`UoIa@E!ehu1NfU5I#nK#kDD#||Dd>;CHgr(5^7+@YkobKdZsw7=;ioFS~8Q!jFC?zVWb z^7h69uM^)+N-C8$cf4OBTvV*Js?GVG8WU?k>Z*2VU$OT;LxsW>tIx|y=9Q+$J&)R7 z^6t2r-%h4qPxRkwt>6+d`)l)BVY>ahyYqzRck`a?-zmCD@4Zf}SktnvR>wm(?a%!i zxQxl*FvE;D9;b!0KTSL?zIR#Zw!KG}=ExLE3l;`iJazS0RBr0)d} z#-a|zfrj8ggKcbx<~n#dA3Vwh8V9{SpY#2UquQ&hUiZsO_j5=lcb;L@bveYU!J4Kf z$-v&LV>07-bD!DiJe$uAmwg#`yj~~JoV$%_NuK1S1q}>~CJJhCbZMt>@_Ie79=V9wqf%>--kX4Q|Su;#WL-SCELBn!yDI2J_z436EtabKg9q zlCUz6hSL8TcA6Z~Vp{%pl>|%r-9H^n!ZSB{a~(Bv(D0;Rnth6I$Es86$*?S1*)WT!QW z-FH_mdlFIBGfjK`+lZ+LI`8TE2>q0wqWO8kj#WoezXh7R@3Al2QgC+RZ5?}d*4ZkF z#T_C|46_oHW~mEEa;>W0mb##mLn&c_^e$zY;>>M#jxldOcrN8+(5fE{Ud8_zp5|Lh z8ug~F_#QI-H^UZ#N8;L@EyoO7jtL413eM>0IOF1yr(`PGamK~m-Ta~Zn}>5Zn6uY^ zWS6S7jqW&dD{ijY%fq|oe(&9LXYS7Xx^b)9UMMX;a6@fv>}Sh)f3vm(s?_X$A1T$g z?#e5*EA7X3?lkApc#^hvO6aaHPg%dShX2)=u()5oM890Q(fT-BsH=#@zbu(kQt_WG zTaL+pQr@*lc?uJ}(}z4o1s<);d%J9Q;o98RJ~d z{o47@^9tXbKl8MjwRLS@?y~cneeHL-d=z^>*N4R;EJs9p>zM^79F`gi{Z4()z&IsP z<+*Xo@3#`c8`rj*olo>izR~3r6EEd4Ki7DgdurPm5nn|{&Z+L{Ogkd%AA}uQ*ij&J z>S6wduC6ApH7cA<9uq=BojDr4f<(+`IHgI7w9Y)Is_3J5?e|;u*Qx1|znb_s1-28akc7eyY@7r43zoG6@=zUtF+5B?I@rv+MlT5u$m&f$0PV%05$u{+GepsaO zk(o1#UPbJ>sI>5Shpxhr%!7}2%7p!XBC-Aq*Dn(%HI|vb1C6w1UJ6)Ha#eA1KpTV5 zoOX>VM-6yccmf3kq&RpMhyGoV=z8<+`dc<44XWP!N9QiN!=n11VYQ@V=!O%i|DL^4 zNw{xt%51sRr(d%V)o&~7uxRvF`S?bjzebH=qU+&+VD6B{=@lzC<}KW@CYU$PP_1_A z?2VVd&M&wmKPmU%oiFXn-Folsi~c@qZ;z+oj@26Ow33yDht z9IWqOdidtH{#}hz3BeXM3nZADQV!&aywzH@q$w@5G}u*%<=m>}TA35n7>#8fv1<4@ zs3|cTGW2-faO1JiPo1qZ^W>d)!Mw+k5vhvy-`%~fvMPP*e==`T;7bUQ?kR|0^`~S; zcxwCMh6miae3osAPgM@@(=f4`vFj9rkD8M_f8NZt1#Gbf^50n;Z9~^ge&l@Y+vU}c zn@X3J^R2U7dThH`o#G3PjHPY6o^GjF^`~&M9IvVMHJ@W&1&>~v?VvvMy*j(rqT0R2 z%L3A^PD~8XewZTUMEUFKn$aJ1z}L{pwJ$HQ7#iyP10h6JrkUtsp8yRzXjuh#0o#apf< zq_$nzm+B}IWE>}Y+~ZD&-#cNKy$ffo%sqB-s>*J~|5dH#%_kX8e8hM&dK8%$oYtJde#u79&VxmxLS#s4qsmA z&0}qz>hzx>wkJu||F4Sl66JfpHRl|$Ue3n9r72jLW6sG5|H=#hBwjP`PTFz#E35mB zeM-MYDi(C~*WOcj8lJ~*%rT?-wN5dARg#jTpVd7_6~rx4dw;;My~*re+uGX9f&2POVzlx9gS0rd2XGKobZ1BR}rfc+>sh_Ms{I zJilt2r%k@S^Oe|>tJ$}6Ui@cxb?ZTc5uYln)r7@;N1EQ8R8^~9!58TnQYo3(ws_NB zlUHWHp1n>wWpL`)igoI3dl&z^`LxtgW~zE?pty`%BjduSl6>wvI(nw>zJL6t*Y+z+ z%M7g_-A^>@O_B=!?Iu1$yU^x|Qsl(q<@U$w3!F+Pyk|1`{3k1M?Va4`nKLe)VtUPY z(?*@w;S%G!#XU*SiyrSX=li(9?Vxu9&#|qyPc_+$C|qxu~-ow+tbez6~Nn!3x? zr&sUPd}?uJ{;j|yvwvD^Une)N{&H*HbgvArIhINxOuO<=KW`BTdv}xdX~k!Ot93i= zzr;@MU*ukKRUqa3rb%6$Ul>Z2^~>d6?Y-Dpzq{qU-rcQ_xb5E-Zx!zoH9EEame@_1 zR}yz08n9h>#H#;ven~@6>!t||3@nT{oes#Z`Iew2z|@{GTS!f&Vd0h?DaRI=aXv9& zlsYbSY-6~^Hr0+t>-oRSCFRe3#MeLb&YoCz?pd4VPlo#09C2ew@3uT-Xk#yyQorpp zcgLhE*zRtZh0I5?>q`X;-vp)%u-UwUzOue~PcaDV@Ic{1U&z z)djaE<<8Hjw(fj1<5xwrjl{Z{Z{ApwuGXz>gE8@iO|26-(^UIw2?>S+%iT@d1@4M3a z`9H&>;Jb5HFlzd+h1U1VFIno5^q=A4Y^Rw$ObiRn9%orU72GgIU+YaW`~u5mr0&*1zVF zn5N5*LSaU;*smP%KP9wve%im3ds6YAL7T7A&w78QO!2A0yLaCne}4Dvaoc-$o{Rox z2(JIh{-5FKe}-vU*{|QfIL-bmH8`zocj8AI$A5=%;}jmVu|@1^js3^jv*c#_2~+k4 z)_)r}Z}YvYF>95;s%2%T8lSN%9NQEFUCCh<`1SACjZJ@jwKrQUZh1G+AJEq9D0-Ct4Z>;4?TZh{atx^ z-JiYT@A*$}_|bl3Pk+xJ`$s}`ydU@be~%aaQ9kii6d1<~T6($430f@WVp^Dv-=0?_peXVQ6&Y-r_~{jGcZpOz&7PXt}# zUfeZp%G6-C{HJc}qAueKjk>bTWxJQ%c&!wh{q5@ZslvD17etmQs#oy2=3k)iLE+67pwnBN^?w+Su=}ip~ErDaLp-(UI_+L&XFw*Y$ZJhCau() zm94Z;)H6ub<*Lt7t1N*7Ou-YL3Tk#G2nZN(G&G!Hv-(=G;bY{ZWxH3&x?Elo7yspX zV0&Tt+K@|EuWSsva*N;a$42$u*Bio46@M2!WIQP+T9DC`WkZm4LX+8Rrwd=)SG;`V zq~qPquIx5j$@>%Ur@Z(Ki^txAvTjiv=ZmgSdn~g)|K9gizyIoH{Oe=C#drVV-g$|- zA7fk>Z{L4)H=FNlli#j}*F-{NTwTR1y=FPM^e`o8wY}$b;80Lfyn1%QuZ6c%54wEd z;paKjkszS-J|tSG#P^tnh?E&4!MK?UG=HV@WlX<+&-E1c5_b1+X z@ZD^c6Q_*z@m7)2Z$DjKf2Ef{UcEn9T5p=s?Sw+%I)&KP*_+p0VOSaY_?iD-XZ}Ay zq5UO`l$B;4I2HTiWNp`5IsL8GjO~vr9v`+lGH2h>j@`{_UB+4#O)nQYEosVBaauOf z!)Zzj!-TM8!#>lmIxDunSu9dAb9eXFqZ` z5)9l@QhiKs{?gta$D1pv=9({?oU_{Zd-gTo&6l@yOBQl@3ofzcaXa`@NBiT9k^|Dp zsmtvGf0oS@DASu8aZ_7QN3x_h*6j2Pj#n&&Sr@0>aWG~qp60^Ka3(M`kfZ%>@nW+M zgN&=)A*Uv%+G5@5#i&K1qHDp12+6O}HPCme{!Dy420m`Hy{XPZZjd^VTHF(kg|i z>0EFCYtWoei~&NDoGsOx=33?6V!NF*yK>8oX_u28Ih6f%U|KZi-{rKI?1gM6K||BR zA2oVis*g$a#MQIf@l+kWTrXf$)qb@~EIYg8MKs5yNYTBelipafUMXLB?2vH5Q_l$- zh1S(BnLN>U$GYx!$K`e7-n%_|x3p9_cGs1rd2NAvzIIQz=506kS*?o4F`>}uoCg@( zZNAN5Ve2^R5c6|)#k-U9eXHYJ-%QW?k-aDJRIbFMit0ZC=cZZ+iilOEJ_)QNs$IsDcX+H^<@-xRI5o$%R+u1 zN|s0~RRquDk<{5qyuUbl#>g;M+&H49}+*Hn|6V@p6+uTlY`cUboeOA$|Pl?ea zW+m5jt}dJNY#DJEcPAd6v1G@)M>ujGSF>t* z1Wf_W+;IgpcyI-9GBBhtFfcIgGHLyCrocYGc8*Aj;@_JePGkwIv3E%Zi!W?(p7Rz4w^&`Z2JKIxXj_+mC3`{Nm8E!HCmNscx ztRQI65ulaKFZg0IXj&Vzs4VC9L9>;vYk#D^HmiAof7weQAT+b6mIaZ;X!Z+8eN9 z%i*$g*{Y|(JY6o)iG9-o4jFTLERi|1^Vs(NJ-&<6ww*3pylL(S9>-}H9!fiZJJx1x zCxHX*s@g? zhc}A7GA-+r*%qkIA?YG&=@=s78*-%jh@}sM;kEK(Z;lHeiw}76=IyB@mgv8_avnL` zg09DPuF2N8eBpNKv8X!dtqY%Rer9t!&(1^bb@EBxYcD5f{@$^iL+hs16K}oy22-WK z=K0QAqNlM?pkdG6<+oH;XrAI)&#}+#j&{{AwoT_6l;?n&2;rc$ja3Z?>w4{GY*1-b z+uQ%<@P;X^J~@TD3q!6j%vjlHe}qSPs>9q1cNls5FHOIk*p_^wJ?-(-vUon(pS3H~ ztIs(XaOOCL-#UEpLG8iT%XLdm_H`f5_l!+aUN(Q`hPzJ==Kr4LJd=O>1>a7G(A%>T zO#Np#U$@ZMKS}CXuJ`ZX!Zu5GgnfPe{Ig-xsmaS%i|#giy*t*CK}mOFV5y&S(o~bK zQXb_A41Pg8kFQ@l|4s46wNvHpX}>k!yk`m6!n)yY@6B)L>i_u#A3k_+=gdHf6K^97 zlN@{}oAq2~n4orbm+lG19bBCp0sI_?*8aQp%dPj|!WXq`p8e~!&EI=um1+F9IlcU0 zJ4GJfekz%L{_;Q(f=8EKAw>6FFWv7 zXh-JF@Jzo60ec_m+)pf9n9>(Gqp@pMMPx_91dfKr7MAo~?JIB8=bn~Xx%kHOtgaOc z8B>-jF@}da{$cR^Mpfc5_x& zy_Zn0afa9Yu0`zjO?*Y27r5T%m3glI^1SPt@ci?ADf%-1WIi8%Jx|5#@#b|Gt8D^T z#V*LQSH-kP56`TBFskr`iG zeV%Fv>O@Rt^ZxjF&+P?Qwq&J<+kEOUQm$(vbZ+Q;Q*-vr74Gde zl6rVuQlW(5j7P}qpxi5OoLm*&xaNW;VP5YCEuc?mUTMs${`li+P=5n5-O{}JC$IDI zb!~+?n;Fkny%XJA3R;g3TA~C>Rp2$N*A1S77sErB4}(@T|JwilR0HE2j$PZ=?fCd{ z#|O|B4sibjw2m9JmYOHoLhj<~#y#(6?^&$c!u3=@{&)J1RdbFoi1;Pz^u&GOJ>YC^ zT6Xsp=gzE^Vva$L9ShkK6n8j1HHbKBz}S$Xz$_aZ3tdBX?N=maD%;Y}0WGe{t)>iEKpzZxgtRO$CbPccdN}nSh+xSm+JiL^9#yyuw z;LaSENP{(t7<$t5B$G1d80M+0SkEjd+pYWM`>LQ)v1#j$w&!Ge9xYs$d&D#JS@!AG z(r13kCLRqn>T$WH+_lc^!O9(aWeZ=c?PyMovT^C&9UZ_7^WOu^82U(yP^PSyOaP3%;4Ze~m zvA@6AAIUGTQ!-V!S<=m~R}+}Iw>xy+W5@cnXA8yK(vLHRR4JcQ3(!?AKQ!ycB*yKk zD-Dyc{9PZg4wS(gewn`Cv~dhn^^HT&VULd!K4I6OS`F#0;U zbk5n#>CurGk)=6>YnG4XGN%R)E+=!Jr3_CP1lOp;Hf6k9cJ$l*jeXl{CmP;~lu;H= zxv2JTVoC6n)v_!H4MKOG3TA3pAXIycLn^^!!cmRi0lU(#$bJug={s%mnz&p;)7^U) zu0B!qhqG*R($qU%hO4JNtr5F7sqn&TwGBnClQ`blU9fQIU$kcCh1aXPR&zhod3Lnv z$&CwM+LP|(S*J~mnX-Oczm*e5R=-IGm&dXOua3Pt`|VbK6z%Yxc$mRKdWFU6&+kPi zvE^R+peYts|8K?1Vo)RD@H59LY47grc1_+s+vUm+|C)j|va5QfbQW5-7nM%Y>Jw+; zIkLpC!$E=9WeKCCUtoibb`@kr{nmfHCfe&}SLD3xTfOOurRzq+*xdBONClgn6PMh} zF}u#g^6dJvtPF?QygPN~^SKv@SuU9DrP=UR?waYfm*sXMEmL{s^&Lq+T0PsKo6jaG zZ2Ajd?X?yTo^O&?WUOjE^(}s*-`x*q8xP0i+`F{Bq(icQruZ$I{dMpHe!2Q5ofq}*$G`vlAWVLHyx@=fQ$M=br~hZju-UKw z_&)>Zr~eGsYVRK@ubS`q+P?S8y!GvyKYwrDTzBT*sj6jl;!l3Xy;rD>U-Epu=PT>| z8y;F)y!mXif7fT5{nN2;b*ZX~t^h4Ghi(kextD0E4T}$shtWUUk1q(WIO-?5xAxch z-k+fD5#Wtxhb7Nio8PYgWA~Ol)$B~5amxpuNb&9kjuWqDC28Efl`{YDv7Ai{0t7kx zOVott zeb#97IBQXE19$Iq+j|ij6STz3(tk~S8@fDu@5;y3(QRt0EG(2Ra~$m2S=}wqci5{) z>0!t-`Q<6$utajZJdcUX3=D$_Ah zo{%o%_gV~0hR;qO+J4nJdcEN(P+bY$#MG64{XL7U@<;w1*WXLK{9PTtx1Y&2c1~|t zYD|3Z!8W%ImojdJ+}b9zXxl^gylCF$R!Qm9izbOvIi-VNl^t9WZX3?JLg>-#WxpA1 zx8M1)Zb#=cZLcF8uh!1$lG^6AqEAyuOH)YiPg(O%&tLV2rW#rJo%=Rf&J3}B>$lhaTkklpM^!)xo^!T+xg;gJ~E4GwA^yq%)xN*lJGuTIbFE)wV)f(i{tvSY z1MmNf3H@7~`tCo&wEe4;WuANUzFD}_C5=;gQ^m!}3Sq6ry=!6}8U8bzTX@XTQ1-FK zznHpJ2bO6@e~WSy5MZ93{87=+U75W;()e6aG5Xx@>did262^n`CWu@nYQ8n?92CEVoks;<|Ig}8MLpWAq}eLltY`uOKvXbCQ3I^0Ye$a*aBJ0+^UT0I2X9L<^3f_--tbS!ue!~86SRLdbcNgbH?|xc|4u#-NLfV zRum>3zqMkXTxh3hxz@pxjHyT8S?I6+dZ~Tq%D}jssm5y8w!J=)??m*$5*jF>Ii9CFG{m_PMYeRGH#-EASdz#9?D9V;JOHIkEV-fQmVGbECW<$9X zYgPuhhW0S2x~hsAupU`C#ZN&dg<0eE#vMUl*$>ut?3^-d+9RQDzE-)x7jsuN{@A$g zm0pt5w%+jauuqfIuKW;Myfr)Q@#LiL);mY0du~hNJ-BXi;FVt6oo1q^?r4k6XII|0 zAYIHQT_*APV>=rmZGE$p!!LBDx@sP1xNxs3Zz>51Rb}v4w!$C7a@SMeM*jCesGSXpGT@w$(t}jKMp0Sqj#Eb-ecW zF=PiiSO=(+2HuJe+NW50`ukKB&@MvAE^yGES@14%P_}^Xegy55Ky5sMwq2vOQ;zzH z?(e9nVm0pp4RC;~XVBJ_y{T*O?|H2NuCw+pU%<1y2UL55_bGz5U4xBA3iLwnCyleC8=btkUU^Yp2OcYd^lCwy z)8PdKc>m|s{|t2@3_K59LFHh7@9`FpA7N_<;d|a+gLdqI_S$CIN%02Rodzu`L!_vBSvzg1)T z#_C`D!q+0-q(!govsO8Mcjn4VSqlzKw9C!$*r4DzJ*HTF^3_ZCCcM7f+R^(fFk+LK z)9PS-pIw>kh3$IRu9dVU9-Fpdb~nc?_PZrgna_Ej$L2oCU3Y!9fI#-nL!ZUZ@SWpc zA0eK2Kuznncc;h$X8RWf2klD^7O=|c%;ep_C*=0MQ$5Qp^SN&HPCn=raQK6at?{(@ z*J~PMcM5Wb#O(Tgn$@XD^S}b*2`rB%t=q*L7tF$w=?cs5n3Yo(_DU$bKhty9)yJ$<*} z$C;0<#d^DD)qURP!o)DubCvj;WBnm|MQgTZ1kPK%AZ1Fx)amb^?KOSq^tSe%c;|^M ztHR4C&hAxRwd=d6$n43swxx?-*(eHgB>mas5@+3}>~vw(e+GrmGY_i0P`vk>L#e+i z_WhQb!tcv7;=UIwv}EXDd28j)|5i9NDred8#}%uWayd7v-rDTrVtsmF$;68}lM??k z6nsB>-;{;RN#d}B#Ou}bSKjehYN5C(hoh3e;MAi$Q4PM>M}n)Aa+WbHOf#7gXTWy9 zZ1R@bRZmSfF6W%MIniSC;aMUlHs;=+AoEnQuXx4Eh6QYq!7D0Rx>R+#gv(v)&feP* zRmvZ~>DAxbytT`&-aNErkMd2e{B?TC4yD^KEn+s=taEVloV6_BPyHrJD7l))Wu(~L z4!m=$EN;_lp5W8zag{%>>2G)}7^vvcEoZn(MO*RGq}y66t{3gl-NLrcqDf_emfMVv zpowaN`@$F3TLy1}?aTvh?gH)b#(IDPxLbDp*duHBIRcNCLw9?D3yb~Nu1#;00JF~d z^bh40v#xS23%}7k$5iD^6vG@z3yuCN2SsHb)+_5pYMEZjEYIG)Z`tdw)82GyUnvMn zJ6Lv5soGp?b$oZG8RyP7y-S`YbN-$ro+PLi>Ag62HgnR~P?hbEXD#Ac9=Kzor@d&N z%jU%8f%ftmy}>V!+o)wr9)g}dB6w)~nyuj7>u%53e>`||<|+Tq?YGO+CzQ9e-261f z-H>TEm&Fuzh4(X@8V#rT)ISd2^!R@Mw?CQ_a^5`OSAX;SnVNi$rs;20Kdk85|2*!* z9S=JpcddCp!J<~aY@_2z2Xb3OT6X?M1iDA?zw_iSK) zdm=Ny?e5x+7Bl!s^*Gxep>JHuE2f%`w;)@CJmrNG2kb(?$SA)hgcYce7x@a+{%b5 z{GH`_QF)68pJ#yhqNYg;`i+t&uPJa@p%j;%HEEI3rxi1sAZ>&73JrIlr@AacJx{|X zhk2jcpJSl2N_K(IdI3cS_@oPPF3N`*QowmX8}pivCa)DtMj)a`7y zMmoENaYxuM$dGRcXaok->jO0`z(c;^3Y~=Zwj-!j-`*d~^Y|5P__)b$`x8?>ae3Wz z(2*>2w5uR>Ca9|X!kapm!QBFBh5vQDwL02Z^?du+VmX`gq*s-MyE?6!w8UV_6H6DK zV3C6X0s@R&tqkVJE&R8g-I6geNYvoC?V<0E;W|C3zM3J=JP#=(=L>Rn^#3>p+S&?j zwu74w9q(&i%KKC;FbG~zrM7X$+Vojd&)p9>I#)?x&!Y7#k$O!hQkRD?%*ou&x>-?3 zF;pbvnbtP$U8bd(Z_~po|L!X|I^nUytNu?b8`dWZd|IKhXi3Majy-zCy{p~^XP3>K zdBeVM3+jisLxjK40Mo1LyZCcLNwi?JkP=&pUPP z)Fb!RTjpvV^3P(j)qPxXK`=Cc)i->LU}z{yg-B@V%^Ejf7E8Ut8J4s~yKG2~~AZ3v4&ft^+Zn=RH&+pfN!jh+e(i3oD;pCR<|LX9cQ-c32?%fxs+!i&Yzm?yV? zW8Q&n-W%_jEYFx}Si8EULtNxmxW*J2={=11GuxKs{n(JeB>#KUoYQ*7)~!BFE|-_r zY1pKEd4G6rOxMLav+Gw*8eYvRSz*-bCAjN;v6!{XwB6U{ZK-a&(3km9TQHErM_KF3 zjZ1p{muL4L{ZQ-hAc%4KicO_kT}oMl_s&p=scN5oSLE_L$+*zN@80J8I(akx!aKRJ zmyhPIwGX^K)hk#y%^=*%%yFX&!=dmWo7lBZYa0qlsyR&LU{K=oORkgMakKB>Z@C)} zeSWZ~&o;Sx$cbt8^)>tVJYo?#;c(=L;p9jB9>xsv2a8$`u!V4@+;JB?{GrXS&?fY= zjWJ)!#OoD*e@}_roYlyb9(i~=yRS&FM#%Airy6O7m+UUs?ftEPGsg3t=%ycb#@oHN z%w!iy*&L(K5Sze%qE~L$@At8S#&zs5GZLd$*iR0fqo%MVvtavv$$9$g-`=|Z#{BOh zP5qKvyg@Z{vmIBYTygD~Bqe!u*K5@q9z9c!Y=85V$>MeY$-vShn><4=_su)f7j$!F z)ANffi*Ipm+r()<^MJnQ%a%FIRVLmRla3Q)v2;22MP#X>!x9aVr3{*00ZdbtGE86q zogt^ez^K6OIAfb-Qvz@6GwYtj3T=n?zSnd+Ob*Zfr+Cl&*LyKn`y*QRQ<)ZfTn@YQ zpFzQPL-LZM>uC}>*N$!q-xCsJlCe*>cbPLogYQ43oj1x4HE}7oC?yEYkP5tbckON7 zWw&*FW74xe{)x`m80z3~eq;MP`E@MsIsaX9i*^3n!j&kf#L<+oOh_wpil*>)pM9tP zt$f2`Y_)htzzcyX0srI!U75M{kkoI zg3*iDP0x9ywS2B(ovfgs?S%Fna+99_VL2>!|JuwKjpwhlC*+D+X@A>)^P`B*q2MXI zecLox4R~6tU+NX{v=_D*Z}G}sd4Bn#p5EK)=?84eCi8#(z3IdA9m!{lVF!XqgGM_i zJ&NR?#%a6~ zwEX5;l(b6y;i;c1PyO4YZa*n~*~DLqewFGRsm^%wMs$v51NSX3Omb}LERzx|O#vdT5j z@E_S?3WaqqQ@YdwH~9ry3TUig5p_`sFkm_CVNrHJcilOGlW)G=cBS~)=1g1F&O<+iu(U&^*F(&g?|HdAFfur-a|1<2Z?A%-Q_tu<{f|sFT7U%zY z@m9L;UsRtq@yp`XyS4}BRBf2enl?AhC*yZOZ=Z%P((sd?~-NZ{xh$n}=1G%{KKnn3b!v$>q@^Ewd$ypH5o% z=afd5c5D8sHqenmpb8yaX@ZWF0;CqR05q&13G>SJgx>h zqYE@Vfi}YEswcW{{qIi;7{F)WfzOqPgh%!^Uql??BK zOMvICp<~gYL3Qv#Nl+~X9$g33HIViMc(?;}oEPGl9ni!z(t-|fXCLIa>vcPSfXBF@ zmVvtOpk6zu^#vKP1&>gG8$h5Mm^Mepfi_2is!#AJ59Ex$z-y5qE=4_!H~urE&RCy) zJLPiv%(-qeqGYencI=um_tV20iG1=UM;QO`ygjpjdCJV=yHfjtHC4J6wCNVC1rJ?F zPx+Pq=4yL-?aT*B98(J4E>Ak2QTRPg|JSm@j_t~AJ1RKNc(h4e44KuGDyVp8>gfp# zqDPi4|7Tj`y7S@vCH;{>0_(o-I9VTa>Gy5+==D=JcD|Nv{dU(W^V&+K3DP_>cJW7f zt<8KE(-9P+;x{Yv@%A@NXO_gbhBKVm^e`m!!DoTUHWjTFRgH@QogyI-xsQb01q6%s zoye&>|3;7Dc-pqiriwbTg9e%$0gRD{7BPO0-5tUeSn&2>^Ek(B01x8^;W}QVTe-_l; z_#J%6TH!{Gf3~54@8KmU(srncrP|&67!w;L{VQyN0#nffHvV02lcwBH-RYPAy_2ED z@fLfAbl@$$3pTf6*B*^YnlX9t?A_l*?7ys;AT056)8X6Yt!g=w-gBtj70_g`J}zK* zE}3tkje3Rst(wr7JEg)kH*~YUxar;faqYlMk-L*i_Lf|Vonmz|IP?Hh{yE{Td!`w+ zPJd!9XOcO|*6YxQ+1~>myeNEp`Kn9e@1QQbSqdNSXq{LzFPhKpc1G8V*i}8QxzRxa z!Nxh(f_JumW&CQob?@fg;k@eAj5pfOx%$|r-(Hn0d;hliFa5%$hj;PIp0Il;#B$>9 z`U;PUJaxZLmD+-isRZ?YK}jBRikvyL+k8A>F8lIZ`QBfv?i#x+Y+jeWHTT=GM$WCS zg_m4DFY}r3XwJ;fPX!iFTJBT&GDzm<+>)unU6XV3lPfJ>Ye(jtneppW-md+Qe$~-A z!VQ@VTpwIt2r1D$aQ>Yso+^5Ee`uoh5L5j+AaY7zEN@#71Td*FGBbWrC7v^wSM zwC#1D*EDMg9@_r#<;&d1pv;S^5nK|K&X@0GD*&CB2|7445Y+!E`ujW*bXeUh@R~UA zz-R5QiW}@Tpu=UNK?~+UgQ(!L6qGN)hJww4mMYL=HbK3WZTruvS%L;a!N=l&GjHs# zXEN`=lMDN9owi~C521oeH_%yi;GzoL_648g1uC>a!=FdN1JyH%cYJ7+fvw>OHKU=E zMjTd?4W2)~w)+QYvoz|0o`Pf5*I_4Kg2ENFDhE{l6Flq_bQUP+jKbBh!&gB%K|uj6 z3PBzRH~T@eM38A1P$0(sdj7cZAtErqgQ(ailfa`hsK*B;E$6zAd;p@pG`j@ofJMk* zv!Llaa9;xNVV`o%1qw_LW*9IqFeFA)fSQPmixe0bC$KrnRmf;pfjb`k&OZbi9#j}i zNn>tJJj5i*$e7X5&~U=&fy`pR`0Rdr?icRY`{S?V)$7&TO+9YEUgqOJ%cMW{_4!-t zUk3kY_7~*aBV*c9(0UiY<))}nF zOs71Iz79T`C};jpF+nxcn}tgh*bZ%5u^^H0UB}dW97+MwJ`6{N!x|E1gs876hpk50 zIghc0{gAtdHH-T$v1_h3I_4hR{p|8R*F)8lR@I!^_iE+4Jx>a+mWIA!JA7)@hbJt4 z^(;R^_yq0!PlJx#d=DNP1J&f&Jz%7eE;Ta=NI`!)WM9pr8y4ZX$q>*9GTfSmpwy48&Qw&}jlt`hjF*P}0CMCGpzM zUI_Jk(M{Lh-z%Mv3Qj<^h@}&t%!hmqFIXew;85_?0WWMe9c1Nu_`#%?j~%dvsDd9a z3Tdf;`kUa43~I7~G9M^6VXWyy$>oq71Fr8uS@J+0tf2xbSD@n)puv_+a*aD+2aJB) z@u7)t1!LR&ji3HA$nW@V0a>Nlcy9X>Q+WpdSg(L%)i(;(z6RwjP;mx64iYr?;#>EE zc^@dhg0mmkagfFfDBD3T0~Ifz*=&MS9B6|fli;H`coy!Ztb-iT1?umEi=wXSVPCJy z$(e!A^@QYFaA^iv1qn)5<*%nhCXG>#hz6hh3r=Reum4)*zRtU7Eq~)prgFpH#J0to zcbtlS_wnM<4I+~h9-QK7a{4NA`;ljBO81op_dU$I+!kS9zk`}O$tm}b*V%ncDx14G zOG7Q`#&64BQxCU<$;%VFHdQ6Hy!?JC;|N>)-$s{IgL%96UDlg(OS>wWZJ zfBi;h-+8&0-(Rhovq&qge;wbsz}t4m?!J}c_`Y%7`I!Fo zb7}Gq0X)Z0ilkDh6@f(2?`2E6B-&CE+r~T9I!jp z`{~fNEk0xS-aC57vDvC8c)I>GC^P2!X4|*?+Mo98pXKS&M=NJ+ zzZ!Oyi}TjO(wQ>qa>-YhUEp4_zf-4D$M`=3Gs8^KNzvf^4X;^2sU2KSf%3$C&?&-h zSByAMBA=RlZIua^2dEtn9+?3Z2fM(f062~j*$#Rh@N38vA?Q5RD)33d&|U%P=wTMv zalxQDd2pEmAIC?_uwY|B&3LqRO%kAaQtjTXq z&hL+U|ClFzFStekou`ay8mQj}vK7*~12=e}1p`POc)bhAb!Y`2xcP+Ig#i_rFCZs= zgVF+Mod-B)L#lEni!kVlUr?C|Dk_=bt^`Lr?3`oBL5)dMVY8;7RJ45hkz?Qz^Zj*D zRW1lS$^~41fDS4JHD@5ldxN6@v=aJwu3g7&pX`mc8|S*!E!LXqy4wb#mmb=G_n*O~vZ-)s zTyTqBU|{f^ucFn*TI|;Sn_G5xbL_rbbJrf)R(X2fIm17pHPJjrKV0#7x=g6Xf$QZx z=`OVfi67}--iH=U4i(pw+L05|(>3>_mFC;kFCV{RPOC1u@l8M4F70;C3}Z*zRX5M? za=E*u#)&C=U&f8&qM?UkR|RX`EMh!0K}LF2LcnCR>Z+6TR4yLoaa>(~X6}*_S(CD^ zJZTG82cfyD7ebc%hMWr&Fysr=Xgy^09yK^+jFz+*|%Hw{}as;QQ(J z*o)8Tx7VH(;z~vl?=!F6%MkSN+$#Dh12i}dJ=y;k_{?(i<+s{D?z}ng+WsSjy)CzD zvJ>R?hq}w(3dy;jVV1e;_{y%6tGW!1MlM=-l2@HS!c7P$(mL>fs*$RKsJrK|=m}l-{PPWT`CZ&#n{sQGeSA)@(V*kzQr7v->+o& zvnZmL9%s>wxf#Ceg_gAL4!fUoUhlQKZI%|N8SL->EY3 zuiD$H1ve_VnB}_Nh`W&ZqfkWDvqf0i;ho5#u0%om!i6UkoMu!X@j0T}pv?5)=Hq^^ zkIH-QXKeXZcX;*rwJRsrhO1o*kz5;f^~iJ~m8ms~>Y|fpTV9;wu`lNu@7CgNNwYK9 zPra)(*nC;*(Jjvn?UvJ*u!JA7u)679d+bhufav|Vw?Z;5pLv@xF`zQP^{G`9{ABS3 z?p%;#`ay*<>iV15KRre1piTs|%7D~^psHYJ-RCt;pkXR-eF(0m_T5FP2Q`sbtblK< z0QW^BXVbIMPXtz;-20tOQouH}=JQ4`*vVtpq!P5L# zzL=GV8bQOK(5nDI^)96KKND8bff_ZSC4`2-u+@wZM}S(&5Qo9`nct604HN|3)e-&m zc_0J$UIozX8c*tuxQofrrd_7TwpEMPH$8e2@_VhJjOnE_cee*UpRySiht-TKZr|icjh(`AP3S z?E5%{f$yDEY0GiDWp}h89b-^PLN8%)ip~7+@lxNu%UeUQ9TpZA7W=c!J!ySs|E;dBc++uGb(8GE z$H}bE+j-yB#cWP<)@Q!CqLDkf`;9{P8iQNYckW?+H#yfno-uUW`xR3JYv)W4`Oi?K z^t*bAWQ>;j)zI2PE%i-Y>#F93s!aEJsWU5EWueO|m6cqJ(lzcZS3KaA)R&MTAalsd z{nq=B-@m-Sbxq~5tQ~h(j-J&Uzs1{cbG%$8a`n}7L1ByXW~-$C44k4piNYGI!`6yM z+@EwxL&^9>dFuRA*KTe+#<)FawtVB`XuBN~_TTxYxw=PP^6;@DqvNR^N&XR!GWjx= z)mS>6@CglB$ew7e`1R|Tu)cdZY=IcV+wH0IUE_W4PGXaL zoc`PF;KrO{UXd&AncFsse48x8uEPIs+N2vz=~-v%zMKh8d@IG2WdE|!N!t7x`=y8V zcW>WMefXc@+Zp5D{|wibZhp8&nf2THKhyu}mu1|FaJ#(gt-YA3@ZmC6mir1(^*hg* z{7sYa@@%V5J-l>j(4veFn{L@uew}>c^7Hwz`jRu2sYaYtJ-3s|!NRsrbxlXpe?lp7+^WRCeuA zDxS@x>E$$~MbpcvL1d{0qZeosb5KhI15*R&>?w{TwX42;z41NCqWrtwmEDdv&rVdl zBs$x$?#rrV{SINyhc~1h3cL4nPVv5%bux%?MKZ&&rr*W?qN=lQClE_w%xgE zmK|E9^B(QE{M};mcda=tKB+Og0z-WR1vLD31y?9M#zg?ZX@|KuYNz&>uuNEn8TCnndUHg=>+_7KkuGpyYy{(wsr0n+XZj;spJG_mQDQB|54m2 zz}LX=_y@;bs(%D??%KV|Q1U-&#ONiqp1)x2YqUY8z^!#{74a|G+n1@W_t!{aJvy6N z>~i| z%>N3xHw0WQfqIp%kvemrE+^h4JyX*I2cYes?uQ*$IZJ|9 z+k-DI0aXpJ>({PV0Iiz^kH3NX|KP4W_?{EUx?cDocGn#3x>ibn9DB9UtBQOYB)G)_X}dtXHSi0|e!tdPr36j|;2WI4>xU70O;&(p zEy3%u!Iz7{7R7-3&2K@YB%pu*kBxx?wH|s$4tVed+y`F;IzSQ>&bz=ZdvMbWn#v#> z-_Qq2y?b|pcAb@f`NB92_l;$crQIOYP}`2+(E)f{2|WG^TDuJ$&IOIxR8>V+fE!Ek z@WCVSYzfFL^a+u5qR=bLK*I{)rXx6)fL7ogSSPx-6w8%m;FaB7G0?Sb3qa8ZUd09u zG4NO@D8xX+r6`F4mgK>6wqR$l$a>Dmw3pjwlMG7M;PeMRRH@?Yg>w?%nPRZ@@av^O z^FELPYEbVk540@|oO&P)SC9w5vo_!nCU91Dhh2FYSEM3*hG>JnLRz!j#;14KWf}9WCj|u9?fGq+g7jOmx zm!II$3e+YCk6(iN6tKI_V9N>Di6ZTB0GkSSK4K=qyLTsK91xtKLBRvgLZFl#1G?A` zG+qW?G6BxN@!*sMn&rF(-e3qywW#?E(WQWwfS>`nx9dN9_JL+iVnOLi0GzNPt1&^N zg^?Bhmk%GZI|scksCey9UiSmc*Mp`Q&if_<%RHbRmf*|-Nho_{<8fg zjQ2rvYG8MR_NqcsJvfblvku6c>xo_Jad__W7Ep13q7xM1NQaMs2Mw1V+78=m;SL(Z z1D)m!PCuZ&+=1-XRWFL3`iby?`%cl6UljQ3v{nabvK6}345cvM4^GV>Z-Ns$D4O8g zG``BFPIYnD03|c<$_a2<{Lc`b#{o*Qe^J-8gDW}I88pyFQ$#rqx|C88bT8OC*oGeH zFgYj%-3N`jgSS+IZlwgLv&h%w@3lOPLA5WqLk_MeK;u2|Apo$Ih+IPn z00pUnO|L_yy%7Z{ysZPa5z-nc0F4VQez*X%`42MKAW*87xa3dOkB^Yc>>z?54}f!B z#Dl|8@8vJ>&-m%EdPer)dr^-Jj)B(3B3~1DeS&NEj4Z1a{xJ&fY*N=N>JHzldDznn zn=l0V65I^y4mbGEFth5n7fV6ndPR_-|C%IDU|WT}^5h>|GrjV3oidY!!3p>F{TtXdl9iB`2td!3%WmfI+qHbp ze}*G$4-Q)v3Vc|<{Y@e$+}4AK)&yatwN63e+9LT246i3R^zoQJvrCX${Fo=jPjuf3 ztGj!^yR=@1O0lX4W;gS+R8;@=p2G3qknp;d@9jT=e1X32tdGZdx*$K-@490wF^6MQ zZM{njC+>h=BLlx{6%=UqAPoCO|{#S9GG!XV7ZFl&wk z0|NtliKnkC`!!BRQ7PWcyzSKt3=Fa*t`Q~9`MJ5Nc_j?aMX8A;sVNHOnI#ztAsML( z?w-B@?^9Is7#I{7JY5_^DsH{q`*O0($*DJ9J}gXiNpZOsIkPl;VS)VJ7nASid^53> z;mwrFv^X}g%ze_^TLov9^k1r1y1YDg^VX|bzO$wtnVM$d)@LCz$$8WAM!O4lU$`-9 zhy;YL*!{^)*~rN6dOJ(kRfkZwl&6uc&##50$)4zm|MmI%pNjW8t+#I7+A840A?P&k z=k43=4Gb&_e6A0i=YRW9W!+RMO9F{T|da$s4Y^-EX z+QGr|$XfOpukDGGt_cG23JcgJ^_ZHkF)>w5c&KEs#aw~GFb1YSVS)%gF2^S(ur1;? zF3ei29SfBWI{2#u9C*YV9cwN$H{59NKA>RdaDXLo2M3Q9E5{4Rw(bKL?lmwRDG-!U zVdVfT48q5a{~*Atz+hOy;wJEfbt==506~c(?6w>VZ6JeRI6AyJ?0TTpprL{D&;-E( zMIMk}jF_C089=TwP|yU0#PJ)2ORWU8Rh_PGxRM|_`dzt`fVUt0BG9W0{DF&aUTM6Bg`cEIcJ}(Bbo;C*Q8# zJiF4xkxN3vRiot3rKwg~_J^6<&4ypsDO)j`~Bx1ZK&=ZXORo{8Y~<+BCn(_ z?EDp@CcL$?Vr%$TiD#__0#8_7>;;%L6jw@4o3(cpYYYdo?TM96SEQX{`FW0sREKi! z5MZmC5PY@y&9p7_rlZf=^H1_&ncbGyfGSmCwh%6X#SIgfe(n77Z0X9cAxk89UT`RG z)qFE`@prSdY30kVq#aN{v}NY;nLDmM`JLXf+x6#X_mw`HH&$~pLDG)JF+1~pUwgab z)tsjOt>^X5iU>+B;#Dk3uf4YAFQ0^n(p%jL3RARCAKkU(|B+J7E+r1dp4jV4qx>z7 zO=NKv^O?8R@|a@Bs;oa@dS8AnzB2c?=ix=sFHP=pcQH<7a#_wVnbW;Tk9%uNPyox+ zWjS|wrd+uYm%3(^=aSE{jD<^!Dzn}$V0|||WkpeHTJ3t7o0`XJ_UUS6E9Gx9bh>`j zet+%9#Y<-{KDOd-yG(Mw>nq`pSsq3LilVw3=7t-ouB^QkwLJG=gBRnX#qBnW&#P^V zn-@E$ahlgBr>Qe&r!aUr)Z?~>EzrD9r zyCX|{^#<8J!2y5voZaxEHzz|`+Uk^7^(8T$3|)mk_ERd}?)82jKQro9{l643_nk`1 zyXVMFKb^er54-pJ^woy{J9Y#K{!~_eleA!F$f|$$#inlk)@`-+WUBV37h71FqqsSy zZBq);)O+5v$4lVitb;YSfot4#+HHT#oO$Hg_4Bn;xYBRGFh4$Hx>~r!v0oR}_un>P znQyPAl6B=`vbd|D>yvF7JTdA%iO>(1-mt@zM&K59eH-D5c#Ef&YV z#hbR3+15Xd7MJgDef=<@c~Qr;Cq+{q_&MG@M{upmv{QdG(Z{Nw^gSn-uXYl%3 z|66@5Vfo+NLW*DI>))!_DBmBD=zd%zFoA#OF1k=c;>5+ z!yv?)B3c)nh*+^>+RP81jrX`az4?_N*>m^t-?YZ<>-68) z-08a;=gAvnFS%jw&R!vj&%7!ONCvb4&$YMed# z{_N3rt*uN>9@||kKh(JF-nyn}QP94x_wV2P>wGofk3v&T@1kE@|1O_e`)u{Hxc!O$ zndcP?G#c-|>3_n=Piqlhh3Mgi#FFL(n$CPr4mHkYh<4_9xhy8LFZ^qZ?+!gdlWohD zz1REwH`4iM)}?!S*>Wjg7qff2KU|L2`@6VJvEo|O!rUv{4_&H@owe?|#|+Y-7&CqvG@}F{J^RIdK%<>XixA*6!tvRvr`1?qm z+2^J-GhfqS%XweH!8SYd>A$5<^i%A<-xg&JpSGjOV#2{GUw8ai^>o8=XP2XQ!6KkISxueH+m?3>@Sbwh0 zg-x|f%Ty14Jy~({^6}y+#$o0+&dc}e=O1TV6L^M$-z%>{PlZ`tooTyD+U#TgMH4xk zwrO8IvvcpU=*qvdUTQeMbQHQ2<#Wek)l%h0?{5A$8&mu2!odx;N|JZxblEN0Wzetw zexh;mskp6zS%<%tc*}))Wz7)KQk#A|vhVTg?tTwb*Dn!AuSzl6Uz+VHcDp*2!|8Tw zfbZkc3yA?TkC@LAuy!oJCsIfou)Q?r?1vW^Nb&Vy`2u^NxZ%6C;nlrB#^+9vv|=JoDvr%NC88;VVe?}*v^d*^~9 zs|ziE8x$|({a&%|V*BpT_J1Fh|NAogf4z0Rnp0Nr7v)PkugE!Xj}{i1ern3$x+T-Q z!X%g7T`j|YKWbjp7UB6l;m4G|dIaPzU7LFPQkmn;Gp(kz9KX9}Ox(2hZ#rYu`#GQf zyZk&_=5_3y+R^h_&r;6LkuA{GIMpj>%kyqJ_euT|?H?Ndm*xE`z0`9udh$b2uCECP z-2zo)ZylZTTIOw3iM0$T=R&)>lE3EO`5I2Kd>L<#&q?zAxJG~39q-`TZ^H|h9nN|7 zxNgbvj;i1H*Ux^lc}%g~%|N3->s26U=Tn9F+;nDHwdpCVKl+ES?~3_st^fa6 zvB=qwq8AR?A^oey>QhNtxfaU9!a!+nsM#Z&3_j5yDO#TR(5K%cAQ9g)@0wq zZufPuuubg4m#-dFPgt>`^N;V7h+7u(|5ym#`Oy60p}~(Uwu}2)jqIc^`tRId8zy+Q z{?|AEXOnKn?W;>$FZ2D0-!U%sat|4+MfdK`$eNq`Fj@5R(?3@#4@+6vpYVv~a29#@ zu=45uNi*L5Yh6`-35;_)Sxz}zy4 zKoL&wrDfZ$cWSQkefjqDd{>qCvZ5>tukQ7P2~1OsUeAm;m)CyGhQ1 zo|WE@vSjy`nU*Ko>=EVJ@>|S(cJ8WYllWweb&^m1`@~+Nydl)*S0?v8ZJ+q-%)5^M zj7h2}(=<+=TL0JGT&8`I#*-aaCZCmD8+fI*$X~-*`1ZnY?>X;okGXs-wDcvzemC*woa9ew?w%>z4&RIUdF_4t-_zgRJd$^-D{?ulV0isq<-CvTuBq~$FN?ix z7Uobqezfm#`Q3**RlUS|x-aj1eD-a$&EX~6KYx1k_y&9T%b3VFr_cR5c;lY%RhP3H z5B%PIP`+r#V!?(@F&neaywA#i_BDI0!b62@#bQgT@;P%Q1dSP&-P_Vq=vHeSI-0jpYx=W#i}rWf}jaO5faJju&#^P!xGE zr?vA`MU1G$Z+H1KtM_(j8y!A%V9JZ*=}-QPJbM?sqWRr@RiB#{^E3CvWuD6nJEi#N zAaewJaQDs^%U2Y$s~vxF&|&8y_5Kg1B4k-#eEz!8U%vise{R5u-0S>hbEkiP<8tN6 z|9}6y`OBC8{dIV6eLef-IsbA`SC!QsyuCjDgkEl&eY9WM`oJ>{x%~o7n%W2N&*A@P z*}hsfbMxCS?W^x|uik&1eJbO36o*f$Qpx*@zZoHSZfni87E#>5d+oTHs*}d)hecn% zsAs>wHd`@%c0)~!iOS5BC2a`Ok|F`qgPD6MC89HV<3X{^W;nRLSvHw?%#VitTXaDW(y8Zd0e}K4U>Wrev2Ya0b zS6*0lykUX+_wCQ+v~ND0pszNi=C|dB^M)UeZ@+i*#Pa@&VvjFQa{ng3u#E4{kC&Y{ z&b6BtT|C%RJ?mWEMxpnf2|WA`QzgCTiv3H9`qS;FGvU&kFGWx1=dXM}bDhl>W^T!x zJysv5n|zZozqQ`o!|7g~+(F}C#+ldJd(5_eJiOhp!u2-i!oE99t3`Ir*|{}s;cu}U znb9iFruy;PvsY{Ui#7|Mmbcz#3)}g9)7lQ!d{WrCMeyCRZx;^ewImjn+I+aY<%74+ z&$&MZTta&{_pkcDz!wP^n&q+ z8LOA_|7|^Px4dWR+8seJF6w-lk;LyQ$9*Ws_QtMd*VPYgnNj^()8$0=^KI$JPATOp zc6~YJU#t)zzh|@5?*zlUTta2*yZ-JKXj|4}@%?1WkKi}A#a{`Px&NNK_11SDb(aeh z#2YyjTjs3TQK|ZM`@H>oGCgPhnz{4E^jte(v0|RwTYTjL6FJ^(Imc)FD!R}6eW*I$ z-&VWx>+1e>Z%nYf^K<8|{jsY;lj{H8w3hxEVxD{P9~W24gjJvCZp&GFuy&u(#$X;_ zb#LK~vy@CNk1Z4^5Nt9mjOki5;jzr5ZEXUJqU9Zq-1LvG-o&v)TWhv%xAe^i zzvitmjl81#_s#oO1Fqe3#Olrk)XkM#Wx6-$ciqa$gJnkrEv3Dlafwgf|0v_V){|Go zj^`dX2=|#Cc2bQ0e`;GpNyXm3L7P{(N4=Z#JlnClU1N^(>S=xNe)>EAe&sZG-|ot1 z)64JW{M6lj`cUa#9=o|pJl&bGS~u#>=kd#zt(@;;pOarN;ZtC)l6LuiM1T3#`!|E? z!?&u%7-=2%zc|HEe7EU3ou3j1UY= z*^?Fj!cHe{d$#oLJkMg2viO!@vzh-4RjQg7pSG*A zu8RJBcj_(sjj@c1Mpl!!J{?{Ca{kYm9c3Xx2V+i+X-7I^dcRtDTm2us=1r|rQm3wq7dd|Z)J#*Dd)5xT2 zuj;pi{hs%hOIcNO-pYNJf8(2C1i$X$m?I_D_2Q)4y(FtAg$W^tr@Z<#QGLyg_`7TC zI|Sv*-X&PgN!`nLV7p9OW_n(|uyef4^SIwLq8|TQX&*c5rS@UtEpzktZChJ+x@2mi zXV)?w%L%<*vlZ*i4_uQtwM4@y+4*6y&Ekc2B2u?kUU1tt&xu3zsqFdQJvVRtIH>X_ zJu5K(RIbogj)kv$e^xsFoZ0g1(WE9!F(8g4r+%>_Jq#K z4ep*Kb=5cU$yQ~zz=aY0Hvf;7+^&8eotjyFuJGl*t*%NTlUd)tc^jNlZR;0pJ!Rpo z%j}=m@|TNp&EFIuy=O_qGCSdYrMh1i-#npiG=KTVo4ejK@Gen#I(M4?q0c4GhlRea zdVB8uiL1wqu3niaH`hxm+Sl&0>%{BMNp~;nR_13fT%T(ws$ZefC$wr2*YX?R_#%bB z*>JB(?9cu-#r+P?^~a6p*>p5#8D0AH_jBib_m*5A%ZvxE38tOve-&Q4KHDp@d+W+5 z&t97|bM#kke7-+AWbx_U>E2mSX6pC3mr2TVAKIn&b*paBMX%qNH|escpFX9z&DNxW zJ5lD)`H$eDnB@jnb2xSAk9^J@>Q;T;kCT_qDkb9dY(-~pyY{Uvf!QkYDZV^Tjw^B2%7aF<>9$)%m`9tBR3Emo9 zg3}6c*$`SmWR z#=8Lt?7Zs(I9!+h$&wSjx+IaE>CMAeH@39A5!77FE}zx5VNbbTy#JA>F%zzHC}kPX zSbwzpYsb?K=j#jqi@n~)cHn#Ukq3K)zv-omRW?@wT$+#Ci^RE-_O4O{omdC-6hF}jchZwU0a!WW8IX?_vcOd zw`}hA2}bJ8`&UVD=dvBXr{&nNa@)HvZz>Bpx6N^go6EudQ{lebbx#isA*Z6RA7g53 ztaeqk#GA}r`^)P4wW1q7sxw#G?EYi@Cofq3W)^R=`(MwCuT}^+N!*&sbk<{oq2TIc zqM;MNFr*v)*na$v-N~OS9m_gjE6poyY7!JV%aDE9Uw{4k`*FYP{~rHtzIlD_(B*7o#>yVRd2t4|L((+aO&P+Cyu-sMR9ZQtkiiEA{L_jhhOjS z{@h-HjXj+Lt4tpCZwi0nV5(%dd*Q-0N9EqdYGrSf+jjJ_MCaq><}bg0I$2`Vx2WU9 zt^Ggmt#4{l{G{e>Eg}5L!`(r}blaQ8x!#vMkC$HZ5`E~10=jW4S!{-0EedqG~x`5mY znQJEu&xI`dbH+rjcLu9c%ewixrJBOa{I_lYzkiyrhLry4J5|3`f@T@%yZ=8N`)PUQ z->lax8~;`IXr2A&Rs5&IZH45+IaZUymw$RSB~4?OXvrOCE2Hy!x9L?HJ$t=u%cQ*# zE7X$?t~s)jL-8ty*wqxz-gnUn`Mihy?|rKaOaFhT?dPmVaSJ9Jo_DR{-S!YD2I4n~x4F9q*Ugv-2 zVIHe>%kS*@e(PQR-J%;cwsTi6Wqa)Z-Sph|o$@XmZ^fM3j&|&+ywtlP=J~F#*Z2+y z2AQjSADh}-{iI(@X!g!&KlYz@|5x1+y-;(pznt>zr{A)sPb<2AYh~QUGacR;P8*(n z_`Ue@#CKf5fxRajxox;E{_>gq$>-764M~x?zdG!0-usunjr(GhvxEBnJ9Q#&g94g8 zxQjUEXYSG6EN!&=-AAAZj=VhtJ_0M`MTaf+zFW1JlgSk(YlP7AG9_syY z++3|nV9|^1$}EZ@rswlk-?tL~S6rX|Pl)aH#RH24_S?z*saX2wZqVm92a~0$7H!>j zda9K0(qk^KAEvyJdtBHjY?!luUdGvgThBt3uLiVDJ)C$`Zm~(_JLB3<_iWFp#m&2) zB>DVF)PwzhAGWTYb7ScO36lwPWN$w$`jyQzdG6HzxAs4uzwAs)g}y_$yvTop>pQ-j zky*dp-a_TgrW+aWy)y5rJba!z)oo8^r~A^jSJNV{J!0Or_x`VGv*IQ@IE6|Jy{Z?x zk){`R@rcWcI;A&jr{2EuD|^NlaqWr!f0b{Z9l5aD@#}Y|8O{H*cb$5COTNQLO|$0N z{%0aeT>DEk|J^@x=YQO#=Nt!Xe;wqSpI`5|{OJeQ+&j;2b7fgA_dDYg+kyzvpYNN<6;wwhOmzyXKWc%qI?Q;YRW1A0 zj#4=hrxT@`e{M(eWG-EMQ}0@dRj`nm(ZTlUqR`~(GV>z}Qx7N|WPe)Url~C#@h0Q6 z(}dGHE&rd*`}=p7;kD)RXD*%n=049E2Zlzu&puC`d9tF?DDGYR(wls#5k0FmZ)Lk~B5`<; zw$%Lf9IqvJ28d=!-QKl((P`oNyTq?7&~Lf;_DI%Oe#@B99ld=jv!}cZ>s{G?&A#By zz8H>X&D)O^s=Vu-86DX6TCZ$#1)rjccyt%*W}$F*j?AOmJpG6m5dm!bztkki{UuTuPFiYBp2VTYR9Dn++ zJMwSuiIReJtz~m&UifXQyf?Uht9|pr_UY$}cJ>MEQeFE@PxR`>6*B}YMHQDw9$Yj_ zC)@D!%j&Rz+2>7s|9$)A+L#?TE9z-vvAy1Vp_q$J^Vh}1+?iv&qjYh-`(MQtpYENX zD-IQX@cw)|_~RxeGff|Xg&a=3YTKiO%D5K#c;3_0SX#B<-UDCha;qTT*J69^maQ%2 zSL;|O!R@`YzD)1W{pLH{{zq?O_W7Ijshx4zp746l&5PEaov>GE{`2!0veDNB4;Af5 zU-Uuw665q&r}V}4Z<{B--)8Hi056j=Q|B96D$}<;EAu*eZQ*rh?)g`w{=B_<@@`Uw zO;q3#HKirDINpdHnz<<@>ilcU zbMM}I`uB5Fe=N8C!>{5Gd3+prf7|MFQM*V(vDyOh??g57_RQPl;I*ji`>dA3%&hu zwc9Vvv3Bb)letk@{_VdEx1Ov|&By<@S5^Hf{P=X$yo!HkMQt~RRjj<#)9l5#NS@;t zyZw)Y2{k+H_GeglUG8&f6`gj?daH9^p30KY+fPH4pG`Qo=%L<1>1m6i9k~>xZkuf5 zJjfe-^2+mRo7d-0KmW7;O7k_QManFtkB{+QaXoi#WAd_GJ7+~>MZI|6f9ajNGLIeN zP7A(!UYEc2OWNg0R)2GO%%(c%X{E8OYvah8Q55JMI=k@p!!~VUhdD_gQ+fs0NW1PV zOwFqlvt=vu5_B@v)z=Wbdpf^R);n z-F(MkVPW3pUsZwj$v3!;XUN?BuwO7b;k97l?ZV8nJ-1}j>YC;`@*5c(5muIYx@%|4 z)iWu6*7H}!XGct2vB5KWzi`OBi^rar9)H?(>&U;O7Za)*Bv#6`{5!~BSKuVoyeVem z8vm*_~HcNN=pZ`Cjk&{o&BoJuWJJ|QZ6X>sR;*w*tKwm1gzwFam^j}Mr3xY>&_ z>59Oaj_~G#X&M`5bKUbl$?wz{%QpMCMd`DX)`F`{AA`csl*M?{)r1X_qSuxkp5Mnh zopqU4;N5%5nYWxG<(a249a*6`LvRgS_twJ7LcJnmot$#xFShdYHC73OHMiX7PW%#8F->;}1&YP;g%8di$;5N{L0-LpJOP4MwvDaJ2 zl_ME!_A2`1>fqI_*?I@TrX4AW`6lvI?I?SCvVA{SzvLa4TD@JW_9ym5<{uMS(%F#M zBiAHpGh^ABB_;1~-QaiK*77SpXZr7==d*7=E!I1@fF*B#jAC!at(|#eRm|PB zaVw+)FLUnDYu%&w)Z*w{U&SLv+YXo>nl!6VczJU6%!s`Q8{d|8C9uW!CY#wDiI_^V_Z2M;OBo7w+6;DaMymdga9`!P=O*-0f8h7cJLqXT7c5;<3lhep_wf ztB-$f^c|4QxY2rS-GSXq`AZjfD70`~HMr56^W@s6BaePX_&z@HZI^HK>rhjk=sT<9 z-=5$oes$;3z4FbkWEv%y6=xKQI_|aj`Qy`FL6|6+Mr}F5k?*X33(juhYM6`@FDs4b!&kn+06W_s)BVhdg)KXjHa$JO z%{`zcpiNnH>&vyLw%)z9^x8oK{V8uZ_K0#%Q%{~b^T@dh75$G^zPD#6y}|VM%;NPk-H7DN5rJkO^k&E&7A+_O*n15qjRG#hg-)Ez2x0Fhql znV`j~Ud2zpQcR5H&Yn@-{xgq!#3jjFw>@WTvf9Ucrh7TER4#E>kTB?3sKB!B=eM2F z>(AX!%-Fqs+w)x(;hg!;CjXqZDY$3a)dj0QPdh76pPm1ozq#?*&y{z6p1hN@N+euL z=J(YufmMkcUeElXepC^_<~BnQmSt~lZd{um^TR^++_xjFUIJMrt#^aI+cr+_HAR1Khu`Nf+s={0=+k{V>`?zVwdXFSDY>NXIO?cU{^s`L}+lrvxwC&G_H~Rr^)iQBhs= z-2T#c*PLDzF7I||3Ro+6M^EMRR*!X3=dK?L_05?z=krxr?+aq;QWxKztIFVcvhncU z2#M(0+J|L9C(CznT;X|GU-RwUqho&(IV8UO@h6q&w^+VxXT5l%^W;+P$=~B=?LBQg zH?>hpti1g58FugM-KCOSzFkq45Qw)IkhwgkFL!_O!^Il|)+vA99Q*6vwVCnvD)%lr zX~16TD8SRP{yBeTSbgok&)3i0c~`<&lL3gJ{crb@2%DN)El0b zzrXHT@w&q?0b4cy{QVpLK2LXxj=-%)M-B7YZtb4FeAT6E-j~bwm3_P1w`W01z|O2U z&FuR6@6SkyG3S0c%;+Fi(0VC&(FgKjKHolhXOmo(t`nH~Ytvi&wYaX~}f7|FK9}VnWDtj%nNU ze09#MU$2cyxctPv=Eo;>?eJOt%NDR~`NryQps-R;(75xgcJTMVJDfQensL9JU;DAw zN43t0e>0Pdy};f(k^h;@+!}K0avz3ytoiw&>5}>M_@6Hxn%-?u?q@K3!=30C%y&Hc zx!t^ucfV$~?%V(6*YnlWzv&8W5fj*7dZyt=-`}G2G?cz7zKd&Mx!8JHf zZ~r3cf>O0F3hwi5Sl-s|X@5LX_I$IJ%=CSm3+r^P8QT~;%=isGURCf5dmSv6h&k(X z|E|^b!<`yij;?e`m~iEzoLlqMZ(CXJlOha!PbTs3BDYH5%=eRv~v;JA|@cahEtKL+NR|{Qxtc{z9nn-K6vywzj^{I zTSu9ec@iaol2Y{ z*Q48>%-g;xG*dse8O-BbB4uOYYT8q=Zo zvjmP@7hJTU?ewZgJ9YLL>@;k$<=FDZLs4N`sZUF$;rw-RAA5rK8127fHHCN6fd%ZA zuR!r?mQ?sT=JKQ4w-dEud|FN!^f>T0RZZQ-_O|xJ!fQM_d2@2}TV%4&su*$bFbn*> z5y{`%D6ngD;k`WRt;a=X`oG=S!yCoTab@+~uNNfP<;AkSmI>wCOZ2&ac3j99#odwT zETXW|S>8-HPu2KpU39R)g`U%<7or?wj6vb^|AOj|i|;~y%Zkn@I)2FYLX<;^*dhkc zpYBgq8Q$gDGJj&5swfL<$2lhv1|C8JZkE%rXCF z8-EmcNBZ@a<%{#2dk<92F<1V?mZ7U~LE-YXxGiFv_L}|BN^*YkHSn$Dg4Fh&2JXbF z1_PaKelc2gPGvL5-&Z|Je=_x4cJ zm;b)yRDb7by>R+-Hq&*MwX7_!>e6jZjv4dEHs!C^6UkcmtvNAdUH$j1=aY+Mw}=U_ z%U`PhbG)8s(yM=omy;^5#d*BnBF}St@zTwYt9hICuP$wtT)tqdzR{yj!KNj<>Lacn zH9u!}U`OnhrbPh(8T01f@oahJJ9(`+Q(w1Zc6^(R?!|~%BW4Uaf{*@CKcnWA;-`U%v@n4~*7>U{56waq8u1uZ_`zW#omXZrt7&sJL> zJ<%z!TV%uYOJ7%})Ta5&^~y>XjODp;r7@(n;zUP#Pf3V+$DKXW`BD=E9yR{xN@iQe z8>JJ>|9EUxyoY7EE6F z_gc2u(zDB?vUfX19Q~5u%dzeG|L$$h^#%VooiLA|6?=T{jfazGa+bN?vzdHuzUOmU z@oe8bTj||j3#ux$Z$_E(MFa@m{Bcft_WONX)VZfUpW1VNO2LJ$6KZRcYy^33#GMyh zy6a1M{5}_sub1v5?<%&o$(Yb}V~^SP;@rIBn_k|XR8(%eca!w(Q?1sfCz7uy$>i7> z+Fx7}u$|Rp)!B532_g0ZJF{M_x2sBCFY@!))8CsGlv}mg#77*P={arrPuIq{Y8Kwm5k_&}rN(^srXos=rUFj=-_>gL`1{}p}P?EZMxyVLiNZT8bzb#CeE&o5u) ztTGeJEV29|t8+8x!Q<+Scbgcbp8lNh@89?R{M)XFw>*9n6dQL>uAI|UQvdgNy|NGk zHN}%VOoA=UBLymNmuhx7ZEKblm$iBqJ43Jj``P37Ym@(;<-YmzW0pmRk;%(WRx7=& z8`b|ldG=#1d*D{bX17Yalmp+`nlmKstQXhMeY$vm`QLXTi#mP?nC6p}y>ep{x5}{T7A8i@HPe zGM#@u@cZ*{+8XJCP1XIEu07bWVBYB?Wd+M*w5~M8uk&5Hc&hoi^>gQ+V5<gcAz(B$u3hpOCeo#}dAeaX-6f=T9vy?*jW20^^{_UKAa58b$?>$}+{rTlX$+}w|M zwtlR!ih3GR{bg;S`3v^h3!}X+TCbj1)4E+YVBR`8BZYkrmA0r=*Bk#$uog`?J7bYv z&vQNh^h+0K9hhBP^spp&l~i@IVP&%6#;KD_n1z{iZ#TE|bmWT&^fjBb2Y)@`X7*{d z{(062W0jZbms+>$t@S^$YH>nuXz$*gGxijk@0=+*TkY+x4M$!`HZdNSFm*YtuvKk) zaDd$obMc8=rk{Tk7k|UE#Z>dcY=bIyzVkkwKb|=LxfYaT{eS93{%I0>oeUBr7WWj$ zgskw~zoYisV)o$Tm6t*mP3l^ql<(Cf$!V5)Fr$9fv5&d^0a?wp8zg^yh)XIB*Sj8h zxytC5WAS&HgAGgkSQg!Tus_DPcIT{H|F3&&_;_yW+3kAyuBm&&4=X#K*i^VuEaDc& z-96UZ_NYqx@11)=?60$d!b;&TjjOHmYiiz|zWU_)`kdGqdPh>`ruNS)apPDjU9wFl zC#6~2`qZnwJ<$TQ)nb;~DX=h4vby+g&exoZ?Giq&S7)YtJyTJcxJhIhPhX*iPr&UP z$**0fxlVuer@8mT+3IBe?IMS*EZ#Y8I^7_^VGEeut6K&UwPvyV!`MAbdY^A^Y z>z5g}O6Hc=5;K|v4o!KzOJvc6$3Z4fg0ST%wx*y|{McSaWr+z_GM!9(?--qU zzQ1V2eg0#6105cKcG++^@W>i=i63&9ATFRU!lc*ID8~|2c7kIE2ctm3J!iKB0eOXl zCWDxb$pM-U3`sj|Ioggfuz>f=fcYFelbAr&(LT(UG4?*E)uU?IR=8nQGAXA!ZgIfi`Vn(4HO#p6h!I zP1x}55<=TU#Nrs|z>u_pgU2!Mg(G;c5wZo~O-LEKpq)JL_>Vz03!RnDTguF$(AIN6 z0ptl0{T4<~MkWDf=L9sPq1-kO9gusDcnCZyTGXOap^U^^r`_ zJ{kdsIT +#include +#include +#include +#include + +int main(int argc, char* const argv[]) + +try { + if (argc != 3) { + std::cout << "Usage: " << argv[0] << " file key\n"; + return 1; + } + + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]); + assert(image.get() != 0); + image->readMetadata(); + + try { + Exiv2::ExifData &exifData = image->exifData(); + const Exiv2::Value &value = exifData[argv[2]].value(); + std::cout << value; + } catch (Exiv2::AnyError &e) {} + + try { + Exiv2::IptcData &iptcData = image->iptcData(); + const Exiv2::Value &value = iptcData[argv[2]].value(); + std::cout << value; + } catch (Exiv2::AnyError &e) {} + + try { + Exiv2::XmpData &xmpData = image->xmpData(); + const Exiv2::Value &value = xmpData[argv[2]].value(); + std::cout << value; + } catch (Exiv2::AnyError &e) {} + + return 0; +} catch (Exiv2::AnyError& e) { + std::cout << "Caught Exiv2 exception '" << e << "'\n"; + return -1; +} diff --git a/taglib-sharp/examples/listData.cpp b/taglib-sharp/examples/listData.cpp new file mode 100644 index 0000000..50283d2 --- /dev/null +++ b/taglib-sharp/examples/listData.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +int main(int argc, char* const argv[]) + +try { + if (argc != 3) { + std::cout << "Usage: " << argv[0] << " mode file\n"; + return 1; + } + + Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[2]); + assert(image.get() != 0); + image->readMetadata(); + + if (argv[1][0] == 'e') { + Exiv2::ExifData &exifData = image->exifData(); + if (!exifData.empty()) { + Exiv2::ExifData::const_iterator exifEnd = exifData.end(); + for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != exifEnd; ++i) { + std::cout << i->tagName() << "\t" + << "0x" << std::setw(4) << std::setfill('0') << std::right + << std::hex << i->tag() << std::dec << "\t" + << i->groupName() << "\t" + << i->typeName() << "\t" + << i->count() << "\t" + << "\n"; + } + } + } + + if (argv[1][0] == 'i') { + Exiv2::IptcData &iptcData = image->iptcData(); + if (!iptcData.empty()) { + Exiv2::IptcData::const_iterator iptcEnd = iptcData.end(); + for (Exiv2::IptcData::const_iterator i = iptcData.begin(); i != iptcEnd; ++i) { + std::cout << i->key() << "\n"; + } + } + } + + if (argv[1][0] == 'x') { + Exiv2::XmpData &xmpData = image->xmpData(); + if (!xmpData.empty()) { + Exiv2::XmpData::const_iterator xmpEnd = xmpData.end(); + for (Exiv2::XmpData::const_iterator i = xmpData.begin(); i != xmpEnd; ++i) { + std::cout << i->key() << "\t" + << i->typeName() << "\t" + << i->count() << "\t" + << "\n"; + } + } + } + + return 0; +} catch (Exiv2::AnyError& e) { + std::cout << "Caught Exiv2 exception '" << e << "'\n"; + return -1; +} diff --git a/taglib-sharp/src/AssemblyInfo.cs.in b/taglib-sharp/src/AssemblyInfo.cs.in new file mode 100644 index 0000000..4b4cf12 --- /dev/null +++ b/taglib-sharp/src/AssemblyInfo.cs.in @@ -0,0 +1,36 @@ +// +// AssemblyInfo.cs.in: Contains flags to use for the assembly. +// +// Author: +// Brian Nickel (brian.nickel@gmail.com) +// +// Copyright (C) 2006-2007 Brian Nickel +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly:AssemblyVersion("@ASSEMBLY_VERSION@")] +[assembly:AssemblyTitle ("TagLib#")] +[assembly:AssemblyDescription ("A library for reading and writing audio metatags.")] +[assembly:AssemblyCopyright ("Copyright (c) 2006-2007 Brian Nickel. Copyright (c) 2009-2010 Other contributors")] +[assembly:AssemblyCompany ("")] +[assembly:AssemblyDelaySign(false)] +[assembly:AssemblyKeyFile("taglib-sharp.snk")] +[assembly:CLSCompliant(false)] diff --git a/taglib-sharp/src/Makefile.am b/taglib-sharp/src/Makefile.am new file mode 100644 index 0000000..17c6340 --- /dev/null +++ b/taglib-sharp/src/Makefile.am @@ -0,0 +1,69 @@ +POLICIES = policy.2.0.$(ASSEMBLY_NAME).dll +ASSEMBLY = $(ASSEMBLY_NAME).dll +TARGET = $(ASSEMBLY) + +if BUILD_DOCS +DOCFILE = $(ASSEMBLY).xml +DOCFLAGS = /doc:$(DOCFILE) /warn:4 +else +DOCFILE = +DOCFLAGS = +endif + +if HAVE_SHARPZIPLIB + SHARPZIPLIB_FLAGS = -r:ICSharpCode.SharpZipLib.dll -define:HAVE_SHARPZIPLIB +endif + +CSC = $(MCS) $(MCS_FLAGS) $(CSFLAGS) + +include $(srcdir)/TagLib/TagLib.sources + +taglib-sharp.snk: $(top_srcdir)/taglib-sharp.snk + cp $(top_srcdir)/taglib-sharp.snk . + +taglib_sources_in = AssemblyInfo.cs.in +taglib_generated_sources = $(taglib_sources_in:.in=) +taglib_policy_names = $(POLICIES:.dll=) +taglib_policy_configs = $(POLICIES:.dll=.config) +taglib_policy_configs_in = $(POLICIES:.dll=.config.in) + +$(ASSEMBLY): $(TAGLIB_CSFILES) $(taglib_generated_sources) taglib-sharp.snk + $(CSC) /target:library $(LIBFLAGS) $(SHARPZIPLIB_FLAGS) $(DOCFLAGS) /define:SIGN /out:$@ $(TAGLIB_CSFILES) $(taglib_generated_sources) + +policy.%.$(ASSEMBLY_NAME).dll: policy.%.$(ASSEMBLY_NAME).config + $(AL) /link:$< /out:$@ /keyfile:taglib-sharp.snk + +all: $(ASSEMBLY) $(POLICIES) + +EXTRA_DIST = $(TAGLIB_CSFILES) $(taglib_sources_in) $(taglib_policy_configs_in) taglib-sharp.csproj +DISTCLEANFILES = *.pidb +CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb $(POLICIES) taglib-sharp.snk $(DOCFILE) +MAINTAINERCLEANFILES = Makefile.in + +install-data-local: + @if test -n '$(TARGET)'; then \ + echo "$(GACUTIL) /i $(ASSEMBLY) /f $(GACUTIL_FLAGS)"; \ + $(GACUTIL) /i $(ASSEMBLY) /f $(GACUTIL_FLAGS) || exit 1; \ + for POLICY in $(POLICIES); \ + do echo "$(GACUTIL) /i $$POLICY /f $(GACUTIL_POLICY_FLAGS)"; \ + $(GACUTIL) /i $$POLICY /f $(GACUTIL_POLICY_FLAGS) || exit 1; \ + done \ + fi + +uninstall-local: + @if test -n '$(TARGET)'; then \ + echo "$(GACUTIL) /u $(ASSEMBLY_NAME) $(GACUTIL_FLAGS)"; \ + $(GACUTIL) /u $(ASSEMBLY_NAME) $(GACUTIL_FLAGS) || exit 1; \ + for POLICY in $(taglib_policy_names); \ + do echo "$(GACUTIL) /u $$POLICY /f $(GACUTIL_POLICY_FLAGS)"; \ + $(GACUTIL) /u $$POLICY /f $(GACUTIL_POLICY_FLAGS) || exit 1; \ + done \ + fi + +distwin: + mkdir -p $(srcdir)/../$(WINDIR)/Libraries + cp $(srcdir)/*.dll $(srcdir)/*.config $(srcdir)/../$(WINDIR)/Libraries + for FILE in $(TAGLIB_CSFILES) $(taglib_generated_sources); \ + do mkdir -p $(srcdir)/../$(WINDIR)/src/`dirname $$FILE`; \ + cp $$FILE $(srcdir)/../$(WINDIR)/src/`dirname $$FILE`; \ + done diff --git a/taglib-sharp/src/TagLib/Aac/AudioHeader.cs b/taglib-sharp/src/TagLib/Aac/AudioHeader.cs new file mode 100644 index 0000000..336fe8d --- /dev/null +++ b/taglib-sharp/src/TagLib/Aac/AudioHeader.cs @@ -0,0 +1,433 @@ +// +// AudioHeader.cs: Provides information about an ADTS AAC audio stream. +// +// Copyright (C) 2009 Patrick Dehne +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; + +namespace TagLib.Aac +{ + /// + /// This structure implements and provides + /// information about an ADTS AAC audio stream. + /// + public class AudioHeader : IAudioCodec + { + #region Private Static Value Arrays + + /// + /// Contains a sample rate table for ADTS AAC audio. + /// + private static readonly int[] sample_rates = new int[13] { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000, 7350 + }; + + /// + /// Contains a channel table for ADTS AAC audio. + /// + private static readonly int[] channels = new int[8] { + 0, 1, 2, 3, 4, 5, 6, 8 + }; + + #endregion + + + + #region Private Properties + + /// + /// Contains the audio stream length. + /// + private long stream_length; + + /// + /// Contains the audio stream duration. + /// + private TimeSpan duration; + + /// + /// Contains the number of channels in the audio + /// + private int audiochannels; + + /// + /// Contains the bitrate of the audio stream + /// + private int audiobitrate; + + /// + /// Contains the samplerate of the audio stream + /// + private int audiosamplerate; + + #endregion + + + + #region Public Fields + + /// + /// An empty and unset header. + /// + public static readonly AudioHeader Unknown = + new AudioHeader(); + + #endregion + + + + #region Constructors + + /// + /// Constructs and initializes a new empty instance of + /// + private AudioHeader() + { + this.stream_length = 0; + this.duration = TimeSpan.Zero; + this.audiochannels = 0; + this.audiobitrate = 0; + this.audiosamplerate = 0; + } + + /// + /// Constructs and initializes a new instance of by populating it with specified + /// values. + /// + /// + /// A value indicating the number + /// of channels in the audio stream + /// + /// + /// A value indicating the bitrate + /// of the audio stream + /// + /// + /// A value indicating the samplerate + /// of the audio stream + /// + /// + /// A value indicating the number + /// of samples in the audio stream + /// + /// + /// A value indicating the number + /// of frames in the audio stream + /// + private AudioHeader(int channels, int bitrate, + int samplerate, int numberofsamples, int numberofframes) + { + this.duration = TimeSpan.Zero; + this.stream_length = 0; + this.audiochannels = channels; + this.audiobitrate = bitrate; + this.audiosamplerate = samplerate; + } + + #endregion + + + + #region Public Properties + + /// + /// Gets a text description of the media represented by the + /// current instance. + /// + /// + /// A object containing a description + /// of the media represented by the current instance. + /// + public string Description + { + get + { + return "ADTS AAC"; + } + } + + /// + /// Gets the types of media represented by the current + /// instance. + /// + /// + /// Always . + /// + public MediaTypes MediaTypes + { + get { return MediaTypes.Audio; } + } + + /// + /// Gets the duration of the media represented by the current + /// instance. + /// + /// + /// A containing the duration of the + /// media represented by the current instance. + /// + /// + /// If has not been called, this + /// value will not be correct. + /// + public TimeSpan Duration + { + get + { + return duration; + } + } + + /// + /// Gets the bitrate of the audio represented by the current + /// instance. + /// + /// + /// A value containing a bitrate of the + /// audio represented by the current instance. + /// + public int AudioBitrate + { + get + { + return audiobitrate; + } + } + + /// + /// Gets the sample rate of the audio represented by the + /// current instance. + /// + /// + /// A value containing the sample rate of + /// the audio represented by the current instance. + /// + public int AudioSampleRate + { + get + { + return audiosamplerate; + } + } + + /// + /// Gets the number of channels in the audio represented by + /// the current instance. + /// + /// + /// A value containing the number of + /// channels in the audio represented by the current + /// instance. + /// + public int AudioChannels + { + get { return audiochannels; } + } + + #endregion + + + + #region Public Methods + + /// + /// Sets the length of the audio stream represented by the + /// current instance. + /// + /// + /// A value specifying the length in + /// bytes of the audio stream represented by the current + /// instance. + /// + /// + /// The this value has been set, will + /// return an incorrect value. + /// + public void SetStreamLength(long streamLength) + { + this.stream_length = streamLength; + duration = TimeSpan.FromSeconds(((double)this.stream_length) * 8.0 / ((double)this.audiobitrate)); + } + + #endregion + + + + #region Public Static Methods + + /// + /// Searches for an audio header in a starting at a specified position and searching through + /// a specified number of bytes. + /// + /// + /// A object in which the found + /// header will be stored. + /// + /// + /// A object to search. + /// + /// + /// A value specifying the seek position + /// in at which to start searching. + /// + /// + /// A value specifying the maximum number + /// of bytes to search before aborting. + /// + /// + /// A value indicating whether or not a + /// header was found. + /// + /// + /// is . + /// + public static bool Find(out AudioHeader header, + TagLib.File file, long position, int length) + { + if (file == null) + throw new ArgumentNullException("file"); + + long end = position + length; + header = AudioHeader.Unknown; + + file.Seek(position); + + ByteVector buffer = file.ReadBlock(3); + + if (buffer.Count < 3) + return false; + + do + { + file.Seek(position + 3); + buffer = buffer.Mid(buffer.Count - 3); + buffer.Add(file.ReadBlock( + (int)File.BufferSize)); + + for (int i = 0; i < buffer.Count - 3 && + (length < 0 || position + i < end); i++) + if (buffer[i] == 0xFF + && buffer[i+1] >= 0xF0) // 0xFFF + try + { + BitStream bits = new BitStream(buffer.Mid(i, 7).Data); + + // 12 bits sync header + bits.ReadInt32(12); + + // 1 bit mpeg 2/4 + bits.ReadInt32(1); + + // 2 bits layer + bits.ReadInt32(2); + + // 1 bit protection absent + bits.ReadInt32(1); + + // 2 bits profile object type + bits.ReadInt32(2); + + // 4 bits sampling frequency index + int samplerateindex = bits.ReadInt32(4); + if(samplerateindex >= sample_rates.Length) + return false; + long samplerate = sample_rates[samplerateindex]; + + // 1 bit private bit + bits.ReadInt32(1); + + // 3 bits channel configuration + int channelconfigindex = bits.ReadInt32(3); + if (channelconfigindex >= channels.Length) + return false; + + // 4 copyright bits + bits.ReadInt32(4); + + // 13 bits frame length + long framelength = bits.ReadInt32(13); // double check framelength + if (framelength < 7) + return false; + + // 11 bits buffer fullness + bits.ReadInt32(11); + + // 2 bits number of raw data blocks in frame + int numberofframes = bits.ReadInt32(2) + 1; + + long numberofsamples = numberofframes * 1024; + long bitrate = framelength * 8 * samplerate / numberofsamples; + + header = new AudioHeader(channels[channelconfigindex], + (int)bitrate, + (int)samplerate, + (int)numberofsamples, + numberofframes); + + return true; + } + catch (CorruptFileException) + { + } + + position += File.BufferSize; + } while (buffer.Count > 3 && (length < 0 || position < end)); + + return false; + } + + /// + /// Searches for an audio header in a starting at a specified position and searching to the + /// end of the file. + /// + /// + /// A object in which the found + /// header will be stored. + /// + /// + /// A object to search. + /// + /// + /// A value specifying the seek position + /// in at which to start searching. + /// + /// + /// A value indicating whether or not a + /// header was found. + /// + /// + /// Searching to the end of the file can be very, very slow + /// especially for corrupt or non-MPEG files. It is + /// recommended to use + /// instead. + /// + public static bool Find(out AudioHeader header, + TagLib.File file, long position) + { + return Find(out header, file, position, -1); + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Aac/BitStream.cs b/taglib-sharp/src/TagLib/Aac/BitStream.cs new file mode 100644 index 0000000..0279867 --- /dev/null +++ b/taglib-sharp/src/TagLib/Aac/BitStream.cs @@ -0,0 +1,110 @@ +// +// BitStream.cs: Helper to read bits from a byte array. +// +// Copyright (C) 2009 Patrick Dehne +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.Diagnostics; + +namespace TagLib.Aac +{ + /// + /// This class is used to help reading arbitary number of bits from + /// a fixed array of bytes + /// + public class BitStream + { + #region Private Fields + + private BitArray bits; + private int bitindex; + + #endregion + + + + #region Constructors + + /// + /// Construct a new . + /// + /// + /// A , must be 7 bytes long. + /// + public BitStream(byte[] buffer) + { + Debug.Assert(buffer.Length == 7, "buffer.Length == 7", "buffer size invalid"); + + if (buffer.Length != 7) + throw new ArgumentException("Buffer size must be 7 bytes"); + + // Reverse bits + bits = new BitArray(buffer.Length * 8); + for (int i = 0; i < buffer.Length; i++) + { + for (int y = 0; y < 8; y++) + { + bits[i * 8 + y] = ((buffer[i] & (1 << (7 - y))) > 0); + } + } + + bitindex = 0; + } + + #endregion + + + + #region Public Methods + + /// + /// Reads an Int32 from the bitstream + /// + /// + /// A value containing the number + /// of bits to read from the bitstream + /// + public int ReadInt32(int numberOfBits) + { + Debug.Assert(numberOfBits > 0, "numberOfBits < 1"); + Debug.Assert(numberOfBits <= 32, "numberOfBits <= 32"); + + if (numberOfBits <= 0) + throw new ArgumentException("Number of bits to read must be >= 1"); + + if (numberOfBits > 32) + throw new ArgumentException("Number of bits to read must be <= 32"); + + int value = 0; + int start = bitindex + numberOfBits - 1; + for (int i = 0; i < numberOfBits; i++) + { + value += bits[start] ? (1 << i) : 0; + bitindex++; + start--; + } + + return value; + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Aac/File.cs b/taglib-sharp/src/TagLib/Aac/File.cs new file mode 100644 index 0000000..d9d14eb --- /dev/null +++ b/taglib-sharp/src/TagLib/Aac/File.cs @@ -0,0 +1,282 @@ +// +// File.cs: Provides tagging and properties support for ADTS AAC files +// +// Here is the ADTS Header description used for implementation: +// http://www.hydrogenaudio.org/forums/lofiversion/index.php/t21617.html +// +// Copyright (C) 2009 Patrick Dehne +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace TagLib.Aac +{ + /// + /// This class extends to + /// provide tagging and properties support for ADTS AAC audio files. + /// + /// + /// A and will be added automatically to any + /// file that doesn't contain one. This change does not effect the + /// file until it is saved and can be reversed using the following + /// method: + /// file.RemoveTags (file.TagTypes & ~file.TagTypesOnDisk); + /// + [SupportedMimeType("taglib/aac", "aac")] + [SupportedMimeType("audio/aac")] + public class File : TagLib.NonContainer.File + { + #region Private Fields + + /// + /// Contains the first audio header. + /// + private AudioHeader first_header; + + #endregion + + + + #region Constructors + + /// + /// Constructs and initializes a new instance of for a specified path in the local + /// file system and specified read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File (string path, ReadStyle propertiesStyle) + : base (path, propertiesStyle) + { + } + + /// + /// Constructs and initializes a new instance of for a specified path in the local + /// file system with an average read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// is . + /// + public File (string path) : base (path) + { + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction and + /// specified read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File (File.IFileAbstraction abstraction, + ReadStyle propertiesStyle) + : base (abstraction, propertiesStyle) + { + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction with + /// an average read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// is . + /// + public File (File.IFileAbstraction abstraction) + : base (abstraction) + { + } + + #endregion + + + + #region Public Methods + + /// + /// Gets a tag of a specified type from the current instance, + /// optionally creating a new tag if possible. + /// + /// + /// A value indicating the + /// type of tag to read. + /// + /// + /// A value specifying whether or not to + /// try and create the tag if one is not found. + /// + /// + /// A object containing the tag that was + /// found in or added to the current instance. If no + /// matching tag was found and none was created, is returned. + /// + /// + /// If a is added to the + /// current instance, it will be placed at the start of the + /// file. On the other hand, + /// will be added to the end of + /// the file. All other tag types will be ignored. + /// + public override TagLib.Tag GetTag (TagTypes type, bool create) + { + Tag t = (Tag as TagLib.NonContainer.Tag).GetTag (type); + + if (t != null || !create) + return t; + + switch (type) + { + case TagTypes.Id3v1: + return EndTag.AddTag (type, Tag); + + case TagTypes.Id3v2: + return StartTag.AddTag (type, Tag); + + case TagTypes.Ape: + return EndTag.AddTag (type, Tag); + + default: + return null; + } + } + + #endregion + + + + #region Protected Methods + + /// + /// Reads format specific information at the start of the + /// file. + /// + /// + /// A value containing the seek position + /// at which the tags end and the media data begins. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// This method only searches for an audio header in the + /// first 16384 bytes of code to avoid searching forever in + /// corrupt files. + /// + protected override void ReadStart (long start, + ReadStyle propertiesStyle) + { + // Only check the first 16 bytes so we're not stuck + // reading a bad file forever. + if (propertiesStyle != ReadStyle.None && + !AudioHeader.Find (out first_header, this, + start, 0x4000)) + throw new CorruptFileException ( + "ADTS audio header not found."); + } + + /// + /// Reads format specific information at the end of the + /// file. + /// + /// + /// A value containing the seek position + /// at which the media data ends and the tags begin. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + protected override void ReadEnd (long end, + ReadStyle propertiesStyle) + { + // Make sure we have ID3v1 and ID3v2 tags. + GetTag (TagTypes.Id3v1, true); + GetTag (TagTypes.Id3v2, true); + } + + /// + /// Reads the audio properties from the file represented by + /// the current instance. + /// + /// + /// A value containing the seek position + /// at which the tags end and the media data begins. + /// + /// + /// A value containing the seek position + /// at which the media data ends and the tags begin. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// A object describing the + /// media properties of the file represented by the current + /// instance. + /// + protected override Properties ReadProperties (long start, + long end, + ReadStyle propertiesStyle) + { + first_header.SetStreamLength (end - start); + return new Properties (TimeSpan.Zero, first_header); + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Aiff/File.cs b/taglib-sharp/src/TagLib/Aiff/File.cs new file mode 100644 index 0000000..55bd63e --- /dev/null +++ b/taglib-sharp/src/TagLib/Aiff/File.cs @@ -0,0 +1,481 @@ +// +// File.cs: Provides tagging and properties support for Apple's AIFF +// files. +// +// Author: +// Helmut Wahrmann +// +// Copyright (C) 2009 Helmut Wahrmann +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; +using TagLib.Id3v2; + +namespace TagLib.Aiff +{ + /// + /// This class extends to provide + /// support for reading and writing tags and properties for files + /// using the AIFF file format. + /// + [SupportedMimeType("taglib/aif", "aif")] + [SupportedMimeType("audio/x-aiff")] + [SupportedMimeType("audio/aiff")] + [SupportedMimeType("sound/aiff")] + [SupportedMimeType("application/x-aiff")] + public class File : TagLib.File + { + #region Private Fields + + /// + /// Contains the address of the AIFF header block. + /// + private ByteVector header_block = null; + + /// + /// Contains the Id3v2 tag. + /// + private Id3v2.Tag tag = null; + + /// + /// Contains the media properties. + /// + private Properties properties = null; + + #endregion + + #region Public Static Fields + + /// + /// The identifier used to recognize a AIFF files. + /// + /// + /// "FORM" + /// + public static readonly ReadOnlyByteVector FileIdentifier = "FORM"; + + /// + /// The identifier used to recognize a AIFF Common chunk. + /// + /// + /// "COMM" + /// + public static readonly ReadOnlyByteVector CommIdentifier = "COMM"; + + /// + /// The identifier used to recognize a AIFF Sound Data Chunk. + /// + /// + /// "SSND" + /// + public static readonly ReadOnlyByteVector SoundIdentifier = "SSND"; + + /// + /// The identifier used to recognize a AIFF ID3 chunk. + /// + /// + /// "ID3 " + /// + public static readonly ReadOnlyByteVector ID3Identifier = "ID3 "; + + #endregion + + #region Public Constructors + + /// + /// Constructs and initializes a new instance of for a specified path in the local file + /// system and specified read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File(string path, ReadStyle propertiesStyle) + : this(new File.LocalFileAbstraction(path), + propertiesStyle) + { + } + + /// + /// Constructs and initializes a new instance of for a specified path in the local file + /// system with an average read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// is . + /// + public File(string path) + : this(path, ReadStyle.Average) + { + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction and + /// specified read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File(File.IFileAbstraction abstraction, + ReadStyle propertiesStyle) + : base(abstraction) + { + Mode = AccessMode.Read; + try + { + uint aiff_size; + long tag_start, tag_end; + Read(true, propertiesStyle, out aiff_size, + out tag_start, out tag_end); + } + finally + { + Mode = AccessMode.Closed; + } + + TagTypesOnDisk = TagTypes; + + GetTag(TagTypes.Id3v2, true); + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction with an + /// average read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// is . + /// + public File(File.IFileAbstraction abstraction) + : this(abstraction, ReadStyle.Average) + { + } + + #endregion + + #region Public Properties + + /// + /// Gets a abstract representation of all tags stored in the + /// current instance. + /// + /// + /// A object representing all tags + /// stored in the current instance. + /// + public override Tag Tag + { + get { return tag; } + } + + /// + /// Gets the media properties of the file represented by the + /// current instance. + /// + /// + /// A object containing the + /// media properties of the file represented by the current + /// instance. + /// + public override TagLib.Properties Properties + { + get { return properties; } + } + + #endregion + + #region Public Methods + + /// + /// Saves the changes made in the current instance to the + /// file it represents. + /// + public override void Save() + { + Mode = AccessMode.Write; + try + { + ByteVector data = new ByteVector(); + + // Add the ID3 chunk and ID32 tag to the vector + if (tag != null) + { + ByteVector tag_data = tag.Render(); + if (tag_data.Count > 10) + { + if (tag_data.Count%2 == 1) + tag_data.Add(0); + + data.Add("ID3 "); + data.Add(ByteVector.FromUInt( + (uint) tag_data.Count, + true)); + data.Add(tag_data); + } + } + + // Read the file to determine the current AIFF + // size and the area tagging is in. + uint aiff_size; + long tag_start, tag_end; + Read(false, ReadStyle.None, out aiff_size, + out tag_start, out tag_end); + + // If tagging info cannot be found, place it at + // the end of the file. + if (tag_start < 12 || tag_end < tag_start) + tag_start = tag_end = Length; + + int length = (int) (tag_end - tag_start + 8); + + // Insert the tagging data. + Insert(data, tag_start, length); + + // If the data size changed update the aiff size. + if (data.Count - length != 0 && + tag_start <= aiff_size) + { + // Depending, if a Tag has been added or removed, + // the length needs to be adjusted + if (tag == null) + { + length -= 16; + } + else + { + length -= 8; + } + + Insert(ByteVector.FromUInt((uint) + (aiff_size + data.Count - length), + true), 4, 4); + } + // Update the tag types. + TagTypesOnDisk = TagTypes; + } + finally + { + Mode = AccessMode.Closed; + } + } + + /// + /// Removes a set of tag types from the current instance. + /// + /// + /// A bitwise combined value + /// containing tag types to be removed from the file. + /// + /// + /// In order to remove all tags from a file, pass as . + /// + public override void RemoveTags(TagTypes types) + { + if (types == TagLib.TagTypes.Id3v2 || + types == TagLib.TagTypes.AllTags) + { + tag = null; + } + } + + /// + /// Gets a tag of a specified type from the current instance, + /// optionally creating a new tag if possible. + /// + /// + /// A value indicating the + /// type of tag to read. + /// + /// + /// A value specifying whether or not to + /// try and create the tag if one is not found. + /// + /// + /// A object containing the tag that was + /// found in or added to the current instance. If no + /// matching tag was found and none was created, is returned. + /// + public override TagLib.Tag GetTag(TagTypes type, bool create) + { + TagLib.Tag id32_tag = null; + + switch (type) + { + case TagTypes.Id3v2: + if (tag == null && create) + { + tag = new Id3v2.Tag(); + tag.Version = 2; + } + + id32_tag = tag; + break; + } + + return id32_tag; + } + + #endregion + + #region Private Methods + + /// + /// Reads the contents of the current instance determining + /// the size of the riff data, the area the tagging is in, + /// and optionally reading in the tags and media properties. + /// + /// + /// If , any tags found will be read + /// into the current instance. + /// + /// + /// A value specifying how the media + /// data is to be read into the current instance. + /// + /// + /// A value reference to be filled with + /// the size of the RIFF data as read from the file. + /// + /// + /// A value reference to be filled with + /// the absolute seek position at which the tagging data + /// starts. + /// + /// + /// A value reference to be filled with + /// the absolute seek position at which the tagging data + /// ends. + /// + /// + /// The file does not begin with . + /// + private void Read(bool read_tags, ReadStyle style, + out uint aiff_size, out long tag_start, + out long tag_end) + { + Seek(0); + if (ReadBlock(4) != FileIdentifier) + throw new CorruptFileException( + "File does not begin with AIFF identifier"); + + aiff_size = ReadBlock(4).ToUInt(true); + tag_start = -1; + tag_end = -1; + + // Get the properties of the file + if (header_block == null && + style != ReadStyle.None) + { + long common_chunk_pos = Find(CommIdentifier, 0); + + if (common_chunk_pos == -1) + { + throw new CorruptFileException( + "No Common chunk available in AIFF file."); + } + + Seek(common_chunk_pos); + header_block = ReadBlock((int) StreamHeader.Size); + + StreamHeader header = new StreamHeader(header_block, aiff_size); + properties = new Properties(TimeSpan.Zero, header); + } + + // Now we search for the ID3 chunk. + // Normally it appears after the Sound data chunk. But as the order of + // chunks is free, it might be the case that the ID3 chunk appears before + // the sound data chunk. + // So we search first for the Sound data chunk and see, if an ID3 chunk appears before + long id3_chunk_pos = -1; + long sound_chunk_pos = Find(SoundIdentifier, 0, ID3Identifier); + if (sound_chunk_pos == -1) + { + // The ID3 chunk appears before the Sound chunk + id3_chunk_pos = Find(ID3Identifier, 0); + } + + // Now let's look for the Sound chunk again + // Since a previous return value of -1 does mean, that the ID3 chunk was found first + sound_chunk_pos = Find(SoundIdentifier, 0); + if (sound_chunk_pos == -1) + { + throw new CorruptFileException( + "No Sound chunk available in AIFF file."); + } + + // Get the length of the Sound chunk and use this as a start value to look for the ID3 chunk + Seek(sound_chunk_pos + 4); + ulong sound_chunk_length = ReadBlock(4).ToULong(true); + long start_search_pos = (long) sound_chunk_length + sound_chunk_pos + 4; + + if (id3_chunk_pos == -1) + { + id3_chunk_pos = Find(ID3Identifier, start_search_pos); + } + + if (id3_chunk_pos > -1) + { + if (read_tags && tag == null) + { + tag = new Id3v2.Tag(this, + id3_chunk_pos + 8); + } + + // Get the length of the tag out of the ID3 chunk + Seek(id3_chunk_pos + 4); + uint tag_size = ReadBlock(4).ToUInt(true) + 8; + + tag_start = InvariantStartPosition = id3_chunk_pos; + tag_end = InvariantEndPosition = tag_start + tag_size; + } + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Aiff/StreamHeader.cs b/taglib-sharp/src/TagLib/Aiff/StreamHeader.cs new file mode 100644 index 0000000..c7d32b7 --- /dev/null +++ b/taglib-sharp/src/TagLib/Aiff/StreamHeader.cs @@ -0,0 +1,324 @@ +// +// StreamHeader.cs: Provides support for reading Apple's AIFF stream +// properties. +// +// Author: +// Helmut Wahrmann +// +// Copyright (C) 2009 Helmut Wahrmann +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; +using System.Globalization; + +namespace TagLib.Aiff +{ + /// + /// This struct implements to provide + /// support for reading Apple's AIFF stream properties. + /// + public struct StreamHeader : IAudioCodec, ILosslessAudioCodec + { + #region Private Fields + + /// + /// Contains the number of channels. + /// + /// + /// This value is stored in bytes (9,10). + /// 1 is monophonic, 2 is stereo, 4 means 4 channels, etc.. + /// any number of audio channels may be represented + /// + private ushort channels; + + /// + /// Contains the number of sample frames in the Sound Data chunk. + /// + /// + /// This value is stored in bytes (11-14). + /// + private ulong total_frames; + + /// + /// Contains the number of bits per sample. + /// + /// + /// This value is stored in bytes (15,16). + /// It can be any number from 1 to 32. + /// + private ushort bits_per_sample; + + /// + /// Contains the sample rate. + /// + /// + /// This value is stored in bytes (17-26). + /// the sample rate at which the sound is to be played back, + /// in sample frames per second + /// + private ulong sample_rate; + + /// + /// Contains the length of the audio stream. + /// + /// + /// This value is provided by the constructor. + /// + private long stream_length; + + #endregion + + #region Public Static Fields + + /// + /// The size of an AIFF Common chunk + /// + public const uint Size = 26; + + /// + /// The identifier used to recognize a AIFF file. + /// Altough an AIFF file start with "FORM2, we're interested + /// in the Common chunk only, which contains the properties we need. + /// + /// + /// "COMM" + /// + public static readonly ReadOnlyByteVector FileIdentifier = + "COMM"; + + #endregion + + #region Constructors + + /// + /// Constructs and initializes a new instance of for a specified header block and + /// stream length. + /// + /// + /// A object containing the stream + /// header data. + /// + /// + /// A value containing the length of the + /// AIFF Audio stream in bytes. + /// + /// + /// is . + /// + /// + /// does not begin with + /// + public StreamHeader(ByteVector data, long streamLength) + { + if (data == null) + throw new ArgumentNullException("data"); + + + if (!data.StartsWith(FileIdentifier)) + throw new CorruptFileException( + "Data does not begin with identifier."); + + stream_length = streamLength; + + // The first 8 bytes contain the Common chunk identifier "COMM" + // And the size of the common chunk, which is always 18 + channels = data.Mid(8, 2).ToUShort(true); + total_frames = data.Mid(10, 4).ToULong(true); + bits_per_sample = data.Mid(14, 2).ToUShort(true); + + ByteVector sample_rate_indicator = data.Mid(17, 1); + ulong sample_rate_tmp = data.Mid(18, 2).ToULong(true); + sample_rate = 44100; // Set 44100 as default sample rate + + // The following are combinations that iTunes 8 encodes to. + // There may be other combinations in the field, but i couldn't test them. + switch (sample_rate_tmp) + { + case 44100: + if (sample_rate_indicator == 0x0E) + { + sample_rate = 44100; + } + else if (sample_rate_indicator == 0x0D) + { + sample_rate = 22050; + } + else if (sample_rate_indicator == 0x0C) + { + sample_rate = 11025; + } + break; + + case 48000: + if (sample_rate_indicator == 0x0E) + { + sample_rate = 48000; + } + else if (sample_rate_indicator == 0x0D) + { + sample_rate = 24000; + } + break; + + case 64000: + if (sample_rate_indicator == 0x0D) + { + sample_rate = 32000; + } + else if (sample_rate_indicator == 0x0C) + { + sample_rate = 16000; + } + else if (sample_rate_indicator == 0x0B) + { + sample_rate = 8000; + } + break; + + case 44510: + if (sample_rate_indicator == 0x0D) + { + sample_rate = 22255; + } + break; + + case 44508: + if (sample_rate_indicator == 0x0C) + { + sample_rate = 11127; + } + break; + } + } + + #endregion + + #region Public Properties + + /// + /// Gets the duration of the media represented by the current + /// instance. + /// + /// + /// A containing the duration of the + /// media represented by the current instance. + /// + public TimeSpan Duration + { + get + { + if (sample_rate <= 0 || total_frames <= 0) + return TimeSpan.Zero; + + return TimeSpan.FromSeconds( + (double) total_frames/ + (double) sample_rate); + } + } + + /// + /// Gets the types of media represented by the current + /// instance. + /// + /// + /// Always . + /// + public MediaTypes MediaTypes + { + get { return MediaTypes.Audio; } + } + + /// + /// Gets a text description of the media represented by the + /// current instance. + /// + /// + /// A object containing a description + /// of the media represented by the current instance. + /// + public string Description + { + get { return "AIFF Audio"; } + } + + /// + /// Gets the bitrate of the audio represented by the current + /// instance. + /// + /// + /// A value containing a bitrate of the + /// audio represented by the current instance. + /// + public int AudioBitrate + { + get + { + TimeSpan d = Duration; + if (d <= TimeSpan.Zero) + return 0; + + return (int) ((stream_length*8L)/ + d.TotalSeconds)/1000; + } + } + + /// + /// Gets the sample rate of the audio represented by the + /// current instance. + /// + /// + /// A value containing the sample rate of + /// the audio represented by the current instance. + /// + public int AudioSampleRate + { + get { return (int) sample_rate; } + } + + /// + /// Gets the number of channels in the audio represented by + /// the current instance. + /// + /// + /// A value containing the number of + /// channels in the audio represented by the current + /// instance. + /// + public int AudioChannels + { + get { return channels; } + } + + /// + /// Gets the number of bits per sample in the audio + /// represented by the current instance. + /// + /// + /// A value containing the number of bits + /// per sample in the audio represented by the current + /// instance. + /// + public int BitsPerSample + { + get { return bits_per_sample; } + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Ape/File.cs b/taglib-sharp/src/TagLib/Ape/File.cs new file mode 100644 index 0000000..31f61ec --- /dev/null +++ b/taglib-sharp/src/TagLib/Ape/File.cs @@ -0,0 +1,280 @@ +// +// File.cs: Provides tagging and properties support for Monkey's Audio APE +// files. +// +// Author: +// Helmut Wahrmann +// +// Copyright (C) 2007 Helmut Wahrmann +// Copyright (C) 2007 Brian Nickel +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; + +namespace TagLib.Ape { + /// + /// This class extends to + /// provide tagging and properties support for Monkey's Audio APE + /// files. + /// + /// + /// A will be added automatically to + /// any file that doesn't contain one. This change does not effect + /// the physical file until is called and can be + /// reversed using the following method: + /// file.RemoveTags (file.TagTypes & ~file.TagTypesOnDisk); + /// + [SupportedMimeType("taglib/ape", "ape")] + [SupportedMimeType("audio/x-ape")] + [SupportedMimeType("audio/ape")] + [SupportedMimeType("application/x-ape")] + public class File : TagLib.NonContainer.File + { + #region Private Fields + + /// + /// Contains the block with the audio header. + /// + private ByteVector header_block = null; + + #endregion + + + + #region Constructors + + /// + /// Constructs and initializes a new instance of for a specified path in the local file + /// system and specified read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File (string path, ReadStyle propertiesStyle) + : base (path, propertiesStyle) + { + } + + /// + /// Constructs and initializes a new instance of for a specified path in the local file + /// system with an average read style. + /// + /// + /// A object containing the path of the + /// file to use in the new instance. + /// + /// + /// is . + /// + public File (string path) + : base (path) + { + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction and + /// specified read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// is . + /// + public File (File.IFileAbstraction abstraction, + ReadStyle propertiesStyle) + : base (abstraction, propertiesStyle) + { + } + + /// + /// Constructs and initializes a new instance of for a specified file abstraction with an + /// average read style. + /// + /// + /// A object to use when + /// reading from and writing to the file. + /// + /// + /// is . + /// + public File (File.IFileAbstraction abstraction) + : base (abstraction) + { + } + + #endregion + + + + #region Public Methods + + /// + /// Gets a tag of a specified type from the current instance, + /// optionally creating a new tag if possible. + /// + /// + /// A value indicating the + /// type of tag to read. + /// + /// + /// A value specifying whether or not to + /// try and create the tag if one is not found. + /// + /// + /// A object containing the tag that was + /// found in or added to the current instance. If no + /// matching tag was found and none was created, is returned. + /// + /// + /// If a is added to the + /// current instance, it will be placed at the start of the + /// file. On the other hand, + /// will be added to the end of + /// the file. All other tag types will be ignored. + /// + public override TagLib.Tag GetTag(TagTypes type, bool create) + { + TagLib.Tag t = (Tag as TagLib.NonContainer.Tag) + .GetTag (type); + + if (t != null || !create) + return t; + + switch (type) + { + case TagTypes.Id3v1: + return EndTag.AddTag (type, Tag); + + case TagTypes.Id3v2: + return StartTag.AddTag (type, Tag); + + case TagTypes.Ape: + return EndTag.AddTag (type, Tag); + + default: + return null; + } + } + + #endregion + + + + #region Protected Methods + + /// + /// Reads format specific information at the start of the + /// file. + /// + /// + /// A value containing the seek position + /// at which the tags end and the media data begins. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + protected override void ReadStart (long start, + ReadStyle propertiesStyle) + { + if (header_block != null && + propertiesStyle == ReadStyle.None) + return; + + Seek(start); + header_block = ReadBlock ((int)StreamHeader.Size); + } + + /// + /// Reads format specific information at the end of the + /// file. + /// + /// + /// A value containing the seek position + /// at which the media data ends and the tags begin. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + protected override void ReadEnd (long end, + ReadStyle propertiesStyle) + { + // Make sure we have an APE tag. + GetTag (TagTypes.Ape, true); + } + + /// + /// Reads the audio properties from the file represented by + /// the current instance. + /// + /// + /// A value containing the seek position + /// at which the tags end and the media data begins. + /// + /// + /// A value containing the seek position + /// at which the media data ends and the tags begin. + /// + /// + /// A value specifying at what level + /// of accuracy to read the media properties, or to ignore the properties. + /// + /// + /// A object describing the + /// media properties of the file represented by the current + /// instance. + /// + protected override Properties ReadProperties (long start, + long end, + ReadStyle propertiesStyle) + { + StreamHeader header = new StreamHeader (header_block, + end - start); + + return new Properties(TimeSpan.Zero, header); + } + + #endregion + } +} diff --git a/taglib-sharp/src/TagLib/Ape/Footer.cs b/taglib-sharp/src/TagLib/Ape/Footer.cs new file mode 100644 index 0000000..c55626b --- /dev/null +++ b/taglib-sharp/src/TagLib/Ape/Footer.cs @@ -0,0 +1,418 @@ +// +// Footer.cs: Provides a representation of an APEv2 tag footer which can be read +// from and written to disk. +// +// Author: +// Brian Nickel (brian.nickel@gmail.com) +// +// Original Source: +// apefooter.cpp from TagLib +// +// Copyright (C) 2005-2007 Brian Nickel +// Copyright (C) 2004 Allan Sandfeld Jensen (Original Implementation) +// copyright (C) 2002, 2003 Scott Wheeler (Original Implementation) +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version +// 2.1 as published by the Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// + +using System; + +namespace TagLib.Ape { + #region Enums + + /// + /// Indicates the flags applied to a object. + /// + [Flags] + public enum FooterFlags : uint { + /// + /// The tag lacks a footer object. + /// + FooterAbsent = 0x40000000, + + /// + /// The footer is actually a header. + /// + IsHeader = 0x20000000, + + /// + /// The tag contains a header. + /// + HeaderPresent = 0x80000000 + } + + #endregion + + + + /// + /// This structure provides a representation of an APEv2 tag footer + /// which can be read from and written to disk. + /// + public struct Footer : IEquatable