d017c73508
tstring bug-fix: 171957) :operator[] and in String::operator+=. (BUG:169389)
331 lines
11 KiB
Diff
331 lines
11 KiB
Diff
diff -Nur taglib-1.5/taglib/ogg/xiphcomment.cpp taglib/taglib/ogg/xiphcomment.cpp
|
|
--- taglib-1.5/taglib/ogg/xiphcomment.cpp 2008-02-04 16:14:46.000000000 +0100
|
|
+++ taglib/taglib/ogg/xiphcomment.cpp 2009-07-11 15:17:06.000000000 +0200
|
|
@@ -103,16 +103,20 @@
|
|
|
|
TagLib::uint Ogg::XiphComment::year() const
|
|
{
|
|
- if(d->fieldListMap["DATE"].isEmpty())
|
|
- return 0;
|
|
- return d->fieldListMap["DATE"].front().toInt();
|
|
+ if(!d->fieldListMap["DATE"].isEmpty())
|
|
+ return d->fieldListMap["DATE"].front().toInt();
|
|
+ if(!d->fieldListMap["YEAR"].isEmpty())
|
|
+ return d->fieldListMap["YEAR"].front().toInt();
|
|
+ return 0;
|
|
}
|
|
|
|
TagLib::uint Ogg::XiphComment::track() const
|
|
{
|
|
- if(d->fieldListMap["TRACKNUMBER"].isEmpty())
|
|
- return 0;
|
|
- return d->fieldListMap["TRACKNUMBER"].front().toInt();
|
|
+ if(!d->fieldListMap["TRACKNUMBER"].isEmpty())
|
|
+ return d->fieldListMap["TRACKNUMBER"].front().toInt();
|
|
+ if(!d->fieldListMap["TRACKNUM"].isEmpty())
|
|
+ return d->fieldListMap["TRACKNUM"].front().toInt();
|
|
+ return 0;
|
|
}
|
|
|
|
void Ogg::XiphComment::setTitle(const String &s)
|
|
@@ -142,6 +146,7 @@
|
|
|
|
void Ogg::XiphComment::setYear(uint i)
|
|
{
|
|
+ removeField("YEAR");
|
|
if(i == 0)
|
|
removeField("DATE");
|
|
else
|
|
@@ -150,6 +155,7 @@
|
|
|
|
void Ogg::XiphComment::setTrack(uint i)
|
|
{
|
|
+ removeField("TRACKNUM");
|
|
if(i == 0)
|
|
removeField("TRACKNUMBER");
|
|
else
|
|
diff -Nur taglib-1.5-orig/taglib/ogg/oggfile.cpp taglib-1.5/taglib/ogg/oggfile.cpp
|
|
--- taglib-1.5-orig/taglib/ogg/oggfile.cpp 2008-02-04 16:14:46.000000000 +0100
|
|
+++ taglib-1.5/taglib/ogg/oggfile.cpp 2009-09-04 11:46:54.859122796 +0200
|
|
@@ -270,11 +270,28 @@
|
|
return true;
|
|
}
|
|
|
|
-void Ogg::File::writePageGroup(const List<int> &pageGroup)
|
|
+void Ogg::File::writePageGroup(const List<int> &thePageGroup)
|
|
{
|
|
- if(pageGroup.isEmpty())
|
|
+ if(thePageGroup.isEmpty())
|
|
return;
|
|
|
|
+
|
|
+ // pages in the pageGroup and packets must be equivalent
|
|
+ // (originalSize and size of packets would not work together),
|
|
+ // therefore we sometimes have to add pages to the group
|
|
+ List<int> pageGroup(thePageGroup);
|
|
+ while (!d->pages[pageGroup.back()]->header()->lastPacketCompleted()) {
|
|
+ if (d->currentPage->header()->pageSequenceNumber() == pageGroup.back()) {
|
|
+ if (nextPage() == false) {
|
|
+ debug("broken ogg file");
|
|
+ return;
|
|
+ }
|
|
+ pageGroup.append(d->currentPage->header()->pageSequenceNumber());
|
|
+ } else {
|
|
+ pageGroup.append(pageGroup.back() + 1);
|
|
+ }
|
|
+ }
|
|
+
|
|
ByteVectorList packets;
|
|
|
|
// If the first page of the group isn't dirty, append its partial content here.
|
|
@@ -313,6 +330,52 @@
|
|
d->streamSerialNumber, pageGroup.front(),
|
|
continued, completed);
|
|
|
|
+ List<Page *> renumberedPages;
|
|
+
|
|
+ // Correct the page numbering of following pages
|
|
+
|
|
+ if (pages.back()->header()->pageSequenceNumber() != pageGroup.back()) {
|
|
+
|
|
+ // TODO: change the internal data structure so that we don't need to hold the
|
|
+ // complete file in memory (is unavoidable at the moment)
|
|
+
|
|
+ // read the complete stream
|
|
+ while(!d->currentPage->header()->lastPageOfStream()) {
|
|
+ if(nextPage() == false) {
|
|
+ debug("broken ogg file");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // create a gap for the new pages
|
|
+ int numberOfNewPages = pages.back()->header()->pageSequenceNumber() - pageGroup.back();
|
|
+ List<Page *>::Iterator pageIter = d->pages.begin();
|
|
+ for(int i = 0; i < pageGroup.back(); i++) {
|
|
+ if(pageIter != d->pages.end()) {
|
|
+ ++pageIter;
|
|
+ }
|
|
+ else {
|
|
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken in original file.");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ++pageIter;
|
|
+ for(; pageIter != d->pages.end(); ++pageIter) {
|
|
+ Ogg::Page *newPage =
|
|
+ (*pageIter)->getCopyWithNewPageSequenceNumber(
|
|
+ (*pageIter)->header()->pageSequenceNumber() + numberOfNewPages);
|
|
+
|
|
+ ByteVector data;
|
|
+ data.append(newPage->render());
|
|
+ insert(data, newPage->fileOffset(), data.size());
|
|
+
|
|
+ renumberedPages.append(newPage);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // insert the new data
|
|
+
|
|
ByteVector data;
|
|
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it)
|
|
data.append((*it)->render());
|
|
@@ -328,9 +391,37 @@
|
|
// Update the page index to include the pages we just created and to delete the
|
|
// old pages.
|
|
|
|
+ // First step: Pages that contain the comment data
|
|
+
|
|
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it) {
|
|
const int index = (*it)->header()->pageSequenceNumber();
|
|
- delete d->pages[index];
|
|
- d->pages[index] = *it;
|
|
+ if(index < static_cast<int>(d->pages.size())) {
|
|
+ delete d->pages[index];
|
|
+ d->pages[index] = *it;
|
|
+ }
|
|
+ else if(index == d->pages.size()) {
|
|
+ d->pages.append(*it);
|
|
+ }
|
|
+ else {
|
|
+ // oops - there's a hole in the sequence
|
|
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Second step: the renumbered pages
|
|
+
|
|
+ for(List<Page *>::ConstIterator it = renumberedPages.begin(); it != renumberedPages.end(); ++it) {
|
|
+ const int index = (*it)->header()->pageSequenceNumber();
|
|
+ if(index < static_cast<int>(d->pages.size())) {
|
|
+ delete d->pages[index];
|
|
+ d->pages[index] = *it;
|
|
+ }
|
|
+ else if(index == d->pages.size()) {
|
|
+ d->pages.append(*it);
|
|
+ }
|
|
+ else {
|
|
+ // oops - there's a hole in the sequence
|
|
+ debug("Ogg::File::writePageGroup() -- Page sequence is broken.");
|
|
+ }
|
|
}
|
|
}
|
|
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.cpp taglib-1.5/taglib/ogg/oggpage.cpp
|
|
--- taglib-1.5-orig/taglib/ogg/oggpage.cpp 2008-02-04 16:14:46.000000000 +0100
|
|
+++ taglib-1.5/taglib/ogg/oggpage.cpp 2009-09-04 11:47:00.527115729 +0200
|
|
@@ -116,12 +116,14 @@
|
|
flags = ContainsPacketFlags(flags | CompletePacket);
|
|
}
|
|
|
|
- // Or if the page is (a) the first page and it's complete or (b) the last page
|
|
- // and it's complete or (c) a page in the middle.
|
|
-
|
|
- else if((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
|
|
- (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
|
|
- (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket)))
|
|
+ // Or if there is more than one page and the page is
|
|
+ // (a) the first page and it's complete or
|
|
+ // (b) the last page and it's complete or
|
|
+ // (c) a page in the middle.
|
|
+ else if(packetCount() > 1 &&
|
|
+ ((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
|
|
+ (flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
|
|
+ (!(flags & BeginsWithPacket) && !(flags & EndsWithPacket))))
|
|
{
|
|
flags = ContainsPacketFlags(flags | CompletePacket);
|
|
}
|
|
@@ -208,20 +210,101 @@
|
|
for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
|
|
totalSize += (*it).size();
|
|
|
|
- if(strategy == Repaginate || totalSize + packets.size() > 255 * 256) {
|
|
- debug("Ogg::Page::paginate() -- Sorry! Repagination is not yet implemented.");
|
|
- return l;
|
|
- }
|
|
+ // Handle creation of multiple pages with appropriate pagination.
|
|
+ if(strategy == Repaginate || totalSize + packets.size() > 255 * 255) {
|
|
|
|
- // TODO: Handle creation of multiple pages here with appropriate pagination.
|
|
+ // SPLITSIZE must be a multiple of 255 in order to get the lacing values right
|
|
+ // create pages of about 8KB each
|
|
+#define SPLITSIZE (32*255)
|
|
+
|
|
+ int pageIndex = 0;
|
|
+
|
|
+ for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) {
|
|
+ bool continued = false;
|
|
+
|
|
+ // mark very first packet?
|
|
+ if(firstPacketContinued && it==packets.begin()) {
|
|
+ continued = true;
|
|
+ }
|
|
+
|
|
+ // append to buf
|
|
+ ByteVector packetBuf;
|
|
+ packetBuf.append(*it);
|
|
+
|
|
+ while(packetBuf.size() > SPLITSIZE) {
|
|
+ // output a Page
|
|
+ ByteVector packetForOnePage;
|
|
+ packetForOnePage.resize(SPLITSIZE);
|
|
+ std::copy(packetBuf.begin(), packetBuf.begin() + SPLITSIZE, packetForOnePage.begin());
|
|
+
|
|
+ ByteVectorList packetList;
|
|
+ packetList.append(packetForOnePage);
|
|
+ Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued, false, false);
|
|
+ l.append(p);
|
|
+
|
|
+ pageIndex++;
|
|
+ continued = true;
|
|
+ packetBuf = packetBuf.mid(SPLITSIZE);
|
|
+ }
|
|
+
|
|
+ ByteVectorList::ConstIterator jt = it;
|
|
+ ++jt;
|
|
+ bool lastPacketInList = (jt == packets.end());
|
|
+
|
|
+ // output a page for the rest (we output one packet per page, so this one should be completed)
|
|
+ ByteVectorList packetList;
|
|
+ packetList.append(packetBuf);
|
|
+
|
|
+ bool isVeryLastPacket = false;
|
|
+ if(containsLastPacket) {
|
|
+ // mark the very last output page as last of stream
|
|
+ ByteVectorList::ConstIterator jt = it;
|
|
+ ++jt;
|
|
+ if(jt == packets.end()) {
|
|
+ isVeryLastPacket = true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ Page *p = new Page(packetList, streamSerialNumber, firstPage+pageIndex, continued,
|
|
+ lastPacketInList ? lastPacketCompleted : true,
|
|
+ isVeryLastPacket);
|
|
+ pageIndex++;
|
|
|
|
- Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
|
|
- lastPacketCompleted, containsLastPacket);
|
|
- l.append(p);
|
|
+ l.append(p);
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
|
|
+ lastPacketCompleted, containsLastPacket);
|
|
+ l.append(p);
|
|
+ }
|
|
|
|
return l;
|
|
}
|
|
|
|
+Ogg::Page* Ogg::Page::getCopyWithNewPageSequenceNumber(int sequenceNumber)
|
|
+{
|
|
+ Page *pResultPage = NULL;
|
|
+
|
|
+ // TODO: a copy constructor would be helpful
|
|
+
|
|
+ if(d->file == 0) {
|
|
+ pResultPage = new Page(
|
|
+ d->packets,
|
|
+ d->header.streamSerialNumber(),
|
|
+ sequenceNumber,
|
|
+ d->header.firstPacketContinued(),
|
|
+ d->header.lastPacketCompleted(),
|
|
+ d->header.lastPageOfStream());
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pResultPage = new Page(d->file, d->fileOffset);
|
|
+ pResultPage->d->header.setPageSequenceNumber(sequenceNumber);
|
|
+ }
|
|
+ return pResultPage;
|
|
+}
|
|
+
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// protected members
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -254,3 +337,4 @@
|
|
d->packets = packets;
|
|
d->header.setPacketSizes(packetSizes);
|
|
}
|
|
+
|
|
diff -Nur taglib-1.5-orig/taglib/ogg/oggpage.h taglib-1.5/taglib/ogg/oggpage.h
|
|
--- taglib-1.5-orig/taglib/ogg/oggpage.h 2008-02-04 16:14:46.000000000 +0100
|
|
+++ taglib-1.5/taglib/ogg/oggpage.h 2009-09-04 11:47:06.387120297 +0200
|
|
@@ -70,6 +70,14 @@
|
|
*/
|
|
const PageHeader *header() const;
|
|
|
|
+ /*!
|
|
+ * Returns a copy of the page with \a sequenceNumber set as sequence number.
|
|
+ *
|
|
+ * \see header()
|
|
+ * \see PageHeader::setPageSequenceNumber()
|
|
+ */
|
|
+ Page* getCopyWithNewPageSequenceNumber(int sequenceNumber);
|
|
+
|
|
/*!
|
|
* Returns the index of the first packet wholly or partially contained in
|
|
* this page.
|