00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "MatroskaFile.h"
00024 #include "..\..\..\DSUtil\DSUtil.h"
00025
00026 using namespace MatroskaWriter;
00027
00028 static void bswap(BYTE* s, int len)
00029 {
00030 for(BYTE* d = s + len-1; s < d; s++, d--)
00031 *s ^= *d, *d ^= *s, *s ^= *d;
00032 }
00033
00034
00035
00036 CID::CID(DWORD id) : m_id(id)
00037 {
00038 }
00039
00040 QWORD CID::Size(bool fWithHeader)
00041 {
00042 return CUInt(0, m_id).Size(false);
00043 }
00044
00045 HRESULT CID::Write(IStream* pStream)
00046 {
00047 QWORD len = CID::Size();
00048 DWORD id = m_id;
00049 bswap((BYTE*)&id, (int)len);
00050 *(BYTE*)&id = ((*(BYTE*)&id)&(1<<(8-len))-1)|(1<<(8-len));
00051 return pStream->Write(&id, (ULONG)len, NULL);
00052 }
00053
00054 QWORD CID::HeaderSize(QWORD len)
00055 {
00056 return CID::Size() + CLength(len).Size();
00057 }
00058
00059 HRESULT CID::HeaderWrite(IStream* pStream)
00060 {
00061 CID::Write(pStream);
00062 CLength(Size(false)).Write(pStream);
00063 return S_OK;
00064 }
00065
00066 QWORD CBinary::Size(bool fWithHeader)
00067 {
00068 if(GetSize() == 0) return 0;
00069
00070 QWORD len = 0;
00071 len += GetSize();
00072 if(fWithHeader) len += HeaderSize(len);
00073 return len;
00074 }
00075
00076 HRESULT CBinary::Write(IStream* pStream)
00077 {
00078 if(GetSize() == 0) return S_OK;
00079
00080 HeaderWrite(pStream);
00081 return pStream->Write(GetData(), GetSize(), NULL);
00082 }
00083
00084 QWORD CANSI::Size(bool fWithHeader)
00085 {
00086 if(GetLength() == 0) return 0;
00087
00088 QWORD len = 0;
00089 len += GetLength();
00090 if(fWithHeader) len += HeaderSize(len);
00091 return len;
00092 }
00093
00094 HRESULT CANSI::Write(IStream* pStream)
00095 {
00096 if(GetLength() == 0) return S_OK;
00097
00098 HeaderWrite(pStream);
00099 return pStream->Write((LPCSTR)*this, GetLength(), NULL);
00100 }
00101
00102 QWORD CUTF8::Size(bool fWithHeader)
00103 {
00104 if(GetLength() == 0) return 0;
00105
00106 QWORD len = 0;
00107 len += UTF16To8(*this).GetLength();
00108 if(fWithHeader) len += HeaderSize(len);
00109 return len;
00110 }
00111
00112 HRESULT CUTF8::Write(IStream* pStream)
00113 {
00114 if(GetLength() == 0) return S_OK;
00115
00116 HeaderWrite(pStream);
00117 CStringA str = UTF16To8(*this);
00118 return pStream->Write((BYTE*)(LPCSTR)str, str.GetLength(), NULL);
00119 }
00120
00121 template<class T, class BASE>
00122 QWORD CSimpleVar<T, BASE>::Size(bool fWithHeader)
00123 {
00124 if(!m_fSet) return 0;
00125
00126 QWORD len = 0;
00127 len += sizeof(T);
00128 if(fWithHeader) len += HeaderSize(len);
00129 return len;
00130 }
00131
00132 template<class T, class BASE>
00133 HRESULT CSimpleVar<T, BASE>::Write(IStream* pStream)
00134 {
00135 if(!m_fSet) return S_OK;
00136
00137 HeaderWrite(pStream);
00138 T val = m_val;
00139 bswap((BYTE*)&val, sizeof(T));
00140 return pStream->Write(&val, sizeof(T), NULL);
00141 }
00142
00143 QWORD CUInt::Size(bool fWithHeader)
00144 {
00145 if(!m_fSet) return 0;
00146
00147 QWORD len = 0;
00148
00149 if(m_val == 0)
00150 {
00151 len++;
00152 }
00153 else
00154 {
00155 for(int i = 8; i > 0; i--)
00156 {
00157 if(((0xffi64<<((i-1)*8))&m_val))
00158 {
00159 len += i;
00160 break;
00161 }
00162 }
00163 }
00164 if(fWithHeader) len += HeaderSize(len);
00165 return len;
00166 }
00167
00168 HRESULT CUInt::Write(IStream* pStream)
00169 {
00170 if(!m_fSet) return S_OK;
00171
00172 CID::Write(pStream);
00173 CLength l(Size(false));
00174 l.Write(pStream);
00175 UINT64 val = m_val;
00176 bswap((BYTE*)&val, (int)l);
00177 return pStream->Write(&val, (ULONG)l, NULL);
00178 }
00179
00180 QWORD CInt::Size(bool fWithHeader)
00181 {
00182 if(!m_fSet) return 0;
00183
00184 QWORD len = 0;
00185
00186 if(m_val == 0)
00187 {
00188 len++;
00189 }
00190 else
00191 {
00192 UINT64 val = m_val >= 0 ? m_val : -m_val;
00193 for(int i = 8; i > 0; i--)
00194 {
00195 if(((0xffi64<<((i-1)*8))&val))
00196 {
00197 len += i;
00198 if(m_val < 0 && !(m_val&(0x80<<(i-1))))
00199 len++;
00200 break;
00201 }
00202 }
00203 }
00204 if(fWithHeader) len += HeaderSize(len);
00205 return len;
00206 }
00207
00208 HRESULT CInt::Write(IStream* pStream)
00209 {
00210 if(!m_fSet) return S_OK;
00211
00212 CID::Write(pStream);
00213 CLength l(Size(false));
00214 l.Write(pStream);
00215 UINT64 val = m_val;
00216 bswap((BYTE*)&val, (int)l);
00217 return pStream->Write(&val, (ULONG)l, NULL);
00218 }
00219
00220 QWORD CLength::Size(bool fWithHeader)
00221 {
00222 if(m_len == 0x00FFFFFFFFFFFFFFi64)
00223 return 8;
00224
00225 QWORD len = 0;
00226 for(int i = 1; i <= 8; i++)
00227 {
00228 if(!(m_len&(~((1i64<<(7*i))-1))) && (m_len&((1i64<<(7*i))-1)) != ((1i64<<(7*i))-1))
00229 {
00230 len += i;
00231 break;
00232 }
00233 }
00234 return len;
00235 }
00236
00237 HRESULT CLength::Write(IStream* pStream)
00238 {
00239 QWORD len = Size(false);
00240 UINT64 val = m_len;
00241 bswap((BYTE*)&val, (int)len);
00242 *(BYTE*)&val = ((*(BYTE*)&val)&(1<<(8-len))-1)|(1<<(8-len));
00243 return pStream->Write(&val, (ULONG)len, NULL);
00244 }
00245
00246
00247
00248 EBML::EBML(DWORD id)
00249 : CID(id)
00250 , EBMLVersion(0x4286)
00251 , EBMLReadVersion(0x42F7)
00252 , EBMLMaxIDLength(0x42F2)
00253 , EBMLMaxSizeLength(0x42F3)
00254 , DocType(0x4282)
00255 , DocTypeVersion(0x4287)
00256 , DocTypeReadVersion(0x4285)
00257 {
00258 }
00259
00260 QWORD EBML::Size(bool fWithHeader)
00261 {
00262 QWORD len = 0;
00263 len += EBMLVersion.Size();
00264 len += EBMLReadVersion.Size();
00265 len += EBMLMaxIDLength.Size();
00266 len += EBMLMaxSizeLength.Size();
00267 len += DocType.Size();
00268 len += DocTypeVersion.Size();
00269 len += DocTypeReadVersion.Size();
00270 if(fWithHeader) len += HeaderSize(len);
00271 return len;
00272 }
00273
00274 HRESULT EBML::Write(IStream* pStream)
00275 {
00276 HeaderWrite(pStream);
00277 EBMLVersion.Write(pStream);
00278 EBMLReadVersion.Write(pStream);
00279 EBMLMaxIDLength.Write(pStream);
00280 EBMLMaxSizeLength.Write(pStream);
00281 DocType.Write(pStream);
00282 DocTypeVersion.Write(pStream);
00283 DocTypeReadVersion.Write(pStream);
00284 return S_OK;
00285 }
00286
00287 Info::Info(DWORD id)
00288 : CID(id)
00289 , SegmentUID(0x73A4)
00290 , SegmentFilename(0x7384)
00291 , PrevUID(0x3CB923)
00292 , PrevFilename(0x3C83AB)
00293 , NextUID(0x3EB923)
00294 , NextFilename(0x3E83BB)
00295 , TimeCodeScale(0x2AD7B1, 1000000ui64)
00296 , Duration(0x4489)
00297 , DateUTC(0x4461)
00298 , Title(0x7BA9)
00299 , MuxingApp(0x4D80)
00300 , WritingApp(0x5741)
00301 {
00302 }
00303
00304 QWORD Info::Size(bool fWithHeader)
00305 {
00306 QWORD len = 0;
00307 len += SegmentUID.Size();
00308 len += PrevUID.Size();
00309 len += NextUID.Size();
00310 len += SegmentFilename.Size();
00311 len += PrevFilename.Size();
00312 len += NextFilename.Size();
00313 len += TimeCodeScale.Size();
00314 len += Duration.Size();
00315 len += DateUTC.Size();
00316 len += Title.Size();
00317 len += MuxingApp.Size();
00318 len += WritingApp.Size();
00319 if(fWithHeader) len += HeaderSize(len);
00320 return len;
00321 }
00322
00323 HRESULT Info::Write(IStream* pStream)
00324 {
00325 HeaderWrite(pStream);
00326 SegmentUID.Write(pStream);
00327 PrevUID.Write(pStream);
00328 NextUID.Write(pStream);
00329 SegmentFilename.Write(pStream);
00330 PrevFilename.Write(pStream);
00331 NextFilename.Write(pStream);
00332 TimeCodeScale.Write(pStream);
00333 Duration.Write(pStream);
00334 DateUTC.Write(pStream);
00335 Title.Write(pStream);
00336 MuxingApp.Write(pStream);
00337 WritingApp.Write(pStream);
00338 return S_OK;
00339 }
00340
00341 Segment::Segment(DWORD id)
00342 : CID(id)
00343 {
00344 }
00345
00346 QWORD Segment::Size(bool fWithHeader)
00347 {
00348 return 0x00FFFFFFFFFFFFFFi64;
00349
00350
00351
00352
00353
00354 }
00355
00356 HRESULT Segment::Write(IStream* pStream)
00357 {
00358 HeaderWrite(pStream);
00359 return S_OK;
00360 }
00361
00362 Track::Track(DWORD id)
00363 : CID(id)
00364 {
00365 }
00366
00367 QWORD Track::Size(bool fWithHeader)
00368 {
00369 QWORD len = 0;
00370 len += TrackEntries.Size();
00371 if(fWithHeader) len += HeaderSize(len);
00372 return len;
00373 }
00374
00375 HRESULT Track::Write(IStream* pStream)
00376 {
00377 HeaderWrite(pStream);
00378 TrackEntries.Write(pStream);
00379 return S_OK;
00380 }
00381
00382 TrackEntry::TrackEntry(DWORD id)
00383 : CID(id)
00384 , TrackNumber(0xD7)
00385 , TrackUID(0x73C5)
00386 , TrackType(0x83)
00387 , FlagEnabled(0xB9)
00388 , FlagDefault(0x88)
00389 , FlagLacing(0x9C)
00390 , MinCache(0x6DE7)
00391 , MaxCache(0x6DF8)
00392 , Name(0x536E)
00393 , Language(0x22B59C)
00394 , CodecID(0x86)
00395 , CodecPrivate(0x63A2)
00396 , CodecName(0x258688)
00397 , CodecSettings(0x3A9697)
00398 , CodecInfoURL(0x3B4040)
00399 , CodecDownloadURL(0x26B240)
00400 , CodecDecodeAll(0xAA)
00401 , TrackOverlay(0x6FAB)
00402 , DefaultDuration(0x23E383)
00403 , v(0xE0)
00404 , a(0xE1)
00405 {
00406 DescType = NoDesc;
00407 }
00408
00409 QWORD TrackEntry::Size(bool fWithHeader)
00410 {
00411 QWORD len = 0;
00412 len += TrackNumber.Size();
00413 len += TrackUID.Size();
00414 len += TrackType.Size();
00415 len += FlagEnabled.Size();
00416 len += FlagDefault.Size();
00417 len += FlagLacing.Size();
00418 len += MinCache.Size();
00419 len += MaxCache.Size();
00420 len += Name.Size();
00421 len += Language.Size();
00422 len += CodecID.Size();
00423 len += CodecPrivate.Size();
00424 len += CodecName.Size();
00425 len += CodecSettings.Size();
00426 len += CodecInfoURL.Size();
00427 len += CodecDownloadURL.Size();
00428 len += CodecDecodeAll.Size();
00429 len += TrackOverlay.Size();
00430 len += DefaultDuration.Size();
00431 if(DescType == TypeVideo) len += v.Size();
00432 if(DescType == TypeAudio) len += a.Size();
00433 if(fWithHeader) len += HeaderSize(len);
00434 return len;
00435 }
00436
00437 HRESULT TrackEntry::Write(IStream* pStream)
00438 {
00439 HeaderWrite(pStream);
00440 TrackNumber.Write(pStream);
00441 TrackUID.Write(pStream);
00442 TrackType.Write(pStream);
00443 FlagEnabled.Write(pStream);
00444 FlagDefault.Write(pStream);
00445 FlagLacing.Write(pStream);
00446 MinCache.Write(pStream);
00447 MaxCache.Write(pStream);
00448 Name.Write(pStream);
00449 Language.Write(pStream);
00450 CodecID.Write(pStream);
00451 CodecPrivate.Write(pStream);
00452 CodecName.Write(pStream);
00453 CodecSettings.Write(pStream);
00454 CodecInfoURL.Write(pStream);
00455 CodecDownloadURL.Write(pStream);
00456 CodecDecodeAll.Write(pStream);
00457 TrackOverlay.Write(pStream);
00458 DefaultDuration.Write(pStream);
00459 if(DescType == TypeVideo) v.Write(pStream);
00460 if(DescType == TypeAudio) a.Write(pStream);
00461 return S_OK;
00462 }
00463
00464 Video::Video(DWORD id)
00465 : CID(id)
00466 , FlagInterlaced(0x9A)
00467 , StereoMode(0x53B8)
00468 , PixelWidth(0xB0)
00469 , PixelHeight(0xBA)
00470 , DisplayWidth(0x54B0)
00471 , DisplayHeight(0x54BA)
00472 , DisplayUnit(0x54B2)
00473 , AspectRatioType(0x54B3)
00474 , ColourSpace(0x2EB524)
00475 , GammaValue(0x2FB523)
00476 , FramePerSec(0x2383E3)
00477 {
00478 }
00479
00480 QWORD Video::Size(bool fWithHeader)
00481 {
00482 QWORD len = 0;
00483 len += FlagInterlaced.Size();
00484 len += StereoMode.Size();
00485 len += PixelWidth.Size();
00486 len += PixelHeight.Size();
00487 len += DisplayWidth.Size();
00488 len += DisplayHeight.Size();
00489 len += DisplayUnit.Size();
00490 len += AspectRatioType.Size();
00491 len += ColourSpace.Size();
00492 len += GammaValue.Size();
00493 len += FramePerSec.Size();
00494 if(fWithHeader) len += HeaderSize(len);
00495 return len;
00496 }
00497
00498 HRESULT Video::Write(IStream* pStream)
00499 {
00500 HeaderWrite(pStream);
00501 FlagInterlaced.Write(pStream);
00502 StereoMode.Write(pStream);
00503 PixelWidth.Write(pStream);
00504 PixelHeight.Write(pStream);
00505 DisplayWidth.Write(pStream);
00506 DisplayHeight.Write(pStream);
00507 DisplayUnit.Write(pStream);
00508 AspectRatioType.Write(pStream);
00509 ColourSpace.Write(pStream);
00510 GammaValue.Write(pStream);
00511 FramePerSec.Write(pStream);
00512 return S_OK;
00513 }
00514
00515 Audio::Audio(DWORD id)
00516 : CID(id)
00517 , SamplingFrequency(0xB5)
00518 , OutputSamplingFrequency(0x78B5)
00519 , Channels(0x9F)
00520 , ChannelPositions(0x7D7B)
00521 , BitDepth(0x6264)
00522 {
00523 }
00524
00525 QWORD Audio::Size(bool fWithHeader)
00526 {
00527 QWORD len = 0;
00528 len += SamplingFrequency.Size();
00529 len += OutputSamplingFrequency.Size();
00530 len += Channels.Size();
00531 len += ChannelPositions.Size();
00532 len += BitDepth.Size();
00533 if(fWithHeader) len += HeaderSize(len);
00534 return len;
00535 }
00536
00537 HRESULT Audio::Write(IStream* pStream)
00538 {
00539 HeaderWrite(pStream);
00540 SamplingFrequency.Write(pStream);
00541 OutputSamplingFrequency.Write(pStream);
00542 Channels.Write(pStream);
00543 ChannelPositions.Write(pStream);
00544 BitDepth.Write(pStream);
00545 return S_OK;
00546 }
00547
00548 Cluster::Cluster(DWORD id)
00549 : CID(id)
00550 , TimeCode(0xE7)
00551 , Position(0xA7)
00552 , PrevSize(0xAB)
00553 {
00554 }
00555
00556 QWORD Cluster::Size(bool fWithHeader)
00557 {
00558 QWORD len = 0;
00559 len += TimeCode.Size();
00560 len += Position.Size();
00561 len += PrevSize.Size();
00562 len += BlockGroups.Size();
00563 if(fWithHeader) len += HeaderSize(len);
00564 return len;
00565 }
00566
00567 HRESULT Cluster::Write(IStream* pStream)
00568 {
00569 HeaderWrite(pStream);
00570 TimeCode.Write(pStream);
00571 Position.Write(pStream);
00572 PrevSize.Write(pStream);
00573 BlockGroups.Write(pStream);
00574 return S_OK;
00575 }
00576
00577 BlockGroup::BlockGroup(DWORD id)
00578 : CID(id)
00579 , BlockDuration(0x9B)
00580 , ReferencePriority(0xFA)
00581 , ReferenceBlock(0xFB)
00582 , ReferenceVirtual(0xFD)
00583 , CodecState(0xA4)
00584 {
00585 }
00586
00587 QWORD BlockGroup::Size(bool fWithHeader)
00588 {
00589 QWORD len = 0;
00590 len += BlockDuration.Size();
00591 len += ReferencePriority.Size();
00592 len += ReferenceBlock.Size();
00593 len += ReferenceVirtual.Size();
00594 len += CodecState.Size();
00595 len += Block.Size();
00596 if(fWithHeader) len += HeaderSize(len);
00597 return len;
00598 }
00599
00600 HRESULT BlockGroup::Write(IStream* pStream)
00601 {
00602 HeaderWrite(pStream);
00603 BlockDuration.Write(pStream);
00604 ReferencePriority.Write(pStream);
00605 ReferenceBlock.Write(pStream);
00606 ReferenceVirtual.Write(pStream);
00607 CodecState.Write(pStream);
00608 Block.Write(pStream);
00609 return S_OK;
00610 }
00611
00612 CBlock::CBlock(DWORD id)
00613 : CID(id)
00614 , TimeCode(0)
00615 {
00616 }
00617
00618 QWORD CBlock::Size(bool fWithHeader)
00619 {
00620 QWORD len = 0;
00621 len += TrackNumber.Size() + 2 + 1;
00622 if(BlockData.GetCount() > 1)
00623 {
00624 len += 1;
00625 POSITION pos = BlockData.GetHeadPosition();
00626 while(pos)
00627 {
00628 CBinary* b = BlockData.GetNext(pos);
00629 if(pos) len += b->GetCount()/255 + 1;
00630 }
00631 }
00632 POSITION pos = BlockData.GetHeadPosition();
00633 while(pos)
00634 {
00635 CBinary* b = BlockData.GetNext(pos);
00636 len += b->GetCount();
00637 }
00638 if(fWithHeader) len += HeaderSize(len);
00639 return len;
00640 }
00641
00642 HRESULT CBlock::Write(IStream* pStream)
00643 {
00644 HeaderWrite(pStream);
00645 TrackNumber.Write(pStream);
00646 short t = (short)TimeCode;
00647 bswap((BYTE*)&t, 2);
00648 pStream->Write(&t, 2, NULL);
00649 BYTE Lacing = 0;
00650 BYTE n = BlockData.GetCount();
00651 if(n > 1) Lacing |= 2;
00652 pStream->Write(&Lacing, 1, NULL);
00653 if(n > 1)
00654 {
00655 pStream->Write(&n, 1, NULL);
00656 POSITION pos = BlockData.GetHeadPosition();
00657 while(pos)
00658 {
00659 CBinary* b = BlockData.GetNext(pos);
00660 if(pos)
00661 {
00662 int len = b->GetCount();
00663 while(len >= 0)
00664 {
00665 n = min(len, 255);
00666 pStream->Write(&n, 1, NULL);
00667 len -= 255;
00668 }
00669 }
00670 }
00671 }
00672 POSITION pos = BlockData.GetHeadPosition();
00673 while(pos)
00674 {
00675 CBinary* b = BlockData.GetNext(pos);
00676 pStream->Write(b->GetData(), b->GetCount(), NULL);
00677 }
00678 return S_OK;
00679 }
00680
00681 Cue::Cue(DWORD id)
00682 : CID(id)
00683 {
00684 }
00685
00686 QWORD Cue::Size(bool fWithHeader)
00687 {
00688 QWORD len = 0;
00689 len += CuePoints.Size();
00690 if(fWithHeader) len += HeaderSize(len);
00691 return len;
00692 }
00693
00694 HRESULT Cue::Write(IStream* pStream)
00695 {
00696 HeaderWrite(pStream);
00697 CuePoints.Write(pStream);
00698 return S_OK;
00699 }
00700
00701 CuePoint::CuePoint(DWORD id)
00702 : CID(id)
00703 , CueTime(0xB3)
00704 {
00705 }
00706
00707 QWORD CuePoint::Size(bool fWithHeader)
00708 {
00709 QWORD len = 0;
00710 len += CueTime.Size();
00711 len += CueTrackPositions.Size();
00712 if(fWithHeader) len += HeaderSize(len);
00713 return len;
00714 }
00715
00716 HRESULT CuePoint::Write(IStream* pStream)
00717 {
00718 HeaderWrite(pStream);
00719 CueTime.Write(pStream);
00720 CueTrackPositions.Write(pStream);
00721 return S_OK;
00722 }
00723
00724 CueTrackPosition::CueTrackPosition(DWORD id)
00725 : CID(id)
00726 , CueTrack(0xF7)
00727 , CueClusterPosition(0xF1)
00728 , CueBlockNumber(0x5387)
00729 , CueCodecState(0xEA)
00730 {
00731 }
00732
00733 QWORD CueTrackPosition::Size(bool fWithHeader)
00734 {
00735 QWORD len = 0;
00736 len += CueTrack.Size();
00737 len += CueClusterPosition.Size();
00738 len += CueBlockNumber.Size();
00739 len += CueCodecState.Size();
00740
00741 if(fWithHeader) len += HeaderSize(len);
00742 return len;
00743 }
00744
00745 HRESULT CueTrackPosition::Write(IStream* pStream)
00746 {
00747 HeaderWrite(pStream);
00748 CueTrack.Write(pStream);
00749 CueClusterPosition.Write(pStream);
00750 CueBlockNumber.Write(pStream);
00751 CueCodecState.Write(pStream);
00752
00753 return S_OK;
00754 }
00755
00756 Seek::Seek(DWORD id)
00757 : CID(id)
00758 {
00759 }
00760
00761 QWORD Seek::Size(bool fWithHeader)
00762 {
00763 QWORD len = 0;
00764 len += SeekHeads.Size();
00765 if(fWithHeader) len += HeaderSize(len);
00766 return len;
00767 }
00768
00769 HRESULT Seek::Write(IStream* pStream)
00770 {
00771 HeaderWrite(pStream);
00772 SeekHeads.Write(pStream);
00773 return S_OK;
00774 }
00775
00776 SeekID::SeekID(DWORD id)
00777 : CID(id)
00778 , m_id(0)
00779 {
00780 }
00781
00782 QWORD SeekID::Size(bool fWithHeader)
00783 {
00784 QWORD len = 0;
00785 len += m_id.Size();
00786 if(fWithHeader) len += HeaderSize(len);
00787 return len;
00788 }
00789
00790 HRESULT SeekID::Write(IStream* pStream)
00791 {
00792 HeaderWrite(pStream);
00793 m_id.Write(pStream);
00794 return S_OK;
00795 }
00796
00797 SeekHead::SeekHead(DWORD id)
00798 : CID(id)
00799 , Position(0x53AC)
00800 {
00801 }
00802
00803 QWORD SeekHead::Size(bool fWithHeader)
00804 {
00805 QWORD len = 0;
00806 len += ID.Size();
00807 len += Position.Size();
00808 if(fWithHeader) len += HeaderSize(len);
00809 return len;
00810 }
00811
00812 HRESULT SeekHead::Write(IStream* pStream)
00813 {
00814 HeaderWrite(pStream);
00815 ID.Write(pStream);
00816 Position.Write(pStream);
00817 return S_OK;
00818 }
00819
00820 Tags::Tags(DWORD id)
00821 : CID(id)
00822 {
00823 }
00824
00825 QWORD Tags::Size(bool fWithHeader)
00826 {
00827 QWORD len = 0;
00828
00829 if(fWithHeader) len += HeaderSize(len);
00830 return len;
00831 }
00832
00833 HRESULT Tags::Write(IStream* pStream)
00834 {
00835 HeaderWrite(pStream);
00836
00837 return S_OK;
00838 }
00839
00840 Void::Void(QWORD len, DWORD id)
00841 : CID(id)
00842 , m_len(len)
00843 {
00844 }
00845
00846 QWORD Void::Size(bool fWithHeader)
00847 {
00848 QWORD len = 0;
00849 len += m_len;
00850 if(fWithHeader) len += HeaderSize(len);
00851 return len;
00852 }
00853
00854 HRESULT Void::Write(IStream* pStream)
00855 {
00856 HeaderWrite(pStream);
00857 BYTE buff[64];
00858 memset(buff, 0x80, sizeof(buff));
00859 for(int len = (int)m_len; len > 0; len -= sizeof(buff))
00860 pStream->Write(buff, (ULONG)min(sizeof(buff), len), NULL);
00861 return S_OK;
00862 }