+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <set>
+
+#include <id3v2tag.h>
+#include <mpegfile.h>
+
+// set::find didn't work...?!
+class ByteVectorSet {
+public:
+ ByteVectorSet(set<TagLib::ByteVector *> bv_set)
+ : set_(bv_set)
+ { }
+
+ bool has(TagLib::ByteVector *bv) {
+ for (set<TagLib::ByteVector *>::const_iterator it = set_.begin();
+ it != set_.end();
+ ++it) {
+ if (**it == *bv) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+private:
+ set<TagLib::ByteVector *> set_;
+};
+
+static bool
+strip_frames(TagLib::MPEG::File &f, ByteVectorSet &preserve)
+{
+ TagLib::ID3v2::Tag *tag = f.ID3v2Tag();
+ if (tag == 0) {
+ return false;
+ }
+
+ bool stripped = false;
+ TagLib::ID3v2::FrameList frames = tag->frameList();
+ TagLib::ID3v2::FrameList::ConstIterator it;
+ for (it = frames.begin();
+ it != frames.end();
+ ++it) {
+ TagLib::ByteVector frameid = (*it)->frameID();
+ uint frameid_size = frameid.size();
+ char *frameid_s = new char[frameid_size + 1];
+ memcpy(frameid_s, frameid.data(), frameid_size);
+ frameid_s[frameid_size] = '\0';
+ printf("%s: %s ", frameid_s, (*it)->toString().toCString());
+ if (preserve.has(&frameid)) {
+ puts("preserve");
+ continue;
+ }
+ puts("remove");
+ delete[] frameid_s;
+ tag->removeFrame(*it, true);
+ stripped = true;
+
+ }
+ return stripped;
+}
+
+int
+main(int argc, char **argv)
+{
+ set<TagLib::ByteVector *> preserve_frames;
+
+ int c;
+ while ((c = getopt(argc, argv, "p:")) != -1) {
+ switch (c) {
+ case 'p':
+ preserve_frames.insert(new TagLib::ByteVector(optarg));
+ break;
+ default:
+ // getopt printed an error.
+ return 2;
+ }
+ }
+ argc -= optind; argv += optind;
+
+ ByteVectorSet preserve_frame_set(preserve_frames);
+
+ for (int i = 0; i < argc; ++i) {
+ const char *mp3_path = argv[i];
+ TagLib::MPEG::File f(mp3_path);
+ if (!strip_frames(f, preserve_frame_set)) {
+ continue;
+ }
+ errno = 0;
+ if (!f.save()) {
+ if (errno != 0) {
+ fprintf(stderr, "failed to save %s: %s\n",
+ mp3_path, strerror(errno));
+ } else {
+ fprintf(stderr, "failed to save %s\n", mp3_path);
+ }
+ return 3;
+ }
+ }
+
+ return 0;
+}