1 /* n2b_d.c -- implementation of the NRV2B 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
++];
75 m_off
= m_off
*2 + getbit(bb
);
76 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
77 fail(m_off
> UCL_UINT32_C(0xffffff) + 3, UCL_E_LOOKBEHIND_OVERRUN
);
78 } while (!getbit(bb
));
85 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
86 m_off
= (m_off
-3)*256 + src
[ilen
++];
87 if (m_off
== UCL_UINT32_C(0xffffffff))
92 m_len
= m_len
*2 + getbit(bb
);
97 m_len
= m_len
*2 + getbit(bb
);
98 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
99 fail(m_len
>= oend
, UCL_E_OUTPUT_OVERRUN
);
100 } while (!getbit(bb
));
103 m_len
+= (m_off
> 0xd00);
104 fail(olen
+ m_len
> oend
, UCL_E_OUTPUT_OVERRUN
);
105 fail(m_off
> olen
, UCL_E_LOOKBEHIND_OVERRUN
);
108 fail(olen
> ilen
, UCL_E_OVERLAP_OVERRUN
);
111 const ucl_byte
*m_pos
;
112 m_pos
= dst
+ olen
- m_off
;
113 dst
[olen
++] = *m_pos
++;
114 do dst
[olen
++] = *m_pos
++; while (--m_len
> 0);
119 return ilen
== src_len
? UCL_E_OK
: (ilen
< src_len
? UCL_E_INPUT_NOT_CONSUMED
: UCL_E_INPUT_OVERRUN
);
127 /***********************************************************************
128 // decompressor entries for the different bit-buffer sizes
129 ************************************************************************/
134 #include "ucl_conf.h"
139 ucl_nrv2b_decompress_8 ( const ucl_bytep src
, ucl_uint src_len
,
140 ucl_bytep dst
, ucl_uintp dst_len
,
143 #define getbit(bb) getbit_8(bb,src,ilen)
150 ucl_nrv2b_decompress_le16 ( const ucl_bytep src
, ucl_uint src_len
,
151 ucl_bytep dst
, ucl_uintp dst_len
,
154 #define getbit(bb) getbit_le16(bb,src,ilen)
161 ucl_nrv2b_decompress_le32 ( const ucl_bytep src
, ucl_uint src_len
,
162 ucl_bytep dst
, ucl_uintp dst_len
,
166 #define getbit(bb) getbit_le32(bb,bc,src,ilen)