📄 loadcodecs.cpp
字号:
int CCodecLib::FindIconIndex(const UString &ext) const
{
for (int i = 0; i < IconPairs.Size(); i++)
{
const CIconPair &pair = IconPairs[i];
if (ext.CompareNoCase(pair.Ext) == 0)
return pair.IconIndex;
}
return -1;
}
#endif
#ifdef _7ZIP_LARGE_PAGES
extern "C"
{
extern SIZE_T g_LargePageSize;
}
#endif
HRESULT CCodecs::LoadDll(const CSysString &dllPath)
{
{
NDLL::CLibrary library;
if (!library.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
return S_OK;
}
Libs.Add(CCodecLib());
CCodecLib &lib = Libs.Back();
#ifdef NEW_FOLDER_INTERFACE
lib.Path = dllPath;
#endif
bool used = false;
HRESULT res = S_OK;
if (lib.Lib.Load(dllPath))
{
#ifdef NEW_FOLDER_INTERFACE
lib.LoadIcons();
#endif
#ifdef _7ZIP_LARGE_PAGES
if (g_LargePageSize != 0)
{
SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProcAddress("SetLargePageMode");
if (setLargePageMode != 0)
setLargePageMode();
}
#endif
lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProcAddress("CreateObject");
if (lib.CreateObject != 0)
{
int startSize = Codecs.Size();
res = LoadCodecs();
used = (Codecs.Size() != startSize);
if (res == S_OK)
{
startSize = Formats.Size();
res = LoadFormats();
used = used || (Formats.Size() != startSize);
}
}
}
if (!used)
Libs.DeleteBack();
return res;
}
HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
{
NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
NFile::NFind::CFileInfo fileInfo;
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDirectory())
continue;
RINOK(LoadDll(folderPrefix + fileInfo.Name));
}
return S_OK;
}
#endif
#ifndef _SFX
static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
{
bb.SetCapacity(size);
memmove((Byte *)bb, data, size);
}
#endif
HRESULT CCodecs::Load()
{
Formats.Clear();
#ifdef EXTERNAL_CODECS
Codecs.Clear();
#endif
for (UInt32 i = 0; i < g_NumArcs; i++)
{
const CArcInfo &arc = *g_Arcs[i];
CArcInfoEx item;
item.Name = arc.Name;
item.CreateInArchive = arc.CreateInArchive;
item.CreateOutArchive = arc.CreateOutArchive;
item.AddExts(arc.Ext, arc.AddExt);
item.UpdateEnabled = (arc.CreateOutArchive != 0);
item.KeepName = arc.KeepName;
#ifndef _SFX
SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);
#endif
Formats.Add(item);
}
#ifdef EXTERNAL_CODECS
const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();
RINOK(LoadDll(baseFolder + kMainDll));
RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));
RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));
#endif
return S_OK;
}
int CCodecs::FindFormatForArchiveName(const UString &archivePath) const
{
int slashPos1 = archivePath.ReverseFind(L'\\');
int slashPos2 = archivePath.ReverseFind(L'.');
int dotPos = archivePath.ReverseFind(L'.');
if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)
return -1;
UString ext = archivePath.Mid(dotPos + 1);
for (int i = 0; i < Formats.Size(); i++)
{
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
// if (arc.FindExtension(ext) >= 0)
UString mainExt = arc.GetMainExt();
if (!mainExt.IsEmpty() && ext.CompareNoCase(mainExt) == 0)
return i;
}
return -1;
}
int CCodecs::FindFormatForArchiveType(const UString &arcType) const
{
for (int i = 0; i < Formats.Size(); i++)
{
const CArcInfoEx &arc = Formats[i];
if (!arc.UpdateEnabled)
continue;
if (arc.Name.CompareNoCase(arcType) == 0)
return i;
}
return -1;
}
#ifdef EXTERNAL_CODECS
#ifdef EXPORT_CODECS
extern unsigned int g_NumCodecs;
STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);
STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
// STDAPI GetNumberOfMethods(UINT32 *numCodecs);
#endif
STDMETHODIMP CCodecs::GetNumberOfMethods(UINT32 *numMethods)
{
*numMethods =
#ifdef EXPORT_CODECS
g_NumCodecs +
#endif
Codecs.Size();
return S_OK;
}
STDMETHODIMP CCodecs::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
return GetMethodProperty(index, propID, value);
#endif
const CDllCodecInfo &ci = Codecs[index
#ifdef EXPORT_CODECS
- g_NumCodecs
#endif
];
if (propID == NMethodPropID::kDecoderIsAssigned)
{
NWindows::NCOM::CPropVariant propVariant;
propVariant = ci.DecoderIsAssigned;
propVariant.Detach(value);
return S_OK;
}
if (propID == NMethodPropID::kEncoderIsAssigned)
{
NWindows::NCOM::CPropVariant propVariant;
propVariant = ci.EncoderIsAssigned;
propVariant.Detach(value);
return S_OK;
}
return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);
}
STDMETHODIMP CCodecs::CreateDecoder(UINT32 index, const GUID *iid, void **coder)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
return CreateCoder2(false, index, iid, coder);
#endif
const CDllCodecInfo &ci = Codecs[index
#ifdef EXPORT_CODECS
- g_NumCodecs
#endif
];
if (ci.DecoderIsAssigned)
return Libs[ci.LibIndex].CreateObject(&ci.Decoder, iid, (void **)coder);
return S_OK;
}
STDMETHODIMP CCodecs::CreateEncoder(UINT32 index, const GUID *iid, void **coder)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
return CreateCoder2(true, index, iid, coder);
#endif
const CDllCodecInfo &ci = Codecs[index
#ifdef EXPORT_CODECS
- g_NumCodecs
#endif
];
if (ci.EncoderIsAssigned)
return Libs[ci.LibIndex].CreateObject(&ci.Encoder, iid, (void **)coder);
return S_OK;
}
HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const
{
for (int i = 0; i < Codecs.Size(); i++)
{
const CDllCodecInfo &codec = Codecs[i];
if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)
continue;
const CCodecLib &lib = Libs[codec.LibIndex];
UString res;
NWindows::NCOM::CPropVariant prop;
RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));
if (prop.vt == VT_BSTR)
res = prop.bstrVal;
else if (prop.vt != VT_EMPTY)
continue;
if (name.CompareNoCase(res) == 0)
return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);
}
return CLASS_E_CLASSNOTAVAILABLE;
}
int CCodecs::GetCodecLibIndex(UInt32 index)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
return -1;
#endif
#ifdef EXTERNAL_CODECS
const CDllCodecInfo &ci = Codecs[index
#ifdef EXPORT_CODECS
- g_NumCodecs
#endif
];
return ci.LibIndex;
#else
return -1;
#endif
}
bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
{
#ifdef EXPORT_CODECS
if (index < g_NumCodecs)
{
NWindows::NCOM::CPropVariant prop;
if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)
if (prop.vt != VT_EMPTY)
return true;
return false;
}
#endif
#ifdef EXTERNAL_CODECS
const CDllCodecInfo &ci = Codecs[index
#ifdef EXPORT_CODECS
- g_NumCodecs
#endif
];
return ci.EncoderIsAssigned;
#else
return false;
#endif
}
HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
{
UString s;
NWindows::NCOM::CPropVariant prop;
RINOK(GetProperty(index, NMethodPropID::kID, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
id = prop.uhVal.QuadPart;
return S_OK;
}
UString CCodecs::GetCodecName(UInt32 index)
{
UString s;
NWindows::NCOM::CPropVariant prop;
if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)
if (prop.vt == VT_BSTR)
s = prop.bstrVal;
return s;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -