1 /* n2d_d.c -- implementation of the NRV2D 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;
97 m_len
= m_len
*2 + getbit(bb
);
102 m_len
= m_len
*2 + getbit(bb
);
103 fail(ilen
>= src_len
, UCL_E_INPUT_OVERRUN
);
104 fail(m_len
>= oend
, UCL_E_OUTPUT_OVERRUN
);
105 } while (!getbit(bb
));
108 m_len
+= (m_off
> 0x500);
109 fail(olen
+ m_len
> oend
, UCL_E_OUTPUT_OVERRUN
);
110 fail(m_off
> olen
, UCL_E_LOOKBEHIND_OVERRUN
);
113 fail(olen
> ilen
, UCL_E_OVERLAP_OVERRUN
);
116 const ucl_byte
*m_pos
;
117 m_pos
= dst
+ olen
- m_off
;
118 dst
[olen
++] = *m_pos
++;
119 do dst
[olen
++] = *m_pos
++; while (--m_len
> 0);
124 return ilen
== src_len
? UCL_E_OK
: (ilen
< src_len
? UCL_E_INPUT_NOT_CONSUMED
: UCL_E_INPUT_OVERRUN
);
132 /***********************************************************************
133 // decompressor entries for the different bit-buffer sizes
134 ************************************************************************/
139 #include "ucl_conf.h"
144 ucl_nrv2d_decompress_8 ( const ucl_bytep src
, ucl_uint src_len
,
145 ucl_bytep dst
, ucl_uintp dst_len
,
148 #define getbit(bb) getbit_8(bb,src,ilen)
155 ucl_nrv2d_decompress_le16 ( const ucl_bytep src
, ucl_uint src_len
,
156 ucl_bytep dst
, ucl_uintp dst_len
,
159 #define getbit(bb) getbit_le16(bb,src,ilen)
166 ucl_nrv2d_decompress_le32 ( const ucl_bytep src
, ucl_uint src_len
,
167 ucl_bytep dst
, ucl_uintp dst_len
,
171 #define getbit(bb) getbit_le32(bb,bc,src,ilen)