mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Merge remote-tracking branch 'offical/master'
# Conflicts: # core/os/os_darwin.odin # core/os/os_freebsd.odin # core/os/os_js.odin # core/os/os_linux.odin # core/os/os_openbsd.odin # core/os/os_windows.odin
This commit is contained in:
BIN
Binary file not shown.
Vendored
+542
@@ -0,0 +1,542 @@
|
||||
package vendor_compress_lz4
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
@(extra_linker_flags="/NODEFAULTLIB:libcmt")
|
||||
foreign import lib "lib/liblz4_static.lib"
|
||||
}
|
||||
|
||||
import "core:c"
|
||||
|
||||
VERSION_MAJOR :: 1 /* for breaking interface changes */
|
||||
VERSION_MINOR :: 10 /* for new (non-breaking) interface capabilities */
|
||||
VERSION_RELEASE :: 0 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
VERSION_NUMBER :: VERSION_MAJOR *100*100 + VERSION_MINOR *100 + VERSION_RELEASE
|
||||
|
||||
MEMORY_USAGE_MIN :: 10
|
||||
MEMORY_USAGE_DEFAULT :: 14
|
||||
MEMORY_USAGE_MAX :: 20
|
||||
|
||||
MEMORY_USAGE :: MEMORY_USAGE_DEFAULT
|
||||
|
||||
MAX_INPUT_SIZE :: 0x7E000000 /* 2_113_929_216 bytes */
|
||||
|
||||
|
||||
COMPRESSBOUND :: #force_inline proc "c" (isize: c.int) -> c.int {
|
||||
return u32(isize) > MAX_INPUT_SIZE ? 0 : isize + (isize/255) + 16
|
||||
}
|
||||
|
||||
|
||||
DECODER_RING_BUFFER_SIZE :: #force_inline proc "c" (maxBlockSize: c.int) -> c.int {
|
||||
return 65536 + 14 + maxBlockSize /* for static allocation; maxBlockSize presumed valid */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="LZ4_")
|
||||
foreign lib {
|
||||
versionNumber :: proc() -> c.int --- /**< library version number; useful to check dll version; requires v1.3.0+ */
|
||||
versionString :: proc() -> cstring --- /**< library version string; useful to check dll version; requires v1.7.5+ */
|
||||
|
||||
/*! LZ4_compress_default() :
|
||||
* Compresses 'srcSize' bytes from buffer 'src'
|
||||
* into already allocated 'dst' buffer of size 'dstCapacity'.
|
||||
* Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
|
||||
* It also runs faster, so it's a recommended setting.
|
||||
* If the function cannot compress 'src' into a more limited 'dst' budget,
|
||||
* compression stops *immediately*, and the function result is zero.
|
||||
* In which case, 'dst' content is undefined (invalid).
|
||||
* srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
|
||||
* dstCapacity : size of buffer 'dst' (which must be already allocated)
|
||||
* @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
|
||||
* or 0 if compression fails
|
||||
* Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
|
||||
*/
|
||||
compress_default :: proc(src, dst: [^]byte, srcSize, dstCapacity: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_decompress_safe() :
|
||||
* @compressedSize : is the exact complete size of the compressed block.
|
||||
* @dstCapacity : is the size of destination buffer (which must be already allocated),
|
||||
* presumed an upper bound of decompressed size.
|
||||
* @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
* Note 1 : This function is protected against malicious data packets :
|
||||
* it will never writes outside 'dst' buffer, nor read outside 'source' buffer,
|
||||
* even if the compressed block is maliciously modified to order the decoder to do these actions.
|
||||
* In such case, the decoder stops immediately, and considers the compressed block malformed.
|
||||
* Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them.
|
||||
* The implementation is free to send / store / derive this information in whichever way is most beneficial.
|
||||
* If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead.
|
||||
*/
|
||||
decompress_safe :: proc(src, dst: [^]byte, compressedSize, dstCapacity: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is incorrect (too large or negative)
|
||||
*/
|
||||
compressBound :: proc(inputSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c).
|
||||
Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c).
|
||||
*/
|
||||
compress_fast :: proc(src, dst: [^]byte, srcSize, dstCapacity: c.int, acceleration: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_compress_fast_extState() :
|
||||
* Same as LZ4_compress_fast(), using an externally allocated memory space for its state.
|
||||
* Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
* and allocate it on 8-bytes boundaries (using `malloc()` typically).
|
||||
* Then, provide this buffer as `void* state` to compression function.
|
||||
*/
|
||||
sizeofState :: proc() -> c.int ---
|
||||
compress_fast_extState :: proc (state: rawptr, src, dst: [^]byte, srcSize, dstCapacity: c.int, acceleration: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_compress_destSize() :
|
||||
* Reverse the logic : compresses as much data as possible from 'src' buffer
|
||||
* into already allocated buffer 'dst', of size >= 'dstCapacity'.
|
||||
* This function either compresses the entire 'src' content into 'dst' if it's large enough,
|
||||
* or fill 'dst' buffer completely with as much data as possible from 'src'.
|
||||
* note: acceleration parameter is fixed to "default".
|
||||
*
|
||||
* *srcSizePtr : in+out parameter. Initially contains size of input.
|
||||
* Will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
|
||||
* New value is necessarily <= input value.
|
||||
* @return : Nb bytes written into 'dst' (necessarily <= dstCapacity)
|
||||
* or 0 if compression fails.
|
||||
*
|
||||
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+):
|
||||
* the produced compressed content could, in specific circumstances,
|
||||
* require to be decompressed into a destination buffer larger
|
||||
* by at least 1 byte than the content to decompress.
|
||||
* If an application uses `LZ4_compress_destSize()`,
|
||||
* it's highly recommended to update liblz4 to v1.9.2 or better.
|
||||
* If this can't be done or ensured,
|
||||
* the receiving decompression function should provide
|
||||
* a dstCapacity which is > decompressedSize, by at least 1 byte.
|
||||
* See https://github.com/lz4/lz4/issues/859 for details
|
||||
*/
|
||||
compress_destSize :: proc(src, dst: [^]byte, srcSizePtr: ^c.int, targetDstSize: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_decompress_safe_partial() :
|
||||
* Decompress an LZ4 compressed block, of size 'srcSize' at position 'src',
|
||||
* into destination buffer 'dst' of size 'dstCapacity'.
|
||||
* Up to 'targetOutputSize' bytes will be decoded.
|
||||
* The function stops decoding on reaching this objective.
|
||||
* This can be useful to boost performance
|
||||
* whenever only the beginning of a block is required.
|
||||
*
|
||||
* @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize)
|
||||
* If source stream is detected malformed, function returns a negative result.
|
||||
*
|
||||
* Note 1 : @return can be < targetOutputSize, if compressed block contains less data.
|
||||
*
|
||||
* Note 2 : targetOutputSize must be <= dstCapacity
|
||||
*
|
||||
* Note 3 : this function effectively stops decoding on reaching targetOutputSize,
|
||||
* so dstCapacity is kind of redundant.
|
||||
* This is because in older versions of this function,
|
||||
* decoding operation would still write complete sequences.
|
||||
* Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize,
|
||||
* it could write more bytes, though only up to dstCapacity.
|
||||
* Some "margin" used to be required for this operation to work properly.
|
||||
* Thankfully, this is no longer necessary.
|
||||
* The function nonetheless keeps the same signature, in an effort to preserve API compatibility.
|
||||
*
|
||||
* Note 4 : If srcSize is the exact size of the block,
|
||||
* then targetOutputSize can be any value,
|
||||
* including larger than the block's decompressed size.
|
||||
* The function will, at most, generate block's decompressed size.
|
||||
*
|
||||
* Note 5 : If srcSize is _larger_ than block's compressed size,
|
||||
* then targetOutputSize **MUST** be <= block's decompressed size.
|
||||
* Otherwise, *silent corruption will occur*.
|
||||
*/
|
||||
decompress_safe_partial :: proc (src, dst: [^]byte, srcSize, targetOutputSize, dstCapacity: c.int) -> c.int ---
|
||||
|
||||
|
||||
createStream :: proc() -> ^stream_t ---
|
||||
freeStream :: proc(streamPtr: ^stream_t) -> c.int ---
|
||||
|
||||
/*! LZ4_resetStream_fast() : v1.9.0+
|
||||
* Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
|
||||
* (e.g., LZ4_compress_fast_continue()).
|
||||
*
|
||||
* An LZ4_stream_t must be initialized once before usage.
|
||||
* This is automatically done when created by LZ4_createStream().
|
||||
* However, should the LZ4_stream_t be simply declared on stack (for example),
|
||||
* it's necessary to initialize it first, using LZ4_initStream().
|
||||
*
|
||||
* After init, start any new stream with LZ4_resetStream_fast().
|
||||
* A same LZ4_stream_t can be re-used multiple times consecutively
|
||||
* and compress multiple streams,
|
||||
* provided that it starts each new stream with LZ4_resetStream_fast().
|
||||
*
|
||||
* LZ4_resetStream_fast() is much faster than LZ4_initStream(),
|
||||
* but is not compatible with memory regions containing garbage data.
|
||||
*
|
||||
* Note: it's only useful to call LZ4_resetStream_fast()
|
||||
* in the context of streaming compression.
|
||||
* The *extState* functions perform their own resets.
|
||||
* Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive.
|
||||
*/
|
||||
resetStream_fast :: proc(streamPtr: ^stream_t) ---
|
||||
|
||||
|
||||
/*! LZ4_loadDict() :
|
||||
* Use this function to reference a static dictionary into LZ4_stream_t.
|
||||
* The dictionary must remain available during compression.
|
||||
* LZ4_loadDict() triggers a reset, so any previous data will be forgotten.
|
||||
* The same dictionary will have to be loaded on decompression side for successful decoding.
|
||||
* Dictionary are useful for better compression of small data (KB range).
|
||||
* While LZ4 itself accepts any input as dictionary, dictionary efficiency is also a topic.
|
||||
* When in doubt, employ the Zstandard's Dictionary Builder.
|
||||
* Loading a size of 0 is allowed, and is the same as reset.
|
||||
* @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded)
|
||||
*/
|
||||
loadDict :: proc(streamPtr: ^stream_t, dictionary: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_loadDictSlow() : v1.10.0+
|
||||
* Same as LZ4_loadDict(),
|
||||
* but uses a bit more cpu to reference the dictionary content more thoroughly.
|
||||
* This is expected to slightly improve compression ratio.
|
||||
* The extra-cpu cost is likely worth it if the dictionary is re-used across multiple sessions.
|
||||
* @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded)
|
||||
*/
|
||||
loadDictSlow :: proc(streamPtr: ^stream_t, dictionary: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_attach_dictionary() : stable since v1.10.0
|
||||
*
|
||||
* This allows efficient re-use of a static dictionary multiple times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
|
||||
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references @dictionaryStream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of @dictionaryStream.
|
||||
* Currently, only states which have been prepared by LZ4_loadDict() or
|
||||
* LZ4_loadDictSlow() should be expected to work.
|
||||
*
|
||||
* Alternatively, the provided @dictionaryStream may be NULL,
|
||||
* in which case any existing dictionary stream is unset.
|
||||
*
|
||||
* If a dictionary is provided, it replaces any pre-existing stream history.
|
||||
* The dictionary contents are the only history that can be referenced and
|
||||
* logically immediately precede the data compressed in the first subsequent
|
||||
* compression call.
|
||||
*
|
||||
* The dictionary will only remain attached to the working stream through the
|
||||
* first compression call, at the end of which it is cleared.
|
||||
* @dictionaryStream stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the completion of the compression session.
|
||||
*
|
||||
* Note: there is no equivalent LZ4_attach_*() method on the decompression side
|
||||
* because there is no initialization cost, hence no need to share the cost across multiple sessions.
|
||||
* To decompress LZ4 blocks using dictionary, attached or not,
|
||||
* just employ the regular LZ4_setStreamDecode() for streaming,
|
||||
* or the stateless LZ4_decompress_safe_usingDict() for one-shot decompression.
|
||||
*/
|
||||
attach_dictionary :: proc(workingStream, dictionaryStream: ^stream_t) ---
|
||||
|
||||
/*! LZ4_compress_fast_continue() :
|
||||
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
*
|
||||
* @return : size of compressed block
|
||||
* or 0 if there is an error (typically, cannot fit into 'dst').
|
||||
*
|
||||
* Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block.
|
||||
* Each block has precise boundaries.
|
||||
* Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata.
|
||||
* It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together.
|
||||
*
|
||||
* Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory !
|
||||
*
|
||||
* Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB.
|
||||
* Make sure that buffers are separated, by at least one byte.
|
||||
* This construction ensures that each block only depends on previous block.
|
||||
*
|
||||
* Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
|
||||
*
|
||||
* Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed.
|
||||
*/
|
||||
compress_fast_continue :: proc(streamPtr: ^stream_t, src, dst: [^]byte, srcSize, dstCapacity: c.int, acceleration: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_saveDict() :
|
||||
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
|
||||
* save it into a safer place (char* safeBuffer).
|
||||
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
|
||||
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
|
||||
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
|
||||
*/
|
||||
saveDict :: proc(streamPtr: ^stream_t, safeBuffer: [^]byte, maxDictSize: c.int) -> c.int ---
|
||||
|
||||
|
||||
createStreamDecode :: proc() -> ^streamDecode_t ---
|
||||
freeStreamDecode :: proc(LZ4_stream: ^streamDecode_t) -> c.int ---
|
||||
|
||||
/*! LZ4_setStreamDecode() :
|
||||
* An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
|
||||
* Use this function to start decompression of a new stream of blocks.
|
||||
* A dictionary can optionally be set. Use NULL or size 0 for a reset order.
|
||||
* Dictionary is presumed stable : it must remain accessible and unmodified during next decompression.
|
||||
* @return : 1 if OK, 0 if error
|
||||
*/
|
||||
setStreamDecode :: proc(LZ4_streamDecode: ^streamDecode_t, dictionary: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_decoderRingBufferSize() : v1.8.2+
|
||||
* Note : in a ring buffer scenario (optional),
|
||||
* blocks are presumed decompressed next to each other
|
||||
* up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize),
|
||||
* at which stage it resumes from beginning of ring buffer.
|
||||
* When setting such a ring buffer for streaming decompression,
|
||||
* provides the minimum size of this ring buffer
|
||||
* to be compatible with any source respecting maxBlockSize condition.
|
||||
* @return : minimum ring buffer size,
|
||||
* or 0 if there is an error (invalid maxBlockSize).
|
||||
*/
|
||||
decoderRingBufferSize :: proc(maxBlockSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_decompress_safe_continue() :
|
||||
* This decoding function allows decompression of consecutive blocks in "streaming" mode.
|
||||
* The difference with the usual independent blocks is that
|
||||
* new blocks are allowed to find references into former blocks.
|
||||
* A block is an unsplittable entity, and must be presented entirely to the decompression function.
|
||||
* LZ4_decompress_safe_continue() only accepts one block at a time.
|
||||
* It's modeled after `LZ4_decompress_safe()` and behaves similarly.
|
||||
*
|
||||
* @LZ4_streamDecode : decompression state, tracking the position in memory of past data
|
||||
* @compressedSize : exact complete size of one compressed block.
|
||||
* @dstCapacity : size of destination buffer (which must be already allocated),
|
||||
* must be an upper bound of decompressed size.
|
||||
* @return : number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
*
|
||||
* The last 64KB of previously decoded data *must* remain available and unmodified
|
||||
* at the memory position where they were previously decoded.
|
||||
* If less than 64KB of data has been decoded, all the data must be present.
|
||||
*
|
||||
* Special : if decompression side sets a ring buffer, it must respect one of the following conditions :
|
||||
* - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize).
|
||||
* maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized.
|
||||
* Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize.
|
||||
* - Synchronized mode :
|
||||
* Decompression buffer size is _exactly_ the same as compression buffer size,
|
||||
* and follows exactly same update rule (block boundaries at same positions),
|
||||
* and decoding function is provided with exact decompressed size of each block (exception for last block of the stream),
|
||||
* _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
* - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
*
|
||||
* Whenever these conditions are not possible,
|
||||
* save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
|
||||
* then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
|
||||
*/
|
||||
decompress_safe_continue :: proc(LZ4_streamDecode: ^streamDecode_t, src, dst: [^]byte, srcSize, dstCapacity: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_decompress_safe_usingDict() :
|
||||
* Works the same as
|
||||
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_safe_continue()
|
||||
* However, it's stateless: it doesn't need any LZ4_streamDecode_t state.
|
||||
* Dictionary is presumed stable : it must remain accessible and unmodified during decompression.
|
||||
* Performance tip : Decompression speed can be substantially increased
|
||||
* when dst == dictStart + dictSize.
|
||||
*/
|
||||
decompress_safe_usingDict :: proc(src, dst: [^]byte, srcSize, dstCapacity: c.int, dictStart: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_decompress_safe_partial_usingDict() :
|
||||
* Behaves the same as LZ4_decompress_safe_partial()
|
||||
* with the added ability to specify a memory segment for past data.
|
||||
* Performance tip : Decompression speed can be substantially increased
|
||||
* when dst == dictStart + dictSize.
|
||||
*/
|
||||
decompress_safe_partial_usingDict :: proc(src, dst: [^]byte, compressedSize, targetOutputSize, maxOutputSize: c.int, dictStart: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
}
|
||||
|
||||
|
||||
STREAM_MINSIZE :: (1 << MEMORY_USAGE) + 32 /* static size, for inter-version compatibility */
|
||||
|
||||
stream_t :: struct #raw_union {
|
||||
minStateSize: [STREAM_MINSIZE]byte,
|
||||
internal_donotuse: stream_t_internal,
|
||||
}
|
||||
|
||||
|
||||
HASHLOG :: MEMORY_USAGE-2
|
||||
HASHTABLESIZE :: 1 << MEMORY_USAGE
|
||||
HASH_SIZE_U32 :: 1 << HASHLOG /* required as macro for static allocation */
|
||||
|
||||
stream_t_internal :: struct {
|
||||
hashTable: [HASH_SIZE_U32]u32,
|
||||
dictionary: [^]byte,
|
||||
dictCtx: ^stream_t_internal,
|
||||
currentOffset: u32,
|
||||
tableType: u32,
|
||||
dictSize: u32,
|
||||
/* Implicit padding to ensure structure is aligned */
|
||||
}
|
||||
|
||||
|
||||
STREAMDECODE_MINSIZE :: 32
|
||||
streamDecode_t :: struct #raw_union {
|
||||
minStateSize: [STREAMDECODE_MINSIZE]byte,
|
||||
internal_donotuse: streamDecode_t_internal,
|
||||
}
|
||||
|
||||
streamDecode_t_internal :: struct {
|
||||
externalDict: [^]byte,
|
||||
prefixEnd: [^]byte,
|
||||
extDictSize: c.size_t,
|
||||
prefixSize: c.size_t,
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////
|
||||
// lz4hc
|
||||
|
||||
CLEVEL_MIN :: 2
|
||||
CLEVEL_DEFAULT :: 9
|
||||
CLEVEL_OPT_MIN :: 10
|
||||
CLEVEL_MAX :: 12
|
||||
|
||||
|
||||
@(default_calling_convention="c", link_prefix="LZ4_")
|
||||
foreign lib {
|
||||
/*! LZ4_compress_HC() :
|
||||
* Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
|
||||
* `dst` must be already allocated.
|
||||
* Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
|
||||
* Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
|
||||
* `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
|
||||
* Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
|
||||
* @return : the number of bytes written into 'dst'
|
||||
* or 0 if compression fails.
|
||||
*/
|
||||
compress_HC :: proc(src, dst: [^]byte, srcSize, dstCapacity, compressionLevel: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_compress_HC_extStateHC() :
|
||||
* Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
|
||||
* `state` size is provided by LZ4_sizeofStateHC().
|
||||
* Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
|
||||
*/
|
||||
sizeofStateHC :: proc() -> c.int ---
|
||||
compress_HC_extStateHC :: proc(stateHC: rawptr, src, dst: [^]byte, srcSize, maxDstSize: c.int, compressionLevel: c.int) -> c.int ---
|
||||
|
||||
|
||||
/*! LZ4_compress_HC_destSize() : v1.9.0+
|
||||
* Will compress as much data as possible from `src`
|
||||
* to fit into `targetDstSize` budget.
|
||||
* Result is provided in 2 parts :
|
||||
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||
* or 0 if compression fails.
|
||||
* `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
|
||||
*/
|
||||
compress_HC_destSize :: proc(stateHC: rawptr, src, dst: [^]byte, srcSizePtr: ^c.int, targetDstSize: c.int, compressionLevel: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
|
||||
* These functions create and release memory for LZ4 HC streaming state.
|
||||
* Newly created states are automatically initialized.
|
||||
* A same state can be used multiple times consecutively,
|
||||
* starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
|
||||
*/
|
||||
createStreamHC :: proc() -> ^streamHC_t ---
|
||||
freeStreamHC :: proc(streamHCPtr: ^streamHC_t) -> c.int ---
|
||||
|
||||
resetStreamHC_fast :: proc(streamHCPtr: ^streamHC_t, compressionLevel: c.int) --- /* v1.9.0+ */
|
||||
loadDictHC :: proc(streamHCPtr: ^streamHC_t, dictionary: [^]byte, dictSize: c.int) -> c.int ---
|
||||
|
||||
compress_HC_continue :: proc(streamHCPtr: ^streamHC_t, src, dst: [^]byte, srcSize, maxDstSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
|
||||
* Similar to LZ4_compress_HC_continue(),
|
||||
* but will read as much data as possible from `src`
|
||||
* to fit into `targetDstSize` budget.
|
||||
* Result is provided into 2 parts :
|
||||
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||
* or 0 if compression fails.
|
||||
* `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
|
||||
* Note that this function may not consume the entire input.
|
||||
*/
|
||||
compress_HC_continue_destSize:: proc(LZ4_streamHCPtr: ^streamHC_t, src, dst: [^]byte, srcSizePtr: ^c.int, targetDstSize: c.int) -> c.int ---
|
||||
|
||||
saveDictHC :: proc(streamHCPtr: ^streamHC_t, safeBuffer: [^]byte, maxDictSize: c.int) -> c.int ---
|
||||
|
||||
/*! LZ4_attach_HC_dictionary() : stable since v1.10.0
|
||||
* This API allows for the efficient re-use of a static dictionary many times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
|
||||
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references the dictionary stream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of the dictionary stream.
|
||||
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
|
||||
* be expected to work.
|
||||
*
|
||||
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
||||
* case any existing dictionary stream is unset.
|
||||
*
|
||||
* A dictionary should only be attached to a stream without any history (i.e.,
|
||||
* a stream that has just been reset).
|
||||
*
|
||||
* The dictionary will remain attached to the working stream only for the
|
||||
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
|
||||
* dictionary context association from the working stream. The dictionary
|
||||
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the lifetime of the stream session.
|
||||
*/
|
||||
attach_HC_dictionary :: proc(working_stream, dictionary_stream: ^streamHC_t) ---
|
||||
}
|
||||
|
||||
|
||||
HC_DICTIONARY_LOGSIZE :: 16
|
||||
HC_MAXD :: 1<<HC_DICTIONARY_LOGSIZE
|
||||
HC_MAXD_MASK :: HC_MAXD - 1
|
||||
|
||||
HC_HASH_LOG :: 15
|
||||
HC_HASHTABLESIZE :: 1 << HC_HASH_LOG
|
||||
HC_HASH_MASK :: HC_HASHTABLESIZE - 1
|
||||
|
||||
|
||||
streamHC_internal_t :: struct {
|
||||
hashTable: [HC_HASHTABLESIZE]u32,
|
||||
chainTable: [HC_MAXD]u16,
|
||||
end: [^]byte, /* next block here to continue on current prefix */
|
||||
prefixStart: [^]byte, /* Indexes relative to this position */
|
||||
dictStart: [^]byte, /* alternate reference for extDict */
|
||||
dictLimit: u32, /* below that point, need extDict */
|
||||
lowLimit: u32, /* below that point, no more history */
|
||||
nextToUpdate: u32, /* index from which to continue dictionary update */
|
||||
compressionLevel: c.short,
|
||||
favorDecSpeed: i8, /* favor decompression speed if this flag set,
|
||||
otherwise, favor compression ratio */
|
||||
dirty: i8, /* stream has to be fully reset if this flag is set */
|
||||
dictCtx: ^streamHC_internal_t,
|
||||
}
|
||||
|
||||
STREAMHC_MINSIZE :: 262200
|
||||
|
||||
streamHC_t :: struct #raw_union {
|
||||
minStateSize: [STREAMHC_MINSIZE]byte,
|
||||
internal_donotuse: streamHC_internal_t,
|
||||
}
|
||||
Vendored
+884
@@ -0,0 +1,884 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-2023, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://www.lz4.org
|
||||
- LZ4 source repository : https://github.com/lz4/lz4
|
||||
*/
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef LZ4_H_2983827168210
|
||||
#define LZ4_H_2983827168210
|
||||
|
||||
/* --- Dependency --- */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
|
||||
/**
|
||||
Introduction
|
||||
|
||||
LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core,
|
||||
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
|
||||
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
|
||||
|
||||
The LZ4 compression library provides in-memory compression and decompression functions.
|
||||
It gives full buffer control to user.
|
||||
Compression can be done in:
|
||||
- a single step (described as Simple Functions)
|
||||
- a single step, reusing a context (described in Advanced Functions)
|
||||
- unbounded multiple steps (described as Streaming compression)
|
||||
|
||||
lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md).
|
||||
Decompressing such a compressed block requires additional metadata.
|
||||
Exact metadata depends on exact decompression function.
|
||||
For the typical case of LZ4_decompress_safe(),
|
||||
metadata includes block's compressed size, and maximum bound of decompressed size.
|
||||
Each application is free to encode and pass such metadata in whichever way it wants.
|
||||
|
||||
lz4.h only handle blocks, it can not generate Frames.
|
||||
|
||||
Blocks are different from Frames (doc/lz4_Frame_format.md).
|
||||
Frames bundle both blocks and metadata in a specified manner.
|
||||
Embedding metadata is required for compressed data to be self-contained and portable.
|
||||
Frame format is delivered through a companion API, declared in lz4frame.h.
|
||||
The `lz4` CLI can only manage frames.
|
||||
*/
|
||||
|
||||
/*^***************************************************************
|
||||
* Export parameters
|
||||
*****************************************************************/
|
||||
/*
|
||||
* LZ4_DLL_EXPORT :
|
||||
* Enable exporting of functions when building a Windows DLL
|
||||
* LZ4LIB_VISIBILITY :
|
||||
* Control library symbols visibility.
|
||||
*/
|
||||
#ifndef LZ4LIB_VISIBILITY
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define LZ4LIB_VISIBILITY
|
||||
# endif
|
||||
#endif
|
||||
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
|
||||
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
|
||||
#else
|
||||
# define LZ4LIB_API LZ4LIB_VISIBILITY
|
||||
#endif
|
||||
|
||||
/*! LZ4_FREESTANDING :
|
||||
* When this macro is set to 1, it enables "freestanding mode" that is
|
||||
* suitable for typical freestanding environment which doesn't support
|
||||
* standard C library.
|
||||
*
|
||||
* - LZ4_FREESTANDING is a compile-time switch.
|
||||
* - It requires the following macros to be defined:
|
||||
* LZ4_memcpy, LZ4_memmove, LZ4_memset.
|
||||
* - It only enables LZ4/HC functions which don't use heap.
|
||||
* All LZ4F_* functions are not supported.
|
||||
* - See tests/freestanding.c to check its basic setup.
|
||||
*/
|
||||
#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1)
|
||||
# define LZ4_HEAPMODE 0
|
||||
# define LZ4HC_HEAPMODE 0
|
||||
# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1
|
||||
# if !defined(LZ4_memcpy)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'."
|
||||
# endif
|
||||
# if !defined(LZ4_memset)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memset'."
|
||||
# endif
|
||||
# if !defined(LZ4_memmove)
|
||||
# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'."
|
||||
# endif
|
||||
#elif ! defined(LZ4_FREESTANDING)
|
||||
# define LZ4_FREESTANDING 0
|
||||
#endif
|
||||
|
||||
|
||||
/*------ Version ------*/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 10 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
|
||||
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
|
||||
#define LZ4_QUOTE(str) #str
|
||||
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
|
||||
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */
|
||||
|
||||
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */
|
||||
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Tuning memory usage
|
||||
**************************************/
|
||||
/*!
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Can be selected at compile time, by setting LZ4_MEMORY_USAGE.
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB)
|
||||
* Increasing memory usage improves compression ratio, generally at the cost of speed.
|
||||
* Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality.
|
||||
* Default value is 14, for 16KB, which nicely fits into most L1 caches.
|
||||
*/
|
||||
#ifndef LZ4_MEMORY_USAGE
|
||||
# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT
|
||||
#endif
|
||||
|
||||
/* These are absolute limits, they should not be changed by users */
|
||||
#define LZ4_MEMORY_USAGE_MIN 10
|
||||
#define LZ4_MEMORY_USAGE_DEFAULT 14
|
||||
#define LZ4_MEMORY_USAGE_MAX 20
|
||||
|
||||
#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN)
|
||||
# error "LZ4_MEMORY_USAGE is too small !"
|
||||
#endif
|
||||
|
||||
#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX)
|
||||
# error "LZ4_MEMORY_USAGE is too large !"
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
/*! LZ4_compress_default() :
|
||||
* Compresses 'srcSize' bytes from buffer 'src'
|
||||
* into already allocated 'dst' buffer of size 'dstCapacity'.
|
||||
* Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
|
||||
* It also runs faster, so it's a recommended setting.
|
||||
* If the function cannot compress 'src' into a more limited 'dst' budget,
|
||||
* compression stops *immediately*, and the function result is zero.
|
||||
* In which case, 'dst' content is undefined (invalid).
|
||||
* srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
|
||||
* dstCapacity : size of buffer 'dst' (which must be already allocated)
|
||||
* @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
|
||||
* or 0 if compression fails
|
||||
* Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
|
||||
/*! LZ4_decompress_safe() :
|
||||
* @compressedSize : is the exact complete size of the compressed block.
|
||||
* @dstCapacity : is the size of destination buffer (which must be already allocated),
|
||||
* presumed an upper bound of decompressed size.
|
||||
* @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
* Note 1 : This function is protected against malicious data packets :
|
||||
* it will never writes outside 'dst' buffer, nor read outside 'source' buffer,
|
||||
* even if the compressed block is maliciously modified to order the decoder to do these actions.
|
||||
* In such case, the decoder stops immediately, and considers the compressed block malformed.
|
||||
* Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them.
|
||||
* The implementation is free to send / store / derive this information in whichever way is most beneficial.
|
||||
* If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*! LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is incorrect (too large or negative)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*! LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c).
|
||||
Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*! LZ4_compress_fast_extState() :
|
||||
* Same as LZ4_compress_fast(), using an externally allocated memory space for its state.
|
||||
* Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
* and allocate it on 8-bytes boundaries (using `malloc()` typically).
|
||||
* Then, provide this buffer as `void* state` to compression function.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_sizeofState(void);
|
||||
LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_compress_destSize() :
|
||||
* Reverse the logic : compresses as much data as possible from 'src' buffer
|
||||
* into already allocated buffer 'dst', of size >= 'dstCapacity'.
|
||||
* This function either compresses the entire 'src' content into 'dst' if it's large enough,
|
||||
* or fill 'dst' buffer completely with as much data as possible from 'src'.
|
||||
* note: acceleration parameter is fixed to "default".
|
||||
*
|
||||
* *srcSizePtr : in+out parameter. Initially contains size of input.
|
||||
* Will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
|
||||
* New value is necessarily <= input value.
|
||||
* @return : Nb bytes written into 'dst' (necessarily <= dstCapacity)
|
||||
* or 0 if compression fails.
|
||||
*
|
||||
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+):
|
||||
* the produced compressed content could, in specific circumstances,
|
||||
* require to be decompressed into a destination buffer larger
|
||||
* by at least 1 byte than the content to decompress.
|
||||
* If an application uses `LZ4_compress_destSize()`,
|
||||
* it's highly recommended to update liblz4 to v1.9.2 or better.
|
||||
* If this can't be done or ensured,
|
||||
* the receiving decompression function should provide
|
||||
* a dstCapacity which is > decompressedSize, by at least 1 byte.
|
||||
* See https://github.com/lz4/lz4/issues/859 for details
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize);
|
||||
|
||||
/*! LZ4_decompress_safe_partial() :
|
||||
* Decompress an LZ4 compressed block, of size 'srcSize' at position 'src',
|
||||
* into destination buffer 'dst' of size 'dstCapacity'.
|
||||
* Up to 'targetOutputSize' bytes will be decoded.
|
||||
* The function stops decoding on reaching this objective.
|
||||
* This can be useful to boost performance
|
||||
* whenever only the beginning of a block is required.
|
||||
*
|
||||
* @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize)
|
||||
* If source stream is detected malformed, function returns a negative result.
|
||||
*
|
||||
* Note 1 : @return can be < targetOutputSize, if compressed block contains less data.
|
||||
*
|
||||
* Note 2 : targetOutputSize must be <= dstCapacity
|
||||
*
|
||||
* Note 3 : this function effectively stops decoding on reaching targetOutputSize,
|
||||
* so dstCapacity is kind of redundant.
|
||||
* This is because in older versions of this function,
|
||||
* decoding operation would still write complete sequences.
|
||||
* Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize,
|
||||
* it could write more bytes, though only up to dstCapacity.
|
||||
* Some "margin" used to be required for this operation to work properly.
|
||||
* Thankfully, this is no longer necessary.
|
||||
* The function nonetheless keeps the same signature, in an effort to preserve API compatibility.
|
||||
*
|
||||
* Note 4 : If srcSize is the exact size of the block,
|
||||
* then targetOutputSize can be any value,
|
||||
* including larger than the block's decompressed size.
|
||||
* The function will, at most, generate block's decompressed size.
|
||||
*
|
||||
* Note 5 : If srcSize is _larger_ than block's compressed size,
|
||||
* then targetOutputSize **MUST** be <= block's decompressed size.
|
||||
* Otherwise, *silent corruption will occur*.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-*********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
|
||||
|
||||
/*!
|
||||
Note about RC_INVOKED
|
||||
|
||||
- RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio).
|
||||
https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros
|
||||
|
||||
- Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars)
|
||||
and reports warning "RC4011: identifier truncated".
|
||||
|
||||
- To eliminate the warning, we surround long preprocessor symbol with
|
||||
"#if !defined(RC_INVOKED) ... #endif" block that means
|
||||
"skip this block when rc.exe is trying to read it".
|
||||
*/
|
||||
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
|
||||
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||
#endif
|
||||
|
||||
/*! LZ4_resetStream_fast() : v1.9.0+
|
||||
* Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
|
||||
* (e.g., LZ4_compress_fast_continue()).
|
||||
*
|
||||
* An LZ4_stream_t must be initialized once before usage.
|
||||
* This is automatically done when created by LZ4_createStream().
|
||||
* However, should the LZ4_stream_t be simply declared on stack (for example),
|
||||
* it's necessary to initialize it first, using LZ4_initStream().
|
||||
*
|
||||
* After init, start any new stream with LZ4_resetStream_fast().
|
||||
* A same LZ4_stream_t can be re-used multiple times consecutively
|
||||
* and compress multiple streams,
|
||||
* provided that it starts each new stream with LZ4_resetStream_fast().
|
||||
*
|
||||
* LZ4_resetStream_fast() is much faster than LZ4_initStream(),
|
||||
* but is not compatible with memory regions containing garbage data.
|
||||
*
|
||||
* Note: it's only useful to call LZ4_resetStream_fast()
|
||||
* in the context of streaming compression.
|
||||
* The *extState* functions perform their own resets.
|
||||
* Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_loadDict() :
|
||||
* Use this function to reference a static dictionary into LZ4_stream_t.
|
||||
* The dictionary must remain available during compression.
|
||||
* LZ4_loadDict() triggers a reset, so any previous data will be forgotten.
|
||||
* The same dictionary will have to be loaded on decompression side for successful decoding.
|
||||
* Dictionary are useful for better compression of small data (KB range).
|
||||
* While LZ4 itself accepts any input as dictionary, dictionary efficiency is also a topic.
|
||||
* When in doubt, employ the Zstandard's Dictionary Builder.
|
||||
* Loading a size of 0 is allowed, and is the same as reset.
|
||||
* @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_loadDictSlow() : v1.10.0+
|
||||
* Same as LZ4_loadDict(),
|
||||
* but uses a bit more cpu to reference the dictionary content more thoroughly.
|
||||
* This is expected to slightly improve compression ratio.
|
||||
* The extra-cpu cost is likely worth it if the dictionary is re-used across multiple sessions.
|
||||
* @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_loadDictSlow(LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_attach_dictionary() : stable since v1.10.0
|
||||
*
|
||||
* This allows efficient re-use of a static dictionary multiple times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
|
||||
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references @dictionaryStream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of @dictionaryStream.
|
||||
* Currently, only states which have been prepared by LZ4_loadDict() or
|
||||
* LZ4_loadDictSlow() should be expected to work.
|
||||
*
|
||||
* Alternatively, the provided @dictionaryStream may be NULL,
|
||||
* in which case any existing dictionary stream is unset.
|
||||
*
|
||||
* If a dictionary is provided, it replaces any pre-existing stream history.
|
||||
* The dictionary contents are the only history that can be referenced and
|
||||
* logically immediately precede the data compressed in the first subsequent
|
||||
* compression call.
|
||||
*
|
||||
* The dictionary will only remain attached to the working stream through the
|
||||
* first compression call, at the end of which it is cleared.
|
||||
* @dictionaryStream stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the completion of the compression session.
|
||||
*
|
||||
* Note: there is no equivalent LZ4_attach_*() method on the decompression side
|
||||
* because there is no initialization cost, hence no need to share the cost across multiple sessions.
|
||||
* To decompress LZ4 blocks using dictionary, attached or not,
|
||||
* just employ the regular LZ4_setStreamDecode() for streaming,
|
||||
* or the stateless LZ4_decompress_safe_usingDict() for one-shot decompression.
|
||||
*/
|
||||
LZ4LIB_API void
|
||||
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
|
||||
const LZ4_stream_t* dictionaryStream);
|
||||
|
||||
/*! LZ4_compress_fast_continue() :
|
||||
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
*
|
||||
* @return : size of compressed block
|
||||
* or 0 if there is an error (typically, cannot fit into 'dst').
|
||||
*
|
||||
* Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block.
|
||||
* Each block has precise boundaries.
|
||||
* Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata.
|
||||
* It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together.
|
||||
*
|
||||
* Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory !
|
||||
*
|
||||
* Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB.
|
||||
* Make sure that buffers are separated, by at least one byte.
|
||||
* This construction ensures that each block only depends on previous block.
|
||||
*
|
||||
* Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
|
||||
*
|
||||
* Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_saveDict() :
|
||||
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
|
||||
* save it into a safer place (char* safeBuffer).
|
||||
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
|
||||
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
|
||||
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
|
||||
|
||||
|
||||
/*-**********************************************
|
||||
* Streaming Decompression Functions
|
||||
* Bufferless synchronous API
|
||||
************************************************/
|
||||
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
|
||||
|
||||
/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
|
||||
* creation / destruction of streaming decompression tracking context.
|
||||
* A tracking context can be re-used multiple times.
|
||||
*/
|
||||
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
|
||||
#endif
|
||||
|
||||
/*! LZ4_setStreamDecode() :
|
||||
* An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
|
||||
* Use this function to start decompression of a new stream of blocks.
|
||||
* A dictionary can optionally be set. Use NULL or size 0 for a reset order.
|
||||
* Dictionary is presumed stable : it must remain accessible and unmodified during next decompression.
|
||||
* @return : 1 if OK, 0 if error
|
||||
*/
|
||||
LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_decoderRingBufferSize() : v1.8.2+
|
||||
* Note : in a ring buffer scenario (optional),
|
||||
* blocks are presumed decompressed next to each other
|
||||
* up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize),
|
||||
* at which stage it resumes from beginning of ring buffer.
|
||||
* When setting such a ring buffer for streaming decompression,
|
||||
* provides the minimum size of this ring buffer
|
||||
* to be compatible with any source respecting maxBlockSize condition.
|
||||
* @return : minimum ring buffer size,
|
||||
* or 0 if there is an error (invalid maxBlockSize).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
|
||||
#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
|
||||
|
||||
/*! LZ4_decompress_safe_continue() :
|
||||
* This decoding function allows decompression of consecutive blocks in "streaming" mode.
|
||||
* The difference with the usual independent blocks is that
|
||||
* new blocks are allowed to find references into former blocks.
|
||||
* A block is an unsplittable entity, and must be presented entirely to the decompression function.
|
||||
* LZ4_decompress_safe_continue() only accepts one block at a time.
|
||||
* It's modeled after `LZ4_decompress_safe()` and behaves similarly.
|
||||
*
|
||||
* @LZ4_streamDecode : decompression state, tracking the position in memory of past data
|
||||
* @compressedSize : exact complete size of one compressed block.
|
||||
* @dstCapacity : size of destination buffer (which must be already allocated),
|
||||
* must be an upper bound of decompressed size.
|
||||
* @return : number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
*
|
||||
* The last 64KB of previously decoded data *must* remain available and unmodified
|
||||
* at the memory position where they were previously decoded.
|
||||
* If less than 64KB of data has been decoded, all the data must be present.
|
||||
*
|
||||
* Special : if decompression side sets a ring buffer, it must respect one of the following conditions :
|
||||
* - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize).
|
||||
* maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized.
|
||||
* Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize.
|
||||
* - Synchronized mode :
|
||||
* Decompression buffer size is _exactly_ the same as compression buffer size,
|
||||
* and follows exactly same update rule (block boundaries at same positions),
|
||||
* and decoding function is provided with exact decompressed size of each block (exception for last block of the stream),
|
||||
* _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
* - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
*
|
||||
* Whenever these conditions are not possible,
|
||||
* save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
|
||||
* then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
|
||||
*/
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode,
|
||||
const char* src, char* dst,
|
||||
int srcSize, int dstCapacity);
|
||||
|
||||
|
||||
/*! LZ4_decompress_safe_usingDict() :
|
||||
* Works the same as
|
||||
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_safe_continue()
|
||||
* However, it's stateless: it doesn't need any LZ4_streamDecode_t state.
|
||||
* Dictionary is presumed stable : it must remain accessible and unmodified during decompression.
|
||||
* Performance tip : Decompression speed can be substantially increased
|
||||
* when dst == dictStart + dictSize.
|
||||
*/
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_usingDict(const char* src, char* dst,
|
||||
int srcSize, int dstCapacity,
|
||||
const char* dictStart, int dictSize);
|
||||
|
||||
/*! LZ4_decompress_safe_partial_usingDict() :
|
||||
* Behaves the same as LZ4_decompress_safe_partial()
|
||||
* with the added ability to specify a memory segment for past data.
|
||||
* Performance tip : Decompression speed can be substantially increased
|
||||
* when dst == dictStart + dictSize.
|
||||
*/
|
||||
LZ4LIB_API int
|
||||
LZ4_decompress_safe_partial_usingDict(const char* src, char* dst,
|
||||
int compressedSize,
|
||||
int targetOutputSize, int maxOutputSize,
|
||||
const char* dictStart, int dictSize);
|
||||
|
||||
#endif /* LZ4_H_2983827168210 */
|
||||
|
||||
|
||||
/*^*************************************
|
||||
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||
***************************************/
|
||||
|
||||
/*-****************************************************************************
|
||||
* Experimental section
|
||||
*
|
||||
* Symbols declared in this section must be considered unstable. Their
|
||||
* signatures or semantics may change, or they may be removed altogether in the
|
||||
* future. They are therefore only safe to depend on when the caller is
|
||||
* statically linked against the library.
|
||||
*
|
||||
* To protect against unsafe usage, not only are the declarations guarded,
|
||||
* the definitions are hidden by default
|
||||
* when building LZ4 as a shared/dynamic library.
|
||||
*
|
||||
* In order to access these declarations,
|
||||
* define LZ4_STATIC_LINKING_ONLY in your application
|
||||
* before including LZ4's headers.
|
||||
*
|
||||
* In order to make their implementations accessible dynamically, you must
|
||||
* define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library.
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LZ4_STATIC_LINKING_ONLY
|
||||
|
||||
#ifndef LZ4_STATIC_3504398509
|
||||
#define LZ4_STATIC_3504398509
|
||||
|
||||
#ifdef LZ4_PUBLISH_STATIC_FUNCTIONS
|
||||
# define LZ4LIB_STATIC_API LZ4LIB_API
|
||||
#else
|
||||
# define LZ4LIB_STATIC_API
|
||||
#endif
|
||||
|
||||
|
||||
/*! LZ4_compress_fast_extState_fastReset() :
|
||||
* A variant of LZ4_compress_fast_extState().
|
||||
*
|
||||
* Using this variant avoids an expensive initialization step.
|
||||
* It is only safe to call if the state buffer is known to be correctly initialized already
|
||||
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized").
|
||||
* From a high level, the difference is that
|
||||
* this function initializes the provided state with a call to something like LZ4_resetStream_fast()
|
||||
* while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
|
||||
*/
|
||||
LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_compress_destSize_extState() : introduced in v1.10.0
|
||||
* Same as LZ4_compress_destSize(), but using an externally allocated state.
|
||||
* Also: exposes @acceleration
|
||||
*/
|
||||
int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration);
|
||||
|
||||
/*! In-place compression and decompression
|
||||
*
|
||||
* It's possible to have input and output sharing the same buffer,
|
||||
* for highly constrained memory environments.
|
||||
* In both cases, it requires input to lay at the end of the buffer,
|
||||
* and decompression to start at beginning of the buffer.
|
||||
* Buffer size must feature some margin, hence be larger than final size.
|
||||
*
|
||||
* |<------------------------buffer--------------------------------->|
|
||||
* |<-----------compressed data--------->|
|
||||
* |<-----------decompressed size------------------>|
|
||||
* |<----margin---->|
|
||||
*
|
||||
* This technique is more useful for decompression,
|
||||
* since decompressed size is typically larger,
|
||||
* and margin is short.
|
||||
*
|
||||
* In-place decompression will work inside any buffer
|
||||
* which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize).
|
||||
* This presumes that decompressedSize > compressedSize.
|
||||
* Otherwise, it means compression actually expanded data,
|
||||
* and it would be more efficient to store such data with a flag indicating it's not compressed.
|
||||
* This can happen when data is not compressible (already compressed, or encrypted).
|
||||
*
|
||||
* For in-place compression, margin is larger, as it must be able to cope with both
|
||||
* history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX,
|
||||
* and data expansion, which can happen when input is not compressible.
|
||||
* As a consequence, buffer size requirements are much higher,
|
||||
* and memory savings offered by in-place compression are more limited.
|
||||
*
|
||||
* There are ways to limit this cost for compression :
|
||||
* - Reduce history size, by modifying LZ4_DISTANCE_MAX.
|
||||
* Note that it is a compile-time constant, so all compressions will apply this limit.
|
||||
* Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX,
|
||||
* so it's a reasonable trick when inputs are known to be small.
|
||||
* - Require the compressor to deliver a "maximum compressed size".
|
||||
* This is the `dstCapacity` parameter in `LZ4_compress*()`.
|
||||
* When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail,
|
||||
* in which case, the return code will be 0 (zero).
|
||||
* The caller must be ready for these cases to happen,
|
||||
* and typically design a backup scheme to send data uncompressed.
|
||||
* The combination of both techniques can significantly reduce
|
||||
* the amount of margin required for in-place compression.
|
||||
*
|
||||
* In-place compression can work in any buffer
|
||||
* which size is >= (maxCompressedSize)
|
||||
* with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success.
|
||||
* LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX,
|
||||
* so it's possible to reduce memory requirements by playing with them.
|
||||
*/
|
||||
|
||||
#define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32)
|
||||
#define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */
|
||||
|
||||
#ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */
|
||||
# define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */
|
||||
#endif
|
||||
|
||||
#define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */
|
||||
#define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */
|
||||
|
||||
#endif /* LZ4_STATIC_3504398509 */
|
||||
#endif /* LZ4_STATIC_LINKING_ONLY */
|
||||
|
||||
|
||||
|
||||
#ifndef LZ4_H_98237428734687
|
||||
#define LZ4_H_98237428734687
|
||||
|
||||
/*-************************************************************
|
||||
* Private Definitions
|
||||
**************************************************************
|
||||
* Do not use these definitions directly.
|
||||
* They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
|
||||
* Accessing members will expose user code to API and/or ABI break in future versions of the library.
|
||||
**************************************************************/
|
||||
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
|
||||
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
|
||||
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
|
||||
|
||||
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||
# include <stdint.h>
|
||||
typedef int8_t LZ4_i8;
|
||||
typedef uint8_t LZ4_byte;
|
||||
typedef uint16_t LZ4_u16;
|
||||
typedef uint32_t LZ4_u32;
|
||||
#else
|
||||
typedef signed char LZ4_i8;
|
||||
typedef unsigned char LZ4_byte;
|
||||
typedef unsigned short LZ4_u16;
|
||||
typedef unsigned int LZ4_u32;
|
||||
#endif
|
||||
|
||||
/*! LZ4_stream_t :
|
||||
* Never ever use below internal definitions directly !
|
||||
* These definitions are not API/ABI safe, and may change in future versions.
|
||||
* If you need static allocation, declare or allocate an LZ4_stream_t object.
|
||||
**/
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
LZ4_u32 hashTable[LZ4_HASH_SIZE_U32];
|
||||
const LZ4_byte* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
LZ4_u32 currentOffset;
|
||||
LZ4_u32 tableType;
|
||||
LZ4_u32 dictSize;
|
||||
/* Implicit padding to ensure structure is aligned */
|
||||
};
|
||||
|
||||
#define LZ4_STREAM_MINSIZE ((1UL << (LZ4_MEMORY_USAGE)) + 32) /* static size, for inter-version compatibility */
|
||||
union LZ4_stream_u {
|
||||
char minStateSize[LZ4_STREAM_MINSIZE];
|
||||
LZ4_stream_t_internal internal_donotuse;
|
||||
}; /* previously typedef'd to LZ4_stream_t */
|
||||
|
||||
|
||||
/*! LZ4_initStream() : v1.9.0+
|
||||
* An LZ4_stream_t structure must be initialized at least once.
|
||||
* This is automatically done when invoking LZ4_createStream(),
|
||||
* but it's not when the structure is simply declared on stack (for example).
|
||||
*
|
||||
* Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t.
|
||||
* It can also initialize any arbitrary buffer of sufficient size,
|
||||
* and will @return a pointer of proper type upon initialization.
|
||||
*
|
||||
* Note : initialization fails if size and alignment conditions are not respected.
|
||||
* In which case, the function will @return NULL.
|
||||
* Note2: An LZ4_stream_t structure guarantees correct alignment and size.
|
||||
* Note3: Before v1.9.0, use LZ4_resetStream() instead
|
||||
**/
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* stateBuffer, size_t size);
|
||||
|
||||
|
||||
/*! LZ4_streamDecode_t :
|
||||
* Never ever use below internal definitions directly !
|
||||
* These definitions are not API/ABI safe, and may change in future versions.
|
||||
* If you need static allocation, declare or allocate an LZ4_streamDecode_t object.
|
||||
**/
|
||||
typedef struct {
|
||||
const LZ4_byte* externalDict;
|
||||
const LZ4_byte* prefixEnd;
|
||||
size_t extDictSize;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#define LZ4_STREAMDECODE_MINSIZE 32
|
||||
union LZ4_streamDecode_u {
|
||||
char minStateSize[LZ4_STREAMDECODE_MINSIZE];
|
||||
LZ4_streamDecode_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_streamDecode_t */
|
||||
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
|
||||
/*! Deprecation warnings
|
||||
*
|
||||
* Deprecated functions make the compiler generate a warning when invoked.
|
||||
* This is meant to invite users to update their source code.
|
||||
* Should deprecation warnings be a problem, it is generally possible to disable them,
|
||||
* typically with -Wno-deprecated-declarations for gcc
|
||||
* or _CRT_SECURE_NO_WARNINGS in Visual.
|
||||
*
|
||||
* Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
* before including the header file.
|
||||
*/
|
||||
#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
|
||||
#else
|
||||
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
|
||||
# define LZ4_DEPRECATED(message) [[deprecated(message)]]
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 45))
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 31)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# else
|
||||
# pragma message("WARNING: LZ4_DEPRECATED needs custom implementation for this compiler")
|
||||
# define LZ4_DEPRECATED(message) /* disabled */
|
||||
# endif
|
||||
#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||
|
||||
/*! Obsolete compression functions (since v1.7.3) */
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/*! Obsolete decompression functions (since v1.8.0) */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||
|
||||
/* Obsolete streaming functions (since v1.7.0)
|
||||
* degraded functionality; do not use!
|
||||
*
|
||||
* In order to perform streaming compression, these functions depended on data
|
||||
* that is no longer tracked in the state. They have been preserved as well as
|
||||
* possible: using them will still produce a correct output. However, they don't
|
||||
* actually retain any history between compression calls. The compression ratio
|
||||
* achieved will therefore be no better than compressing each chunk
|
||||
* independently.
|
||||
*/
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/*! Obsolete streaming decoding functions (since v1.7.0) */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
/*! Obsolete LZ4_decompress_fast variants (since v1.9.0) :
|
||||
* These functions used to be faster than LZ4_decompress_safe(),
|
||||
* but this is no longer the case. They are now slower.
|
||||
* This is because LZ4_decompress_fast() doesn't know the input size,
|
||||
* and therefore must progress more cautiously into the input buffer to not read beyond the end of block.
|
||||
* On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability.
|
||||
* As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated.
|
||||
*
|
||||
* The last remaining LZ4_decompress_fast() specificity is that
|
||||
* it can decompress a block without knowing its compressed size.
|
||||
* Such functionality can be achieved in a more secure manner
|
||||
* by employing LZ4_decompress_safe_partial().
|
||||
*
|
||||
* Parameters:
|
||||
* originalSize : is the uncompressed size to regenerate.
|
||||
* `dst` must be already allocated, its size must be >= 'originalSize' bytes.
|
||||
* @return : number of bytes read from source buffer (== compressed size).
|
||||
* The function expects to finish at block's end exactly.
|
||||
* If the source stream is detected malformed, the function stops decoding and returns a negative result.
|
||||
* note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer.
|
||||
* However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds.
|
||||
* Also, since match offsets are not validated, match reads from 'src' may underflow too.
|
||||
* These issues never happen if input (compressed) data is correct.
|
||||
* But they may happen if input data is invalid (error or intentional tampering).
|
||||
* As a consequence, use these functions in trusted environments with trusted data **only**.
|
||||
*/
|
||||
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial() instead")
|
||||
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
|
||||
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider migrating towards LZ4_decompress_safe_continue() instead. "
|
||||
"Note that the contract will change (requires block's compressed size, instead of decompressed size)")
|
||||
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
|
||||
LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial_usingDict() instead")
|
||||
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
/*! LZ4_resetStream() :
|
||||
* An LZ4_stream_t structure must be initialized at least once.
|
||||
* This is done with LZ4_initStream(), or LZ4_resetStream().
|
||||
* Consider switching to LZ4_initStream(),
|
||||
* invoking LZ4_resetStream() will trigger deprecation warnings in the future.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
|
||||
#endif /* LZ4_H_98237428734687 */
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
Vendored
+751
@@ -0,0 +1,751 @@
|
||||
/*
|
||||
LZ4F - LZ4-Frame library
|
||||
Header File
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 source repository : https://github.com/lz4/lz4
|
||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
|
||||
/* LZ4F is a stand-alone API able to create and decode LZ4 frames
|
||||
* conformant with specification v1.6.1 in doc/lz4_Frame_format.md .
|
||||
* Generated frames are compatible with `lz4` CLI.
|
||||
*
|
||||
* LZ4F also offers streaming capabilities.
|
||||
*
|
||||
* lz4.h is not required when using lz4frame.h,
|
||||
* except to extract common constants such as LZ4_VERSION_NUMBER.
|
||||
* */
|
||||
|
||||
#ifndef LZ4F_H_09782039843
|
||||
#define LZ4F_H_09782039843
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --- Dependency --- */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
|
||||
/**
|
||||
* Introduction
|
||||
*
|
||||
* lz4frame.h implements LZ4 frame specification: see doc/lz4_Frame_format.md .
|
||||
* LZ4 Frames are compatible with `lz4` CLI,
|
||||
* and designed to be interoperable with any system.
|
||||
**/
|
||||
|
||||
/*-***************************************************************
|
||||
* Compiler specifics
|
||||
*****************************************************************/
|
||||
/* LZ4_DLL_EXPORT :
|
||||
* Enable exporting of functions when building a Windows DLL
|
||||
* LZ4FLIB_VISIBILITY :
|
||||
* Control library symbols visibility.
|
||||
*/
|
||||
#ifndef LZ4FLIB_VISIBILITY
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define LZ4FLIB_VISIBILITY __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define LZ4FLIB_VISIBILITY
|
||||
# endif
|
||||
#endif
|
||||
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
||||
# define LZ4FLIB_API __declspec(dllexport) LZ4FLIB_VISIBILITY
|
||||
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
||||
# define LZ4FLIB_API __declspec(dllimport) LZ4FLIB_VISIBILITY
|
||||
#else
|
||||
# define LZ4FLIB_API LZ4FLIB_VISIBILITY
|
||||
#endif
|
||||
|
||||
#ifdef LZ4F_DISABLE_DEPRECATE_WARNINGS
|
||||
# define LZ4F_DEPRECATE(x) x
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define LZ4F_DEPRECATE(x) x /* __declspec(deprecated) x - only works with C++ */
|
||||
# elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
|
||||
# define LZ4F_DEPRECATE(x) x __attribute__((deprecated))
|
||||
# else
|
||||
# define LZ4F_DEPRECATE(x) x /* no deprecation warning for this compiler */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Error management
|
||||
**************************************/
|
||||
typedef size_t LZ4F_errorCode_t;
|
||||
|
||||
LZ4FLIB_API unsigned LZ4F_isError(LZ4F_errorCode_t code); /**< tells when a function result is an error code */
|
||||
LZ4FLIB_API const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /**< return error code string; for debugging */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Frame compression types
|
||||
************************************* */
|
||||
/* #define LZ4F_ENABLE_OBSOLETE_ENUMS // uncomment to enable obsolete enums */
|
||||
#ifdef LZ4F_ENABLE_OBSOLETE_ENUMS
|
||||
# define LZ4F_OBSOLETE_ENUM(x) , LZ4F_DEPRECATE(x) = LZ4F_##x
|
||||
#else
|
||||
# define LZ4F_OBSOLETE_ENUM(x)
|
||||
#endif
|
||||
|
||||
/* The larger the block size, the (slightly) better the compression ratio,
|
||||
* though there are diminishing returns.
|
||||
* Larger blocks also increase memory usage on both compression and decompression sides.
|
||||
*/
|
||||
typedef enum {
|
||||
LZ4F_default=0,
|
||||
LZ4F_max64KB=4,
|
||||
LZ4F_max256KB=5,
|
||||
LZ4F_max1MB=6,
|
||||
LZ4F_max4MB=7
|
||||
LZ4F_OBSOLETE_ENUM(max64KB)
|
||||
LZ4F_OBSOLETE_ENUM(max256KB)
|
||||
LZ4F_OBSOLETE_ENUM(max1MB)
|
||||
LZ4F_OBSOLETE_ENUM(max4MB)
|
||||
} LZ4F_blockSizeID_t;
|
||||
|
||||
/* Linked blocks sharply reduce inefficiencies when using small blocks,
|
||||
* they compress better.
|
||||
* However, some LZ4 decoders are only compatible with independent blocks */
|
||||
typedef enum {
|
||||
LZ4F_blockLinked=0,
|
||||
LZ4F_blockIndependent
|
||||
LZ4F_OBSOLETE_ENUM(blockLinked)
|
||||
LZ4F_OBSOLETE_ENUM(blockIndependent)
|
||||
} LZ4F_blockMode_t;
|
||||
|
||||
typedef enum {
|
||||
LZ4F_noContentChecksum=0,
|
||||
LZ4F_contentChecksumEnabled
|
||||
LZ4F_OBSOLETE_ENUM(noContentChecksum)
|
||||
LZ4F_OBSOLETE_ENUM(contentChecksumEnabled)
|
||||
} LZ4F_contentChecksum_t;
|
||||
|
||||
typedef enum {
|
||||
LZ4F_noBlockChecksum=0,
|
||||
LZ4F_blockChecksumEnabled
|
||||
} LZ4F_blockChecksum_t;
|
||||
|
||||
typedef enum {
|
||||
LZ4F_frame=0,
|
||||
LZ4F_skippableFrame
|
||||
LZ4F_OBSOLETE_ENUM(skippableFrame)
|
||||
} LZ4F_frameType_t;
|
||||
|
||||
#ifdef LZ4F_ENABLE_OBSOLETE_ENUMS
|
||||
typedef LZ4F_blockSizeID_t blockSizeID_t;
|
||||
typedef LZ4F_blockMode_t blockMode_t;
|
||||
typedef LZ4F_frameType_t frameType_t;
|
||||
typedef LZ4F_contentChecksum_t contentChecksum_t;
|
||||
#endif
|
||||
|
||||
/*! LZ4F_frameInfo_t :
|
||||
* makes it possible to set or read frame parameters.
|
||||
* Structure must be first init to 0, using memset() or LZ4F_INIT_FRAMEINFO,
|
||||
* setting all parameters to default.
|
||||
* It's then possible to update selectively some parameters */
|
||||
typedef struct {
|
||||
LZ4F_blockSizeID_t blockSizeID; /* max64KB, max256KB, max1MB, max4MB; 0 == default (LZ4F_max64KB) */
|
||||
LZ4F_blockMode_t blockMode; /* LZ4F_blockLinked, LZ4F_blockIndependent; 0 == default (LZ4F_blockLinked) */
|
||||
LZ4F_contentChecksum_t contentChecksumFlag; /* 1: add a 32-bit checksum of frame's decompressed data; 0 == default (disabled) */
|
||||
LZ4F_frameType_t frameType; /* read-only field : LZ4F_frame or LZ4F_skippableFrame */
|
||||
unsigned long long contentSize; /* Size of uncompressed content ; 0 == unknown */
|
||||
unsigned dictID; /* Dictionary ID, sent by compressor to help decoder select correct dictionary; 0 == no dictID provided */
|
||||
LZ4F_blockChecksum_t blockChecksumFlag; /* 1: each block followed by a checksum of block's compressed data; 0 == default (disabled) */
|
||||
} LZ4F_frameInfo_t;
|
||||
|
||||
#define LZ4F_INIT_FRAMEINFO { LZ4F_max64KB, LZ4F_blockLinked, LZ4F_noContentChecksum, LZ4F_frame, 0ULL, 0U, LZ4F_noBlockChecksum } /* v1.8.3+ */
|
||||
|
||||
/*! LZ4F_preferences_t :
|
||||
* makes it possible to supply advanced compression instructions to streaming interface.
|
||||
* Structure must be first init to 0, using memset() or LZ4F_INIT_PREFERENCES,
|
||||
* setting all parameters to default.
|
||||
* All reserved fields must be set to zero. */
|
||||
typedef struct {
|
||||
LZ4F_frameInfo_t frameInfo;
|
||||
int compressionLevel; /* 0: default (fast mode); values > LZ4HC_CLEVEL_MAX count as LZ4HC_CLEVEL_MAX; values < 0 trigger "fast acceleration" */
|
||||
unsigned autoFlush; /* 1: always flush; reduces usage of internal buffers */
|
||||
unsigned favorDecSpeed; /* 1: parser favors decompression speed vs compression ratio. Only works for high compression modes (>= LZ4HC_CLEVEL_OPT_MIN) */ /* v1.8.2+ */
|
||||
unsigned reserved[3]; /* must be zero for forward compatibility */
|
||||
} LZ4F_preferences_t;
|
||||
|
||||
#define LZ4F_INIT_PREFERENCES { LZ4F_INIT_FRAMEINFO, 0, 0u, 0u, { 0u, 0u, 0u } } /* v1.8.3+ */
|
||||
|
||||
|
||||
/*-*********************************
|
||||
* Simple compression function
|
||||
***********************************/
|
||||
|
||||
/*! LZ4F_compressFrame() :
|
||||
* Compress srcBuffer content into an LZ4-compressed frame.
|
||||
* It's a one shot operation, all input content is consumed, and all output is generated.
|
||||
*
|
||||
* Note : it's a stateless operation (no LZ4F_cctx state needed).
|
||||
* In order to reduce load on the allocator, LZ4F_compressFrame(), by default,
|
||||
* uses the stack to allocate space for the compression state and some table.
|
||||
* If this usage of the stack is too much for your application,
|
||||
* consider compiling `lz4frame.c` with compile-time macro LZ4F_HEAPMODE set to 1 instead.
|
||||
* All state allocations will use the Heap.
|
||||
* It also means each invocation of LZ4F_compressFrame() will trigger several internal alloc/free invocations.
|
||||
*
|
||||
* @dstCapacity MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
|
||||
* @preferencesPtr is optional : one can provide NULL, in which case all preferences are set to default.
|
||||
* @return : number of bytes written into dstBuffer.
|
||||
* or an error code if it fails (can be tested using LZ4F_isError())
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_preferences_t* preferencesPtr);
|
||||
|
||||
/*! LZ4F_compressFrameBound() :
|
||||
* Returns the maximum possible compressed size with LZ4F_compressFrame() given srcSize and preferences.
|
||||
* `preferencesPtr` is optional. It can be replaced by NULL, in which case, the function will assume default preferences.
|
||||
* Note : this result is only usable with LZ4F_compressFrame().
|
||||
* It may also be relevant to LZ4F_compressUpdate() _only if_ no flush() operation is ever performed.
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
|
||||
|
||||
|
||||
/*! LZ4F_compressionLevel_max() :
|
||||
* @return maximum allowed compression level (currently: 12)
|
||||
*/
|
||||
LZ4FLIB_API int LZ4F_compressionLevel_max(void); /* v1.8.0+ */
|
||||
|
||||
|
||||
/*-***********************************
|
||||
* Advanced compression functions
|
||||
*************************************/
|
||||
typedef struct LZ4F_cctx_s LZ4F_cctx; /* incomplete type */
|
||||
typedef LZ4F_cctx* LZ4F_compressionContext_t; /* for compatibility with older APIs, prefer using LZ4F_cctx */
|
||||
|
||||
typedef struct {
|
||||
unsigned stableSrc; /* 1 == src content will remain present on future calls to LZ4F_compress(); skip copying src content within tmp buffer */
|
||||
unsigned reserved[3];
|
||||
} LZ4F_compressOptions_t;
|
||||
|
||||
/*--- Resource Management ---*/
|
||||
|
||||
#define LZ4F_VERSION 100 /* This number can be used to check for an incompatible API breaking change */
|
||||
LZ4FLIB_API unsigned LZ4F_getVersion(void);
|
||||
|
||||
/*! LZ4F_createCompressionContext() :
|
||||
* The first thing to do is to create a compressionContext object,
|
||||
* which will keep track of operation state during streaming compression.
|
||||
* This is achieved using LZ4F_createCompressionContext(), which takes as argument a version,
|
||||
* and a pointer to LZ4F_cctx*, to write the resulting pointer into.
|
||||
* @version provided MUST be LZ4F_VERSION. It is intended to track potential version mismatch, notably when using DLL.
|
||||
* The function provides a pointer to a fully allocated LZ4F_cctx object.
|
||||
* @cctxPtr MUST be != NULL.
|
||||
* If @return != zero, context creation failed.
|
||||
* A created compression context can be employed multiple times for consecutive streaming operations.
|
||||
* Once all streaming compression jobs are completed,
|
||||
* the state object can be released using LZ4F_freeCompressionContext().
|
||||
* Note1 : LZ4F_freeCompressionContext() is always successful. Its return value can be ignored.
|
||||
* Note2 : LZ4F_freeCompressionContext() works fine with NULL input pointers (do nothing).
|
||||
**/
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** cctxPtr, unsigned version);
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctx);
|
||||
|
||||
|
||||
/*---- Compression ----*/
|
||||
|
||||
#define LZ4F_HEADER_SIZE_MIN 7 /* LZ4 Frame header size can vary, depending on selected parameters */
|
||||
#define LZ4F_HEADER_SIZE_MAX 19
|
||||
|
||||
/* Size in bytes of a block header in little-endian format. Highest bit indicates if block data is uncompressed */
|
||||
#define LZ4F_BLOCK_HEADER_SIZE 4
|
||||
|
||||
/* Size in bytes of a block checksum footer in little-endian format. */
|
||||
#define LZ4F_BLOCK_CHECKSUM_SIZE 4
|
||||
|
||||
/* Size in bytes of the content checksum. */
|
||||
#define LZ4F_CONTENT_CHECKSUM_SIZE 4
|
||||
|
||||
/*! LZ4F_compressBegin() :
|
||||
* will write the frame header into dstBuffer.
|
||||
* dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
* `prefsPtr` is optional : NULL can be provided to set all preferences to default.
|
||||
* @return : number of bytes written into dstBuffer for the header
|
||||
* or an error code (which can be tested using LZ4F_isError())
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressBegin(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_preferences_t* prefsPtr);
|
||||
|
||||
/*! LZ4F_compressBound() :
|
||||
* Provides minimum dstCapacity required to guarantee success of
|
||||
* LZ4F_compressUpdate(), given a srcSize and preferences, for a worst case scenario.
|
||||
* When srcSize==0, LZ4F_compressBound() provides an upper bound for LZ4F_flush() and LZ4F_compressEnd() instead.
|
||||
* Note that the result is only valid for a single invocation of LZ4F_compressUpdate().
|
||||
* When invoking LZ4F_compressUpdate() multiple times,
|
||||
* if the output buffer is gradually filled up instead of emptied and re-used from its start,
|
||||
* one must check if there is enough remaining capacity before each invocation, using LZ4F_compressBound().
|
||||
* @return is always the same for a srcSize and prefsPtr.
|
||||
* prefsPtr is optional : when NULL is provided, preferences will be set to cover worst case scenario.
|
||||
* tech details :
|
||||
* @return if automatic flushing is not enabled, includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes.
|
||||
* It also includes frame footer (ending + checksum), since it might be generated by LZ4F_compressEnd().
|
||||
* @return doesn't include frame header, as it was already generated by LZ4F_compressBegin().
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* prefsPtr);
|
||||
|
||||
/*! LZ4F_compressUpdate() :
|
||||
* LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
|
||||
* Important rule: dstCapacity MUST be large enough to ensure operation success even in worst case situations.
|
||||
* This value is provided by LZ4F_compressBound().
|
||||
* If this condition is not respected, LZ4F_compress() will fail (result is an errorCode).
|
||||
* After an error, the state is left in a UB state, and must be re-initialized or freed.
|
||||
* If previously an uncompressed block was written, buffered data is flushed
|
||||
* before appending compressed data is continued.
|
||||
* `cOptPtr` is optional : NULL can be provided, in which case all options are set to default.
|
||||
* @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressUpdate(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_compressOptions_t* cOptPtr);
|
||||
|
||||
/*! LZ4F_flush() :
|
||||
* When data must be generated and sent immediately, without waiting for a block to be completely filled,
|
||||
* it's possible to call LZ4_flush(). It will immediately compress any data buffered within cctx.
|
||||
* `dstCapacity` must be large enough to ensure the operation will be successful.
|
||||
* `cOptPtr` is optional : it's possible to provide NULL, all options will be set to default.
|
||||
* @return : nb of bytes written into dstBuffer (can be zero, when there is no data stored within cctx)
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
* Note : LZ4F_flush() is guaranteed to be successful when dstCapacity >= LZ4F_compressBound(0, prefsPtr).
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_flush(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_compressOptions_t* cOptPtr);
|
||||
|
||||
/*! LZ4F_compressEnd() :
|
||||
* To properly finish an LZ4 frame, invoke LZ4F_compressEnd().
|
||||
* It will flush whatever data remained within `cctx` (like LZ4_flush())
|
||||
* and properly finalize the frame, with an endMark and a checksum.
|
||||
* `cOptPtr` is optional : NULL can be provided, in which case all options will be set to default.
|
||||
* @return : nb of bytes written into dstBuffer, necessarily >= 4 (endMark),
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
* Note : LZ4F_compressEnd() is guaranteed to be successful when dstCapacity >= LZ4F_compressBound(0, prefsPtr).
|
||||
* A successful call to LZ4F_compressEnd() makes `cctx` available again for another compression task.
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_compressEnd(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_compressOptions_t* cOptPtr);
|
||||
|
||||
|
||||
/*-*********************************
|
||||
* Decompression functions
|
||||
***********************************/
|
||||
typedef struct LZ4F_dctx_s LZ4F_dctx; /* incomplete type */
|
||||
typedef LZ4F_dctx* LZ4F_decompressionContext_t; /* compatibility with previous API versions */
|
||||
|
||||
typedef struct {
|
||||
unsigned stableDst; /* pledges that last 64KB decompressed data is present right before @dstBuffer pointer.
|
||||
* This optimization skips internal storage operations.
|
||||
* Once set, this pledge must remain valid up to the end of current frame. */
|
||||
unsigned skipChecksums; /* disable checksum calculation and verification, even when one is present in frame, to save CPU time.
|
||||
* Setting this option to 1 once disables all checksums for the rest of the frame. */
|
||||
unsigned reserved1; /* must be set to zero for forward compatibility */
|
||||
unsigned reserved0; /* idem */
|
||||
} LZ4F_decompressOptions_t;
|
||||
|
||||
|
||||
/* Resource management */
|
||||
|
||||
/*! LZ4F_createDecompressionContext() :
|
||||
* Create an LZ4F_dctx object, to track all decompression operations.
|
||||
* @version provided MUST be LZ4F_VERSION.
|
||||
* @dctxPtr MUST be valid.
|
||||
* The function fills @dctxPtr with the value of a pointer to an allocated and initialized LZ4F_dctx object.
|
||||
* The @return is an errorCode, which can be tested using LZ4F_isError().
|
||||
* dctx memory can be released using LZ4F_freeDecompressionContext();
|
||||
* Result of LZ4F_freeDecompressionContext() indicates current state of decompressionContext when being released.
|
||||
* That is, it should be == 0 if decompression has been completed fully and correctly.
|
||||
*/
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** dctxPtr, unsigned version);
|
||||
LZ4FLIB_API LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx);
|
||||
|
||||
|
||||
/*-***********************************
|
||||
* Streaming decompression functions
|
||||
*************************************/
|
||||
|
||||
#define LZ4F_MAGICNUMBER 0x184D2204U
|
||||
#define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
|
||||
#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH 5
|
||||
|
||||
/*! LZ4F_headerSize() : v1.9.0+
|
||||
* Provide the header size of a frame starting at `src`.
|
||||
* `srcSize` must be >= LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH,
|
||||
* which is enough to decode the header length.
|
||||
* @return : size of frame header
|
||||
* or an error code, which can be tested using LZ4F_isError()
|
||||
* note : Frame header size is variable, but is guaranteed to be
|
||||
* >= LZ4F_HEADER_SIZE_MIN bytes, and <= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
*/
|
||||
LZ4FLIB_API size_t LZ4F_headerSize(const void* src, size_t srcSize);
|
||||
|
||||
/*! LZ4F_getFrameInfo() :
|
||||
* This function extracts frame parameters (max blockSize, dictID, etc.).
|
||||
* Its usage is optional: user can also invoke LZ4F_decompress() directly.
|
||||
*
|
||||
* Extracted information will fill an existing LZ4F_frameInfo_t structure.
|
||||
* This can be useful for allocation and dictionary identification purposes.
|
||||
*
|
||||
* LZ4F_getFrameInfo() can work in the following situations :
|
||||
*
|
||||
* 1) At the beginning of a new frame, before any invocation of LZ4F_decompress().
|
||||
* It will decode header from `srcBuffer`,
|
||||
* consuming the header and starting the decoding process.
|
||||
*
|
||||
* Input size must be large enough to contain the full frame header.
|
||||
* Frame header size can be known beforehand by LZ4F_headerSize().
|
||||
* Frame header size is variable, but is guaranteed to be >= LZ4F_HEADER_SIZE_MIN bytes,
|
||||
* and not more than <= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
* Hence, blindly providing LZ4F_HEADER_SIZE_MAX bytes or more will always work.
|
||||
* It's allowed to provide more input data than the header size,
|
||||
* LZ4F_getFrameInfo() will only consume the header.
|
||||
*
|
||||
* If input size is not large enough,
|
||||
* aka if it's smaller than header size,
|
||||
* function will fail and return an error code.
|
||||
*
|
||||
* 2) After decoding has been started,
|
||||
* it's possible to invoke LZ4F_getFrameInfo() anytime
|
||||
* to extract already decoded frame parameters stored within dctx.
|
||||
*
|
||||
* Note that, if decoding has barely started,
|
||||
* and not yet read enough information to decode the header,
|
||||
* LZ4F_getFrameInfo() will fail.
|
||||
*
|
||||
* The number of bytes consumed from srcBuffer will be updated in *srcSizePtr (necessarily <= original value).
|
||||
* LZ4F_getFrameInfo() only consumes bytes when decoding has not yet started,
|
||||
* and when decoding the header has been successful.
|
||||
* Decompression must then resume from (srcBuffer + *srcSizePtr).
|
||||
*
|
||||
* @return : a hint about how many srcSize bytes LZ4F_decompress() expects for next call,
|
||||
* or an error code which can be tested using LZ4F_isError().
|
||||
* note 1 : in case of error, dctx is not modified. Decoding operation can resume from beginning safely.
|
||||
* note 2 : frame parameters are *copied into* an already allocated LZ4F_frameInfo_t structure.
|
||||
*/
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
||||
LZ4F_frameInfo_t* frameInfoPtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr);
|
||||
|
||||
/*! LZ4F_decompress() :
|
||||
* Call this function repetitively to regenerate data compressed in `srcBuffer`.
|
||||
*
|
||||
* The function requires a valid dctx state.
|
||||
* It will read up to *srcSizePtr bytes from srcBuffer,
|
||||
* and decompress data into dstBuffer, of capacity *dstSizePtr.
|
||||
*
|
||||
* The nb of bytes consumed from srcBuffer will be written into *srcSizePtr (necessarily <= original value).
|
||||
* The nb of bytes decompressed into dstBuffer will be written into *dstSizePtr (necessarily <= original value).
|
||||
*
|
||||
* The function does not necessarily read all input bytes, so always check value in *srcSizePtr.
|
||||
* Unconsumed source data must be presented again in subsequent invocations.
|
||||
*
|
||||
* `dstBuffer` can freely change between each consecutive function invocation.
|
||||
* `dstBuffer` content will be overwritten.
|
||||
*
|
||||
* Note: if `LZ4F_getFrameInfo()` is called before `LZ4F_decompress()`, srcBuffer must be updated to reflect
|
||||
* the number of bytes consumed after reading the frame header. Failure to update srcBuffer before calling
|
||||
* `LZ4F_decompress()` will cause decompression failure or, even worse, successful but incorrect decompression.
|
||||
* See the `LZ4F_getFrameInfo()` docs for details.
|
||||
*
|
||||
* @return : an hint of how many `srcSize` bytes LZ4F_decompress() expects for next call.
|
||||
* Schematically, it's the size of the current (or remaining) compressed block + header of next block.
|
||||
* Respecting the hint provides some small speed benefit, because it skips intermediate buffers.
|
||||
* This is just a hint though, it's always possible to provide any srcSize.
|
||||
*
|
||||
* When a frame is fully decoded, @return will be 0 (no more data expected).
|
||||
* When provided with more bytes than necessary to decode a frame,
|
||||
* LZ4F_decompress() will stop reading exactly at end of current frame, and @return 0.
|
||||
*
|
||||
* If decompression failed, @return is an error code, which can be tested using LZ4F_isError().
|
||||
* After a decompression error, the `dctx` context is not resumable.
|
||||
* Use LZ4F_resetDecompressionContext() to return to clean state.
|
||||
*
|
||||
* After a frame is fully decoded, dctx can be used again to decompress another frame.
|
||||
*/
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_decompress(LZ4F_dctx* dctx,
|
||||
void* dstBuffer, size_t* dstSizePtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr,
|
||||
const LZ4F_decompressOptions_t* dOptPtr);
|
||||
|
||||
|
||||
/*! LZ4F_resetDecompressionContext() : added in v1.8.0
|
||||
* In case of an error, the context is left in "undefined" state.
|
||||
* In which case, it's necessary to reset it, before re-using it.
|
||||
* This method can also be used to abruptly stop any unfinished decompression,
|
||||
* and start a new one using same context resources. */
|
||||
LZ4FLIB_API void LZ4F_resetDecompressionContext(LZ4F_dctx* dctx); /* always successful */
|
||||
|
||||
|
||||
/**********************************
|
||||
* Dictionary compression API
|
||||
*********************************/
|
||||
|
||||
/* A Dictionary is useful for the compression of small messages (KB range).
|
||||
* It dramatically improves compression efficiency.
|
||||
*
|
||||
* LZ4 can ingest any input as dictionary, though only the last 64 KB are useful.
|
||||
* Better results are generally achieved by using Zstandard's Dictionary Builder
|
||||
* to generate a high-quality dictionary from a set of samples.
|
||||
*
|
||||
* The same dictionary will have to be used on the decompression side
|
||||
* for decoding to be successful.
|
||||
* To help identify the correct dictionary at decoding stage,
|
||||
* the frame header allows optional embedding of a dictID field.
|
||||
*/
|
||||
|
||||
/*! LZ4F_compressBegin_usingDict() : stable since v1.10
|
||||
* Inits dictionary compression streaming, and writes the frame header into dstBuffer.
|
||||
* @dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
* @prefsPtr is optional : one may provide NULL as argument,
|
||||
* however, it's the only way to provide dictID in the frame header.
|
||||
* @dictBuffer must outlive the compression session.
|
||||
* @return : number of bytes written into dstBuffer for the header,
|
||||
* or an error code (which can be tested using LZ4F_isError())
|
||||
* NOTE: The LZ4Frame spec allows each independent block to be compressed with the dictionary,
|
||||
* but this entry supports a more limited scenario, where only the first block uses the dictionary.
|
||||
* This is still useful for small data, which only need one block anyway.
|
||||
* For larger inputs, one may be more interested in LZ4F_compressFrame_usingCDict() below.
|
||||
*/
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_compressBegin_usingDict(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const void* dictBuffer, size_t dictSize,
|
||||
const LZ4F_preferences_t* prefsPtr);
|
||||
|
||||
/*! LZ4F_decompress_usingDict() : stable since v1.10
|
||||
* Same as LZ4F_decompress(), using a predefined dictionary.
|
||||
* Dictionary is used "in place", without any preprocessing.
|
||||
** It must remain accessible throughout the entire frame decoding. */
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_decompress_usingDict(LZ4F_dctx* dctxPtr,
|
||||
void* dstBuffer, size_t* dstSizePtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr,
|
||||
const void* dict, size_t dictSize,
|
||||
const LZ4F_decompressOptions_t* decompressOptionsPtr);
|
||||
|
||||
/*****************************************
|
||||
* Bulk processing dictionary compression
|
||||
*****************************************/
|
||||
|
||||
/* Loading a dictionary has a cost, since it involves construction of tables.
|
||||
* The Bulk processing dictionary API makes it possible to share this cost
|
||||
* over an arbitrary number of compression jobs, even concurrently,
|
||||
* markedly improving compression latency for these cases.
|
||||
*
|
||||
* Note that there is no corresponding bulk API for the decompression side,
|
||||
* because dictionary does not carry any initialization cost for decompression.
|
||||
* Use the regular LZ4F_decompress_usingDict() there.
|
||||
*/
|
||||
typedef struct LZ4F_CDict_s LZ4F_CDict;
|
||||
|
||||
/*! LZ4_createCDict() : stable since v1.10
|
||||
* When compressing multiple messages / blocks using the same dictionary, it's recommended to initialize it just once.
|
||||
* LZ4_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
|
||||
* LZ4_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
|
||||
* @dictBuffer can be released after LZ4_CDict creation, since its content is copied within CDict. */
|
||||
LZ4FLIB_API LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize);
|
||||
LZ4FLIB_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
|
||||
|
||||
/*! LZ4_compressFrame_usingCDict() : stable since v1.10
|
||||
* Compress an entire srcBuffer into a valid LZ4 frame using a digested Dictionary.
|
||||
* @cctx must point to a context created by LZ4F_createCompressionContext().
|
||||
* If @cdict==NULL, compress without a dictionary.
|
||||
* @dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
|
||||
* If this condition is not respected, function will fail (@return an errorCode).
|
||||
* The LZ4F_preferences_t structure is optional : one may provide NULL as argument,
|
||||
* but it's not recommended, as it's the only way to provide @dictID in the frame header.
|
||||
* @return : number of bytes written into dstBuffer.
|
||||
* or an error code if it fails (can be tested using LZ4F_isError())
|
||||
* Note: for larger inputs generating multiple independent blocks,
|
||||
* this entry point uses the dictionary for each block. */
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* preferencesPtr);
|
||||
|
||||
/*! LZ4F_compressBegin_usingCDict() : stable since v1.10
|
||||
* Inits streaming dictionary compression, and writes the frame header into dstBuffer.
|
||||
* @dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
* @prefsPtr is optional : one may provide NULL as argument,
|
||||
* note however that it's the only way to insert a @dictID in the frame header.
|
||||
* @cdict must outlive the compression session.
|
||||
* @return : number of bytes written into dstBuffer for the header,
|
||||
* or an error code, which can be tested using LZ4F_isError(). */
|
||||
LZ4FLIB_API size_t
|
||||
LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* prefsPtr);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LZ4F_H_09782039843 */
|
||||
|
||||
#if defined(LZ4F_STATIC_LINKING_ONLY) && !defined(LZ4F_H_STATIC_09782039843)
|
||||
#define LZ4F_H_STATIC_09782039843
|
||||
|
||||
/* Note :
|
||||
* The below declarations are not stable and may change in the future.
|
||||
* They are therefore only safe to depend on
|
||||
* when the caller is statically linked against the library.
|
||||
* To access their declarations, define LZ4F_STATIC_LINKING_ONLY.
|
||||
*
|
||||
* By default, these symbols aren't published into shared/dynamic libraries.
|
||||
* You can override this behavior and force them to be published
|
||||
* by defining LZ4F_PUBLISH_STATIC_FUNCTIONS.
|
||||
* Use at your own risk.
|
||||
*/
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef LZ4F_PUBLISH_STATIC_FUNCTIONS
|
||||
# define LZ4FLIB_STATIC_API LZ4FLIB_API
|
||||
#else
|
||||
# define LZ4FLIB_STATIC_API
|
||||
#endif
|
||||
|
||||
|
||||
/* --- Error List --- */
|
||||
#define LZ4F_LIST_ERRORS(ITEM) \
|
||||
ITEM(OK_NoError) \
|
||||
ITEM(ERROR_GENERIC) \
|
||||
ITEM(ERROR_maxBlockSize_invalid) \
|
||||
ITEM(ERROR_blockMode_invalid) \
|
||||
ITEM(ERROR_parameter_invalid) \
|
||||
ITEM(ERROR_compressionLevel_invalid) \
|
||||
ITEM(ERROR_headerVersion_wrong) \
|
||||
ITEM(ERROR_blockChecksum_invalid) \
|
||||
ITEM(ERROR_reservedFlag_set) \
|
||||
ITEM(ERROR_allocation_failed) \
|
||||
ITEM(ERROR_srcSize_tooLarge) \
|
||||
ITEM(ERROR_dstMaxSize_tooSmall) \
|
||||
ITEM(ERROR_frameHeader_incomplete) \
|
||||
ITEM(ERROR_frameType_unknown) \
|
||||
ITEM(ERROR_frameSize_wrong) \
|
||||
ITEM(ERROR_srcPtr_wrong) \
|
||||
ITEM(ERROR_decompressionFailed) \
|
||||
ITEM(ERROR_headerChecksum_invalid) \
|
||||
ITEM(ERROR_contentChecksum_invalid) \
|
||||
ITEM(ERROR_frameDecoding_alreadyStarted) \
|
||||
ITEM(ERROR_compressionState_uninitialized) \
|
||||
ITEM(ERROR_parameter_null) \
|
||||
ITEM(ERROR_io_write) \
|
||||
ITEM(ERROR_io_read) \
|
||||
ITEM(ERROR_maxCode)
|
||||
|
||||
#define LZ4F_GENERATE_ENUM(ENUM) LZ4F_##ENUM,
|
||||
|
||||
/* enum list is exposed, to handle specific errors */
|
||||
typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM)
|
||||
_LZ4F_dummy_error_enum_for_c89_never_used } LZ4F_errorCodes;
|
||||
|
||||
LZ4FLIB_STATIC_API LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult);
|
||||
|
||||
/**********************************
|
||||
* Advanced compression operations
|
||||
*********************************/
|
||||
|
||||
/*! LZ4F_getBlockSize() :
|
||||
* @return, in scalar format (size_t),
|
||||
* the maximum block size associated with @blockSizeID,
|
||||
* or an error code (can be tested using LZ4F_isError()) if @blockSizeID is invalid.
|
||||
**/
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_getBlockSize(LZ4F_blockSizeID_t blockSizeID);
|
||||
|
||||
/*! LZ4F_uncompressedUpdate() :
|
||||
* LZ4F_uncompressedUpdate() can be called repetitively to add data stored as uncompressed blocks.
|
||||
* Important rule: dstCapacity MUST be large enough to store the entire source buffer as
|
||||
* no compression is done for this operation
|
||||
* If this condition is not respected, LZ4F_uncompressedUpdate() will fail (result is an errorCode).
|
||||
* After an error, the state is left in a UB state, and must be re-initialized or freed.
|
||||
* If previously a compressed block was written, buffered data is flushed first,
|
||||
* before appending uncompressed data is continued.
|
||||
* This operation is only supported when LZ4F_blockIndependent is used.
|
||||
* `cOptPtr` is optional : NULL can be provided, in which case all options are set to default.
|
||||
* @return : number of bytes written into `dstBuffer` (it can be zero, meaning input data was just buffered).
|
||||
* or an error code if it fails (which can be tested using LZ4F_isError())
|
||||
*/
|
||||
LZ4FLIB_STATIC_API size_t
|
||||
LZ4F_uncompressedUpdate(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_compressOptions_t* cOptPtr);
|
||||
|
||||
/**********************************
|
||||
* Custom memory allocation
|
||||
*********************************/
|
||||
|
||||
/*! Custom memory allocation : v1.9.4+
|
||||
* These prototypes make it possible to pass custom allocation/free functions.
|
||||
* LZ4F_customMem is provided at state creation time, using LZ4F_create*_advanced() listed below.
|
||||
* All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
|
||||
*/
|
||||
typedef void* (*LZ4F_AllocFunction) (void* opaqueState, size_t size);
|
||||
typedef void* (*LZ4F_CallocFunction) (void* opaqueState, size_t size);
|
||||
typedef void (*LZ4F_FreeFunction) (void* opaqueState, void* address);
|
||||
typedef struct {
|
||||
LZ4F_AllocFunction customAlloc;
|
||||
LZ4F_CallocFunction customCalloc; /* optional; when not defined, uses customAlloc + memset */
|
||||
LZ4F_FreeFunction customFree;
|
||||
void* opaqueState;
|
||||
} LZ4F_CustomMem;
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__attribute__((__unused__))
|
||||
#endif
|
||||
LZ4F_CustomMem const LZ4F_defaultCMem = { NULL, NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
|
||||
|
||||
LZ4FLIB_STATIC_API LZ4F_cctx* LZ4F_createCompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
|
||||
LZ4FLIB_STATIC_API LZ4F_dctx* LZ4F_createDecompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
|
||||
LZ4FLIB_STATIC_API LZ4F_CDict* LZ4F_createCDict_advanced(LZ4F_CustomMem customMem, const void* dictBuffer, size_t dictSize);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(LZ4F_STATIC_LINKING_ONLY) && !defined(LZ4F_H_STATIC_09782039843) */
|
||||
Vendored
+414
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
LZ4 HC - High Compression Mode of LZ4
|
||||
Header File
|
||||
Copyright (C) 2011-2020, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 source repository : https://github.com/lz4/lz4
|
||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
#ifndef LZ4_HC_H_19834876238432
|
||||
#define LZ4_HC_H_19834876238432
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --- Dependency --- */
|
||||
/* note : lz4hc requires lz4.h/lz4.c for compilation */
|
||||
#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
|
||||
|
||||
|
||||
/* --- Useful constants --- */
|
||||
#define LZ4HC_CLEVEL_MIN 2
|
||||
#define LZ4HC_CLEVEL_DEFAULT 9
|
||||
#define LZ4HC_CLEVEL_OPT_MIN 10
|
||||
#define LZ4HC_CLEVEL_MAX 12
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Block Compression
|
||||
**************************************/
|
||||
/*! LZ4_compress_HC() :
|
||||
* Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
|
||||
* `dst` must be already allocated.
|
||||
* Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
|
||||
* Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
|
||||
* `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
|
||||
* Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
|
||||
* @return : the number of bytes written into 'dst'
|
||||
* or 0 if compression fails.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
|
||||
|
||||
|
||||
/* Note :
|
||||
* Decompression functions are provided within "lz4.h" (BSD license)
|
||||
*/
|
||||
|
||||
|
||||
/*! LZ4_compress_HC_extStateHC() :
|
||||
* Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
|
||||
* `state` size is provided by LZ4_sizeofStateHC().
|
||||
* Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_sizeofStateHC(void);
|
||||
LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
|
||||
|
||||
|
||||
/*! LZ4_compress_HC_destSize() : v1.9.0+
|
||||
* Will compress as much data as possible from `src`
|
||||
* to fit into `targetDstSize` budget.
|
||||
* Result is provided in 2 parts :
|
||||
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||
* or 0 if compression fails.
|
||||
* `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC,
|
||||
const char* src, char* dst,
|
||||
int* srcSizePtr, int targetDstSize,
|
||||
int compressionLevel);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Streaming Compression
|
||||
* Bufferless synchronous API
|
||||
**************************************/
|
||||
typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
|
||||
|
||||
/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
|
||||
* These functions create and release memory for LZ4 HC streaming state.
|
||||
* Newly created states are automatically initialized.
|
||||
* A same state can be used multiple times consecutively,
|
||||
* starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
|
||||
*/
|
||||
LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
|
||||
LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
|
||||
|
||||
/*
|
||||
These functions compress data in successive blocks of any size,
|
||||
using previous blocks as dictionary, to improve compression ratio.
|
||||
One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
|
||||
There is an exception for ring buffers, which can be smaller than 64 KB.
|
||||
Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue().
|
||||
|
||||
Before starting compression, state must be allocated and properly initialized.
|
||||
LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT.
|
||||
|
||||
Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream)
|
||||
or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental).
|
||||
LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once,
|
||||
which is automatically the case when state is created using LZ4_createStreamHC().
|
||||
|
||||
After reset, a first "fictional block" can be designated as initial dictionary,
|
||||
using LZ4_loadDictHC() (Optional).
|
||||
Note: In order for LZ4_loadDictHC() to create the correct data structure,
|
||||
it is essential to set the compression level _before_ loading the dictionary.
|
||||
|
||||
Invoke LZ4_compress_HC_continue() to compress each successive block.
|
||||
The number of blocks is unlimited.
|
||||
Previous input blocks, including initial dictionary when present,
|
||||
must remain accessible and unmodified during compression.
|
||||
|
||||
It's allowed to update compression level anytime between blocks,
|
||||
using LZ4_setCompressionLevel() (experimental).
|
||||
|
||||
@dst buffer should be sized to handle worst case scenarios
|
||||
(see LZ4_compressBound(), it ensures compression success).
|
||||
In case of failure, the API does not guarantee recovery,
|
||||
so the state _must_ be reset.
|
||||
To ensure compression success
|
||||
whenever @dst buffer size cannot be made >= LZ4_compressBound(),
|
||||
consider using LZ4_compress_HC_continue_destSize().
|
||||
|
||||
Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
|
||||
it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC().
|
||||
Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB)
|
||||
|
||||
After completing a streaming compression,
|
||||
it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state,
|
||||
just by resetting it, using LZ4_resetStreamHC_fast().
|
||||
*/
|
||||
|
||||
LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */
|
||||
LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
|
||||
|
||||
LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr,
|
||||
const char* src, char* dst,
|
||||
int srcSize, int maxDstSize);
|
||||
|
||||
/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
|
||||
* Similar to LZ4_compress_HC_continue(),
|
||||
* but will read as much data as possible from `src`
|
||||
* to fit into `targetDstSize` budget.
|
||||
* Result is provided into 2 parts :
|
||||
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
|
||||
* or 0 if compression fails.
|
||||
* `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
|
||||
* Note that this function may not consume the entire input.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr,
|
||||
const char* src, char* dst,
|
||||
int* srcSizePtr, int targetDstSize);
|
||||
|
||||
LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
|
||||
|
||||
|
||||
/*! LZ4_attach_HC_dictionary() : stable since v1.10.0
|
||||
* This API allows for the efficient re-use of a static dictionary many times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
|
||||
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references the dictionary stream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of the dictionary stream.
|
||||
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
|
||||
* be expected to work.
|
||||
*
|
||||
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
||||
* case any existing dictionary stream is unset.
|
||||
*
|
||||
* A dictionary should only be attached to a stream without any history (i.e.,
|
||||
* a stream that has just been reset).
|
||||
*
|
||||
* The dictionary will remain attached to the working stream only for the
|
||||
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
|
||||
* dictionary context association from the working stream. The dictionary
|
||||
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the lifetime of the stream session.
|
||||
*/
|
||||
LZ4LIB_API void
|
||||
LZ4_attach_HC_dictionary(LZ4_streamHC_t* working_stream,
|
||||
const LZ4_streamHC_t* dictionary_stream);
|
||||
|
||||
|
||||
/*^**********************************************
|
||||
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||
***********************************************/
|
||||
|
||||
/*-******************************************************************
|
||||
* PRIVATE DEFINITIONS :
|
||||
* Do not use these definitions directly.
|
||||
* They are merely exposed to allow static allocation of `LZ4_streamHC_t`.
|
||||
* Declare an `LZ4_streamHC_t` directly, rather than any type below.
|
||||
* Even then, only do so in the context of static linking, as definitions may change between versions.
|
||||
********************************************************************/
|
||||
|
||||
#define LZ4HC_DICTIONARY_LOGSIZE 16
|
||||
#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
|
||||
#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
|
||||
|
||||
#define LZ4HC_HASH_LOG 15
|
||||
#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
|
||||
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
|
||||
|
||||
|
||||
/* Never ever use these definitions directly !
|
||||
* Declare or allocate an LZ4_streamHC_t instead.
|
||||
**/
|
||||
typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
|
||||
struct LZ4HC_CCtx_internal
|
||||
{
|
||||
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE];
|
||||
LZ4_u16 chainTable[LZ4HC_MAXD];
|
||||
const LZ4_byte* end; /* next block here to continue on current prefix */
|
||||
const LZ4_byte* prefixStart; /* Indexes relative to this position */
|
||||
const LZ4_byte* dictStart; /* alternate reference for extDict */
|
||||
LZ4_u32 dictLimit; /* below that point, need extDict */
|
||||
LZ4_u32 lowLimit; /* below that point, no more history */
|
||||
LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
|
||||
short compressionLevel;
|
||||
LZ4_i8 favorDecSpeed; /* favor decompression speed if this flag set,
|
||||
otherwise, favor compression ratio */
|
||||
LZ4_i8 dirty; /* stream has to be fully reset if this flag is set */
|
||||
const LZ4HC_CCtx_internal* dictCtx;
|
||||
};
|
||||
|
||||
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
|
||||
union LZ4_streamHC_u {
|
||||
char minStateSize[LZ4_STREAMHC_MINSIZE];
|
||||
LZ4HC_CCtx_internal internal_donotuse;
|
||||
}; /* previously typedef'd to LZ4_streamHC_t */
|
||||
|
||||
/* LZ4_streamHC_t :
|
||||
* This structure allows static allocation of LZ4 HC streaming state.
|
||||
* This can be used to allocate statically on stack, or as part of a larger structure.
|
||||
*
|
||||
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
|
||||
*
|
||||
* Note that invoking LZ4_initStreamHC() is not required when
|
||||
* the state was created using LZ4_createStreamHC() (which is recommended).
|
||||
* Using the normal builder, a newly created state is automatically initialized.
|
||||
*
|
||||
* Static allocation shall only be used in combination with static linking.
|
||||
*/
|
||||
|
||||
/* LZ4_initStreamHC() : v1.9.0+
|
||||
* Required before first use of a statically allocated LZ4_streamHC_t.
|
||||
* Before v1.9.0 : use LZ4_resetStreamHC() instead
|
||||
*/
|
||||
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, size_t size);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Deprecated Functions
|
||||
**************************************/
|
||||
/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
|
||||
|
||||
/* deprecated compression functions */
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete streaming functions; degraded functionality; do not use!
|
||||
*
|
||||
* In order to perform streaming compression, these functions depended on data
|
||||
* that is no longer tracked in the state. They have been preserved as well as
|
||||
* possible: using them will still produce a correct output. However, use of
|
||||
* LZ4_slideInputBufferHC() will truncate the history of the stream, rather
|
||||
* than preserve a window-sized chunk of history.
|
||||
*/
|
||||
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
|
||||
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
|
||||
#endif
|
||||
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
|
||||
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
|
||||
LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
|
||||
|
||||
|
||||
/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC().
|
||||
* The intention is to emphasize the difference with LZ4_resetStreamHC_fast(),
|
||||
* which is now the recommended function to start a new stream of blocks,
|
||||
* but cannot be used to initialize a memory segment containing arbitrary garbage data.
|
||||
*
|
||||
* It is recommended to switch to LZ4_initStreamHC().
|
||||
* LZ4_resetStreamHC() will generate deprecation warnings in a future version.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LZ4_HC_H_19834876238432 */
|
||||
|
||||
|
||||
/*-**************************************************
|
||||
* !!!!! STATIC LINKING ONLY !!!!!
|
||||
* Following definitions are considered experimental.
|
||||
* They should not be linked from DLL,
|
||||
* as there is no guarantee of API stability yet.
|
||||
* Prototypes will be promoted to "stable" status
|
||||
* after successful usage in real-life scenarios.
|
||||
***************************************************/
|
||||
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
|
||||
#ifndef LZ4_HC_SLO_098092834
|
||||
#define LZ4_HC_SLO_098092834
|
||||
|
||||
#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */
|
||||
#include "lz4.h"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental)
|
||||
* It's possible to change compression level
|
||||
* between successive invocations of LZ4_compress_HC_continue*()
|
||||
* for dynamic adaptation.
|
||||
*/
|
||||
LZ4LIB_STATIC_API void LZ4_setCompressionLevel(
|
||||
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
|
||||
|
||||
/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental)
|
||||
* Opt. Parser will favor decompression speed over compression ratio.
|
||||
* Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN.
|
||||
*/
|
||||
LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed(
|
||||
LZ4_streamHC_t* LZ4_streamHCPtr, int favor);
|
||||
|
||||
/*! LZ4_resetStreamHC_fast() : v1.9.0+
|
||||
* When an LZ4_streamHC_t is known to be in a internally coherent state,
|
||||
* it can often be prepared for a new compression with almost no work, only
|
||||
* sometimes falling back to the full, expensive reset that is always required
|
||||
* when the stream is in an indeterminate state (i.e., the reset performed by
|
||||
* LZ4_resetStreamHC()).
|
||||
*
|
||||
* LZ4_streamHCs are guaranteed to be in a valid state when:
|
||||
* - returned from LZ4_createStreamHC()
|
||||
* - reset by LZ4_resetStreamHC()
|
||||
* - memset(stream, 0, sizeof(LZ4_streamHC_t))
|
||||
* - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast()
|
||||
* - the stream was in a valid state and was then used in any compression call
|
||||
* that returned success
|
||||
* - the stream was in an indeterminate state and was used in a compression
|
||||
* call that fully reset the state (LZ4_compress_HC_extStateHC()) and that
|
||||
* returned success
|
||||
*
|
||||
* Note:
|
||||
* A stream that was last used in a compression call that returned an error
|
||||
* may be passed to this function. However, it will be fully reset, which will
|
||||
* clear any existing history and settings from the context.
|
||||
*/
|
||||
LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast(
|
||||
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
|
||||
|
||||
/*! LZ4_compress_HC_extStateHC_fastReset() :
|
||||
* A variant of LZ4_compress_HC_extStateHC().
|
||||
*
|
||||
* Using this variant avoids an expensive initialization step. It is only safe
|
||||
* to call if the state buffer is known to be correctly initialized already
|
||||
* (see above comment on LZ4_resetStreamHC_fast() for a definition of
|
||||
* "correctly initialized"). From a high level, the difference is that this
|
||||
* function initializes the provided state with a call to
|
||||
* LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a
|
||||
* call to LZ4_resetStreamHC().
|
||||
*/
|
||||
LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
|
||||
void* state,
|
||||
const char* src, char* dst,
|
||||
int srcSize, int dstCapacity,
|
||||
int compressionLevel);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LZ4_HC_SLO_098092834 */
|
||||
#endif /* LZ4_HC_STATIC_LINKING_ONLY */
|
||||
Vendored
+3
-8
@@ -29,14 +29,9 @@ SIZE :: win32.SIZE
|
||||
WCHAR :: win32.WCHAR
|
||||
DWORD :: win32.DWORD
|
||||
|
||||
IUnknown :: struct {
|
||||
using _iunknown_vtable: ^IUnknown_VTable,
|
||||
}
|
||||
IUnknown_VTable :: struct {
|
||||
QueryInterface: proc "system" (this: ^IUnknown, riid: ^IID, ppvObject: ^rawptr) -> HRESULT,
|
||||
AddRef: proc "system" (this: ^IUnknown) -> ULONG,
|
||||
Release: proc "system" (this: ^IUnknown) -> ULONG,
|
||||
}
|
||||
IUnknown :: win32.IUnknown
|
||||
IUnknown_VTable :: win32.IUnknown_VTable
|
||||
LPUNKNOWN :: win32.LPUNKNOWN
|
||||
|
||||
@(default_calling_convention="system")
|
||||
foreign dxgi {
|
||||
|
||||
Vendored
+3
-17
@@ -1,14 +1,14 @@
|
||||
//+build windows, linux, darwin
|
||||
//+vet !using-param
|
||||
package fontstash
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:log"
|
||||
import "core:os"
|
||||
import "core:mem"
|
||||
import "core:math"
|
||||
import "core:strings"
|
||||
import "core:slice"
|
||||
|
||||
import stbtt "vendor:stb/truetype"
|
||||
|
||||
// This is a port from Fontstash into odin - specialized for nanovg
|
||||
@@ -321,20 +321,6 @@ __AtlasAddWhiteRect :: proc(ctx: ^FontContext, w, h: int) -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
AddFontPath :: proc(
|
||||
ctx: ^FontContext,
|
||||
name: string,
|
||||
path: string,
|
||||
) -> int {
|
||||
data, ok := os.read_entire_file(path)
|
||||
|
||||
if !ok {
|
||||
log.panicf("FONT: failed to read font at %s", path)
|
||||
}
|
||||
|
||||
return AddFontMem(ctx, name, data, true)
|
||||
}
|
||||
|
||||
// push a font to the font stack
|
||||
// optionally init with ascii characters at a wanted size
|
||||
AddFontMem :: proc(
|
||||
@@ -1192,4 +1178,4 @@ EndState :: proc(using ctx: ^FontContext) {
|
||||
}
|
||||
__dirtyRectReset(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
//+build !js
|
||||
package fontstash
|
||||
|
||||
import "core:log"
|
||||
import "core:os"
|
||||
|
||||
AddFontPath :: proc(
|
||||
ctx: ^FontContext,
|
||||
name: string,
|
||||
path: string,
|
||||
) -> int {
|
||||
data, ok := os.read_entire_file(path)
|
||||
|
||||
if !ok {
|
||||
log.panicf("FONT: failed to read font at %s", path)
|
||||
}
|
||||
|
||||
return AddFontMem(ctx, name, data, true)
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//+build js
|
||||
package fontstash
|
||||
|
||||
AddFontPath :: proc(
|
||||
ctx: ^FontContext,
|
||||
name: string,
|
||||
path: string,
|
||||
) -> int {
|
||||
panic("fontstash.AddFontPath is unsupported on the JS target")
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2002-2006 Marcus Geelnard
|
||||
|
||||
Copyright (c) 2006-2019 Camilla Löwy
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would
|
||||
be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
Vendored
+5
@@ -197,7 +197,12 @@ foreign glfw {
|
||||
|
||||
SetErrorCallback :: proc(cbfun: ErrorProc) -> ErrorProc ---
|
||||
|
||||
// Functions added in 3.4, Linux links against system glfw so we define these as weak to be able
|
||||
// to check at runtime if they are available.
|
||||
|
||||
@(linkage="weak")
|
||||
GetPlatform :: proc() -> c.int ---
|
||||
@(linkage="weak")
|
||||
PlatformSupported :: proc(platform: c.int) -> b32 ---
|
||||
}
|
||||
|
||||
|
||||
Vendored
+6
@@ -13,7 +13,13 @@ foreign {
|
||||
SetX11SelectionString :: proc(string: cstring) ---
|
||||
GetX11SelectionString :: proc() -> cstring ---
|
||||
|
||||
// Functions added in 3.4, Linux links against system glfw so we define these as weak to be able
|
||||
// to check at runtime if they are available.
|
||||
|
||||
@(linkage="weak")
|
||||
GetWaylandDisplay :: proc() -> rawptr /* struct wl_display* */ ---
|
||||
@(linkage="weak")
|
||||
GetWaylandWindow :: proc(window: WindowHandle) -> rawptr /* struct wl_surface* */ ---
|
||||
@(linkage="weak")
|
||||
GetWaylandMonitor :: proc(monitor: MonitorHandle) -> rawptr /* struct wl_output* */ ---
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -16,7 +16,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua5.1.so"
|
||||
} else {
|
||||
foreign import lib "system:liblua.so.5.1"
|
||||
foreign import lib "system:lua5.1"
|
||||
}
|
||||
} else {
|
||||
when ODIN_OS == .Windows {
|
||||
@@ -24,7 +24,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua5.1.a"
|
||||
} else {
|
||||
foreign import lib "system:liblua5.1.a"
|
||||
foreign import lib "system:lua5.1"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -16,7 +16,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua52.so"
|
||||
} else {
|
||||
foreign import lib "system:liblua.so.5.2"
|
||||
foreign import lib "system:lua5.2"
|
||||
}
|
||||
} else {
|
||||
when ODIN_OS == .Windows {
|
||||
@@ -24,7 +24,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua52.a"
|
||||
} else {
|
||||
foreign import lib "system:liblua52.a"
|
||||
foreign import lib "system:lua5.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -16,7 +16,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua53.so"
|
||||
} else {
|
||||
foreign import lib "system:liblua.so.5.3"
|
||||
foreign import lib "system:lua5.3"
|
||||
}
|
||||
} else {
|
||||
when ODIN_OS == .Windows {
|
||||
@@ -24,7 +24,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua53.a"
|
||||
} else {
|
||||
foreign import lib "system:liblua53.a"
|
||||
foreign import lib "system:lua5.3"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-10
@@ -16,15 +16,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua54.so"
|
||||
} else {
|
||||
// Note(bumbread): My linux system has a few aliases for this shared object
|
||||
// lublua5.4.so, liblua.so, lublua.so.5.4, liblua.so.5.4.6. I don't know
|
||||
// who enforces these numbers (probably ld?), and if it can be done in a
|
||||
// unix-generic way, but in any way I think the most sane thing to do is to
|
||||
// keep it close to what linux does and if it breaks, just special case those
|
||||
// operating systems.
|
||||
// Also there was no alias for liblua54.so, that seems to suggest that way
|
||||
// of specifying it isn't portable
|
||||
foreign import lib "system:liblua.so.5.4"
|
||||
foreign import lib "system:lua5.4"
|
||||
}
|
||||
} else {
|
||||
when ODIN_OS == .Windows {
|
||||
@@ -32,7 +24,7 @@ when LUA_SHARED {
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "linux/liblua54.a"
|
||||
} else {
|
||||
foreign import lib "system:liblua54.a"
|
||||
foreign import lib "system:lua5.4"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+43
-5
@@ -1,12 +1,50 @@
|
||||
# Lua in Odin
|
||||
|
||||
```odin
|
||||
import lua "vendor:lua/5.4" // or whatever version you want
|
||||
```
|
||||
|
||||
Lua packages
|
||||
|
||||
* `vendor:lua/5.1` (version 5.1.5)
|
||||
* `vendor:lua/5.2` (version 5.2.4)
|
||||
* `vendor:lua/5.3` (version 5.3.6)
|
||||
* `vendor:lua/5.4` (version 5.4.2)
|
||||
* `vendor:lua/5.4` (version 5.4.2)
|
||||
|
||||
With custom context-based allocator:
|
||||
|
||||
```odin
|
||||
package lua_example_with_context
|
||||
|
||||
import "core:fmt"
|
||||
import lua "vendor:lua/5.4" // or whatever version you want
|
||||
import "core:c"
|
||||
import "base:runtime"
|
||||
|
||||
state: ^lua.State
|
||||
|
||||
lua_allocator :: proc "c" (ud: rawptr, ptr: rawptr, osize, nsize: c.size_t) -> (buf: rawptr) {
|
||||
old_size := int(osize)
|
||||
new_size := int(nsize)
|
||||
context = (^runtime.Context)(ud)^
|
||||
|
||||
if ptr == nil {
|
||||
data, err := runtime.mem_alloc(new_size)
|
||||
return raw_data(data) if err == .None else nil
|
||||
} else {
|
||||
if nsize > 0 {
|
||||
data, err := runtime.mem_resize(ptr, old_size, new_size)
|
||||
return raw_data(data) if err == .None else nil
|
||||
} else {
|
||||
runtime.mem_free(ptr)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
_context := context
|
||||
state = lua.newstate(lua_allocator, &_context)
|
||||
defer lua.close(state)
|
||||
|
||||
lua.L_dostring(state, "return 'somestring'")
|
||||
str := lua.tostring(state, -1)
|
||||
fmt.println(str)
|
||||
}
|
||||
```
|
||||
Vendored
+2
-9
@@ -28,13 +28,6 @@ when ODIN_OS == .Windows {
|
||||
|
||||
RAYGUI_VERSION :: "4.0"
|
||||
|
||||
// Style property
|
||||
GuiStyleProp :: struct {
|
||||
controlId: u16,
|
||||
propertyId: u16,
|
||||
propertyValue: c.int,
|
||||
}
|
||||
|
||||
// Gui control state
|
||||
GuiState :: enum c.int {
|
||||
STATE_NORMAL = 0,
|
||||
@@ -236,8 +229,8 @@ foreign lib {
|
||||
|
||||
// Style set/get functions
|
||||
|
||||
GuiSetStyle :: proc(control: GuiControl, property: GuiStyleProp, value: c.int) --- // Set one style property
|
||||
GuiGetStyle :: proc(control: GuiControl, property: GuiStyleProp) -> c.int --- // Get one style property
|
||||
GuiSetStyle :: proc(control: GuiControl, property: GuiControlProperty, value: c.int) --- // Set one style property
|
||||
GuiGetStyle :: proc(control: GuiControl, property: GuiControlProperty) -> c.int --- // Get one style property
|
||||
|
||||
// Styles loading functions
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -1015,8 +1015,8 @@ foreign lib {
|
||||
|
||||
SetRandomSeed :: proc(seed: c.uint) --- // Set the seed for the random number generator
|
||||
GetRandomValue :: proc(min, max: c.int) -> c.int --- // Get a random value between min and max (both included)
|
||||
LoadRandomSequence :: proc(count : c.uint, min, max: c.int) --- // Load random values sequence, no values repeated
|
||||
UnloadRandomSequence :: proc(sequence : ^c.int) --- // Unload random values sequence
|
||||
LoadRandomSequence :: proc(count: c.uint, min, max: c.int) --- // Load random values sequence, no values repeated
|
||||
UnloadRandomSequence :: proc(sequence: ^c.int) --- // Unload random values sequence
|
||||
|
||||
// Misc. functions
|
||||
TakeScreenshot :: proc(fileName: cstring) --- // Takes a screenshot of current screen (filename extension defines format)
|
||||
@@ -1424,9 +1424,9 @@ foreign lib {
|
||||
|
||||
LoadUTF8 :: proc(codepoints: [^]rune, length: c.int) -> [^]byte --- // Load UTF-8 text encoded from codepoints array
|
||||
UnloadUTF8 :: proc(text: [^]byte) --- // Unload UTF-8 text encoded from codepoints array
|
||||
LoadCodepoints :: proc(text: rawptr, count: ^c.int) -> [^]rune --- // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
LoadCodepoints :: proc(text: cstring, count: ^c.int) -> [^]rune --- // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
UnloadCodepoints :: proc(codepoints: [^]rune) --- // Unload codepoints data from memory
|
||||
GetCodepointCount :: proc(text : cstring) -> c.int --- // Get total number of codepoints in a UTF-8 encoded string
|
||||
GetCodepointCount :: proc(text: cstring) -> c.int --- // Get total number of codepoints in a UTF-8 encoded string
|
||||
GetCodepoint :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
GetCodepointNext :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
GetCodepointPrevious :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
@@ -1667,7 +1667,7 @@ IsGestureDetected :: proc "c" (gesture: Gesture) -> bool {
|
||||
|
||||
|
||||
// Text formatting with variables (sprintf style)
|
||||
TextFormat :: proc(text: cstring, args: ..any) -> cstring {
|
||||
TextFormat :: proc(text: cstring, args: ..any) -> cstring {
|
||||
@static buffers: [MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH]byte
|
||||
@static index: u32
|
||||
|
||||
@@ -1683,7 +1683,7 @@ TextFormat :: proc(text: cstring, args: ..any) -> cstring {
|
||||
}
|
||||
|
||||
// Text formatting with variables (sprintf style) and allocates (must be freed with 'MemFree')
|
||||
TextFormatAlloc :: proc(text: cstring, args: ..any) -> cstring {
|
||||
TextFormatAlloc :: proc(text: cstring, args: ..any) -> cstring {
|
||||
str := fmt.tprintf(string(text), ..args)
|
||||
return strings.clone_to_cstring(str, MemAllocator())
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -22,7 +22,7 @@ PIXELTYPE_ARRAYU8 :: 7
|
||||
PIXELTYPE_ARRAYU16 :: 8
|
||||
PIXELTYPE_ARRAYU32 :: 9
|
||||
PIXELTYPE_ARRAYF16 :: 10
|
||||
PIXELTYPE_ARRAYF3 :: 11
|
||||
PIXELTYPE_ARRAYF32 :: 11
|
||||
|
||||
BITMAPORDER_NONE :: 0
|
||||
BITMAPORDER_4321 :: 1
|
||||
@@ -47,7 +47,7 @@ ARRAYORDER_RGBA :: 2
|
||||
ARRAYORDER_ARGB :: 3
|
||||
ARRAYORDER_BGR :: 4
|
||||
ARRAYORDER_BGRA :: 5
|
||||
ARRAYORDER_ABG :: 6
|
||||
ARRAYORDER_ABGR :: 6
|
||||
|
||||
PACKEDLAYOUT_NONE :: 0
|
||||
PACKEDLAYOUT_332 :: 1
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+4
@@ -6,6 +6,10 @@ else
|
||||
all: unix
|
||||
endif
|
||||
|
||||
wasm:
|
||||
mkdir -p ../lib
|
||||
clang -c -Os --target=wasm32 -nostdlib stb_truetype_wasm.c -o ../lib/stb_truetype_wasm.o
|
||||
|
||||
unix:
|
||||
mkdir -p ../lib
|
||||
$(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c
|
||||
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
#include <stddef.h>
|
||||
|
||||
void *stbtt_malloc(size_t size);
|
||||
void stbtt_free(void *ptr);
|
||||
|
||||
void stbtt_qsort(void* base, size_t num, size_t size, int (*compare)(const void*, const void*));
|
||||
|
||||
double stbtt_floor(double x);
|
||||
double stbtt_ceil(double x);
|
||||
double stbtt_sqrt(double x);
|
||||
double stbtt_pow(double x, double y);
|
||||
double stbtt_fmod(double x, double y);
|
||||
double stbtt_cos(double x);
|
||||
double stbtt_acos(double x);
|
||||
double stbtt_fabs(double x);
|
||||
|
||||
unsigned long stbtt_strlen(const char *str);
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t count);
|
||||
void *memset(void *dst, int x, size_t count);
|
||||
|
||||
#define STBRP_SORT stbtt_qsort
|
||||
#define STBRP_ASSERT(condition) ((void)0)
|
||||
|
||||
#define STBTT_malloc(x,u) ((void)(u),stbtt_malloc(x))
|
||||
#define STBTT_free(x,u) ((void)(u),stbtt_free(x))
|
||||
|
||||
#define STBTT_assert(condition) ((void)0)
|
||||
|
||||
#define STBTT_ifloor(x) ((int) stbtt_floor(x))
|
||||
#define STBTT_iceil(x) ((int) stbtt_ceil(x))
|
||||
#define STBTT_sqrt(x) stbtt_sqrt(x)
|
||||
#define STBTT_pow(x,y) stbtt_pow(x,y)
|
||||
#define STBTT_fmod(x,y) stbtt_fmod(x,y)
|
||||
#define STBTT_cos(x) stbtt_cos(x)
|
||||
#define STBTT_acos(x) stbtt_acos(x)
|
||||
#define STBTT_fabs(x) stbtt_fabs(x)
|
||||
#define STBTT_strlen(x) stbtt_strlen(x)
|
||||
#define STBTT_memcpy memcpy
|
||||
#define STBTT_memset memset
|
||||
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
+3
-1
@@ -17,6 +17,8 @@ when LIB != "" {
|
||||
}
|
||||
|
||||
foreign import stbtt { LIB }
|
||||
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
|
||||
foreign import stbtt "../lib/stb_truetype_wasm.o"
|
||||
} else {
|
||||
foreign import stbtt "system:stb_truetype"
|
||||
}
|
||||
@@ -566,7 +568,7 @@ foreign stbtt {
|
||||
// some of the values for the IDs are below; for more see the truetype spec:
|
||||
// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
|
||||
// http://www.microsoft.com/typography/otspec/name.htm
|
||||
GetFontNameString :: proc(font: ^fontinfo, length: c.int, platformID: PLATFORM_ID, encodingID, languageID, nameID: c.int) -> cstring ---
|
||||
GetFontNameString :: proc(font: ^fontinfo, length: ^c.int, platformID: PLATFORM_ID, encodingID, languageID, nameID: c.int) -> cstring ---
|
||||
}
|
||||
|
||||
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
//+build wasm32, wasm64p32
|
||||
package stb_truetype
|
||||
|
||||
import "base:builtin"
|
||||
import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
|
||||
import "core:c"
|
||||
import "core:math"
|
||||
import "core:slice"
|
||||
import "core:sort"
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_malloc")
|
||||
malloc :: proc "c" (size: uint) -> rawptr {
|
||||
context = runtime.default_context()
|
||||
ptr, _ := runtime.mem_alloc_non_zeroed(int(size))
|
||||
return raw_data(ptr)
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_free")
|
||||
free :: proc "c" (ptr: rawptr) {
|
||||
context = runtime.default_context()
|
||||
builtin.free(ptr)
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_qsort")
|
||||
qsort :: proc "c" (base: rawptr, num: uint, size: uint, cmp: proc "c" (a, b: rawptr) -> i32) {
|
||||
context = runtime.default_context()
|
||||
|
||||
Inputs :: struct {
|
||||
base: rawptr,
|
||||
num: uint,
|
||||
size: uint,
|
||||
cmp: proc "c" (a, b: rawptr) -> i32,
|
||||
}
|
||||
|
||||
sort.sort({
|
||||
collection = &Inputs{base, num, size, cmp},
|
||||
len = proc(it: sort.Interface) -> int {
|
||||
inputs := (^Inputs)(it.collection)
|
||||
return int(inputs.num)
|
||||
},
|
||||
less = proc(it: sort.Interface, i, j: int) -> bool {
|
||||
inputs := (^Inputs)(it.collection)
|
||||
a := rawptr(uintptr(inputs.base) + (uintptr(i) * uintptr(inputs.size)))
|
||||
b := rawptr(uintptr(inputs.base) + (uintptr(j) * uintptr(inputs.size)))
|
||||
return inputs.cmp(a, b) < 0
|
||||
},
|
||||
swap = proc(it: sort.Interface, i, j: int) {
|
||||
inputs := (^Inputs)(it.collection)
|
||||
|
||||
a := rawptr(uintptr(inputs.base) + (uintptr(i) * uintptr(inputs.size)))
|
||||
b := rawptr(uintptr(inputs.base) + (uintptr(j) * uintptr(inputs.size)))
|
||||
|
||||
slice.ptr_swap_non_overlapping(a, b, int(inputs.size))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_floor")
|
||||
floor :: proc "c" (x: f64) -> f64 { return math.floor(x) }
|
||||
@(require, linkage="strong", link_name="stbtt_ceil")
|
||||
ceil :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
|
||||
@(require, linkage="strong", link_name="stbtt_sqrt")
|
||||
sqrt :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
|
||||
@(require, linkage="strong", link_name="stbtt_pow")
|
||||
pow :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_fmod")
|
||||
fmod :: proc "c" (x, y: f64) -> f64 {
|
||||
context = runtime.default_context()
|
||||
// NOTE: only called in the `stbtt_GetGlyphSDF` code path.
|
||||
panic("`math.round` is broken on 32 bit targets, see #3856")
|
||||
}
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_cos")
|
||||
cos :: proc "c" (x: f64) -> f64 { return math.cos(x) }
|
||||
@(require, linkage="strong", link_name="stbtt_acos")
|
||||
acos :: proc "c" (x: f64) -> f64 { return math.acos(x) }
|
||||
@(require, linkage="strong", link_name="stbtt_fabs")
|
||||
fabs :: proc "c" (x: f64) -> f64 { return math.abs(x) }
|
||||
|
||||
@(require, linkage="strong", link_name="stbtt_strlen")
|
||||
strlen :: proc "c" (str: cstring) -> c.ulong { return c.ulong(len(str)) }
|
||||
|
||||
// NOTE: defined in runtime.
|
||||
// void *memcpy(void *dst, const void *src, size_t count);
|
||||
// void *memset(void *dst, int x, size_t count);
|
||||
Vendored
+1
-1
@@ -247,7 +247,7 @@ BufferDataSlice :: proc "contextless" (target: Enum, slice: $S/[]$E, usage: Enum
|
||||
BufferData(target, len(slice)*size_of(E), raw_data(slice), usage)
|
||||
}
|
||||
BufferSubDataSlice :: proc "contextless" (target: Enum, offset: uintptr, slice: $S/[]$E) {
|
||||
BufferSubData(target, offset, len(slice)*size_of(E), raw_data(slice), usage)
|
||||
BufferSubData(target, offset, len(slice)*size_of(E), raw_data(slice))
|
||||
}
|
||||
|
||||
CompressedTexImage2DSlice :: proc "contextless" (target: Enum, level: i32, internalformat: Enum, width, height: i32, border: i32, slice: $S/[]$E) {
|
||||
|
||||
Vendored
+2
@@ -33,6 +33,7 @@ Event_Kind :: enum u32 {
|
||||
Submit,
|
||||
Blur,
|
||||
Change,
|
||||
HashChange,
|
||||
Select,
|
||||
|
||||
Animation_Start,
|
||||
@@ -112,6 +113,7 @@ event_kind_string := [Event_Kind]string{
|
||||
.Submit = "submit",
|
||||
.Blur = "blur",
|
||||
.Change = "change",
|
||||
.HashChange = "hashchange",
|
||||
.Select = "select",
|
||||
|
||||
.Animation_Start = "animationstart",
|
||||
|
||||
Vendored
+17
-4
@@ -37,12 +37,25 @@ The bindings work on both `-target:js_wasm32` and `-target:js_wasm64p32`.
|
||||
## GLFW Glue
|
||||
|
||||
There is an inner package `glfwglue` that can be used to glue together WGPU and GLFW.
|
||||
It exports one procedure `GetSurface(wgpu.Instance, glfw.WindowHandle) -> glfw.Surface`.
|
||||
It exports one procedure `GetSurface(wgpu.Instance, glfw.WindowHandle) -> wgpu.Surface`.
|
||||
The procedure will call the needed target specific procedures and return a surface configured
|
||||
for the given window.
|
||||
|
||||
To support Wayland on Linux, you need to have GLFW compiled to support it, and use
|
||||
`-define:WGPU_GFLW_GLUE_SUPPORT_WAYLAND=true` to enable the package to check for Wayland.
|
||||
|
||||
Do note that wgpu does not require GLFW, you can use native windows or another windowing library too.
|
||||
For that you can take inspiration from `glfwglue` on glueing them together.
|
||||
|
||||
## SDL2 Glue
|
||||
|
||||
There is an inner package `sdl2glue` that can be used to glue together WGPU and SDL2.
|
||||
It exports one procedure `GetSurface(wgpu.Instance, ^sdl2.Window) -> wgpu.Surface`.
|
||||
The procedure will call the needed target specific procedures and return a surface configured
|
||||
for the given window.
|
||||
|
||||
### Wayland
|
||||
|
||||
GLFW supports Wayland from version 3.4 onwards and only if it is compiled with `-DGLFW_EXPOSE_NATIVE_WAYLAND`.
|
||||
|
||||
Odin links against your system's glfw library (probably installed through a package manager).
|
||||
If that version is lower than 3.4 or hasn't been compiled with the previously mentioned define,
|
||||
you will have to compile glfw from source yourself and adjust the `foreign import` declarations in `vendor:glfw/bindings` to
|
||||
point to it.
|
||||
|
||||
@@ -8,10 +8,10 @@ PAGE_SIZE := 65536
|
||||
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||
|
||||
web/triangle.wasm: $(FILES) ../wgpu.js ../../wasm/js/runtime.js
|
||||
web/triangle.wasm: $(FILES) ../../wgpu.js ../../../wasm/js/runtime.js
|
||||
odin build . \
|
||||
-target:js_wasm32 -out:web/triangle.wasm -o:size \
|
||||
-extra-linker-flags:"--export-table --import-memory --initial-memory=$(INITIAL_MEMORY_BYTES) --max-memory=$(MAX_MEMORY_BYTES)"
|
||||
|
||||
cp ../wgpu.js web/wgpu.js
|
||||
cp ../../wasm/js/runtime.js web/runtime.js
|
||||
cp ../../wgpu.js web/wgpu.js
|
||||
cp ../../../wasm/js/runtime.js web/runtime.js
|
||||
@@ -8,5 +8,5 @@ set /a MAX_MEMORY_BYTES=%MAX_MEMORY_PAGES% * %PAGE_SIZE%
|
||||
|
||||
call odin.exe build . -target:js_wasm32 -out:web/triangle.wasm -o:size -extra-linker-flags:"--export-table --import-memory --initial-memory=%INITIAL_MEMORY_BYTES% --max-memory=%MAX_MEMORY_BYTES%"
|
||||
|
||||
copy "..\wgpu.js" "web\wgpu.js"
|
||||
copy "..\..\wasm\js\runtime.js" "web\runtime.js"
|
||||
copy "..\..\wgpu.js" "web\wgpu.js"
|
||||
copy "..\..\..\wasm\js\runtime.js" "web\runtime.js"
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
FILES := $(wildcard *)
|
||||
|
||||
# NOTE: changing this requires changing the same values in the `web/index.html`.
|
||||
INITIAL_MEMORY_PAGES := 2000
|
||||
MAX_MEMORY_PAGES := 65536
|
||||
|
||||
PAGE_SIZE := 65536
|
||||
INITIAL_MEMORY_BYTES := $(shell expr $(INITIAL_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||
MAX_MEMORY_BYTES := $(shell expr $(MAX_MEMORY_PAGES) \* $(PAGE_SIZE))
|
||||
|
||||
web/triangle.wasm: $(FILES) ../../wgpu.js ../../../wasm/js/runtime.js
|
||||
odin build . \
|
||||
-target:js_wasm32 -out:web/triangle.wasm -o:size \
|
||||
-extra-linker-flags:"--export-table --import-memory --initial-memory=$(INITIAL_MEMORY_BYTES) --max-memory=$(MAX_MEMORY_BYTES)"
|
||||
|
||||
cp ../../wgpu.js web/wgpu.js
|
||||
cp ../../../wasm/js/runtime.js web/runtime.js
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
REM NOTE: changing this requires changing the same values in the `web/index.html`.
|
||||
set INITIAL_MEMORY_PAGES=2000
|
||||
set MAX_MEMORY_PAGES=65536
|
||||
|
||||
set PAGE_SIZE=65536
|
||||
set /a INITIAL_MEMORY_BYTES=%INITIAL_MEMORY_PAGES% * %PAGE_SIZE%
|
||||
set /a MAX_MEMORY_BYTES=%MAX_MEMORY_PAGES% * %PAGE_SIZE%
|
||||
|
||||
call odin.exe build . -target:js_wasm32 -out:web/triangle.wasm -o:size -extra-linker-flags:"--export-table --import-memory --initial-memory=%INITIAL_MEMORY_BYTES% --max-memory=%MAX_MEMORY_BYTES%"
|
||||
|
||||
copy "..\..\wgpu.js" "web\wgpu.js"
|
||||
copy "..\..\..\wasm\js\runtime.js" "web\runtime.js"
|
||||
Vendored
+187
@@ -0,0 +1,187 @@
|
||||
package vendor_wgpu_example_triangle
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
import "core:fmt"
|
||||
|
||||
import "vendor:wgpu"
|
||||
|
||||
State :: struct {
|
||||
ctx: runtime.Context,
|
||||
os: OS,
|
||||
|
||||
instance: wgpu.Instance,
|
||||
surface: wgpu.Surface,
|
||||
adapter: wgpu.Adapter,
|
||||
device: wgpu.Device,
|
||||
config: wgpu.SurfaceConfiguration,
|
||||
queue: wgpu.Queue,
|
||||
module: wgpu.ShaderModule,
|
||||
pipeline_layout: wgpu.PipelineLayout,
|
||||
pipeline: wgpu.RenderPipeline,
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
state: State
|
||||
|
||||
main :: proc() {
|
||||
state.ctx = context
|
||||
|
||||
os_init(&state.os)
|
||||
|
||||
state.instance = wgpu.CreateInstance(nil)
|
||||
if state.instance == nil {
|
||||
panic("WebGPU is not supported")
|
||||
}
|
||||
state.surface = os_get_surface(&state.os, state.instance)
|
||||
|
||||
wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil)
|
||||
|
||||
on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: cstring, userdata: rawptr) {
|
||||
context = state.ctx
|
||||
if status != .Success || adapter == nil {
|
||||
fmt.panicf("request adapter failure: [%v] %s", status, message)
|
||||
}
|
||||
state.adapter = adapter
|
||||
wgpu.AdapterRequestDevice(adapter, nil, on_device)
|
||||
}
|
||||
|
||||
on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: cstring, userdata: rawptr) {
|
||||
context = state.ctx
|
||||
if status != .Success || device == nil {
|
||||
fmt.panicf("request device failure: [%v] %s", status, message)
|
||||
}
|
||||
state.device = device
|
||||
|
||||
width, height := os_get_render_bounds(&state.os)
|
||||
|
||||
state.config = wgpu.SurfaceConfiguration {
|
||||
device = state.device,
|
||||
usage = { .RenderAttachment },
|
||||
format = .BGRA8Unorm,
|
||||
width = width,
|
||||
height = height,
|
||||
presentMode = .Fifo,
|
||||
alphaMode = .Opaque,
|
||||
}
|
||||
wgpu.SurfaceConfigure(state.surface, &state.config)
|
||||
|
||||
state.queue = wgpu.DeviceGetQueue(state.device)
|
||||
|
||||
shader :: `
|
||||
@vertex
|
||||
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
|
||||
let x = f32(i32(in_vertex_index) - 1);
|
||||
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
|
||||
return vec4<f32>(x, y, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main() -> @location(0) vec4<f32> {
|
||||
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
}`
|
||||
|
||||
state.module = wgpu.DeviceCreateShaderModule(state.device, &{
|
||||
nextInChain = &wgpu.ShaderModuleWGSLDescriptor{
|
||||
sType = .ShaderModuleWGSLDescriptor,
|
||||
code = shader,
|
||||
},
|
||||
})
|
||||
|
||||
state.pipeline_layout = wgpu.DeviceCreatePipelineLayout(state.device, &{})
|
||||
state.pipeline = wgpu.DeviceCreateRenderPipeline(state.device, &{
|
||||
layout = state.pipeline_layout,
|
||||
vertex = {
|
||||
module = state.module,
|
||||
entryPoint = "vs_main",
|
||||
},
|
||||
fragment = &{
|
||||
module = state.module,
|
||||
entryPoint = "fs_main",
|
||||
targetCount = 1,
|
||||
targets = &wgpu.ColorTargetState{
|
||||
format = .BGRA8Unorm,
|
||||
writeMask = wgpu.ColorWriteMaskFlags_All,
|
||||
},
|
||||
},
|
||||
primitive = {
|
||||
topology = .TriangleList,
|
||||
|
||||
},
|
||||
multisample = {
|
||||
count = 1,
|
||||
mask = 0xFFFFFFFF,
|
||||
},
|
||||
})
|
||||
|
||||
os_run(&state.os)
|
||||
}
|
||||
}
|
||||
|
||||
resize :: proc "c" () {
|
||||
context = state.ctx
|
||||
|
||||
state.config.width, state.config.height = os_get_render_bounds(&state.os)
|
||||
wgpu.SurfaceConfigure(state.surface, &state.config)
|
||||
}
|
||||
|
||||
frame :: proc "c" (dt: f32) {
|
||||
context = state.ctx
|
||||
|
||||
surface_texture := wgpu.SurfaceGetCurrentTexture(state.surface)
|
||||
switch surface_texture.status {
|
||||
case .Success:
|
||||
// All good, could check for `surface_texture.suboptimal` here.
|
||||
case .Timeout, .Outdated, .Lost:
|
||||
// Skip this frame, and re-configure surface.
|
||||
if surface_texture.texture != nil {
|
||||
wgpu.TextureRelease(surface_texture.texture)
|
||||
}
|
||||
resize()
|
||||
return
|
||||
case .OutOfMemory, .DeviceLost:
|
||||
// Fatal error
|
||||
fmt.panicf("[triangle] get_current_texture status=%v", surface_texture.status)
|
||||
}
|
||||
defer wgpu.TextureRelease(surface_texture.texture)
|
||||
|
||||
frame := wgpu.TextureCreateView(surface_texture.texture, nil)
|
||||
defer wgpu.TextureViewRelease(frame)
|
||||
|
||||
command_encoder := wgpu.DeviceCreateCommandEncoder(state.device, nil)
|
||||
defer wgpu.CommandEncoderRelease(command_encoder)
|
||||
|
||||
render_pass_encoder := wgpu.CommandEncoderBeginRenderPass(
|
||||
command_encoder, &{
|
||||
colorAttachmentCount = 1,
|
||||
colorAttachments = &wgpu.RenderPassColorAttachment{
|
||||
view = frame,
|
||||
loadOp = .Clear,
|
||||
storeOp = .Store,
|
||||
clearValue = { r = 0, g = 1, b = 0, a = 1 },
|
||||
},
|
||||
},
|
||||
)
|
||||
defer wgpu.RenderPassEncoderRelease(render_pass_encoder)
|
||||
|
||||
wgpu.RenderPassEncoderSetPipeline(render_pass_encoder, state.pipeline)
|
||||
wgpu.RenderPassEncoderDraw(render_pass_encoder, vertexCount=3, instanceCount=1, firstVertex=0, firstInstance=0)
|
||||
wgpu.RenderPassEncoderEnd(render_pass_encoder)
|
||||
|
||||
command_buffer := wgpu.CommandEncoderFinish(command_encoder, nil)
|
||||
defer wgpu.CommandBufferRelease(command_buffer)
|
||||
|
||||
wgpu.QueueSubmit(state.queue, { command_buffer })
|
||||
wgpu.SurfacePresent(state.surface)
|
||||
}
|
||||
|
||||
finish :: proc() {
|
||||
wgpu.RenderPipelineRelease(state.pipeline)
|
||||
wgpu.PipelineLayoutRelease(state.pipeline_layout)
|
||||
wgpu.ShaderModuleRelease(state.module)
|
||||
wgpu.QueueRelease(state.queue)
|
||||
wgpu.DeviceRelease(state.device)
|
||||
wgpu.AdapterRelease(state.adapter)
|
||||
wgpu.SurfaceRelease(state.surface)
|
||||
wgpu.InstanceRelease(state.instance)
|
||||
}
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
package vendor_wgpu_example_triangle
|
||||
|
||||
import "vendor:wgpu"
|
||||
import "vendor:wasm/js"
|
||||
|
||||
OS :: struct {
|
||||
initialized: bool,
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
g_os: ^OS
|
||||
|
||||
os_init :: proc(os: ^OS) {
|
||||
g_os = os
|
||||
assert(js.add_window_event_listener(.Resize, nil, size_callback))
|
||||
}
|
||||
|
||||
// NOTE: frame loop is done by the runtime.js repeatedly calling `step`.
|
||||
os_run :: proc(os: ^OS) {
|
||||
os.initialized = true
|
||||
}
|
||||
|
||||
os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
|
||||
rect := js.get_bounding_client_rect("body")
|
||||
return u32(rect.width), u32(rect.height)
|
||||
}
|
||||
|
||||
os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
|
||||
return wgpu.InstanceCreateSurface(
|
||||
instance,
|
||||
&wgpu.SurfaceDescriptor{
|
||||
nextInChain = &wgpu.SurfaceDescriptorFromCanvasHTMLSelector{
|
||||
sType = .SurfaceDescriptorFromCanvasHTMLSelector,
|
||||
selector = "#wgpu-canvas",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@(private="file", export)
|
||||
step :: proc(dt: f32) -> bool {
|
||||
if !g_os.initialized {
|
||||
return true
|
||||
}
|
||||
|
||||
frame(dt)
|
||||
return true
|
||||
}
|
||||
|
||||
@(private="file", fini)
|
||||
os_fini :: proc() {
|
||||
js.remove_window_event_listener(.Resize, nil, size_callback)
|
||||
|
||||
finish()
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
size_callback :: proc(e: js.Event) {
|
||||
resize()
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
//+build !js
|
||||
package vendor_wgpu_example_triangle
|
||||
|
||||
import "core:c"
|
||||
import "core:fmt"
|
||||
|
||||
import "vendor:sdl2"
|
||||
import "vendor:wgpu"
|
||||
import "vendor:wgpu/sdl2glue"
|
||||
|
||||
OS :: struct {
|
||||
window: ^sdl2.Window,
|
||||
}
|
||||
|
||||
os_init :: proc(os: ^OS) {
|
||||
sdl_flags := sdl2.InitFlags{.VIDEO, .JOYSTICK, .GAMECONTROLLER, .EVENTS}
|
||||
if res := sdl2.Init(sdl_flags); res != 0 {
|
||||
fmt.eprintfln("ERROR: Failed to initialize SDL: [%s]", sdl2.GetError())
|
||||
return
|
||||
}
|
||||
|
||||
window_flags: sdl2.WindowFlags = {.SHOWN, .ALLOW_HIGHDPI, .RESIZABLE}
|
||||
os.window = sdl2.CreateWindow(
|
||||
"WGPU Native Triangle",
|
||||
sdl2.WINDOWPOS_CENTERED,
|
||||
sdl2.WINDOWPOS_CENTERED,
|
||||
960,
|
||||
540,
|
||||
window_flags,
|
||||
)
|
||||
if os.window == nil {
|
||||
fmt.eprintfln("ERROR: Failed to create the SDL Window: [%s]", sdl2.GetError())
|
||||
return
|
||||
}
|
||||
|
||||
sdl2.AddEventWatch(size_callback, nil)
|
||||
}
|
||||
|
||||
os_run :: proc(os: ^OS) {
|
||||
now := sdl2.GetPerformanceCounter()
|
||||
last : u64
|
||||
dt: f32
|
||||
main_loop: for {
|
||||
last = now
|
||||
now = sdl2.GetPerformanceCounter()
|
||||
dt = f32((now - last) * 1000) / f32(sdl2.GetPerformanceFrequency())
|
||||
|
||||
e: sdl2.Event
|
||||
|
||||
for sdl2.PollEvent(&e) {
|
||||
#partial switch (e.type) {
|
||||
case .QUIT:
|
||||
break main_loop
|
||||
}
|
||||
}
|
||||
|
||||
frame(dt)
|
||||
}
|
||||
|
||||
sdl2.DestroyWindow(os.window)
|
||||
sdl2.Quit()
|
||||
|
||||
finish()
|
||||
}
|
||||
|
||||
|
||||
os_get_render_bounds :: proc(os: ^OS) -> (width, height: u32) {
|
||||
iw, ih: c.int
|
||||
sdl2.GetWindowSize(os.window, &iw, &ih)
|
||||
return u32(iw), u32(ih)
|
||||
}
|
||||
|
||||
os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface {
|
||||
return sdl2glue.GetSurface(instance, os.window)
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
size_callback :: proc "c" (userdata: rawptr, event: ^sdl2.Event) -> c.int {
|
||||
if event.type == .WINDOWEVENT {
|
||||
if event.window.event == .SIZE_CHANGED || event.window.event == .RESIZED {
|
||||
resize()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" style="height: 100%;">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>WGPU WASM Triangle</title>
|
||||
</head>
|
||||
<body id="body" style="height: 100%; padding: 0; margin: 0; overflow: hidden;">
|
||||
<canvas id="wgpu-canvas"></canvas>
|
||||
|
||||
<script type="text/javascript" src="runtime.js"></script>
|
||||
<script type="text/javascript" src="wgpu.js"></script>
|
||||
<script type="text/javascript">
|
||||
const mem = new WebAssembly.Memory({ initial: 2000, maximum: 65536, shared: false });
|
||||
const memInterface = new odin.WasmMemoryInterface();
|
||||
memInterface.setMemory(mem);
|
||||
|
||||
const wgpuInterface = new odin.WebGPUInterface(memInterface);
|
||||
|
||||
odin.runWasm("triangle.wasm", null, { wgpu: wgpuInterface.getInterface() }, memInterface, /*intSize=8*/);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+5
-4
@@ -3,11 +3,8 @@ package wgpu_glfw_glue
|
||||
import "vendor:glfw"
|
||||
import "vendor:wgpu"
|
||||
|
||||
// GLFW needs to be compiled with wayland support for this to work.
|
||||
SUPPORT_WAYLAND :: #config(WGPU_GFLW_GLUE_SUPPORT_WAYLAND, false)
|
||||
|
||||
GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.Surface {
|
||||
when SUPPORT_WAYLAND {
|
||||
if glfw.GetPlatform != nil {
|
||||
if glfw.GetPlatform() == glfw.PLATFORM_WAYLAND {
|
||||
display := glfw.GetWaylandDisplay()
|
||||
surface := glfw.GetWaylandWindow(window)
|
||||
@@ -24,6 +21,10 @@ GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.S
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if glfw.GetPlatform() != glfw.PLATFORM_X11 {
|
||||
panic("wgpu glfw glue: unsupported platform, expected Wayland or X11")
|
||||
}
|
||||
}
|
||||
|
||||
display := glfw.GetX11Display()
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
//+build !linux
|
||||
//+build !windows
|
||||
//+build !darwin
|
||||
package wgpu_sdl2_glue
|
||||
|
||||
#panic("package wgpu/sdl2glue is not supported on the current target")
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package wgpu_sdl2_glue
|
||||
|
||||
import "vendor:sdl2"
|
||||
import "vendor:wgpu"
|
||||
import CA "vendor:darwin/QuartzCore"
|
||||
import NS "core:sys/darwin/Foundation"
|
||||
|
||||
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||
window_info: sdl2.SysWMinfo
|
||||
sdl2.GetWindowWMInfo(window, &window_info)
|
||||
ns_window := cast(^NS.Window)window_info.info.cocoa.window
|
||||
metal_layer := CA.MetalLayer_layer()
|
||||
ns_window->contentView()->setLayer(metal_layer)
|
||||
return wgpu.InstanceCreateSurface(
|
||||
instance,
|
||||
&wgpu.SurfaceDescriptor{
|
||||
nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{
|
||||
chain = wgpu.ChainedStruct{
|
||||
sType = .SurfaceDescriptorFromMetalLayer,
|
||||
},
|
||||
layer = rawptr(metal_layer),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
package wgpu_sdl2_glue
|
||||
|
||||
import "vendor:sdl2"
|
||||
import "vendor:wgpu"
|
||||
|
||||
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||
window_info: sdl2.SysWMinfo
|
||||
sdl2.GetWindowWMInfo(window, &window_info)
|
||||
if window_info.subsystem == .WAYLAND {
|
||||
display := window_info.info.wl.display
|
||||
surface := window_info.info.wl.surface
|
||||
return wgpu.InstanceCreateSurface(
|
||||
instance,
|
||||
&wgpu.SurfaceDescriptor{
|
||||
nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{
|
||||
chain = {
|
||||
sType = .SurfaceDescriptorFromWaylandSurface,
|
||||
},
|
||||
display = display,
|
||||
surface = surface,
|
||||
},
|
||||
},
|
||||
)
|
||||
} else if window_info.subsystem == .X11 {
|
||||
display := window_info.info.x11.display
|
||||
window := window_info.info.x11.window
|
||||
return wgpu.InstanceCreateSurface(
|
||||
instance,
|
||||
&wgpu.SurfaceDescriptor{
|
||||
nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{
|
||||
chain = {
|
||||
sType = .SurfaceDescriptorFromXlibWindow,
|
||||
},
|
||||
display = display,
|
||||
window = u64(window),
|
||||
},
|
||||
},
|
||||
)
|
||||
} else {
|
||||
panic("wgpu sdl2 glue: unsupported platform, expected Wayland or X11")
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package wgpu_sdl2_glue
|
||||
|
||||
import win "core:sys/windows"
|
||||
|
||||
import "vendor:sdl2"
|
||||
import "vendor:wgpu"
|
||||
|
||||
GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surface {
|
||||
window_info: sdl2.SysWMinfo
|
||||
sdl2.GetWindowWMInfo(window, &window_info)
|
||||
hwnd := window_info.info.win.window
|
||||
hinstance := win.GetModuleHandleW(nil)
|
||||
return wgpu.InstanceCreateSurface(
|
||||
instance,
|
||||
&wgpu.SurfaceDescriptor{
|
||||
nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND{
|
||||
chain = wgpu.ChainedStruct{
|
||||
sType = .SurfaceDescriptorFromWindowsHWND,
|
||||
},
|
||||
hinstance = rawptr(hinstance),
|
||||
hwnd = rawptr(hwnd),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
Vendored
+71
-6
@@ -716,12 +716,7 @@ BufferDescriptor :: struct {
|
||||
mappedAtCreation: b32,
|
||||
}
|
||||
|
||||
Color :: struct {
|
||||
r: f64,
|
||||
g: f64,
|
||||
b: f64,
|
||||
a: f64,
|
||||
}
|
||||
Color :: [4]f64
|
||||
|
||||
CommandBufferDescriptor :: struct {
|
||||
nextInChain: ^ChainedStruct,
|
||||
@@ -1636,3 +1631,73 @@ SurfaceGetCurrentTexture :: proc(surface: Surface) -> (surface_texture: SurfaceT
|
||||
RawSurfaceGetCurrentTexture(surface, &surface_texture)
|
||||
return
|
||||
}
|
||||
|
||||
// WGPU Native bindings
|
||||
|
||||
BINDINGS_VERSION :: [4]u8{0, 19, 4, 1}
|
||||
BINDINGS_VERSION_STRING :: "0.19.4.1"
|
||||
|
||||
when ODIN_OS != .JS {
|
||||
@(private="file", init)
|
||||
wgpu_native_version_check :: proc() {
|
||||
v := (transmute([4]u8)GetVersion()).wzyx
|
||||
|
||||
if v != BINDINGS_VERSION {
|
||||
buf: [1024]byte
|
||||
n := copy(buf[:], "wgpu-native version mismatch: ")
|
||||
n += copy(buf[n:], "bindings are for version ")
|
||||
n += copy(buf[n:], BINDINGS_VERSION_STRING)
|
||||
n += copy(buf[n:], ", but a different version is linked")
|
||||
panic(string(buf[:n]))
|
||||
}
|
||||
}
|
||||
|
||||
@(link_prefix="wgpu")
|
||||
foreign libwgpu {
|
||||
@(link_name="wgpuGenerateReport")
|
||||
RawGenerateReport :: proc(instance: Instance, report: ^GlobalReport) ---
|
||||
@(link_name="wgpuInstanceEnumerateAdapters")
|
||||
RawInstanceEnumerateAdapters :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^InstanceEnumerateAdapterOptions, adapters: [^]Adapter) -> uint ---
|
||||
|
||||
@(link_name="wgpuQueueSubmitForIndex")
|
||||
RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex ---
|
||||
|
||||
// Returns true if the queue is empty, or false if there are more queue submissions still in flight.
|
||||
DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex = nil) -> b32 ---
|
||||
|
||||
SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) ---
|
||||
|
||||
SetLogLevel :: proc(level: LogLevel) ---
|
||||
|
||||
GetVersion :: proc() -> u32 ---
|
||||
|
||||
RenderPassEncoderSetPushConstants :: proc(encoder: RenderPassEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: rawptr) ---
|
||||
|
||||
RenderPassEncoderMultiDrawIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||
RenderPassEncoderMultiDrawIndexedIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||
|
||||
RenderPassEncoderMultiDrawIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||
RenderPassEncoderMultiDrawIndexedIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||
|
||||
ComputePassEncoderBeginPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||
ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder) ---
|
||||
RenderPassEncoderBeginPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||
RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder) ---
|
||||
}
|
||||
|
||||
GenerateReport :: proc(instance: Instance) -> (report: GlobalReport) {
|
||||
RawGenerateReport(instance, &report)
|
||||
return
|
||||
}
|
||||
|
||||
InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerateAdapterOptions = nil, allocator := context.allocator) -> (adapters: []Adapter) {
|
||||
count := RawInstanceEnumerateAdapters(instance, options, nil)
|
||||
adapters = make([]Adapter, count, allocator)
|
||||
RawInstanceEnumerateAdapters(instance, options, raw_data(adapters))
|
||||
return
|
||||
}
|
||||
|
||||
QueueSubmitForIndex :: proc(queue: Queue, commands: []CommandBuffer) -> SubmissionIndex {
|
||||
return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands))
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -22,5 +22,6 @@ wgpu_alloc :: proc "contextless" (size: i32) -> [^]byte {
|
||||
@(private="file", export)
|
||||
wgpu_free :: proc "contextless" (ptr: rawptr) {
|
||||
context = g_context
|
||||
assert(free(ptr) == nil, "wgpu_free failed")
|
||||
err := free(ptr)
|
||||
assert(err == nil, "wgpu_free failed")
|
||||
}
|
||||
|
||||
Vendored
-68
@@ -1,68 +0,0 @@
|
||||
//+build !js
|
||||
package wgpu
|
||||
|
||||
BINDINGS_VERSION :: [4]u8{0, 19, 4, 1}
|
||||
BINDINGS_VERSION_STRING :: "0.19.4.1"
|
||||
|
||||
@(private="file", init)
|
||||
wgpu_native_version_check :: proc() {
|
||||
v := (transmute([4]u8)GetVersion()).wzyx
|
||||
|
||||
if v != BINDINGS_VERSION {
|
||||
buf: [1024]byte
|
||||
n := copy(buf[:], "wgpu-native version mismatch: ")
|
||||
n += copy(buf[n:], "bindings are for version ")
|
||||
n += copy(buf[n:], BINDINGS_VERSION_STRING)
|
||||
n += copy(buf[n:], ", but a different version is linked")
|
||||
panic(string(buf[:n]))
|
||||
}
|
||||
}
|
||||
|
||||
@(link_prefix="wgpu")
|
||||
foreign {
|
||||
@(link_name="wgpuGenerateReport")
|
||||
RawGenerateReport :: proc(instance: Instance, report: ^GlobalReport) ---
|
||||
@(link_name="wgpuInstanceEnumerateAdapters")
|
||||
RawInstanceEnumerateAdapters :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^InstanceEnumerateAdapterOptions, adapters: [^]Adapter) -> uint ---
|
||||
|
||||
@(link_name="wgpuQueueSubmitForIndex")
|
||||
RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex ---
|
||||
|
||||
// Returns true if the queue is empty, or false if there are more queue submissions still in flight.
|
||||
DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex = nil) -> b32 ---
|
||||
|
||||
SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) ---
|
||||
|
||||
SetLogLevel :: proc(level: LogLevel) ---
|
||||
|
||||
GetVersion :: proc() -> u32 ---
|
||||
|
||||
RenderPassEncoderSetPushConstants :: proc(encoder: RenderPassEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: cstring) ---
|
||||
|
||||
RenderPassEncoderMultiDrawIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||
RenderPassEncoderMultiDrawIndexedIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) ---
|
||||
|
||||
RenderPassEncoderMultiDrawIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||
RenderPassEncoderMultiDrawIndexedIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) ---
|
||||
|
||||
ComputePassEncoderBeginPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||
ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder) ---
|
||||
RenderPassEncoderBeginPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) ---
|
||||
RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder) ---
|
||||
}
|
||||
|
||||
GenerateReport :: proc(instance: Instance) -> (report: GlobalReport) {
|
||||
RawGenerateReport(instance, &report)
|
||||
return
|
||||
}
|
||||
|
||||
InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerateAdapterOptions = nil, allocator := context.allocator) -> (adapters: []Adapter) {
|
||||
count := RawInstanceEnumerateAdapters(instance, options, nil)
|
||||
adapters = make([]Adapter, count, allocator)
|
||||
RawInstanceEnumerateAdapters(instance, options, raw_data(adapters))
|
||||
return
|
||||
}
|
||||
|
||||
QueueSubmitForIndex :: proc(queue: Queue, commands: []CommandBuffer) -> SubmissionIndex {
|
||||
return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands))
|
||||
}
|
||||
Vendored
+74
@@ -1,6 +1,80 @@
|
||||
//+build linux, freebsd, openbsd
|
||||
package xlib
|
||||
|
||||
/* ---- X11/extensions/XKB.h ---------------------------------------------------------*/
|
||||
|
||||
XkbMinLegalKeyCode :: 8
|
||||
XkbMaxLegalKeyCode :: 255
|
||||
XkbMaxKeyCount :: XkbMaxLegalKeyCode - XkbMinLegalKeyCode + 1
|
||||
XkbPerKeyBitArraySize :: (XkbMaxLegalKeyCode + 1) / 8
|
||||
XkbKeyNameLength :: 4
|
||||
XkbNumVirtualMods :: 16
|
||||
XkbNumIndicators :: 32
|
||||
XkbNumKbdGroups :: 4
|
||||
XkbAnyActionDataSize :: 7
|
||||
XkbUseCoreKbd :: 0x0100
|
||||
XkbActionMessageLength :: 6
|
||||
|
||||
XkbInfoMask :: bit_set[XkbInfoMaskBits; int]
|
||||
XkbInfoMaskBits :: enum u32 {
|
||||
KeyTypes = 0,
|
||||
KeySyms = 1,
|
||||
ModifierMap = 2,
|
||||
ExplicitComponents = 3,
|
||||
KeyActions = 4,
|
||||
KeyBehaviors = 5,
|
||||
VirtualMods = 6,
|
||||
VirtualModMap = 7,
|
||||
}
|
||||
|
||||
XkbAllClientInfoMask :: XkbInfoMask {
|
||||
.KeyTypes,
|
||||
.KeySyms,
|
||||
.ModifierMap,
|
||||
}
|
||||
|
||||
XkbAllServerInfoMask :: XkbInfoMask {
|
||||
.ExplicitComponents,
|
||||
.KeyActions,
|
||||
.KeyBehaviors,
|
||||
.VirtualMods,
|
||||
.VirtualModMap,
|
||||
}
|
||||
|
||||
XkbEventMask :: bit_set[XkbEventType; int]
|
||||
XkbEventType :: enum i32 {
|
||||
NewKeyboardNotify = 0,
|
||||
MapNotify = 1,
|
||||
StateNotify = 2,
|
||||
ControlsNotify = 3,
|
||||
IndicatorStateNotify = 4,
|
||||
IndicatorMapNotify = 5,
|
||||
NamesNotify = 6,
|
||||
CompatMapNotify = 7,
|
||||
BellNotify = 8,
|
||||
ActionMessage = 9,
|
||||
AccessXNotify = 10,
|
||||
ExtensionDeviceNotify = 11,
|
||||
}
|
||||
|
||||
XkbAllEventsMask :: XkbEventMask {
|
||||
.NewKeyboardNotify,
|
||||
.MapNotify,
|
||||
.StateNotify,
|
||||
.ControlsNotify,
|
||||
.IndicatorStateNotify,
|
||||
.IndicatorMapNotify,
|
||||
.NamesNotify,
|
||||
.CompatMapNotify,
|
||||
.BellNotify,
|
||||
.ActionMessage,
|
||||
.AccessXNotify,
|
||||
.ExtensionDeviceNotify,
|
||||
}
|
||||
|
||||
|
||||
/* ---- X11/Xlib.h ---------------------------------------------------------*/
|
||||
|
||||
// Special values for many types. Most of these constants
|
||||
// aren't attached to a specific type.
|
||||
|
||||
|
||||
Vendored
+59
-4
@@ -49,7 +49,7 @@ foreign xlib {
|
||||
DisplayString :: proc(display: ^Display) -> cstring ---
|
||||
// Display macros (defaults)
|
||||
DefaultColormap :: proc(display: ^Display, screen_no: i32) -> Colormap ---
|
||||
DefaultDepth :: proc(display: ^Display) -> i32 ---
|
||||
DefaultDepth :: proc(display: ^Display, screen_no: i32) -> i32 ---
|
||||
DefaultGC :: proc(display: ^Display, screen_no: i32) -> GC ---
|
||||
DefaultRootWindow :: proc(display: ^Display) -> Window ---
|
||||
DefaultScreen :: proc(display: ^Display) -> i32 ---
|
||||
@@ -79,7 +79,7 @@ foreign xlib {
|
||||
DoesBackingStore :: proc(screen: ^Screen) -> BackingStore ---
|
||||
DoesSaveUnders :: proc(screen: ^Screen) -> b32 ---
|
||||
DisplayOfScreen :: proc(screen: ^Screen) -> ^Display ---
|
||||
ScreenNumberOfScreens :: proc(screen: ^Screen) -> i32 ---
|
||||
ScreenNumberOfScreen :: proc(screen: ^Screen) -> i32 ---
|
||||
EventMaskOfScreen :: proc(screen: ^Screen) -> EventMask ---
|
||||
WidthOfScreen :: proc(screen: ^Screen) -> i32 ---
|
||||
HeightOfScreen :: proc(screen: ^Screen) -> i32 ---
|
||||
@@ -138,8 +138,8 @@ foreign xlib {
|
||||
width: u32,
|
||||
height: u32,
|
||||
bordersz: u32,
|
||||
border: int,
|
||||
bg: int,
|
||||
border: uint,
|
||||
bg: uint,
|
||||
) -> Window ---
|
||||
DestroyWindow :: proc(display: ^Display, window: Window) ---
|
||||
DestroySubwindows :: proc(display: ^Display, window: Window) ---
|
||||
@@ -1637,6 +1637,13 @@ foreign xlib {
|
||||
wm_hints: ^XWMHints,
|
||||
class_hints: ^XClassHint,
|
||||
) ---
|
||||
OpenIM :: proc(
|
||||
display: ^Display,
|
||||
rdb: XrmHashBucket,
|
||||
res_name: cstring,
|
||||
res_class: cstring,
|
||||
) -> XIM ---
|
||||
SetLocaleModifiers :: proc(modifiers: cstring) -> cstring ---
|
||||
}
|
||||
|
||||
@(default_calling_convention="c")
|
||||
@@ -1938,4 +1945,52 @@ foreign xlib {
|
||||
XrmInitialize :: proc() ---
|
||||
XrmGetStringDatabase :: proc(data: cstring) -> XrmDatabase ---
|
||||
XrmGetResource :: proc(db: XrmDatabase, name: cstring, class: cstring, type_return: ^cstring, val_return: ^XrmValue) -> b32 ---
|
||||
|
||||
/* ---- X11/XKBlib.h ---------------------------------------------------------*/
|
||||
|
||||
XkbQueryExtension :: proc(
|
||||
display: ^Display,
|
||||
opcode_return: ^i32,
|
||||
event_base_return: ^i32,
|
||||
error_base_return: ^i32,
|
||||
major_return: ^i32,
|
||||
minor_return: ^i32,
|
||||
) -> b32 ---
|
||||
XkbUseExtension :: proc(
|
||||
display: ^Display,
|
||||
major_return: ^i32,
|
||||
minor_return: ^i32,
|
||||
) -> b32 ---
|
||||
XkbGetMap :: proc(
|
||||
display: ^Display,
|
||||
which: XkbInfoMask,
|
||||
device_spec: i32,
|
||||
) -> XkbDescPtr ---
|
||||
XkbGetUpdatedMap :: proc(
|
||||
display: ^Display,
|
||||
which: XkbInfoMask,
|
||||
desc: XkbDescPtr,
|
||||
) -> b32 ---
|
||||
XkbSelectEvents :: proc(
|
||||
display: ^Display,
|
||||
deviceID: u32,
|
||||
bits_to_change: XkbEventMask,
|
||||
values: XkbEventMask,
|
||||
) -> b32 ---
|
||||
XkbSetDetectableAutoRepeat :: proc(
|
||||
display: ^Display,
|
||||
detectable: b32,
|
||||
supported: ^b32,
|
||||
) -> b32 ---
|
||||
XkbGetState :: proc (
|
||||
display: ^Display,
|
||||
device_spec: u32,
|
||||
return_state: XkbStatePtr,
|
||||
) -> Status ---
|
||||
XkbGetKeySyms :: proc(
|
||||
display: ^Display,
|
||||
first: u32,
|
||||
num: u32,
|
||||
xkb: XkbDescPtr,
|
||||
) -> Status ---
|
||||
}
|
||||
|
||||
Vendored
+761
@@ -1006,6 +1006,767 @@ XConnectionWatchProc :: #type proc "c" (
|
||||
opening: b32,
|
||||
watch_data: rawptr)
|
||||
|
||||
/* ---- X11/extensions/XKBlib.h ---------------------------------------------------------*/
|
||||
|
||||
XkbAnyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: u32,
|
||||
}
|
||||
|
||||
XkbNewKeyboardNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
old_device: i32,
|
||||
min_key_code: i32,
|
||||
max_key_code: i32,
|
||||
old_min_key_code: i32,
|
||||
old_max_key_code: i32,
|
||||
changed: u32,
|
||||
req_major: i8,
|
||||
req_minor: i8,
|
||||
}
|
||||
|
||||
XkbMapNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed: u32,
|
||||
flags: u32,
|
||||
first_type: i32,
|
||||
num_types: i32,
|
||||
min_key_code: KeyCode,
|
||||
max_key_code: KeyCode,
|
||||
first_key_sym: KeyCode,
|
||||
first_key_act: KeyCode,
|
||||
first_key_behavior: KeyCode,
|
||||
first_key_explicit: KeyCode,
|
||||
first_modmap_key: KeyCode,
|
||||
first_vmodmap_key: KeyCode,
|
||||
num_key_syms: i32,
|
||||
num_key_acts: i32,
|
||||
num_key_behaviors: i32,
|
||||
num_key_explicit: i32,
|
||||
num_modmap_keys: i32,
|
||||
num_vmodmap_keys: i32,
|
||||
vmods: u32,
|
||||
}
|
||||
|
||||
XkbStateNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed: u32,
|
||||
group: i32,
|
||||
base_group: i32,
|
||||
latched_group: i32,
|
||||
locked_group: i32,
|
||||
mods: u32,
|
||||
base_mods: u32,
|
||||
latched_mods: u32,
|
||||
locked_mods: u32,
|
||||
compat_state: i32,
|
||||
grab_mods: u8,
|
||||
compat_grab_mods: u8,
|
||||
lookup_mods: u8,
|
||||
compat_lookup_mods: u8,
|
||||
ptr_buttons: i32,
|
||||
keycode: KeyCode,
|
||||
event_type: i8, // should be EventType but needs to be i8 instead of i32
|
||||
req_major: i8,
|
||||
req_minor: i8,
|
||||
}
|
||||
|
||||
XkbControlsNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed_ctrls: u32,
|
||||
enabled_ctrls: u32,
|
||||
enabled_ctrls_changes: u32,
|
||||
num_groups: i32,
|
||||
keycode: KeyCode,
|
||||
event_type: i8,
|
||||
req_major: i8,
|
||||
req_minor: i8,
|
||||
}
|
||||
|
||||
XkbIndicatorNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed: u32,
|
||||
state: u32,
|
||||
}
|
||||
|
||||
XkbNamesNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed: u32,
|
||||
first_type: i32,
|
||||
num_types: i32,
|
||||
first_lvl: i32,
|
||||
num_lvls: i32,
|
||||
num_aliases: i32,
|
||||
num_radio_groups: i32,
|
||||
changed_vmods: u32,
|
||||
changed_groups: u32,
|
||||
changed_indicators: u32,
|
||||
first_key: i32,
|
||||
num_keys: i32,
|
||||
}
|
||||
|
||||
XkbCompatMapNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
changed_groups: u32,
|
||||
first_si: i32,
|
||||
num_si: i32,
|
||||
num_total_si: i32,
|
||||
}
|
||||
|
||||
XkbBellNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
percent: i32,
|
||||
pitch: i32,
|
||||
duration: i32,
|
||||
bell_class: i32,
|
||||
bell_id: i32,
|
||||
name: Atom,
|
||||
window: Window,
|
||||
event_only: b32,
|
||||
}
|
||||
|
||||
XkbActionMessageEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
keycode: KeyCode,
|
||||
press: b32,
|
||||
key_event_follows: b32,
|
||||
group: i32,
|
||||
mods: u32,
|
||||
message: [XkbActionMessageLength+1]i8,
|
||||
}
|
||||
|
||||
XkbAccessXNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
detail: i32,
|
||||
keycode: i32,
|
||||
sk_delay: i32,
|
||||
debounce_delay: i32,
|
||||
}
|
||||
|
||||
XkbExtensionDeviceNotifyEvent :: struct {
|
||||
type: i32,
|
||||
serial: u64,
|
||||
send_event: b32,
|
||||
display: ^Display,
|
||||
time: Time,
|
||||
xkb_type: XkbEventType,
|
||||
device: i32,
|
||||
reason: u32,
|
||||
supported: u32,
|
||||
unsupported: u32,
|
||||
first_btn: i32,
|
||||
num_btns: i32,
|
||||
leds_defined: u32,
|
||||
led_state: u32,
|
||||
led_class: i32,
|
||||
led_id: i32,
|
||||
}
|
||||
|
||||
XkbEvent :: struct #raw_union {
|
||||
type: XkbEventType,
|
||||
any: XkbAnyEvent,
|
||||
new_kbd: XkbNewKeyboardNotifyEvent,
|
||||
_map: XkbMapNotifyEvent,
|
||||
state: XkbStateNotifyEvent,
|
||||
ctrls: XkbControlsNotifyEvent,
|
||||
indicators: XkbIndicatorNotifyEvent,
|
||||
names: XkbNamesNotifyEvent,
|
||||
compat: XkbCompatMapNotifyEvent,
|
||||
bell: XkbBellNotifyEvent,
|
||||
message: XkbActionMessageEvent,
|
||||
accessx: XkbAccessXNotifyEvent,
|
||||
device: XkbExtensionDeviceNotifyEvent,
|
||||
core: XEvent,
|
||||
}
|
||||
|
||||
/* ---- X11/extensions/XKBgeom.h ---------------------------------------------------------*/
|
||||
|
||||
XkbPointRec :: struct {
|
||||
x: i16,
|
||||
y: i16,
|
||||
}
|
||||
XkbPointPtr :: ^XkbPointRec
|
||||
|
||||
XkbBoundsRec :: struct {
|
||||
x1, x2: i16,
|
||||
y1, y2: i16,
|
||||
}
|
||||
XkbBoundsPtr :: ^XkbBoundsRec
|
||||
|
||||
XkbOutlineRec :: struct {
|
||||
num_points: u16,
|
||||
sz_points: u16,
|
||||
corner_radius: u16,
|
||||
points: [^]XkbPointRec,
|
||||
}
|
||||
XkbOutlinePtr :: ^XkbOutlineRec
|
||||
|
||||
XkbShapeRec :: struct {
|
||||
name: Atom,
|
||||
num_outlines: u16,
|
||||
sz_outlines: u16,
|
||||
outlines: [^]XkbOutlineRec,
|
||||
approx: XkbOutlinePtr,
|
||||
primary: XkbOutlinePtr,
|
||||
bounds: XkbBoundsRec,
|
||||
}
|
||||
XkbShapePtr :: ^XkbShapeRec
|
||||
|
||||
XkbPropertyRec :: struct {
|
||||
name: cstring,
|
||||
value: cstring,
|
||||
}
|
||||
XkbPropertyPtr :: ^XkbPropertyRec
|
||||
|
||||
XkbColorRec :: struct {
|
||||
pixel: u32,
|
||||
spec: ^u8, // cstring?
|
||||
}
|
||||
XkbColorPtr :: ^XkbColorRec
|
||||
|
||||
XkbKeyRec :: struct {
|
||||
name: XkbKeyNameRec,
|
||||
gap: i16,
|
||||
shape_ndx: u8,
|
||||
color_ndx: u8,
|
||||
}
|
||||
XkbKeyPtr :: ^XkbKeyRec
|
||||
|
||||
XkbRowRec :: struct {
|
||||
top: i16,
|
||||
left: i16,
|
||||
num_keys: u16,
|
||||
sz_keys: u16,
|
||||
vertical: i32,
|
||||
keys: [^]XkbKeyRec,
|
||||
bounds: XkbBoundsRec,
|
||||
}
|
||||
XkbRowPtr :: ^XkbRowRec
|
||||
|
||||
XkbAnyDoodadRec :: struct {
|
||||
name: Atom,
|
||||
type: u8,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
angle: i16,
|
||||
}
|
||||
XkbAnyDoodadPtr :: ^XkbAnyDoodadRec
|
||||
|
||||
XkbShapeDoodadRec :: struct {
|
||||
name: Atom,
|
||||
type: u8,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
angle: i16,
|
||||
color_ndx: u16,
|
||||
shape_ndx: u16,
|
||||
}
|
||||
XkbShapeDoodadPtr :: ^XkbShapeDoodadRec
|
||||
|
||||
XkbTextDoodadRec :: struct {
|
||||
name: Atom,
|
||||
type: u8,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
angle: i16,
|
||||
color_ndx: u16,
|
||||
text: cstring,
|
||||
font: cstring,
|
||||
}
|
||||
XkbTextDoodadPtr :: ^XkbTextDoodadRec
|
||||
|
||||
XkbIndicatorDoodadRec :: struct {
|
||||
name: Atom,
|
||||
type: u8,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
angle: i16,
|
||||
color_ndx: u16,
|
||||
on_color_ndx: u16,
|
||||
off_color_ndx: u16,
|
||||
}
|
||||
XkbIndicatorDoodadPtr :: ^XkbIndicatorDoodadRec
|
||||
|
||||
XkbLogoDoodadRec :: struct {
|
||||
name: Atom,
|
||||
type: u8,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
angle: i16,
|
||||
color_ndx: u16,
|
||||
shape_ndx: u16,
|
||||
logo_name: cstring,
|
||||
}
|
||||
XkbLogoDoodadPtr :: ^XkbLogoDoodadRec
|
||||
|
||||
XkbDoodadRec :: struct #raw_union {
|
||||
any: XkbAnyDoodadRec,
|
||||
shape: XkbShapeDoodadRec,
|
||||
text: XkbTextDoodadRec,
|
||||
indicator: XkbIndicatorDoodadRec,
|
||||
logo: XkbLogoDoodadRec,
|
||||
}
|
||||
XkbDoodadPtr :: ^XkbDoodadRec
|
||||
|
||||
XkbOverlayKeyRec :: struct {
|
||||
over: XkbKeyNameRec,
|
||||
under: XkbKeyNameRec,
|
||||
}
|
||||
XkbOverlayKeyPtr :: ^XkbOverlayKeyRec
|
||||
|
||||
XkbOverlayRowRec :: struct {
|
||||
row_under: u16,
|
||||
num_keys: u16,
|
||||
sz_keys: u16,
|
||||
keys: [^]XkbOverlayKeyRec,
|
||||
}
|
||||
XkbOverlayRowPtr :: ^XkbOverlayRowRec
|
||||
|
||||
XkbOverlayRec :: struct {
|
||||
name: Atom,
|
||||
section_under: XkbSectionPtr,
|
||||
num_rows: u16,
|
||||
sz_rows: u16,
|
||||
rows: [^]XkbOverlayRowRec,
|
||||
bounds: [^]XkbBoundsRec,
|
||||
}
|
||||
XkbOverlayPtr :: ^XkbOverlayRec
|
||||
|
||||
XkbSectionRec :: struct {
|
||||
name: Atom,
|
||||
priority: u8,
|
||||
top: i16,
|
||||
left: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
angle: i16,
|
||||
num_rows: u16,
|
||||
num_doodads: u16,
|
||||
num_overlays: u16,
|
||||
sz_rows: u16,
|
||||
sz_doodads: u16,
|
||||
sz_overlays: u16,
|
||||
rows: [^]XkbRowRec,
|
||||
doodads: [^]XkbDoodadRec,
|
||||
bounds: XkbBoundsRec,
|
||||
overlays: [^]XkbOverlayRec,
|
||||
}
|
||||
XkbSectionPtr :: ^XkbSectionRec
|
||||
|
||||
XkbGeometryRec :: struct {
|
||||
name: Atom,
|
||||
width_mm: u16,
|
||||
height_mm: u16,
|
||||
label_font: cstring,
|
||||
label_color: XkbColorPtr,
|
||||
base_color: XkbColorPtr,
|
||||
sz_properties: u16,
|
||||
sz_colors: u16,
|
||||
sz_shapes: u16,
|
||||
sz_sections: u16,
|
||||
sz_doodads: u16,
|
||||
sz_key_aliases: u16,
|
||||
num_properties: u16,
|
||||
num_colors: u16,
|
||||
num_shapes: u16,
|
||||
num_sections: u16,
|
||||
num_doodads: u16,
|
||||
num_key_aliases: u16,
|
||||
properties: [^]XkbPropertyRec,
|
||||
colors: [^]XkbColorRec,
|
||||
shapes: [^]XkbShapeRec,
|
||||
sections: [^]XkbSectionRec,
|
||||
doodads: [^]XkbDoodadRec,
|
||||
key_aliases: [^]XkbKeyAliasRec,
|
||||
}
|
||||
XkbGeometryPtr :: ^XkbGeometryRec
|
||||
|
||||
|
||||
/* ---- X11/extensions/XKBstr.h ---------------------------------------------------------*/
|
||||
|
||||
XkbStateRec :: struct {
|
||||
group: u8,
|
||||
locked_group: u8,
|
||||
base_group: u16,
|
||||
latched_group: u16,
|
||||
mods: u8,
|
||||
base_mods: u8,
|
||||
latched_mods: u8,
|
||||
locked_mods: u8,
|
||||
compat_state: u8,
|
||||
grab_mods: u8,
|
||||
compat_grab_mods: u8,
|
||||
lookup_mods: u8,
|
||||
compat_lookup_mods: u8,
|
||||
ptr_buttons: u16,
|
||||
}
|
||||
XkbStatePtr :: ^XkbStateRec
|
||||
|
||||
XkbModsRec :: struct {
|
||||
mask: u8, /* effective mods */
|
||||
real_mods: u8,
|
||||
vmods: u16,
|
||||
}
|
||||
XkbModsPtr :: ^XkbModsRec
|
||||
|
||||
XkbKTMapEntryRec :: struct {
|
||||
active: b32,
|
||||
level: u8,
|
||||
mods: XkbModsRec,
|
||||
}
|
||||
XkbKTMapEntryPtr :: ^XkbKTMapEntryRec
|
||||
|
||||
XkbKeyTypeRec :: struct {
|
||||
mod: XkbModsRec,
|
||||
num_levels: u8,
|
||||
map_count: u8,
|
||||
_map: [^]XkbKTMapEntryRec,
|
||||
preserve: [^]XkbModsRec,
|
||||
name: Atom,
|
||||
level_names: [^]Atom,
|
||||
}
|
||||
XkbKeyTypePtr :: ^XkbKeyTypeRec
|
||||
|
||||
XkbBehavior :: struct {
|
||||
type: u8,
|
||||
data: u8,
|
||||
}
|
||||
|
||||
XkbAnyAction :: struct {
|
||||
type: u8,
|
||||
data: [XkbAnyActionDataSize]u8,
|
||||
}
|
||||
|
||||
XkbModAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
mask: u8,
|
||||
real_mods: u8,
|
||||
vmods1: u8,
|
||||
vmods2: u8,
|
||||
}
|
||||
|
||||
XkbGroupAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
group_XXX: i8,
|
||||
}
|
||||
|
||||
XkbISOAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
mask: u8,
|
||||
real_mods: u8,
|
||||
group_XXX: i8,
|
||||
affect: u8,
|
||||
vmods1: u8,
|
||||
vmods2: u8,
|
||||
}
|
||||
|
||||
XkbPtrAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
high_XXX: u8,
|
||||
low_XXX: u8,
|
||||
high_YYY: u8,
|
||||
low_YYY: u8,
|
||||
}
|
||||
|
||||
XkbPtrBtnAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
count: u8,
|
||||
button: u8,
|
||||
}
|
||||
|
||||
XkbPtrDfltAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
affect: u8,
|
||||
value_XXX: u8,
|
||||
}
|
||||
|
||||
XkbSwitchScreenAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
screenXXX: i8,
|
||||
}
|
||||
|
||||
XkbCtrlsAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
ctrls3: u8,
|
||||
ctrls2: u8,
|
||||
ctrls1: u8,
|
||||
ctrls0: u8,
|
||||
}
|
||||
|
||||
XkbMessageAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
message: [6]u8,
|
||||
}
|
||||
|
||||
XkbRedirectKeyAction :: struct {
|
||||
type: u8,
|
||||
new_key: u8,
|
||||
mods_mask: u8,
|
||||
mods: u8,
|
||||
vmods_mask0: u8,
|
||||
vmods_mask1: u8,
|
||||
vmods0: u8,
|
||||
vmods1: u8,
|
||||
}
|
||||
|
||||
XkbDeviceBtnAction :: struct {
|
||||
type: u8,
|
||||
flags: u8,
|
||||
count: u8,
|
||||
button: u8,
|
||||
device: u8,
|
||||
}
|
||||
|
||||
XkbDeviceValuatorAction :: struct {
|
||||
type: u8,
|
||||
device: u8,
|
||||
v1_what: u8,
|
||||
v1_ndx: u8,
|
||||
v1_value: u8,
|
||||
v2_what: u8,
|
||||
v2_ndx: u8,
|
||||
v2_value: u8,
|
||||
}
|
||||
|
||||
XkbAction :: struct #raw_union {
|
||||
any: XkbAnyAction,
|
||||
mod: XkbModAction,
|
||||
group: XkbGroupAction,
|
||||
iso: XkbISOAction,
|
||||
ptr: XkbPtrAction,
|
||||
btn: XkbPtrBtnAction,
|
||||
dflt: XkbPtrDfltAction,
|
||||
screen: XkbSwitchScreenAction,
|
||||
ctrls: XkbCtrlsAction,
|
||||
msg: XkbMessageAction,
|
||||
redirect: XkbRedirectKeyAction,
|
||||
devbtn: XkbDeviceBtnAction,
|
||||
devval: XkbDeviceValuatorAction,
|
||||
type: u8,
|
||||
}
|
||||
|
||||
XkbControlsRec :: struct {
|
||||
mk_dflt_btn: u8,
|
||||
num_groups: u8,
|
||||
groups_wrap: u8,
|
||||
internal: XkbModsRec,
|
||||
ignore_lock: XkbModsRec,
|
||||
enabled_ctrls: u32,
|
||||
repeat_delay: u16,
|
||||
repeat_interval: u16,
|
||||
slow_keys_delay: u16,
|
||||
debounce_delay: u16,
|
||||
mk_delay: u16,
|
||||
mk_interval: u16,
|
||||
mk_time_to_max: u16,
|
||||
mk_max_speed: u16,
|
||||
mk_curve: i16,
|
||||
ax_options: u16,
|
||||
ax_timeout: u16,
|
||||
axt_opts_mask: u16,
|
||||
axt_opts_values: u16,
|
||||
axt_ctrls_mask: u32,
|
||||
axt_ctrls_values: u32,
|
||||
per_key_repeat: [XkbPerKeyBitArraySize]u8,
|
||||
}
|
||||
XkbControlsPtr :: ^XkbControlsRec
|
||||
|
||||
XkbServerMapRec :: struct {
|
||||
num_acts: u16,
|
||||
size_acts: u16,
|
||||
acts: [^]XkbAction,
|
||||
|
||||
behaviors: [^]XkbBehavior,
|
||||
key_acts: [^]u16,
|
||||
explicit: [^]u8,
|
||||
vmods: [XkbNumVirtualMods]u8,
|
||||
vmodmap: [^]u16,
|
||||
}
|
||||
XkbServerMapPtr :: ^XkbServerMapRec
|
||||
|
||||
XkbSymMapRec :: struct {
|
||||
kt_index: [XkbNumKbdGroups]u8,
|
||||
group_info: u8,
|
||||
width: u8,
|
||||
offset: u16,
|
||||
}
|
||||
XkbSymMapPtr :: ^XkbSymMapRec
|
||||
|
||||
XkbClientMapRec :: struct {
|
||||
size_types: u8,
|
||||
num_types: u8,
|
||||
types: [^]XkbKeyTypeRec,
|
||||
|
||||
size_syms: u16,
|
||||
num_syms: u16,
|
||||
syms: [^]XID, // Keysym
|
||||
key_sym_map: [^]XkbSymMapRec,
|
||||
|
||||
modmap: [^]u8,
|
||||
}
|
||||
XkbClientMapPtr :: ^XkbClientMapRec
|
||||
|
||||
XkbSymInterpretRec :: struct {
|
||||
sym: XID, // KeySym
|
||||
flags: u8,
|
||||
match: u8,
|
||||
mods: u8,
|
||||
virtual_mod: u8,
|
||||
act: XkbAnyAction,
|
||||
}
|
||||
XkbSymInterpretPtr :: ^XkbSymInterpretRec
|
||||
|
||||
XkbCompatMapRec :: struct {
|
||||
sym_interpret: [^]XkbSymInterpretRec,
|
||||
groups: [XkbNumKbdGroups]XkbModsRec,
|
||||
num_si: u16,
|
||||
size_si: u16,
|
||||
}
|
||||
XkbCompatMapPtr :: ^XkbCompatMapRec
|
||||
|
||||
XkbIndicatorMapRec :: struct {
|
||||
flags: u8,
|
||||
which_groups: u8,
|
||||
groups: u8,
|
||||
which_mods: u8,
|
||||
mods: XkbModsRec,
|
||||
ctrls: u32,
|
||||
}
|
||||
XkbIndicatorMapPtr :: ^XkbIndicatorMapRec
|
||||
|
||||
XkbIndicatorRec :: struct {
|
||||
phys_indicators: u64,
|
||||
maps: [XkbNumIndicators]XkbIndicatorMapRec,
|
||||
}
|
||||
XkbIndicatorPtr :: ^XkbIndicatorRec
|
||||
|
||||
XkbKeyNameRec :: struct {
|
||||
name: [XkbKeyNameLength]i8, // Non nul-terminated string
|
||||
}
|
||||
XkbKeyNamePtr :: ^XkbKeyNameRec
|
||||
|
||||
XkbKeyAliasRec :: struct {
|
||||
real: [XkbKeyNameLength]i8, // Non nul-terminated string
|
||||
alias: [XkbKeyNameLength]i8, // Non nul-terminated string
|
||||
}
|
||||
XkbKeyAliasPtr :: ^XkbKeyAliasRec
|
||||
|
||||
XkbNamesRec :: struct {
|
||||
keycodes: Atom,
|
||||
geometry: Atom,
|
||||
symbols: Atom,
|
||||
types: Atom,
|
||||
compat: Atom,
|
||||
vmods: [XkbNumVirtualMods]Atom,
|
||||
indicators: [XkbNumIndicators]Atom,
|
||||
groups: [XkbNumKbdGroups]Atom,
|
||||
keys: [^]XkbKeyNameRec,
|
||||
key_aliases: [^]XkbKeyAliasRec,
|
||||
radio_groups: [^]Atom,
|
||||
phys_symbol: Atom,
|
||||
num_keys: u8,
|
||||
num_key_aliases: u8,
|
||||
num_rg: u16,
|
||||
}
|
||||
XkbNamesPtr :: ^XkbNamesRec
|
||||
|
||||
XkbDescRec :: struct {
|
||||
display: ^Display,
|
||||
flags: u16,
|
||||
device_spec: u16,
|
||||
min_key_code: KeyCode,
|
||||
max_key_code: KeyCode,
|
||||
|
||||
ctrls: XkbControlsPtr,
|
||||
server: XkbServerMapPtr,
|
||||
_map: XkbClientMapPtr,
|
||||
indicators: XkbIndicatorPtr,
|
||||
names: XkbNamesPtr,
|
||||
compat: XkbCompatMapPtr,
|
||||
geom: XkbGeometryPtr,
|
||||
}
|
||||
XkbDescPtr :: ^XkbDescRec
|
||||
|
||||
|
||||
/* ---- X11/Xcms.h ---------------------------------------------------------*/
|
||||
|
||||
XcmsColorFormat :: uint
|
||||
|
||||
Reference in New Issue
Block a user