コード例 #1
0
ファイル: KaxBlock.cpp プロジェクト: ares89/vlc
uint64 KaxInternalBlock::ReadInternalHead(IOCallback & input)
{
	binary Buffer[5], *cursor = Buffer;
	uint64 Result = input.read(cursor, 4);
	if (Result != 4)
		return Result;
	
	// update internal values
	TrackNumber = *cursor++;
	if ((TrackNumber & 0x80) == 0) {
		// there is extra data
		if ((TrackNumber & 0x40) == 0) {
			// We don't support track numbers that large !
			return Result;
		}
		Result += input.read(&Buffer[4], 1);
		TrackNumber = (TrackNumber & 0x3F) << 8;
		TrackNumber += *cursor++;
	} else {
		TrackNumber &= 0x7F;
	}

    
	big_int16 b16;
	b16.Eval(cursor);
	assert(ParentCluster != NULL);
	Timecode = ParentCluster->GetBlockGlobalTimecode(int16(b16));
	bLocalTimecodeUsed = false;
	cursor += 2;

	return Result;
}
コード例 #2
0
filepos_t EbmlString::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		if (GetSize() == 0) {
			Value = "";
			SetValueIsSet();
		} else {
			char *Buffer = new char[GetSize() + 1];
			if (Buffer == NULL) {
				// unable to store the data, skip it
				input.setFilePointer(GetSize(), seek_current);
			} else {
				input.readFully(Buffer, GetSize());
				if (Buffer[GetSize()-1] != '\0') {
					Buffer[GetSize()] = '\0';
				}
				Value = Buffer;
				delete [] Buffer;
				SetValueIsSet();
			}
		}
	}

	return GetSize();
}
コード例 #3
0
ファイル: EbmlString.cpp プロジェクト: AmirAbrams/haiku
uint64 EbmlString::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		if (Size == 0) {
			Value = "";
			bValueIsSet = true;
		} else {
			char *Buffer = new char[Size + 1];
			if (Buffer == NULL) {
				// unable to store the data, skip it
				input.setFilePointer(Size, seek_current);
			} else {
				input.readFully(Buffer, Size);
				if (Buffer[Size-1] != '\0') {
					Buffer[Size] = '\0';
				}
				Value = Buffer;
				delete [] Buffer;
				bValueIsSet = true;
			}
		}
	}

	return Size;
}
コード例 #4
0
ファイル: EbmlVoid.cpp プロジェクト: AmirAbrams/haiku
uint32 EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact)
{
	// write dummy data by 4KB chunks
	static binary DummyBuf[4*1024];

	uint64 SizeToWrite = Size;
	while (SizeToWrite > 4*1024)
	{
		output.writeFully(DummyBuf, 4*1024);
		SizeToWrite -= 4*1024;
	}
	output.writeFully(DummyBuf, SizeToWrite);
	return Size;
}
コード例 #5
0
ファイル: EbmlVoid.cpp プロジェクト: OS2World/LIB-MM-libebml
filepos_t EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bWithDefault)
{
	// write dummy data by 4KB chunks
	static binary DummyBuf[4*1024];

	uint64 SizeToWrite = GetSize();
	while (SizeToWrite > 4*1024)
	{
		output.writeFully(DummyBuf, 4*1024);
		SizeToWrite -= 4*1024;
	}
	output.writeFully(DummyBuf, SizeToWrite);
	return GetSize();
}
コード例 #6
0
ファイル: EbmlFloat.cpp プロジェクト: AmirAbrams/haiku
/*!
	\todo remove the hack for possible endianess pb (test on little & big endian)
*/
uint64 EbmlFloat::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		binary Buffer[20];
		assert(Size <= 20);
		input.readFully(Buffer, Size);
		
		if (Size == 4) {
			big_int32 TmpRead;
			TmpRead.Eval(Buffer);
			int32 tmpp = int32(TmpRead);
			float val;
			memcpy(&val, &tmpp, 4);
			Value = val;
			bValueIsSet = true;
		} else if (Size == 8) {
			big_int64 TmpRead;
			TmpRead.Eval(Buffer);
			int64 tmpp = int64(TmpRead);
			double val;
			memcpy(&val, &tmpp, 8);
			Value = val;
			bValueIsSet = true;
		}
	}

	return Size;
}
コード例 #7
0
ファイル: EbmlMaster.cpp プロジェクト: ares89/vlc
/*!
	\todo handle exception on errors
	\todo write all the Mandatory elements in the Context, otherwise assert
*/
filepos_t EbmlMaster::RenderData(IOCallback & output, bool bForceRender, bool bWithDefault)
{
	filepos_t Result = 0;
	size_t Index;

	if (!bForceRender) {
		assert(CheckMandatory());
	}

	if (!bChecksumUsed) { // old school
		for (Index = 0; Index < ElementList.size(); Index++) {
			if (!bWithDefault && (ElementList[Index])->IsDefaultValue())
				continue;
			Result += (ElementList[Index])->Render(output, bWithDefault, false ,bForceRender);
		}
	} else { // new school
		MemIOCallback TmpBuf(GetSize() - 6);
		for (Index = 0; Index < ElementList.size(); Index++) {
			if (!bWithDefault && (ElementList[Index])->IsDefaultValue())
				continue;
			(ElementList[Index])->Render(TmpBuf, bWithDefault, false ,bForceRender);
		}
		Checksum.FillCRC32(TmpBuf.GetDataBuffer(), TmpBuf.GetDataBufferSize());
		Result += Checksum.Render(output, true, false ,bForceRender);
		output.writeFully(TmpBuf.GetDataBuffer(), TmpBuf.GetDataBufferSize());
		Result += TmpBuf.GetDataBufferSize();
	}

	return Result;
}
コード例 #8
0
ファイル: EbmlFloat.cpp プロジェクト: MediaArea/libebml
/*!
  \todo remove the hack for possible endianess pb (test on little & big endian)
*/
filepos_t EbmlFloat::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if (ReadFully != SCOPE_NO_DATA) {
    binary Buffer[20];
    assert(GetSize() <= 20);
    input.readFully(Buffer, GetSize());

    if (GetSize() == 4) {
      big_int32 TmpRead;
      TmpRead.Eval(Buffer);
      int32 tmpp = int32(TmpRead);
      float val;
      memcpy(&val, &tmpp, 4);
      Value = val;
      SetValueIsSet();
    } else if (GetSize() == 8) {
      big_int64 TmpRead;
      TmpRead.Eval(Buffer);
      int64 tmpp = int64(TmpRead);
      double val;
      memcpy(&val, &tmpp, 8);
      Value = val;
      SetValueIsSet();
    }
  }

  return GetSize();
}
コード例 #9
0
ファイル: EbmlCrc32.cpp プロジェクト: Azpidatziak/mkvtoolnix
filepos_t EbmlCrc32::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		binary *Buffer = new binary[GetSize()];
		if (Buffer == NULL) {
			// impossible to read, skip it
			input.setFilePointer(GetSize(), seek_current);
		} else {
			input.readFully(Buffer, GetSize());

			memcpy((void *)&m_crc_final, Buffer, 4);
			delete [] Buffer;
			SetValueIsSet();
		}
	}

	return GetSize();
}
コード例 #10
0
ファイル: MemIOCallback.cpp プロジェクト: MCZarin/libebml
uint32 MemIOCallback::write(IOCallback & IOToRead, size_t Size)
{
  if (dataBufferMemorySize < dataBufferPos + Size) {
    //We need more memory!
    dataBuffer = (binary *)realloc((void *)dataBuffer, dataBufferPos + Size);
  }
  IOToRead.readFully(&dataBuffer[dataBufferPos], Size);
  dataBufferTotalSize = Size;
  return Size;
}
コード例 #11
0
ファイル: EbmlFloat.cpp プロジェクト: AmirAbrams/haiku
/*!
	\todo handle exception on errors
	\todo handle 10 bits precision
*/
uint32 EbmlFloat::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact)
{
	assert(Size == 4 || Size == 8);

	if (Size == 4) {
		float val = Value;
		int Tmp;
		memcpy(&Tmp, &val, 4);
		big_int32 TmpToWrite(Tmp);
		output.writeFully(&TmpToWrite.endian(), Size);
	} else if (Size == 8) {
		double val = Value;
		int64 Tmp;
		memcpy(&Tmp, &val, 8);
		big_int64 TmpToWrite(Tmp);
		output.writeFully(&TmpToWrite.endian(), Size);
	} 

	return Size;
}
コード例 #12
0
ファイル: EbmlString.cpp プロジェクト: MCZarin/libebml
/*!
  \todo handle exception on errors
*/
filepos_t EbmlString::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
  filepos_t Result;
  output.writeFully(Value.c_str(), Value.length());
  Result = Value.length();

  if (Result < GetDefaultSize()) {
    // pad the rest with 0
    binary *Pad = new (std::nothrow) binary[GetDefaultSize() - Result];
    if (Pad == NULL) {
      return Result;
    }
    memset(Pad, 0x00, GetDefaultSize() - Result);
    output.writeFully(Pad, GetDefaultSize() - Result);
    Result = GetDefaultSize();
    delete [] Pad;
  }

  return Result;
}
コード例 #13
0
ファイル: EbmlDate.cpp プロジェクト: MediaArea/libebml
filepos_t EbmlDate::RenderData(IOCallback & output, bool /* bForceRender */, bool  /* bWithDefault */)
{
  if (GetSize() != 0) {
    assert(GetSize() == 8);
    big_int64 b64(myDate);

    output.writeFully(&b64.endian(),GetSize());
  }

  return GetSize();
}
コード例 #14
0
ファイル: EbmlFloat.cpp プロジェクト: MediaArea/libebml
/*!
  \todo handle exception on errors
  \todo handle 10 bits precision
*/
filepos_t EbmlFloat::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
  assert(GetSize() == 4 || GetSize() == 8);

  if (GetSize() == 4) {
    float val = Value;
    int Tmp;
    memcpy(&Tmp, &val, 4);
    big_int32 TmpToWrite(Tmp);
    output.writeFully(&TmpToWrite.endian(), GetSize());
  } else if (GetSize() == 8) {
    double val = Value;
    int64 Tmp;
    memcpy(&Tmp, &val, 8);
    big_int64 TmpToWrite(Tmp);
    output.writeFully(&TmpToWrite.endian(), GetSize());
  }

  return GetSize();
}
コード例 #15
0
ファイル: EbmlString.cpp プロジェクト: AmirAbrams/haiku
/*!
	\todo handle exception on errors
*/
uint32 EbmlString::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact)
{
	uint32 Result;
	output.writeFully(Value.c_str(), Value.length());
	Result = Value.length();
	
	if (Result < DefaultSize) {
		// pad the rest with 0
		binary *Pad = new binary[DefaultSize - Result];
		if (Pad == NULL)
		{
			return Result;
		}
		memset(Pad, 0x00, DefaultSize - Result);
		output.writeFully(Pad, DefaultSize - Result);
		Result = DefaultSize;
		delete [] Pad;
	}
	
	return Result;
}
コード例 #16
0
ファイル: EbmlCrc32.cpp プロジェクト: Azpidatziak/mkvtoolnix
filepos_t EbmlCrc32::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
	filepos_t Result = 4;

	if (Result != 0) {
	    output.writeFully(&m_crc_final, Result);
	}

	if (Result < GetDefaultSize()) {
		// pad the rest with 0
		binary *Pad = new binary[GetDefaultSize() - Result];
		if (Pad != NULL) {
			memset(Pad, 0x00, GetDefaultSize() - Result);
			output.writeFully(Pad, GetDefaultSize() - Result);

			Result = GetDefaultSize();
			delete [] Pad;
		}
	}

	return Result;
}
コード例 #17
0
ファイル: EbmlVoid.cpp プロジェクト: OS2World/LIB-MM-libebml
uint64 EbmlVoid::Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward, bool bWithDefault)
{
//	EltToVoid.UpdateSize(bWithDefault);
	if (EltToVoid.GetElementPosition() == 0) {
		// this element has never been written
		return 0;
	}
	if (EltToVoid.GetSize() + EltToVoid.HeadSize() <2) {
		// the element can't be written here !
		return 0;
	}

	uint64 CurrentPosition = output.getFilePointer();

	output.setFilePointer(EltToVoid.GetElementPosition());

	// compute the size of the voided data based on the original one
	SetSize(EltToVoid.GetSize() + EltToVoid.HeadSize() - 1); // 1 for the ID
	SetSize(GetSize() - CodedSizeLength(GetSize(), GetSizeLength(), IsFiniteSize()));
	// make sure we handle even the strange cases
	//uint32 A1 = GetSize() + HeadSize();
	//uint32 A2 = EltToVoid.GetSize() + EltToVoid.HeadSize();
	if (GetSize() + HeadSize() != EltToVoid.GetSize() + EltToVoid.HeadSize()) {
		SetSize(GetSize()-1);
		SetSizeLength(CodedSizeLength(GetSize(), GetSizeLength(), IsFiniteSize()) + 1);
	}

	if (GetSize() != 0) {
		RenderHead(output, false, bWithDefault); // the rest of the data is not rewritten
	}

	if (ComeBackAfterward) {
		output.setFilePointer(CurrentPosition);
	}

	return EltToVoid.GetSize() + EltToVoid.HeadSize();
}
コード例 #18
0
ファイル: EbmlVoid.cpp プロジェクト: OS2World/LIB-MM-libebml
uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward, bool bWithDefault)
{
	EltToReplaceWith.UpdateSize(bWithDefault);
	if (HeadSize() + GetSize() < EltToReplaceWith.GetSize() + EltToReplaceWith.HeadSize()) {
		// the element can't be written here !
		return INVALID_FILEPOS_T;
	}
	if (HeadSize() + GetSize() - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() == 1) {
		// there is not enough space to put a filling element
		return INVALID_FILEPOS_T;
	}

	uint64 CurrentPosition = output.getFilePointer();

	output.setFilePointer(GetElementPosition());
	EltToReplaceWith.Render(output, bWithDefault);

	if (HeadSize() + GetSize() - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() > 1) {
	  // fill the rest with another void element
	  EbmlVoid aTmp;
	  aTmp.SetSize_(HeadSize() + GetSize() - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() - 1); // 1 is the length of the Void ID
	  int HeadBefore = aTmp.HeadSize();
	  aTmp.SetSize_(aTmp.GetSize() - CodedSizeLength(aTmp.GetSize(), aTmp.GetSizeLength(), aTmp.IsFiniteSize()));
	  int HeadAfter = aTmp.HeadSize();
	  if (HeadBefore != HeadAfter) {
		  aTmp.SetSizeLength(CodedSizeLength(aTmp.GetSize(), aTmp.GetSizeLength(), aTmp.IsFiniteSize()) - (HeadAfter - HeadBefore));
	  }
	  aTmp.RenderHead(output, false, bWithDefault); // the rest of the data is not rewritten
	}

	if (ComeBackAfterward) {
		output.setFilePointer(CurrentPosition);
	}

	return GetSize() + HeadSize();
}
コード例 #19
0
ファイル: EbmlBinary.cpp プロジェクト: MCZarin/libebml
filepos_t EbmlBinary::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if (Data != NULL)
    free(Data);

  if (ReadFully == SCOPE_NO_DATA || !GetSize()) {
    Data = NULL;
    return GetSize();
  }

  Data = (binary *)malloc(GetSize());
  if (Data == NULL)
    throw CRTError(std::string("Error allocating data"));
  SetValueIsSet();
  return input.read(Data, GetSize());
}
コード例 #20
0
ファイル: EbmlUInteger.cpp プロジェクト: MediaArea/libebml
filepos_t EbmlUInteger::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if (ReadFully != SCOPE_NO_DATA) {
    binary Buffer[8];
    input.readFully(Buffer, GetSize());
    Value = 0;

    for (unsigned int i=0; i<GetSize(); i++) {
      Value <<= 8;
      Value |= Buffer[i];
    }
    SetValueIsSet();
  }

  return GetSize();
}
コード例 #21
0
/*!
	\todo handle exception on errors
*/
filepos_t EbmlUInteger::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
	binary FinalData[8]; // we don't handle more than 64 bits integers
	
	if (GetSizeLength() > 8)
		return 0; // integer bigger coded on more than 64 bits are not supported
	
	uint64 TempValue = Value;
	for (unsigned int i=0; i<GetSize();i++) {
		FinalData[GetSize()-i-1] = TempValue & 0xFF;
		TempValue >>= 8;
	}
	
	output.writeFully(FinalData,GetSize());

	return GetSize();
}
コード例 #22
0
ファイル: EbmlDate.cpp プロジェクト: MediaArea/libebml
filepos_t EbmlDate::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  if ((ReadFully == SCOPE_NO_DATA) || (GetSize() == 0))
    return GetSize();

  assert(GetSize() == 8);
  binary Buffer[8];
  input.readFully(Buffer, GetSize());

  big_int64 b64;
  b64.Eval(Buffer);

  myDate = b64;
  SetValueIsSet();

  return GetSize();
}
コード例 #23
0
ファイル: EbmlUInteger.cpp プロジェクト: AmirAbrams/haiku
/*!
	\todo handle exception on errors
*/
uint32 EbmlUInteger::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact)
{
	binary FinalData[8]; // we don't handle more than 64 bits integers
	
	if (SizeLength > 8)
		return 0; // integer bigger coded on more than 64 bits are not supported
	
	uint64 TempValue = Value;
	for (unsigned int i=0; i<Size;i++) {
		FinalData[Size-i-1] = TempValue & 0xFF;
		TempValue >>= 8;
	}
	
	output.writeFully(FinalData,Size);

	return Size;
}
コード例 #24
0
ファイル: EbmlUInteger.cpp プロジェクト: AmirAbrams/haiku
uint64 EbmlUInteger::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		binary Buffer[8];
		input.readFully(Buffer, Size);
		Value = 0;
		
		for (unsigned int i=0; i<Size; i++)
		{
			Value <<= 8;
			Value |= Buffer[i];
		}
		bValueIsSet = true;
	}

	return Size;
}
コード例 #25
0
filepos_t EbmlSInteger::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	if (ReadFully != SCOPE_NO_DATA)
	{
		binary Buffer[8];
		input.readFully(Buffer, GetSize());
		
		if (Buffer[0] & 0x80)
			Value = -1; // this is a negative value
		else
			Value = 0; // this is a positive value
		
		for (unsigned int i=0; i<GetSize(); i++)
		{
			Value <<= 8;
			Value |= Buffer[i];
		}
		SetValueIsSet();
	}

	return GetSize();
}
コード例 #26
0
ファイル: EbmlBinary.cpp プロジェクト: MCZarin/libebml
filepos_t EbmlBinary::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bWithDefault */)
{
  output.writeFully(Data,GetSize());

  return GetSize();
}
コード例 #27
0
ファイル: KaxBlock.cpp プロジェクト: ares89/vlc
/*!
	\todo better zero copy handling
*/
filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	filepos_t Result;

	FirstFrameLocation = input.getFilePointer(); // will be updated accordingly below

	if (ReadFully == SCOPE_ALL_DATA)
	{
		Result = EbmlBinary::ReadData(input, ReadFully);
        binary *cursor = EbmlBinary::GetBuffer();
		uint8 BlockHeadSize = 4;

		// update internal values
		TrackNumber = *cursor++;
		if ((TrackNumber & 0x80) == 0) {
			// there is extra data
			if ((TrackNumber & 0x40) == 0) {
				// We don't support track numbers that large !
				return Result;
			}
			TrackNumber = (TrackNumber & 0x3F) << 8;
			TrackNumber += *cursor++;
			BlockHeadSize++;
		} else {
			TrackNumber &= 0x7F;
		}

		big_int16 b16;
		b16.Eval(cursor);
		LocalTimecode = int16(b16);
		bLocalTimecodeUsed = true;
		cursor += 2;

		if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
			bIsKeyframe = (*cursor & 0x80) != 0;
			bIsDiscardable = (*cursor & 0x01) != 0;
		}
		mInvisible = (*cursor & 0x08) >> 3;
		mLacing = LacingType((*cursor++ & 0x06) >> 1);

		// put all Frames in the list
		if (mLacing == LACING_NONE) {
			FirstFrameLocation += cursor - EbmlBinary::GetBuffer();
			DataBuffer * soloFrame = new DataBuffer(cursor, GetSize() - BlockHeadSize);
			myBuffers.push_back(soloFrame);
			SizeList.resize(1);
			SizeList[0] = GetSize() - BlockHeadSize;
		} else {
			// read the number of frames in the lace
			uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
			uint8 FrameNum = *cursor++; // number of frames in the lace - 1
			// read the list of frame sizes
			uint8 Index;
			int32 FrameSize;
			uint32 SizeRead;
			uint64 SizeUnknown;

			SizeList.resize(FrameNum + 1);

			switch (mLacing)
			{
			case LACING_XIPH:
				for (Index=0; Index<FrameNum; Index++) {
					// get the size of the frame
					FrameSize = 0;
					do {
						FrameSize += uint8(*cursor);
						LastBufferSize--;
					} while (*cursor++ == 0xFF);
					SizeList[Index] = FrameSize;
					LastBufferSize -= FrameSize;
				}
				SizeList[Index] = LastBufferSize;
				break;
			case LACING_EBML:
				SizeRead = LastBufferSize;
				FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
				SizeList[0] = FrameSize;
				cursor += SizeRead;
				LastBufferSize -= FrameSize + SizeRead;

				for (Index=1; Index<FrameNum; Index++) {
					// get the size of the frame
					SizeRead = LastBufferSize;
					FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
					SizeList[Index] = FrameSize;
					cursor += SizeRead;
					LastBufferSize -= FrameSize + SizeRead;
				}
				SizeList[Index] = LastBufferSize;
				break;
			case LACING_FIXED:
				for (Index=0; Index<=FrameNum; Index++) {
					// get the size of the frame
					SizeList[Index] = LastBufferSize / (FrameNum + 1);
				}
				break;
			default: // other lacing not supported
				assert(0);
			}

			FirstFrameLocation += cursor - EbmlBinary::GetBuffer();

			for (Index=0; Index<=FrameNum; Index++) {
				DataBuffer * lacedFrame = new DataBuffer(cursor, SizeList[Index]);
				myBuffers.push_back(lacedFrame);
				cursor += SizeList[Index];
			}
		}
		SetValueIsSet();
	}
コード例 #28
0
ファイル: EbmlMaster.cpp プロジェクト: ares89/vlc
/*!
	\todo this code is very suspicious !
*/
filepos_t EbmlMaster::ReadData(IOCallback & input, ScopeMode ReadFully)
{
	input.setFilePointer(GetSize(), seek_current);
	return GetSize();
}
コード例 #29
0
ファイル: KaxBlock.cpp プロジェクト: ares89/vlc
/*!
	\todo more optimisation is possible (render the Block head and don't copy the buffer in memory, care should be taken with the allocation of Data)
	\todo the actual timecode to write should be retrieved from the Cluster from here
*/
filepos_t KaxInternalBlock::RenderData(IOCallback & output, bool bForceRender, bool bSaveDefault)
{
	if (myBuffers.size() == 0) {
		return 0;
	} else {
		assert(TrackNumber < 0x4000);
		binary BlockHead[5], *cursor = BlockHead;
		unsigned int i;

		if (myBuffers.size() == 1) {
			SetSize_(4);
			mLacing = LACING_NONE;
		} else {
			if (mLacing == LACING_NONE)
				mLacing = LACING_EBML; // supposedly the best of all
			SetSize_(4 + 1); // 1 for the lacing head (number of laced elements)
		}
		if (TrackNumber > 0x80)
			SetSize_(GetSize() + 1);

		// write Block Head
		if (TrackNumber < 0x80) {
			*cursor++ = TrackNumber | 0x80; // set the first bit to 1 
		} else {
			*cursor++ = (TrackNumber >> 8) | 0x40; // set the second bit to 1
			*cursor++ = TrackNumber & 0xFF;
		}

		assert(ParentCluster != NULL);
		int16 ActualTimecode = ParentCluster->GetBlockLocalTimecode(Timecode);
		big_int16 b16(ActualTimecode);
		b16.Fill(cursor);
		cursor += 2;

		*cursor = 0; // flags

		if (mLacing == LACING_AUTO) {
			mLacing = GetBestLacingType();
		}

		// invisible flag
		if (mInvisible)
			*cursor = 0x08;

		if (bIsSimple) {
			if (bIsKeyframe)
				*cursor |= 0x80;
			if (bIsDiscardable)
				*cursor |= 0x01;
		}
		
		// lacing flag
		switch (mLacing)
		{
		case LACING_XIPH:
			*cursor++ |= 0x02;
			break;
		case LACING_EBML:
			*cursor++ |= 0x06;
			break;
		case LACING_FIXED:
			*cursor++ |= 0x04;
			break;
		case LACING_NONE:
			break;
	    default:
			assert(0);
		}

		output.writeFully(BlockHead, 4 + ((TrackNumber > 0x80) ? 1 : 0));

		binary tmpValue;
		switch (mLacing)
		{
		case LACING_XIPH:
			// number of laces
			tmpValue = myBuffers.size()-1;
			output.writeFully(&tmpValue, 1);

			// set the size of each member in the lace
			for (i=0; i<myBuffers.size()-1; i++) {
				tmpValue = 0xFF;
				uint16 tmpSize = myBuffers[i]->Size();
				while (tmpSize >= 0xFF) {
					output.writeFully(&tmpValue, 1);
					SetSize_(GetSize() + 1);
					tmpSize -= 0xFF;
				}
				tmpValue = binary(tmpSize);
				output.writeFully(&tmpValue, 1);
				SetSize_(GetSize() + 1);
			}
			break;
		case LACING_EBML:
			// number of laces
			tmpValue = myBuffers.size()-1;
			output.writeFully(&tmpValue, 1);

			{
				int64 _Size;
				int _CodedSize;
				binary _FinalHead[8]; // 64 bits max coded size

				_Size = myBuffers[0]->Size();

				_CodedSize = CodedSizeLength(_Size, 0, IsFiniteSize());

				// first size in the lace is not a signed
				CodedValueLength(_Size, _CodedSize, _FinalHead);
				output.writeFully(_FinalHead, _CodedSize);
				SetSize_(GetSize() + _CodedSize);

				// set the size of each member in the lace
				for (i=1; i<myBuffers.size()-1; i++) {
					_Size = int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size());
					_CodedSize = CodedSizeLengthSigned(_Size, 0);
					CodedValueLengthSigned(_Size, _CodedSize, _FinalHead);
					output.writeFully(_FinalHead, _CodedSize);
					SetSize_(GetSize() + _CodedSize);
				}
			}
			break;
		case LACING_FIXED:
			// number of laces
			tmpValue = myBuffers.size()-1;
			output.writeFully(&tmpValue, 1);
			break;
		case LACING_NONE:
			break;
	    default:
			assert(0);
		}

		// put the data of each frame
		for (i=0; i<myBuffers.size(); i++) {
			output.writeFully(myBuffers[i]->Buffer(), myBuffers[i]->Size());
			SetSize_(GetSize() + myBuffers[i]->Size());
		}
	}

	return GetSize();
}
コード例 #30
0
ファイル: KaxBlock.cpp プロジェクト: PeterZs/lumahdrv
/*!
  \todo better zero copy handling
*/
filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
{
  filepos_t Result;

  FirstFrameLocation = input.getFilePointer(); // will be updated accordingly below

  SetValueIsSet(false);

  try {
    if (ReadFully == SCOPE_ALL_DATA) {
      Result = EbmlBinary::ReadData(input, ReadFully);
      if (Result != GetSize())
        throw SafeReadIOCallback::EndOfStreamX(GetSize() - Result);

      binary *BufferStart = EbmlBinary::GetBuffer();

      SafeReadIOCallback Mem(*this);
      uint8 BlockHeadSize = 4;

      // update internal values
      TrackNumber = Mem.GetUInt8();
      if ((TrackNumber & 0x80) == 0) {
        // there is extra data
        if ((TrackNumber & 0x40) == 0) {
          // We don't support track numbers that large !
          throw SafeReadIOCallback::EndOfStreamX(0);
        }
        TrackNumber = (TrackNumber & 0x3F) << 8;
        TrackNumber += Mem.GetUInt8();
        BlockHeadSize++;
      } else {
        TrackNumber &= 0x7F;
      }

      LocalTimecode = int16(Mem.GetUInt16BE());
      bLocalTimecodeUsed = true;

      uint8 Flags = Mem.GetUInt8();
      if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
        bIsKeyframe = (Flags & 0x80) != 0;
        bIsDiscardable = (Flags & 0x01) != 0;
      }
      mInvisible = (Flags & 0x08) >> 3;
      mLacing = LacingType((Flags & 0x06) >> 1);

      // put all Frames in the list
      if (mLacing == LACING_NONE) {
        FirstFrameLocation += Mem.GetPosition();
        DataBuffer * soloFrame = new DataBuffer(BufferStart + Mem.GetPosition(), GetSize() - BlockHeadSize);
        myBuffers.push_back(soloFrame);
        SizeList.resize(1);
        SizeList[0] = GetSize() - BlockHeadSize;
      } else {
        // read the number of frames in the lace
        uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
        uint8 FrameNum = Mem.GetUInt8(); // number of frames in the lace - 1
        // read the list of frame sizes
        uint8 Index;
        int32 FrameSize;
        uint32 SizeRead;
        uint64 SizeUnknown;

        SizeList.resize(FrameNum + 1);

        switch (mLacing) {
          case LACING_XIPH:
            for (Index=0; Index<FrameNum; Index++) {
              // get the size of the frame
              FrameSize = 0;
              uint8 Value;
              do {
                Value = Mem.GetUInt8();
                FrameSize += Value;
                LastBufferSize--;
              } while (Value == 0xFF);
              SizeList[Index] = FrameSize;
              LastBufferSize -= FrameSize;
            }
            SizeList[Index] = LastBufferSize;
            break;
          case LACING_EBML:
            SizeRead = LastBufferSize;
            FrameSize = ReadCodedSizeValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
            SizeList[0] = FrameSize;
            Mem.Skip(SizeRead);
            LastBufferSize -= FrameSize + SizeRead;

            for (Index=1; Index<FrameNum; Index++) {
              // get the size of the frame
              SizeRead = LastBufferSize;
              FrameSize += ReadCodedSizeSignedValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
              SizeList[Index] = FrameSize;
              Mem.Skip(SizeRead);
              LastBufferSize -= FrameSize + SizeRead;
            }
            if (Index <= FrameNum) // Safety check if FrameNum == 0
              SizeList[Index] = LastBufferSize;
            break;
          case LACING_FIXED:
            for (Index=0; Index<=FrameNum; Index++) {
              // get the size of the frame
              SizeList[Index] = LastBufferSize / (FrameNum + 1);
            }
            break;
          default: // other lacing not supported
            assert(0);
        }

        FirstFrameLocation += Mem.GetPosition();

        for (Index=0; Index<=FrameNum; Index++) {
          DataBuffer * lacedFrame = new DataBuffer(BufferStart + Mem.GetPosition(), SizeList[Index]);
          myBuffers.push_back(lacedFrame);
          Mem.Skip(SizeList[Index]);
        }
      }

      binary *BufferEnd = BufferStart + GetSize();
      size_t NumFrames  = myBuffers.size();

      // Sanity checks for frame pointers and boundaries.
      for (size_t Index = 0; Index < NumFrames; ++Index) {
        binary *FrameStart  = myBuffers[Index]->Buffer();
        binary *FrameEnd    = FrameStart + myBuffers[Index]->Size();
        binary *ExpectedEnd = (Index + 1) < NumFrames ? myBuffers[Index + 1]->Buffer() : BufferEnd;

        if ((FrameStart < BufferStart) || (FrameEnd > BufferEnd) || (FrameEnd != ExpectedEnd))
          throw SafeReadIOCallback::EndOfStreamX(0);
      }

      SetValueIsSet();
    } else if (ReadFully == SCOPE_PARTIAL_DATA) {
      binary _TempHead[5];
      Result = input.read(_TempHead, 5);
      if (Result != 5)
        throw SafeReadIOCallback::EndOfStreamX(0);
      binary *cursor = _TempHead;
      binary *_tmpBuf;
      uint8 BlockHeadSize = 4;

      // update internal values
      TrackNumber = *cursor++;
      if ((TrackNumber & 0x80) == 0) {
        // there is extra data
        if ((TrackNumber & 0x40) == 0) {
          // We don't support track numbers that large !
          return Result;
        }
        TrackNumber = (TrackNumber & 0x3F) << 8;
        TrackNumber += *cursor++;
        BlockHeadSize++;
      } else {
        TrackNumber &= 0x7F;
      }

      big_int16 b16;
      b16.Eval(cursor);
      LocalTimecode = int16(b16);
      bLocalTimecodeUsed = true;
      cursor += 2;

      if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
        bIsKeyframe = (*cursor & 0x80) != 0;
        bIsDiscardable = (*cursor & 0x01) != 0;
      }
      mInvisible = (*cursor & 0x08) >> 3;
      mLacing = LacingType((*cursor++ & 0x06) >> 1);
      if (cursor == &_TempHead[4]) {
        _TempHead[0] = _TempHead[4];
      } else {
        Result += input.read(_TempHead, 1);
      }

      FirstFrameLocation += cursor - _TempHead;

      // put all Frames in the list
      if (mLacing != LACING_NONE) {
        // read the number of frames in the lace
        uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
        uint8 FrameNum = _TempHead[0]; // number of frames in the lace - 1
        // read the list of frame sizes
        uint8 Index;
        int32 FrameSize;
        uint32 SizeRead;
        uint64 SizeUnknown;

        SizeList.resize(FrameNum + 1);

        switch (mLacing) {
          case LACING_XIPH:
            for (Index=0; Index<FrameNum; Index++) {
              // get the size of the frame
              FrameSize = 0;
              do {
                Result += input.read(_TempHead, 1);
                FrameSize += uint8(_TempHead[0]);
                LastBufferSize--;

                FirstFrameLocation++;
              } while (_TempHead[0] == 0xFF);

              FirstFrameLocation++;
              SizeList[Index] = FrameSize;
              LastBufferSize -= FrameSize;
            }
            SizeList[Index] = LastBufferSize;
            break;
          case LACING_EBML:
            SizeRead = LastBufferSize;
            cursor = _tmpBuf = new binary[FrameNum*4]; /// \warning assume the mean size will be coded in less than 4 bytes
            Result += input.read(cursor, FrameNum*4);
            FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
            SizeList[0] = FrameSize;
            cursor += SizeRead;
            LastBufferSize -= FrameSize + SizeRead;

            for (Index=1; Index<FrameNum; Index++) {
              // get the size of the frame
              SizeRead = LastBufferSize;
              FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
              SizeList[Index] = FrameSize;
              cursor += SizeRead;
              LastBufferSize -= FrameSize + SizeRead;
            }

            FirstFrameLocation += cursor - _tmpBuf;

            SizeList[Index] = LastBufferSize;
            delete [] _tmpBuf;
            break;
          case LACING_FIXED:
            for (Index=0; Index<=FrameNum; Index++) {
              // get the size of the frame
              SizeList[Index] = LastBufferSize / (FrameNum + 1);
            }
            break;
          default: // other lacing not supported
            assert(0);
        }
      } else {
        SizeList.resize(1);
        SizeList[0] = GetSize() - BlockHeadSize;
      }
      SetValueIsSet(false);
      Result = GetSize();
    } else {