--- C/LzmaDec.c
+++ C/LzmaDec.c
@@ -952,13 +952,11 @@
   return SZ_OK;
 }
 
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+static SRes LzmaDec_AllocateImpl(CLzmaDec *p, CLzmaProps *propNew, ISzAlloc *alloc)
 {
-  CLzmaProps propNew;
   SizeT dicBufSize;
-  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-  dicBufSize = propNew.dicSize;
+  RINOK(LzmaDec_AllocateProbs2(p, propNew, alloc));
+  dicBufSize = propNew->dicSize;
   if (p->dic == 0 || dicBufSize != p->dicBufSize)
   {
     LzmaDec_FreeDict(p, alloc);
@@ -970,10 +968,29 @@
     }
   }
   p->dicBufSize = dicBufSize;
-  p->prop = propNew;
+  p->prop = *propNew;
   return SZ_OK;
 }
 
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+
+  return LzmaDec_AllocateImpl(p, &propNew, alloc);
+}
+
+SRes LzmaDec_AllocateRawProps(CLzmaDec *p, unsigned lc, unsigned lp, unsigned pb, UInt32 dicSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  propNew.lc = lc;
+  propNew.lp = lp;
+  propNew.pb = pb;
+  propNew.dicSize = dicSize;
+
+  return LzmaDec_AllocateImpl(p, &propNew, alloc);
+}
+
 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
     ELzmaStatus *status, ISzAlloc *alloc)
--- C/LzmaDec.h
+++ C/LzmaDec.h
@@ -131,6 +131,7 @@
 void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
 
 SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+SRes LzmaDec_AllocateRawProps(CLzmaDec *p, unsigned lc, unsigned lp, unsigned pb, UInt32 dicSize, ISzAlloc *alloc);
 void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
 
 /* ---------- Dictionary Interface ---------- */
--- CPP/7zip/Compress/LzmaDecoder.cpp
+++ CPP/7zip/Compress/LzmaDecoder.cpp
@@ -59,6 +59,21 @@
   return S_OK;
 }
 
+STDMETHODIMP CDecoder::SetDecoderPropertiesRaw(unsigned lc, unsigned lp, unsigned pb, UInt32 dictionarySize)
+{
+  RINOK(SResToHRESULT(LzmaDec_AllocateRawProps(&_state, lc, lp, pb, dictionarySize, &g_Alloc)));
+
+  if (_inBuf == 0)
+  {
+    _inBuf = (Byte *)MyAlloc(kInBufSize);
+    if (_inBuf == 0)
+      return E_OUTOFMEMORY;
+  }
+
+  return S_OK;
+}
+
+
 STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value) { *value = _inSizeProcessed; return S_OK; }
 STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) { _inStream = inStream; return S_OK; }
 STDMETHODIMP CDecoder::ReleaseInStream() { _inStream.Release(); return S_OK; }
--- CPP/7zip/Compress/LzmaDecoder.h
+++ CPP/7zip/Compress/LzmaDecoder.h
@@ -52,6 +52,7 @@
   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+  STDMETHOD(SetDecoderPropertiesRaw)(unsigned lc, unsigned lp, unsigned pb, UInt32 dictionarySize);
   STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
   STDMETHOD(SetInStream)(ISequentialInStream *inStream);
   STDMETHOD(ReleaseInStream)();
