soc/intel: Remove blank lines before '}' and after '{'
[coreboot2.git] / src / commonlib / bsd / lz4.c.inc
blob8c75e2f2797dab44b3ac1bd977ae17576744c59a
1 /*
2    LZ4 - Fast LZ compression algorithm
3    Copyright (C) 2011-2015, Yann Collet.
5    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7    Redistribution and use in source and binary forms, with or without
8    modification, are permitted provided that the following conditions are
9    met:
11        * Redistributions of source code must retain the above copyright
12    notice, this list of conditions and the following disclaimer.
13        * Redistributions in binary form must reproduce the above
14    copyright notice, this list of conditions and the following disclaimer
15    in the documentation and/or other materials provided with the
16    distribution.
18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30    You can contact the author at :
31    - LZ4 source repository : https://github.com/Cyan4973/lz4
32    - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
36 /**************************************
37 *  Reading and writing into memory
38 **************************************/
40 /* customized variant of memcpy, which can overwrite up to 7 bytes beyond dstEnd */
41 static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
43     BYTE* d = (BYTE*)dstPtr;
44     const BYTE* s = (const BYTE*)srcPtr;
45     BYTE* const e = (BYTE*)dstEnd;
47 #if 0
48     const size_t l2 = 8 - (((size_t)d) & (sizeof(void*)-1));
49     LZ4_copy8(d,s); if (d>e-9) return;
50     d+=l2; s+=l2;
51 #endif /* join to align */
53     do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
57 /**************************************
58 *  Common Constants
59 **************************************/
60 #define MINMATCH 4
62 #define WILDCOPYLENGTH 8
63 #define LASTLITERALS 5
64 #define MFLIMIT (WILDCOPYLENGTH+MINMATCH)
65 static const int LZ4_minLength = (MFLIMIT+1);
67 #define KB *(1 <<10)
68 #define MB *(1 <<20)
69 #define GB *(1U<<30)
71 #define MAXD_LOG 16
72 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
74 #define ML_BITS  4
75 #define ML_MASK  ((1U<<ML_BITS)-1)
76 #define RUN_BITS (8-ML_BITS)
77 #define RUN_MASK ((1U<<RUN_BITS)-1)
80 /**************************************
81 *  Local Structures and types
82 **************************************/
83 typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
84 typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
85 typedef enum { full = 0, partial = 1 } earlyEnd_directive;
89 /*******************************
90 *  Decompression functions
91 *******************************/
93  * This generic decompression function cover all use cases.
94  * It shall be instantiated several times, using different sets of directives
95  * Note that it is essential this generic function is really inlined,
96  * in order to remove useless branches during compilation optimization.
97  */
98 FORCE_INLINE int LZ4_decompress_generic(
99                  const char* const source,
100                  char* const dest,
101                  int inputSize,
102                  int outputSize,         /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
104                  int endOnInput,         /* endOnOutputSize, endOnInputSize */
105                  int partialDecoding,    /* full, partial */
106                  int targetOutputSize,   /* only used if partialDecoding==partial */
107                  int dict,               /* noDict, withPrefix64k, usingExtDict */
108                  const BYTE* const lowPrefix,  /* == dest if dict == noDict */
109                  const BYTE* const dictStart,  /* only if dict==usingExtDict */
110                  const size_t dictSize         /* note : = 0 if noDict */
111                  )
113     /* Local Variables */
114     const BYTE* ip = (const BYTE*) source;
115     const BYTE* const iend = ip + inputSize;
117     BYTE* op = (BYTE*) dest;
118     BYTE* const oend = op + outputSize;
119     BYTE* cpy;
120     BYTE* oexit = op + targetOutputSize;
121     const BYTE* const lowLimit = lowPrefix - dictSize;
123     const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
124     const unsigned dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
125     const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
127     const int safeDecode = (endOnInput==endOnInputSize);
128     const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
129     const int inPlaceDecode = ((ip >= op) && (ip < oend));
132     /* Special cases */
133     if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;                         /* targetOutputSize too high => decode everything */
134     if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1;  /* Empty output buffer */
135     if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
138     /* Main Loop */
139     while (1)
140     {
141         unsigned token;
142         size_t length;
143         const BYTE* match;
144         size_t offset;
146         if (unlikely((inPlaceDecode) && (op + WILDCOPYLENGTH > ip))) goto _output_error;   /* output stream ran over input stream */
148         /* get literal length */
149         token = *ip++;
150         if ((length=(token>>ML_BITS)) == RUN_MASK)
151         {
152             unsigned s;
153             if ((endOnInput) && unlikely(ip>=iend-RUN_MASK)) goto _output_error;   /* overflow detection */
154             do
155             {
156                 s = *ip++;
157                 length += s;
158             }
159             while ( likely(endOnInput ? ip<iend-RUN_MASK : 1) && (s==255) );
160             if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error;   /* overflow detection */
161             if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error;   /* overflow detection */
162         }
164         /* copy literals */
165         cpy = op+length;
166         if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
167             || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)))
168         {
169             if (partialDecoding)
170             {
171                 if (cpy > oend) goto _output_error;                           /* Error : write attempt beyond end of output buffer */
172                 if ((endOnInput) && (ip+length > iend)) goto _output_error;   /* Error : read attempt beyond end of input buffer */
173             }
174             else
175             {
176                 if ((!endOnInput) && (cpy != oend)) goto _output_error;       /* Error : block decoding must stop exactly there */
177                 if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error;   /* Error : input must be consumed */
178             }
179             memmove(op, ip, length);
180             ip += length;
181             op += length;
182             break;     /* Necessarily EOF, due to parsing restrictions */
183         }
184         LZ4_wildCopy(op, ip, cpy);
185         ip += length; op = cpy;
187         /* get offset */
188         offset = LZ4_readLE16(ip); ip+=2;
189         match = op - offset;
190         if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error;   /* Error : offset outside buffers */
192         /* get matchlength */
193         length = token & ML_MASK;
194         if (length == ML_MASK)
195         {
196             unsigned s;
197             do
198             {
199                 if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
200                 s = *ip++;
201                 length += s;
202             } while (s==255);
203             if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error;   /* overflow detection */
204         }
205         length += MINMATCH;
207         /* check external dictionary */
208         if ((dict==usingExtDict) && (match < lowPrefix))
209         {
210             if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error;   /* doesn't respect parsing restriction */
212             if (length <= (size_t)(lowPrefix-match))
213             {
214                 /* match can be copied as a single segment from external dictionary */
215                 match = dictEnd - (lowPrefix-match);
216                 memmove(op, match, length); op += length;
217             }
218             else
219             {
220                 /* match encompass external dictionary and current block */
221                 size_t copySize = (size_t)(lowPrefix-match);
222                 memcpy(op, dictEnd - copySize, copySize);
223                 op += copySize;
224                 copySize = length - copySize;
225                 if (copySize > (size_t)(op-lowPrefix))   /* overlap copy */
226                 {
227                     BYTE* const endOfMatch = op + copySize;
228                     const BYTE* copyFrom = lowPrefix;
229                     while (op < endOfMatch) *op++ = *copyFrom++;
230                 }
231                 else
232                 {
233                     memcpy(op, lowPrefix, copySize);
234                     op += copySize;
235                 }
236             }
237             continue;
238         }
240         /* copy match within block */
241         cpy = op + length;
242         if (unlikely(offset<8))
243         {
244             const int dec64 = dec64table[offset];
245             op[0] = match[0];
246             op[1] = match[1];
247             op[2] = match[2];
248             op[3] = match[3];
249             match += dec32table[offset];
250             memcpy(op+4, match, 4);
251             match -= dec64;
252         } else { LZ4_copy8(op, match); match+=8; }
253         op += 8;
255         if (unlikely(cpy>oend-12))
256         {
257             BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1);
258             if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
259             if (op < oCopyLimit)
260             {
261                 LZ4_wildCopy(op, match, oCopyLimit);
262                 match += oCopyLimit - op;
263                 op = oCopyLimit;
264             }
265             while (op<cpy) *op++ = *match++;
266         }
267         else
268             LZ4_wildCopy(op, match, cpy);
269         op=cpy;   /* correction */
270     }
272     /* end of decoding */
273     if (endOnInput)
274        return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
275     else
276        return (int) (((const char*)ip)-source);   /* Nb of input bytes read */
278     /* Overflow error detected */
279 _output_error:
280     return (int) (-(((const char*)ip)-source))-1;