Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/CodecExports.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/CodecExports.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,157 @@ 1.4 +// CodecExports.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "../../Common/ComTry.h" 1.9 +#include "../../Windows/PropVariant.h" 1.10 +#include "../Common/RegisterCodec.h" 1.11 +#include "../ICoder.h" 1.12 + 1.13 +extern unsigned int g_NumCodecs; 1.14 +extern const CCodecInfo *g_Codecs[]; 1.15 + 1.16 +static const UInt16 kDecodeId = 0x2790; 1.17 + 1.18 +DEFINE_GUID(CLSID_CCodec, 1.19 +0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 1.20 + 1.21 +static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value) 1.22 +{ 1.23 + if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0) 1.24 + value->vt = VT_BSTR; 1.25 + return S_OK; 1.26 +} 1.27 + 1.28 +static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value) 1.29 +{ 1.30 + return SetPropString((const char *)&guid, sizeof(GUID), value); 1.31 +} 1.32 + 1.33 +static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value) 1.34 +{ 1.35 + GUID clsId = CLSID_CCodec; 1.36 + for (int i = 0; i < sizeof(id); i++, id >>= 8) 1.37 + clsId.Data4[i] = (Byte)(id & 0xFF); 1.38 + if (encode) 1.39 + clsId.Data3++; 1.40 + return SetPropGUID(clsId, value); 1.41 +} 1.42 + 1.43 +static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index) 1.44 +{ 1.45 + index = -1; 1.46 + if (clsID->Data1 != CLSID_CCodec.Data1 || 1.47 + clsID->Data2 != CLSID_CCodec.Data2 || 1.48 + (clsID->Data3 & ~1) != kDecodeId) 1.49 + return S_OK; 1.50 + encode = (clsID->Data3 != kDecodeId); 1.51 + UInt64 id = 0; 1.52 + for (int j = 0; j < 8; j++) 1.53 + id |= ((UInt64)clsID->Data4[j]) << (8 * j); 1.54 + for (unsigned i = 0; i < g_NumCodecs; i++) 1.55 + { 1.56 + const CCodecInfo &codec = *g_Codecs[i]; 1.57 + if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder) 1.58 + continue; 1.59 + if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || 1.60 + codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) 1.61 + return E_NOINTERFACE; 1.62 + index = i; 1.63 + return S_OK; 1.64 + } 1.65 + return S_OK; 1.66 +} 1.67 + 1.68 +STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject) 1.69 +{ 1.70 + COM_TRY_BEGIN 1.71 + *outObject = 0; 1.72 + bool isCoder = (*iid == IID_ICompressCoder) != 0; 1.73 + bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; 1.74 + bool isFilter = (*iid == IID_ICompressFilter) != 0; 1.75 + const CCodecInfo &codec = *g_Codecs[index]; 1.76 + if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter || 1.77 + codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2) 1.78 + return E_NOINTERFACE; 1.79 + if (encode) 1.80 + { 1.81 + if (!codec.CreateEncoder) 1.82 + return CLASS_E_CLASSNOTAVAILABLE; 1.83 + *outObject = codec.CreateEncoder(); 1.84 + } 1.85 + else 1.86 + { 1.87 + if (!codec.CreateDecoder) 1.88 + return CLASS_E_CLASSNOTAVAILABLE; 1.89 + *outObject = codec.CreateDecoder(); 1.90 + } 1.91 + if (isCoder) 1.92 + ((ICompressCoder *)*outObject)->AddRef(); 1.93 + else if (isCoder2) 1.94 + ((ICompressCoder2 *)*outObject)->AddRef(); 1.95 + else 1.96 + ((ICompressFilter *)*outObject)->AddRef(); 1.97 + return S_OK; 1.98 + COM_TRY_END 1.99 +} 1.100 + 1.101 +STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject) 1.102 +{ 1.103 + *outObject = 0; 1.104 + bool isCoder = (*iid == IID_ICompressCoder) != 0; 1.105 + bool isCoder2 = (*iid == IID_ICompressCoder2) != 0; 1.106 + bool isFilter = (*iid == IID_ICompressFilter) != 0; 1.107 + if (!isCoder && !isCoder2 && !isFilter) 1.108 + return E_NOINTERFACE; 1.109 + bool encode; 1.110 + int codecIndex; 1.111 + HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex); 1.112 + if (res != S_OK) 1.113 + return res; 1.114 + if (codecIndex < 0) 1.115 + return CLASS_E_CLASSNOTAVAILABLE; 1.116 + return CreateCoder2(encode, codecIndex, iid, outObject); 1.117 +} 1.118 + 1.119 +STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value) 1.120 +{ 1.121 + ::VariantClear((VARIANTARG *)value); 1.122 + const CCodecInfo &codec = *g_Codecs[codecIndex]; 1.123 + switch(propID) 1.124 + { 1.125 + case NMethodPropID::kID: 1.126 + { 1.127 + value->uhVal.QuadPart = (UInt64)codec.Id; 1.128 + value->vt = VT_UI8; 1.129 + break; 1.130 + } 1.131 + case NMethodPropID::kName: 1.132 + if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0) 1.133 + value->vt = VT_BSTR; 1.134 + break; 1.135 + case NMethodPropID::kDecoder: 1.136 + if (codec.CreateDecoder) 1.137 + return SetClassID(codec.Id, false, value); 1.138 + break; 1.139 + case NMethodPropID::kEncoder: 1.140 + if (codec.CreateEncoder) 1.141 + return SetClassID(codec.Id, true, value); 1.142 + break; 1.143 + case NMethodPropID::kInStreams: 1.144 + { 1.145 + if (codec.NumInStreams != 1) 1.146 + { 1.147 + value->vt = VT_UI4; 1.148 + value->ulVal = (ULONG)codec.NumInStreams; 1.149 + } 1.150 + break; 1.151 + } 1.152 + } 1.153 + return S_OK; 1.154 +} 1.155 + 1.156 +STDAPI GetNumberOfMethods(UINT32 *numCodecs) 1.157 +{ 1.158 + *numCodecs = g_NumCodecs; 1.159 + return S_OK; 1.160 +}