diff options
author | Matthieu Patou <mat@matws.net> | 2014-10-10 16:53:20 -0400 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2014-10-30 15:28:47 +0000 |
commit | cda985d3eb637454fb773157893d4d8cb18313a2 (patch) | |
tree | 04a5c56720817e7a40ad5984fdbdd89da8525827 /epan/compress/lzxpress.c | |
parent | fea733e82b290882b592adfef4b8ae621245f5cd (diff) |
Create the compress module for compression functions.
For the moment there is only the lzxpress compression used by DRS
Bug: 10546
Change-Id: Ifc7e1767934224c0198f0b09caa3efbad979ca1f
Reviewed-on: https://code.wireshark.org/review/4600
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/compress/lzxpress.c')
-rw-r--r-- | epan/compress/lzxpress.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/epan/compress/lzxpress.c b/epan/compress/lzxpress.c new file mode 100644 index 0000000000..2e8883a407 --- /dev/null +++ b/epan/compress/lzxpress.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) Matthieu Suiche 2008 + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include "lzxpress.h" + +#define __BUF_POS_CONST(buf,ofs)(((const guint8 *)buf)+(ofs)) +#define __PULL_BYTE(buf,ofs) \ + ((guint8)((*__BUF_POS_CONST(buf,ofs)) & 0xFF)) + +#ifndef PULL_LE_UINT16 +#define PULL_LE_UINT16(buf,ofs) ((guint16)( \ + ((guint16)(((guint16)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ + ((guint16)(((guint16)(__PULL_BYTE(buf,(ofs)+1))) << 8)) \ +)) +#endif + +#ifndef PULL_LE_UINT32 +#define PULL_LE_UINT32(buf,ofs) ((guint32)( \ + ((guint32)(((guint32)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ + ((guint32)(((guint32)(__PULL_BYTE(buf,(ofs)+1))) << 8)) | \ + ((guint32)(((guint32)(__PULL_BYTE(buf,(ofs)+2))) << 16)) | \ + ((guint32)(((guint32)(__PULL_BYTE(buf,(ofs)+3))) << 24)) \ +)) +#endif + +gssize lzxpress_decompress(const guint8 *input, + guint32 input_size, + guint8 *output, + guint32 max_output_size) +{ + guint32 output_index, input_index; + guint32 indicator, indicator_bit; + guint32 length; + guint32 offset; + guint32 nibble_index; + + output_index = 0; + input_index = 0; + indicator = 0; + indicator_bit = 0; + length = 0; + offset = 0; + nibble_index = 0; + + do { + if (indicator_bit == 0) { + indicator = PULL_LE_UINT32(input, input_index); + input_index += sizeof(guint32); + indicator_bit = 32; + } + indicator_bit--; + + /* + * check whether the bit specified by indicator_bit is set or not + * set in indicator. For example, if indicator_bit has value 4 + * check whether the 4th bit of the value in indicator is set + */ + if (((indicator >> indicator_bit) & 1) == 0) { + output[output_index] = input[input_index]; + input_index += sizeof(guint8); + output_index += sizeof(guint8); + } else { + length = PULL_LE_UINT16(input, input_index); + input_index += sizeof(guint16); + offset = length / 8; + length = length % 8; + + if (length == 7) { + if (nibble_index == 0) { + nibble_index = input_index; + length = input[input_index] % 16; + input_index += sizeof(guint8); + } else { + length = input[nibble_index] / 16; + nibble_index = 0; + } + + if (length == 15) { + length = input[input_index]; + input_index += sizeof(guint8); + if (length == 255) { + length = PULL_LE_UINT16(input, input_index); + input_index += sizeof(guint16); + length -= (15 + 7); + } + length += 15; + } + length += 7; + } + + length += 3; + + do { + if ((output_index >= max_output_size) || ((offset + 1) > output_index)) break; + + output[output_index] = output[output_index - offset - 1]; + + output_index += sizeof(guint8); + length -= sizeof(guint8); + } while (length != 0); + } + } while ((output_index < max_output_size) && (input_index < (input_size))); + + return output_index; +} |