1 /* n2e_d.c -- implementation of the NRV2E decompression algorithm
3 This file is part of the UCL data compression library.
5 Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
8 The UCL library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
13 The UCL library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the UCL library; see the file COPYING.
20 If not, write to the Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 Markus F.X.J. Oberhumer
24 <markus@oberhumer.com>
25 http://www.oberhumer.com/opensource/ucl/
29 /***********************************************************************
30 // actual implementation used by a recursive #include
31 ************************************************************************/
36 #define fail(x,r) if (x) { *dst_len = olen; return r; }
44 ucl_uint ilen
= src_off
, olen
= 0, last_m_off
= 1;
46 ucl_uint ilen
= 0, olen
= 0, last_m_off
= 1;
49 const ucl_uint oend
= *dst_len
;
55 fail(oend
>= src_len
, UCL_E_OVERLAP_OVERRUN
);
60 ucl_uint m_off
, m_len
;
64 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
65 fail(olen
>= oend
, UCL_E_OUTPUT_OVERRUN
);
67 fail(olen
> ilen
, UCL_E_OVERLAP_OVERRUN
);
70 dst
[olen
++] = src
[ilen
++];
76 m_off
= m_off
*2 + getbit(bb
);
77 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
78 fail(m_off
> UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN
);
79 if (getbit(bb
)) break;
80 m_off
= (m_off
-1)*2 + getbit(bb
);
89 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
90 m_off
= (m_off
-3)*256 + src
[ilen
++];
91 if (m_off
== UCL_UINT32_C(0xffffffff))
93 m_len
= (m_off
^ UCL_UINT32_C(0xffffffff)) & 1;
98 m_len
= 1 + getbit(bb
);
100 m_len
= 3 + getbit(bb
);
105 m_len
= m_len
*2 + getbit(bb
);
106 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
107 fail(m_len
>= oend
, UCL_E_OUTPUT_OVERRUN
);
108 } while (!getbit(bb
));
111 m_len
+= (m_off
> 0x500);
112 fail(olen
+ m_len
> oend
, UCL_E_OUTPUT_OVERRUN
);
113 fail(m_off
> olen
, UCL_E_LOOKBEHIND_OVERRUN
);
116 fail(olen
> ilen
, UCL_E_OVERLAP_OVERRUN
);
119 const ucl_byte
*m_pos
;
120 m_pos
= dst
+ olen
- m_off
;
121 dst
[olen
++] = *m_pos
++;
122 do dst
[olen
++] = *m_pos
++; while (--m_len
> 0);
127 return ilen
== src_len
? UCL_E_OK
: (ilen
< src_len
? UCL_E_INPUT_NOT_CONSUMED
: UCL_E_INPUT_OVERRUN
);
135 /***********************************************************************
136 // decompressor entries for the different bit-buffer sizes
137 ************************************************************************/
142 #include "ucl_conf.h"
147 ucl_nrv2e_decompress_8 ( const ucl_byte
*src
, ucl_uint src_len
,
148 ucl_byte
*dst
, ucl_uintp dst_len
,
151 #define getbit(bb) getbit_8(bb,src,ilen)
158 ucl_nrv2e_decompress_le16 ( const ucl_bytep src
, ucl_uint src_len
,
159 ucl_bytep dst
, ucl_uintp dst_len
,
162 #define getbit(bb) getbit_le16(bb,src,ilen)
169 ucl_nrv2e_decompress_le32 ( const ucl_bytep src
, ucl_uint src_len
,
170 ucl_bytep dst
, ucl_uintp dst_len
,
174 #define getbit(bb) getbit_le32(bb,bc,src,ilen)