25 Commits
Author SHA1 Message Date
Ernesto A. Fernández de4083a506 0.3.15
This release adds support for the upcoming 6.16 kernel version.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-07-25 19:27:24 -03:00
Ernesto A. Fernández a3c23dffc3 Don't reference page index in 6.16
The build is broken for the 6.16 release candidate:

  https://github.com/linux-apfs/linux-apfs-rw/issues/99

The problem is that the page struct no longer has a member called
"index". Use folios for this instead.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-07-01 20:45:23 -03:00
Ernesto A. Fernández 7d8dc8821e 0.3.14
This release adds support for the upcoming 6.15 kernel version, and for
RHEL 9.6.

A longstanding objtool warning has also been fixed.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-05-23 21:32:10 -03:00
Ernesto A. Fernández 26bf3c5ba7 Fix build if kernel has no __annotate_jump_table
I recently started to use the __annotate_jump_table macro to silence an
objtool warning, but it seems that this macro was only added for the 5.3
kernel. Just define it to nothing for older releases, the objtool
warnings probably don't matter that much.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-05-16 17:40:41 -03:00
Ernesto A. Fernández c87d7aa77f Fix build for RHEL 9.6
The build has broken again for RHEL:

  https://github.com/linux-apfs/linux-apfs-rw/issues/95

Fix it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-05-14 20:43:28 -03:00
Ernesto A. Fernández 87cc3f6940 Get rid of "pragma once" in lzfse code
Use regular macro guards instead.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-05-09 18:56:43 -03:00
Ernesto A. Fernández 51a5b742ec Fix the returned type of ->mkdir() for 6.15
The ->mkdir() method now needs to return a dentry struct instead of an
int, but this is meant for clustered filesystems or something so just
return NULL on success, like most filesystems do.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-21 19:24:48 -03:00
Ernesto A. Fernández e41b8f1f0e Handle page functions newly removed in 6.15
It seems that wait_for_stable_page(), page_has_buffers() and
grab_cache_page_write_begin() are no longer available, so put
implementations inside the driver.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-21 18:31:15 -03:00
Ernesto A. Fernández 68ad507875 Get rid of typedef for fse_value_decoder_entry
I don't intend to remove all typedefs from the lzfse code, but this one
is triggering a false positive for another issue in checkpatch. Get rid
of it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-16 17:32:24 -03:00
Ernesto A. Fernández 1039569db9 Correct brace placement in an lzfse for loop
Checkpatch complains about the brace placement in this for loop. Change
it.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-16 17:20:17 -03:00
Ernesto A. Fernández 86cee6ecf8 Add SPDX identifiers to lzfse files
They are all under the 3-clause BSD license, so annotate them as such.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 20:58:12 -03:00
Ernesto A. Fernández 37e9e2a726 Unify lzfse style for sizeof
Always use sizeof with brackets, like checkpatch prefers.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 20:39:43 -03:00
Ernesto A. Fernández 991eebd92a Don't use __attribute__ in lzfse
The kernel has macros for these things, so use them instead and silence
the checkpatch warnings.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 20:30:08 -03:00
Ernesto A. Fernández f47daaf15c Don't use "unsigned" alone in lzfse
Checkpatch prefers "unsigned int" over "unsigned", so fix this where
needed.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 20:02:59 -03:00
Ernesto A. Fernández be38209c0b Don't use unnecessary braces in lzfse
Another checkpatch warning: remove all braces around blocks that have a
single statement, except for two cases where it makes more sense to
reorganize long comments so that the warnings stop.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 19:20:22 -03:00
Ernesto A. Fernández 84e57c48c4 Add blank lines after declarations in lzfse
Continue to silence checkpatch warnings with this change.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-15 19:08:09 -03:00
Ernesto A. Fernández 5aa52b928f Change the comment style of lzfse
Change the comment style in the lzfse code (by hand) to more or less
match the rest of the driver.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-11 20:00:54 -03:00
Ernesto A. Fernández c42445a577 Run clang-format on the remaining lzfse code
Continuing with the lzfse code cleanup: it seems that clang-format can
at least fix the whitespace reliably, so run it and get that out of the
way. But set the column limit to 100 like checkpatch uses, to avoid too
much awkward line wrapping on the parts of the code that go far to the
right.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-10 19:39:14 -03:00
Ernesto A. Fernández 6384c5dd50 Get rid of the lzfse inline macros
The kernel provides its own __always_inline macro, so get rid of those
that came with lzfse.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-09 18:12:44 -03:00
Ernesto A. Fernández acdad48cbc Get rid of LZFSE_API macro
The LZFSE_API macro doesn't seem to be used anywhere right now, so clean
it up.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-09 17:34:09 -03:00
Ernesto A. Fernández 92583d1c8f Get rid of C++ stuff in lzfse
None of this code will ever get called from C++, so clean that up.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-09 16:52:50 -03:00
Ernesto A. Fernández efc3c7b5ac Get rid of compiler checks in the lzfse code
I don't think any rare compilers are used to build the kernel, so just
assume gcc/clang everywhere. Also get rid of the dll checks.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-09 16:25:36 -03:00
Ernesto A. Fernández d3ea85f068 Allow jumptables without preprocessor checks
Jumptables are used elsewhere in the kernel, so it's safe to assume that
the compiler supports them. Clean up all the dead fallback code for
lzvn decompression.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-08 20:53:57 -03:00
Ernesto A. Fernández 21f190f58b Annotate jump table in lzvn decompression code
Since I first copied the lzfse code into the driver, the build has been
throwing the following error:

  lzfse/lzvn_decode_base.o: warning: objtool: lzvn_decode+0x10: sibling call from callable instruction with modified stack frame

I've been ignoring this because objtool warnings are probably not a big
deal for us; I think they are mostly for live patches. I'm also not
familiar with the lzfse code so I assumed this would be hard to fix.
It's not though: just annotate the jump table correctly.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-08 20:40:29 -03:00
Ernesto A. Fernández f0982e87d4 Clear unused lzfse/lzvn compression code
I have no real intention of ever supporting compressed writes. Last I
checked, the official implementation simply decompresses files when you
try to write to them, so maybe I will do that here as well at some
point. For now users that need this can work with a copy of the file
(and delete the original).

So, get rid of all the unused lzfse/lzvn compression code. This will
make it easier to fix the code style in the following patches.

Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
2025-04-08 19:39:22 -03:00
24 changed files with 2089 additions and 4814 deletions

No files matched your search

+18 -5
View File
@@ -945,7 +945,7 @@ extern int apfs_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned int flags);
extern int apfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
bool excl);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
extern int apfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev);
extern int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
@@ -955,11 +955,20 @@ extern int apfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *new_dentry, unsigned int flags);
extern int apfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl);
#else
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 15, 0)
extern int apfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev);
extern int apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode);
extern int apfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags);
extern int apfs_create(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl);
#else
extern int apfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev);
extern struct dentry *apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode);
extern int apfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags);
@@ -1018,7 +1027,7 @@ extern int apfs_dstream_adj_refcnt(struct apfs_dstream_info *dstream, u32 delta)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
extern int apfs_setattr(struct dentry *dentry, struct iattr *iattr);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
extern int apfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *iattr);
#else
@@ -1040,7 +1049,7 @@ extern int apfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
extern int apfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
extern int apfs_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat, u32 request_mask,
unsigned int query_flags);
@@ -1052,7 +1061,7 @@ extern int apfs_getattr(struct mnt_idmap *idmap,
extern int apfs_crypto_adj_refcnt(struct super_block *sb, u64 crypto_id, int delta);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) || RHEL_VERSION_GE(9, 6)
extern int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
extern int apfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
@@ -1194,6 +1203,10 @@ static inline void apfs_assert_query_is_valid(const struct apfs_query *query)
ASSERT(apfs_node_is_root(apfs_query_root(query)));
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
#define page_has_buffers(page) folio_buffers(page_folio(page))
#endif
/*
* TODO: the following are modified variants of buffer head functions that will
* work with the shared block device for the container. The correct approach
+4
View File
@@ -422,7 +422,11 @@ static int apfs_compress_readpage(struct file *filp, struct page *page)
loff_t off;
/* Mostly copied from ext4_read_inline_page() */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
off = page_folio(page)->index << PAGE_SHIFT;
#else
off = page->index << PAGE_SHIFT;
#endif
addr = kmap(page);
ret = apfs_compress_file_read_page(filp, addr, off);
flush_dcache_page(page);
+12 -5
View File
@@ -698,7 +698,7 @@ out_abort:
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
int apfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
dev_t rdev)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, dev_t rdev)
#else
@@ -716,7 +716,7 @@ int apfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
return apfs_mknod(dir, dentry, mode | S_IFDIR, 0 /* rdev */);
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode)
@@ -724,7 +724,7 @@ int apfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
return apfs_mknod(mnt_userns, dir, dentry, mode | S_IFDIR, 0 /* rdev */);
}
#else
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 15, 0)
int apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *dentry, umode_t mode)
@@ -732,6 +732,13 @@ int apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
return apfs_mknod(idmap, dir, dentry, mode | S_IFDIR, 0 /* rdev */);
}
#else
struct dentry *apfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)
{
return ERR_PTR(apfs_mknod(idmap, dir, dentry, mode | S_IFDIR, 0 /* rdev */));
}
#endif
@@ -743,7 +750,7 @@ int apfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
return apfs_mknod(dir, dentry, mode, 0 /* rdev */);
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_create(struct user_namespace *mnt_userns, struct inode *dir,
struct dentry *dentry, umode_t mode, bool excl)
@@ -1373,7 +1380,7 @@ int apfs_rmdir(struct inode *dir, struct dentry *dentry)
int apfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
struct dentry *old_dentry, struct inode *new_dir,
struct dentry *new_dentry, unsigned int flags)
+1 -1
View File
@@ -1,5 +1,5 @@
PACKAGE_NAME="linux-apfs-rw"
PACKAGE_VERSION="0.3.13"
PACKAGE_VERSION="0.3.15"
BUILT_MODULE_NAME[0]="apfs"
DEST_MODULE_LOCATION[0]="/extra"
+11
View File
@@ -12,6 +12,13 @@
typedef int vm_fault_t;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
static void wait_for_stable_page(struct page *page)
{
return folio_wait_stable(page_folio(page));
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
static vm_fault_t apfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
@@ -65,7 +72,11 @@ static vm_fault_t apfs_page_mkwrite(struct vm_fault *vmf)
}
size = i_size_read(inode);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 16, 0)
if (page_folio(page)->index == size >> PAGE_SHIFT)
#else
if (page->index == size >> PAGE_SHIFT)
#endif
len = size & ~PAGE_MASK;
else
len = PAGE_SIZE;
+15 -8
View File
@@ -20,6 +20,13 @@
#define MAX_PFK_LEN 512
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0)
static struct page *grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index)
{
return pagecache_get_page(mapping, index, FGP_WRITEBEGIN, mapping_gfp_mask(mapping));
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) || RHEL_VERSION_GE(9, 3)
static int apfs_read_folio(struct file *file, struct folio *folio)
@@ -1071,7 +1078,7 @@ int apfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
int apfs_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_getattr(struct user_namespace *mnt_userns,
const struct path *path, struct kstat *stat, u32 request_mask,
unsigned int query_flags)
@@ -1103,7 +1110,7 @@ int apfs_getattr(struct mnt_idmap *idmap,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
generic_fillattr(inode, stat);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
generic_fillattr(mnt_userns, inode, stat);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
generic_fillattr(idmap, inode, stat);
@@ -1875,7 +1882,7 @@ struct inode *apfs_new_inode(struct inode *dir, umode_t mode, dev_t rdev)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
inode_init_owner(inode, dir, mode);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
inode_init_owner(&init_user_ns, inode, dir, mode);
#else
inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
@@ -2023,7 +2030,7 @@ static int apfs_setsize(struct inode *inode, loff_t new_size)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
int apfs_setattr(struct dentry *dentry, struct iattr *iattr)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_setattr(struct user_namespace *mnt_userns,
struct dentry *dentry, struct iattr *iattr)
#else
@@ -2044,7 +2051,7 @@ int apfs_setattr(struct mnt_idmap *idmap,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
err = setattr_prepare(dentry, iattr);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
err = setattr_prepare(&init_user_ns, dentry, iattr);
#else
err = setattr_prepare(&nop_mnt_idmap, dentry, iattr);
@@ -2068,7 +2075,7 @@ int apfs_setattr(struct mnt_idmap *idmap,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
setattr_copy(inode, iattr);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
setattr_copy(&init_user_ns, inode, iattr);
#else
setattr_copy(&nop_mnt_idmap, inode, iattr);
@@ -2100,7 +2107,7 @@ int apfs_update_time(struct inode *inode, int flags)
return err;
apfs_inode_join_transaction(sb, inode);
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && !RHEL_VERSION_GE(9, 6)
generic_update_time(inode, time, flags);
#else
generic_update_time(inode, flags);
@@ -2436,7 +2443,7 @@ static int apfs_ioc_setflags(struct file *file, int __user *arg)
return err;
}
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0) && !RHEL_VERSION_GE(9, 6)
int apfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
{
+25 -94
View File
@@ -1,23 +1,24 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
* Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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.
*/
#ifndef LZFSE_H
#define LZFSE_H
@@ -25,71 +26,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
#include <linux/stddef.h>
#include <linux/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_MSC_VER) && !defined(__clang__)
# define __attribute__(X)
# pragma warning(disable : 4068)
#endif
#if defined(LZFSE_DLL)
# if defined(_WIN32) || defined(__CYGWIN__)
# if defined(LZFSE_DLL_EXPORTS)
# define LZFSE_API __declspec(dllexport)
# else
# define LZFSE_API __declspec(dllimport)
# endif
# endif
#endif
#if !defined(LZFSE_API)
# if __GNUC__ >= 4
# define LZFSE_API __attribute__((visibility("default")))
# else
# define LZFSE_API
# endif
#endif
/*! @abstract Get the required scratch buffer size to compress using LZFSE. */
size_t lzfse_encode_scratch_size(void);
/*! @abstract Compress a buffer using LZFSE.
*
* @param dst_buffer
* Pointer to the first byte of the destination buffer.
*
* @param dst_size
* Size of the destination buffer in bytes.
*
* @param src_buffer
* Pointer to the first byte of the source buffer.
*
* @param src_size
* Size of the source buffer in bytes.
*
* @param scratch_buffer
* If non-NULL, a pointer to scratch space for the routine to use as workspace;
* the routine may use up to lzfse_encode_scratch_size( ) bytes of workspace
* during its operation, and will not perform any internal allocations. If
* NULL, the routine may allocate its own memory to use during operation via
* a single call to malloc( ), and will release it by calling free( ) prior
* to returning. For most use, passing NULL is perfectly satisfactory, but if
* you require strict control over allocation, you will want to pass an
* explicit scratch buffer.
*
* @return
* The number of bytes written to the destination buffer if the input is
* successfully compressed. If the input cannot be compressed to fit into
* the provided buffer, or an error occurs, zero is returned, and the
* contents of dst_buffer are unspecified. */
size_t lzfse_encode_buffer(uint8_t *__restrict dst_buffer,
size_t dst_size,
const uint8_t *__restrict src_buffer,
size_t src_size,
void *__restrict scratch_buffer);
/*! @abstract Get the required scratch buffer size to decompress using LZFSE. */
size_t lzfse_decode_scratch_size(void);
@@ -122,15 +58,10 @@ size_t lzfse_decode_scratch_size(void);
* successfully decompressed. If there is not enough space in the destination
* buffer to hold the entire expanded output, only the first dst_size bytes
* will be written to the buffer and dst_size is returned. Note that this
* behavior differs from that of lzfse_encode_buffer. */
size_t lzfse_decode_buffer(uint8_t *__restrict dst_buffer,
size_t dst_size,
const uint8_t *__restrict src_buffer,
size_t src_size,
void *__restrict scratch_buffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
* behavior differs from that of lzfse_encode_buffer.
*/
size_t lzfse_decode_buffer(uint8_t *__restrict dst_buffer, size_t dst_size,
const uint8_t *__restrict src_buffer, size_t src_size,
void *__restrict scratch_buffer);
#endif /* LZFSE_H */
+65 -59
View File
@@ -1,74 +1,80 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
Copyright (c) 2015-2016, Apple Inc. All rights reserved.
* Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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.
*/
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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
// LZFSE decode API
/* LZFSE decode API */
#include <linux/slab.h>
#include "lzfse.h"
#include "lzfse_internal.h"
size_t lzfse_decode_scratch_size(void) { return sizeof(lzfse_decoder_state); }
size_t lzfse_decode_scratch_size(void)
{
return sizeof(lzfse_decoder_state);
}
static size_t lzfse_decode_buffer_with_scratch(uint8_t *__restrict dst_buffer,
size_t dst_size, const uint8_t *__restrict src_buffer,
size_t src_size, void *__restrict scratch_buffer) {
int status;
lzfse_decoder_state *s = (lzfse_decoder_state *)scratch_buffer;
memset(s, 0x00, sizeof(*s));
static size_t lzfse_decode_buffer_with_scratch(uint8_t *__restrict dst_buffer, size_t dst_size,
const uint8_t *__restrict src_buffer,
size_t src_size, void *__restrict scratch_buffer)
{
int status;
lzfse_decoder_state *s = (lzfse_decoder_state *)scratch_buffer;
// Initialize state
s->src = src_buffer;
s->src_begin = src_buffer;
s->src_end = s->src + src_size;
s->dst = dst_buffer;
s->dst_begin = dst_buffer;
s->dst_end = dst_buffer + dst_size;
memset(s, 0x00, sizeof(*s));
// Decode
status = lzfse_decode(s);
if (status == LZFSE_STATUS_DST_FULL)
return dst_size;
if (status != LZFSE_STATUS_OK)
return 0; // failed
return (size_t)(s->dst - dst_buffer); // bytes written
/* Initialize state */
s->src = src_buffer;
s->src_begin = src_buffer;
s->src_end = s->src + src_size;
s->dst = dst_buffer;
s->dst_begin = dst_buffer;
s->dst_end = dst_buffer + dst_size;
/* Decode */
status = lzfse_decode(s);
if (status == LZFSE_STATUS_DST_FULL)
return dst_size;
if (status != LZFSE_STATUS_OK)
return 0; /* failed */
return (size_t)(s->dst - dst_buffer); /* bytes written */
}
size_t lzfse_decode_buffer(uint8_t *__restrict dst_buffer, size_t dst_size,
const uint8_t *__restrict src_buffer,
size_t src_size, void *__restrict scratch_buffer) {
int has_malloc = 0;
size_t ret = 0;
const uint8_t *__restrict src_buffer, size_t src_size,
void *__restrict scratch_buffer)
{
int has_malloc = 0;
size_t ret = 0;
// Deal with the possible NULL pointer
if (scratch_buffer == NULL) {
// +1 in case scratch size could be zero
scratch_buffer = kmalloc(lzfse_decode_scratch_size() + 1, GFP_KERNEL);
has_malloc = 1;
}
if (scratch_buffer == NULL)
return 0;
ret = lzfse_decode_buffer_with_scratch(dst_buffer,
dst_size, src_buffer,
src_size, scratch_buffer);
if (has_malloc)
kfree(scratch_buffer);
return ret;
/* Deal with the possible NULL pointer */
if (scratch_buffer == NULL) {
/* +1 in case scratch size could be zero */
scratch_buffer = kmalloc(lzfse_decode_scratch_size() + 1, GFP_KERNEL);
has_malloc = 1;
}
if (scratch_buffer == NULL)
return 0;
ret = lzfse_decode_buffer_with_scratch(dst_buffer, dst_size, src_buffer, src_size,
scratch_buffer);
if (has_malloc)
kfree(scratch_buffer);
return ret;
}
+647 -556
View File
File diff suppressed because it is too large. Load diff
-163
View File
@@ -1,163 +0,0 @@
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
// LZFSE encode API
#include "lzfse.h"
#include "lzfse_internal.h"
size_t lzfse_encode_scratch_size() {
size_t s1 = sizeof(lzfse_encoder_state);
size_t s2 = lzvn_encode_scratch_size();
return (s1 > s2) ? s1 : s2; // max(lzfse,lzvn)
}
size_t lzfse_encode_buffer_with_scratch(uint8_t *__restrict dst_buffer,
size_t dst_size, const uint8_t *__restrict src_buffer,
size_t src_size, void *__restrict scratch_buffer) {
const size_t original_size = src_size;
// If input is really really small, go directly to uncompressed buffer
// (because LZVN will refuse to encode it, and we will report a failure)
if (src_size < LZVN_ENCODE_MIN_SRC_SIZE)
goto try_uncompressed;
// If input is too small, try encoding with LZVN
if (src_size < LZFSE_ENCODE_LZVN_THRESHOLD) {
// need header + end-of-stream marker
size_t extra_size = 4 + sizeof(lzvn_compressed_block_header);
if (dst_size <= extra_size)
goto try_uncompressed; // DST is really too small, give up
size_t sz = lzvn_encode_buffer(
dst_buffer + sizeof(lzvn_compressed_block_header),
dst_size - extra_size, src_buffer, src_size, scratch_buffer);
if (sz == 0 || sz >= src_size)
goto try_uncompressed; // failed, or no compression, fall back to
// uncompressed block
// If we could encode, setup header and end-of-stream marker (we left room
// for them, no need to test)
lzvn_compressed_block_header header;
header.magic = LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC;
header.n_raw_bytes = (uint32_t)src_size;
header.n_payload_bytes = (uint32_t)sz;
memcpy(dst_buffer, &header, sizeof(header));
store4(dst_buffer + sizeof(lzvn_compressed_block_header) + sz,
LZFSE_ENDOFSTREAM_BLOCK_MAGIC);
return sz + extra_size;
}
// Try encoding with LZFSE
{
lzfse_encoder_state *state = scratch_buffer;
memset(state, 0x00, sizeof *state);
if (lzfse_encode_init(state) != LZFSE_STATUS_OK)
goto try_uncompressed;
state->dst = dst_buffer;
state->dst_begin = dst_buffer;
state->dst_end = &dst_buffer[dst_size];
state->src = src_buffer;
state->src_encode_i = 0;
if (src_size >= 0xffffffffU) {
// lzfse only uses 32 bits for offsets internally, so if the input
// buffer is really huge, we need to process it in smaller chunks.
// Note that we switch over to this path for sizes much smaller
// 2GB because it's actually faster to change algorithms well before
// it's necessary for correctness.
// The first chunk, we just process normally.
const lzfse_offset encoder_block_size = 262144;
state->src_end = encoder_block_size;
if (lzfse_encode_base(state) != LZFSE_STATUS_OK)
goto try_uncompressed;
src_size -= encoder_block_size;
while (src_size >= encoder_block_size) {
// All subsequent chunks require a translation to keep the offsets
// from getting too big. Note that we are always going from
// encoder_block_size up to 2*encoder_block_size so that the
// offsets remain positive (as opposed to resetting to zero and
// having negative offsets).
state->src_end = 2 * encoder_block_size;
if (lzfse_encode_base(state) != LZFSE_STATUS_OK)
goto try_uncompressed;
lzfse_encode_translate(state, encoder_block_size);
src_size -= encoder_block_size;
}
// Set the end for the final chunk.
state->src_end = encoder_block_size + (lzfse_offset)src_size;
}
// If the source buffer is small enough to use 32-bit offsets, we simply
// encode the whole thing in a single chunk.
else
state->src_end = (lzfse_offset)src_size;
// This is either the trailing chunk (if the source file is huge), or
// the whole source file.
if (lzfse_encode_base(state) != LZFSE_STATUS_OK)
goto try_uncompressed;
if (lzfse_encode_finish(state) != LZFSE_STATUS_OK)
goto try_uncompressed;
// No error occured, return compressed size.
return state->dst - dst_buffer;
}
try_uncompressed:
// Compression failed for some reason. If we can fit the data into the
// output buffer uncompressed, go ahead and do that instead.
if (original_size + 12 <= dst_size && original_size < INT32_MAX) {
uncompressed_block_header header = {.magic = LZFSE_UNCOMPRESSED_BLOCK_MAGIC,
.n_raw_bytes = (uint32_t)src_size};
uint8_t *dst_end = dst_buffer;
memcpy(dst_end, &header, sizeof header);
dst_end += sizeof header;
memcpy(dst_end, src_buffer, original_size);
dst_end += original_size;
store4(dst_end, LZFSE_ENDOFSTREAM_BLOCK_MAGIC);
dst_end += 4;
return dst_end - dst_buffer;
}
// Otherwise, there's nothing we can do, so return zero.
return 0;
}
size_t lzfse_encode_buffer(uint8_t *__restrict dst_buffer, size_t dst_size,
const uint8_t *__restrict src_buffer,
size_t src_size, void *__restrict scratch_buffer) {
int has_malloc = 0;
size_t ret = 0;
// Deal with the possible NULL pointer
if (scratch_buffer == NULL) {
// +1 in case scratch size could be zero
scratch_buffer = malloc(lzfse_encode_scratch_size() + 1);
has_malloc = 1;
}
if (scratch_buffer == NULL)
return 0;
ret = lzfse_encode_buffer_with_scratch(dst_buffer,
dst_size, src_buffer,
src_size, scratch_buffer);
if (has_malloc)
free(scratch_buffer);
return ret;
}
File diff suppressed because it is too large. Load diff
-218
View File
@@ -1,218 +0,0 @@
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
#ifndef LZFSE_ENCODE_TABLES_H
#define LZFSE_ENCODE_TABLES_H
#if defined(_MSC_VER) && !defined(__clang__)
# define inline __inline
#endif
static inline uint8_t l_base_from_value(int32_t value) {
static const uint8_t sym[LZFSE_ENCODE_MAX_L_VALUE + 1] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16,
16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19};
return sym[value];
}
static inline uint8_t m_base_from_value(int32_t value) {
static const uint8_t sym[LZFSE_ENCODE_MAX_M_VALUE + 1] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16,
16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19};
return sym[value];
}
static inline uint8_t d_base_from_value(int32_t value) {
static const uint8_t sym[64 * 4] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 9, 9,
9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15,
15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 19, 20, 20, 21, 21,
22, 22, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27,
27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29,
30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32,
32, 32, 32, 33, 34, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 40,
41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44,
44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 50, 51, 52, 52,
53, 53, 54, 54, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58,
59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61,
61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63,
0, 0, 0, 0};
int index = 0;
int in_range_k;
in_range_k = (value >= 0 && value < 60);
index |= (((value - 0) >> 0) + 0) & -in_range_k;
in_range_k = (value >= 60 && value < 1020);
index |= (((value - 60) >> 4) + 64) & -in_range_k;
in_range_k = (value >= 1020 && value < 16380);
index |= (((value - 1020) >> 8) + 128) & -in_range_k;
in_range_k = (value >= 16380 && value < 262140);
index |= (((value - 16380) >> 12) + 192) & -in_range_k;
return sym[index & 255];
}
#endif // LZFSE_ENCODE_TABLES_H
+112 -203
View File
@@ -1,217 +1,126 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
* Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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 "lzfse_internal.h"
// Initialize encoder table T[NSYMBOLS].
// NSTATES = sum FREQ[i] is the number of states (a power of 2)
// NSYMBOLS is the number of symbols.
// FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i]
// >= 0.
// Some symbols may have a 0 frequency. In that case, they should not be
// present in the data.
void fse_init_encoder_table(int nstates, int nsymbols,
const uint16_t *__restrict freq,
fse_encoder_entry *__restrict t) {
int offset = 0; // current offset
int n_clz = __builtin_clz(nstates);
int i;
for (i = 0; i < nsymbols; i++) {
int f = (int)freq[i];
int k;
if (f == 0)
continue; // skip this symbol, no occurrences
k = __builtin_clz(f) - n_clz; // shift needed to ensure N <= (F<<K) < 2*N
t[i].s0 = (int16_t)((f << k) - nstates);
t[i].k = (int16_t)k;
t[i].delta0 = (int16_t)(offset - f + (nstates >> k));
t[i].delta1 = (int16_t)(offset - f + (nstates >> (k - 1)));
offset += f;
}
/*
* Initialize decoder table T[NSTATES].
* NSTATES = sum FREQ[i] is the number of states (a power of 2)
* NSYMBOLS is the number of symbols.
* FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i]
* >= 0.
* Some symbols may have a 0 frequency. In that case, they should not be
* present in the data.
*/
int fse_init_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq,
int32_t *__restrict t)
{
int n_clz = __builtin_clz(nstates);
int sum_of_freq = 0;
int i, j0, j;
for (i = 0; i < nsymbols; i++) {
int f = (int)freq[i];
int k;
if (f == 0)
continue; /* skip this symbol, no occurrences */
sum_of_freq += f;
if (sum_of_freq > nstates)
return -1;
k = __builtin_clz(f) - n_clz; /* shift needed to ensure N <= (F<<K) < 2*N */
j0 = ((2 * nstates) >> k) - f;
/* Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F */
for (j = 0; j < f; j++) {
fse_decoder_entry e;
e.symbol = (uint8_t)i;
if (j < j0) {
e.k = (int8_t)k;
e.delta = (int16_t)(((f + j) << k) - nstates);
} else {
e.k = (int8_t)(k - 1);
e.delta = (int16_t)((j - j0) << (k - 1));
}
memcpy(t, &e, sizeof(e));
t++;
}
}
return 0; /* OK */
}
// Initialize decoder table T[NSTATES].
// NSTATES = sum FREQ[i] is the number of states (a power of 2)
// NSYMBOLS is the number of symbols.
// FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i]
// >= 0.
// Some symbols may have a 0 frequency. In that case, they should not be
// present in the data.
int fse_init_decoder_table(int nstates, int nsymbols,
const uint16_t *__restrict freq,
int32_t *__restrict t) {
int n_clz = __builtin_clz(nstates);
int sum_of_freq = 0;
int i, j0, j;
for (i = 0; i < nsymbols; i++) {
int f = (int)freq[i];
int k;
if (f == 0)
continue; // skip this symbol, no occurrences
/*
* Initialize value decoder table T[NSTATES].
* NSTATES = sum FREQ[i] is the number of states (a power of 2)
* NSYMBOLS is the number of symbols.
* FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i]
* >= 0.
* SYMBOL_VBITS[NSYMBOLS] and SYMBOLS_VBASE[NSYMBOLS] are the number of value
* bits to read and the base value for each symbol.
* Some symbols may have a 0 frequency. In that case, they should not be
* present in the data.
*/
void fse_init_value_decoder_table(int nstates, int nsymbols, const uint16_t *__restrict freq,
const uint8_t *__restrict symbol_vbits,
const int32_t *__restrict symbol_vbase,
struct fse_value_decoder_entry *__restrict t)
{
int n_clz = __builtin_clz(nstates);
int i;
sum_of_freq += f;
for (i = 0; i < nsymbols; i++) {
struct fse_value_decoder_entry ei = { 0 };
int f = (int)freq[i];
int k, j0, j;
if (sum_of_freq > nstates) {
return -1;
}
if (f == 0)
continue; /* skip this symbol, no occurrences */
k = __builtin_clz(f) - n_clz; // shift needed to ensure N <= (F<<K) < 2*N
j0 = ((2 * nstates) >> k) - f;
k = __builtin_clz(f) - n_clz; /* shift needed to ensure N <= (F<<K) < 2*N */
j0 = ((2 * nstates) >> k) - f;
// Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F
for (j = 0; j < f; j++) {
fse_decoder_entry e;
ei.value_bits = symbol_vbits[i];
ei.vbase = symbol_vbase[i];
e.symbol = (uint8_t)i;
if (j < j0) {
e.k = (int8_t)k;
e.delta = (int16_t)(((f + j) << k) - nstates);
} else {
e.k = (int8_t)(k - 1);
e.delta = (int16_t)((j - j0) << (k - 1));
}
/* Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F */
for (j = 0; j < f; j++) {
struct fse_value_decoder_entry e = ei;
memcpy(t, &e, sizeof(e));
t++;
}
}
if (j < j0) {
e.total_bits = (uint8_t)k + e.value_bits;
e.delta = (int16_t)(((f + j) << k) - nstates);
} else {
e.total_bits = (uint8_t)(k - 1) + e.value_bits;
e.delta = (int16_t)((j - j0) << (k - 1));
}
return 0; // OK
}
// Initialize value decoder table T[NSTATES].
// NSTATES = sum FREQ[i] is the number of states (a power of 2)
// NSYMBOLS is the number of symbols.
// FREQ[NSYMBOLS] is a normalized histogram of symbol frequencies, with FREQ[i]
// >= 0.
// SYMBOL_VBITS[NSYMBOLS] and SYMBOLS_VBASE[NSYMBOLS] are the number of value
// bits to read and the base value for each symbol.
// Some symbols may have a 0 frequency. In that case, they should not be
// present in the data.
void fse_init_value_decoder_table(int nstates, int nsymbols,
const uint16_t *__restrict freq,
const uint8_t *__restrict symbol_vbits,
const int32_t *__restrict symbol_vbase,
fse_value_decoder_entry *__restrict t) {
int n_clz = __builtin_clz(nstates);
int i;
for (i = 0; i < nsymbols; i++) {
fse_value_decoder_entry ei = {0};
int f = (int)freq[i];
int k, j0, j;
if (f == 0)
continue; // skip this symbol, no occurrences
k = __builtin_clz(f) - n_clz; // shift needed to ensure N <= (F<<K) < 2*N
j0 = ((2 * nstates) >> k) - f;
ei.value_bits = symbol_vbits[i];
ei.vbase = symbol_vbase[i];
// Initialize all states S reached by this symbol: OFFSET <= S < OFFSET + F
for (j = 0; j < f; j++) {
fse_value_decoder_entry e = ei;
if (j < j0) {
e.total_bits = (uint8_t)k + e.value_bits;
e.delta = (int16_t)(((f + j) << k) - nstates);
} else {
e.total_bits = (uint8_t)(k - 1) + e.value_bits;
e.delta = (int16_t)((j - j0) << (k - 1));
}
memcpy(t, &e, 8);
t++;
}
}
}
// Remove states from symbols until the correct number of states is used.
static void fse_adjust_freqs(uint16_t *freq, int overrun, int nsymbols) {
int shift;
for (shift = 3; overrun != 0; shift--) {
int sym;
for (sym = 0; sym < nsymbols; sym++) {
if (freq[sym] > 1) {
int n = (freq[sym] - 1) >> shift;
if (n > overrun)
n = overrun;
freq[sym] -= n;
overrun -= n;
if (overrun == 0)
break;
}
}
}
}
// Normalize a table T[NSYMBOLS] of occurrences to FREQ[NSYMBOLS].
void fse_normalize_freq(int nstates, int nsymbols, const uint32_t *__restrict t,
uint16_t *__restrict freq) {
uint32_t s_count = 0;
int remaining = nstates; // must be signed; this may become < 0
int max_freq = 0;
int max_freq_sym = 0;
int shift = __builtin_clz(nstates) - 1;
uint32_t highprec_step;
int i;
// Compute the total number of symbol occurrences
for (i = 0; i < nsymbols; i++)
s_count += t[i];
if (s_count == 0)
highprec_step = 0; // no symbols used
else
highprec_step = ((uint32_t)1 << 31) / s_count;
for (i = 0; i < nsymbols; i++) {
// Rescale the occurrence count to get the normalized frequency.
// Round up if the fractional part is >= 0.5; otherwise round down.
// For efficiency, we do this calculation using integer arithmetic.
int f = (((t[i] * highprec_step) >> shift) + 1) >> 1;
// If a symbol was used, it must be given a nonzero normalized frequency.
if (f == 0 && t[i] != 0)
f = 1;
freq[i] = f;
remaining -= f;
// Remember the maximum frequency and which symbol had it.
if (f > max_freq) {
max_freq = f;
max_freq_sym = i;
}
}
// If there remain states to be assigned, then just assign them to the most
// frequent symbol. Alternatively, if we assigned more states than were
// actually available, then either remove states from the most frequent symbol
// (for minor overruns) or use the slower adjustment algorithm (for major
// overruns).
if (-remaining < (max_freq >> 2)) {
freq[max_freq_sym] += remaining;
} else {
fse_adjust_freqs(freq, -remaining, nsymbols);
}
memcpy(t, &e, 8);
t++;
}
}
}
+344 -377
View File
File diff suppressed because it is too large. Load diff
+339 -469
View File
File diff suppressed because it is too large. Load diff
-336
View File
@@ -1,336 +0,0 @@
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
// LZFSE command line tool
#if !defined(_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)
# undef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 200112L
#endif
#if defined(_MSC_VER)
# if !defined(_CRT_NONSTDC_NO_DEPRECATE)
# define _CRT_NONSTDC_NO_DEPRECATE
# endif
# if !defined(_CRT_SECURE_NO_WARNINGS)
# define _CRT_SECURE_NO_WARNINGS
# endif
# if !defined(__clang__)
# define inline __inline
# endif
#endif
#include "lzfse.h"
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#if defined(_MSC_VER)
# include <io.h>
# include <windows.h>
#else
# include <sys/time.h>
# include <unistd.h>
#endif
// Same as realloc(x,s), except x is freed when realloc fails
static inline void *lzfse_reallocf(void *x, size_t s) {
void *y = realloc(x, s);
if (y == 0) {
free(x);
return 0;
}
return y;
}
static double get_time() {
#if defined(_MSC_VER)
LARGE_INTEGER count, freq;
if (QueryPerformanceFrequency(&freq) && QueryPerformanceCounter(&count)) {
return (double)count.QuadPart / (double)freq.QuadPart;
}
return 1.0e-3 * (double)GetTickCount();
#else
struct timeval tv;
if (gettimeofday(&tv, 0) != 0) {
perror("gettimeofday");
exit(1);
}
return (double)tv.tv_sec + 1.0e-6 * (double)tv.tv_usec;
#endif
}
//--------------------
enum { LZFSE_ENCODE = 0, LZFSE_DECODE };
void usage(int argc, char **argv) {
fprintf(
stderr,
"Usage: %s -encode|-decode [-i input_file] [-o output_file] [-h] [-v]\n",
argv[0]);
}
#define USAGE(argc, argv) \
do { \
usage(argc, argv); \
exit(0); \
} while (0)
#define USAGE_MSG(argc, argv, ...) \
do { \
usage(argc, argv); \
fprintf(stderr, __VA_ARGS__); \
exit(1); \
} while (0)
int main(int argc, char **argv) {
const char *in_file = 0; // stdin
const char *out_file = 0; // stdout
int op = -1; // invalid op
int verbosity = 0; // quiet
// Parse options
for (int i = 1; i < argc;) {
// no args
const char *a = argv[i++];
if (strcmp(a, "-h") == 0)
USAGE(argc, argv);
if (strcmp(a, "-v") == 0) {
verbosity++;
continue;
}
if (strcmp(a, "-encode") == 0) {
op = LZFSE_ENCODE;
continue;
}
if (strcmp(a, "-decode") == 0) {
op = LZFSE_DECODE;
continue;
}
// one arg
const char **arg_var = 0;
if (strcmp(a, "-i") == 0 && in_file == 0)
arg_var = &in_file;
else if (strcmp(a, "-o") == 0 && out_file == 0)
arg_var = &out_file;
if (arg_var != 0) {
// Flag is recognized. Check if there is an argument.
if (i == argc)
USAGE_MSG(argc, argv, "Error: Missing arg after %s\n", a);
*arg_var = argv[i++];
continue;
}
USAGE_MSG(argc, argv, "Error: invalid flag %s\n", a);
}
if (op < 0)
USAGE_MSG(argc, argv, "Error: -encode|-decode required\n");
// Info
if (verbosity > 0) {
if (op == LZFSE_ENCODE)
fprintf(stderr, "LZFSE encode\n");
if (op == LZFSE_DECODE)
fprintf(stderr, "LZFSE decode\n");
fprintf(stderr, "Input: %s\n", in_file ? in_file : "stdin");
fprintf(stderr, "Output: %s\n", out_file ? out_file : "stdout");
}
// Load input
size_t in_allocated = 0; // allocated in IN
size_t in_size = 0; // used in IN
uint8_t *in = 0; // input buffer
int in_fd = -1; // input file desc
if (in_file != 0) {
// If we have a file name, open it, and allocate the exact input size
struct stat st;
#if defined(_WIN32)
in_fd = open(in_file, O_RDONLY | O_BINARY);
#else
in_fd = open(in_file, O_RDONLY);
#endif
if (in_fd < 0) {
perror(in_file);
exit(1);
}
if (fstat(in_fd, &st) != 0) {
perror(in_file);
exit(1);
}
if (st.st_size > SIZE_MAX) {
fprintf(stderr, "File is too large\n");
exit(1);
}
in_allocated = (size_t)st.st_size;
} else {
// Otherwise, read from stdin, and allocate to 1 MB, grow as needed
in_allocated = 1 << 20;
in_fd = 0;
#if defined(_WIN32)
if (setmode(in_fd, O_BINARY) == -1) {
perror("setmode");
exit(1);
}
#endif
}
in = (uint8_t *)malloc(in_allocated);
if (in == 0) {
perror("malloc");
exit(1);
}
while (1) {
// re-alloc if needed
if (in_size == in_allocated) {
if (in_allocated < (100 << 20))
in_allocated <<= 1; // double it
else
in_allocated += (100 << 20); // or add 100 MB if already large
in = lzfse_reallocf(in, in_allocated);
if (in == 0) {
perror("malloc");
exit(1);
}
}
ptrdiff_t r = read(in_fd, in + in_size, in_allocated - in_size);
if (r < 0) {
perror("read");
exit(1);
}
if (r == 0)
break; // end of file
in_size += (size_t)r;
}
if (in_file != 0) {
close(in_fd);
in_fd = -1;
}
// Size info
if (verbosity > 0) {
fprintf(stderr, "Input size: %zu B\n", in_size);
}
// Encode/decode
// Compute size for result buffer; we assume here that encode shrinks size,
// and that decode grows by no more than 4x. These are reasonable common-
// case guidelines, but are not formally guaranteed to be satisfied.
size_t out_allocated = (op == LZFSE_ENCODE) ? in_size : (4 * in_size);
size_t out_size = 0;
size_t aux_allocated = (op == LZFSE_ENCODE) ? lzfse_encode_scratch_size()
: lzfse_decode_scratch_size();
void *aux = aux_allocated ? malloc(aux_allocated) : 0;
if (aux_allocated != 0 && aux == 0) {
perror("malloc");
exit(1);
}
uint8_t *out = (uint8_t *)malloc(out_allocated);
if (out == 0) {
perror("malloc");
exit(1);
}
double c0 = get_time();
while (1) {
if (op == LZFSE_ENCODE)
out_size = lzfse_encode_buffer(out, out_allocated, in, in_size, aux);
else
out_size = lzfse_decode_buffer(out, out_allocated, in, in_size, aux);
// If output buffer was too small, grow and retry.
if (out_size == 0 || (op == LZFSE_DECODE && out_size == out_allocated)) {
if (verbosity > 0)
fprintf(stderr, "Output buffer was too small, increasing size...\n");
out_allocated <<= 1;
out = (uint8_t *)lzfse_reallocf(out, out_allocated);
if (out == 0) {
perror("malloc");
exit(1);
}
continue;
}
break;
}
double c1 = get_time();
if (verbosity > 0) {
fprintf(stderr, "Output size: %zu B\n", out_size);
size_t raw_size = (op == LZFSE_ENCODE) ? in_size : out_size;
size_t compressed_size = (op == LZFSE_ENCODE) ? out_size : in_size;
fprintf(stderr, "Compression ratio: %.3f\n",
(double)raw_size / (double)compressed_size);
double ns_per_byte = 1.0e9 * (c1 - c0) / (double)raw_size;
double mb_per_s = (double)raw_size / 1024.0 / 1024.0 / (c1 - c0);
fprintf(stderr, "Speed: %.2f ns/B, %.2f MB/s\n",ns_per_byte,mb_per_s);
}
// Write output
int out_fd = -1;
if (out_file) {
#if defined(_WIN32)
out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
S_IWRITE);
#else
out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
#endif
if (out_fd < 0) {
perror(out_file);
exit(1);
}
} else {
out_fd = 1; // stdout
#if defined(_WIN32)
if (setmode(out_fd, O_BINARY) == -1) {
perror("setmode");
exit(1);
}
#endif
}
for (size_t out_pos = 0; out_pos < out_size;) {
ptrdiff_t w = write(out_fd, out + out_pos, out_size - out_pos);
if (w < 0) {
perror("write");
exit(1);
}
if (w == 0) {
fprintf(stderr, "Failed to write to output file\n");
exit(1);
}
out_pos += (size_t)w;
}
if (out_file != 0) {
close(out_fd);
out_fd = -1;
}
free(in);
free(out);
free(aux);
return 0; // OK
}
-60
View File
@@ -1,60 +0,0 @@
/*
Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
#ifndef LZFSE_TUNABLES_H
#define LZFSE_TUNABLES_H
// Parameters controlling details of the LZ-style match search. These values
// may be modified to fine tune compression ratio vs. encoding speed, while
// keeping the compressed format compatible with LZFSE. Note that
// modifying them will also change the amount of work space required by
// the encoder. The values here are those used in the compression library
// on iOS and OS X.
// Number of bits for hash function to produce. Should be in the range
// [10, 16]. Larger values reduce the number of false-positive found during
// the match search, and expand the history table, which may allow additional
// matches to be found, generally improving the achieved compression ratio.
// Larger values also increase the workspace size, and make it less likely
// that the history table will be present in cache, which reduces performance.
#define LZFSE_ENCODE_HASH_BITS 14
// Number of positions to store for each line in the history table. May
// be either 4 or 8. Using 8 doubles the size of the history table, which
// increases the chance of finding matches (thus improving compression ratio),
// but also increases the workspace size.
#define LZFSE_ENCODE_HASH_WIDTH 4
// Match length in bytes to cause immediate emission. Generally speaking,
// LZFSE maintains multiple candidate matches and waits to decide which match
// to emit until more information is available. When a match exceeds this
// threshold, it is emitted immediately. Thus, smaller values may give
// somewhat better performance, and larger values may give somewhat better
// compression ratios.
#define LZFSE_ENCODE_GOOD_MATCH 40
// When the source buffer is very small, LZFSE doesn't compress as well as
// some simpler algorithms. To maintain reasonable compression for these
// cases, we transition to use LZVN instead if the size of the source buffer
// is below this threshold.
#define LZFSE_ENCODE_LZVN_THRESHOLD 4096
#endif // LZFSE_TUNABLES_H
+442 -676
View File
File diff suppressed because it is too large. Load diff
+51 -46
View File
@@ -1,27 +1,30 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
Copyright (c) 2015-2016, Apple Inc. All rights reserved.
* Copyright (c) 2015-2016, Apple Inc. 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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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.
*/
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 copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.
*/
// LZVN low-level decoder (v2)
// Functions in the low-level API should switch to these at some point.
// Apr 2014
/*
* LZVN low-level decoder (v2)
* Functions in the low-level API should switch to these at some point.
* Apr 2014
*/
#ifndef LZVN_DECODE_BASE_H
#define LZVN_DECODE_BASE_H
@@ -30,39 +33,41 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
/*! @abstract Base decoder state. */
typedef struct {
/* Decoder I/O */
// Decoder I/O
/* Next byte to read in source buffer */
const unsigned char *src;
/* Next byte after source buffer */
const unsigned char *src_end;
// Next byte to read in source buffer
const unsigned char *src;
// Next byte after source buffer
const unsigned char *src_end;
/* Next byte to write in destination buffer (by decoder) */
unsigned char *dst;
/* Valid range for destination buffer is [dst_begin, dst_end - 1] */
unsigned char *dst_begin;
unsigned char *dst_end;
/* Next byte to read in destination buffer (modified by caller) */
unsigned char *dst_current;
// Next byte to write in destination buffer (by decoder)
unsigned char *dst;
// Valid range for destination buffer is [dst_begin, dst_end - 1]
unsigned char *dst_begin;
unsigned char *dst_end;
// Next byte to read in destination buffer (modified by caller)
unsigned char *dst_current;
/* Decoder state */
// Decoder state
/*
* Partially expanded match, or 0,0,0.
* In that case, src points to the next literal to copy, or the next
* op-code if L==0.
*/
size_t L, M, D;
// Partially expanded match, or 0,0,0.
// In that case, src points to the next literal to copy, or the next op-code
// if L==0.
size_t L, M, D;
/* Distance for last emitted match, or 0 */
lzvn_offset d_prev;
// Distance for last emitted match, or 0
lzvn_offset d_prev;
// Did we decode end-of-stream?
int end_of_stream;
/* Did we decode end-of-stream? */
int end_of_stream;
} lzvn_decoder_state;
/*! @abstract Decode source to destination.
* Updates \p state (src,dst,d_prev). */
* Updates \p state (src,dst,d_prev).
*/
void lzvn_decode(lzvn_decoder_state *state);
#endif // LZVN_DECODE_BASE_H
#endif /* LZVN_DECODE_BASE_H */
File diff suppressed because it is too large. Load diff
Loaded 20 of 24 files, more files were not shown because too many files have changed in this diff. Show more