Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/FlvHandler.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/Archive/FlvHandler.cpp253
1 files changed, 118 insertions, 135 deletions
diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp
index a22c29e3..3bb4620b 100755..100644
--- a/CPP/7zip/Archive/FlvHandler.cpp
+++ b/CPP/7zip/Archive/FlvHandler.cpp
@@ -4,13 +4,13 @@
#include "../../../C/CpuArch.h"
-#include "Common/Buffer.h"
-#include "Common/ComTry.h"
-// #include "Common/Defs.h"
-#include "Common/MyString.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/MyString.h"
-#include "Windows/PropVariant.h"
+#include "../../Windows/PropVariant.h"
+#include "../Common/InBuffer.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamObjects.h"
@@ -29,9 +29,9 @@ namespace NArchive {
namespace NFlv {
static const UInt32 kFileSizeMax = (UInt32)1 << 30;
-static const int kNumChunksMax = (UInt32)1 << 23;
+static const UInt32 kNumChunksMax = (UInt32)1 << 23;
-const UInt32 kTagHeaderSize = 11;
+static const UInt32 kTagHeaderSize = 11;
static const Byte kFlag_Video = 1;
static const Byte kFlag_Audio = 4;
@@ -39,13 +39,11 @@ static const Byte kFlag_Audio = 4;
static const Byte kType_Audio = 8;
static const Byte kType_Video = 9;
static const Byte kType_Meta = 18;
-static const int kNumTypes = 19;
+static const unsigned kNumTypes = 19;
struct CItem
{
- UInt32 Offset;
- UInt32 Size;
- // UInt32 Time;
+ CByteBuffer Data;
Byte Type;
};
@@ -55,7 +53,7 @@ struct CItem2
Byte SubType;
Byte Props;
bool SameSubTypes;
- int NumChunks;
+ unsigned NumChunks;
size_t Size;
CReferenceBuf *BufSpec;
@@ -69,10 +67,12 @@ class CHandler:
public IInArchiveGetStream,
public CMyUnknownImp
{
- int _isRaw;
CMyComPtr<IInStream> _stream;
CObjectVector<CItem2> _items2;
// CByteBuffer _metadata;
+ bool _isRaw;
+ UInt64 _phySize;
+
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
AString GetComment();
public:
@@ -81,76 +81,64 @@ public:
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
};
-STATPROPSTG kProps[] =
+static const Byte kProps[] =
{
- { NULL, kpidSize, VT_UI8},
- { NULL, kpidNumBlocks, VT_UI4},
- { NULL, kpidComment, VT_BSTR}
+ kpidSize,
+ kpidNumBlocks,
+ kpidComment
};
-/*
-STATPROPSTG kArcProps[] =
-{
- { NULL, kpidComment, VT_BSTR}
-};
-*/
-
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO
+IMP_IInArchive_ArcProps_NO_Table
static const char *g_AudioTypes[16] =
{
- "pcm",
- "adpcm",
- "mp3",
- "pcm_le",
- "nellymoser16",
- "nellymoser8",
- "nellymoser",
- "g711a",
- "g711m",
- "audio9",
- "aac",
- "speex",
- "audio12",
- "audio13",
- "mp3",
- "audio15"
+ "pcm"
+ , "adpcm"
+ , "mp3"
+ , "pcm_le"
+ , "nellymoser16"
+ , "nellymoser8"
+ , "nellymoser"
+ , "g711a"
+ , "g711m"
+ , "audio9"
+ , "aac"
+ , "speex"
+ , "audio12"
+ , "audio13"
+ , "mp3"
+ , "audio15"
};
static const char *g_VideoTypes[16] =
{
- "video0",
- "jpeg",
- "h263",
- "screen",
- "vp6",
- "vp6alpha",
- "screen2",
- "avc",
- "video8",
- "video9",
- "video10",
- "video11",
- "video12",
- "video13",
- "video14",
- "video15"
+ "video0"
+ , "jpeg"
+ , "h263"
+ , "screen"
+ , "vp6"
+ , "vp6alpha"
+ , "screen2"
+ , "avc"
+ , "video8"
+ , "video9"
+ , "video10"
+ , "video11"
+ , "video12"
+ , "video13"
+ , "video14"
+ , "video15"
};
static const char *g_Rates[4] =
{
- "5.5 kHz",
- "11 kHz",
- "22 kHz",
- "44 kHz"
+ "5.5 kHz"
+ , "11 kHz"
+ , "22 kHz"
+ , "44 kHz"
};
-static void MyStrCat(char *d, const char *s)
-{
- MyStringCopy(d + MyStringLen(d), s);
-}
-
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
@@ -170,13 +158,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidComment:
{
char sz[64];
- MyStringCopy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) );
+ char *s = MyStpCpy(sz, (item.IsAudio() ? g_AudioTypes[item.SubType] : g_VideoTypes[item.SubType]) );
if (item.IsAudio())
{
- MyStrCat(sz, " ");
- MyStrCat(sz, g_Rates[(item.Props >> 2) & 3]);
- MyStrCat(sz, (item.Props & 2) ? " 16-bit" : " 8-bit");
- MyStrCat(sz, (item.Props & 1) ? " stereo" : " mono");
+ *s++ = ' ';
+ s = MyStpCpy(s, g_Rates[(item.Props >> 2) & 3]);
+ s = MyStpCpy(s, (item.Props & 2) ? " 16-bit" : " 8-bit");
+ s = MyStpCpy(s, (item.Props & 1) ? " stereo" : " mono");
}
prop = sz;
break;
@@ -190,7 +178,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
AString CHandler::GetComment()
{
const Byte *p = _metadata;
- size_t size = _metadata.GetCapacity();
+ size_t size = _metadata.Size();
AString res;
if (size > 0)
{
@@ -264,24 +252,25 @@ AString CHandler::GetComment()
return res;
}
+*/
+
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
- COM_TRY_BEGIN
+ // COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
- case kpidComment: prop = GetComment(); break;
+ // case kpidComment: prop = GetComment(); break;
+ case kpidPhySize: prop = (UInt64)_phySize; break;
+ case kpidIsNotArcType: prop = true; break;
}
prop.Detach(value);
return S_OK;
- COM_TRY_END
+ // COM_TRY_END
}
-*/
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
- CRecordVector<CItem> items;
-
const UInt32 kHeaderSize = 13;
Byte header[kHeaderSize];
RINOK(ReadStream_FALSE(stream, header, kHeaderSize));
@@ -291,69 +280,51 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
header[3] != 1 ||
(header[4] & 0xFA) != 0)
return S_FALSE;
- UInt32 offset = Get32(header + 5);
+ UInt64 offset = Get32(header + 5);
if (offset != 9 || Get32(header + 9) != 0)
return S_FALSE;
- offset += 4;
+ offset = kHeaderSize;
- CByteBuffer inBuf;
- size_t fileSize;
- {
- UInt64 fileSize64;
- RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize64));
- if (fileSize64 > kFileSizeMax)
- return S_FALSE;
-
- if (callback)
- RINOK(callback->SetTotal(NULL, &fileSize64))
-
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- fileSize = (size_t)fileSize64;
- inBuf.SetCapacity(fileSize);
- for (size_t pos = 0; pos < fileSize;)
- {
- UInt64 offset64 = pos;
- if (callback)
- RINOK(callback->SetCompleted(NULL, &offset64))
- size_t rem = MyMin(fileSize - pos, (size_t)(1 << 20));
- RINOK(ReadStream_FALSE(stream, inBuf + pos, rem));
- pos += rem;
- }
- }
+ CInBuffer inBuf;
+ if (!inBuf.Create(1 << 15))
+ return E_OUTOFMEMORY;
+ inBuf.SetStream(stream);
+ CObjectVector<CItem> items;
int lasts[kNumTypes];
- int i;
+ unsigned i;
for (i = 0; i < kNumTypes; i++)
lasts[i] = -1;
- while (offset < fileSize)
+ _phySize = offset;
+ for (;;)
{
+ Byte buf[kTagHeaderSize];
CItem item;
- item.Offset = offset;
- const Byte *buf = inBuf + offset;
- offset += kTagHeaderSize;
- if (offset > fileSize)
- return S_FALSE;
-
+ if (inBuf.ReadBytes(buf, kTagHeaderSize) != kTagHeaderSize)
+ break;
item.Type = buf[0];
UInt32 size = Get24(buf + 1);
if (size < 1)
- return S_FALSE;
+ break;
// item.Time = Get24(buf + 4);
// item.Time |= (UInt32)buf[7] << 24;
if (Get24(buf + 8) != 0) // streamID
- return S_FALSE;
+ break;
UInt32 curSize = kTagHeaderSize + size + 4;
- item.Size = curSize;
-
- offset += curSize - kTagHeaderSize;
- if (offset > fileSize)
- return S_FALSE;
-
- if (Get32(buf + kTagHeaderSize + size) != kTagHeaderSize + size)
- return S_FALSE;
+ item.Data.Alloc(curSize);
+ memcpy(item.Data, buf, kTagHeaderSize);
+ if (inBuf.ReadBytes(item.Data + kTagHeaderSize, size) != size)
+ break;
+ if (inBuf.ReadBytes(item.Data + kTagHeaderSize + size, 4) != 4)
+ break;
+ if (Get32(item.Data + kTagHeaderSize + size) != kTagHeaderSize + size)
+ break;
+
+ offset += curSize;
+
// printf("\noffset = %6X type = %2d time = %6d size = %6d", (UInt32)offset, item.Type, item.Time, item.Size);
if (item.Type == kType_Meta)
@@ -363,20 +334,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
else
{
if (item.Type != kType_Audio && item.Type != kType_Video)
- return S_FALSE;
+ break;
if (items.Size() >= kNumChunksMax)
return S_FALSE;
Byte firstByte = buf[kTagHeaderSize];
Byte subType, props;
if (item.Type == kType_Audio)
{
- subType = firstByte >> 4;
- props = firstByte & 0xF;
+ subType = (Byte)(firstByte >> 4);
+ props = (Byte)(firstByte & 0xF);
}
else
{
- subType = firstByte & 0xF;
- props = firstByte >> 4;
+ subType = (Byte)(firstByte & 0xF);
+ props = (Byte)(firstByte >> 4);
}
int last = lasts[item.Type];
if (last < 0)
@@ -401,7 +372,14 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
}
items.Add(item);
}
+ _phySize = offset;
+ if (callback && (items.Size() & 0xFF) == 0)
+ {
+ RINOK(callback->SetCompleted(NULL, &offset))
+ }
}
+ if (items.IsEmpty())
+ return S_FALSE;
_isRaw = (_items2.Size() == 1);
for (i = 0; i < _items2.Size(); i++)
@@ -412,12 +390,12 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
if (!item2.SameSubTypes)
return S_FALSE;
- itemBuf.SetCapacity((size_t)item2.Size - (kTagHeaderSize + 4 + 1) * item2.NumChunks);
+ itemBuf.Alloc((size_t)item2.Size - (size_t)(kTagHeaderSize + 4 + 1) * item2.NumChunks);
item2.Size = 0;
}
else
{
- itemBuf.SetCapacity(kHeaderSize + (size_t)item2.Size);
+ itemBuf.Alloc(kHeaderSize + (size_t)item2.Size);
memcpy(itemBuf, header, kHeaderSize);
itemBuf[4] = item2.IsAudio() ? kFlag_Audio : kFlag_Video;
item2.Size = kHeaderSize;
@@ -428,8 +406,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
const CItem &item = items[i];
CItem2 &item2 = _items2[lasts[item.Type]];
- size_t size = item.Size;
- const Byte *src = inBuf + item.Offset;
+ size_t size = item.Data.Size();
+ const Byte *src = item.Data;
if (_isRaw)
{
src += kTagHeaderSize + 1;
@@ -464,6 +442,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
STDMETHODIMP CHandler::Close()
{
+ _phySize = 0;
_stream.Release();
_items2.Clear();
// _metadata.SetCapacity(0);
@@ -480,7 +459,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
- bool allFilesMode = (numItems == (UInt32)-1);
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _items2.Size();
if (numItems == 0)
@@ -514,7 +493,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->PrepareOperation(askMode));
if (outStream)
{
- RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.GetCapacity()));
+ RINOK(WriteStream(outStream, item.BufSpec->Buf, item.BufSpec->Buf.Size()));
}
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
}
@@ -534,10 +513,14 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
COM_TRY_END
}
-static IInArchive *CreateArc() { return new CHandler; }
+IMP_CreateArcIn
static CArcInfo g_ArcInfo =
- { L"FLV", L"flv", 0, 0xD6, { 'F', 'L', 'V' }, 3, false, CreateArc, 0 };
+ { "FLV", "flv", 0, 0xD6,
+ 4, { 'F', 'L', 'V', 1, },
+ 0,
+ 0,
+ CreateArc };
REGISTER_ARC(Flv)