Skip to content

Commit 0394dc4

Browse files
committed
Naming improvement renamed ReadingOption.skipImage to skipPictures, same for c++ equivalent;
Improved safeguards when creating images from metadata; Recompiled XCFrameworks
1 parent 32ef13c commit 0394dc4

33 files changed

Lines changed: 167 additions & 124 deletions

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ import SwiftTagLib
2121
let url = URL(fileURLWithPath: "./path/to/audiofile.mp3")
2222
var audioFile = try AudioFile(url: url)
2323

24-
// by default images are read from metadata during initialization
24+
// by default attached pictures are read from metadata during initialization
2525
// skipping them will reduce time spent reading metadata
26-
audioFile = try AudioFile(url: url, options: [.skipImages])
27-
// if you need to know if file metadata has attached pictures
26+
audioFile = try AudioFile(url: url, options: [.skipPictures])
27+
28+
// if you need to know if file metadata has attached pictures,
29+
// might give false positives if pictures are corrupted/empty
2830
print("has attached pictures:", audioFile.metadata.hasAttachedPictures)
2931

3032
// get metadata values

XCFrameworkPackage/CxxTagLibBridge.xcframework/Info.plist

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,32 @@
88
<key>BinaryPath</key>
99
<string>CxxTagLibBridge.framework/CxxTagLibBridge</string>
1010
<key>LibraryIdentifier</key>
11-
<string>ios-arm64_x86_64-simulator</string>
11+
<string>ios-arm64</string>
1212
<key>LibraryPath</key>
1313
<string>CxxTagLibBridge.framework</string>
1414
<key>SupportedArchitectures</key>
1515
<array>
1616
<string>arm64</string>
17-
<string>x86_64</string>
1817
</array>
1918
<key>SupportedPlatform</key>
2019
<string>ios</string>
21-
<key>SupportedPlatformVariant</key>
22-
<string>simulator</string>
2320
</dict>
2421
<dict>
2522
<key>BinaryPath</key>
2623
<string>CxxTagLibBridge.framework/CxxTagLibBridge</string>
2724
<key>LibraryIdentifier</key>
28-
<string>ios-arm64</string>
25+
<string>ios-arm64_x86_64-simulator</string>
2926
<key>LibraryPath</key>
3027
<string>CxxTagLibBridge.framework</string>
3128
<key>SupportedArchitectures</key>
3229
<array>
3330
<string>arm64</string>
31+
<string>x86_64</string>
3432
</array>
3533
<key>SupportedPlatform</key>
3634
<string>ios</string>
35+
<key>SupportedPlatformVariant</key>
36+
<string>simulator</string>
3737
</dict>
3838
</array>
3939
<key>CFBundlePackageType</key>

XCFrameworkPackage/Sources/CxxTagLibBridge/AudioMetadata/Picture/AudioMetadata.Picture+create_from.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
#import <CxxTagLibBridge/AudioMetadata.hpp>
33

44
/// builds `AudioMetadata::Picture` from `TagLib::FLAC::Picture`.
5-
AudioMetadata::Picture AudioMetadata::Picture::create_from_FLACPicture(const TagLib::FLAC::Picture *flacPicture) {
5+
std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_FLACPicture(const TagLib::FLAC::Picture *flacPicture) {
6+
if (!flacPicture) {
7+
return std::nullopt;
8+
}
69
auto pointer = flacPicture->data().data();
710
auto size = flacPicture->data().size();
11+
if (!pointer || size <= 0) {
12+
return std::nullopt;
13+
}
814
auto picture = AudioMetadata::Picture {
915
std::vector<char>(pointer, pointer + size),
1016
size
@@ -17,22 +23,35 @@ AudioMetadata::Picture AudioMetadata::Picture::create_from_FLACPicture(const Tag
1723
}
1824

1925
/// builds `AudioMetadata::Picture` from `TagLib::MP4::CoverArt`.
20-
AudioMetadata::Picture AudioMetadata::Picture::create_from_MP4Picture(const TagLib::MP4::CoverArt coverArt) {
21-
auto pointer = coverArt.data().data();
22-
auto size = coverArt.data().size();
23-
return {
24-
std::vector<char>(pointer, pointer + size),
25-
size
26+
std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_MP4Picture(const TagLib::MP4::CoverArt *coverArt) {
27+
if (!coverArt) {
28+
return std::nullopt;
29+
}
30+
auto pointer = coverArt->data().data();
31+
auto size = coverArt->data().size();
32+
if (!pointer || size <= 0) {
33+
return std::nullopt;
34+
}
35+
auto picture = AudioMetadata::Picture {
36+
.bytes = std::vector<char>(pointer, pointer + size),
37+
.size = size
2638
};
39+
return picture;
2740
}
2841

2942
/// builds `AudioMetadata::Picture` from `TagLib::ID3v2::AttachedPictureFrame *`.
30-
AudioMetadata::Picture AudioMetadata::Picture::create_from_ID3v2Picture(const TagLib::ID3v2::AttachedPictureFrame *frame) {
43+
std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_ID3v2Picture(const TagLib::ID3v2::AttachedPictureFrame *frame) {
44+
if (!frame) {
45+
return std::nullopt;
46+
}
3147
auto pointer = frame->picture().data();
3248
auto size = frame->picture().size();
49+
if (!pointer || size <= 0) {
50+
return std::nullopt;
51+
}
3352
auto picture = AudioMetadata::Picture {
34-
std::vector<char>(pointer, pointer + size),
35-
size
53+
.bytes = std::vector<char>(pointer, pointer + size),
54+
.size = size
3655
};
3756
if (!frame->description().isEmpty()) {
3857
picture.description = frame->description().toCString(true);
@@ -41,7 +60,7 @@ AudioMetadata::Picture AudioMetadata::Picture::create_from_ID3v2Picture(const Ta
4160
}
4261

4362
/// maybe builds `AudioMetadata::Picture` from `const TagLib::APE::Item item` and `const char* key` return wrapped in `std::optional`.
44-
std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_APEPicture(const TagLib::APE::Item item, const char* key) {
63+
std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_APEPicture(const TagLib::APE::Item *item, const char* key) {
4564
// From http://www.hydrogenaudio.org/forums/index.php?showtopic=40603&view=findpost&p=504669
4665
/*
4766
<length> 32 bit
@@ -52,21 +71,27 @@ std::optional<AudioMetadata::Picture> AudioMetadata::Picture::create_from_APEPic
5271
0x00
5372
<cover data> binary
5473
*/
55-
auto binaryData = item.binaryData();
74+
if (!item) {
75+
return std::nullopt;
76+
}
77+
auto binaryData = item->binaryData();
5678
auto pos = binaryData.find('\0');
5779
if (-1 != pos && 3 < binaryData.size()) {
5880
auto upos = static_cast<unsigned int>(pos);
5981
auto pointer = binaryData.mid(upos + 1).data();
6082
auto size = (binaryData.size() - upos - 1);
83+
if (!pointer || size <= 0) {
84+
return std::nullopt;
85+
}
6186
auto description = TagLib::String(binaryData.mid(0, upos), TagLib::String::UTF8).toCString(true);
6287
auto type = strcasecmp(key, "Cover Art (Front)")
6388
? AudioMetadata::Picture::Kind::frontCover
6489
: AudioMetadata::Picture::Kind::backCover;
6590
auto picture = AudioMetadata::Picture {
66-
std::vector<char>(pointer, pointer + size),
67-
size,
68-
description,
69-
type
91+
.bytes = std::vector<char>(pointer, pointer + size),
92+
.size = size,
93+
.description = description,
94+
.kind = type
7095
};
7196
return picture;
7297
} else {

XCFrameworkPackage/Sources/CxxTagLibBridge/AudioMetadata/Tags/AudioMetadata+APETag.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,15 @@ AudioMetadata AudioMetadata::read_from_APE_tag(const TagLib::APE::Tag *tag, cons
150150
} else if(TagLib::APE::Item::Binary == item.type()) {
151151
if (key == Key::coverArtFront || key == Key::coverArtBack) {
152152
++metadata.attachedPicturesCount;
153-
/// if theres no need to read images skip this step.
154-
if (options & MetadataReadingOptions::skipImages) {
153+
/// if theres no need to read pictures skip this step.
154+
if (options & MetadataReadingOptions::skipPictures) {
155155
continue;
156156
}
157-
auto picture = AudioMetadata::Picture::create_from_APEPicture(item, key);
157+
auto picture = AudioMetadata::Picture::create_from_APEPicture(&item, key);
158158
if (picture.has_value()) {
159159
metadata.attachedPictures.push_back(picture.value());
160+
} else {
161+
--metadata.attachedPicturesCount;
160162
}
161163
} else {
162164
continue;

XCFrameworkPackage/Sources/CxxTagLibBridge/AudioMetadata/Tags/AudioMetadata+ID3v2Tag.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,15 @@ AudioMetadata AudioMetadata::read_from_ID3v2_tag(const TagLib::ID3v2::Tag *tag,
172172
for (auto iterator: tag->frameListMap()[Key::pictures]) {
173173
TagLib::ID3v2::AttachedPictureFrame *frame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame *>(iterator);
174174
++metadata.attachedPicturesCount;
175-
/// if theres no need to read images skip this step.
176-
if (options & MetadataReadingOptions::skipImages) {
175+
/// if theres no need to read pictures skip this step.
176+
if (options & MetadataReadingOptions::skipPictures) {
177177
continue;
178178
}
179-
if (frame) {
180-
auto picture = AudioMetadata::Picture::create_from_ID3v2Picture(frame);
181-
metadata.attachedPictures.push_back(picture);
179+
auto picture = AudioMetadata::Picture::create_from_ID3v2Picture(frame);
180+
if (picture.has_value()) {
181+
metadata.attachedPictures.push_back(picture.value());
182+
} else {
183+
--metadata.attachedPicturesCount;
182184
}
183185
}
184186
return metadata;

XCFrameworkPackage/Sources/CxxTagLibBridge/AudioMetadata/Tags/AudioMetadata+MP4Tag.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,16 @@ AudioMetadata AudioMetadata::read_from_MP4_tag(const TagLib::MP4::Tag *tag, cons
105105
auto art = tag->item(Key::pictures).toCoverArtList();
106106
for (auto iterator: art) {
107107
++metadata.attachedPicturesCount;
108-
/// if theres no need to read images skip this step.
109-
if (options & MetadataReadingOptions::skipImages) {
108+
/// if theres no need to read pictures skip this step.
109+
if (options & MetadataReadingOptions::skipPictures) {
110110
continue;
111111
}
112-
auto picture = AudioMetadata::Picture::create_from_MP4Picture(iterator);
113-
metadata.attachedPictures.push_back(picture);
112+
auto picture = AudioMetadata::Picture::create_from_MP4Picture(&iterator);
113+
if (picture.has_value()) {
114+
metadata.attachedPictures.push_back(picture.value());
115+
} else {
116+
--metadata.attachedPicturesCount;
117+
}
114118
}
115119
}
116120

XCFrameworkPackage/Sources/CxxTagLibBridge/AudioMetadata/Tags/AudioMetadata+XIPHComment.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,16 @@ AudioMetadata AudioMetadata::read_from_XiphComment(const TagLib::Ogg::XiphCommen
156156

157157
for (auto iterator: const_cast<TagLib::Ogg::XiphComment *>(tag)->pictureList()) {
158158
++metadata.attachedPicturesCount;
159-
/// if theres no need to read images skip this step.
160-
if (options & MetadataReadingOptions::skipImages) {
159+
/// if theres no need to read pictures skip this step.
160+
if (options & MetadataReadingOptions::skipPictures) {
161161
continue;
162162
}
163163
auto picture = AudioMetadata::Picture::create_from_FLACPicture(iterator);
164-
metadata.attachedPictures.push_back(picture);
164+
if (picture.has_value()) {
165+
metadata.attachedPictures.push_back(picture.value());
166+
} else {
167+
--metadata.attachedPicturesCount;
168+
}
165169
}
166170

167171
return metadata;

XCFrameworkPackage/Sources/CxxTagLibBridge/include/CxxTagLibBridge/AudioMetadata.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ struct AudioMetadata final {
133133
APEPicture convert_to_APEPicture();
134134

135135
// MARK: - AttachedPicture: builders from specific format
136-
static Picture create_from_FLACPicture(const TagLib::FLAC::Picture *flacPicture);
137-
static Picture create_from_MP4Picture(const TagLib::MP4::CoverArt coverArt);
138-
static Picture create_from_ID3v2Picture(const TagLib::ID3v2::AttachedPictureFrame *frame);
139-
static std::optional<Picture> create_from_APEPicture(const TagLib::APE::Item item, const char* key);
136+
static std::optional<Picture> create_from_FLACPicture(const TagLib::FLAC::Picture *flacPicture);
137+
static std::optional<Picture> create_from_MP4Picture(const TagLib::MP4::CoverArt *coverArt);
138+
static std::optional<Picture> create_from_ID3v2Picture(const TagLib::ID3v2::AttachedPictureFrame *frame);
139+
static std::optional<Picture> create_from_APEPicture(const TagLib::APE::Item *item, const char* key);
140140
};
141141
using AttachedPictures = std::vector<Picture>;
142142
AttachedPictures attachedPictures;

0 commit comments

Comments
 (0)