Mercurial > vba-linux
comparison src/win32/7zip/7z/CPP/7zip/Common/CreateCoder.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // CreateCoder.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "CreateCoder.h" | |
6 | |
7 #include "../../Windows/PropVariant.h" | |
8 #include "../../Windows/Defs.h" | |
9 #include "FilterCoder.h" | |
10 #include "RegisterCodec.h" | |
11 | |
12 static const unsigned int kNumCodecsMax = 64; | |
13 unsigned int g_NumCodecs = 0; | |
14 const CCodecInfo *g_Codecs[kNumCodecsMax]; | |
15 void RegisterCodec(const CCodecInfo *codecInfo) | |
16 { | |
17 if (g_NumCodecs < kNumCodecsMax) | |
18 g_Codecs[g_NumCodecs++] = codecInfo; | |
19 } | |
20 | |
21 #ifdef EXTERNAL_CODECS | |
22 static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res) | |
23 { | |
24 NWindows::NCOM::CPropVariant prop; | |
25 RINOK(codecsInfo->GetProperty(index, propID, &prop)); | |
26 if (prop.vt == VT_EMPTY) | |
27 res = 1; | |
28 else if (prop.vt == VT_UI4) | |
29 res = prop.ulVal; | |
30 else | |
31 return E_INVALIDARG; | |
32 return S_OK; | |
33 } | |
34 | |
35 static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res) | |
36 { | |
37 NWindows::NCOM::CPropVariant prop; | |
38 RINOK(codecsInfo->GetProperty(index, propID, &prop)); | |
39 if (prop.vt == VT_EMPTY) | |
40 res = true; | |
41 else if (prop.vt == VT_BOOL) | |
42 res = VARIANT_BOOLToBool(prop.boolVal); | |
43 else | |
44 return E_INVALIDARG; | |
45 return S_OK; | |
46 } | |
47 | |
48 HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs) | |
49 { | |
50 UInt32 num; | |
51 RINOK(codecsInfo->GetNumberOfMethods(&num)); | |
52 for (UInt32 i = 0; i < num; i++) | |
53 { | |
54 CCodecInfoEx info; | |
55 NWindows::NCOM::CPropVariant prop; | |
56 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop)); | |
57 // if (prop.vt != VT_BSTR) | |
58 // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal); | |
59 // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize); | |
60 if (prop.vt != VT_UI8) | |
61 { | |
62 continue; // old Interface | |
63 // return E_INVALIDARG; | |
64 } | |
65 info.Id = prop.uhVal.QuadPart; | |
66 prop.Clear(); | |
67 | |
68 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop)); | |
69 if (prop.vt == VT_BSTR) | |
70 info.Name = prop.bstrVal; | |
71 else if (prop.vt != VT_EMPTY) | |
72 return E_INVALIDARG;; | |
73 | |
74 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams)); | |
75 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams)); | |
76 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned)); | |
77 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned)); | |
78 | |
79 externalCodecs.Add(info); | |
80 } | |
81 return S_OK; | |
82 } | |
83 | |
84 #endif | |
85 | |
86 bool FindMethod( | |
87 #ifdef EXTERNAL_CODECS | |
88 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, | |
89 #endif | |
90 const UString &name, | |
91 CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) | |
92 { | |
93 UInt32 i; | |
94 for (i = 0; i < g_NumCodecs; i++) | |
95 { | |
96 const CCodecInfo &codec = *g_Codecs[i]; | |
97 if (name.CompareNoCase(codec.Name) == 0) | |
98 { | |
99 methodId = codec.Id; | |
100 numInStreams = codec.NumInStreams; | |
101 numOutStreams = 1; | |
102 return true; | |
103 } | |
104 } | |
105 #ifdef EXTERNAL_CODECS | |
106 if (externalCodecs) | |
107 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
108 { | |
109 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
110 if (codec.Name.CompareNoCase(name) == 0) | |
111 { | |
112 methodId = codec.Id; | |
113 numInStreams = codec.NumInStreams; | |
114 numOutStreams = codec.NumOutStreams; | |
115 return true; | |
116 } | |
117 } | |
118 #endif | |
119 return false; | |
120 } | |
121 | |
122 bool FindMethod( | |
123 #ifdef EXTERNAL_CODECS | |
124 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs, | |
125 #endif | |
126 CMethodId methodId, UString &name) | |
127 { | |
128 UInt32 i; | |
129 for (i = 0; i < g_NumCodecs; i++) | |
130 { | |
131 const CCodecInfo &codec = *g_Codecs[i]; | |
132 if (methodId == codec.Id) | |
133 { | |
134 name = codec.Name; | |
135 return true; | |
136 } | |
137 } | |
138 #ifdef EXTERNAL_CODECS | |
139 if (externalCodecs) | |
140 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
141 { | |
142 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
143 if (methodId == codec.Id) | |
144 { | |
145 name = codec.Name; | |
146 return true; | |
147 } | |
148 } | |
149 #endif | |
150 return false; | |
151 } | |
152 | |
153 HRESULT CreateCoder( | |
154 DECL_EXTERNAL_CODECS_LOC_VARS | |
155 CMethodId methodId, | |
156 CMyComPtr<ICompressFilter> &filter, | |
157 CMyComPtr<ICompressCoder> &coder, | |
158 CMyComPtr<ICompressCoder2> &coder2, | |
159 bool encode, bool onlyCoder) | |
160 { | |
161 bool created = false; | |
162 UInt32 i; | |
163 for (i = 0; i < g_NumCodecs; i++) | |
164 { | |
165 const CCodecInfo &codec = *g_Codecs[i]; | |
166 if (codec.Id == methodId) | |
167 { | |
168 if (encode) | |
169 { | |
170 if (codec.CreateEncoder) | |
171 { | |
172 void *p = codec.CreateEncoder(); | |
173 if (codec.IsFilter) filter = (ICompressFilter *)p; | |
174 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; | |
175 else coder2 = (ICompressCoder2 *)p; | |
176 created = (p != 0); | |
177 break; | |
178 } | |
179 } | |
180 else | |
181 if (codec.CreateDecoder) | |
182 { | |
183 void *p = codec.CreateDecoder(); | |
184 if (codec.IsFilter) filter = (ICompressFilter *)p; | |
185 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p; | |
186 else coder2 = (ICompressCoder2 *)p; | |
187 created = (p != 0); | |
188 break; | |
189 } | |
190 } | |
191 } | |
192 | |
193 #ifdef EXTERNAL_CODECS | |
194 if (!created && externalCodecs) | |
195 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
196 { | |
197 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
198 if (codec.Id == methodId) | |
199 { | |
200 if (encode) | |
201 { | |
202 if (codec.EncoderIsAssigned) | |
203 { | |
204 if (codec.IsSimpleCodec()) | |
205 { | |
206 HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder); | |
207 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) | |
208 return result; | |
209 if (!coder) | |
210 { | |
211 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter)); | |
212 } | |
213 } | |
214 else | |
215 { | |
216 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2)); | |
217 } | |
218 break; | |
219 } | |
220 } | |
221 else | |
222 if (codec.DecoderIsAssigned) | |
223 { | |
224 if (codec.IsSimpleCodec()) | |
225 { | |
226 HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder); | |
227 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) | |
228 return result; | |
229 if (!coder) | |
230 { | |
231 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter)); | |
232 } | |
233 } | |
234 else | |
235 { | |
236 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2)); | |
237 } | |
238 break; | |
239 } | |
240 } | |
241 } | |
242 #endif | |
243 | |
244 if (onlyCoder && filter) | |
245 { | |
246 CFilterCoder *coderSpec = new CFilterCoder; | |
247 coder = coderSpec; | |
248 coderSpec->Filter = filter; | |
249 } | |
250 return S_OK; | |
251 } | |
252 | |
253 HRESULT CreateCoder( | |
254 DECL_EXTERNAL_CODECS_LOC_VARS | |
255 CMethodId methodId, | |
256 CMyComPtr<ICompressCoder> &coder, | |
257 CMyComPtr<ICompressCoder2> &coder2, | |
258 bool encode) | |
259 { | |
260 CMyComPtr<ICompressFilter> filter; | |
261 return CreateCoder( | |
262 EXTERNAL_CODECS_LOC_VARS | |
263 methodId, | |
264 filter, coder, coder2, encode, true); | |
265 } | |
266 | |
267 HRESULT CreateCoder( | |
268 DECL_EXTERNAL_CODECS_LOC_VARS | |
269 CMethodId methodId, | |
270 CMyComPtr<ICompressCoder> &coder, bool encode) | |
271 { | |
272 CMyComPtr<ICompressFilter> filter; | |
273 CMyComPtr<ICompressCoder2> coder2; | |
274 return CreateCoder( | |
275 EXTERNAL_CODECS_LOC_VARS | |
276 methodId, | |
277 coder, coder2, encode); | |
278 } | |
279 | |
280 HRESULT CreateFilter( | |
281 DECL_EXTERNAL_CODECS_LOC_VARS | |
282 CMethodId methodId, | |
283 CMyComPtr<ICompressFilter> &filter, | |
284 bool encode) | |
285 { | |
286 CMyComPtr<ICompressCoder> coder; | |
287 CMyComPtr<ICompressCoder2> coder2; | |
288 return CreateCoder( | |
289 EXTERNAL_CODECS_LOC_VARS | |
290 methodId, | |
291 filter, coder, coder2, encode, false); | |
292 } |