Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F632281
Lzma2Dec.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None
Lzma2Dec.c
View Options
/* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
#ifdef SHOW_DEBUG_INFO
#include
<stdio.h>
#endif
#include
<string.h>
#include
"Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
typedef
enum
{
LZMA2_STATE_CONTROL
,
LZMA2_STATE_UNPACK0
,
LZMA2_STATE_UNPACK1
,
LZMA2_STATE_PACK0
,
LZMA2_STATE_PACK1
,
LZMA2_STATE_PROP
,
LZMA2_STATE_DATA
,
LZMA2_STATE_DATA_CONT
,
LZMA2_STATE_FINISHED
,
LZMA2_STATE_ERROR
}
ELzma2State
;
static
SRes
Lzma2Dec_GetOldProps
(
Byte
prop
,
Byte
*
props
)
{
UInt32
dicSize
;
if
(
prop
>
40
)
return
SZ_ERROR_UNSUPPORTED
;
dicSize
=
(
prop
==
40
)
?
0xFFFFFFFF
:
LZMA2_DIC_SIZE_FROM_PROP
(
prop
);
props
[
0
]
=
(
Byte
)
LZMA2_LCLP_MAX
;
props
[
1
]
=
(
Byte
)(
dicSize
);
props
[
2
]
=
(
Byte
)(
dicSize
>>
8
);
props
[
3
]
=
(
Byte
)(
dicSize
>>
16
);
props
[
4
]
=
(
Byte
)(
dicSize
>>
24
);
return
SZ_OK
;
}
SRes
Lzma2Dec_AllocateProbs
(
CLzma2Dec
*
p
,
Byte
prop
,
ISzAlloc
*
alloc
)
{
Byte
props
[
LZMA_PROPS_SIZE
];
RINOK
(
Lzma2Dec_GetOldProps
(
prop
,
props
));
return
LzmaDec_AllocateProbs
(
&
p
->
decoder
,
props
,
LZMA_PROPS_SIZE
,
alloc
);
}
SRes
Lzma2Dec_Allocate
(
CLzma2Dec
*
p
,
Byte
prop
,
ISzAlloc
*
alloc
)
{
Byte
props
[
LZMA_PROPS_SIZE
];
RINOK
(
Lzma2Dec_GetOldProps
(
prop
,
props
));
return
LzmaDec_Allocate
(
&
p
->
decoder
,
props
,
LZMA_PROPS_SIZE
,
alloc
);
}
void
Lzma2Dec_Init
(
CLzma2Dec
*
p
)
{
p
->
state
=
LZMA2_STATE_CONTROL
;
p
->
needInitDic
=
True
;
p
->
needInitState
=
True
;
p
->
needInitProp
=
True
;
LzmaDec_Init
(
&
p
->
decoder
);
}
static
ELzma2State
Lzma2Dec_UpdateState
(
CLzma2Dec
*
p
,
Byte
b
)
{
switch
(
p
->
state
)
{
case
LZMA2_STATE_CONTROL
:
p
->
control
=
b
;
PRF
(
printf
(
"
\n
%4X "
,
p
->
decoder
.
dicPos
));
PRF
(
printf
(
" %2X"
,
b
));
if
(
p
->
control
==
0
)
return
LZMA2_STATE_FINISHED
;
if
(
LZMA2_IS_UNCOMPRESSED_STATE
(
p
))
{
if
((
p
->
control
&
0x7F
)
>
2
)
return
LZMA2_STATE_ERROR
;
p
->
unpackSize
=
0
;
}
else
p
->
unpackSize
=
(
UInt32
)(
p
->
control
&
0x1F
)
<<
16
;
return
LZMA2_STATE_UNPACK0
;
case
LZMA2_STATE_UNPACK0
:
p
->
unpackSize
|=
(
UInt32
)
b
<<
8
;
return
LZMA2_STATE_UNPACK1
;
case
LZMA2_STATE_UNPACK1
:
p
->
unpackSize
|=
(
UInt32
)
b
;
p
->
unpackSize
++
;
PRF
(
printf
(
" %8d"
,
p
->
unpackSize
));
return
(
LZMA2_IS_UNCOMPRESSED_STATE
(
p
))
?
LZMA2_STATE_DATA
:
LZMA2_STATE_PACK0
;
case
LZMA2_STATE_PACK0
:
p
->
packSize
=
(
UInt32
)
b
<<
8
;
return
LZMA2_STATE_PACK1
;
case
LZMA2_STATE_PACK1
:
p
->
packSize
|=
(
UInt32
)
b
;
p
->
packSize
++
;
PRF
(
printf
(
" %8d"
,
p
->
packSize
));
return
LZMA2_IS_THERE_PROP
(
LZMA2_GET_LZMA_MODE
(
p
))
?
LZMA2_STATE_PROP
:
(
p
->
needInitProp
?
LZMA2_STATE_ERROR
:
LZMA2_STATE_DATA
);
case
LZMA2_STATE_PROP
:
{
int
lc
,
lp
;
if
(
b
>=
(
9
*
5
*
5
))
return
LZMA2_STATE_ERROR
;
lc
=
b
%
9
;
b
/=
9
;
p
->
decoder
.
prop
.
pb
=
b
/
5
;
lp
=
b
%
5
;
if
(
lc
+
lp
>
LZMA2_LCLP_MAX
)
return
LZMA2_STATE_ERROR
;
p
->
decoder
.
prop
.
lc
=
lc
;
p
->
decoder
.
prop
.
lp
=
lp
;
p
->
needInitProp
=
False
;
return
LZMA2_STATE_DATA
;
}
}
return
LZMA2_STATE_ERROR
;
}
static
void
LzmaDec_UpdateWithUncompressed
(
CLzmaDec
*
p
,
const
Byte
*
src
,
SizeT
size
)
{
memcpy
(
p
->
dic
+
p
->
dicPos
,
src
,
size
);
p
->
dicPos
+=
size
;
if
(
p
->
checkDicSize
==
0
&&
p
->
prop
.
dicSize
-
p
->
processedPos
<=
size
)
p
->
checkDicSize
=
p
->
prop
.
dicSize
;
p
->
processedPos
+=
(
UInt32
)
size
;
}
void
LzmaDec_InitDicAndState
(
CLzmaDec
*
p
,
LzmaBool
initDic
,
LzmaBool
initState
);
SRes
Lzma2Dec_DecodeToDic
(
CLzma2Dec
*
p
,
SizeT
dicLimit
,
const
Byte
*
src
,
SizeT
*
srcLen
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
)
{
SizeT
inSize
=
*
srcLen
;
*
srcLen
=
0
;
*
status
=
LZMA_STATUS_NOT_SPECIFIED
;
while
(
p
->
state
!=
LZMA2_STATE_FINISHED
)
{
SizeT
dicPos
=
p
->
decoder
.
dicPos
;
if
(
p
->
state
==
LZMA2_STATE_ERROR
)
return
SZ_ERROR_DATA
;
if
(
dicPos
==
dicLimit
&&
finishMode
==
LZMA_FINISH_ANY
)
{
*
status
=
LZMA_STATUS_NOT_FINISHED
;
return
SZ_OK
;
}
if
(
p
->
state
!=
LZMA2_STATE_DATA
&&
p
->
state
!=
LZMA2_STATE_DATA_CONT
)
{
if
(
*
srcLen
==
inSize
)
{
*
status
=
LZMA_STATUS_NEEDS_MORE_INPUT
;
return
SZ_OK
;
}
(
*
srcLen
)
++
;
p
->
state
=
Lzma2Dec_UpdateState
(
p
,
*
src
++
);
continue
;
}
{
SizeT
destSizeCur
=
dicLimit
-
dicPos
;
SizeT
srcSizeCur
=
inSize
-
*
srcLen
;
ELzmaFinishMode
curFinishMode
=
LZMA_FINISH_ANY
;
if
(
p
->
unpackSize
<=
destSizeCur
)
{
destSizeCur
=
(
SizeT
)
p
->
unpackSize
;
curFinishMode
=
LZMA_FINISH_END
;
}
if
(
LZMA2_IS_UNCOMPRESSED_STATE
(
p
))
{
if
(
*
srcLen
==
inSize
)
{
*
status
=
LZMA_STATUS_NEEDS_MORE_INPUT
;
return
SZ_OK
;
}
if
(
p
->
state
==
LZMA2_STATE_DATA
)
{
LzmaBool
initDic
=
(
p
->
control
==
LZMA2_CONTROL_COPY_RESET_DIC
);
if
(
initDic
)
p
->
needInitProp
=
p
->
needInitState
=
True
;
else
if
(
p
->
needInitDic
)
return
SZ_ERROR_DATA
;
p
->
needInitDic
=
False
;
LzmaDec_InitDicAndState
(
&
p
->
decoder
,
initDic
,
False
);
}
if
(
srcSizeCur
>
destSizeCur
)
srcSizeCur
=
destSizeCur
;
if
(
srcSizeCur
==
0
)
return
SZ_ERROR_DATA
;
LzmaDec_UpdateWithUncompressed
(
&
p
->
decoder
,
src
,
srcSizeCur
);
src
+=
srcSizeCur
;
*
srcLen
+=
srcSizeCur
;
p
->
unpackSize
-=
(
UInt32
)
srcSizeCur
;
p
->
state
=
(
p
->
unpackSize
==
0
)
?
LZMA2_STATE_CONTROL
:
LZMA2_STATE_DATA_CONT
;
}
else
{
SizeT
outSizeProcessed
;
SRes
res
;
if
(
p
->
state
==
LZMA2_STATE_DATA
)
{
int
mode
=
LZMA2_GET_LZMA_MODE
(
p
);
LzmaBool
initDic
=
(
mode
==
3
);
LzmaBool
initState
=
(
mode
>
0
);
if
((
!
initDic
&&
p
->
needInitDic
)
||
(
!
initState
&&
p
->
needInitState
))
return
SZ_ERROR_DATA
;
LzmaDec_InitDicAndState
(
&
p
->
decoder
,
initDic
,
initState
);
p
->
needInitDic
=
False
;
p
->
needInitState
=
False
;
p
->
state
=
LZMA2_STATE_DATA_CONT
;
}
if
(
srcSizeCur
>
p
->
packSize
)
srcSizeCur
=
(
SizeT
)
p
->
packSize
;
res
=
LzmaDec_DecodeToDic
(
&
p
->
decoder
,
dicPos
+
destSizeCur
,
src
,
&
srcSizeCur
,
curFinishMode
,
status
);
src
+=
srcSizeCur
;
*
srcLen
+=
srcSizeCur
;
p
->
packSize
-=
(
UInt32
)
srcSizeCur
;
outSizeProcessed
=
p
->
decoder
.
dicPos
-
dicPos
;
p
->
unpackSize
-=
(
UInt32
)
outSizeProcessed
;
RINOK
(
res
);
if
(
*
status
==
LZMA_STATUS_NEEDS_MORE_INPUT
)
return
res
;
if
(
srcSizeCur
==
0
&&
outSizeProcessed
==
0
)
{
if
(
*
status
!=
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
||
p
->
unpackSize
!=
0
||
p
->
packSize
!=
0
)
return
SZ_ERROR_DATA
;
p
->
state
=
LZMA2_STATE_CONTROL
;
}
if
(
*
status
==
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
)
*
status
=
LZMA_STATUS_NOT_FINISHED
;
}
}
}
*
status
=
LZMA_STATUS_FINISHED_WITH_MARK
;
return
SZ_OK
;
}
SRes
Lzma2Dec_DecodeToBuf
(
CLzma2Dec
*
p
,
Byte
*
dest
,
SizeT
*
destLen
,
const
Byte
*
src
,
SizeT
*
srcLen
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
)
{
SizeT
outSize
=
*
destLen
,
inSize
=
*
srcLen
;
*
srcLen
=
*
destLen
=
0
;
for
(;;)
{
SizeT
srcSizeCur
=
inSize
,
outSizeCur
,
dicPos
;
ELzmaFinishMode
curFinishMode
;
SRes
res
;
if
(
p
->
decoder
.
dicPos
==
p
->
decoder
.
dicBufSize
)
p
->
decoder
.
dicPos
=
0
;
dicPos
=
p
->
decoder
.
dicPos
;
if
(
outSize
>
p
->
decoder
.
dicBufSize
-
dicPos
)
{
outSizeCur
=
p
->
decoder
.
dicBufSize
;
curFinishMode
=
LZMA_FINISH_ANY
;
}
else
{
outSizeCur
=
dicPos
+
outSize
;
curFinishMode
=
finishMode
;
}
res
=
Lzma2Dec_DecodeToDic
(
p
,
outSizeCur
,
src
,
&
srcSizeCur
,
curFinishMode
,
status
);
src
+=
srcSizeCur
;
inSize
-=
srcSizeCur
;
*
srcLen
+=
srcSizeCur
;
outSizeCur
=
p
->
decoder
.
dicPos
-
dicPos
;
memcpy
(
dest
,
p
->
decoder
.
dic
+
dicPos
,
outSizeCur
);
dest
+=
outSizeCur
;
outSize
-=
outSizeCur
;
*
destLen
+=
outSizeCur
;
if
(
res
!=
0
)
return
res
;
if
(
outSizeCur
==
0
||
outSize
==
0
)
return
SZ_OK
;
}
}
SRes
Lzma2Decode
(
Byte
*
dest
,
SizeT
*
destLen
,
const
Byte
*
src
,
SizeT
*
srcLen
,
Byte
prop
,
ELzmaFinishMode
finishMode
,
ELzmaStatus
*
status
,
ISzAlloc
*
alloc
)
{
CLzma2Dec
decoder
;
SRes
res
;
SizeT
outSize
=
*
destLen
,
inSize
=
*
srcLen
;
Byte
props
[
LZMA_PROPS_SIZE
];
Lzma2Dec_Construct
(
&
decoder
);
*
destLen
=
*
srcLen
=
0
;
*
status
=
LZMA_STATUS_NOT_SPECIFIED
;
decoder
.
decoder
.
dic
=
dest
;
decoder
.
decoder
.
dicBufSize
=
outSize
;
RINOK
(
Lzma2Dec_GetOldProps
(
prop
,
props
));
RINOK
(
LzmaDec_AllocateProbs
(
&
decoder
.
decoder
,
props
,
LZMA_PROPS_SIZE
,
alloc
));
*
srcLen
=
inSize
;
res
=
Lzma2Dec_DecodeToDic
(
&
decoder
,
outSize
,
src
,
srcLen
,
finishMode
,
status
);
*
destLen
=
decoder
.
decoder
.
dicPos
;
if
(
res
==
SZ_OK
&&
*
status
==
LZMA_STATUS_NEEDS_MORE_INPUT
)
res
=
SZ_ERROR_INPUT_EOF
;
LzmaDec_FreeProbs
(
&
decoder
.
decoder
,
alloc
);
return
res
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Nov 15, 1:59 PM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
124135
Default Alt Text
Lzma2Dec.c (10 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline