0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _LINUX_NTFS3_LIB_DECOMPRESS_COMMON_H
0009 #define _LINUX_NTFS3_LIB_DECOMPRESS_COMMON_H
0010
0011 #include <linux/string.h>
0012 #include <linux/compiler.h>
0013 #include <linux/types.h>
0014 #include <linux/slab.h>
0015 #include <asm/unaligned.h>
0016
0017
0018
0019 #define forceinline __always_inline
0020
0021
0022 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_FEATURE_UNALIGNED)
0023 # define FAST_UNALIGNED_ACCESS
0024 #endif
0025
0026
0027 #define WORDBYTES (sizeof(size_t))
0028
0029 static forceinline void
0030 copy_unaligned_word(const void *src, void *dst)
0031 {
0032 put_unaligned(get_unaligned((const size_t *)src), (size_t *)dst);
0033 }
0034
0035
0036
0037
0038
0039 static forceinline size_t repeat_byte(u8 b)
0040 {
0041 size_t v;
0042
0043 v = b;
0044 v |= v << 8;
0045 v |= v << 16;
0046 v |= v << ((WORDBYTES == 8) ? 32 : 0);
0047 return v;
0048 }
0049
0050
0051
0052
0053
0054
0055 struct input_bitstream {
0056
0057
0058
0059
0060 u32 bitbuf;
0061
0062
0063 u32 bitsleft;
0064
0065
0066 const u8 *next;
0067
0068
0069 const u8 *end;
0070 };
0071
0072
0073 static forceinline void init_input_bitstream(struct input_bitstream *is,
0074 const void *buffer, u32 size)
0075 {
0076 is->bitbuf = 0;
0077 is->bitsleft = 0;
0078 is->next = buffer;
0079 is->end = is->next + size;
0080 }
0081
0082
0083
0084
0085
0086
0087 static forceinline void bitstream_ensure_bits(struct input_bitstream *is,
0088 u32 num_bits)
0089 {
0090 if (is->bitsleft < num_bits) {
0091 if (is->end - is->next >= 2) {
0092 is->bitbuf |= (u32)get_unaligned_le16(is->next)
0093 << (16 - is->bitsleft);
0094 is->next += 2;
0095 }
0096 is->bitsleft += 16;
0097 }
0098 }
0099
0100
0101
0102
0103
0104 static forceinline u32
0105 bitstream_peek_bits(const struct input_bitstream *is, const u32 num_bits)
0106 {
0107 return (is->bitbuf >> 1) >> (sizeof(is->bitbuf) * 8 - num_bits - 1);
0108 }
0109
0110
0111
0112
0113
0114 static forceinline void
0115 bitstream_remove_bits(struct input_bitstream *is, u32 num_bits)
0116 {
0117 is->bitbuf <<= num_bits;
0118 is->bitsleft -= num_bits;
0119 }
0120
0121
0122
0123
0124
0125 static forceinline u32
0126 bitstream_pop_bits(struct input_bitstream *is, u32 num_bits)
0127 {
0128 u32 bits = bitstream_peek_bits(is, num_bits);
0129
0130 bitstream_remove_bits(is, num_bits);
0131 return bits;
0132 }
0133
0134
0135 static forceinline u32
0136 bitstream_read_bits(struct input_bitstream *is, u32 num_bits)
0137 {
0138 bitstream_ensure_bits(is, num_bits);
0139 return bitstream_pop_bits(is, num_bits);
0140 }
0141
0142
0143 static forceinline u8
0144 bitstream_read_byte(struct input_bitstream *is)
0145 {
0146 if (unlikely(is->end == is->next))
0147 return 0;
0148 return *is->next++;
0149 }
0150
0151
0152 static forceinline u16
0153 bitstream_read_u16(struct input_bitstream *is)
0154 {
0155 u16 v;
0156
0157 if (unlikely(is->end - is->next < 2))
0158 return 0;
0159 v = get_unaligned_le16(is->next);
0160 is->next += 2;
0161 return v;
0162 }
0163
0164
0165 static forceinline u32
0166 bitstream_read_u32(struct input_bitstream *is)
0167 {
0168 u32 v;
0169
0170 if (unlikely(is->end - is->next < 4))
0171 return 0;
0172 v = get_unaligned_le32(is->next);
0173 is->next += 4;
0174 return v;
0175 }
0176
0177
0178
0179
0180
0181 static forceinline void *bitstream_read_bytes(struct input_bitstream *is,
0182 void *dst_buffer, size_t count)
0183 {
0184 if ((size_t)(is->end - is->next) < count)
0185 return NULL;
0186 memcpy(dst_buffer, is->next, count);
0187 is->next += count;
0188 return (u8 *)dst_buffer + count;
0189 }
0190
0191
0192 static forceinline void bitstream_align(struct input_bitstream *is)
0193 {
0194 is->bitsleft = 0;
0195 is->bitbuf = 0;
0196 }
0197
0198 extern int make_huffman_decode_table(u16 decode_table[], const u32 num_syms,
0199 const u32 num_bits, const u8 lens[],
0200 const u32 max_codeword_len,
0201 u16 working_space[]);
0202
0203
0204
0205
0206
0207
0208 static forceinline u32 read_huffsym(struct input_bitstream *istream,
0209 const u16 decode_table[],
0210 u32 table_bits,
0211 u32 max_codeword_len)
0212 {
0213 u32 entry;
0214 u32 key_bits;
0215
0216 bitstream_ensure_bits(istream, max_codeword_len);
0217
0218
0219 key_bits = bitstream_peek_bits(istream, table_bits);
0220 entry = decode_table[key_bits];
0221 if (entry < 0xC000) {
0222
0223
0224
0225
0226 bitstream_remove_bits(istream, entry >> 11);
0227 return entry & 0x7FF;
0228 }
0229
0230
0231
0232
0233
0234
0235 bitstream_remove_bits(istream, table_bits);
0236 do {
0237 key_bits = (entry & 0x3FFF) + bitstream_pop_bits(istream, 1);
0238 } while ((entry = decode_table[key_bits]) >= 0xC000);
0239 return entry;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 static forceinline u8 *lz_copy(u8 *dst, u32 length, u32 offset, const u8 *bufend,
0255 u32 min_length)
0256 {
0257 const u8 *src = dst - offset;
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 #ifdef FAST_UNALIGNED_ACCESS
0273 u8 * const end = dst + length;
0274
0275 if (bufend - end >= (ptrdiff_t)(WORDBYTES - 1)) {
0276
0277 if (offset >= WORDBYTES) {
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 copy_unaligned_word(src, dst);
0288 src += WORDBYTES;
0289 dst += WORDBYTES;
0290
0291 if (dst < end) {
0292 do {
0293 copy_unaligned_word(src, dst);
0294 src += WORDBYTES;
0295 dst += WORDBYTES;
0296 } while (dst < end);
0297 }
0298 return end;
0299 } else if (offset == 1) {
0300
0301
0302
0303
0304
0305 size_t v = repeat_byte(*(dst - 1));
0306
0307 do {
0308 put_unaligned(v, (size_t *)dst);
0309 src += WORDBYTES;
0310 dst += WORDBYTES;
0311 } while (dst < end);
0312 return end;
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 }
0324 #endif
0325
0326
0327
0328 if (min_length >= 2) {
0329 *dst++ = *src++;
0330 length--;
0331 }
0332 if (min_length >= 3) {
0333 *dst++ = *src++;
0334 length--;
0335 }
0336 do {
0337 *dst++ = *src++;
0338 } while (--length);
0339
0340 return dst;
0341 }
0342
0343 #endif