Esempio n. 1
0
void
MP4::Tag::parseText(const MP4::Atom *atom, int expectedFlags)
{
  ByteVectorList data = parseData(atom, expectedFlags);
  if(data.size()) {
    StringList value;
    for(unsigned int i = 0; i < data.size(); i++) {
      value.append(String(data[i], String::UTF8));
    }
    addItem(atom->name, value);
  }
}
Esempio n. 2
0
void
MP4::Tag::parseText(MP4::Atom *atom, TagLib::File *file, int expectedFlags)
{
  ByteVectorList data = parseData(atom, file, expectedFlags);
  if(data.size()) {
    StringList value;
    for(unsigned int i = 0; i < data.size(); i++) {
      value.append(String(data[i], String::UTF8));
    }
    d->items.insert(atom->name, value);
  }
}
Esempio n. 3
0
void
MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file, 1, true);
  if(data.size() > 2) {
    StringList value;
    for(unsigned int i = 2; i < data.size(); i++) {
      value.append(String(data[i], String::UTF8));
    }
    String name = "----:" + data[0] + ':' + data[1];
    d->items.insert(name, value);
  }
}
void UnsynchronizedLyricsFrame::parseFields(const ByteVector &data)
{
  if(data.size() < 5) {
    debug("An unsynchronized lyrics frame must contain at least 5 bytes.");
    return;
  }

  d->textEncoding = String::Type(data[0]);
  d->language = data.mid(1, 3);

  int byteAlign
    = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;

  ByteVectorList l =
    ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);

  if(l.size() == 2) {
    if(d->textEncoding == String::Latin1) {
      d->description = Tag::latin1StringHandler()->parse(l.front());
      d->text = Tag::latin1StringHandler()->parse(l.back());
    } else {
      d->description = String(l.front(), d->textEncoding);
      d->text = String(l.back(), d->textEncoding);
    }
  }
}
Esempio n. 5
0
ByteVector
MP4::Tag::renderFreeForm(const String &name, const MP4::Item &item) const
{
  StringList header = StringList::split(name, ":");
  if (header.size() != 3) {
    debug("MP4: Invalid free-form item name \"" + name + "\"");
    return ByteVector::null;
  }
  ByteVector data;
  data.append(renderAtom("mean", ByteVector::fromUInt(0) + header[1].data(String::UTF8)));
  data.append(renderAtom("name", ByteVector::fromUInt(0) + header[2].data(String::UTF8)));
  AtomDataType type = item.atomDataType();
  if(type == TypeUndefined) {
    if(!item.toStringList().isEmpty()) {
      type = TypeUTF8;
    }
    else {
      type = TypeImplicit;
    }
  }
  if(type == TypeUTF8) {
    StringList value = item.toStringList();
    for(unsigned int i = 0; i < value.size(); i++) {
      data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i].data(String::UTF8)));
    }
  }
  else {
    ByteVectorList value = item.toByteVectorList();
    for(unsigned int i = 0; i < value.size(); i++) {
      data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i]));
    }
  }
  return renderAtom("----", data);
}
Esempio n. 6
0
  void testSplitSingleChar_2()
  {
    ByteVector v("a");

    ByteVectorList l = ByteVectorList::split(v, " ");
    CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), l.size());
    CPPUNIT_ASSERT_EQUAL(ByteVector("a"), l[0]);
  }
Esempio n. 7
0
void
MP4::Tag::parseByte(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    addItem(atom->name, (uchar)data[0].at(0));
  }
}
Esempio n. 8
0
void
MP4::Tag::parseLongLong(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    addItem(atom->name, data[0].toLongLong());
  }
}
Esempio n. 9
0
  void testSplitSingleChar_2()
  {
    ByteVector v("a");

    ByteVectorList l = ByteVectorList::split(v, " ");
    CPPUNIT_ASSERT_EQUAL((unsigned int)1, l.size());
    CPPUNIT_ASSERT_EQUAL(ByteVector("a"), l[0]);
  }
Esempio n. 10
0
void
MP4::Tag::parseInt(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    d->items.insert(atom->name, (int)data[0].toShort());
  }
}
Esempio n. 11
0
void
MP4::Tag::parseByte(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    addItem(atom->name, (uchar)data[0].at(0));
  }
}
Esempio n. 12
0
void
MP4::Tag::parseLongLong(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    addItem(atom->name, data[0].toLongLong());
  }
}
Esempio n. 13
0
void
MP4::Tag::parseInt(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    addItem(atom->name, (int)data[0].toShort());
  }
}
Esempio n. 14
0
void
MP4::Tag::parseBool(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    bool value = data[0].size() ? data[0][0] != '\0' : false;
    d->items.insert(atom->name, value);
  }
}
Esempio n. 15
0
void
MP4::Tag::parseBool(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    bool value = data[0].size() ? data[0][0] != '\0' : false;
    addItem(atom->name, value);
  }
}
Esempio n. 16
0
ByteVector
MP4::Tag::renderData(const ByteVector &name, int flags, const ByteVectorList &data) const
{
  ByteVector result;
  for(unsigned int i = 0; i < data.size(); i++) {
    result.append(renderAtom("data", ByteVector::fromUInt(flags) + ByteVector(4, '\0') + data[i]));
  }
  return renderAtom(name, result);
}
Esempio n. 17
0
void
MP4::Tag::parseIntPair(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    int a = data[0].mid(2, 2).toShort();
    int b = data[0].mid(4, 2).toShort();
    d->items.insert(atom->name, MP4::Item(a, b));
  }
}
Esempio n. 18
0
void
MP4::Tag::parseIntPair(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    const int a = data[0].toShort(2U);
    const int b = data[0].toShort(4U);
    addItem(atom->name, MP4::Item(a, b));
  }
}
Esempio n. 19
0
void
MP4::Tag::parseGnre(MP4::Atom *atom, TagLib::File *file)
{
  ByteVectorList data = parseData(atom, file);
  if(data.size()) {
    int idx = (int)data[0].toShort();
    if(!d->items.contains("\251gen") && idx > 0) {
      d->items.insert("\251gen", StringList(ID3v1::genre(idx - 1)));
    }
  }
}
Esempio n. 20
0
void
MP4::Tag::parseGnre(const MP4::Atom *atom)
{
  ByteVectorList data = parseData(atom);
  if(data.size()) {
    int idx = (int)data[0].toShort();
    if(idx > 0) {
      addItem("\251gen", StringList(ID3v1::genre(idx - 1)));
    }
  }
}
Esempio n. 21
0
void CommentsFrame::parseFields(const ByteVector &data)
{
  if(data.size() < 5) {
    debug("A comment frame must contain at least 5 bytes.");
    return;
  }

  d->textEncoding = String::Type(data[0]);
  d->language = data.mid(1, 3);

  int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;

  ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);

  if(l.size() == 2) {
    d->description = String(l.front(), d->textEncoding);
    d->text = String(l.back(), d->textEncoding);
  }
}
Esempio n. 22
0
MP4::Tag::Tag(File *file, MP4::Atoms *atoms)
{
  d = new TagPrivate;
  d->file = file;
  d->atoms = atoms;

  MP4::Atom *ilst = atoms->find("moov", "udta", "meta", "ilst");
  if(!ilst) {
    //debug("Atom moov.udta.meta.ilst not found.");
    return;
  }

  for(unsigned int i = 0; i < ilst->children.size(); i++) {
    MP4::Atom *atom = ilst->children[i];
    file->seek(atom->offset + 8);
    if(atom->name == "----") {
      parseFreeForm(atom, file);
    }
    else if(atom->name == "trkn" || atom->name == "disk") {
      parseIntPair(atom, file);
    }
    else if(atom->name == "cpil" || atom->name == "pgap" || atom->name == "pcst") {
      parseBool(atom, file);
    }
    else if(atom->name == "tmpo") {
      parseInt(atom, file);
    }
    else if(atom->name == "gnre") {
      parseGnre(atom, file);
    }
	else if(atom->name == "covr") {
	  //Added for artwork support in PlayerKit.
	  ByteVectorList data = parseData(atom, file);
	  if(data.size() > 0) {
	    d->items.insert(atom->name, data);
	  }
	}
    else {
      parseText(atom, file);
    }
  }
}
Esempio n. 23
0
ByteVectorList ByteVectorList::split(
  const ByteVector &v, const ByteVector &pattern, size_t byteAlign, size_t max)
{
  ByteVectorList l;

  size_t previousOffset = 0;
  for(size_t offset = v.find(pattern, 0, byteAlign);
      offset != ByteVector::npos() && (max == 0 || max > l.size() + 1);
      offset = v.find(pattern, offset + pattern.size(), byteAlign))
  {
    if(offset - previousOffset >= 1)
      l.append(v.mid(previousOffset, offset - previousOffset));
    else
      l.append(ByteVector());

    previousOffset = offset + pattern.size();
  }

  if(previousOffset < v.size())
    l.append(v.mid(previousOffset, v.size() - previousOffset));

  return l;
}
ByteVectorList ByteVectorList::split(const ByteVector &v, const ByteVector &pattern,
                                     int byteAlign, int max)
{
  ByteVectorList l;

  uint previousOffset = 0;
  for(int offset = v.find(pattern, 0, byteAlign);
      offset != -1 && (max == 0 || max > int(l.size()) + 1);
      offset = v.find(pattern, offset + pattern.size(), byteAlign))
  {
    if(offset - previousOffset > 1)
    l.append(v.mid(previousOffset, offset - previousOffset));
    else
      l.append(ByteVector::null);

    previousOffset = offset + pattern.size();
  }

  if(previousOffset < v.size())
    l.append(v.mid(previousOffset, v.size() - previousOffset));

  return l;
}
Esempio n. 25
0
List<Ogg::Page *> Ogg::Page::paginate(const ByteVectorList &packets,
                                      PaginationStrategy strategy,
                                      unsigned int streamSerialNumber,
                                      int firstPage,
                                      bool firstPacketContinued,
                                      bool lastPacketCompleted,
                                      bool containsLastPacket)
{
  // SplitSize must be a multiple of 255 in order to get the lacing values right
  // create pages of about 8KB each

  static const unsigned int SplitSize = 32 * 255;

  // Force repagination if the packets are too large for a page.

  if(strategy != Repaginate) {

    size_t totalSize = packets.size();
    for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
      totalSize += it->size();

    if(totalSize > 255 * 255)
      strategy = Repaginate;
  }

  List<Page *> l;

  // Handle creation of multiple pages with appropriate pagination.

  if(strategy == Repaginate) {

    int pageIndex = firstPage;

    for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) {

      const bool lastPacketInList = (it == --packets.end());

      // mark very first packet?

      bool continued = (firstPacketContinued && it == packets.begin());
      unsigned int pos = 0;

      while(pos < it->size()) {

        const bool lastSplit = (pos + SplitSize >= it->size());

        ByteVectorList packetList;
        packetList.append(it->mid(pos, SplitSize));

        l.append(new Page(packetList,
                          streamSerialNumber,
                          pageIndex,
                          continued,
                          lastSplit && (lastPacketInList ? lastPacketCompleted : true),
                          lastSplit && (containsLastPacket && lastPacketInList)));
        pageIndex++;
        continued = true;

        pos += SplitSize;
      }
    }
  }
  else {
    l.append(new Page(packets,
                      streamSerialNumber,
                      firstPage,
                      firstPacketContinued,
                      lastPacketCompleted,
                      containsLastPacket));
  }

  return l;
}
Esempio n. 26
0
List<Ogg::Page *> Ogg::Page::paginate(const ByteVectorList &packets,
                                      PaginationStrategy strategy,
                                      uint streamSerialNumber,
                                      int firstPage,
                                      bool firstPacketContinued,
                                      bool lastPacketCompleted,
                                      bool containsLastPacket)
{
  List<Page *> l;

  int totalSize = 0;

  for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
    totalSize += (*it).size();

  // Handle creation of multiple pages with appropriate pagination.
  if(strategy == Repaginate || totalSize + packets.size() > 255 * 255) {

    // 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++;

      l.append(p);
    }
  }
  else {
    Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
                       lastPacketCompleted, containsLastPacket);
    l.append(p);
  }

  return l;
}