*
* Header for decompression code shared by multiple compression formats.
*
- * The author dedicates this file to the public domain.
- * You can do whatever you want with this file.
+ * The following copying information applies to this specific source code file:
+ *
+ * Written in 2012-2016 by Eric Biggers <ebiggers3@gmail.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide via the Creative Commons Zero 1.0 Universal Public Domain
+ * Dedication (the "CC0").
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the CC0 for more details.
+ *
+ * You should have received a copy of the CC0 along with this software; if not
+ * see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#ifndef _WIMLIB_DECOMPRESS_COMMON_H
#define _WIMLIB_DECOMPRESS_COMMON_H
+#include <string.h>
+
#include "wimlib/compiler.h"
#include "wimlib/types.h"
#include "wimlib/unaligned.h"
if (unlikely(is->end - is->next < 2))
goto overflow;
- is->bitbuf |= (u32)get_unaligned_u16_le(is->next) << (16 - is->bitsleft);
+ is->bitbuf |= (u32)get_unaligned_le16(is->next) << (16 - is->bitsleft);
is->next += 2;
is->bitsleft += 16;
if (unlikely(is->end - is->next < 2))
goto overflow;
- is->bitbuf |= (u32)get_unaligned_u16_le(is->next);
+ is->bitbuf |= (u32)get_unaligned_le16(is->next);
is->next += 2;
is->bitsleft = 32;
}
if (unlikely(is->end - is->next < 2))
return 0;
- v = get_unaligned_u16_le(is->next);
+ v = get_unaligned_le16(is->next);
is->next += 2;
return v;
}
if (unlikely(is->end - is->next < 4))
return 0;
- v = get_unaligned_u32_le(is->next);
+ v = get_unaligned_le32(is->next);
is->next += 4;
return v;
}
-/* Read an array of literal bytes embedded in the bitstream. Return a pointer
- * to the resulting array, or NULL if the read overflows the input buffer. */
-static inline const u8 *
-bitstream_read_bytes(struct input_bitstream *is, size_t count)
+/* Read into @dst_buffer an array of literal bytes embedded in the bitstream.
+ * Return 0 if there were enough bytes remaining in the input, otherwise -1. */
+static inline int
+bitstream_read_bytes(struct input_bitstream *is, void *dst_buffer, size_t count)
{
- const u8 *p;
-
if (unlikely(is->end - is->next < count))
- return NULL;
- p = is->next;
+ return -1;
+ memcpy(dst_buffer, is->next, count);
is->next += count;
- return p;
+ return 0;
}
/* Align the input bitstream on a coding-unit boundary. */
{
machine_word_t v;
- BUILD_BUG_ON(WORDSIZE != 4 && WORDSIZE != 8);
+ STATIC_ASSERT(WORDBITS == 32 || WORDBITS == 64);
v = b;
v |= v << 8;
v |= v << 16;
- v |= v << ((WORDSIZE == 8) ? 32 : 0);
+ v |= v << ((WORDBITS == 64) ? 32 : 0);
return v;
}
* example, if a word is 8 bytes and the match is of length 5, then
* we'll simply copy 8 bytes. This is okay as long as we don't write
* beyond the end of the output buffer, hence the check for (winend -
- * end >= WORDSIZE - 1).
+ * end >= WORDBYTES - 1).
*/
- if (UNALIGNED_ACCESS_IS_VERY_FAST &&
- likely(winend - end >= WORDSIZE - 1))
- {
+ if (UNALIGNED_ACCESS_IS_FAST && likely(winend - end >= WORDBYTES - 1)) {
- if (offset >= WORDSIZE) {
+ if (offset >= WORDBYTES) {
/* The source and destination words don't overlap. */
/* To improve branch prediction, one iteration of this
* and we'll need to continue copying. */
copy_word_unaligned(src, dst);
- src += WORDSIZE;
- dst += WORDSIZE;
+ src += WORDBYTES;
+ dst += WORDBYTES;
if (dst < end) {
do {
copy_word_unaligned(src, dst);
- src += WORDSIZE;
- dst += WORDSIZE;
+ src += WORDBYTES;
+ dst += WORDBYTES;
} while (dst < end);
}
return;
machine_word_t v = repeat_byte(*(dst - 1));
do {
store_word_unaligned(v, dst);
- src += WORDSIZE;
- dst += WORDSIZE;
+ src += WORDBYTES;
+ dst += WORDBYTES;
} while (dst < end);
return;
}
/*
* We don't bother with special cases for other 'offset <
- * WORDSIZE', which are usually rarer than 'offset == 1'. Extra
- * checks will just slow things down. Actually, it's possible
- * to handle all the 'offset < WORDSIZE' cases using the same
- * code, but it still becomes more complicated doesn't seem any
- * faster overall; it definitely slows down the more common
- * 'offset == 1' case.
+ * WORDBYTES', which are usually rarer than 'offset == 1'.
+ * Extra checks will just slow things down. Actually, it's
+ * possible to handle all the 'offset < WORDBYTES' cases using
+ * the same code, but it still becomes more complicated doesn't
+ * seem any faster overall; it definitely slows down the more
+ * common 'offset == 1' case.
*/
}