Mercurial > vba-linux
view 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 source
1 // CodecExports.cpp3 #include "StdAfx.h"5 #include "../../Common/ComTry.h"6 #include "../../Windows/PropVariant.h"7 #include "../Common/RegisterCodec.h"8 #include "../ICoder.h"10 extern unsigned int g_NumCodecs;11 extern const CCodecInfo *g_Codecs[];13 static const UInt16 kDecodeId = 0x2790;15 DEFINE_GUID(CLSID_CCodec,16 0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);18 static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)19 {20 if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)21 value->vt = VT_BSTR;22 return S_OK;23 }25 static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)26 {27 return SetPropString((const char *)&guid, sizeof(GUID), value);28 }30 static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)31 {32 GUID clsId = CLSID_CCodec;33 for (int i = 0; i < sizeof(id); i++, id >>= 8)34 clsId.Data4[i] = (Byte)(id & 0xFF);35 if (encode)36 clsId.Data3++;37 return SetPropGUID(clsId, value);38 }40 static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)41 {42 index = -1;43 if (clsID->Data1 != CLSID_CCodec.Data1 ||44 clsID->Data2 != CLSID_CCodec.Data2 ||45 (clsID->Data3 & ~1) != kDecodeId)46 return S_OK;47 encode = (clsID->Data3 != kDecodeId);48 UInt64 id = 0;49 for (int j = 0; j < 8; j++)50 id |= ((UInt64)clsID->Data4[j]) << (8 * j);51 for (unsigned i = 0; i < g_NumCodecs; i++)52 {53 const CCodecInfo &codec = *g_Codecs[i];54 if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)55 continue;56 if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||57 codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)58 return E_NOINTERFACE;59 index = i;60 return S_OK;61 }62 return S_OK;63 }65 STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)66 {67 COM_TRY_BEGIN68 *outObject = 0;69 bool isCoder = (*iid == IID_ICompressCoder) != 0;70 bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;71 bool isFilter = (*iid == IID_ICompressFilter) != 0;72 const CCodecInfo &codec = *g_Codecs[index];73 if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||74 codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)75 return E_NOINTERFACE;76 if (encode)77 {78 if (!codec.CreateEncoder)79 return CLASS_E_CLASSNOTAVAILABLE;80 *outObject = codec.CreateEncoder();81 }82 else83 {84 if (!codec.CreateDecoder)85 return CLASS_E_CLASSNOTAVAILABLE;86 *outObject = codec.CreateDecoder();87 }88 if (isCoder)89 ((ICompressCoder *)*outObject)->AddRef();90 else if (isCoder2)91 ((ICompressCoder2 *)*outObject)->AddRef();92 else93 ((ICompressFilter *)*outObject)->AddRef();94 return S_OK;95 COM_TRY_END96 }98 STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)99 {100 *outObject = 0;101 bool isCoder = (*iid == IID_ICompressCoder) != 0;102 bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;103 bool isFilter = (*iid == IID_ICompressFilter) != 0;104 if (!isCoder && !isCoder2 && !isFilter)105 return E_NOINTERFACE;106 bool encode;107 int codecIndex;108 HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);109 if (res != S_OK)110 return res;111 if (codecIndex < 0)112 return CLASS_E_CLASSNOTAVAILABLE;113 return CreateCoder2(encode, codecIndex, iid, outObject);114 }116 STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)117 {118 ::VariantClear((VARIANTARG *)value);119 const CCodecInfo &codec = *g_Codecs[codecIndex];120 switch(propID)121 {122 case NMethodPropID::kID:123 {124 value->uhVal.QuadPart = (UInt64)codec.Id;125 value->vt = VT_UI8;126 break;127 }128 case NMethodPropID::kName:129 if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)130 value->vt = VT_BSTR;131 break;132 case NMethodPropID::kDecoder:133 if (codec.CreateDecoder)134 return SetClassID(codec.Id, false, value);135 break;136 case NMethodPropID::kEncoder:137 if (codec.CreateEncoder)138 return SetClassID(codec.Id, true, value);139 break;140 case NMethodPropID::kInStreams:141 {142 if (codec.NumInStreams != 1)143 {144 value->vt = VT_UI4;145 value->ulVal = (ULONG)codec.NumInStreams;146 }147 break;148 }149 }150 return S_OK;151 }153 STDAPI GetNumberOfMethods(UINT32 *numCodecs)154 {155 *numCodecs = g_NumCodecs;156 return S_OK;157 }