Merge pull request #1400 from reicast/baka/chdv5_2
Support reading CHDv5
This commit is contained in:
commit
f03219473c
42
core/core.mk
42
core/core.mk
|
@ -1,16 +1,19 @@
|
|||
#LOCAL_PATH:=
|
||||
#LOCAL_PATH:=
|
||||
|
||||
#MFLAGS := -marm -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp
|
||||
#ASFLAGS := -march=armv7-a -mfpu=vfp-d16 -mfloat-abi=softfp
|
||||
#LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common
|
||||
#LDFLAGS := -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common
|
||||
|
||||
RZDCY_SRC_DIR ?= $(call my-dir)
|
||||
|
||||
RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \
|
||||
hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \
|
||||
hw/extdev/ hw/arm/ hw/naomi/ imgread/ linux/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ \
|
||||
deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/
|
||||
deps/libelf/ deps/chdpsr/ arm_emitter/ rend/ reios/ deps/libpng/
|
||||
|
||||
ifdef CHD5_LZMA
|
||||
RZDCY_MODULES += deps/lzma/
|
||||
endif
|
||||
|
||||
ifdef WEBUI
|
||||
RZDCY_MODULES += webui/
|
||||
|
@ -70,7 +73,7 @@ endif
|
|||
RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp))
|
||||
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c))
|
||||
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S))
|
||||
|
||||
|
||||
ifdef FOR_PANDORA
|
||||
RZDCY_CFLAGS := \
|
||||
$(CFLAGS) -c -O3 -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps \
|
||||
|
@ -86,7 +89,7 @@ RZDCY_CFLAGS := \
|
|||
-D_ANDROID -DRELEASE\
|
||||
-frename-registers -fsingle-precision-constant -ffast-math \
|
||||
-ftree-vectorize -fomit-frame-pointer
|
||||
|
||||
|
||||
ifndef NOT_ARM
|
||||
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16
|
||||
RZDCY_CFLAGS += -DTARGET_LINUX_ARMELv7
|
||||
|
@ -111,4 +114,33 @@ ifdef HAS_SOFTREND
|
|||
RZDCY_CFLAGS += -DTARGET_SOFTREND
|
||||
endif
|
||||
|
||||
ifdef CHD5_FLAC
|
||||
RZDCY_MODULES += deps/flac/src/libFLAC/
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/bitmath.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/bitreader.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/cpu.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/crc.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/fixed.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/fixed_intrin_sse2.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/fixed_intrin_ssse3.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/float.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/format.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/lpc.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/lpc_intrin_avx2.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/lpc_intrin_sse2.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/lpc_intrin_sse41.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/lpc_intrin_sse.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/md5.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/memory.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/metadata_iterators.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/metadata_object.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/stream_decoder.c
|
||||
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/window.c
|
||||
|
||||
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include
|
||||
RZDCY_CFLAGS += -DPACKAGE_VERSION=\"1.3.2\" -DFLAC__HAS_OGG=0 -DFLAC__NO_DLL -DHAVE_LROUND -DHAVE_STDINT_H -DHAVE_STDLIB_H -DHAVE_SYS_PARAM_H
|
||||
CFLAGS += -I$(RZDCY_SRC_DIR)/deps/flac/include -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/
|
||||
CFLAGS += -DPACKAGE_VERSION=\"1.3.2\" -DFLAC__HAS_OGG=0 -DFLAC__NO_DLL -DHAVE_LROUND -DHAVE_STDINT_H -DHAVE_STDLIB_H -DHAVE_SYS_PARAM_H
|
||||
endif
|
||||
|
||||
RZDCY_CXXFLAGS := $(RZDCY_CFLAGS) -fno-exceptions -fno-rtti -std=gnu++11
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
bitstream.c
|
||||
|
||||
Helper classes for reading/writing at the bit level.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "bitstream.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/***************************************************************************
|
||||
* INLINE FUNCTIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
int bitstream_overflow(struct bitstream* bitstream) { return ((bitstream->doffset - bitstream->bits / 8) > bitstream->dlength); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
* create_bitstream - constructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
struct bitstream* create_bitstream(const void *src, uint32_t srclength)
|
||||
{
|
||||
struct bitstream* bitstream = (struct bitstream*)malloc(sizeof(struct bitstream));
|
||||
bitstream->buffer = 0;
|
||||
bitstream->bits = 0;
|
||||
bitstream->read = (const uint8_t*)src;
|
||||
bitstream->doffset = 0;
|
||||
bitstream->dlength = srclength;
|
||||
return bitstream;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_peek - fetch the requested number of bits
|
||||
* but don't advance the input pointer
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_peek(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
if (numbits == 0)
|
||||
return 0;
|
||||
|
||||
/* fetch data if we need more */
|
||||
if (numbits > bitstream->bits)
|
||||
{
|
||||
while (bitstream->bits <= 24)
|
||||
{
|
||||
if (bitstream->doffset < bitstream->dlength)
|
||||
bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits);
|
||||
bitstream->doffset++;
|
||||
bitstream->bits += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* return the data */
|
||||
return bitstream->buffer >> (32 - numbits);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_remove - advance the input pointer by the
|
||||
* specified number of bits
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
void bitstream_remove(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
bitstream->buffer <<= numbits;
|
||||
bitstream->bits -= numbits;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------
|
||||
* bitstream_read - fetch the requested number of bits
|
||||
*-----------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_read(struct bitstream* bitstream, int numbits)
|
||||
{
|
||||
uint32_t result = bitstream_peek(bitstream, numbits);
|
||||
bitstream_remove(bitstream, numbits);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* read_offset - return the current read offset
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_read_offset(struct bitstream* bitstream)
|
||||
{
|
||||
uint32_t result = bitstream->doffset;
|
||||
int bits = bitstream->bits;
|
||||
while (bits >= 8)
|
||||
{
|
||||
result--;
|
||||
bits -= 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flush - flush to the nearest byte
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t bitstream_flush(struct bitstream* bitstream)
|
||||
{
|
||||
while (bitstream->bits >= 8)
|
||||
{
|
||||
bitstream->doffset--;
|
||||
bitstream->bits -= 8;
|
||||
}
|
||||
bitstream->bits = bitstream->buffer = 0;
|
||||
return bitstream->doffset;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
bitstream.h
|
||||
|
||||
Helper classes for reading/writing at the bit level.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BITSTREAM_H__
|
||||
#define __BITSTREAM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/* helper class for reading from a bit buffer */
|
||||
struct bitstream
|
||||
{
|
||||
uint32_t buffer; /* current bit accumulator */
|
||||
int bits; /* number of bits in the accumulator */
|
||||
const uint8_t * read; /* read pointer */
|
||||
uint32_t doffset; /* byte offset within the data */
|
||||
uint32_t dlength; /* length of the data */
|
||||
};
|
||||
|
||||
struct bitstream* create_bitstream(const void *src, uint32_t srclength);
|
||||
int bitstream_overflow(struct bitstream* bitstream);
|
||||
uint32_t bitstream_read_offset(struct bitstream* bitstream);
|
||||
|
||||
uint32_t bitstream_read(struct bitstream* bitstream, int numbits);
|
||||
uint32_t bitstream_peek(struct bitstream* bitstream, int numbits);
|
||||
void bitstream_remove(struct bitstream* bitstream, int numbits);
|
||||
uint32_t bitstream_flush(struct bitstream* bitstream);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,412 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
cdrom.c
|
||||
|
||||
Generic MAME CD-ROM utilties - build IDE and SCSI CD-ROMs on top of this
|
||||
|
||||
****************************************************************************
|
||||
|
||||
IMPORTANT:
|
||||
"physical" block addresses are the actual addresses on the emulated CD.
|
||||
"chd" block addresses are the block addresses in the CHD file.
|
||||
Because we pad each track to a 4-frame boundary, these addressing
|
||||
schemes will differ after track 1!
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cdrom.h"
|
||||
|
||||
/***************************************************************************
|
||||
DEBUGGING
|
||||
***************************************************************************/
|
||||
|
||||
/** @brief The verbose. */
|
||||
#define VERBOSE (0)
|
||||
#if VERBOSE
|
||||
|
||||
/**
|
||||
* @def LOG(x) do
|
||||
*
|
||||
* @brief A macro that defines log.
|
||||
*
|
||||
* @param x The void to process.
|
||||
*/
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
/**
|
||||
* @fn void CLIB_DECL logerror(const char *text, ...) ATTR_PRINTF(1,2);
|
||||
*
|
||||
* @brief Logerrors the given text.
|
||||
*
|
||||
* @param text The text.
|
||||
*
|
||||
* @return A CLIB_DECL.
|
||||
*/
|
||||
|
||||
void CLIB_DECL logerror(const char *text, ...) ATTR_PRINTF(1,2);
|
||||
#else
|
||||
|
||||
/**
|
||||
* @def LOG(x);
|
||||
*
|
||||
* @brief A macro that defines log.
|
||||
*
|
||||
* @param x The void to process.
|
||||
*/
|
||||
|
||||
#define LOG(x)
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define SYNC_OFFSET 0x000
|
||||
/** @brief 12 bytes. */
|
||||
#define SYNC_NUM_BYTES 12
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define MODE_OFFSET 0x00f
|
||||
|
||||
/** @brief offset within sector. */
|
||||
#define ECC_P_OFFSET 0x81c
|
||||
/** @brief 2 lots of 86. */
|
||||
#define ECC_P_NUM_BYTES 86
|
||||
/** @brief 24 bytes each. */
|
||||
#define ECC_P_COMP 24
|
||||
|
||||
/** @brief The ECC q offset. */
|
||||
#define ECC_Q_OFFSET (ECC_P_OFFSET + 2 * ECC_P_NUM_BYTES)
|
||||
/** @brief 2 lots of 52. */
|
||||
#define ECC_Q_NUM_BYTES 52
|
||||
/** @brief 43 bytes each. */
|
||||
#define ECC_Q_COMP 43
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* ECC lookup tables pre-calculated tables for ECC data calcs
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint8_t ecclow[256] =
|
||||
{
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
|
||||
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
|
||||
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
|
||||
0x1d, 0x1f, 0x19, 0x1b, 0x15, 0x17, 0x11, 0x13, 0x0d, 0x0f, 0x09, 0x0b, 0x05, 0x07, 0x01, 0x03,
|
||||
0x3d, 0x3f, 0x39, 0x3b, 0x35, 0x37, 0x31, 0x33, 0x2d, 0x2f, 0x29, 0x2b, 0x25, 0x27, 0x21, 0x23,
|
||||
0x5d, 0x5f, 0x59, 0x5b, 0x55, 0x57, 0x51, 0x53, 0x4d, 0x4f, 0x49, 0x4b, 0x45, 0x47, 0x41, 0x43,
|
||||
0x7d, 0x7f, 0x79, 0x7b, 0x75, 0x77, 0x71, 0x73, 0x6d, 0x6f, 0x69, 0x6b, 0x65, 0x67, 0x61, 0x63,
|
||||
0x9d, 0x9f, 0x99, 0x9b, 0x95, 0x97, 0x91, 0x93, 0x8d, 0x8f, 0x89, 0x8b, 0x85, 0x87, 0x81, 0x83,
|
||||
0xbd, 0xbf, 0xb9, 0xbb, 0xb5, 0xb7, 0xb1, 0xb3, 0xad, 0xaf, 0xa9, 0xab, 0xa5, 0xa7, 0xa1, 0xa3,
|
||||
0xdd, 0xdf, 0xd9, 0xdb, 0xd5, 0xd7, 0xd1, 0xd3, 0xcd, 0xcf, 0xc9, 0xcb, 0xc5, 0xc7, 0xc1, 0xc3,
|
||||
0xfd, 0xff, 0xf9, 0xfb, 0xf5, 0xf7, 0xf1, 0xf3, 0xed, 0xef, 0xe9, 0xeb, 0xe5, 0xe7, 0xe1, 0xe3
|
||||
};
|
||||
|
||||
/** @brief The ecchigh[ 256]. */
|
||||
static const uint8_t ecchigh[256] =
|
||||
{
|
||||
0x00, 0xf4, 0xf5, 0x01, 0xf7, 0x03, 0x02, 0xf6, 0xf3, 0x07, 0x06, 0xf2, 0x04, 0xf0, 0xf1, 0x05,
|
||||
0xfb, 0x0f, 0x0e, 0xfa, 0x0c, 0xf8, 0xf9, 0x0d, 0x08, 0xfc, 0xfd, 0x09, 0xff, 0x0b, 0x0a, 0xfe,
|
||||
0xeb, 0x1f, 0x1e, 0xea, 0x1c, 0xe8, 0xe9, 0x1d, 0x18, 0xec, 0xed, 0x19, 0xef, 0x1b, 0x1a, 0xee,
|
||||
0x10, 0xe4, 0xe5, 0x11, 0xe7, 0x13, 0x12, 0xe6, 0xe3, 0x17, 0x16, 0xe2, 0x14, 0xe0, 0xe1, 0x15,
|
||||
0xcb, 0x3f, 0x3e, 0xca, 0x3c, 0xc8, 0xc9, 0x3d, 0x38, 0xcc, 0xcd, 0x39, 0xcf, 0x3b, 0x3a, 0xce,
|
||||
0x30, 0xc4, 0xc5, 0x31, 0xc7, 0x33, 0x32, 0xc6, 0xc3, 0x37, 0x36, 0xc2, 0x34, 0xc0, 0xc1, 0x35,
|
||||
0x20, 0xd4, 0xd5, 0x21, 0xd7, 0x23, 0x22, 0xd6, 0xd3, 0x27, 0x26, 0xd2, 0x24, 0xd0, 0xd1, 0x25,
|
||||
0xdb, 0x2f, 0x2e, 0xda, 0x2c, 0xd8, 0xd9, 0x2d, 0x28, 0xdc, 0xdd, 0x29, 0xdf, 0x2b, 0x2a, 0xde,
|
||||
0x8b, 0x7f, 0x7e, 0x8a, 0x7c, 0x88, 0x89, 0x7d, 0x78, 0x8c, 0x8d, 0x79, 0x8f, 0x7b, 0x7a, 0x8e,
|
||||
0x70, 0x84, 0x85, 0x71, 0x87, 0x73, 0x72, 0x86, 0x83, 0x77, 0x76, 0x82, 0x74, 0x80, 0x81, 0x75,
|
||||
0x60, 0x94, 0x95, 0x61, 0x97, 0x63, 0x62, 0x96, 0x93, 0x67, 0x66, 0x92, 0x64, 0x90, 0x91, 0x65,
|
||||
0x9b, 0x6f, 0x6e, 0x9a, 0x6c, 0x98, 0x99, 0x6d, 0x68, 0x9c, 0x9d, 0x69, 0x9f, 0x6b, 0x6a, 0x9e,
|
||||
0x40, 0xb4, 0xb5, 0x41, 0xb7, 0x43, 0x42, 0xb6, 0xb3, 0x47, 0x46, 0xb2, 0x44, 0xb0, 0xb1, 0x45,
|
||||
0xbb, 0x4f, 0x4e, 0xba, 0x4c, 0xb8, 0xb9, 0x4d, 0x48, 0xbc, 0xbd, 0x49, 0xbf, 0x4b, 0x4a, 0xbe,
|
||||
0xab, 0x5f, 0x5e, 0xaa, 0x5c, 0xa8, 0xa9, 0x5d, 0x58, 0xac, 0xad, 0x59, 0xaf, 0x5b, 0x5a, 0xae,
|
||||
0x50, 0xa4, 0xa5, 0x51, 0xa7, 0x53, 0x52, 0xa6, 0xa3, 0x57, 0x56, 0xa2, 0x54, 0xa0, 0xa1, 0x55
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* poffsets - each row represents the addresses used to calculate a byte of the ECC P
|
||||
* data 86 (*2) ECC P bytes, 24 values represented by each
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint16_t poffsets[ECC_P_NUM_BYTES][ECC_P_COMP] =
|
||||
{
|
||||
{ 0x000,0x056,0x0ac,0x102,0x158,0x1ae,0x204,0x25a,0x2b0,0x306,0x35c,0x3b2,0x408,0x45e,0x4b4,0x50a,0x560,0x5b6,0x60c,0x662,0x6b8,0x70e,0x764,0x7ba },
|
||||
{ 0x001,0x057,0x0ad,0x103,0x159,0x1af,0x205,0x25b,0x2b1,0x307,0x35d,0x3b3,0x409,0x45f,0x4b5,0x50b,0x561,0x5b7,0x60d,0x663,0x6b9,0x70f,0x765,0x7bb },
|
||||
{ 0x002,0x058,0x0ae,0x104,0x15a,0x1b0,0x206,0x25c,0x2b2,0x308,0x35e,0x3b4,0x40a,0x460,0x4b6,0x50c,0x562,0x5b8,0x60e,0x664,0x6ba,0x710,0x766,0x7bc },
|
||||
{ 0x003,0x059,0x0af,0x105,0x15b,0x1b1,0x207,0x25d,0x2b3,0x309,0x35f,0x3b5,0x40b,0x461,0x4b7,0x50d,0x563,0x5b9,0x60f,0x665,0x6bb,0x711,0x767,0x7bd },
|
||||
{ 0x004,0x05a,0x0b0,0x106,0x15c,0x1b2,0x208,0x25e,0x2b4,0x30a,0x360,0x3b6,0x40c,0x462,0x4b8,0x50e,0x564,0x5ba,0x610,0x666,0x6bc,0x712,0x768,0x7be },
|
||||
{ 0x005,0x05b,0x0b1,0x107,0x15d,0x1b3,0x209,0x25f,0x2b5,0x30b,0x361,0x3b7,0x40d,0x463,0x4b9,0x50f,0x565,0x5bb,0x611,0x667,0x6bd,0x713,0x769,0x7bf },
|
||||
{ 0x006,0x05c,0x0b2,0x108,0x15e,0x1b4,0x20a,0x260,0x2b6,0x30c,0x362,0x3b8,0x40e,0x464,0x4ba,0x510,0x566,0x5bc,0x612,0x668,0x6be,0x714,0x76a,0x7c0 },
|
||||
{ 0x007,0x05d,0x0b3,0x109,0x15f,0x1b5,0x20b,0x261,0x2b7,0x30d,0x363,0x3b9,0x40f,0x465,0x4bb,0x511,0x567,0x5bd,0x613,0x669,0x6bf,0x715,0x76b,0x7c1 },
|
||||
{ 0x008,0x05e,0x0b4,0x10a,0x160,0x1b6,0x20c,0x262,0x2b8,0x30e,0x364,0x3ba,0x410,0x466,0x4bc,0x512,0x568,0x5be,0x614,0x66a,0x6c0,0x716,0x76c,0x7c2 },
|
||||
{ 0x009,0x05f,0x0b5,0x10b,0x161,0x1b7,0x20d,0x263,0x2b9,0x30f,0x365,0x3bb,0x411,0x467,0x4bd,0x513,0x569,0x5bf,0x615,0x66b,0x6c1,0x717,0x76d,0x7c3 },
|
||||
{ 0x00a,0x060,0x0b6,0x10c,0x162,0x1b8,0x20e,0x264,0x2ba,0x310,0x366,0x3bc,0x412,0x468,0x4be,0x514,0x56a,0x5c0,0x616,0x66c,0x6c2,0x718,0x76e,0x7c4 },
|
||||
{ 0x00b,0x061,0x0b7,0x10d,0x163,0x1b9,0x20f,0x265,0x2bb,0x311,0x367,0x3bd,0x413,0x469,0x4bf,0x515,0x56b,0x5c1,0x617,0x66d,0x6c3,0x719,0x76f,0x7c5 },
|
||||
{ 0x00c,0x062,0x0b8,0x10e,0x164,0x1ba,0x210,0x266,0x2bc,0x312,0x368,0x3be,0x414,0x46a,0x4c0,0x516,0x56c,0x5c2,0x618,0x66e,0x6c4,0x71a,0x770,0x7c6 },
|
||||
{ 0x00d,0x063,0x0b9,0x10f,0x165,0x1bb,0x211,0x267,0x2bd,0x313,0x369,0x3bf,0x415,0x46b,0x4c1,0x517,0x56d,0x5c3,0x619,0x66f,0x6c5,0x71b,0x771,0x7c7 },
|
||||
{ 0x00e,0x064,0x0ba,0x110,0x166,0x1bc,0x212,0x268,0x2be,0x314,0x36a,0x3c0,0x416,0x46c,0x4c2,0x518,0x56e,0x5c4,0x61a,0x670,0x6c6,0x71c,0x772,0x7c8 },
|
||||
{ 0x00f,0x065,0x0bb,0x111,0x167,0x1bd,0x213,0x269,0x2bf,0x315,0x36b,0x3c1,0x417,0x46d,0x4c3,0x519,0x56f,0x5c5,0x61b,0x671,0x6c7,0x71d,0x773,0x7c9 },
|
||||
{ 0x010,0x066,0x0bc,0x112,0x168,0x1be,0x214,0x26a,0x2c0,0x316,0x36c,0x3c2,0x418,0x46e,0x4c4,0x51a,0x570,0x5c6,0x61c,0x672,0x6c8,0x71e,0x774,0x7ca },
|
||||
{ 0x011,0x067,0x0bd,0x113,0x169,0x1bf,0x215,0x26b,0x2c1,0x317,0x36d,0x3c3,0x419,0x46f,0x4c5,0x51b,0x571,0x5c7,0x61d,0x673,0x6c9,0x71f,0x775,0x7cb },
|
||||
{ 0x012,0x068,0x0be,0x114,0x16a,0x1c0,0x216,0x26c,0x2c2,0x318,0x36e,0x3c4,0x41a,0x470,0x4c6,0x51c,0x572,0x5c8,0x61e,0x674,0x6ca,0x720,0x776,0x7cc },
|
||||
{ 0x013,0x069,0x0bf,0x115,0x16b,0x1c1,0x217,0x26d,0x2c3,0x319,0x36f,0x3c5,0x41b,0x471,0x4c7,0x51d,0x573,0x5c9,0x61f,0x675,0x6cb,0x721,0x777,0x7cd },
|
||||
{ 0x014,0x06a,0x0c0,0x116,0x16c,0x1c2,0x218,0x26e,0x2c4,0x31a,0x370,0x3c6,0x41c,0x472,0x4c8,0x51e,0x574,0x5ca,0x620,0x676,0x6cc,0x722,0x778,0x7ce },
|
||||
{ 0x015,0x06b,0x0c1,0x117,0x16d,0x1c3,0x219,0x26f,0x2c5,0x31b,0x371,0x3c7,0x41d,0x473,0x4c9,0x51f,0x575,0x5cb,0x621,0x677,0x6cd,0x723,0x779,0x7cf },
|
||||
{ 0x016,0x06c,0x0c2,0x118,0x16e,0x1c4,0x21a,0x270,0x2c6,0x31c,0x372,0x3c8,0x41e,0x474,0x4ca,0x520,0x576,0x5cc,0x622,0x678,0x6ce,0x724,0x77a,0x7d0 },
|
||||
{ 0x017,0x06d,0x0c3,0x119,0x16f,0x1c5,0x21b,0x271,0x2c7,0x31d,0x373,0x3c9,0x41f,0x475,0x4cb,0x521,0x577,0x5cd,0x623,0x679,0x6cf,0x725,0x77b,0x7d1 },
|
||||
{ 0x018,0x06e,0x0c4,0x11a,0x170,0x1c6,0x21c,0x272,0x2c8,0x31e,0x374,0x3ca,0x420,0x476,0x4cc,0x522,0x578,0x5ce,0x624,0x67a,0x6d0,0x726,0x77c,0x7d2 },
|
||||
{ 0x019,0x06f,0x0c5,0x11b,0x171,0x1c7,0x21d,0x273,0x2c9,0x31f,0x375,0x3cb,0x421,0x477,0x4cd,0x523,0x579,0x5cf,0x625,0x67b,0x6d1,0x727,0x77d,0x7d3 },
|
||||
{ 0x01a,0x070,0x0c6,0x11c,0x172,0x1c8,0x21e,0x274,0x2ca,0x320,0x376,0x3cc,0x422,0x478,0x4ce,0x524,0x57a,0x5d0,0x626,0x67c,0x6d2,0x728,0x77e,0x7d4 },
|
||||
{ 0x01b,0x071,0x0c7,0x11d,0x173,0x1c9,0x21f,0x275,0x2cb,0x321,0x377,0x3cd,0x423,0x479,0x4cf,0x525,0x57b,0x5d1,0x627,0x67d,0x6d3,0x729,0x77f,0x7d5 },
|
||||
{ 0x01c,0x072,0x0c8,0x11e,0x174,0x1ca,0x220,0x276,0x2cc,0x322,0x378,0x3ce,0x424,0x47a,0x4d0,0x526,0x57c,0x5d2,0x628,0x67e,0x6d4,0x72a,0x780,0x7d6 },
|
||||
{ 0x01d,0x073,0x0c9,0x11f,0x175,0x1cb,0x221,0x277,0x2cd,0x323,0x379,0x3cf,0x425,0x47b,0x4d1,0x527,0x57d,0x5d3,0x629,0x67f,0x6d5,0x72b,0x781,0x7d7 },
|
||||
{ 0x01e,0x074,0x0ca,0x120,0x176,0x1cc,0x222,0x278,0x2ce,0x324,0x37a,0x3d0,0x426,0x47c,0x4d2,0x528,0x57e,0x5d4,0x62a,0x680,0x6d6,0x72c,0x782,0x7d8 },
|
||||
{ 0x01f,0x075,0x0cb,0x121,0x177,0x1cd,0x223,0x279,0x2cf,0x325,0x37b,0x3d1,0x427,0x47d,0x4d3,0x529,0x57f,0x5d5,0x62b,0x681,0x6d7,0x72d,0x783,0x7d9 },
|
||||
{ 0x020,0x076,0x0cc,0x122,0x178,0x1ce,0x224,0x27a,0x2d0,0x326,0x37c,0x3d2,0x428,0x47e,0x4d4,0x52a,0x580,0x5d6,0x62c,0x682,0x6d8,0x72e,0x784,0x7da },
|
||||
{ 0x021,0x077,0x0cd,0x123,0x179,0x1cf,0x225,0x27b,0x2d1,0x327,0x37d,0x3d3,0x429,0x47f,0x4d5,0x52b,0x581,0x5d7,0x62d,0x683,0x6d9,0x72f,0x785,0x7db },
|
||||
{ 0x022,0x078,0x0ce,0x124,0x17a,0x1d0,0x226,0x27c,0x2d2,0x328,0x37e,0x3d4,0x42a,0x480,0x4d6,0x52c,0x582,0x5d8,0x62e,0x684,0x6da,0x730,0x786,0x7dc },
|
||||
{ 0x023,0x079,0x0cf,0x125,0x17b,0x1d1,0x227,0x27d,0x2d3,0x329,0x37f,0x3d5,0x42b,0x481,0x4d7,0x52d,0x583,0x5d9,0x62f,0x685,0x6db,0x731,0x787,0x7dd },
|
||||
{ 0x024,0x07a,0x0d0,0x126,0x17c,0x1d2,0x228,0x27e,0x2d4,0x32a,0x380,0x3d6,0x42c,0x482,0x4d8,0x52e,0x584,0x5da,0x630,0x686,0x6dc,0x732,0x788,0x7de },
|
||||
{ 0x025,0x07b,0x0d1,0x127,0x17d,0x1d3,0x229,0x27f,0x2d5,0x32b,0x381,0x3d7,0x42d,0x483,0x4d9,0x52f,0x585,0x5db,0x631,0x687,0x6dd,0x733,0x789,0x7df },
|
||||
{ 0x026,0x07c,0x0d2,0x128,0x17e,0x1d4,0x22a,0x280,0x2d6,0x32c,0x382,0x3d8,0x42e,0x484,0x4da,0x530,0x586,0x5dc,0x632,0x688,0x6de,0x734,0x78a,0x7e0 },
|
||||
{ 0x027,0x07d,0x0d3,0x129,0x17f,0x1d5,0x22b,0x281,0x2d7,0x32d,0x383,0x3d9,0x42f,0x485,0x4db,0x531,0x587,0x5dd,0x633,0x689,0x6df,0x735,0x78b,0x7e1 },
|
||||
{ 0x028,0x07e,0x0d4,0x12a,0x180,0x1d6,0x22c,0x282,0x2d8,0x32e,0x384,0x3da,0x430,0x486,0x4dc,0x532,0x588,0x5de,0x634,0x68a,0x6e0,0x736,0x78c,0x7e2 },
|
||||
{ 0x029,0x07f,0x0d5,0x12b,0x181,0x1d7,0x22d,0x283,0x2d9,0x32f,0x385,0x3db,0x431,0x487,0x4dd,0x533,0x589,0x5df,0x635,0x68b,0x6e1,0x737,0x78d,0x7e3 },
|
||||
{ 0x02a,0x080,0x0d6,0x12c,0x182,0x1d8,0x22e,0x284,0x2da,0x330,0x386,0x3dc,0x432,0x488,0x4de,0x534,0x58a,0x5e0,0x636,0x68c,0x6e2,0x738,0x78e,0x7e4 },
|
||||
{ 0x02b,0x081,0x0d7,0x12d,0x183,0x1d9,0x22f,0x285,0x2db,0x331,0x387,0x3dd,0x433,0x489,0x4df,0x535,0x58b,0x5e1,0x637,0x68d,0x6e3,0x739,0x78f,0x7e5 },
|
||||
{ 0x02c,0x082,0x0d8,0x12e,0x184,0x1da,0x230,0x286,0x2dc,0x332,0x388,0x3de,0x434,0x48a,0x4e0,0x536,0x58c,0x5e2,0x638,0x68e,0x6e4,0x73a,0x790,0x7e6 },
|
||||
{ 0x02d,0x083,0x0d9,0x12f,0x185,0x1db,0x231,0x287,0x2dd,0x333,0x389,0x3df,0x435,0x48b,0x4e1,0x537,0x58d,0x5e3,0x639,0x68f,0x6e5,0x73b,0x791,0x7e7 },
|
||||
{ 0x02e,0x084,0x0da,0x130,0x186,0x1dc,0x232,0x288,0x2de,0x334,0x38a,0x3e0,0x436,0x48c,0x4e2,0x538,0x58e,0x5e4,0x63a,0x690,0x6e6,0x73c,0x792,0x7e8 },
|
||||
{ 0x02f,0x085,0x0db,0x131,0x187,0x1dd,0x233,0x289,0x2df,0x335,0x38b,0x3e1,0x437,0x48d,0x4e3,0x539,0x58f,0x5e5,0x63b,0x691,0x6e7,0x73d,0x793,0x7e9 },
|
||||
{ 0x030,0x086,0x0dc,0x132,0x188,0x1de,0x234,0x28a,0x2e0,0x336,0x38c,0x3e2,0x438,0x48e,0x4e4,0x53a,0x590,0x5e6,0x63c,0x692,0x6e8,0x73e,0x794,0x7ea },
|
||||
{ 0x031,0x087,0x0dd,0x133,0x189,0x1df,0x235,0x28b,0x2e1,0x337,0x38d,0x3e3,0x439,0x48f,0x4e5,0x53b,0x591,0x5e7,0x63d,0x693,0x6e9,0x73f,0x795,0x7eb },
|
||||
{ 0x032,0x088,0x0de,0x134,0x18a,0x1e0,0x236,0x28c,0x2e2,0x338,0x38e,0x3e4,0x43a,0x490,0x4e6,0x53c,0x592,0x5e8,0x63e,0x694,0x6ea,0x740,0x796,0x7ec },
|
||||
{ 0x033,0x089,0x0df,0x135,0x18b,0x1e1,0x237,0x28d,0x2e3,0x339,0x38f,0x3e5,0x43b,0x491,0x4e7,0x53d,0x593,0x5e9,0x63f,0x695,0x6eb,0x741,0x797,0x7ed },
|
||||
{ 0x034,0x08a,0x0e0,0x136,0x18c,0x1e2,0x238,0x28e,0x2e4,0x33a,0x390,0x3e6,0x43c,0x492,0x4e8,0x53e,0x594,0x5ea,0x640,0x696,0x6ec,0x742,0x798,0x7ee },
|
||||
{ 0x035,0x08b,0x0e1,0x137,0x18d,0x1e3,0x239,0x28f,0x2e5,0x33b,0x391,0x3e7,0x43d,0x493,0x4e9,0x53f,0x595,0x5eb,0x641,0x697,0x6ed,0x743,0x799,0x7ef },
|
||||
{ 0x036,0x08c,0x0e2,0x138,0x18e,0x1e4,0x23a,0x290,0x2e6,0x33c,0x392,0x3e8,0x43e,0x494,0x4ea,0x540,0x596,0x5ec,0x642,0x698,0x6ee,0x744,0x79a,0x7f0 },
|
||||
{ 0x037,0x08d,0x0e3,0x139,0x18f,0x1e5,0x23b,0x291,0x2e7,0x33d,0x393,0x3e9,0x43f,0x495,0x4eb,0x541,0x597,0x5ed,0x643,0x699,0x6ef,0x745,0x79b,0x7f1 },
|
||||
{ 0x038,0x08e,0x0e4,0x13a,0x190,0x1e6,0x23c,0x292,0x2e8,0x33e,0x394,0x3ea,0x440,0x496,0x4ec,0x542,0x598,0x5ee,0x644,0x69a,0x6f0,0x746,0x79c,0x7f2 },
|
||||
{ 0x039,0x08f,0x0e5,0x13b,0x191,0x1e7,0x23d,0x293,0x2e9,0x33f,0x395,0x3eb,0x441,0x497,0x4ed,0x543,0x599,0x5ef,0x645,0x69b,0x6f1,0x747,0x79d,0x7f3 },
|
||||
{ 0x03a,0x090,0x0e6,0x13c,0x192,0x1e8,0x23e,0x294,0x2ea,0x340,0x396,0x3ec,0x442,0x498,0x4ee,0x544,0x59a,0x5f0,0x646,0x69c,0x6f2,0x748,0x79e,0x7f4 },
|
||||
{ 0x03b,0x091,0x0e7,0x13d,0x193,0x1e9,0x23f,0x295,0x2eb,0x341,0x397,0x3ed,0x443,0x499,0x4ef,0x545,0x59b,0x5f1,0x647,0x69d,0x6f3,0x749,0x79f,0x7f5 },
|
||||
{ 0x03c,0x092,0x0e8,0x13e,0x194,0x1ea,0x240,0x296,0x2ec,0x342,0x398,0x3ee,0x444,0x49a,0x4f0,0x546,0x59c,0x5f2,0x648,0x69e,0x6f4,0x74a,0x7a0,0x7f6 },
|
||||
{ 0x03d,0x093,0x0e9,0x13f,0x195,0x1eb,0x241,0x297,0x2ed,0x343,0x399,0x3ef,0x445,0x49b,0x4f1,0x547,0x59d,0x5f3,0x649,0x69f,0x6f5,0x74b,0x7a1,0x7f7 },
|
||||
{ 0x03e,0x094,0x0ea,0x140,0x196,0x1ec,0x242,0x298,0x2ee,0x344,0x39a,0x3f0,0x446,0x49c,0x4f2,0x548,0x59e,0x5f4,0x64a,0x6a0,0x6f6,0x74c,0x7a2,0x7f8 },
|
||||
{ 0x03f,0x095,0x0eb,0x141,0x197,0x1ed,0x243,0x299,0x2ef,0x345,0x39b,0x3f1,0x447,0x49d,0x4f3,0x549,0x59f,0x5f5,0x64b,0x6a1,0x6f7,0x74d,0x7a3,0x7f9 },
|
||||
{ 0x040,0x096,0x0ec,0x142,0x198,0x1ee,0x244,0x29a,0x2f0,0x346,0x39c,0x3f2,0x448,0x49e,0x4f4,0x54a,0x5a0,0x5f6,0x64c,0x6a2,0x6f8,0x74e,0x7a4,0x7fa },
|
||||
{ 0x041,0x097,0x0ed,0x143,0x199,0x1ef,0x245,0x29b,0x2f1,0x347,0x39d,0x3f3,0x449,0x49f,0x4f5,0x54b,0x5a1,0x5f7,0x64d,0x6a3,0x6f9,0x74f,0x7a5,0x7fb },
|
||||
{ 0x042,0x098,0x0ee,0x144,0x19a,0x1f0,0x246,0x29c,0x2f2,0x348,0x39e,0x3f4,0x44a,0x4a0,0x4f6,0x54c,0x5a2,0x5f8,0x64e,0x6a4,0x6fa,0x750,0x7a6,0x7fc },
|
||||
{ 0x043,0x099,0x0ef,0x145,0x19b,0x1f1,0x247,0x29d,0x2f3,0x349,0x39f,0x3f5,0x44b,0x4a1,0x4f7,0x54d,0x5a3,0x5f9,0x64f,0x6a5,0x6fb,0x751,0x7a7,0x7fd },
|
||||
{ 0x044,0x09a,0x0f0,0x146,0x19c,0x1f2,0x248,0x29e,0x2f4,0x34a,0x3a0,0x3f6,0x44c,0x4a2,0x4f8,0x54e,0x5a4,0x5fa,0x650,0x6a6,0x6fc,0x752,0x7a8,0x7fe },
|
||||
{ 0x045,0x09b,0x0f1,0x147,0x19d,0x1f3,0x249,0x29f,0x2f5,0x34b,0x3a1,0x3f7,0x44d,0x4a3,0x4f9,0x54f,0x5a5,0x5fb,0x651,0x6a7,0x6fd,0x753,0x7a9,0x7ff },
|
||||
{ 0x046,0x09c,0x0f2,0x148,0x19e,0x1f4,0x24a,0x2a0,0x2f6,0x34c,0x3a2,0x3f8,0x44e,0x4a4,0x4fa,0x550,0x5a6,0x5fc,0x652,0x6a8,0x6fe,0x754,0x7aa,0x800 },
|
||||
{ 0x047,0x09d,0x0f3,0x149,0x19f,0x1f5,0x24b,0x2a1,0x2f7,0x34d,0x3a3,0x3f9,0x44f,0x4a5,0x4fb,0x551,0x5a7,0x5fd,0x653,0x6a9,0x6ff,0x755,0x7ab,0x801 },
|
||||
{ 0x048,0x09e,0x0f4,0x14a,0x1a0,0x1f6,0x24c,0x2a2,0x2f8,0x34e,0x3a4,0x3fa,0x450,0x4a6,0x4fc,0x552,0x5a8,0x5fe,0x654,0x6aa,0x700,0x756,0x7ac,0x802 },
|
||||
{ 0x049,0x09f,0x0f5,0x14b,0x1a1,0x1f7,0x24d,0x2a3,0x2f9,0x34f,0x3a5,0x3fb,0x451,0x4a7,0x4fd,0x553,0x5a9,0x5ff,0x655,0x6ab,0x701,0x757,0x7ad,0x803 },
|
||||
{ 0x04a,0x0a0,0x0f6,0x14c,0x1a2,0x1f8,0x24e,0x2a4,0x2fa,0x350,0x3a6,0x3fc,0x452,0x4a8,0x4fe,0x554,0x5aa,0x600,0x656,0x6ac,0x702,0x758,0x7ae,0x804 },
|
||||
{ 0x04b,0x0a1,0x0f7,0x14d,0x1a3,0x1f9,0x24f,0x2a5,0x2fb,0x351,0x3a7,0x3fd,0x453,0x4a9,0x4ff,0x555,0x5ab,0x601,0x657,0x6ad,0x703,0x759,0x7af,0x805 },
|
||||
{ 0x04c,0x0a2,0x0f8,0x14e,0x1a4,0x1fa,0x250,0x2a6,0x2fc,0x352,0x3a8,0x3fe,0x454,0x4aa,0x500,0x556,0x5ac,0x602,0x658,0x6ae,0x704,0x75a,0x7b0,0x806 },
|
||||
{ 0x04d,0x0a3,0x0f9,0x14f,0x1a5,0x1fb,0x251,0x2a7,0x2fd,0x353,0x3a9,0x3ff,0x455,0x4ab,0x501,0x557,0x5ad,0x603,0x659,0x6af,0x705,0x75b,0x7b1,0x807 },
|
||||
{ 0x04e,0x0a4,0x0fa,0x150,0x1a6,0x1fc,0x252,0x2a8,0x2fe,0x354,0x3aa,0x400,0x456,0x4ac,0x502,0x558,0x5ae,0x604,0x65a,0x6b0,0x706,0x75c,0x7b2,0x808 },
|
||||
{ 0x04f,0x0a5,0x0fb,0x151,0x1a7,0x1fd,0x253,0x2a9,0x2ff,0x355,0x3ab,0x401,0x457,0x4ad,0x503,0x559,0x5af,0x605,0x65b,0x6b1,0x707,0x75d,0x7b3,0x809 },
|
||||
{ 0x050,0x0a6,0x0fc,0x152,0x1a8,0x1fe,0x254,0x2aa,0x300,0x356,0x3ac,0x402,0x458,0x4ae,0x504,0x55a,0x5b0,0x606,0x65c,0x6b2,0x708,0x75e,0x7b4,0x80a },
|
||||
{ 0x051,0x0a7,0x0fd,0x153,0x1a9,0x1ff,0x255,0x2ab,0x301,0x357,0x3ad,0x403,0x459,0x4af,0x505,0x55b,0x5b1,0x607,0x65d,0x6b3,0x709,0x75f,0x7b5,0x80b },
|
||||
{ 0x052,0x0a8,0x0fe,0x154,0x1aa,0x200,0x256,0x2ac,0x302,0x358,0x3ae,0x404,0x45a,0x4b0,0x506,0x55c,0x5b2,0x608,0x65e,0x6b4,0x70a,0x760,0x7b6,0x80c },
|
||||
{ 0x053,0x0a9,0x0ff,0x155,0x1ab,0x201,0x257,0x2ad,0x303,0x359,0x3af,0x405,0x45b,0x4b1,0x507,0x55d,0x5b3,0x609,0x65f,0x6b5,0x70b,0x761,0x7b7,0x80d },
|
||||
{ 0x054,0x0aa,0x100,0x156,0x1ac,0x202,0x258,0x2ae,0x304,0x35a,0x3b0,0x406,0x45c,0x4b2,0x508,0x55e,0x5b4,0x60a,0x660,0x6b6,0x70c,0x762,0x7b8,0x80e },
|
||||
{ 0x055,0x0ab,0x101,0x157,0x1ad,0x203,0x259,0x2af,0x305,0x35b,0x3b1,0x407,0x45d,0x4b3,0x509,0x55f,0x5b5,0x60b,0x661,0x6b7,0x70d,0x763,0x7b9,0x80f }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief -------------------------------------------------
|
||||
* qoffsets - each row represents the addresses used to calculate a byte of the ECC Q
|
||||
* data 52 (*2) ECC Q bytes, 43 values represented by each
|
||||
* -------------------------------------------------.
|
||||
*/
|
||||
|
||||
static const uint16_t qoffsets[ECC_Q_NUM_BYTES][ECC_Q_COMP] =
|
||||
{
|
||||
{ 0x000,0x058,0x0b0,0x108,0x160,0x1b8,0x210,0x268,0x2c0,0x318,0x370,0x3c8,0x420,0x478,0x4d0,0x528,0x580,0x5d8,0x630,0x688,0x6e0,0x738,0x790,0x7e8,0x840,0x898,0x034,0x08c,0x0e4,0x13c,0x194,0x1ec,0x244,0x29c,0x2f4,0x34c,0x3a4,0x3fc,0x454,0x4ac,0x504,0x55c,0x5b4 },
|
||||
{ 0x001,0x059,0x0b1,0x109,0x161,0x1b9,0x211,0x269,0x2c1,0x319,0x371,0x3c9,0x421,0x479,0x4d1,0x529,0x581,0x5d9,0x631,0x689,0x6e1,0x739,0x791,0x7e9,0x841,0x899,0x035,0x08d,0x0e5,0x13d,0x195,0x1ed,0x245,0x29d,0x2f5,0x34d,0x3a5,0x3fd,0x455,0x4ad,0x505,0x55d,0x5b5 },
|
||||
{ 0x056,0x0ae,0x106,0x15e,0x1b6,0x20e,0x266,0x2be,0x316,0x36e,0x3c6,0x41e,0x476,0x4ce,0x526,0x57e,0x5d6,0x62e,0x686,0x6de,0x736,0x78e,0x7e6,0x83e,0x896,0x032,0x08a,0x0e2,0x13a,0x192,0x1ea,0x242,0x29a,0x2f2,0x34a,0x3a2,0x3fa,0x452,0x4aa,0x502,0x55a,0x5b2,0x60a },
|
||||
{ 0x057,0x0af,0x107,0x15f,0x1b7,0x20f,0x267,0x2bf,0x317,0x36f,0x3c7,0x41f,0x477,0x4cf,0x527,0x57f,0x5d7,0x62f,0x687,0x6df,0x737,0x78f,0x7e7,0x83f,0x897,0x033,0x08b,0x0e3,0x13b,0x193,0x1eb,0x243,0x29b,0x2f3,0x34b,0x3a3,0x3fb,0x453,0x4ab,0x503,0x55b,0x5b3,0x60b },
|
||||
{ 0x0ac,0x104,0x15c,0x1b4,0x20c,0x264,0x2bc,0x314,0x36c,0x3c4,0x41c,0x474,0x4cc,0x524,0x57c,0x5d4,0x62c,0x684,0x6dc,0x734,0x78c,0x7e4,0x83c,0x894,0x030,0x088,0x0e0,0x138,0x190,0x1e8,0x240,0x298,0x2f0,0x348,0x3a0,0x3f8,0x450,0x4a8,0x500,0x558,0x5b0,0x608,0x660 },
|
||||
{ 0x0ad,0x105,0x15d,0x1b5,0x20d,0x265,0x2bd,0x315,0x36d,0x3c5,0x41d,0x475,0x4cd,0x525,0x57d,0x5d5,0x62d,0x685,0x6dd,0x735,0x78d,0x7e5,0x83d,0x895,0x031,0x089,0x0e1,0x139,0x191,0x1e9,0x241,0x299,0x2f1,0x349,0x3a1,0x3f9,0x451,0x4a9,0x501,0x559,0x5b1,0x609,0x661 },
|
||||
{ 0x102,0x15a,0x1b2,0x20a,0x262,0x2ba,0x312,0x36a,0x3c2,0x41a,0x472,0x4ca,0x522,0x57a,0x5d2,0x62a,0x682,0x6da,0x732,0x78a,0x7e2,0x83a,0x892,0x02e,0x086,0x0de,0x136,0x18e,0x1e6,0x23e,0x296,0x2ee,0x346,0x39e,0x3f6,0x44e,0x4a6,0x4fe,0x556,0x5ae,0x606,0x65e,0x6b6 },
|
||||
{ 0x103,0x15b,0x1b3,0x20b,0x263,0x2bb,0x313,0x36b,0x3c3,0x41b,0x473,0x4cb,0x523,0x57b,0x5d3,0x62b,0x683,0x6db,0x733,0x78b,0x7e3,0x83b,0x893,0x02f,0x087,0x0df,0x137,0x18f,0x1e7,0x23f,0x297,0x2ef,0x347,0x39f,0x3f7,0x44f,0x4a7,0x4ff,0x557,0x5af,0x607,0x65f,0x6b7 },
|
||||
{ 0x158,0x1b0,0x208,0x260,0x2b8,0x310,0x368,0x3c0,0x418,0x470,0x4c8,0x520,0x578,0x5d0,0x628,0x680,0x6d8,0x730,0x788,0x7e0,0x838,0x890,0x02c,0x084,0x0dc,0x134,0x18c,0x1e4,0x23c,0x294,0x2ec,0x344,0x39c,0x3f4,0x44c,0x4a4,0x4fc,0x554,0x5ac,0x604,0x65c,0x6b4,0x70c },
|
||||
{ 0x159,0x1b1,0x209,0x261,0x2b9,0x311,0x369,0x3c1,0x419,0x471,0x4c9,0x521,0x579,0x5d1,0x629,0x681,0x6d9,0x731,0x789,0x7e1,0x839,0x891,0x02d,0x085,0x0dd,0x135,0x18d,0x1e5,0x23d,0x295,0x2ed,0x345,0x39d,0x3f5,0x44d,0x4a5,0x4fd,0x555,0x5ad,0x605,0x65d,0x6b5,0x70d },
|
||||
{ 0x1ae,0x206,0x25e,0x2b6,0x30e,0x366,0x3be,0x416,0x46e,0x4c6,0x51e,0x576,0x5ce,0x626,0x67e,0x6d6,0x72e,0x786,0x7de,0x836,0x88e,0x02a,0x082,0x0da,0x132,0x18a,0x1e2,0x23a,0x292,0x2ea,0x342,0x39a,0x3f2,0x44a,0x4a2,0x4fa,0x552,0x5aa,0x602,0x65a,0x6b2,0x70a,0x762 },
|
||||
{ 0x1af,0x207,0x25f,0x2b7,0x30f,0x367,0x3bf,0x417,0x46f,0x4c7,0x51f,0x577,0x5cf,0x627,0x67f,0x6d7,0x72f,0x787,0x7df,0x837,0x88f,0x02b,0x083,0x0db,0x133,0x18b,0x1e3,0x23b,0x293,0x2eb,0x343,0x39b,0x3f3,0x44b,0x4a3,0x4fb,0x553,0x5ab,0x603,0x65b,0x6b3,0x70b,0x763 },
|
||||
{ 0x204,0x25c,0x2b4,0x30c,0x364,0x3bc,0x414,0x46c,0x4c4,0x51c,0x574,0x5cc,0x624,0x67c,0x6d4,0x72c,0x784,0x7dc,0x834,0x88c,0x028,0x080,0x0d8,0x130,0x188,0x1e0,0x238,0x290,0x2e8,0x340,0x398,0x3f0,0x448,0x4a0,0x4f8,0x550,0x5a8,0x600,0x658,0x6b0,0x708,0x760,0x7b8 },
|
||||
{ 0x205,0x25d,0x2b5,0x30d,0x365,0x3bd,0x415,0x46d,0x4c5,0x51d,0x575,0x5cd,0x625,0x67d,0x6d5,0x72d,0x785,0x7dd,0x835,0x88d,0x029,0x081,0x0d9,0x131,0x189,0x1e1,0x239,0x291,0x2e9,0x341,0x399,0x3f1,0x449,0x4a1,0x4f9,0x551,0x5a9,0x601,0x659,0x6b1,0x709,0x761,0x7b9 },
|
||||
{ 0x25a,0x2b2,0x30a,0x362,0x3ba,0x412,0x46a,0x4c2,0x51a,0x572,0x5ca,0x622,0x67a,0x6d2,0x72a,0x782,0x7da,0x832,0x88a,0x026,0x07e,0x0d6,0x12e,0x186,0x1de,0x236,0x28e,0x2e6,0x33e,0x396,0x3ee,0x446,0x49e,0x4f6,0x54e,0x5a6,0x5fe,0x656,0x6ae,0x706,0x75e,0x7b6,0x80e },
|
||||
{ 0x25b,0x2b3,0x30b,0x363,0x3bb,0x413,0x46b,0x4c3,0x51b,0x573,0x5cb,0x623,0x67b,0x6d3,0x72b,0x783,0x7db,0x833,0x88b,0x027,0x07f,0x0d7,0x12f,0x187,0x1df,0x237,0x28f,0x2e7,0x33f,0x397,0x3ef,0x447,0x49f,0x4f7,0x54f,0x5a7,0x5ff,0x657,0x6af,0x707,0x75f,0x7b7,0x80f },
|
||||
{ 0x2b0,0x308,0x360,0x3b8,0x410,0x468,0x4c0,0x518,0x570,0x5c8,0x620,0x678,0x6d0,0x728,0x780,0x7d8,0x830,0x888,0x024,0x07c,0x0d4,0x12c,0x184,0x1dc,0x234,0x28c,0x2e4,0x33c,0x394,0x3ec,0x444,0x49c,0x4f4,0x54c,0x5a4,0x5fc,0x654,0x6ac,0x704,0x75c,0x7b4,0x80c,0x864 },
|
||||
{ 0x2b1,0x309,0x361,0x3b9,0x411,0x469,0x4c1,0x519,0x571,0x5c9,0x621,0x679,0x6d1,0x729,0x781,0x7d9,0x831,0x889,0x025,0x07d,0x0d5,0x12d,0x185,0x1dd,0x235,0x28d,0x2e5,0x33d,0x395,0x3ed,0x445,0x49d,0x4f5,0x54d,0x5a5,0x5fd,0x655,0x6ad,0x705,0x75d,0x7b5,0x80d,0x865 },
|
||||
{ 0x306,0x35e,0x3b6,0x40e,0x466,0x4be,0x516,0x56e,0x5c6,0x61e,0x676,0x6ce,0x726,0x77e,0x7d6,0x82e,0x886,0x022,0x07a,0x0d2,0x12a,0x182,0x1da,0x232,0x28a,0x2e2,0x33a,0x392,0x3ea,0x442,0x49a,0x4f2,0x54a,0x5a2,0x5fa,0x652,0x6aa,0x702,0x75a,0x7b2,0x80a,0x862,0x8ba },
|
||||
{ 0x307,0x35f,0x3b7,0x40f,0x467,0x4bf,0x517,0x56f,0x5c7,0x61f,0x677,0x6cf,0x727,0x77f,0x7d7,0x82f,0x887,0x023,0x07b,0x0d3,0x12b,0x183,0x1db,0x233,0x28b,0x2e3,0x33b,0x393,0x3eb,0x443,0x49b,0x4f3,0x54b,0x5a3,0x5fb,0x653,0x6ab,0x703,0x75b,0x7b3,0x80b,0x863,0x8bb },
|
||||
{ 0x35c,0x3b4,0x40c,0x464,0x4bc,0x514,0x56c,0x5c4,0x61c,0x674,0x6cc,0x724,0x77c,0x7d4,0x82c,0x884,0x020,0x078,0x0d0,0x128,0x180,0x1d8,0x230,0x288,0x2e0,0x338,0x390,0x3e8,0x440,0x498,0x4f0,0x548,0x5a0,0x5f8,0x650,0x6a8,0x700,0x758,0x7b0,0x808,0x860,0x8b8,0x054 },
|
||||
{ 0x35d,0x3b5,0x40d,0x465,0x4bd,0x515,0x56d,0x5c5,0x61d,0x675,0x6cd,0x725,0x77d,0x7d5,0x82d,0x885,0x021,0x079,0x0d1,0x129,0x181,0x1d9,0x231,0x289,0x2e1,0x339,0x391,0x3e9,0x441,0x499,0x4f1,0x549,0x5a1,0x5f9,0x651,0x6a9,0x701,0x759,0x7b1,0x809,0x861,0x8b9,0x055 },
|
||||
{ 0x3b2,0x40a,0x462,0x4ba,0x512,0x56a,0x5c2,0x61a,0x672,0x6ca,0x722,0x77a,0x7d2,0x82a,0x882,0x01e,0x076,0x0ce,0x126,0x17e,0x1d6,0x22e,0x286,0x2de,0x336,0x38e,0x3e6,0x43e,0x496,0x4ee,0x546,0x59e,0x5f6,0x64e,0x6a6,0x6fe,0x756,0x7ae,0x806,0x85e,0x8b6,0x052,0x0aa },
|
||||
{ 0x3b3,0x40b,0x463,0x4bb,0x513,0x56b,0x5c3,0x61b,0x673,0x6cb,0x723,0x77b,0x7d3,0x82b,0x883,0x01f,0x077,0x0cf,0x127,0x17f,0x1d7,0x22f,0x287,0x2df,0x337,0x38f,0x3e7,0x43f,0x497,0x4ef,0x547,0x59f,0x5f7,0x64f,0x6a7,0x6ff,0x757,0x7af,0x807,0x85f,0x8b7,0x053,0x0ab },
|
||||
{ 0x408,0x460,0x4b8,0x510,0x568,0x5c0,0x618,0x670,0x6c8,0x720,0x778,0x7d0,0x828,0x880,0x01c,0x074,0x0cc,0x124,0x17c,0x1d4,0x22c,0x284,0x2dc,0x334,0x38c,0x3e4,0x43c,0x494,0x4ec,0x544,0x59c,0x5f4,0x64c,0x6a4,0x6fc,0x754,0x7ac,0x804,0x85c,0x8b4,0x050,0x0a8,0x100 },
|
||||
{ 0x409,0x461,0x4b9,0x511,0x569,0x5c1,0x619,0x671,0x6c9,0x721,0x779,0x7d1,0x829,0x881,0x01d,0x075,0x0cd,0x125,0x17d,0x1d5,0x22d,0x285,0x2dd,0x335,0x38d,0x3e5,0x43d,0x495,0x4ed,0x545,0x59d,0x5f5,0x64d,0x6a5,0x6fd,0x755,0x7ad,0x805,0x85d,0x8b5,0x051,0x0a9,0x101 },
|
||||
{ 0x45e,0x4b6,0x50e,0x566,0x5be,0x616,0x66e,0x6c6,0x71e,0x776,0x7ce,0x826,0x87e,0x01a,0x072,0x0ca,0x122,0x17a,0x1d2,0x22a,0x282,0x2da,0x332,0x38a,0x3e2,0x43a,0x492,0x4ea,0x542,0x59a,0x5f2,0x64a,0x6a2,0x6fa,0x752,0x7aa,0x802,0x85a,0x8b2,0x04e,0x0a6,0x0fe,0x156 },
|
||||
{ 0x45f,0x4b7,0x50f,0x567,0x5bf,0x617,0x66f,0x6c7,0x71f,0x777,0x7cf,0x827,0x87f,0x01b,0x073,0x0cb,0x123,0x17b,0x1d3,0x22b,0x283,0x2db,0x333,0x38b,0x3e3,0x43b,0x493,0x4eb,0x543,0x59b,0x5f3,0x64b,0x6a3,0x6fb,0x753,0x7ab,0x803,0x85b,0x8b3,0x04f,0x0a7,0x0ff,0x157 },
|
||||
{ 0x4b4,0x50c,0x564,0x5bc,0x614,0x66c,0x6c4,0x71c,0x774,0x7cc,0x824,0x87c,0x018,0x070,0x0c8,0x120,0x178,0x1d0,0x228,0x280,0x2d8,0x330,0x388,0x3e0,0x438,0x490,0x4e8,0x540,0x598,0x5f0,0x648,0x6a0,0x6f8,0x750,0x7a8,0x800,0x858,0x8b0,0x04c,0x0a4,0x0fc,0x154,0x1ac },
|
||||
{ 0x4b5,0x50d,0x565,0x5bd,0x615,0x66d,0x6c5,0x71d,0x775,0x7cd,0x825,0x87d,0x019,0x071,0x0c9,0x121,0x179,0x1d1,0x229,0x281,0x2d9,0x331,0x389,0x3e1,0x439,0x491,0x4e9,0x541,0x599,0x5f1,0x649,0x6a1,0x6f9,0x751,0x7a9,0x801,0x859,0x8b1,0x04d,0x0a5,0x0fd,0x155,0x1ad },
|
||||
{ 0x50a,0x562,0x5ba,0x612,0x66a,0x6c2,0x71a,0x772,0x7ca,0x822,0x87a,0x016,0x06e,0x0c6,0x11e,0x176,0x1ce,0x226,0x27e,0x2d6,0x32e,0x386,0x3de,0x436,0x48e,0x4e6,0x53e,0x596,0x5ee,0x646,0x69e,0x6f6,0x74e,0x7a6,0x7fe,0x856,0x8ae,0x04a,0x0a2,0x0fa,0x152,0x1aa,0x202 },
|
||||
{ 0x50b,0x563,0x5bb,0x613,0x66b,0x6c3,0x71b,0x773,0x7cb,0x823,0x87b,0x017,0x06f,0x0c7,0x11f,0x177,0x1cf,0x227,0x27f,0x2d7,0x32f,0x387,0x3df,0x437,0x48f,0x4e7,0x53f,0x597,0x5ef,0x647,0x69f,0x6f7,0x74f,0x7a7,0x7ff,0x857,0x8af,0x04b,0x0a3,0x0fb,0x153,0x1ab,0x203 },
|
||||
{ 0x560,0x5b8,0x610,0x668,0x6c0,0x718,0x770,0x7c8,0x820,0x878,0x014,0x06c,0x0c4,0x11c,0x174,0x1cc,0x224,0x27c,0x2d4,0x32c,0x384,0x3dc,0x434,0x48c,0x4e4,0x53c,0x594,0x5ec,0x644,0x69c,0x6f4,0x74c,0x7a4,0x7fc,0x854,0x8ac,0x048,0x0a0,0x0f8,0x150,0x1a8,0x200,0x258 },
|
||||
{ 0x561,0x5b9,0x611,0x669,0x6c1,0x719,0x771,0x7c9,0x821,0x879,0x015,0x06d,0x0c5,0x11d,0x175,0x1cd,0x225,0x27d,0x2d5,0x32d,0x385,0x3dd,0x435,0x48d,0x4e5,0x53d,0x595,0x5ed,0x645,0x69d,0x6f5,0x74d,0x7a5,0x7fd,0x855,0x8ad,0x049,0x0a1,0x0f9,0x151,0x1a9,0x201,0x259 },
|
||||
{ 0x5b6,0x60e,0x666,0x6be,0x716,0x76e,0x7c6,0x81e,0x876,0x012,0x06a,0x0c2,0x11a,0x172,0x1ca,0x222,0x27a,0x2d2,0x32a,0x382,0x3da,0x432,0x48a,0x4e2,0x53a,0x592,0x5ea,0x642,0x69a,0x6f2,0x74a,0x7a2,0x7fa,0x852,0x8aa,0x046,0x09e,0x0f6,0x14e,0x1a6,0x1fe,0x256,0x2ae },
|
||||
{ 0x5b7,0x60f,0x667,0x6bf,0x717,0x76f,0x7c7,0x81f,0x877,0x013,0x06b,0x0c3,0x11b,0x173,0x1cb,0x223,0x27b,0x2d3,0x32b,0x383,0x3db,0x433,0x48b,0x4e3,0x53b,0x593,0x5eb,0x643,0x69b,0x6f3,0x74b,0x7a3,0x7fb,0x853,0x8ab,0x047,0x09f,0x0f7,0x14f,0x1a7,0x1ff,0x257,0x2af },
|
||||
{ 0x60c,0x664,0x6bc,0x714,0x76c,0x7c4,0x81c,0x874,0x010,0x068,0x0c0,0x118,0x170,0x1c8,0x220,0x278,0x2d0,0x328,0x380,0x3d8,0x430,0x488,0x4e0,0x538,0x590,0x5e8,0x640,0x698,0x6f0,0x748,0x7a0,0x7f8,0x850,0x8a8,0x044,0x09c,0x0f4,0x14c,0x1a4,0x1fc,0x254,0x2ac,0x304 },
|
||||
{ 0x60d,0x665,0x6bd,0x715,0x76d,0x7c5,0x81d,0x875,0x011,0x069,0x0c1,0x119,0x171,0x1c9,0x221,0x279,0x2d1,0x329,0x381,0x3d9,0x431,0x489,0x4e1,0x539,0x591,0x5e9,0x641,0x699,0x6f1,0x749,0x7a1,0x7f9,0x851,0x8a9,0x045,0x09d,0x0f5,0x14d,0x1a5,0x1fd,0x255,0x2ad,0x305 },
|
||||
{ 0x662,0x6ba,0x712,0x76a,0x7c2,0x81a,0x872,0x00e,0x066,0x0be,0x116,0x16e,0x1c6,0x21e,0x276,0x2ce,0x326,0x37e,0x3d6,0x42e,0x486,0x4de,0x536,0x58e,0x5e6,0x63e,0x696,0x6ee,0x746,0x79e,0x7f6,0x84e,0x8a6,0x042,0x09a,0x0f2,0x14a,0x1a2,0x1fa,0x252,0x2aa,0x302,0x35a },
|
||||
{ 0x663,0x6bb,0x713,0x76b,0x7c3,0x81b,0x873,0x00f,0x067,0x0bf,0x117,0x16f,0x1c7,0x21f,0x277,0x2cf,0x327,0x37f,0x3d7,0x42f,0x487,0x4df,0x537,0x58f,0x5e7,0x63f,0x697,0x6ef,0x747,0x79f,0x7f7,0x84f,0x8a7,0x043,0x09b,0x0f3,0x14b,0x1a3,0x1fb,0x253,0x2ab,0x303,0x35b },
|
||||
{ 0x6b8,0x710,0x768,0x7c0,0x818,0x870,0x00c,0x064,0x0bc,0x114,0x16c,0x1c4,0x21c,0x274,0x2cc,0x324,0x37c,0x3d4,0x42c,0x484,0x4dc,0x534,0x58c,0x5e4,0x63c,0x694,0x6ec,0x744,0x79c,0x7f4,0x84c,0x8a4,0x040,0x098,0x0f0,0x148,0x1a0,0x1f8,0x250,0x2a8,0x300,0x358,0x3b0 },
|
||||
{ 0x6b9,0x711,0x769,0x7c1,0x819,0x871,0x00d,0x065,0x0bd,0x115,0x16d,0x1c5,0x21d,0x275,0x2cd,0x325,0x37d,0x3d5,0x42d,0x485,0x4dd,0x535,0x58d,0x5e5,0x63d,0x695,0x6ed,0x745,0x79d,0x7f5,0x84d,0x8a5,0x041,0x099,0x0f1,0x149,0x1a1,0x1f9,0x251,0x2a9,0x301,0x359,0x3b1 },
|
||||
{ 0x70e,0x766,0x7be,0x816,0x86e,0x00a,0x062,0x0ba,0x112,0x16a,0x1c2,0x21a,0x272,0x2ca,0x322,0x37a,0x3d2,0x42a,0x482,0x4da,0x532,0x58a,0x5e2,0x63a,0x692,0x6ea,0x742,0x79a,0x7f2,0x84a,0x8a2,0x03e,0x096,0x0ee,0x146,0x19e,0x1f6,0x24e,0x2a6,0x2fe,0x356,0x3ae,0x406 },
|
||||
{ 0x70f,0x767,0x7bf,0x817,0x86f,0x00b,0x063,0x0bb,0x113,0x16b,0x1c3,0x21b,0x273,0x2cb,0x323,0x37b,0x3d3,0x42b,0x483,0x4db,0x533,0x58b,0x5e3,0x63b,0x693,0x6eb,0x743,0x79b,0x7f3,0x84b,0x8a3,0x03f,0x097,0x0ef,0x147,0x19f,0x1f7,0x24f,0x2a7,0x2ff,0x357,0x3af,0x407 },
|
||||
{ 0x764,0x7bc,0x814,0x86c,0x008,0x060,0x0b8,0x110,0x168,0x1c0,0x218,0x270,0x2c8,0x320,0x378,0x3d0,0x428,0x480,0x4d8,0x530,0x588,0x5e0,0x638,0x690,0x6e8,0x740,0x798,0x7f0,0x848,0x8a0,0x03c,0x094,0x0ec,0x144,0x19c,0x1f4,0x24c,0x2a4,0x2fc,0x354,0x3ac,0x404,0x45c },
|
||||
{ 0x765,0x7bd,0x815,0x86d,0x009,0x061,0x0b9,0x111,0x169,0x1c1,0x219,0x271,0x2c9,0x321,0x379,0x3d1,0x429,0x481,0x4d9,0x531,0x589,0x5e1,0x639,0x691,0x6e9,0x741,0x799,0x7f1,0x849,0x8a1,0x03d,0x095,0x0ed,0x145,0x19d,0x1f5,0x24d,0x2a5,0x2fd,0x355,0x3ad,0x405,0x45d },
|
||||
{ 0x7ba,0x812,0x86a,0x006,0x05e,0x0b6,0x10e,0x166,0x1be,0x216,0x26e,0x2c6,0x31e,0x376,0x3ce,0x426,0x47e,0x4d6,0x52e,0x586,0x5de,0x636,0x68e,0x6e6,0x73e,0x796,0x7ee,0x846,0x89e,0x03a,0x092,0x0ea,0x142,0x19a,0x1f2,0x24a,0x2a2,0x2fa,0x352,0x3aa,0x402,0x45a,0x4b2 },
|
||||
{ 0x7bb,0x813,0x86b,0x007,0x05f,0x0b7,0x10f,0x167,0x1bf,0x217,0x26f,0x2c7,0x31f,0x377,0x3cf,0x427,0x47f,0x4d7,0x52f,0x587,0x5df,0x637,0x68f,0x6e7,0x73f,0x797,0x7ef,0x847,0x89f,0x03b,0x093,0x0eb,0x143,0x19b,0x1f3,0x24b,0x2a3,0x2fb,0x353,0x3ab,0x403,0x45b,0x4b3 },
|
||||
{ 0x810,0x868,0x004,0x05c,0x0b4,0x10c,0x164,0x1bc,0x214,0x26c,0x2c4,0x31c,0x374,0x3cc,0x424,0x47c,0x4d4,0x52c,0x584,0x5dc,0x634,0x68c,0x6e4,0x73c,0x794,0x7ec,0x844,0x89c,0x038,0x090,0x0e8,0x140,0x198,0x1f0,0x248,0x2a0,0x2f8,0x350,0x3a8,0x400,0x458,0x4b0,0x508 },
|
||||
{ 0x811,0x869,0x005,0x05d,0x0b5,0x10d,0x165,0x1bd,0x215,0x26d,0x2c5,0x31d,0x375,0x3cd,0x425,0x47d,0x4d5,0x52d,0x585,0x5dd,0x635,0x68d,0x6e5,0x73d,0x795,0x7ed,0x845,0x89d,0x039,0x091,0x0e9,0x141,0x199,0x1f1,0x249,0x2a1,0x2f9,0x351,0x3a9,0x401,0x459,0x4b1,0x509 },
|
||||
{ 0x866,0x002,0x05a,0x0b2,0x10a,0x162,0x1ba,0x212,0x26a,0x2c2,0x31a,0x372,0x3ca,0x422,0x47a,0x4d2,0x52a,0x582,0x5da,0x632,0x68a,0x6e2,0x73a,0x792,0x7ea,0x842,0x89a,0x036,0x08e,0x0e6,0x13e,0x196,0x1ee,0x246,0x29e,0x2f6,0x34e,0x3a6,0x3fe,0x456,0x4ae,0x506,0x55e },
|
||||
{ 0x867,0x003,0x05b,0x0b3,0x10b,0x163,0x1bb,0x213,0x26b,0x2c3,0x31b,0x373,0x3cb,0x423,0x47b,0x4d3,0x52b,0x583,0x5db,0x633,0x68b,0x6e3,0x73b,0x793,0x7eb,0x843,0x89b,0x037,0x08f,0x0e7,0x13f,0x197,0x1ef,0x247,0x29f,0x2f7,0x34f,0x3a7,0x3ff,0x457,0x4af,0x507,0x55f }
|
||||
};
|
||||
|
||||
/*-------------------------------------------------
|
||||
* ecc_source_byte - return data from the sector
|
||||
* at the given offset, masking anything
|
||||
* particular to a mode
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline uint8_t ecc_source_byte(const uint8_t *sector, uint32_t offset)
|
||||
{
|
||||
/* in mode 2 always treat these as 0 bytes */
|
||||
return (sector[MODE_OFFSET] == 2 && offset < 4) ? 0x00 : sector[SYNC_OFFSET + SYNC_NUM_BYTES + offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t &val1, uint8_t &val2)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_compute_bytes - calculate an ECC value (P or Q)
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param sector The sector.
|
||||
* @param row The row.
|
||||
* @param rowlen The rowlen.
|
||||
* @param [in,out] val1 The first value.
|
||||
* @param [in,out] val2 The second value.
|
||||
*/
|
||||
|
||||
void ecc_compute_bytes(const uint8_t *sector, const uint16_t *row, int rowlen, uint8_t *val1, uint8_t *val2)
|
||||
{
|
||||
int component;
|
||||
*val1 = *val2 = 0;
|
||||
for (component = 0; component < rowlen; component++)
|
||||
{
|
||||
*val1 ^= ecc_source_byte(sector, row[component]);
|
||||
*val2 ^= ecc_source_byte(sector, row[component]);
|
||||
*val1 = ecclow[*val1];
|
||||
}
|
||||
*val1 = ecchigh[ecclow[*val1] ^ *val2];
|
||||
*val2 ^= *val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn int ecc_verify(const uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_verify - verify the P and Q ECC codes in a sector
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param sector The sector.
|
||||
*
|
||||
* @return true if it succeeds, false if it fails.
|
||||
*/
|
||||
|
||||
int ecc_verify(const uint8_t *sector)
|
||||
{
|
||||
int byte;
|
||||
/* first verify P bytes */
|
||||
for (byte = 0; byte < ECC_P_NUM_BYTES; byte++)
|
||||
{
|
||||
uint8_t val1, val2;
|
||||
ecc_compute_bytes(sector, poffsets[byte], ECC_P_COMP, &val1, &val2);
|
||||
if (sector[ECC_P_OFFSET + byte] != val1 || sector[ECC_P_OFFSET + ECC_P_NUM_BYTES + byte] != val2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* then verify Q bytes */
|
||||
for (byte = 0; byte < ECC_Q_NUM_BYTES; byte++)
|
||||
{
|
||||
uint8_t val1, val2;
|
||||
ecc_compute_bytes(sector, qoffsets[byte], ECC_Q_COMP, &val1, &val2);
|
||||
if (sector[ECC_Q_OFFSET + byte] != val1 || sector[ECC_Q_OFFSET + ECC_Q_NUM_BYTES + byte] != val2)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_generate(uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_generate - generate the P and Q ECC codes for a sector, overwriting any
|
||||
* existing codes
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param [in,out] sector If non-null, the sector.
|
||||
*/
|
||||
|
||||
void ecc_generate(uint8_t *sector)
|
||||
{
|
||||
int byte;
|
||||
/* first verify P bytes */
|
||||
for (byte = 0; byte < ECC_P_NUM_BYTES; byte++)
|
||||
ecc_compute_bytes(sector, poffsets[byte], ECC_P_COMP, §or[ECC_P_OFFSET + byte], §or[ECC_P_OFFSET + ECC_P_NUM_BYTES + byte]);
|
||||
|
||||
/* then verify Q bytes */
|
||||
for (byte = 0; byte < ECC_Q_NUM_BYTES; byte++)
|
||||
ecc_compute_bytes(sector, qoffsets[byte], ECC_Q_COMP, §or[ECC_Q_OFFSET + byte], §or[ECC_Q_OFFSET + ECC_Q_NUM_BYTES + byte]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void ecc_clear(uint8_t *sector)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* ecc_clear - erase the ECC P and Q cods to 0 within a sector
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param [in,out] sector If non-null, the sector.
|
||||
*/
|
||||
|
||||
void ecc_clear(uint8_t *sector)
|
||||
{
|
||||
memset(§or[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES);
|
||||
memset(§or[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES);
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
cdrom.h
|
||||
|
||||
Generic MAME cd-rom implementation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CDROM_H__
|
||||
#define __CDROM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define CD_MAX_TRACKS (99) /* AFAIK the theoretical limit */
|
||||
#define CD_MAX_SECTOR_DATA (2352)
|
||||
#define CD_MAX_SUBCODE_DATA (96)
|
||||
|
||||
#define CD_FRAME_SIZE (CD_MAX_SECTOR_DATA + CD_MAX_SUBCODE_DATA)
|
||||
#define CD_FRAMES_PER_HUNK (8)
|
||||
|
||||
#define CD_METADATA_WORDS (1+(CD_MAX_TRACKS * 6))
|
||||
|
||||
enum
|
||||
{
|
||||
CD_TRACK_MODE1 = 0, /* mode 1 2048 bytes/sector */
|
||||
CD_TRACK_MODE1_RAW, /* mode 1 2352 bytes/sector */
|
||||
CD_TRACK_MODE2, /* mode 2 2336 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM1, /* mode 2 2048 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM2, /* mode 2 2324 bytes/sector */
|
||||
CD_TRACK_MODE2_FORM_MIX, /* mode 2 2336 bytes/sector */
|
||||
CD_TRACK_MODE2_RAW, /* mode 2 2352 bytes / sector */
|
||||
CD_TRACK_AUDIO, /* redbook audio track 2352 bytes/sector (588 samples) */
|
||||
|
||||
CD_TRACK_RAW_DONTCARE /* special flag for cdrom_read_data: just return me whatever is there */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
|
||||
CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
|
||||
CD_SUB_NONE /* no subcode data stored */
|
||||
};
|
||||
|
||||
#define CD_FLAG_GDROM 0x00000001 /* disc is a GD-ROM, all tracks should be stored with GD-ROM metadata */
|
||||
#define CD_FLAG_GDROMLE 0x00000002 /* legacy GD-ROM, with little-endian CDDA data */
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* ECC utilities */
|
||||
int ecc_verify(const uint8_t *sector);
|
||||
void ecc_generate(uint8_t *sector);
|
||||
void ecc_clear(uint8_t *sector);
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
static inline uint32_t msf_to_lba(uint32_t msf)
|
||||
{
|
||||
return ( ((msf&0x00ff0000)>>16) * 60 * 75) + (((msf&0x0000ff00)>>8) * 75) + ((msf&0x000000ff)>>0);
|
||||
}
|
||||
|
||||
static inline uint32_t lba_to_msf(uint32_t lba)
|
||||
{
|
||||
uint8_t m, s, f;
|
||||
|
||||
m = lba / (60 * 75);
|
||||
lba -= m * (60 * 75);
|
||||
s = lba / 75;
|
||||
f = lba % 75;
|
||||
|
||||
return ((m / 10) << 20) | ((m % 10) << 16) |
|
||||
((s / 10) << 12) | ((s % 10) << 8) |
|
||||
((f / 10) << 4) | ((f % 10) << 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* segacd needs it like this.. investigate
|
||||
* Angelo also says PCE tracks often start playing at the
|
||||
* wrong address.. related?
|
||||
**/
|
||||
static inline uint32_t lba_to_msf_alt(int lba)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
ret |= ((lba / (60 * 75))&0xff)<<16;
|
||||
ret |= (((lba / 75) % 60)&0xff)<<8;
|
||||
ret |= ((lba % 75)&0xff)<<0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __CDROM_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -42,8 +42,11 @@
|
|||
#ifndef __CHD_H__
|
||||
#define __CHD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "coretypes.h"
|
||||
#include "deps/coreio/coreio.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -122,6 +125,49 @@
|
|||
0x00000001 - set if this drive has a parent
|
||||
0x00000002 - set if this drive allows writes
|
||||
|
||||
=========================================================================
|
||||
|
||||
V5 header:
|
||||
|
||||
[ 0] char tag[8]; // 'MComprHD'
|
||||
[ 8] uint32_t length; // length of header (including tag and length fields)
|
||||
[ 12] uint32_t version; // drive format version
|
||||
[ 16] uint32_t compressors[4];// which custom compressors are used?
|
||||
[ 32] uint64_t logicalbytes; // logical size of the data (in bytes)
|
||||
[ 40] uint64_t mapoffset; // offset to the map
|
||||
[ 48] uint64_t metaoffset; // offset to the first blob of metadata
|
||||
[ 56] uint32_t hunkbytes; // number of bytes per hunk (512k maximum)
|
||||
[ 60] uint32_t unitbytes; // number of bytes per unit within each hunk
|
||||
[ 64] uint8_t rawsha1[20]; // raw data SHA1
|
||||
[ 84] uint8_t sha1[20]; // combined raw+meta SHA1
|
||||
[104] uint8_t parentsha1[20];// combined raw+meta SHA1 of parent
|
||||
[124] (V5 header length)
|
||||
|
||||
If parentsha1 != 0, we have a parent (no need for flags)
|
||||
If compressors[0] == 0, we are uncompressed (including maps)
|
||||
|
||||
V5 uncompressed map format:
|
||||
|
||||
[ 0] uint32_t offset; // starting offset / hunk size
|
||||
|
||||
V5 compressed map format header:
|
||||
|
||||
[ 0] uint32_t length; // length of compressed map
|
||||
[ 4] UINT48 datastart; // offset of first block
|
||||
[ 10] uint16_t crc; // crc-16 of the map
|
||||
[ 12] uint8_t lengthbits; // bits used to encode complength
|
||||
[ 13] uint8_t hunkbits; // bits used to encode self-refs
|
||||
[ 14] uint8_t parentunitbits; // bits used to encode parent unit refs
|
||||
[ 15] uint8_t reserved; // future use
|
||||
[ 16] (compressed header length)
|
||||
|
||||
Each compressed map entry, once expanded, looks like:
|
||||
|
||||
[ 0] uint8_t compression; // compression type
|
||||
[ 1] UINT24 complength; // compressed length
|
||||
[ 4] UINT48 offset; // offset
|
||||
[ 10] uint16_t crc; // crc-16 of the data
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
@ -130,12 +176,14 @@
|
|||
***************************************************************************/
|
||||
|
||||
/* header information */
|
||||
#define CHD_HEADER_VERSION 4
|
||||
#define CHD_HEADER_VERSION 5
|
||||
#define CHD_V1_HEADER_SIZE 76
|
||||
#define CHD_V2_HEADER_SIZE 80
|
||||
#define CHD_V3_HEADER_SIZE 120
|
||||
#define CHD_V4_HEADER_SIZE 108
|
||||
#define CHD_MAX_HEADER_SIZE CHD_V4_HEADER_SIZE
|
||||
#define CHD_V5_HEADER_SIZE 124
|
||||
|
||||
#define CHD_MAX_HEADER_SIZE CHD_V5_HEADER_SIZE
|
||||
|
||||
/* checksumming information */
|
||||
#define CHD_MD5_BYTES 16
|
||||
|
@ -146,12 +194,21 @@
|
|||
#define CHDFLAGS_IS_WRITEABLE 0x00000002
|
||||
#define CHDFLAGS_UNDEFINED 0xfffffffc
|
||||
|
||||
#define CHD_MAKE_TAG(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
|
||||
/* compression types */
|
||||
#define CHDCOMPRESSION_NONE 0
|
||||
#define CHDCOMPRESSION_ZLIB 1
|
||||
#define CHDCOMPRESSION_ZLIB_PLUS 2
|
||||
#define CHDCOMPRESSION_AV 3
|
||||
|
||||
#define CHD_CODEC_NONE 0
|
||||
#define CHD_CODEC_ZLIB CHD_MAKE_TAG('z','l','i','b')
|
||||
/* general codecs with CD frontend */
|
||||
#define CHD_CODEC_CD_ZLIB CHD_MAKE_TAG('c','d','z','l')
|
||||
#define CHD_CODEC_CD_LZMA CHD_MAKE_TAG('c','d','l','z')
|
||||
#define CHD_CODEC_CD_FLAC CHD_MAKE_TAG('c','d','f','l')
|
||||
|
||||
/* A/V codec configuration parameters */
|
||||
#define AV_CODEC_COMPRESS_CONFIG 1
|
||||
#define AV_CODEC_DECOMPRESS_CONFIG 2
|
||||
|
@ -164,31 +221,34 @@
|
|||
#define CHD_MDFLAGS_CHECKSUM 0x01 /* indicates data is checksummed */
|
||||
|
||||
/* standard hard disk metadata */
|
||||
#define HARD_DISK_METADATA_TAG 0x47444444 /* 'GDDD' */
|
||||
#define HARD_DISK_METADATA_TAG CHD_MAKE_TAG('G','D','D','D')
|
||||
#define HARD_DISK_METADATA_FORMAT "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d"
|
||||
|
||||
/* hard disk identify information */
|
||||
#define HARD_DISK_IDENT_METADATA_TAG 0x49444e54 /* 'IDNT' */
|
||||
#define HARD_DISK_IDENT_METADATA_TAG CHD_MAKE_TAG('I','D','N','T')
|
||||
|
||||
/* hard disk key information */
|
||||
#define HARD_DISK_KEY_METADATA_TAG 0x4b455920 /* 'KEY ' */
|
||||
#define HARD_DISK_KEY_METADATA_TAG CHD_MAKE_TAG('K','E','Y',' ')
|
||||
|
||||
/* pcmcia CIS information */
|
||||
#define PCMCIA_CIS_METADATA_TAG 0x43495320 /* 'CIS ' */
|
||||
#define PCMCIA_CIS_METADATA_TAG CHD_MAKE_TAG('C','I','S',' ')
|
||||
|
||||
/* standard CD-ROM metadata */
|
||||
#define CDROM_OLD_METADATA_TAG 0x43484344 /* 'CHCD' */
|
||||
#define CDROM_TRACK_METADATA_TAG 0x43485452 /* 'CHTR' */
|
||||
#define CDROM_OLD_METADATA_TAG CHD_MAKE_TAG('C','H','C','D')
|
||||
#define CDROM_TRACK_METADATA_TAG CHD_MAKE_TAG('C','H','T','R')
|
||||
#define CDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d"
|
||||
#define CDROM_TRACK_METADATA2_TAG 0x43485432 /* 'CHT2' */
|
||||
#define CDROM_TRACK_METADATA2_TAG CHD_MAKE_TAG('C','H','T','2')
|
||||
#define CDROM_TRACK_METADATA2_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"
|
||||
#define GDROM_OLD_METADATA_TAG CHD_MAKE_TAG('C','H','G','T')
|
||||
#define GDROM_TRACK_METADATA_TAG CHD_MAKE_TAG('C', 'H', 'G', 'D')
|
||||
#define GDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PAD:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"
|
||||
|
||||
/* standard A/V metadata */
|
||||
#define AV_METADATA_TAG 0x41564156 /* 'AVAV' */
|
||||
#define AV_METADATA_TAG CHD_MAKE_TAG('A','V','A','V')
|
||||
#define AV_METADATA_FORMAT "FPS:%d.%06d WIDTH:%d HEIGHT:%d INTERLACED:%d CHANNELS:%d SAMPLERATE:%d"
|
||||
|
||||
/* A/V laserdisc frame metadata */
|
||||
#define AV_LD_METADATA_TAG 0x41564C44 /* 'AVLD' */
|
||||
#define AV_LD_METADATA_TAG CHD_MAKE_TAG('A','V','L','D')
|
||||
|
||||
/* CHD open values */
|
||||
#define CHD_OPEN_READ 1
|
||||
|
@ -245,16 +305,24 @@ struct _chd_header
|
|||
UINT32 length; /* length of header data */
|
||||
UINT32 version; /* drive format version */
|
||||
UINT32 flags; /* flags field */
|
||||
UINT32 compression; /* compression type */
|
||||
UINT32 compression[4]; /* compression type */
|
||||
UINT32 hunkbytes; /* number of bytes per hunk */
|
||||
UINT32 totalhunks; /* total # of hunks represented */
|
||||
UINT64 logicalbytes; /* logical size of the data */
|
||||
UINT64 metaoffset; /* offset in file of first metadata */
|
||||
UINT64 mapoffset; /* TOOD V5 */
|
||||
UINT8 md5[CHD_MD5_BYTES]; /* overall MD5 checksum */
|
||||
UINT8 parentmd5[CHD_MD5_BYTES]; /* overall MD5 checksum of parent */
|
||||
UINT8 sha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum */
|
||||
UINT8 rawsha1[CHD_SHA1_BYTES]; /* SHA1 checksum of raw data */
|
||||
UINT8 parentsha1[CHD_SHA1_BYTES]; /* overall SHA1 checksum of parent */
|
||||
UINT32 unitbytes; /* TODO V5 */
|
||||
UINT64 unitcount; /* TODO V5 */
|
||||
UINT32 hunkcount; /* TODO V5 */
|
||||
|
||||
/* map information */
|
||||
UINT32 mapentrybytes; /* length of each entry in a map (V5) */
|
||||
UINT8* rawmap; /* raw map data */
|
||||
|
||||
UINT32 obsolete_cylinders; /* obsolete field -- do not use! */
|
||||
UINT32 obsolete_sectors; /* obsolete field -- do not use! */
|
||||
|
@ -283,13 +351,13 @@ struct _chd_verify_result
|
|||
/* ----- CHD file management ----- */
|
||||
|
||||
/* create a new CHD file fitting the given description */
|
||||
chd_error chd_create(const char *filename, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent);
|
||||
/* chd_error chd_create(const char *filename, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */
|
||||
|
||||
/* same as chd_create(), but accepts an already-opened core_file object */
|
||||
chd_error chd_create_file(core_file *file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent);
|
||||
/* chd_error chd_create_file(core_file *file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */
|
||||
|
||||
/* open an existing CHD file */
|
||||
chd_error chd_open(const wchar *filename, int mode, chd_file *parent, chd_file **chd);
|
||||
chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd);
|
||||
|
||||
|
||||
/* close a CHD file */
|
||||
|
@ -326,19 +394,6 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex,
|
|||
|
||||
|
||||
|
||||
/* ----- verification management ----- */
|
||||
|
||||
/* begin verifying a CHD */
|
||||
chd_error chd_verify_begin(chd_file *chd);
|
||||
|
||||
/* verify a single hunk of data */
|
||||
chd_error chd_verify_hunk(chd_file *chd);
|
||||
|
||||
/* finish verifying a CHD, returning the computed MD5 and SHA1 */
|
||||
chd_error chd_verify_finish(chd_file *chd, chd_verify_result *result);
|
||||
|
||||
|
||||
|
||||
/* ----- codec interfaces ----- */
|
||||
|
||||
/* set internal codec parameters */
|
||||
|
@ -347,5 +402,8 @@ chd_error chd_codec_config(chd_file *chd, int param, void *config);
|
|||
/* return a string description of a codec */
|
||||
const char *chd_get_codec_name(UINT32 codec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CHD_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +1,34 @@
|
|||
#pragma once
|
||||
#ifndef __CORETYPES_H__
|
||||
#define __CORETYPES_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef u64 UINT64;
|
||||
typedef u32 UINT32;
|
||||
typedef u16 UINT16;
|
||||
typedef u8 UINT8;
|
||||
|
||||
typedef s64 INT64;
|
||||
typedef s32 INT32;
|
||||
typedef s16 INT16;
|
||||
typedef s8 INT8;
|
||||
|
||||
#ifndef INLINE
|
||||
#define INLINE inline
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
typedef uint64_t UINT64;
|
||||
typedef uint32_t UINT32;
|
||||
typedef uint16_t UINT16;
|
||||
typedef uint8_t UINT8;
|
||||
|
||||
typedef int64_t INT64;
|
||||
typedef int32_t INT32;
|
||||
typedef int16_t INT16;
|
||||
typedef int8_t INT8;
|
||||
|
||||
#define core_file FILE
|
||||
#define core_fopen(file) fopen(file, "rb")
|
||||
#define core_fseek fseek
|
||||
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
|
||||
#define core_fclose fclose
|
||||
#define core_ftell ftell
|
||||
static size_t core_fsize(core_file *f)
|
||||
{
|
||||
long p = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
long rv = ftell(f);
|
||||
fseek(f, p, SEEK_SET);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
#if defined(CHD5_FLAC)
|
||||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
flac.c
|
||||
|
||||
FLAC compression wrappers
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "flac.h"
|
||||
|
||||
/***************************************************************************
|
||||
* FLAC DECODER
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
static FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes);
|
||||
static void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
||||
static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
|
||||
static FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void* client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
|
||||
static void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
|
||||
|
||||
/* getters (valid after reset) */
|
||||
static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
|
||||
static uint8_t channels(flac_decoder *decoder) { return decoder->channels; }
|
||||
static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
|
||||
static uint32_t total_samples(flac_decoder *decoder) { return FLAC__stream_decoder_get_total_samples(decoder->decoder); }
|
||||
static FLAC__StreamDecoderState state(flac_decoder *decoder) { return FLAC__stream_decoder_get_state(decoder->decoder); }
|
||||
static const char *state_string(flac_decoder *decoder) { return FLAC__stream_decoder_get_resolved_state_string(decoder->decoder); }
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flac_decoder - constructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_init(flac_decoder *decoder)
|
||||
{
|
||||
decoder->decoder = FLAC__stream_decoder_new();
|
||||
decoder->sample_rate = 0;
|
||||
decoder->channels = 0;
|
||||
decoder->bits_per_sample = 0;
|
||||
decoder->compressed_offset = 0;
|
||||
decoder->compressed_start = NULL;
|
||||
decoder->compressed_length = 0;
|
||||
decoder->compressed2_start = NULL;
|
||||
decoder->compressed2_length = 0;
|
||||
decoder->uncompressed_offset = 0;
|
||||
decoder->uncompressed_length = 0;
|
||||
decoder->uncompressed_swap = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* flac_decoder - destructor
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_free(flac_decoder* decoder)
|
||||
{
|
||||
if ((decoder != NULL) && (decoder->decoder != NULL))
|
||||
FLAC__stream_decoder_delete(decoder->decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* reset - reset state with the original
|
||||
* parameters
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static int flac_decoder_internal_reset(flac_decoder* decoder)
|
||||
{
|
||||
decoder->compressed_offset = 0;
|
||||
if (FLAC__stream_decoder_init_stream(decoder->decoder,
|
||||
&flac_decoder_read_callback_static,
|
||||
NULL,
|
||||
&flac_decoder_tell_callback_static,
|
||||
NULL,
|
||||
NULL,
|
||||
&flac_decoder_write_callback_static,
|
||||
&flac_decoder_metadata_callback_static,
|
||||
&flac_decoder_error_callback_static, decoder) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
||||
return 0;
|
||||
return FLAC__stream_decoder_process_until_end_of_metadata(decoder->decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* reset - reset state with new memory parameters
|
||||
* and a custom-generated header
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length)
|
||||
{
|
||||
/* modify the template header with our parameters */
|
||||
static const uint8_t s_header_template[0x2a] =
|
||||
{
|
||||
0x66, 0x4C, 0x61, 0x43, /* +00: 'fLaC' stream header */
|
||||
0x80, /* +04: metadata block type 0 (STREAMINFO), */
|
||||
/* flagged as last block */
|
||||
0x00, 0x00, 0x22, /* +05: metadata block length = 0x22 */
|
||||
0x00, 0x00, /* +08: minimum block size */
|
||||
0x00, 0x00, /* +0A: maximum block size */
|
||||
0x00, 0x00, 0x00, /* +0C: minimum frame size (0 == unknown) */
|
||||
0x00, 0x00, 0x00, /* +0F: maximum frame size (0 == unknown) */
|
||||
0x0A, 0xC4, 0x42, 0xF0, 0x00, 0x00, 0x00, 0x00, /* +12: sample rate (0x0ac44 == 44100), */
|
||||
/* numchannels (2), sample bits (16), */
|
||||
/* samples in stream (0 == unknown) */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* +1A: MD5 signature (0 == none) */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
|
||||
};
|
||||
memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
|
||||
decoder->custom_header[0x08] = decoder->custom_header[0x0a] = block_size >> 8;
|
||||
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = block_size & 0xff;
|
||||
decoder->custom_header[0x12] = sample_rate >> 12;
|
||||
decoder->custom_header[0x13] = sample_rate >> 4;
|
||||
decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
||||
|
||||
/* configure the header ahead of the provided buffer */
|
||||
decoder->compressed_start = (const FLAC__byte *)(decoder->custom_header);
|
||||
decoder->compressed_length = sizeof(decoder->custom_header);
|
||||
decoder->compressed2_start = (const FLAC__byte *)(buffer);
|
||||
decoder->compressed2_length = length;
|
||||
return flac_decoder_internal_reset(decoder);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* decode_interleaved - decode to an interleaved
|
||||
* sound stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian)
|
||||
{
|
||||
/* configure the uncompressed buffer */
|
||||
memset(decoder->uncompressed_start, 0, sizeof(decoder->uncompressed_start));
|
||||
decoder->uncompressed_start[0] = samples;
|
||||
decoder->uncompressed_offset = 0;
|
||||
decoder->uncompressed_length = num_samples;
|
||||
decoder->uncompressed_swap = swap_endian;
|
||||
|
||||
/* loop until we get everything we want */
|
||||
while (decoder->uncompressed_offset < decoder->uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(decoder->decoder))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*-------------------------------------------------
|
||||
* decode - decode to an multiple independent
|
||||
* data streams
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_endian)
|
||||
{
|
||||
/* make sure we don't have too many channels */
|
||||
int chans = channels();
|
||||
if (chans > ARRAY_LENGTH(m_uncompressed_start))
|
||||
return false;
|
||||
|
||||
/* configure the uncompressed buffer */
|
||||
memset(m_uncompressed_start, 0, sizeof(m_uncompressed_start));
|
||||
for (int curchan = 0; curchan < chans; curchan++)
|
||||
m_uncompressed_start[curchan] = samples[curchan];
|
||||
m_uncompressed_offset = 0;
|
||||
m_uncompressed_length = num_samples;
|
||||
m_uncompressed_swap = swap_endian;
|
||||
|
||||
/* loop until we get everything we want */
|
||||
while (m_uncompressed_offset < m_uncompressed_length)
|
||||
if (!FLAC__stream_decoder_process_single(m_decoder))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------
|
||||
* finish - finish up the decode
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t flac_decoder_finish(flac_decoder* decoder)
|
||||
{
|
||||
/* get the final decoding position and move forward */
|
||||
FLAC__uint64 position = 0;
|
||||
FLAC__stream_decoder_get_decode_position(decoder->decoder, &position);
|
||||
FLAC__stream_decoder_finish(decoder->decoder);
|
||||
|
||||
/* adjust position if we provided the header */
|
||||
if (position == 0)
|
||||
return 0;
|
||||
if (decoder->compressed_start == (const FLAC__byte *)(decoder->custom_header))
|
||||
position -= decoder->compressed_length;
|
||||
return position;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* read_callback - handle reads from the input
|
||||
* stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
|
||||
{
|
||||
return flac_decoder_read_callback(client_data, buffer, bytes);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes)
|
||||
{
|
||||
flac_decoder* decoder = (flac_decoder*)client_data;
|
||||
|
||||
uint32_t expected = *bytes;
|
||||
|
||||
/* copy from primary buffer first */
|
||||
uint32_t outputpos = 0;
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
|
||||
memcpy(&buffer[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
|
||||
/* once we're out of that, copy from the secondary buffer */
|
||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
|
||||
{
|
||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed2_length - (decoder->compressed_offset - decoder->compressed_length));
|
||||
memcpy(&buffer[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
|
||||
outputpos += bytes_to_copy;
|
||||
decoder->compressed_offset += bytes_to_copy;
|
||||
}
|
||||
*bytes = outputpos;
|
||||
|
||||
/* return based on whether we ran out of data */
|
||||
return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* metadata_callback - handle STREAMINFO metadata
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||
{
|
||||
flac_decoder *fldecoder;
|
||||
/* ignore all but STREAMINFO metadata */
|
||||
if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO)
|
||||
return;
|
||||
|
||||
/* parse out the data we care about */
|
||||
fldecoder = (flac_decoder *)(client_data);
|
||||
fldecoder->sample_rate = metadata->data.stream_info.sample_rate;
|
||||
fldecoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
||||
fldecoder->channels = metadata->data.stream_info.channels;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* tell_callback - handle requests to find out
|
||||
* where in the input stream we are
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
||||
{
|
||||
*absolute_byte_offset = ((flac_decoder *)client_data)->compressed_offset;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* write_callback - handle writes to the output
|
||||
* stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
||||
{
|
||||
return flac_decoder_write_callback(client_data, frame, buffer);
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback(void *client_data, const FLAC__Frame *frame, const FLAC__int32 * const buffer[])
|
||||
{
|
||||
int sampnum, chan;
|
||||
int shift, blocksize;
|
||||
flac_decoder * decoder = (flac_decoder *)client_data;
|
||||
|
||||
assert(frame->header.channels == channels(decoder));
|
||||
|
||||
/* interleaved case */
|
||||
shift = decoder->uncompressed_swap ? 8 : 0;
|
||||
blocksize = frame->header.blocksize;
|
||||
if (decoder->uncompressed_start[1] == NULL)
|
||||
{
|
||||
int16_t *dest = decoder->uncompressed_start[0] + decoder->uncompressed_offset * frame->header.channels;
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
*dest++ = (int16_t)((((uint16_t)buffer[chan][sampnum]) << shift) | (((uint16_t)buffer[chan][sampnum]) >> shift));
|
||||
}
|
||||
|
||||
/* non-interleaved case */
|
||||
else
|
||||
{
|
||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
||||
for (chan = 0; chan < frame->header.channels; chan++)
|
||||
if (decoder->uncompressed_start[chan] != NULL)
|
||||
decoder->uncompressed_start[chan][decoder->uncompressed_offset] = (int16_t) ( (((uint16_t)(buffer[chan][sampnum])) << shift) | ( ((uint16_t)(buffer[chan][sampnum])) >> shift) );
|
||||
}
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn void flac_decoder::error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
*
|
||||
* @brief -------------------------------------------------
|
||||
* error_callback - handle errors (ignore them)
|
||||
* -------------------------------------------------.
|
||||
*
|
||||
* @param decoder The decoder.
|
||||
* @param status The status.
|
||||
* @param [in,out] client_data If non-null, information describing the client.
|
||||
*/
|
||||
|
||||
void flac_decoder_error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
||||
{
|
||||
}
|
||||
#endif // CHD5_FLAC
|
|
@ -0,0 +1,51 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
flac.h
|
||||
|
||||
FLAC compression wrappers
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FLAC_H__
|
||||
#define __FLAC_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "deps/flac/include/FLAC/all.h"
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
typedef struct _flac_decoder flac_decoder;
|
||||
struct _flac_decoder {
|
||||
/* output state */
|
||||
FLAC__StreamDecoder* decoder; /* actual encoder */
|
||||
uint32_t sample_rate; /* decoded sample rate */
|
||||
uint8_t channels; /* decoded number of channels */
|
||||
uint8_t bits_per_sample; /* decoded bits per sample */
|
||||
uint32_t compressed_offset; /* current offset in compressed data */
|
||||
const FLAC__byte * compressed_start; /* start of compressed data */
|
||||
uint32_t compressed_length; /* length of compressed data */
|
||||
const FLAC__byte * compressed2_start; /* start of compressed data */
|
||||
uint32_t compressed2_length; /* length of compressed data */
|
||||
int16_t * uncompressed_start[8]; /* pointer to start of uncompressed data (up to 8 streams) */
|
||||
uint32_t uncompressed_offset; /* current position in uncompressed data */
|
||||
uint32_t uncompressed_length; /* length of uncompressed data */
|
||||
int uncompressed_swap; /* swap uncompressed sample data */
|
||||
uint8_t custom_header[0x2a]; /* custom header */
|
||||
};
|
||||
|
||||
/* ======================> flac_decoder */
|
||||
|
||||
void flac_decoder_init(flac_decoder* decoder);
|
||||
void flac_decoder_free(flac_decoder* decoder);
|
||||
int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_channels, uint32_t block_size, const void *buffer, uint32_t length);
|
||||
int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian);
|
||||
uint32_t flac_decoder_finish(flac_decoder* decoder);
|
||||
|
||||
#endif /* __FLAC_H__ */
|
|
@ -0,0 +1,514 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
****************************************************************************
|
||||
|
||||
huffman.c
|
||||
|
||||
Static Huffman compression and decompression helpers.
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Maximum codelength is officially (alphabetsize - 1). This would be 255 bits
|
||||
(since we use 1 byte values). However, it is also dependent upon the number
|
||||
of samples used, as follows:
|
||||
|
||||
2 bits -> 3..4 samples
|
||||
3 bits -> 5..7 samples
|
||||
4 bits -> 8..12 samples
|
||||
5 bits -> 13..20 samples
|
||||
6 bits -> 21..33 samples
|
||||
7 bits -> 34..54 samples
|
||||
8 bits -> 55..88 samples
|
||||
9 bits -> 89..143 samples
|
||||
10 bits -> 144..232 samples
|
||||
11 bits -> 233..376 samples
|
||||
12 bits -> 377..609 samples
|
||||
13 bits -> 610..986 samples
|
||||
14 bits -> 987..1596 samples
|
||||
15 bits -> 1597..2583 samples
|
||||
16 bits -> 2584..4180 samples -> note that a 4k data size guarantees codelength <= 16 bits
|
||||
17 bits -> 4181..6764 samples
|
||||
18 bits -> 6765..10945 samples
|
||||
19 bits -> 10946..17710 samples
|
||||
20 bits -> 17711..28656 samples
|
||||
21 bits -> 28657..46367 samples
|
||||
22 bits -> 46368..75024 samples
|
||||
23 bits -> 75025..121392 samples
|
||||
24 bits -> 121393..196417 samples
|
||||
25 bits -> 196418..317810 samples
|
||||
26 bits -> 317811..514228 samples
|
||||
27 bits -> 514229..832039 samples
|
||||
28 bits -> 832040..1346268 samples
|
||||
29 bits -> 1346269..2178308 samples
|
||||
30 bits -> 2178309..3524577 samples
|
||||
31 bits -> 3524578..5702886 samples
|
||||
32 bits -> 5702887..9227464 samples
|
||||
|
||||
Looking at it differently, here is where powers of 2 fall into these buckets:
|
||||
|
||||
256 samples -> 11 bits max
|
||||
512 samples -> 12 bits max
|
||||
1k samples -> 14 bits max
|
||||
2k samples -> 15 bits max
|
||||
4k samples -> 16 bits max
|
||||
8k samples -> 18 bits max
|
||||
16k samples -> 19 bits max
|
||||
32k samples -> 21 bits max
|
||||
64k samples -> 22 bits max
|
||||
128k samples -> 24 bits max
|
||||
256k samples -> 25 bits max
|
||||
512k samples -> 27 bits max
|
||||
1M samples -> 28 bits max
|
||||
2M samples -> 29 bits max
|
||||
4M samples -> 31 bits max
|
||||
8M samples -> 32 bits max
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Delta-RLE encoding works as follows:
|
||||
|
||||
Starting value is assumed to be 0. All data is encoded as a delta
|
||||
from the previous value, such that final[i] = final[i - 1] + delta.
|
||||
Long runs of 0s are RLE-encoded as follows:
|
||||
|
||||
0x100 = repeat count of 8
|
||||
0x101 = repeat count of 9
|
||||
0x102 = repeat count of 10
|
||||
0x103 = repeat count of 11
|
||||
0x104 = repeat count of 12
|
||||
0x105 = repeat count of 13
|
||||
0x106 = repeat count of 14
|
||||
0x107 = repeat count of 15
|
||||
0x108 = repeat count of 16
|
||||
0x109 = repeat count of 32
|
||||
0x10a = repeat count of 64
|
||||
0x10b = repeat count of 128
|
||||
0x10c = repeat count of 256
|
||||
0x10d = repeat count of 512
|
||||
0x10e = repeat count of 1024
|
||||
0x10f = repeat count of 2048
|
||||
|
||||
Note that repeat counts are reset at the end of a row, so if a 0 run
|
||||
extends to the end of a row, a large repeat count may be used.
|
||||
|
||||
The reason for starting the run counts at 8 is that 0 is expected to
|
||||
be the most common symbol, and is typically encoded in 1 or 2 bits.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "huffman.h"
|
||||
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
/***************************************************************************
|
||||
* MACROS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define MAKE_LOOKUP(code,bits) (((code) << 5) | ((bits) & 0x1f))
|
||||
|
||||
/***************************************************************************
|
||||
* IMPLEMENTATION
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* huffman_context_base - create an encoding/
|
||||
* decoding context
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits)
|
||||
{
|
||||
/* limit to 24 bits */
|
||||
if (maxbits > 24)
|
||||
return NULL;
|
||||
|
||||
struct huffman_decoder* decoder = (struct huffman_decoder*)malloc(sizeof(struct huffman_decoder));
|
||||
decoder->numcodes = numcodes;
|
||||
decoder->maxbits = maxbits;
|
||||
decoder->lookup = (lookup_value*)malloc(sizeof(lookup_value) * (1 << maxbits));
|
||||
decoder->huffnode = (struct node_t*)malloc(sizeof(struct node_t) * numcodes);
|
||||
decoder->datahisto = NULL;
|
||||
decoder->prevdata = 0;
|
||||
decoder->rleremaining = 0;
|
||||
return decoder;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* decode_one - decode a single code from the
|
||||
* huffman stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* peek ahead to get maxbits worth of data */
|
||||
uint32_t bits = bitstream_peek(bitbuf, decoder->maxbits);
|
||||
|
||||
/* look it up, then remove the actual number of bits for this code */
|
||||
lookup_value lookup = decoder->lookup[bits];
|
||||
bitstream_remove(bitbuf, lookup & 0x1f);
|
||||
|
||||
/* return the value */
|
||||
return lookup >> 5;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* import_tree_rle - import an RLE-encoded
|
||||
* huffman tree from a source data stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* bits per entry depends on the maxbits */
|
||||
int numbits;
|
||||
if (decoder->maxbits >= 16)
|
||||
numbits = 5;
|
||||
else if (decoder->maxbits >= 8)
|
||||
numbits = 4;
|
||||
else
|
||||
numbits = 3;
|
||||
|
||||
/* loop until we read all the nodes */
|
||||
int curnode;
|
||||
for (curnode = 0; curnode < decoder->numcodes; )
|
||||
{
|
||||
/* a non-one value is just raw */
|
||||
int nodebits = bitstream_read(bitbuf, numbits);
|
||||
if (nodebits != 1)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
|
||||
/* a one value is an escape code */
|
||||
else
|
||||
{
|
||||
/* a double 1 is just a single 1 */
|
||||
nodebits = bitstream_read(bitbuf, numbits);
|
||||
if (nodebits == 1)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
|
||||
/* otherwise, we need one for value for the repeat count */
|
||||
else
|
||||
{
|
||||
int repcount = bitstream_read(bitbuf, numbits) + 3;
|
||||
while (repcount--)
|
||||
decoder->huffnode[curnode++].numbits = nodebits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure we ended up with the right number */
|
||||
if (curnode != decoder->numcodes)
|
||||
return HUFFERR_INVALID_DATA;
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
enum huffman_error error = huffman_assign_canonical_codes(decoder);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
|
||||
/* build the lookup table */
|
||||
huffman_build_lookup_table(decoder);
|
||||
|
||||
/* determine final input length and report errors */
|
||||
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
* import_tree_huffman - import a huffman-encoded
|
||||
* huffman tree from a source data stream
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||
{
|
||||
/* start by parsing the lengths for the small tree */
|
||||
struct huffman_decoder* smallhuff = create_huffman_decoder(24, 6);
|
||||
smallhuff->huffnode[0].numbits = bitstream_read(bitbuf, 3);
|
||||
int start = bitstream_read(bitbuf, 3) + 1;
|
||||
int count = 0;
|
||||
for (int index = 1; index < 24; index++)
|
||||
{
|
||||
if (index < start || count == 7)
|
||||
smallhuff->huffnode[index].numbits = 0;
|
||||
else
|
||||
{
|
||||
count = bitstream_read(bitbuf, 3);
|
||||
smallhuff->huffnode[index].numbits = (count == 7) ? 0 : count;
|
||||
}
|
||||
}
|
||||
|
||||
/* then regenerate the tree */
|
||||
enum huffman_error error = huffman_assign_canonical_codes(smallhuff);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
huffman_build_lookup_table(smallhuff);
|
||||
|
||||
/* determine the maximum length of an RLE count */
|
||||
uint32_t temp = decoder->numcodes - 9;
|
||||
uint8_t rlefullbits = 0;
|
||||
while (temp != 0)
|
||||
temp >>= 1, rlefullbits++;
|
||||
|
||||
/* now process the rest of the data */
|
||||
int last = 0;
|
||||
int curcode;
|
||||
for (curcode = 0; curcode < decoder->numcodes; )
|
||||
{
|
||||
int value = huffman_decode_one(smallhuff, bitbuf);
|
||||
if (value != 0)
|
||||
decoder->huffnode[curcode++].numbits = last = value - 1;
|
||||
else
|
||||
{
|
||||
int count = bitstream_read(bitbuf, 3) + 2;
|
||||
if (count == 7+2)
|
||||
count += bitstream_read(bitbuf, rlefullbits);
|
||||
for ( ; count != 0 && curcode < decoder->numcodes; count--)
|
||||
decoder->huffnode[curcode++].numbits = last;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure we ended up with the right number */
|
||||
if (curcode != decoder->numcodes)
|
||||
return HUFFERR_INVALID_DATA;
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
error = huffman_assign_canonical_codes(decoder);
|
||||
if (error != HUFFERR_NONE)
|
||||
return error;
|
||||
|
||||
/* build the lookup table */
|
||||
huffman_build_lookup_table(decoder);
|
||||
|
||||
/* determine final input length and report errors */
|
||||
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* compute_tree_from_histo - common backend for
|
||||
* computing a tree based on the data histogram
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* compute the number of data items in the histogram */
|
||||
uint32_t sdatacount = 0;
|
||||
for (int i = 0; i < decoder->numcodes; i++)
|
||||
sdatacount += decoder->datahisto[i];
|
||||
|
||||
/* binary search to achieve the optimum encoding */
|
||||
uint32_t lowerweight = 0;
|
||||
uint32_t upperweight = sdatacount * 2;
|
||||
while (1)
|
||||
{
|
||||
/* build a tree using the current weight */
|
||||
uint32_t curweight = (upperweight + lowerweight) / 2;
|
||||
int curmaxbits = huffman_build_tree(decoder, sdatacount, curweight);
|
||||
|
||||
/* apply binary search here */
|
||||
if (curmaxbits <= decoder->maxbits)
|
||||
{
|
||||
lowerweight = curweight;
|
||||
|
||||
/* early out if it worked with the raw weights, or if we're done searching */
|
||||
if (curweight == sdatacount || (upperweight - lowerweight) <= 1)
|
||||
break;
|
||||
}
|
||||
else
|
||||
upperweight = curweight;
|
||||
}
|
||||
|
||||
/* assign canonical codes for all nodes based on their code lengths */
|
||||
return huffman_assign_canonical_codes(decoder);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* INTERNAL FUNCTIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
* tree_node_compare - compare two tree nodes
|
||||
* by weight
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
static int huffman_tree_node_compare(const void *item1, const void *item2)
|
||||
{
|
||||
const struct node_t *node1 = *(const struct node_t **)item1;
|
||||
const struct node_t *node2 = *(const struct node_t **)item2;
|
||||
if (node2->weight != node1->weight)
|
||||
return node2->weight - node1->weight;
|
||||
if (node2->bits - node1->bits == 0)
|
||||
fprintf(stderr, "identical node sort keys, should not happen!\n");
|
||||
return (int)node1->bits - (int)node2->bits;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* build_tree - build a huffman tree based on the
|
||||
* data distribution
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight)
|
||||
{
|
||||
/* make a list of all non-zero nodes */
|
||||
struct node_t** list = (struct node_t**)malloc(sizeof(struct node_t*) * decoder->numcodes * 2);
|
||||
int listitems = 0;
|
||||
memset(decoder->huffnode, 0, decoder->numcodes * sizeof(decoder->huffnode[0]));
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
if (decoder->datahisto[curcode] != 0)
|
||||
{
|
||||
list[listitems++] = &decoder->huffnode[curcode];
|
||||
decoder->huffnode[curcode].count = decoder->datahisto[curcode];
|
||||
decoder->huffnode[curcode].bits = curcode;
|
||||
|
||||
/* scale the weight by the current effective length, ensuring we don't go to 0 */
|
||||
decoder->huffnode[curcode].weight = ((uint64_t)decoder->datahisto[curcode]) * ((uint64_t)totalweight) / ((uint64_t)totaldata);
|
||||
if (decoder->huffnode[curcode].weight == 0)
|
||||
decoder->huffnode[curcode].weight = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Pre-sort:\n");
|
||||
for (int i = 0; i < listitems; i++) {
|
||||
fprintf(stderr, "weight: %d code: %d\n", list[i]->m_weight, list[i]->m_bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sort the list by weight, largest weight first */
|
||||
qsort(&list[0], listitems, sizeof(list[0]), huffman_tree_node_compare);
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "Post-sort:\n");
|
||||
for (int i = 0; i < listitems; i++) {
|
||||
fprintf(stderr, "weight: %d code: %d\n", list[i]->m_weight, list[i]->m_bits);
|
||||
}
|
||||
fprintf(stderr, "===================\n");
|
||||
#endif
|
||||
|
||||
/* now build the tree */
|
||||
int nextalloc = decoder->numcodes;
|
||||
while (listitems > 1)
|
||||
{
|
||||
/* remove lowest two items */
|
||||
struct node_t* node1 = &(*list[--listitems]);
|
||||
struct node_t* node0 = &(*list[--listitems]);
|
||||
|
||||
/* create new node */
|
||||
struct node_t* newnode = &decoder->huffnode[nextalloc++];
|
||||
newnode->parent = NULL;
|
||||
node0->parent = node1->parent = newnode;
|
||||
newnode->weight = node0->weight + node1->weight;
|
||||
|
||||
/* insert into list at appropriate location */
|
||||
int curitem;
|
||||
for (curitem = 0; curitem < listitems; curitem++)
|
||||
if (newnode->weight > list[curitem]->weight)
|
||||
{
|
||||
memmove(&list[curitem+1], &list[curitem], (listitems - curitem) * sizeof(list[0]));
|
||||
break;
|
||||
}
|
||||
list[curitem] = newnode;
|
||||
listitems++;
|
||||
}
|
||||
|
||||
/* compute the number of bits in each code, and fill in another histogram */
|
||||
int maxbits = 0;
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
node->numbits = 0;
|
||||
node->bits = 0;
|
||||
|
||||
/* if we have a non-zero weight, compute the number of bits */
|
||||
if (node->weight > 0)
|
||||
{
|
||||
/* determine the number of bits for this node */
|
||||
for (struct node_t *curnode = node; curnode->parent != NULL; curnode = curnode->parent)
|
||||
node->numbits++;
|
||||
if (node->numbits == 0)
|
||||
node->numbits = 1;
|
||||
|
||||
/* keep track of the max */
|
||||
maxbits = MAX(maxbits, ((int)node->numbits));
|
||||
}
|
||||
}
|
||||
return maxbits;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* assign_canonical_codes - assign canonical codes
|
||||
* to all the nodes based on the number of bits
|
||||
* in each
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* build up a histogram of bit lengths */
|
||||
uint32_t bithisto[33] = { 0 };
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > decoder->maxbits)
|
||||
return HUFFERR_INTERNAL_INCONSISTENCY;
|
||||
if (node->numbits <= 32)
|
||||
bithisto[node->numbits]++;
|
||||
}
|
||||
|
||||
/* for each code length, determine the starting code number */
|
||||
uint32_t curstart = 0;
|
||||
for (int codelen = 32; codelen > 0; codelen--)
|
||||
{
|
||||
uint32_t nextstart = (curstart + bithisto[codelen]) >> 1;
|
||||
if (codelen != 1 && nextstart * 2 != (curstart + bithisto[codelen]))
|
||||
return HUFFERR_INTERNAL_INCONSISTENCY;
|
||||
bithisto[codelen] = curstart;
|
||||
curstart = nextstart;
|
||||
}
|
||||
|
||||
/* now assign canonical codes */
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > 0)
|
||||
node->bits = bithisto[node->numbits]++;
|
||||
}
|
||||
return HUFFERR_NONE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
* build_lookup_table - build a lookup table for
|
||||
* fast decoding
|
||||
*-------------------------------------------------
|
||||
*/
|
||||
|
||||
void huffman_build_lookup_table(struct huffman_decoder* decoder)
|
||||
{
|
||||
/* iterate over all codes */
|
||||
for (int curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||
{
|
||||
/* process all nodes which have non-zero bits */
|
||||
struct node_t* node = &decoder->huffnode[curcode];
|
||||
if (node->numbits > 0)
|
||||
{
|
||||
/* set up the entry */
|
||||
lookup_value value = MAKE_LOOKUP(curcode, node->numbits);
|
||||
|
||||
/* fill all matching entries */
|
||||
int shift = decoder->maxbits - node->numbits;
|
||||
lookup_value *dest = &decoder->lookup[node->bits << shift];
|
||||
lookup_value *destend = &decoder->lookup[((node->bits + 1) << shift) - 1];
|
||||
while (dest <= destend)
|
||||
*dest++ = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/* license:BSD-3-Clause
|
||||
* copyright-holders:Aaron Giles
|
||||
***************************************************************************
|
||||
|
||||
huffman.h
|
||||
|
||||
Static Huffman compression and decompression helpers.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HUFFMAN_H__
|
||||
#define __HUFFMAN_H__
|
||||
|
||||
#include "bitstream.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CONSTANTS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
enum huffman_error
|
||||
{
|
||||
HUFFERR_NONE = 0,
|
||||
HUFFERR_TOO_MANY_BITS,
|
||||
HUFFERR_INVALID_DATA,
|
||||
HUFFERR_INPUT_BUFFER_TOO_SMALL,
|
||||
HUFFERR_OUTPUT_BUFFER_TOO_SMALL,
|
||||
HUFFERR_INTERNAL_INCONSISTENCY,
|
||||
HUFFERR_TOO_MANY_CONTEXTS
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* TYPE DEFINITIONS
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
typedef uint16_t lookup_value;
|
||||
|
||||
/* a node in the huffman tree */
|
||||
struct node_t
|
||||
{
|
||||
struct node_t* parent; /* pointer to parent node */
|
||||
uint32_t count; /* number of hits on this node */
|
||||
uint32_t weight; /* assigned weight of this node */
|
||||
uint32_t bits; /* bits used to encode the node */
|
||||
uint8_t numbits; /* number of bits needed for this node */
|
||||
};
|
||||
|
||||
/* ======================> huffman_context_base */
|
||||
|
||||
/* context class for decoding */
|
||||
struct huffman_decoder
|
||||
{
|
||||
/* internal state */
|
||||
uint32_t numcodes; /* number of total codes being processed */
|
||||
uint8_t maxbits; /* maximum bits per code */
|
||||
uint8_t prevdata; /* value of the previous data (for delta-RLE encoding) */
|
||||
int rleremaining; /* number of RLE bytes remaining (for delta-RLE encoding) */
|
||||
lookup_value * lookup; /* pointer to the lookup table */
|
||||
struct node_t * huffnode; /* array of nodes */
|
||||
uint32_t * datahisto; /* histogram of data values */
|
||||
|
||||
/* array versions of the info we need */
|
||||
#if 0
|
||||
node_t* huffnode_array; /* [_NumCodes]; */
|
||||
lookup_value* lookup_array; /* [1 << _MaxBits]; */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ======================> huffman_decoder */
|
||||
|
||||
struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits);
|
||||
|
||||
/* single item operations */
|
||||
uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* bitbuf);
|
||||
|
||||
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf);
|
||||
enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, struct bitstream* bitbuf);
|
||||
|
||||
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight);
|
||||
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder);
|
||||
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder);
|
||||
|
||||
void huffman_build_lookup_table(struct huffman_decoder* decoder);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,371 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ALL_H
|
||||
#define FLAC__ALL_H
|
||||
|
||||
#include "export.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "callback.h"
|
||||
#include "format.h"
|
||||
#include "metadata.h"
|
||||
#include "ordinals.h"
|
||||
#include "stream_decoder.h"
|
||||
#include "stream_encoder.h"
|
||||
|
||||
/** \mainpage
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* This is the documentation for the FLAC C and C++ APIs. It is
|
||||
* highly interconnected; this introduction should give you a top
|
||||
* level idea of the structure and how to find the information you
|
||||
* need. As a prerequisite you should have at least a basic
|
||||
* knowledge of the FLAC format, documented
|
||||
* <A HREF="../format.html">here</A>.
|
||||
*
|
||||
* \section c_api FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files. The public include files will be installed
|
||||
* in your include area (for example /usr/include/FLAC/...).
|
||||
*
|
||||
* By writing a little code and linking against libFLAC, it is
|
||||
* relatively easy to add FLAC support to another program. The
|
||||
* library is licensed under <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
* Complete source code of libFLAC as well as the command-line
|
||||
* encoder and plugins is available and is a useful source of
|
||||
* examples.
|
||||
*
|
||||
* Aside from encoders and decoders, libFLAC provides a powerful
|
||||
* metadata interface for manipulating metadata in FLAC files. It
|
||||
* allows the user to add, delete, and modify FLAC metadata blocks
|
||||
* and it can automatically take advantage of PADDING blocks to avoid
|
||||
* rewriting the entire FLAC file when changing the size of the
|
||||
* metadata.
|
||||
*
|
||||
* libFLAC usually only requires the standard C library and C math
|
||||
* library. In particular, threading is not used so there is no
|
||||
* dependency on a thread library. However, libFLAC does not use
|
||||
* global variables and should be thread-safe.
|
||||
*
|
||||
* libFLAC also supports encoding to and decoding from Ogg FLAC.
|
||||
* However the metadata editing interfaces currently have limited
|
||||
* read-only support for Ogg FLAC files.
|
||||
*
|
||||
* \section cpp_api FLAC C++ API
|
||||
*
|
||||
* The FLAC C++ API is a set of classes that encapsulate the
|
||||
* structures and functions in libFLAC. They provide slightly more
|
||||
* functionality with respect to metadata but are otherwise
|
||||
* equivalent. For the most part, they share the same usage as
|
||||
* their counterparts in libFLAC, and the FLAC C API documentation
|
||||
* can be used as a supplement. The public include files
|
||||
* for the C++ API will be installed in your include area (for
|
||||
* example /usr/include/FLAC++/...).
|
||||
*
|
||||
* libFLAC++ is also licensed under
|
||||
* <A HREF="../license.html">Xiph's BSD license</A>.
|
||||
*
|
||||
* \section getting_started Getting Started
|
||||
*
|
||||
* A good starting point for learning the API is to browse through
|
||||
* the <A HREF="modules.html">modules</A>. Modules are logical
|
||||
* groupings of related functions or classes, which correspond roughly
|
||||
* to header files or sections of header files. Each module includes a
|
||||
* detailed description of the general usage of its functions or
|
||||
* classes.
|
||||
*
|
||||
* From there you can go on to look at the documentation of
|
||||
* individual functions. You can see different views of the individual
|
||||
* functions through the links in top bar across this page.
|
||||
*
|
||||
* If you prefer a more hands-on approach, you can jump right to some
|
||||
* <A HREF="../documentation_example_code.html">example code</A>.
|
||||
*
|
||||
* \section porting_guide Porting Guide
|
||||
*
|
||||
* Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink
|
||||
* has been introduced which gives detailed instructions on how to
|
||||
* port your code to newer versions of FLAC.
|
||||
*
|
||||
* \section embedded_developers Embedded Developers
|
||||
*
|
||||
* libFLAC has grown larger over time as more functionality has been
|
||||
* included, but much of it may be unnecessary for a particular embedded
|
||||
* implementation. Unused parts may be pruned by some simple editing of
|
||||
* src/libFLAC/Makefile.am. In general, the decoders, encoders, and
|
||||
* metadata interface are all independent from each other.
|
||||
*
|
||||
* It is easiest to just describe the dependencies:
|
||||
*
|
||||
* - All modules depend on the \link flac_format Format \endlink module.
|
||||
* - The decoders and encoders depend on the bitbuffer.
|
||||
* - The decoder is independent of the encoder. The encoder uses the
|
||||
* decoder because of the verify feature, but this can be removed if
|
||||
* not needed.
|
||||
* - Parts of the metadata interface require the stream decoder (but not
|
||||
* the encoder).
|
||||
* - Ogg support is selectable through the compile time macro
|
||||
* \c FLAC__HAS_OGG.
|
||||
*
|
||||
* For example, if your application only requires the stream decoder, no
|
||||
* encoder, and no metadata interface, you can remove the stream encoder
|
||||
* and the metadata interface, which will greatly reduce the size of the
|
||||
* library.
|
||||
*
|
||||
* Also, there are several places in the libFLAC code with comments marked
|
||||
* with "OPT:" where a #define can be changed to enable code that might be
|
||||
* faster on a specific platform. Experimenting with these can yield faster
|
||||
* binaries.
|
||||
*/
|
||||
|
||||
/** \defgroup porting Porting Guide for New Versions
|
||||
*
|
||||
* This module describes differences in the library interfaces from
|
||||
* version to version. It assists in the porting of code that uses
|
||||
* the libraries to newer versions of FLAC.
|
||||
*
|
||||
* One simple facility for making porting easier that has been added
|
||||
* in FLAC 1.1.3 is a set of \c #defines in \c export.h of each
|
||||
* library's includes (e.g. \c include/FLAC/export.h). The
|
||||
* \c #defines mirror the libraries'
|
||||
* <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>,
|
||||
* e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT,
|
||||
* \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE.
|
||||
* These can be used to support multiple versions of an API during the
|
||||
* transition phase, e.g.
|
||||
*
|
||||
* \code
|
||||
* #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
||||
* legacy code
|
||||
* #else
|
||||
* new code
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* The source will work for multiple versions and the legacy code can
|
||||
* easily be removed when the transition is complete.
|
||||
*
|
||||
* Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in
|
||||
* include/FLAC/export.h), which can be used to determine whether or not
|
||||
* the library has been compiled with support for Ogg FLAC. This is
|
||||
* simpler than trying to call an Ogg init function and catching the
|
||||
* error.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.2 to FLAC 1.1.3.
|
||||
*
|
||||
* The main change between the APIs in 1.1.2 and 1.1.3 is that they have
|
||||
* been simplified. First, libOggFLAC has been merged into libFLAC and
|
||||
* libOggFLAC++ has been merged into libFLAC++. Second, both the three
|
||||
* decoding layers and three encoding layers have been merged into a
|
||||
* single stream decoder and stream encoder. That is, the functionality
|
||||
* of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged
|
||||
* into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and
|
||||
* FLAC__FileEncoder into FLAC__StreamEncoder. Only the
|
||||
* FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means
|
||||
* is there is now a single API that can be used to encode or decode
|
||||
* streams to/from native FLAC or Ogg FLAC and the single API can work
|
||||
* on both seekable and non-seekable streams.
|
||||
*
|
||||
* Instead of creating an encoder or decoder of a certain layer, now the
|
||||
* client will always create a FLAC__StreamEncoder or
|
||||
* FLAC__StreamDecoder. The old layers are now differentiated by the
|
||||
* initialization function. For example, for the decoder,
|
||||
* FLAC__stream_decoder_init() has been replaced by
|
||||
* FLAC__stream_decoder_init_stream(). This init function takes
|
||||
* callbacks for the I/O, and the seeking callbacks are optional. This
|
||||
* allows the client to use the same object for seekable and
|
||||
* non-seekable streams. For decoding a FLAC file directly, the client
|
||||
* can use FLAC__stream_decoder_init_file() and pass just a filename
|
||||
* and fewer callbacks; most of the other callbacks are supplied
|
||||
* internally. For situations where fopen()ing by filename is not
|
||||
* possible (e.g. Unicode filenames on Windows) the client can instead
|
||||
* open the file itself and supply the FILE* to
|
||||
* FLAC__stream_decoder_init_FILE(). The init functions now returns a
|
||||
* FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState.
|
||||
* Since the callbacks and client data are now passed to the init
|
||||
* function, the FLAC__stream_decoder_set_*_callback() functions and
|
||||
* FLAC__stream_decoder_set_client_data() are no longer needed. The
|
||||
* rest of the calls to the decoder are the same as before.
|
||||
*
|
||||
* There are counterpart init functions for Ogg FLAC, e.g.
|
||||
* FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls
|
||||
* and callbacks are the same as for native FLAC.
|
||||
*
|
||||
* As an example, in FLAC 1.1.2 a seekable stream decoder would have
|
||||
* been set up like so:
|
||||
*
|
||||
* \code
|
||||
* FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__seekable_stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback);
|
||||
* FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback);
|
||||
* FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback);
|
||||
* FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback);
|
||||
* FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback);
|
||||
* FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback);
|
||||
* FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback);
|
||||
* FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback);
|
||||
* FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data);
|
||||
* if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* In FLAC 1.1.3 it is like this:
|
||||
*
|
||||
* \code
|
||||
* FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
|
||||
* if(decoder == NULL) do_something;
|
||||
* FLAC__stream_decoder_set_md5_checking(decoder, true);
|
||||
* [... other settings ...]
|
||||
* if(FLAC__stream_decoder_init_stream(
|
||||
* decoder,
|
||||
* my_read_callback,
|
||||
* my_seek_callback, // or NULL
|
||||
* my_tell_callback, // or NULL
|
||||
* my_length_callback, // or NULL
|
||||
* my_eof_callback, // or NULL
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or you could do;
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* FILE *file = fopen("somefile.flac","rb");
|
||||
* if(file == NULL) do_somthing;
|
||||
* if(FLAC__stream_decoder_init_FILE(
|
||||
* decoder,
|
||||
* file,
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* or just:
|
||||
*
|
||||
* \code
|
||||
* [...]
|
||||
* if(FLAC__stream_decoder_init_file(
|
||||
* decoder,
|
||||
* "somefile.flac",
|
||||
* my_write_callback,
|
||||
* my_metadata_callback, // or NULL
|
||||
* my_error_callback,
|
||||
* my_client_data
|
||||
* ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something;
|
||||
* \endcode
|
||||
*
|
||||
* Another small change to the decoder is in how it handles unparseable
|
||||
* streams. Before, when the decoder found an unparseable stream
|
||||
* (reserved for when the decoder encounters a stream from a future
|
||||
* encoder that it can't parse), it changed the state to
|
||||
* \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead
|
||||
* drops sync and calls the error callback with a new error code
|
||||
* \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is
|
||||
* more robust. If your error callback does not discriminate on the the
|
||||
* error state, your code does not need to be changed.
|
||||
*
|
||||
* The encoder now has a new setting:
|
||||
* FLAC__stream_encoder_set_apodization(). This is for setting the
|
||||
* method used to window the data before LPC analysis. You only need to
|
||||
* add a call to this function if the default is not suitable. There
|
||||
* are also two new convenience functions that may be useful:
|
||||
* FLAC__metadata_object_cuesheet_calculate_cddb_id() and
|
||||
* FLAC__metadata_get_cuesheet().
|
||||
*
|
||||
* The \a bytes parameter to FLAC__StreamDecoderReadCallback,
|
||||
* FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback
|
||||
* is now \c size_t instead of \c unsigned.
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.3 to FLAC 1.1.4.
|
||||
*
|
||||
* There were no changes to any of the interfaces from 1.1.3 to 1.1.4.
|
||||
* There was a slight change in the implementation of
|
||||
* FLAC__stream_encoder_set_metadata(); the function now makes a copy
|
||||
* of the \a metadata array of pointers so the client no longer needs
|
||||
* to maintain it after the call. The objects themselves that are
|
||||
* pointed to by the array are still not copied though and must be
|
||||
* maintained until the call to FLAC__stream_encoder_finish().
|
||||
*/
|
||||
|
||||
/** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0
|
||||
* \ingroup porting
|
||||
*
|
||||
* \brief
|
||||
* This module describes porting from FLAC 1.1.4 to FLAC 1.2.0.
|
||||
*
|
||||
* There were only very minor changes to the interfaces from 1.1.4 to 1.2.0.
|
||||
* In libFLAC, \c FLAC__format_sample_rate_is_subset() was added.
|
||||
* In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added.
|
||||
*
|
||||
* Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN
|
||||
* has changed to reflect the conversion of one of the reserved bits
|
||||
* into active use. It used to be \c 2 and now is \c 1. However the
|
||||
* FLAC frame header length has not changed, so to skip the proper
|
||||
* number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN +
|
||||
* \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
|
||||
*/
|
||||
|
||||
/** \defgroup flac FLAC C API
|
||||
*
|
||||
* The FLAC C API is the interface to libFLAC, a set of structures
|
||||
* describing the components of FLAC streams, and functions for
|
||||
* encoding and decoding streams, as well as manipulating FLAC
|
||||
* metadata in files.
|
||||
*
|
||||
* You should start with the format components as all other modules
|
||||
* are dependent on it.
|
||||
*/
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ASSERT_H
|
||||
#define FLAC__ASSERT_H
|
||||
|
||||
/* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */
|
||||
#ifdef DEBUG
|
||||
#include <assert.h>
|
||||
#define FLAC__ASSERT(x) assert(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x) x
|
||||
#else
|
||||
#define FLAC__ASSERT(x)
|
||||
#define FLAC__ASSERT_DECLARATION(x)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,185 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__CALLBACK_H
|
||||
#define FLAC__CALLBACK_H
|
||||
|
||||
#include "ordinals.h"
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
/** \file include/FLAC/callback.h
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* See the detailed documentation for callbacks in the
|
||||
* \link flac_callbacks callbacks \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module defines the structures for describing I/O callbacks
|
||||
* to the other FLAC interfaces.
|
||||
*
|
||||
* The purpose of the I/O callback functions is to create a common way
|
||||
* for the metadata interfaces to handle I/O.
|
||||
*
|
||||
* Originally the metadata interfaces required filenames as the way of
|
||||
* specifying FLAC files to operate on. This is problematic in some
|
||||
* environments so there is an additional option to specify a set of
|
||||
* callbacks for doing I/O on the FLAC file, instead of the filename.
|
||||
*
|
||||
* In addition to the callbacks, a FLAC__IOHandle type is defined as an
|
||||
* opaque structure for a data source.
|
||||
*
|
||||
* The callback function prototypes are similar (but not identical) to the
|
||||
* stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use
|
||||
* stdio streams to implement the callbacks, you can pass fread, fwrite, and
|
||||
* fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or
|
||||
* FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle
|
||||
* is required. \warning You generally CANNOT directly use fseek or ftell
|
||||
* for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems
|
||||
* these use 32-bit offsets and FLAC requires 64-bit offsets to deal with
|
||||
* large files. You will have to find an equivalent function (e.g. ftello),
|
||||
* or write a wrapper. The same is true for feof() since this is usually
|
||||
* implemented as a macro, not as a function whose address can be taken.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** This is the opaque handle type used by the callbacks. Typically
|
||||
* this is a \c FILE* or address of a file descriptor.
|
||||
*/
|
||||
typedef void* FLAC__IOHandle;
|
||||
|
||||
/** Signature for the read callback.
|
||||
* The signature and semantics match POSIX fread() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the read buffer.
|
||||
* \param size The size of the records to be read.
|
||||
* \param nmemb The number of records to be read.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records read.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the write callback.
|
||||
* The signature and semantics match POSIX fwrite() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param ptr The address of the write buffer.
|
||||
* \param size The size of the records to be written.
|
||||
* \param nmemb The number of records to be written.
|
||||
* \param handle The handle to the data source.
|
||||
* \retval size_t
|
||||
* The number of records written.
|
||||
*/
|
||||
typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the seek callback.
|
||||
* The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \param offset The new position, relative to \a whence
|
||||
* \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END
|
||||
* \retval int
|
||||
* \c 0 on success, \c -1 on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence);
|
||||
|
||||
/** Signature for the tell callback.
|
||||
* The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT
|
||||
* EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long'
|
||||
* and 32-bits wide.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval FLAC__int64
|
||||
* The current position on success, \c -1 on error.
|
||||
*/
|
||||
typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the EOF callback.
|
||||
* The signature and semantics mostly match POSIX feof() but WATCHOUT:
|
||||
* on many systems, feof() is a macro, so in this case a wrapper function
|
||||
* must be provided instead.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 if not at end of file, nonzero if at end of file.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle);
|
||||
|
||||
/** Signature for the close callback.
|
||||
* The signature and semantics match POSIX fclose() implementations
|
||||
* and can generally be used interchangeably.
|
||||
*
|
||||
* \param handle The handle to the data source.
|
||||
* \retval int
|
||||
* \c 0 on success, \c EOF on error.
|
||||
*/
|
||||
typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle);
|
||||
|
||||
/** A structure for holding a set of callbacks.
|
||||
* Each FLAC interface that requires a FLAC__IOCallbacks structure will
|
||||
* describe which of the callbacks are required. The ones that are not
|
||||
* required may be set to NULL.
|
||||
*
|
||||
* If the seek requirement for an interface is optional, you can signify that
|
||||
* a data sorce is not seekable by setting the \a seek field to \c NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
FLAC__IOCallback_Read read;
|
||||
FLAC__IOCallback_Write write;
|
||||
FLAC__IOCallback_Seek seek;
|
||||
FLAC__IOCallback_Tell tell;
|
||||
FLAC__IOCallback_Eof eof;
|
||||
FLAC__IOCallback_Close close;
|
||||
} FLAC__IOCallbacks;
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,97 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__EXPORT_H
|
||||
#define FLAC__EXPORT_H
|
||||
|
||||
/** \file include/FLAC/export.h
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* See the \link flac_export export \endlink module.
|
||||
*/
|
||||
|
||||
/** \defgroup flac_export FLAC/export.h: export symbols
|
||||
* \ingroup flac
|
||||
*
|
||||
* \brief
|
||||
* This module contains #defines and symbols for exporting function
|
||||
* calls, and providing version information and compiled-in features.
|
||||
*
|
||||
* If you are compiling with MSVC and will link to the static library
|
||||
* (libFLAC.lib) you should define FLAC__NO_DLL in your project to
|
||||
* make sure the symbols are exported properly.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if defined(FLAC__NO_DLL)
|
||||
#define FLAC_API
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#ifdef FLAC_API_EXPORTS
|
||||
#define FLAC_API __declspec(dllexport)
|
||||
#else
|
||||
#define FLAC_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#elif defined(FLAC__USE_VISIBILITY_ATTR)
|
||||
#define FLAC_API __attribute__ ((visibility ("default")))
|
||||
|
||||
#else
|
||||
#define FLAC_API
|
||||
|
||||
#endif
|
||||
|
||||
/** These #defines will mirror the libtool-based library version number, see
|
||||
* http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning
|
||||
*/
|
||||
#define FLAC_API_VERSION_CURRENT 11
|
||||
#define FLAC_API_VERSION_REVISION 0 /**< see above */
|
||||
#define FLAC_API_VERSION_AGE 3 /**< see above */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */
|
||||
extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* \} */
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__ORDINALS_H
|
||||
#define FLAC__ORDINALS_H
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
|
||||
/* Microsoft Visual Studio earlier than the 2010 version did not provide
|
||||
* the 1999 ISO C Standard header file <stdint.h>.
|
||||
*/
|
||||
|
||||
typedef __int8 FLAC__int8;
|
||||
typedef unsigned __int8 FLAC__uint8;
|
||||
|
||||
typedef __int16 FLAC__int16;
|
||||
typedef __int32 FLAC__int32;
|
||||
typedef __int64 FLAC__int64;
|
||||
typedef unsigned __int16 FLAC__uint16;
|
||||
typedef unsigned __int32 FLAC__uint32;
|
||||
typedef unsigned __int64 FLAC__uint64;
|
||||
|
||||
#else
|
||||
|
||||
/* For MSVC 2010 and everything else which provides <stdint.h>. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int8_t FLAC__int8;
|
||||
typedef uint8_t FLAC__uint8;
|
||||
|
||||
typedef int16_t FLAC__int16;
|
||||
typedef int32_t FLAC__int32;
|
||||
typedef int64_t FLAC__int64;
|
||||
typedef uint16_t FLAC__uint16;
|
||||
typedef uint32_t FLAC__uint32;
|
||||
typedef uint64_t FLAC__uint64;
|
||||
|
||||
#endif
|
||||
|
||||
typedef int FLAC__bool;
|
||||
|
||||
typedef FLAC__uint8 FLAC__byte;
|
||||
|
||||
|
||||
#ifdef true
|
||||
#undef true
|
||||
#endif
|
||||
#ifdef false
|
||||
#undef false
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,219 @@
|
|||
/* alloc - Convenience routines for safely allocating memory
|
||||
* Copyright (C) 2007-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__ALLOC_H
|
||||
#define FLAC__SHARE__ALLOC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
|
||||
* before #including this file, otherwise SIZE_MAX might not be defined
|
||||
*/
|
||||
|
||||
#include <limits.h> /* for SIZE_MAX */
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
|
||||
#endif
|
||||
#include <stdlib.h> /* for size_t, malloc(), etc */
|
||||
#include "share/compat.h"
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# ifndef SIZE_T_MAX
|
||||
# ifdef _MSC_VER
|
||||
# ifdef _WIN64
|
||||
# define SIZE_T_MAX FLAC__U64L(0xffffffffffffffff)
|
||||
# else
|
||||
# define SIZE_T_MAX 0xffffffff
|
||||
# endif
|
||||
# else
|
||||
# error
|
||||
# endif
|
||||
# endif
|
||||
# define SIZE_MAX SIZE_T_MAX
|
||||
#endif
|
||||
|
||||
/* avoid malloc()ing 0 bytes, see:
|
||||
* https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
|
||||
*/
|
||||
static inline void *safe_malloc_(size_t size)
|
||||
{
|
||||
/* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(!size)
|
||||
size++;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static inline void *safe_calloc_(size_t nmemb, size_t size)
|
||||
{
|
||||
if(!nmemb || !size)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
|
||||
/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
|
||||
|
||||
static inline void *safe_malloc_add_2op_(size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
return safe_malloc_(size2);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return safe_malloc_(size3);
|
||||
}
|
||||
|
||||
static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return safe_malloc_(size4);
|
||||
}
|
||||
|
||||
void *safe_malloc_mul_2op_(size_t size1, size_t size2) ;
|
||||
|
||||
static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2 || !size3)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
size1 *= size2;
|
||||
if(size1 > SIZE_MAX / size3)
|
||||
return 0;
|
||||
return malloc(size1*size3);
|
||||
}
|
||||
|
||||
/* size1*size2 + size3 */
|
||||
static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return safe_malloc_(size3);
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return safe_malloc_add_2op_(size1*size2, size3);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_(void *ptr, size_t size)
|
||||
{
|
||||
void *oldptr = ptr;
|
||||
void *newptr = realloc(ptr, size);
|
||||
if(size > 0 && newptr == 0)
|
||||
free(oldptr);
|
||||
return newptr;
|
||||
}
|
||||
static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1) {
|
||||
free(ptr);
|
||||
return 0;
|
||||
}
|
||||
return realloc(ptr, size2);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
return realloc(ptr, size3);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
|
||||
{
|
||||
size2 += size1;
|
||||
if(size2 < size1)
|
||||
return 0;
|
||||
size3 += size2;
|
||||
if(size3 < size2)
|
||||
return 0;
|
||||
size4 += size3;
|
||||
if(size4 < size3)
|
||||
return 0;
|
||||
return realloc(ptr, size4);
|
||||
}
|
||||
|
||||
static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return safe_realloc_(ptr, size1*size2);
|
||||
}
|
||||
|
||||
/* size1 * (size2 + size3) */
|
||||
static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
|
||||
{
|
||||
if(!size1 || (!size2 && !size3))
|
||||
return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
|
||||
size2 += size3;
|
||||
if(size2 < size3)
|
||||
return 0;
|
||||
return safe_realloc_mul_2op_(ptr, size1, size2);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,209 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2016 Xiph.org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/* This is the prefered location of all CPP hackery to make $random_compiler
|
||||
* work like something approaching a C99 (or maybe more accurately GNU99)
|
||||
* compiler.
|
||||
*
|
||||
* It is assumed that this header will be included after "config.h".
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE__COMPAT_H
|
||||
#define FLAC__SHARE__COMPAT_H
|
||||
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
/* where MSVC puts unlink() */
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */
|
||||
#if !defined __MINGW32__
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#else /* MinGW */
|
||||
#if !defined(HAVE_FSEEKO)
|
||||
#define fseeko fseeko64
|
||||
#define ftello ftello64
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define FLAC__off_t off_t
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strtoll _strtoi64
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
|
||||
/* MSVS generates VERY slow 32-bit code with __restrict */
|
||||
#define flac_restrict __restrict
|
||||
#elif defined __GNUC__
|
||||
#define flac_restrict __restrict__
|
||||
#else
|
||||
#define flac_restrict
|
||||
#endif
|
||||
|
||||
#define FLAC__U64L(x) x##ULL
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
#define FLAC__STRCASECMP _stricmp
|
||||
#define FLAC__STRNCASECMP _strnicmp
|
||||
#elif defined __BORLANDC__
|
||||
#define FLAC__STRCASECMP stricmp
|
||||
#define FLAC__STRNCASECMP strnicmp
|
||||
#else
|
||||
#define FLAC__STRCASECMP strcasecmp
|
||||
#define FLAC__STRNCASECMP strncasecmp
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__
|
||||
#include <io.h> /* for _setmode(), chmod() */
|
||||
#include <fcntl.h> /* for _O_BINARY */
|
||||
#else
|
||||
#include <unistd.h> /* for chown(), unlink() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
|
||||
#if defined __BORLANDC__
|
||||
#include <utime.h> /* for utime() */
|
||||
#else
|
||||
#include <sys/utime.h> /* for utime() */
|
||||
#endif
|
||||
#else
|
||||
#include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
|
||||
#include <utime.h> /* for utime() */
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
# if _MSC_VER >= 1800
|
||||
# include <inttypes.h>
|
||||
# elif _MSC_VER >= 1600
|
||||
/* Visual Studio 2010 has decent C99 support */
|
||||
# include <stdint.h>
|
||||
# define PRIu64 "llu"
|
||||
# define PRId64 "lld"
|
||||
# define PRIx64 "llx"
|
||||
# else
|
||||
# include <limits.h>
|
||||
# ifndef UINT32_MAX
|
||||
# define UINT32_MAX _UI32_MAX
|
||||
# endif
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
# define PRIu64 "I64u"
|
||||
# define PRId64 "I64d"
|
||||
# define PRIx64 "I64x"
|
||||
# endif
|
||||
#endif /* defined _MSC_VER */
|
||||
|
||||
#ifdef _WIN32
|
||||
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */
|
||||
|
||||
#include "share/win_utf8_io.h"
|
||||
#define flac_printf printf_utf8
|
||||
#define flac_fprintf fprintf_utf8
|
||||
#define flac_vfprintf vfprintf_utf8
|
||||
|
||||
#include "share/windows_unicode_filenames.h"
|
||||
#define flac_fopen flac_internal_fopen_utf8
|
||||
#define flac_chmod flac_internal_chmod_utf8
|
||||
#define flac_utime flac_internal_utime_utf8
|
||||
#define flac_unlink flac_internal_unlink_utf8
|
||||
#define flac_rename flac_internal_rename_utf8
|
||||
#define flac_stat flac_internal_stat64_utf8
|
||||
|
||||
#else
|
||||
|
||||
#define flac_printf printf
|
||||
#define flac_fprintf fprintf
|
||||
#define flac_vfprintf vfprintf
|
||||
|
||||
#define flac_fopen fopen
|
||||
#define flac_chmod chmod
|
||||
#define flac_utime utime
|
||||
#define flac_unlink unlink
|
||||
#define flac_rename rename
|
||||
#define flac_stat stat
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define flac_stat_s __stat64 /* stat struct */
|
||||
#define flac_fstat _fstat64
|
||||
#else
|
||||
#define flac_stat_s stat /* stat struct */
|
||||
#define flac_fstat fstat
|
||||
#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* FLAC needs to compile and work correctly on systems with a normal ISO C99
|
||||
* snprintf as well as Microsoft Visual Studio which has an non-standards
|
||||
* conformant snprint_s function.
|
||||
*
|
||||
* This function wraps the MS version to behave more like the ISO version.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int flac_snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* FLAC__SHARE__COMPAT_H */
|
|
@ -0,0 +1,84 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2016 Xiph.org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/* It is assumed that this header will be included after "config.h". */
|
||||
|
||||
#if HAVE_BSWAP32 /* GCC and Clang */
|
||||
|
||||
/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */
|
||||
#if ! HAVE_BSWAP16
|
||||
static inline unsigned short __builtin_bswap16(unsigned short a)
|
||||
{
|
||||
return (a<<8)|(a>>8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ENDSWAP_16(x) (__builtin_bswap16 (x))
|
||||
#define ENDSWAP_32(x) (__builtin_bswap32 (x))
|
||||
#define ENDSWAP_64(x) (__builtin_bswap64 (x))
|
||||
|
||||
#elif defined _MSC_VER /* Windows */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ENDSWAP_16(x) (_byteswap_ushort (x))
|
||||
#define ENDSWAP_32(x) (_byteswap_ulong (x))
|
||||
#define ENDSWAP_64(x) (_byteswap_uint64 (x))
|
||||
|
||||
#elif defined HAVE_BYTESWAP_H /* Linux */
|
||||
|
||||
#include <byteswap.h>
|
||||
|
||||
#define ENDSWAP_16(x) (bswap_16 (x))
|
||||
#define ENDSWAP_32(x) (bswap_32 (x))
|
||||
#define ENDSWAP_64(x) (bswap_64 (x))
|
||||
|
||||
#else
|
||||
|
||||
#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8))
|
||||
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24))
|
||||
#define ENDSWAP_64(x) ((ENDSWAP_32(((x) >> 32) & 0xFFFFFFFF)) | (ENDSWAP_32((x) & 0xFFFFFFFF) << 32))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Host to little-endian byte swapping (for MD5 calculation) */
|
||||
#if CPU_IS_BIG_ENDIAN
|
||||
|
||||
#define H2LE_16(x) ENDSWAP_16 (x)
|
||||
#define H2LE_32(x) ENDSWAP_32 (x)
|
||||
|
||||
#else
|
||||
|
||||
#define H2LE_16(x) (x)
|
||||
#define H2LE_32(x) (x)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2016 Xiph.org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* FLAC_CHECK_RETURN : Check the return value of the provided function and
|
||||
* print an error message if it fails (ie returns a value < 0).
|
||||
*
|
||||
* Ideally, a library should not print anything, but this macro is only used
|
||||
* for things that extremely unlikely to fail, like `chown` to a previoulsy
|
||||
* saved `uid`.
|
||||
*/
|
||||
|
||||
#define FLAC_CHECK_RETURN(x) \
|
||||
{ if ((x) < 0) \
|
||||
fprintf (stderr, "%s : %s\n", #x, strerror (errno)) ; \
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2016 Xiph.org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/* Safe string handling functions to replace things like strcpy, strncpy,
|
||||
* strcat, strncat etc.
|
||||
* All of these functions guarantee a correctly NUL terminated string but
|
||||
* the string may be truncated if the destination buffer was too short.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__SHARE_SAFE_STR_H
|
||||
#define FLAC__SHARE_SAFE_STR_H
|
||||
|
||||
static inline char *
|
||||
safe_strncat(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
char * ret;
|
||||
|
||||
if (dest_size < 1)
|
||||
return dest;
|
||||
|
||||
ret = strncat(dest, src, dest_size - strlen (dest));
|
||||
dest [dest_size - 1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
safe_strncpy(char *dest, const char *src, size_t dest_size)
|
||||
{
|
||||
char * ret;
|
||||
|
||||
if (dest_size < 1)
|
||||
return dest;
|
||||
|
||||
ret = strncpy(dest, src, dest_size);
|
||||
dest [dest_size - 1] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SHARE_SAFE_STR_H */
|
|
@ -0,0 +1,58 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef flac__win_utf8_io_h
|
||||
#define flac__win_utf8_io_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t strlen_utf8(const char *str);
|
||||
int win_get_console_width(void);
|
||||
|
||||
int get_utf8_argv(int *argc, char ***argv);
|
||||
|
||||
int printf_utf8(const char *format, ...);
|
||||
int fprintf_utf8(FILE *stream, const char *format, ...);
|
||||
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef flac__windows_unicode_filenames_h
|
||||
#define flac__windows_unicode_filenames_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utime.h>
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void flac_internal_set_utf8_filenames(FLAC__bool flag);
|
||||
FLAC__bool flac_internal_get_utf8_filenames(void);
|
||||
#define flac_set_utf8_filenames flac_internal_set_utf8_filenames
|
||||
#define flac_get_utf8_filenames flac_internal_get_utf8_filenames
|
||||
|
||||
FILE* flac_internal_fopen_utf8(const char *filename, const char *mode);
|
||||
int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer);
|
||||
int flac_internal_chmod_utf8(const char *filename, int pmode);
|
||||
int flac_internal_utime_utf8(const char *filename, struct utimbuf *times);
|
||||
int flac_internal_unlink_utf8(const char *filename);
|
||||
int flac_internal_rename_utf8(const char *oldname, const char *newname);
|
||||
|
||||
#include <windows.h>
|
||||
HANDLE WINAPI flac_internal_CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
#define CreateFile_utf8 flac_internal_CreateFile_utf8
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/bitmath.h"
|
||||
|
||||
/* An example of what FLAC__bitmath_silog2() computes:
|
||||
*
|
||||
* silog2(-10) = 5
|
||||
* silog2(- 9) = 5
|
||||
* silog2(- 8) = 4
|
||||
* silog2(- 7) = 4
|
||||
* silog2(- 6) = 4
|
||||
* silog2(- 5) = 4
|
||||
* silog2(- 4) = 3
|
||||
* silog2(- 3) = 3
|
||||
* silog2(- 2) = 2
|
||||
* silog2(- 1) = 2
|
||||
* silog2( 0) = 0
|
||||
* silog2( 1) = 2
|
||||
* silog2( 2) = 3
|
||||
* silog2( 3) = 3
|
||||
* silog2( 4) = 4
|
||||
* silog2( 5) = 4
|
||||
* silog2( 6) = 4
|
||||
* silog2( 7) = 4
|
||||
* silog2( 8) = 5
|
||||
* silog2( 9) = 5
|
||||
* silog2( 10) = 5
|
||||
*/
|
||||
unsigned FLAC__bitmath_silog2(FLAC__int64 v)
|
||||
{
|
||||
if(v == 0)
|
||||
return 0;
|
||||
|
||||
if(v == -1)
|
||||
return 2;
|
||||
|
||||
v = (v < 0) ? (-(v+1)) : v;
|
||||
return FLAC__bitmath_ilog2_wide(v)+2;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,293 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include "share/compat.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# include <intrin.h> /* for __cpuid() and _xgetbv() */
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && defined HAVE_CPUID_H
|
||||
# include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
#define dfprintf fprintf
|
||||
#else
|
||||
/* This is bad practice, it should be a static void empty function */
|
||||
#define dfprintf(file, format, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined FLAC__CPU_IA32
|
||||
/* these are flags in EDX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
|
||||
#endif
|
||||
|
||||
#if FLAC__HAS_X86INTRIN || FLAC__AVX_SUPPORTED
|
||||
/* these are flags in ECX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
|
||||
|
||||
/* these are flags in ECX of CPUID AX=00000001 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
|
||||
/* these are flags in EBX of CPUID AX=00000007 */
|
||||
static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
|
||||
#endif
|
||||
|
||||
#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64
|
||||
static uint32_t
|
||||
cpu_xgetbv_x86(void)
|
||||
{
|
||||
#if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED
|
||||
return (uint32_t)_xgetbv(0);
|
||||
#elif defined __GNUC__
|
||||
uint32_t lo, hi;
|
||||
asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0));
|
||||
return lo;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ia32_cpu_info (FLAC__CPUInfo *info)
|
||||
{
|
||||
#if !defined FLAC__CPU_IA32
|
||||
(void) info;
|
||||
#else
|
||||
FLAC__bool ia32_osxsave = false;
|
||||
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
|
||||
|
||||
#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN)
|
||||
info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
|
||||
#if defined FLAC__HAS_NASM
|
||||
if(!FLAC__cpu_have_cpuid_asm_ia32())
|
||||
return;
|
||||
#endif
|
||||
/* http://www.sandpile.org/x86/cpuid.htm */
|
||||
if (FLAC__HAS_X86INTRIN) {
|
||||
FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->ia32.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */
|
||||
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
}
|
||||
else {
|
||||
FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
|
||||
}
|
||||
|
||||
info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV ) ? true : false;
|
||||
info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX ) ? true : false;
|
||||
info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE ) ? true : false;
|
||||
info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 ) ? true : false;
|
||||
info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false;
|
||||
info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false;
|
||||
info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false;
|
||||
info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false;
|
||||
|
||||
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
|
||||
ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false;
|
||||
info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX ) ? true : false;
|
||||
info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA ) ? true : false;
|
||||
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false;
|
||||
}
|
||||
|
||||
dfprintf(stderr, "CPU info (IA-32):\n");
|
||||
dfprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
|
||||
dfprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
|
||||
|
||||
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
|
||||
dfprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
|
||||
dfprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
|
||||
dfprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
|
||||
}
|
||||
|
||||
/*
|
||||
* now have to check for OS support of AVX instructions
|
||||
*/
|
||||
if (!FLAC__HAS_X86INTRIN || !info->ia32.avx || !ia32_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) {
|
||||
/* no OS AVX support */
|
||||
info->ia32.avx = false;
|
||||
info->ia32.avx2 = false;
|
||||
info->ia32.fma = false;
|
||||
}
|
||||
|
||||
if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
|
||||
dfprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
|
||||
}
|
||||
#else
|
||||
info->use_asm = false;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
x86_64_cpu_info (FLAC__CPUInfo *info)
|
||||
{
|
||||
#if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN
|
||||
FLAC__bool x86_osxsave = false;
|
||||
FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
|
||||
|
||||
info->use_asm = true;
|
||||
|
||||
/* http://www.sandpile.org/x86/cpuid.htm */
|
||||
FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */
|
||||
FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false;
|
||||
info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false;
|
||||
info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false;
|
||||
info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false;
|
||||
|
||||
if (FLAC__AVX_SUPPORTED) {
|
||||
x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false;
|
||||
info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX ) ? true : false;
|
||||
info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA ) ? true : false;
|
||||
FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
|
||||
info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false;
|
||||
}
|
||||
|
||||
dfprintf(stderr, "CPU info (x86-64):\n");
|
||||
dfprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
|
||||
dfprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
|
||||
|
||||
if (FLAC__AVX_SUPPORTED) {
|
||||
dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
|
||||
dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
|
||||
dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
|
||||
}
|
||||
|
||||
/*
|
||||
* now have to check for OS support of AVX instructions
|
||||
*/
|
||||
if (!info->x86.avx || !x86_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) {
|
||||
/* no OS AVX support */
|
||||
info->x86.avx = false;
|
||||
info->x86.avx2 = false;
|
||||
info->x86.fma = false;
|
||||
}
|
||||
|
||||
if (FLAC__AVX_SUPPORTED) {
|
||||
dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
|
||||
}
|
||||
#else
|
||||
/* Silence compiler warnings. */
|
||||
(void) info;
|
||||
#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64
|
||||
if (0) cpu_xgetbv_x86 ();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void FLAC__cpu_info (FLAC__CPUInfo *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
info->type = FLAC__CPUINFO_TYPE_IA32;
|
||||
#elif defined FLAC__CPU_X86_64
|
||||
info->type = FLAC__CPUINFO_TYPE_X86_64;
|
||||
#else
|
||||
info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
|
||||
info->use_asm = false;
|
||||
#endif
|
||||
|
||||
switch (info->type) {
|
||||
case FLAC__CPUINFO_TYPE_IA32:
|
||||
ia32_cpu_info (info);
|
||||
break;
|
||||
case FLAC__CPUINFO_TYPE_X86_64:
|
||||
x86_64_cpu_info (info);
|
||||
break;
|
||||
default:
|
||||
info->use_asm = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
|
||||
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
|
||||
{
|
||||
#if defined _MSC_VER || defined __INTEL_COMPILER
|
||||
int cpuinfo[4];
|
||||
int ext = level & 0x80000000;
|
||||
__cpuid(cpuinfo, ext);
|
||||
if((unsigned)cpuinfo[0] >= level) {
|
||||
#if FLAC__AVX_SUPPORTED
|
||||
__cpuidex(cpuinfo, ext, 0); /* for AVX2 detection */
|
||||
#else
|
||||
__cpuid(cpuinfo, ext); /* some old compilers don't support __cpuidex */
|
||||
#endif
|
||||
|
||||
*eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
|
||||
|
||||
return;
|
||||
}
|
||||
#elif defined __GNUC__ && defined HAVE_CPUID_H
|
||||
FLAC__uint32 ext = level & 0x80000000;
|
||||
__cpuid(ext, *eax, *ebx, *ecx, *edx);
|
||||
if (*eax >= level) {
|
||||
__cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
}
|
||||
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
|
@ -0,0 +1,143 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/crc.h"
|
||||
|
||||
/* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
|
||||
|
||||
FLAC__byte const FLAC__crc8_table[256] = {
|
||||
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
|
||||
0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
|
||||
0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
|
||||
0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
|
||||
0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
|
||||
0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
|
||||
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
|
||||
0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
|
||||
0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
|
||||
0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
|
||||
0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
|
||||
0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
|
||||
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
|
||||
0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
|
||||
0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
|
||||
0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
|
||||
0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
|
||||
0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
|
||||
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
|
||||
0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
|
||||
0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
|
||||
0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
|
||||
0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
|
||||
0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
|
||||
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
|
||||
0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
|
||||
0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
|
||||
0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
|
||||
0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
|
||||
0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
|
||||
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
|
||||
0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
|
||||
};
|
||||
|
||||
/* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
|
||||
|
||||
unsigned const FLAC__crc16_table[256] = {
|
||||
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
|
||||
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
|
||||
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
|
||||
0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
|
||||
0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
|
||||
0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
|
||||
0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
|
||||
0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
|
||||
0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
|
||||
0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
|
||||
0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
|
||||
0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
|
||||
0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
|
||||
0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
|
||||
0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
|
||||
0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
|
||||
0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
|
||||
0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
|
||||
0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
|
||||
0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
|
||||
0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
|
||||
0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
|
||||
0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
|
||||
0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
|
||||
0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
|
||||
0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
|
||||
0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
|
||||
0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
|
||||
0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
|
||||
0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
|
||||
0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
|
||||
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
|
||||
};
|
||||
|
||||
|
||||
void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc)
|
||||
{
|
||||
*crc = FLAC__crc8_table[*crc ^ data];
|
||||
}
|
||||
|
||||
void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc)
|
||||
{
|
||||
while(len--)
|
||||
*crc = FLAC__crc8_table[*crc ^ *data++];
|
||||
}
|
||||
|
||||
FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len)
|
||||
{
|
||||
FLAC__uint8 crc = 0;
|
||||
|
||||
while(len--)
|
||||
crc = FLAC__crc8_table[crc ^ *data++];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
unsigned FLAC__crc16(const FLAC__byte *data, unsigned len)
|
||||
{
|
||||
unsigned crc = 0;
|
||||
|
||||
while(len--)
|
||||
crc = ((crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]) & 0xffff;
|
||||
|
||||
return crc;
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "share/compat.h"
|
||||
#include "private/bitmath.h"
|
||||
#include "private/fixed.h"
|
||||
#include "private/macros.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef local_abs
|
||||
#undef local_abs
|
||||
#endif
|
||||
#define local_abs(x) ((unsigned)((x)<0? -(x) : (x)))
|
||||
|
||||
#ifdef FLAC__INTEGER_ONLY_LIBRARY
|
||||
/* rbps stands for residual bits per sample
|
||||
*
|
||||
* (ln(2) * err)
|
||||
* rbps = log (-----------)
|
||||
* 2 ( n )
|
||||
*/
|
||||
static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n)
|
||||
{
|
||||
FLAC__uint32 rbps;
|
||||
unsigned bits; /* the number of bits required to represent a number */
|
||||
int fracbits; /* the number of bits of rbps that comprise the fractional part */
|
||||
|
||||
FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
|
||||
FLAC__ASSERT(err > 0);
|
||||
FLAC__ASSERT(n > 0);
|
||||
|
||||
FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
|
||||
if(err <= n)
|
||||
return 0;
|
||||
/*
|
||||
* The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
|
||||
* These allow us later to know we won't lose too much precision in the
|
||||
* fixed-point division (err<<fracbits)/n.
|
||||
*/
|
||||
|
||||
fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1);
|
||||
|
||||
err <<= fracbits;
|
||||
err /= n;
|
||||
/* err now holds err/n with fracbits fractional bits */
|
||||
|
||||
/*
|
||||
* Whittle err down to 16 bits max. 16 significant bits is enough for
|
||||
* our purposes.
|
||||
*/
|
||||
FLAC__ASSERT(err > 0);
|
||||
bits = FLAC__bitmath_ilog2(err)+1;
|
||||
if(bits > 16) {
|
||||
err >>= (bits-16);
|
||||
fracbits -= (bits-16);
|
||||
}
|
||||
rbps = (FLAC__uint32)err;
|
||||
|
||||
/* Multiply by fixed-point version of ln(2), with 16 fractional bits */
|
||||
rbps *= FLAC__FP_LN2;
|
||||
fracbits += 16;
|
||||
FLAC__ASSERT(fracbits >= 0);
|
||||
|
||||
/* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
|
||||
{
|
||||
const int f = fracbits & 3;
|
||||
if(f) {
|
||||
rbps >>= f;
|
||||
fracbits -= f;
|
||||
}
|
||||
}
|
||||
|
||||
rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
|
||||
|
||||
if(rbps == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The return value must have 16 fractional bits. Since the whole part
|
||||
* of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
|
||||
* must be >= -3, these assertion allows us to be able to shift rbps
|
||||
* left if necessary to get 16 fracbits without losing any bits of the
|
||||
* whole part of rbps.
|
||||
*
|
||||
* There is a slight chance due to accumulated error that the whole part
|
||||
* will require 6 bits, so we use 6 in the assertion. Really though as
|
||||
* long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
|
||||
*/
|
||||
FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
|
||||
FLAC__ASSERT(fracbits >= -3);
|
||||
|
||||
/* now shift the decimal point into place */
|
||||
if(fracbits < 16)
|
||||
return rbps << (16-fracbits);
|
||||
else if(fracbits > 16)
|
||||
return rbps >> (fracbits-16);
|
||||
else
|
||||
return rbps;
|
||||
}
|
||||
|
||||
static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n)
|
||||
{
|
||||
FLAC__uint32 rbps;
|
||||
unsigned bits; /* the number of bits required to represent a number */
|
||||
int fracbits; /* the number of bits of rbps that comprise the fractional part */
|
||||
|
||||
FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint));
|
||||
FLAC__ASSERT(err > 0);
|
||||
FLAC__ASSERT(n > 0);
|
||||
|
||||
FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE);
|
||||
if(err <= n)
|
||||
return 0;
|
||||
/*
|
||||
* The above two things tell us 1) n fits in 16 bits; 2) err/n > 1.
|
||||
* These allow us later to know we won't lose too much precision in the
|
||||
* fixed-point division (err<<fracbits)/n.
|
||||
*/
|
||||
|
||||
fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1);
|
||||
|
||||
err <<= fracbits;
|
||||
err /= n;
|
||||
/* err now holds err/n with fracbits fractional bits */
|
||||
|
||||
/*
|
||||
* Whittle err down to 16 bits max. 16 significant bits is enough for
|
||||
* our purposes.
|
||||
*/
|
||||
FLAC__ASSERT(err > 0);
|
||||
bits = FLAC__bitmath_ilog2_wide(err)+1;
|
||||
if(bits > 16) {
|
||||
err >>= (bits-16);
|
||||
fracbits -= (bits-16);
|
||||
}
|
||||
rbps = (FLAC__uint32)err;
|
||||
|
||||
/* Multiply by fixed-point version of ln(2), with 16 fractional bits */
|
||||
rbps *= FLAC__FP_LN2;
|
||||
fracbits += 16;
|
||||
FLAC__ASSERT(fracbits >= 0);
|
||||
|
||||
/* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */
|
||||
{
|
||||
const int f = fracbits & 3;
|
||||
if(f) {
|
||||
rbps >>= f;
|
||||
fracbits -= f;
|
||||
}
|
||||
}
|
||||
|
||||
rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1));
|
||||
|
||||
if(rbps == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The return value must have 16 fractional bits. Since the whole part
|
||||
* of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits
|
||||
* must be >= -3, these assertion allows us to be able to shift rbps
|
||||
* left if necessary to get 16 fracbits without losing any bits of the
|
||||
* whole part of rbps.
|
||||
*
|
||||
* There is a slight chance due to accumulated error that the whole part
|
||||
* will require 6 bits, so we use 6 in the assertion. Really though as
|
||||
* long as it fits in 13 bits (32 - (16 - (-3))) we are fine.
|
||||
*/
|
||||
FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6);
|
||||
FLAC__ASSERT(fracbits >= -3);
|
||||
|
||||
/* now shift the decimal point into place */
|
||||
if(fracbits < 16)
|
||||
return rbps << (16-fracbits);
|
||||
else if(fracbits > 16)
|
||||
return rbps >> (fracbits-16);
|
||||
else
|
||||
return rbps;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#endif
|
||||
{
|
||||
FLAC__int32 last_error_0 = data[-1];
|
||||
FLAC__int32 last_error_1 = data[-1] - data[-2];
|
||||
FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
|
||||
FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
|
||||
FLAC__int32 error, save;
|
||||
FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
|
||||
unsigned i, order;
|
||||
|
||||
for(i = 0; i < data_len; i++) {
|
||||
error = data[i] ; total_error_0 += local_abs(error); save = error;
|
||||
error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
|
||||
error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
|
||||
error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
|
||||
error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
|
||||
}
|
||||
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
#else
|
||||
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0;
|
||||
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0;
|
||||
residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0;
|
||||
residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0;
|
||||
residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0;
|
||||
#endif
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
|
||||
#endif
|
||||
{
|
||||
FLAC__int32 last_error_0 = data[-1];
|
||||
FLAC__int32 last_error_1 = data[-1] - data[-2];
|
||||
FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
|
||||
FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
|
||||
FLAC__int32 error, save;
|
||||
/* total_error_* are 64-bits to avoid overflow when encoding
|
||||
* erratic signals when the bits-per-sample and blocksize are
|
||||
* large.
|
||||
*/
|
||||
FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
|
||||
unsigned i, order;
|
||||
|
||||
for(i = 0; i < data_len; i++) {
|
||||
error = data[i] ; total_error_0 += local_abs(error); save = error;
|
||||
error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
|
||||
error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
|
||||
error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
|
||||
error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
|
||||
}
|
||||
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
#else
|
||||
residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0;
|
||||
residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;
|
||||
residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0;
|
||||
residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0;
|
||||
residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0;
|
||||
#endif
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[])
|
||||
{
|
||||
const int idata_len = (int)data_len;
|
||||
int i;
|
||||
|
||||
switch(order) {
|
||||
case 0:
|
||||
FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
|
||||
memcpy(residual, data, sizeof(residual[0])*data_len);
|
||||
break;
|
||||
case 1:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
residual[i] = data[i] - data[i-1];
|
||||
break;
|
||||
case 2:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
residual[i] = data[i] - 2*data[i-1] + data[i-2];
|
||||
break;
|
||||
case 3:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3];
|
||||
break;
|
||||
case 4:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4];
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[])
|
||||
{
|
||||
int i, idata_len = (int)data_len;
|
||||
|
||||
switch(order) {
|
||||
case 0:
|
||||
FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0]));
|
||||
memcpy(data, residual, sizeof(residual[0])*data_len);
|
||||
break;
|
||||
case 1:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
data[i] = residual[i] + data[i-1];
|
||||
break;
|
||||
case 2:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
data[i] = residual[i] + 2*data[i-1] - data[i-2];
|
||||
break;
|
||||
case 3:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3];
|
||||
break;
|
||||
case 4:
|
||||
for(i = 0; i < idata_len; i++)
|
||||
data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4];
|
||||
break;
|
||||
default:
|
||||
FLAC__ASSERT(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
|
||||
#include "private/fixed.h"
|
||||
#ifdef FLAC__SSE2_SUPPORTED
|
||||
|
||||
#include <emmintrin.h> /* SSE2 */
|
||||
#include <math.h>
|
||||
#include "private/macros.h"
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
|
||||
#else
|
||||
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
|
||||
#endif
|
||||
|
||||
FLAC__SSE_TARGET("sse2")
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err2;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error;
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1, tmp;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
|
||||
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
|
||||
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
|
||||
|
||||
tmp = _mm_srai_epi32(err0, 31);
|
||||
err0 = _mm_xor_si128(err0, tmp);
|
||||
err0 = _mm_sub_epi32(err0, tmp);
|
||||
tmp = _mm_srai_epi32(err1, 31);
|
||||
err1 = _mm_xor_si128(err1, tmp);
|
||||
err1 = _mm_sub_epi32(err1, tmp);
|
||||
|
||||
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
|
||||
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
|
||||
}
|
||||
}
|
||||
|
||||
total_error_0 = _mm_cvtsi128_si32(total_err0);
|
||||
total_err2 = total_err1; // te1 te2 te3 te4
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
|
||||
total_error_4 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_2 = _mm_cvtsi128_si32(total_err1);
|
||||
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
|
||||
total_error_3 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_1 = _mm_cvtsi128_si32(total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse2")
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err3;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error, zero = _mm_setzero_si128();
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1, tmp;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
|
||||
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
|
||||
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
|
||||
|
||||
tmp = _mm_srai_epi32(err0, 31);
|
||||
err0 = _mm_xor_si128(err0, tmp);
|
||||
err0 = _mm_sub_epi32(err0, tmp);
|
||||
tmp = _mm_srai_epi32(err1, 31);
|
||||
err1 = _mm_xor_si128(err1, tmp);
|
||||
err1 = _mm_sub_epi32(err1, tmp);
|
||||
|
||||
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
|
||||
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
|
||||
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
|
||||
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
|
||||
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
|
||||
}
|
||||
}
|
||||
|
||||
m128i_to_i64(total_error_0, total_err0);
|
||||
m128i_to_i64(total_error_4, total_err3);
|
||||
m128i_to_i64(total_error_2, total_err1);
|
||||
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
|
||||
m128i_to_i64(total_error_3, total_err3);
|
||||
m128i_to_i64(total_error_1, total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSE2_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
|
@ -0,0 +1,243 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
#include "private/fixed.h"
|
||||
#ifdef FLAC__SSSE3_SUPPORTED
|
||||
|
||||
#include <tmmintrin.h> /* SSSE3 */
|
||||
#include <math.h>
|
||||
#include "private/macros.h"
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#ifdef FLAC__CPU_IA32
|
||||
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
|
||||
#else
|
||||
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
|
||||
#endif
|
||||
|
||||
FLAC__SSE_TARGET("ssse3")
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err2;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error;
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
|
||||
|
||||
err0 = _mm_abs_epi32(err0);
|
||||
err1 = _mm_abs_epi32(err1);
|
||||
|
||||
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
|
||||
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
|
||||
}
|
||||
}
|
||||
|
||||
total_error_0 = _mm_cvtsi128_si32(total_err0);
|
||||
total_err2 = total_err1; // te1 te2 te3 te4
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
|
||||
total_error_4 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_2 = _mm_cvtsi128_si32(total_err1);
|
||||
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
|
||||
total_error_3 = _mm_cvtsi128_si32(total_err2);
|
||||
total_error_1 = _mm_cvtsi128_si32(total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("ssse3")
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
|
||||
{
|
||||
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
|
||||
unsigned i, order;
|
||||
|
||||
__m128i total_err0, total_err1, total_err3;
|
||||
|
||||
{
|
||||
FLAC__int32 itmp;
|
||||
__m128i last_error, zero = _mm_setzero_si128();
|
||||
|
||||
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
|
||||
itmp = data[-2];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
|
||||
itmp -= data[-3];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
|
||||
itmp -= data[-3] - data[-4];
|
||||
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
|
||||
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
|
||||
|
||||
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
|
||||
for(i = 0; i < data_len; i++) {
|
||||
__m128i err0, err1;
|
||||
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
|
||||
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
|
||||
#if 1 /* OPT_SSE */
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
|
||||
err1 = _mm_sub_epi32(err1, last_error);
|
||||
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#else
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
|
||||
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
|
||||
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
|
||||
#endif
|
||||
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
|
||||
|
||||
err0 = _mm_abs_epi32(err0);
|
||||
err1 = _mm_abs_epi32(err1); // |e1| |e2| |e3| |e4|
|
||||
|
||||
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
|
||||
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
|
||||
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
|
||||
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
|
||||
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
|
||||
}
|
||||
}
|
||||
|
||||
m128i_to_i64(total_error_0, total_err0);
|
||||
m128i_to_i64(total_error_4, total_err3);
|
||||
m128i_to_i64(total_error_2, total_err1);
|
||||
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
|
||||
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
|
||||
m128i_to_i64(total_error_3, total_err3);
|
||||
m128i_to_i64(total_error_1, total_err1);
|
||||
|
||||
/* prefer higher order */
|
||||
if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
|
||||
order = 0;
|
||||
else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
|
||||
order = 1;
|
||||
else if(total_error_2 < flac_min(total_error_3, total_error_4))
|
||||
order = 2;
|
||||
else if(total_error_3 < total_error_4)
|
||||
order = 3;
|
||||
else
|
||||
order = 4;
|
||||
|
||||
/* Estimate the expected number of bits per residual signal sample. */
|
||||
/* 'total_error*' is linearly related to the variance of the residual */
|
||||
/* signal, so we use it directly to compute E(|x|) */
|
||||
FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
|
||||
FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
|
||||
|
||||
residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
|
||||
residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSSE3_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
|
@ -0,0 +1,302 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/compat.h"
|
||||
#include "private/float.h"
|
||||
|
||||
#ifdef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
const FLAC__fixedpoint FLAC__FP_ZERO = 0;
|
||||
const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000;
|
||||
const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000;
|
||||
const FLAC__fixedpoint FLAC__FP_LN2 = 45426;
|
||||
const FLAC__fixedpoint FLAC__FP_E = 178145;
|
||||
|
||||
/* Lookup tables for Knuth's logarithm algorithm */
|
||||
#define LOG2_LOOKUP_PRECISION 16
|
||||
static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = {
|
||||
{
|
||||
/*
|
||||
* 0 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000001,
|
||||
/* lg(4/3) = */ 0x00000000,
|
||||
/* lg(8/7) = */ 0x00000000,
|
||||
/* lg(16/15) = */ 0x00000000,
|
||||
/* lg(32/31) = */ 0x00000000,
|
||||
/* lg(64/63) = */ 0x00000000,
|
||||
/* lg(128/127) = */ 0x00000000,
|
||||
/* lg(256/255) = */ 0x00000000,
|
||||
/* lg(512/511) = */ 0x00000000,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 4 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000010,
|
||||
/* lg(4/3) = */ 0x00000007,
|
||||
/* lg(8/7) = */ 0x00000003,
|
||||
/* lg(16/15) = */ 0x00000001,
|
||||
/* lg(32/31) = */ 0x00000001,
|
||||
/* lg(64/63) = */ 0x00000000,
|
||||
/* lg(128/127) = */ 0x00000000,
|
||||
/* lg(256/255) = */ 0x00000000,
|
||||
/* lg(512/511) = */ 0x00000000,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 8 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00000100,
|
||||
/* lg(4/3) = */ 0x0000006a,
|
||||
/* lg(8/7) = */ 0x00000031,
|
||||
/* lg(16/15) = */ 0x00000018,
|
||||
/* lg(32/31) = */ 0x0000000c,
|
||||
/* lg(64/63) = */ 0x00000006,
|
||||
/* lg(128/127) = */ 0x00000003,
|
||||
/* lg(256/255) = */ 0x00000001,
|
||||
/* lg(512/511) = */ 0x00000001,
|
||||
/* lg(1024/1023) = */ 0x00000000,
|
||||
/* lg(2048/2047) = */ 0x00000000,
|
||||
/* lg(4096/4095) = */ 0x00000000,
|
||||
/* lg(8192/8191) = */ 0x00000000,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 12 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00001000,
|
||||
/* lg(4/3) = */ 0x000006a4,
|
||||
/* lg(8/7) = */ 0x00000315,
|
||||
/* lg(16/15) = */ 0x0000017d,
|
||||
/* lg(32/31) = */ 0x000000bc,
|
||||
/* lg(64/63) = */ 0x0000005d,
|
||||
/* lg(128/127) = */ 0x0000002e,
|
||||
/* lg(256/255) = */ 0x00000017,
|
||||
/* lg(512/511) = */ 0x0000000c,
|
||||
/* lg(1024/1023) = */ 0x00000006,
|
||||
/* lg(2048/2047) = */ 0x00000003,
|
||||
/* lg(4096/4095) = */ 0x00000001,
|
||||
/* lg(8192/8191) = */ 0x00000001,
|
||||
/* lg(16384/16383) = */ 0x00000000,
|
||||
/* lg(32768/32767) = */ 0x00000000
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 16 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00010000,
|
||||
/* lg(4/3) = */ 0x00006a40,
|
||||
/* lg(8/7) = */ 0x00003151,
|
||||
/* lg(16/15) = */ 0x000017d6,
|
||||
/* lg(32/31) = */ 0x00000bba,
|
||||
/* lg(64/63) = */ 0x000005d1,
|
||||
/* lg(128/127) = */ 0x000002e6,
|
||||
/* lg(256/255) = */ 0x00000172,
|
||||
/* lg(512/511) = */ 0x000000b9,
|
||||
/* lg(1024/1023) = */ 0x0000005c,
|
||||
/* lg(2048/2047) = */ 0x0000002e,
|
||||
/* lg(4096/4095) = */ 0x00000017,
|
||||
/* lg(8192/8191) = */ 0x0000000c,
|
||||
/* lg(16384/16383) = */ 0x00000006,
|
||||
/* lg(32768/32767) = */ 0x00000003
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 20 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x00100000,
|
||||
/* lg(4/3) = */ 0x0006a3fe,
|
||||
/* lg(8/7) = */ 0x00031513,
|
||||
/* lg(16/15) = */ 0x00017d60,
|
||||
/* lg(32/31) = */ 0x0000bb9d,
|
||||
/* lg(64/63) = */ 0x00005d10,
|
||||
/* lg(128/127) = */ 0x00002e59,
|
||||
/* lg(256/255) = */ 0x00001721,
|
||||
/* lg(512/511) = */ 0x00000b8e,
|
||||
/* lg(1024/1023) = */ 0x000005c6,
|
||||
/* lg(2048/2047) = */ 0x000002e3,
|
||||
/* lg(4096/4095) = */ 0x00000171,
|
||||
/* lg(8192/8191) = */ 0x000000b9,
|
||||
/* lg(16384/16383) = */ 0x0000005c,
|
||||
/* lg(32768/32767) = */ 0x0000002e
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 24 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x01000000,
|
||||
/* lg(4/3) = */ 0x006a3fe6,
|
||||
/* lg(8/7) = */ 0x00315130,
|
||||
/* lg(16/15) = */ 0x0017d605,
|
||||
/* lg(32/31) = */ 0x000bb9ca,
|
||||
/* lg(64/63) = */ 0x0005d0fc,
|
||||
/* lg(128/127) = */ 0x0002e58f,
|
||||
/* lg(256/255) = */ 0x0001720e,
|
||||
/* lg(512/511) = */ 0x0000b8d8,
|
||||
/* lg(1024/1023) = */ 0x00005c61,
|
||||
/* lg(2048/2047) = */ 0x00002e2d,
|
||||
/* lg(4096/4095) = */ 0x00001716,
|
||||
/* lg(8192/8191) = */ 0x00000b8b,
|
||||
/* lg(16384/16383) = */ 0x000005c5,
|
||||
/* lg(32768/32767) = */ 0x000002e3
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 28 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ 0x10000000,
|
||||
/* lg(4/3) = */ 0x06a3fe5c,
|
||||
/* lg(8/7) = */ 0x03151301,
|
||||
/* lg(16/15) = */ 0x017d6049,
|
||||
/* lg(32/31) = */ 0x00bb9ca6,
|
||||
/* lg(64/63) = */ 0x005d0fba,
|
||||
/* lg(128/127) = */ 0x002e58f7,
|
||||
/* lg(256/255) = */ 0x001720da,
|
||||
/* lg(512/511) = */ 0x000b8d87,
|
||||
/* lg(1024/1023) = */ 0x0005c60b,
|
||||
/* lg(2048/2047) = */ 0x0002e2d7,
|
||||
/* lg(4096/4095) = */ 0x00017160,
|
||||
/* lg(8192/8191) = */ 0x0000b8ad,
|
||||
/* lg(16384/16383) = */ 0x00005c56,
|
||||
/* lg(32768/32767) = */ 0x00002e2b
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const FLAC__uint64 log2_lookup_wide[] = {
|
||||
{
|
||||
/*
|
||||
* 32 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ FLAC__U64L(0x100000000),
|
||||
/* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6),
|
||||
/* lg(8/7) = */ FLAC__U64L(0x31513015),
|
||||
/* lg(16/15) = */ FLAC__U64L(0x17d60497),
|
||||
/* lg(32/31) = */ FLAC__U64L(0x0bb9ca65),
|
||||
/* lg(64/63) = */ FLAC__U64L(0x05d0fba2),
|
||||
/* lg(128/127) = */ FLAC__U64L(0x02e58f74),
|
||||
/* lg(256/255) = */ FLAC__U64L(0x01720d9c),
|
||||
/* lg(512/511) = */ FLAC__U64L(0x00b8d875),
|
||||
/* lg(1024/1023) = */ FLAC__U64L(0x005c60aa),
|
||||
/* lg(2048/2047) = */ FLAC__U64L(0x002e2d72),
|
||||
/* lg(4096/4095) = */ FLAC__U64L(0x00171600),
|
||||
/* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2),
|
||||
/* lg(16384/16383) = */ FLAC__U64L(0x0005c55d),
|
||||
/* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac)
|
||||
},
|
||||
{
|
||||
/*
|
||||
* 48 fraction bits
|
||||
*/
|
||||
/* undefined */ 0x00000000,
|
||||
/* lg(2/1) = */ FLAC__U64L(0x1000000000000),
|
||||
/* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429),
|
||||
/* lg(8/7) = */ FLAC__U64L(0x315130157f7a),
|
||||
/* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb),
|
||||
/* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac),
|
||||
/* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd),
|
||||
/* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee),
|
||||
/* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8),
|
||||
/* lg(512/511) = */ FLAC__U64L(0xb8d8752173),
|
||||
/* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e),
|
||||
/* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8),
|
||||
/* lg(4096/4095) = */ FLAC__U64L(0x1716001719),
|
||||
/* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b),
|
||||
/* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d),
|
||||
/* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52)
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision)
|
||||
{
|
||||
const FLAC__uint32 ONE = (1u << fracbits);
|
||||
const FLAC__uint32 *table = log2_lookup[fracbits >> 2];
|
||||
|
||||
FLAC__ASSERT(fracbits < 32);
|
||||
FLAC__ASSERT((fracbits & 0x3) == 0);
|
||||
|
||||
if(x < ONE)
|
||||
return 0;
|
||||
|
||||
if(precision > LOG2_LOOKUP_PRECISION)
|
||||
precision = LOG2_LOOKUP_PRECISION;
|
||||
|
||||
/* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */
|
||||
{
|
||||
FLAC__uint32 y = 0;
|
||||
FLAC__uint32 z = x >> 1, k = 1;
|
||||
while (x > ONE && k < precision) {
|
||||
if (x - z >= ONE) {
|
||||
x -= z;
|
||||
z = x >> k;
|
||||
y += table[k];
|
||||
}
|
||||
else {
|
||||
z >>= 1;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined FLAC__INTEGER_ONLY_LIBRARY */
|
|
@ -0,0 +1,589 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* for qsort() */
|
||||
#include <string.h> /* for memset() */
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
#include "share/alloc.h"
|
||||
#include "share/compat.h"
|
||||
#include "private/format.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
/* PACKAGE_VERSION should come from configure */
|
||||
FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION;
|
||||
|
||||
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20170101";
|
||||
|
||||
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
|
||||
FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
|
||||
FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
|
||||
|
||||
FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
|
||||
FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
|
||||
FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
|
||||
|
||||
FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
|
||||
"PARTITIONED_RICE",
|
||||
"PARTITIONED_RICE2"
|
||||
};
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
|
||||
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
|
||||
FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
|
||||
|
||||
FLAC_API const char * const FLAC__SubframeTypeString[] = {
|
||||
"CONSTANT",
|
||||
"VERBATIM",
|
||||
"FIXED",
|
||||
"LPC"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
|
||||
"INDEPENDENT",
|
||||
"LEFT_SIDE",
|
||||
"RIGHT_SIDE",
|
||||
"MID_SIDE"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
|
||||
"FRAME_NUMBER_TYPE_FRAME_NUMBER",
|
||||
"FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__MetadataTypeString[] = {
|
||||
"STREAMINFO",
|
||||
"PADDING",
|
||||
"APPLICATION",
|
||||
"SEEKTABLE",
|
||||
"VORBIS_COMMENT",
|
||||
"CUESHEET",
|
||||
"PICTURE"
|
||||
};
|
||||
|
||||
FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
|
||||
"Other",
|
||||
"32x32 pixels 'file icon' (PNG only)",
|
||||
"Other file icon",
|
||||
"Cover (front)",
|
||||
"Cover (back)",
|
||||
"Leaflet page",
|
||||
"Media (e.g. label side of CD)",
|
||||
"Lead artist/lead performer/soloist",
|
||||
"Artist/performer",
|
||||
"Conductor",
|
||||
"Band/Orchestra",
|
||||
"Composer",
|
||||
"Lyricist/text writer",
|
||||
"Recording Location",
|
||||
"During recording",
|
||||
"During performance",
|
||||
"Movie/video screen capture",
|
||||
"A bright coloured fish",
|
||||
"Illustration",
|
||||
"Band/artist logotype",
|
||||
"Publisher/Studio logotype"
|
||||
};
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
|
||||
{
|
||||
if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate)
|
||||
{
|
||||
if(blocksize > 16384)
|
||||
return false;
|
||||
else if(sample_rate <= 48000 && blocksize > 4608)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
|
||||
{
|
||||
if(
|
||||
!FLAC__format_sample_rate_is_valid(sample_rate) ||
|
||||
(
|
||||
sample_rate >= (1u << 16) &&
|
||||
!(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
|
||||
{
|
||||
unsigned i;
|
||||
FLAC__uint64 prev_sample_number = 0;
|
||||
FLAC__bool got_prev = false;
|
||||
|
||||
FLAC__ASSERT(0 != seek_table);
|
||||
|
||||
for(i = 0; i < seek_table->num_points; i++) {
|
||||
if(got_prev) {
|
||||
if(
|
||||
seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
|
||||
seek_table->points[i].sample_number <= prev_sample_number
|
||||
)
|
||||
return false;
|
||||
}
|
||||
prev_sample_number = seek_table->points[i].sample_number;
|
||||
got_prev = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* used as the sort predicate for qsort() */
|
||||
static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
|
||||
{
|
||||
/* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
|
||||
if(l->sample_number == r->sample_number)
|
||||
return 0;
|
||||
else if(l->sample_number < r->sample_number)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
|
||||
{
|
||||
unsigned i, j;
|
||||
FLAC__bool first;
|
||||
|
||||
FLAC__ASSERT(0 != seek_table);
|
||||
|
||||
if (seek_table->num_points == 0)
|
||||
return 0;
|
||||
|
||||
/* sort the seekpoints */
|
||||
qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
|
||||
|
||||
/* uniquify the seekpoints */
|
||||
first = true;
|
||||
for(i = j = 0; i < seek_table->num_points; i++) {
|
||||
if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
|
||||
if(!first) {
|
||||
if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
seek_table->points[j++] = seek_table->points[i];
|
||||
}
|
||||
|
||||
for(i = j; i < seek_table->num_points; i++) {
|
||||
seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
|
||||
seek_table->points[i].stream_offset = 0;
|
||||
seek_table->points[i].frame_samples = 0;
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* also disallows non-shortest-form encodings, c.f.
|
||||
* http://www.unicode.org/versions/corrigendum1.html
|
||||
* and a more clear explanation at the end of this section:
|
||||
* http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
*/
|
||||
static unsigned utf8len_(const FLAC__byte *utf8)
|
||||
{
|
||||
FLAC__ASSERT(0 != utf8);
|
||||
if ((utf8[0] & 0x80) == 0) {
|
||||
return 1;
|
||||
}
|
||||
else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
|
||||
if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
/* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
|
||||
if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
|
||||
return 0;
|
||||
if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
|
||||
return 0;
|
||||
return 3;
|
||||
}
|
||||
else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 4;
|
||||
}
|
||||
else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 5;
|
||||
}
|
||||
else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) {
|
||||
if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
|
||||
return 0;
|
||||
return 6;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
|
||||
{
|
||||
char c;
|
||||
for(c = *name; c; c = *(++name))
|
||||
if(c < 0x20 || c == 0x3d || c > 0x7d)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
|
||||
{
|
||||
if(length == (unsigned)(-1)) {
|
||||
while(*value) {
|
||||
unsigned n = utf8len_(value);
|
||||
if(n == 0)
|
||||
return false;
|
||||
value += n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const FLAC__byte *end = value + length;
|
||||
while(value < end) {
|
||||
unsigned n = utf8len_(value);
|
||||
if(n == 0)
|
||||
return false;
|
||||
value += n;
|
||||
}
|
||||
if(value != end)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length)
|
||||
{
|
||||
const FLAC__byte *s, *end;
|
||||
|
||||
for(s = entry, end = s + length; s < end && *s != '='; s++) {
|
||||
if(*s < 0x20 || *s > 0x7D)
|
||||
return false;
|
||||
}
|
||||
if(s == end)
|
||||
return false;
|
||||
|
||||
s++; /* skip '=' */
|
||||
|
||||
while(s < end) {
|
||||
unsigned n = utf8len_(s);
|
||||
if(n == 0)
|
||||
return false;
|
||||
s += n;
|
||||
}
|
||||
if(s != end)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
if(check_cd_da_subset) {
|
||||
if(cue_sheet->lead_in < 2 * 44100) {
|
||||
if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
|
||||
return false;
|
||||
}
|
||||
if(cue_sheet->lead_in % 588 != 0) {
|
||||
if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(cue_sheet->num_tracks == 0) {
|
||||
if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
|
||||
if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i = 0; i < cue_sheet->num_tracks; i++) {
|
||||
if(cue_sheet->tracks[i].number == 0) {
|
||||
if(violation) *violation = "cue sheet may not have a track number 0";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check_cd_da_subset) {
|
||||
if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
|
||||
if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
|
||||
if(violation) {
|
||||
if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
|
||||
*violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
|
||||
else
|
||||
*violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(i < cue_sheet->num_tracks - 1) {
|
||||
if(cue_sheet->tracks[i].num_indices == 0) {
|
||||
if(violation) *violation = "cue sheet track must have at least one index point";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cue_sheet->tracks[i].indices[0].number > 1) {
|
||||
if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
|
||||
if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
|
||||
if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(j > 0) {
|
||||
if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
|
||||
if(violation) *violation = "cue sheet track index numbers must increase by 1";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
|
||||
FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
|
||||
{
|
||||
char *p;
|
||||
FLAC__byte *b;
|
||||
|
||||
for(p = picture->mime_type; *p; p++) {
|
||||
if(*p < 0x20 || *p > 0x7e) {
|
||||
if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(b = picture->description; *b; ) {
|
||||
unsigned n = utf8len_(b);
|
||||
if(n == 0) {
|
||||
if(violation) *violation = "description string must be valid UTF-8";
|
||||
return false;
|
||||
}
|
||||
b += n;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* These routines are private to libFLAC
|
||||
*/
|
||||
unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
|
||||
{
|
||||
return
|
||||
FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
|
||||
FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
|
||||
blocksize,
|
||||
predictor_order
|
||||
);
|
||||
}
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
|
||||
{
|
||||
unsigned max_rice_partition_order = 0;
|
||||
while(!(blocksize & 1)) {
|
||||
max_rice_partition_order++;
|
||||
blocksize >>= 1;
|
||||
}
|
||||
return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
|
||||
}
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
|
||||
{
|
||||
unsigned max_rice_partition_order = limit;
|
||||
|
||||
while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
|
||||
max_rice_partition_order--;
|
||||
|
||||
FLAC__ASSERT(
|
||||
(max_rice_partition_order == 0 && blocksize >= predictor_order) ||
|
||||
(max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
|
||||
);
|
||||
|
||||
return max_rice_partition_order;
|
||||
}
|
||||
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
object->parameters = 0;
|
||||
object->raw_bits = 0;
|
||||
object->capacity_by_order = 0;
|
||||
}
|
||||
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
if(0 != object->parameters)
|
||||
free(object->parameters);
|
||||
if(0 != object->raw_bits)
|
||||
free(object->raw_bits);
|
||||
FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
|
||||
{
|
||||
FLAC__ASSERT(0 != object);
|
||||
|
||||
FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
|
||||
|
||||
if(object->capacity_by_order < max_partition_order) {
|
||||
if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
|
||||
return false;
|
||||
if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
|
||||
return false;
|
||||
memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
|
||||
object->capacity_by_order = max_partition_order;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__BITMATH_H
|
||||
#define FLAC__PRIVATE__BITMATH_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "FLAC/assert.h"
|
||||
|
||||
#include "share/compat.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h> /* for _BitScanReverse* */
|
||||
#endif
|
||||
|
||||
/* Will never be emitted for MSVC, GCC, Intel compilers */
|
||||
static inline unsigned int FLAC__clz_soft_uint32(FLAC__uint32 word)
|
||||
{
|
||||
static const unsigned char byte_to_unary_table[] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
return word > 0xffffff ? byte_to_unary_table[word >> 24] :
|
||||
word > 0xffff ? byte_to_unary_table[word >> 16] + 8 :
|
||||
word > 0xff ? byte_to_unary_table[word >> 8] + 16 :
|
||||
byte_to_unary_table[word] + 24;
|
||||
}
|
||||
|
||||
static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v)
|
||||
{
|
||||
/* Never used with input 0 */
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(v) ^ 31U;
|
||||
#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on
|
||||
* -march= setting or to a software routine in exotic machines. */
|
||||
return __builtin_clz(v);
|
||||
#elif defined(_MSC_VER)
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse(&idx, v);
|
||||
return idx ^ 31U;
|
||||
}
|
||||
#else
|
||||
return FLAC__clz_soft_uint32(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Used when 64-bit bsr/clz is unavailable; can use 32-bit bsr/clz when possible */
|
||||
static inline unsigned int FLAC__clz_soft_uint64(FLAC__uint64 word)
|
||||
{
|
||||
return (FLAC__uint32)(word>>32) ? FLAC__clz_uint32((FLAC__uint32)(word>>32)) :
|
||||
FLAC__clz_uint32((FLAC__uint32)word) + 32;
|
||||
}
|
||||
|
||||
static inline unsigned int FLAC__clz_uint64(FLAC__uint64 v)
|
||||
{
|
||||
/* Never used with input 0 */
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
return __builtin_clzll(v);
|
||||
#elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64))
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse64(&idx, v);
|
||||
return idx ^ 63U;
|
||||
}
|
||||
#else
|
||||
return FLAC__clz_soft_uint64(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* These two functions work with input 0 */
|
||||
static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
|
||||
{
|
||||
if (!v)
|
||||
return 32;
|
||||
return FLAC__clz_uint32(v);
|
||||
}
|
||||
|
||||
static inline unsigned int FLAC__clz2_uint64(FLAC__uint64 v)
|
||||
{
|
||||
if (!v)
|
||||
return 64;
|
||||
return FLAC__clz_uint64(v);
|
||||
}
|
||||
|
||||
/* An example of what FLAC__bitmath_ilog2() computes:
|
||||
*
|
||||
* ilog2( 0) = assertion failure
|
||||
* ilog2( 1) = 0
|
||||
* ilog2( 2) = 1
|
||||
* ilog2( 3) = 1
|
||||
* ilog2( 4) = 2
|
||||
* ilog2( 5) = 2
|
||||
* ilog2( 6) = 2
|
||||
* ilog2( 7) = 2
|
||||
* ilog2( 8) = 3
|
||||
* ilog2( 9) = 3
|
||||
* ilog2(10) = 3
|
||||
* ilog2(11) = 3
|
||||
* ilog2(12) = 3
|
||||
* ilog2(13) = 3
|
||||
* ilog2(14) = 3
|
||||
* ilog2(15) = 3
|
||||
* ilog2(16) = 4
|
||||
* ilog2(17) = 4
|
||||
* ilog2(18) = 4
|
||||
*/
|
||||
|
||||
static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v)
|
||||
{
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(v);
|
||||
#elif defined(_MSC_VER)
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse(&idx, v);
|
||||
return idx;
|
||||
}
|
||||
#else
|
||||
return FLAC__clz_uint32(v) ^ 31U;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
|
||||
{
|
||||
FLAC__ASSERT(v > 0);
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
return __builtin_clzll(v) ^ 63U;
|
||||
/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */
|
||||
#elif (defined(__INTEL_COMPILER) || defined(_MSC_VER)) && (defined(_M_IA64) || defined(_M_X64))
|
||||
{
|
||||
unsigned long idx;
|
||||
_BitScanReverse64(&idx, v);
|
||||
return idx;
|
||||
}
|
||||
#else
|
||||
/* Brain-damaged compilers will use the fastest possible way that is,
|
||||
de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf)
|
||||
(C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain).
|
||||
*/
|
||||
{
|
||||
static const unsigned char DEBRUIJN_IDX64[64]={
|
||||
0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
|
||||
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
|
||||
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56,
|
||||
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58
|
||||
};
|
||||
v|= v>>1;
|
||||
v|= v>>2;
|
||||
v|= v>>4;
|
||||
v|= v>>8;
|
||||
v|= v>>16;
|
||||
v|= v>>32;
|
||||
v= (v>>1)+1;
|
||||
return DEBRUIJN_IDX64[v*FLAC__U64L(0x218A392CD3D5DBF)>>58&0x3F];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned FLAC__bitmath_silog2(FLAC__int64 v);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,91 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__BITREADER_H
|
||||
#define FLAC__PRIVATE__BITREADER_H
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
#include "FLAC/ordinals.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* opaque structure definition
|
||||
*/
|
||||
struct FLAC__BitReader;
|
||||
typedef struct FLAC__BitReader FLAC__BitReader;
|
||||
|
||||
typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data);
|
||||
|
||||
/*
|
||||
* construction, deletion, initialization, etc functions
|
||||
*/
|
||||
FLAC__BitReader *FLAC__bitreader_new(void);
|
||||
void FLAC__bitreader_delete(FLAC__BitReader *br);
|
||||
FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd);
|
||||
void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
|
||||
FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
|
||||
void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out);
|
||||
|
||||
/*
|
||||
* CRC functions
|
||||
*/
|
||||
void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed);
|
||||
FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br);
|
||||
|
||||
/*
|
||||
* info functions
|
||||
*/
|
||||
FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br);
|
||||
unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br);
|
||||
unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br);
|
||||
|
||||
/*
|
||||
* read functions
|
||||
*/
|
||||
|
||||
FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits);
|
||||
FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/
|
||||
FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */
|
||||
FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
|
||||
FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals); /* WATCHOUT: does not CRC the read data! */
|
||||
FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val);
|
||||
FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter);
|
||||
#if 0 /* UNUSED */
|
||||
FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter);
|
||||
FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
|
||||
#endif
|
||||
FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen);
|
||||
FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen);
|
||||
#endif
|
|
@ -0,0 +1,186 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__CPU_H
|
||||
#define FLAC__PRIVATE__CPU_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__CPU_X86_64
|
||||
|
||||
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
|
||||
#define FLAC__CPU_X86_64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FLAC__CPU_IA32
|
||||
|
||||
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)
|
||||
#define FLAC__CPU_IA32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if FLAC__HAS_X86INTRIN
|
||||
/* SSE intrinsics support by ICC/MSVC/GCC */
|
||||
#if defined __INTEL_COMPILER
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined _MSC_VER
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#elif defined __GNUC__
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* since GCC 4.9 -msse.. compiler options aren't necessary */
|
||||
#define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#ifdef FLAC__USE_AVX
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#else /* for GCC older than 4.9 */
|
||||
#define FLAC__SSE_TARGET(x)
|
||||
#ifdef __SSE__
|
||||
#define FLAC__SSE_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSE2__
|
||||
#define FLAC__SSE2_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSSE3__
|
||||
#define FLAC__SSSE3_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#define FLAC__SSE4_1_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#define FLAC__AVX_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#define FLAC__AVX2_SUPPORTED 1
|
||||
#endif
|
||||
#ifdef __FMA__
|
||||
#define FLAC__FMA_SUPPORTED 1
|
||||
#endif
|
||||
#endif /* GCC version */
|
||||
#endif /* compiler version */
|
||||
#endif /* intrinsics support */
|
||||
|
||||
|
||||
#ifndef FLAC__AVX_SUPPORTED
|
||||
#define FLAC__AVX_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
FLAC__CPUINFO_TYPE_IA32,
|
||||
FLAC__CPUINFO_TYPE_X86_64,
|
||||
FLAC__CPUINFO_TYPE_UNKNOWN
|
||||
} FLAC__CPUInfo_Type;
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool intel;
|
||||
|
||||
FLAC__bool cmov;
|
||||
FLAC__bool mmx;
|
||||
FLAC__bool sse;
|
||||
FLAC__bool sse2;
|
||||
|
||||
FLAC__bool sse3;
|
||||
FLAC__bool ssse3;
|
||||
FLAC__bool sse41;
|
||||
FLAC__bool sse42;
|
||||
FLAC__bool avx;
|
||||
FLAC__bool avx2;
|
||||
FLAC__bool fma;
|
||||
} FLAC__CPUInfo_IA32;
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool intel;
|
||||
|
||||
FLAC__bool sse3;
|
||||
FLAC__bool ssse3;
|
||||
FLAC__bool sse41;
|
||||
FLAC__bool sse42;
|
||||
FLAC__bool avx;
|
||||
FLAC__bool avx2;
|
||||
FLAC__bool fma;
|
||||
} FLAC__CPUInfo_x86;
|
||||
|
||||
|
||||
typedef struct {
|
||||
FLAC__bool use_asm;
|
||||
FLAC__CPUInfo_Type type;
|
||||
FLAC__CPUInfo_IA32 ia32;
|
||||
FLAC__CPUInfo_x86 x86;
|
||||
} FLAC__CPUInfo;
|
||||
|
||||
void FLAC__cpu_info(FLAC__CPUInfo *info);
|
||||
|
||||
FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
|
||||
|
||||
void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
|
||||
|
||||
void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__CRC_H
|
||||
#define FLAC__PRIVATE__CRC_H
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/* 8 bit CRC generator, MSB shifted first
|
||||
** polynomial = x^8 + x^2 + x^1 + x^0
|
||||
** init = 0
|
||||
*/
|
||||
extern FLAC__byte const FLAC__crc8_table[256];
|
||||
#define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)];
|
||||
void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc);
|
||||
void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc);
|
||||
FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len);
|
||||
|
||||
/* 16 bit CRC generator, MSB shifted first
|
||||
** polynomial = x^16 + x^15 + x^2 + x^0
|
||||
** init = 0
|
||||
*/
|
||||
extern unsigned const FLAC__crc16_table[256];
|
||||
|
||||
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])
|
||||
/* this alternate may be faster on some systems/compilers */
|
||||
#if 0
|
||||
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)
|
||||
#endif
|
||||
|
||||
unsigned FLAC__crc16(const FLAC__byte *data, unsigned len);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,107 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FIXED_H
|
||||
#define FLAC__PRIVATE__FIXED_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
/*
|
||||
* FLAC__fixed_compute_best_predictor()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the best fixed predictor and the expected bits-per-sample
|
||||
* of the residual signal for each order. The _wide() version uses
|
||||
* 64-bit integers which is statistically necessary when bits-per-
|
||||
* sample + log2(blocksize) > 30
|
||||
*
|
||||
* IN data[0,data_len-1]
|
||||
* IN data_len
|
||||
* OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER]
|
||||
*/
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
# ifndef FLAC__NO_ASM
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
# endif
|
||||
# ifdef FLAC__SSSE3_SUPPORTED
|
||||
unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]);
|
||||
# endif
|
||||
# endif
|
||||
# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
|
||||
unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FLAC__fixed_compute_residual()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the residual signal obtained from sutracting the predicted
|
||||
* signal from the original.
|
||||
*
|
||||
* IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
|
||||
* IN data_len length of original signal
|
||||
* IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
|
||||
* OUT residual[0,data_len-1] residual signal
|
||||
*/
|
||||
void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]);
|
||||
|
||||
/*
|
||||
* FLAC__fixed_restore_signal()
|
||||
* --------------------------------------------------------------------
|
||||
* Restore the original signal by summing the residual and the
|
||||
* predictor.
|
||||
*
|
||||
* IN residual[0,data_len-1] residual signal
|
||||
* IN data_len length of original signal
|
||||
* IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order
|
||||
* *** IMPORTANT: the caller must pass in the historical samples:
|
||||
* IN data[-order,-1] previously-reconstructed historical samples
|
||||
* OUT data[0,data_len-1] original signal
|
||||
*/
|
||||
void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,95 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2004-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FLOAT_H
|
||||
#define FLAC__PRIVATE__FLOAT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
/*
|
||||
* All the code in libFLAC that uses float and double
|
||||
* should be protected by checks of the macro
|
||||
* FLAC__INTEGER_ONLY_LIBRARY.
|
||||
*
|
||||
*/
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
/*
|
||||
* FLAC__real is the basic floating point type used in LPC analysis.
|
||||
*
|
||||
* WATCHOUT: changing FLAC__real will change the signatures of many
|
||||
* functions that have assembly language equivalents and break them.
|
||||
*/
|
||||
typedef float FLAC__real;
|
||||
#else
|
||||
/*
|
||||
* The convention for FLAC__fixedpoint is to use the upper 16 bits
|
||||
* for the integer part and lower 16 bits for the fractional part.
|
||||
*/
|
||||
typedef FLAC__int32 FLAC__fixedpoint;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ZERO;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE_HALF;
|
||||
extern const FLAC__fixedpoint FLAC__FP_ONE;
|
||||
extern const FLAC__fixedpoint FLAC__FP_LN2;
|
||||
extern const FLAC__fixedpoint FLAC__FP_E;
|
||||
|
||||
#define FLAC__fixedpoint_trunc(x) ((x)>>16)
|
||||
|
||||
#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) )
|
||||
|
||||
#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) )
|
||||
|
||||
/*
|
||||
* FLAC__fixedpoint_log2()
|
||||
* --------------------------------------------------------------------
|
||||
* Returns the base-2 logarithm of the fixed-point number 'x' using an
|
||||
* algorithm by Knuth for x >= 1.0
|
||||
*
|
||||
* 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must
|
||||
* be < 32 and evenly divisible by 4 (0 is OK but not very precise).
|
||||
*
|
||||
* 'precision' roughly limits the number of iterations that are done;
|
||||
* use (unsigned)(-1) for maximum precision.
|
||||
*
|
||||
* If 'x' is less than one -- that is, x < (1<<fracbits) -- then this
|
||||
* function will punt and return 0.
|
||||
*
|
||||
* The return value will also have 'fracbits' fractional bits.
|
||||
*/
|
||||
FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__FORMAT_H
|
||||
#define FLAC__PRIVATE__FORMAT_H
|
||||
|
||||
#include "FLAC/format.h"
|
||||
|
||||
unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order);
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize);
|
||||
unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order);
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
|
||||
void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object);
|
||||
FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,250 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__LPC_H
|
||||
#define FLAC__PRIVATE__LPC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__lpc_window_data()
|
||||
* --------------------------------------------------------------------
|
||||
* Applies the given window to the data.
|
||||
* OPT: asm implementation
|
||||
*
|
||||
* IN in[0,data_len-1]
|
||||
* IN window[0,data_len-1]
|
||||
* OUT out[0,lag-1]
|
||||
* IN data_len
|
||||
*/
|
||||
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_autocorrelation()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the autocorrelation for lags between 0 and lag-1.
|
||||
* Assumes data[] outside of [0,data_len-1] == 0.
|
||||
* Asserts that lag > 0.
|
||||
*
|
||||
* IN data[0,data_len-1]
|
||||
* IN data_len
|
||||
* IN 0 < lag <= data_len
|
||||
* OUT autoc[0,lag-1]
|
||||
*/
|
||||
void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
# endif
|
||||
# endif
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE_SUPPORTED
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_lp_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Computes LP coefficients for orders 1..max_order.
|
||||
* Do not call if autoc[0] == 0.0. This means the signal is zero
|
||||
* and there is no point in calculating a predictor.
|
||||
*
|
||||
* IN autoc[0,max_order] autocorrelation values
|
||||
* IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute
|
||||
* OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order
|
||||
* *** IMPORTANT:
|
||||
* *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched
|
||||
* OUT error[0,max_order-1] error for each order (more
|
||||
* specifically, the variance of
|
||||
* the error signal times # of
|
||||
* samples in the signal)
|
||||
*
|
||||
* Example: if max_order is 9, the LP coefficients for order 9 will be
|
||||
* in lp_coeff[8][0,8], the LP coefficients for order 8 will be
|
||||
* in lp_coeff[7][0,7], etc.
|
||||
*/
|
||||
void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_quantize_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Quantizes the LP coefficients. NOTE: precision + bits_per_sample
|
||||
* must be less than 32 (sizeof(FLAC__int32)*8).
|
||||
*
|
||||
* IN lp_coeff[0,order-1] LP coefficients
|
||||
* IN order LP order
|
||||
* IN FLAC__MIN_QLP_COEFF_PRECISION < precision
|
||||
* desired precision (in bits, including sign
|
||||
* bit) of largest coefficient
|
||||
* OUT qlp_coeff[0,order-1] quantized coefficients
|
||||
* OUT shift # of bits to shift right to get approximated
|
||||
* LP coefficients. NOTE: could be negative.
|
||||
* RETURN 0 => quantization OK
|
||||
* 1 => coefficients require too much shifting for *shift to
|
||||
* fit in the LPC subframe header. 'shift' is unset.
|
||||
* 2 => coefficients are all zero, which is bad. 'shift' is
|
||||
* unset.
|
||||
*/
|
||||
int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_residual_from_qlp_coefficients()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the residual signal obtained from sutracting the predicted
|
||||
* signal from the original.
|
||||
*
|
||||
* IN data[-order,data_len-1] original signal (NOTE THE INDICES!)
|
||||
* IN data_len length of original signal
|
||||
* IN qlp_coeff[0,order-1] quantized LP coefficients
|
||||
* IN order > 0 LP order
|
||||
* IN lp_quantization quantization of LP coefficients in bits
|
||||
* OUT residual[0,data_len-1] residual signal
|
||||
*/
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# endif
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# ifdef FLAC__SSE4_1_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# ifdef FLAC__AVX2_SUPPORTED
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
/*
|
||||
* FLAC__lpc_restore_signal()
|
||||
* --------------------------------------------------------------------
|
||||
* Restore the original signal by summing the residual and the
|
||||
* predictor.
|
||||
*
|
||||
* IN residual[0,data_len-1] residual signal
|
||||
* IN data_len length of original signal
|
||||
* IN qlp_coeff[0,order-1] quantized LP coefficients
|
||||
* IN order > 0 LP order
|
||||
* IN lp_quantization quantization of LP coefficients in bits
|
||||
* *** IMPORTANT: the caller must pass in the historical samples:
|
||||
* IN data[-order,-1] previously-reconstructed historical samples
|
||||
* OUT data[0,data_len-1] original signal
|
||||
*/
|
||||
void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
#ifndef FLAC__NO_ASM
|
||||
# ifdef FLAC__CPU_IA32
|
||||
# ifdef FLAC__HAS_NASM
|
||||
void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif /* FLAC__HAS_NASM */
|
||||
# endif /* FLAC__CPU_IA32 */
|
||||
# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
# ifdef FLAC__SSE2_SUPPORTED
|
||||
void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif
|
||||
# ifdef FLAC__SSE4_1_SUPPORTED
|
||||
void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]);
|
||||
# endif
|
||||
# endif
|
||||
#endif /* FLAC__NO_ASM */
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_expected_bits_per_residual_sample()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the expected number of bits per residual signal sample
|
||||
* based on the LP error (which is related to the residual variance).
|
||||
*
|
||||
* IN lpc_error >= 0.0 error returned from calculating LP coefficients
|
||||
* IN total_samples > 0 # of samples in residual signal
|
||||
* RETURN expected bits per sample
|
||||
*/
|
||||
double FLAC__lpc_compute_expected_bits_per_residual_sample(double lpc_error, unsigned total_samples);
|
||||
double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(double lpc_error, double error_scale);
|
||||
|
||||
/*
|
||||
* FLAC__lpc_compute_best_order()
|
||||
* --------------------------------------------------------------------
|
||||
* Compute the best order from the array of signal errors returned
|
||||
* during coefficient computation.
|
||||
*
|
||||
* IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients
|
||||
* IN max_order > 0 max LP order
|
||||
* IN total_samples > 0 # of samples in residual signal
|
||||
* IN overhead_bits_per_order # of bits overhead for each increased LP order
|
||||
* (includes warmup sample size and quantized LP coefficient)
|
||||
* RETURN [1,max_order] best order
|
||||
*/
|
||||
unsigned FLAC__lpc_compute_best_order(const double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order);
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2012-2016 Xiph.org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__MACROS_H
|
||||
#define FLAC__PRIVATE__MACROS_H
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
|
||||
#define flac_max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
#define MIN_PASTE(A,B) A##B
|
||||
#define MIN_IMPL(A,B,L) ({ \
|
||||
__typeof__(A) MIN_PASTE(__a,L) = (A); \
|
||||
__typeof__(B) MIN_PASTE(__b,L) = (B); \
|
||||
MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \
|
||||
})
|
||||
|
||||
#define flac_min(A,B) MIN_IMPL(A,B,__COUNTER__)
|
||||
|
||||
/* Whatever other unix that has sys/param.h */
|
||||
#elif defined(HAVE_SYS_PARAM_H)
|
||||
#include <sys/param.h>
|
||||
#define flac_max(a,b) MAX(a,b)
|
||||
#define flac_min(a,b) MIN(a,b)
|
||||
|
||||
/* Windows VS has them in stdlib.h.. XXX:Untested */
|
||||
#elif defined(_MSC_VER)
|
||||
#include <stdlib.h>
|
||||
#define flac_max(a,b) __max(a,b)
|
||||
#define flac_min(a,b) __min(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x) >= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef FLAC__PRIVATE__MD5_H
|
||||
#define FLAC__PRIVATE__MD5_H
|
||||
|
||||
/*
|
||||
* This is the header file for the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h'
|
||||
* header definitions; now uses stuff from dpkg's config.h
|
||||
* - Ian Jackson <ijackson@nyx.cs.du.edu>.
|
||||
* Still in the public domain.
|
||||
*
|
||||
* Josh Coalson: made some changes to integrate with libFLAC.
|
||||
* Still in the public domain, with no warranty.
|
||||
*/
|
||||
|
||||
#include "FLAC/ordinals.h"
|
||||
|
||||
typedef union {
|
||||
FLAC__byte *p8;
|
||||
FLAC__int16 *p16;
|
||||
FLAC__int32 *p32;
|
||||
} FLAC__multibyte;
|
||||
|
||||
typedef struct {
|
||||
FLAC__uint32 in[16];
|
||||
FLAC__uint32 buf[4];
|
||||
FLAC__uint32 bytes[2];
|
||||
FLAC__multibyte internal_buf;
|
||||
size_t capacity;
|
||||
} FLAC__MD5Context;
|
||||
|
||||
void FLAC__MD5Init(FLAC__MD5Context *context);
|
||||
void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context);
|
||||
|
||||
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__MEMORY_H
|
||||
#define FLAC__PRIVATE__MEMORY_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for size_t */
|
||||
|
||||
#include "private/float.h"
|
||||
#include "FLAC/ordinals.h" /* for FLAC__bool */
|
||||
|
||||
/* Returns the unaligned address returned by malloc.
|
||||
* Use free() on this address to deallocate.
|
||||
*/
|
||||
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer);
|
||||
FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer);
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer);
|
||||
#endif
|
||||
void *safe_malloc_mul_2op_p(size_t size1, size_t size2);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2002-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__METADATA_H
|
||||
#define FLAC__PRIVATE__METADATA_H
|
||||
|
||||
#include "FLAC/metadata.h"
|
||||
|
||||
/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not
|
||||
* be a consistent state (e.g. PICTURE) or equivalent to the initial
|
||||
* state after FLAC__metadata_object_new()
|
||||
*/
|
||||
void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object);
|
||||
|
||||
void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,74 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2006-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PRIVATE__WINDOW_H
|
||||
#define FLAC__PRIVATE__WINDOW_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/float.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
/*
|
||||
* FLAC__window_*()
|
||||
* --------------------------------------------------------------------
|
||||
* Calculates window coefficients according to different apodization
|
||||
* functions.
|
||||
*
|
||||
* OUT window[0,L-1]
|
||||
* IN L (number of points in window)
|
||||
*/
|
||||
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */
|
||||
void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L);
|
||||
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p);
|
||||
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
|
||||
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end);
|
||||
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FLAC__PROTECTED__STREAM_DECODER_H
|
||||
#define FLAC__PROTECTED__STREAM_DECODER_H
|
||||
|
||||
#include "FLAC/stream_decoder.h"
|
||||
#if FLAC__HAS_OGG
|
||||
#include "private/ogg_decoder_aspect.h"
|
||||
#endif
|
||||
|
||||
typedef struct FLAC__StreamDecoderProtected {
|
||||
FLAC__StreamDecoderState state;
|
||||
FLAC__StreamDecoderInitStatus initstate;
|
||||
unsigned channels;
|
||||
FLAC__ChannelAssignment channel_assignment;
|
||||
unsigned bits_per_sample;
|
||||
unsigned sample_rate; /* in Hz */
|
||||
unsigned blocksize; /* in samples (per channel) */
|
||||
FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */
|
||||
#if FLAC__HAS_OGG
|
||||
FLAC__OggDecoderAspect ogg_decoder_aspect;
|
||||
#endif
|
||||
} FLAC__StreamDecoderProtected;
|
||||
|
||||
/*
|
||||
* return the number of input bytes consumed
|
||||
*/
|
||||
unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,454 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2000-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "private/cpu.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
#ifndef FLAC__NO_ASM
|
||||
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
|
||||
#include "private/lpc.h"
|
||||
#ifdef FLAC__SSE_SUPPORTED
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
|
||||
#include <xmmintrin.h> /* SSE */
|
||||
|
||||
/* new routines: more unaligned loads, less shuffle
|
||||
* old routines: less unaligned loads, more shuffle
|
||||
* these *_old routines are equivalent to the ASM routines in ia32/lpc_asm.nasm
|
||||
*/
|
||||
|
||||
/* new routines: faster on current Intel (starting from Core i aka Nehalem) and all AMD CPUs */
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 4;
|
||||
__m128 sum0;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 4);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 8;
|
||||
__m128 sum0, sum1;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 8);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 12;
|
||||
__m128 sum0, sum1, sum2;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 12);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
sum2 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1, d2;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d2 = _mm_loadu_ps(data+i+8);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
__m128 d2 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d2 = _mm_move_ss(d2, d1);
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
_mm_storeu_ps(autoc+8, sum2);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
int i;
|
||||
int limit = data_len - 16;
|
||||
__m128 sum0, sum1, sum2, sum3;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag <= 16);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
|
||||
sum0 = _mm_setzero_ps();
|
||||
sum1 = _mm_setzero_ps();
|
||||
sum2 = _mm_setzero_ps();
|
||||
sum3 = _mm_setzero_ps();
|
||||
|
||||
for(i = 0; i <= limit; i++) {
|
||||
__m128 d, d0, d1, d2, d3;
|
||||
d0 = _mm_loadu_ps(data+i);
|
||||
d1 = _mm_loadu_ps(data+i+4);
|
||||
d2 = _mm_loadu_ps(data+i+8);
|
||||
d3 = _mm_loadu_ps(data+i+12);
|
||||
d = d0; d = _mm_shuffle_ps(d, d, 0);
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
|
||||
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d3, d));
|
||||
}
|
||||
|
||||
{
|
||||
__m128 d0 = _mm_setzero_ps();
|
||||
__m128 d1 = _mm_setzero_ps();
|
||||
__m128 d2 = _mm_setzero_ps();
|
||||
__m128 d3 = _mm_setzero_ps();
|
||||
limit++; if(limit < 0) limit = 0;
|
||||
|
||||
for(i = data_len-1; i >= limit; i--) {
|
||||
__m128 d;
|
||||
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
|
||||
d3 = _mm_shuffle_ps(d3, d3, _MM_SHUFFLE(2,1,0,3));
|
||||
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
|
||||
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
|
||||
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
|
||||
d3 = _mm_move_ss(d3, d2);
|
||||
d2 = _mm_move_ss(d2, d1);
|
||||
d1 = _mm_move_ss(d1, d0);
|
||||
d0 = _mm_move_ss(d0, d);
|
||||
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d, d3));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
|
||||
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
|
||||
}
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, sum0);
|
||||
_mm_storeu_ps(autoc+4, sum1);
|
||||
_mm_storeu_ps(autoc+8, sum2);
|
||||
_mm_storeu_ps(autoc+12,sum3);
|
||||
}
|
||||
|
||||
/* old routines: faster on older Intel CPUs (up to Core 2) */
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm2, xmm5;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 4);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm5, xmm6;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 8);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
xmm6 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm1);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
_mm_storeu_ps(autoc+4, xmm6);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 12);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm5 = _mm_setzero_ps();
|
||||
xmm6 = _mm_setzero_ps();
|
||||
xmm7 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
xmm4 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_move_ss(xmm4, xmm3);
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm2);
|
||||
xmm5 = _mm_add_ps(xmm5, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm1);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm4);
|
||||
xmm7 = _mm_add_ps(xmm7, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm5);
|
||||
_mm_storeu_ps(autoc+4, xmm6);
|
||||
_mm_storeu_ps(autoc+8, xmm7);
|
||||
}
|
||||
|
||||
FLAC__SSE_TARGET("sse")
|
||||
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||
{
|
||||
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9;
|
||||
|
||||
(void) lag;
|
||||
FLAC__ASSERT(lag > 0);
|
||||
FLAC__ASSERT(lag <= 16);
|
||||
FLAC__ASSERT(lag <= data_len);
|
||||
FLAC__ASSERT(data_len > 0);
|
||||
|
||||
xmm6 = _mm_setzero_ps();
|
||||
xmm7 = _mm_setzero_ps();
|
||||
xmm8 = _mm_setzero_ps();
|
||||
xmm9 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_load_ss(data++);
|
||||
xmm2 = xmm0;
|
||||
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
|
||||
xmm3 = _mm_setzero_ps();
|
||||
xmm4 = _mm_setzero_ps();
|
||||
xmm5 = _mm_setzero_ps();
|
||||
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm0);
|
||||
|
||||
data_len--;
|
||||
|
||||
while(data_len)
|
||||
{
|
||||
xmm0 = _mm_load1_ps(data++);
|
||||
|
||||
/* shift xmm5:xmm4:xmm3:xmm2 left by one float */
|
||||
xmm5 = _mm_shuffle_ps(xmm5, xmm5, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
|
||||
xmm5 = _mm_move_ss(xmm5, xmm4);
|
||||
xmm4 = _mm_move_ss(xmm4, xmm3);
|
||||
xmm3 = _mm_move_ss(xmm3, xmm2);
|
||||
xmm2 = _mm_move_ss(xmm2, xmm0);
|
||||
|
||||
/* xmm9|xmm8|xmm7|xmm6 += xmm0|xmm0|xmm0|xmm0 * xmm5|xmm4|xmm3|xmm2 */
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm5);
|
||||
xmm9 = _mm_add_ps(xmm9, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm4);
|
||||
xmm8 = _mm_add_ps(xmm8, xmm1);
|
||||
xmm1 = xmm0;
|
||||
xmm1 = _mm_mul_ps(xmm1, xmm3);
|
||||
xmm7 = _mm_add_ps(xmm7, xmm1);
|
||||
xmm0 = _mm_mul_ps(xmm0, xmm2);
|
||||
xmm6 = _mm_add_ps(xmm6, xmm0);
|
||||
|
||||
data_len--;
|
||||
}
|
||||
|
||||
_mm_storeu_ps(autoc, xmm6);
|
||||
_mm_storeu_ps(autoc+4, xmm7);
|
||||
_mm_storeu_ps(autoc+8, xmm8);
|
||||
_mm_storeu_ps(autoc+12,xmm9);
|
||||
}
|
||||
|
||||
#endif /* FLAC__SSE_SUPPORTED */
|
||||
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
|
||||
#endif /* FLAC__NO_ASM */
|
||||
#endif /* FLAC__INTEGER_ONLY_LIBRARY */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,516 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* for malloc() */
|
||||
#include <string.h> /* for memcpy() */
|
||||
|
||||
#include "private/md5.h"
|
||||
#include "share/alloc.h"
|
||||
#include "share/endswap.h"
|
||||
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*
|
||||
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
|
||||
* definitions; now uses stuff from dpkg's config.h.
|
||||
* - Ian Jackson <ijackson@nyx.cs.du.edu>.
|
||||
* Still in the public domain.
|
||||
*
|
||||
* Josh Coalson: made some changes to integrate with libFLAC.
|
||||
* Still in the public domain.
|
||||
*/
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f,w,x,y,z,in,s) \
|
||||
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16])
|
||||
{
|
||||
register FLAC__uint32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
//@@@@@@ OPT: use bswap/intrinsics
|
||||
static void byteSwap(FLAC__uint32 *buf, unsigned words)
|
||||
{
|
||||
register FLAC__uint32 x;
|
||||
do {
|
||||
x = *buf;
|
||||
x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
|
||||
*buf++ = (x >> 16) | (x << 16);
|
||||
} while (--words);
|
||||
}
|
||||
static void byteSwapX16(FLAC__uint32 *buf)
|
||||
{
|
||||
register FLAC__uint32 x;
|
||||
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
|
||||
x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16);
|
||||
}
|
||||
#else
|
||||
#define byteSwap(buf, words)
|
||||
#define byteSwapX16(buf)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len)
|
||||
{
|
||||
FLAC__uint32 t;
|
||||
|
||||
/* Update byte count */
|
||||
|
||||
t = ctx->bytes[0];
|
||||
if ((ctx->bytes[0] = t + len) < t)
|
||||
ctx->bytes[1]++; /* Carry from low to high */
|
||||
|
||||
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
|
||||
if (t > len) {
|
||||
memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len);
|
||||
return;
|
||||
}
|
||||
/* First chunk is an odd size */
|
||||
memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void FLAC__MD5Init(FLAC__MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bytes[0] = 0;
|
||||
ctx->bytes[1] = 0;
|
||||
|
||||
ctx->internal_buf.p8 = 0;
|
||||
ctx->capacity = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
|
||||
{
|
||||
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
|
||||
FLAC__byte *p = (FLAC__byte *)ctx->in + count;
|
||||
|
||||
/* Set the first char of padding to 0x80. There is always room. */
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 56 bytes (-8..55) */
|
||||
count = 56 - 1 - count;
|
||||
|
||||
if (count < 0) { /* Padding forces an extra block */
|
||||
memset(p, 0, count + 8);
|
||||
byteSwapX16(ctx->in);
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
p = (FLAC__byte *)ctx->in;
|
||||
count = 56;
|
||||
}
|
||||
memset(p, 0, count);
|
||||
byteSwap(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ctx->in[14] = ctx->bytes[0] << 3;
|
||||
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
|
||||
FLAC__MD5Transform(ctx->buf, ctx->in);
|
||||
|
||||
byteSwap(ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
if (0 != ctx->internal_buf.p8) {
|
||||
free(ctx->internal_buf.p8);
|
||||
ctx->internal_buf.p8 = 0;
|
||||
ctx->capacity = 0;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the incoming audio signal to a byte stream
|
||||
*/
|
||||
static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
|
||||
{
|
||||
FLAC__byte *buf_ = mbuf->p8;
|
||||
FLAC__int16 *buf16 = mbuf->p16;
|
||||
FLAC__int32 *buf32 = mbuf->p32;
|
||||
FLAC__int32 a_word;
|
||||
unsigned channel, sample;
|
||||
|
||||
/* Storage in the output buffer, buf, is little endian. */
|
||||
|
||||
#define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
|
||||
|
||||
/* First do the most commonly used combinations. */
|
||||
switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
|
||||
/* One byte per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf_++ = signal[0][sample];
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
*buf_++ = signal[4][sample];
|
||||
*buf_++ = signal[5][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (1, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf_++ = signal[0][sample];
|
||||
*buf_++ = signal[1][sample];
|
||||
*buf_++ = signal[2][sample];
|
||||
*buf_++ = signal[3][sample];
|
||||
*buf_++ = signal[4][sample];
|
||||
*buf_++ = signal[5][sample];
|
||||
*buf_++ = signal[6][sample];
|
||||
*buf_++ = signal[7][sample];
|
||||
}
|
||||
return;
|
||||
|
||||
/* Two bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
*buf16++ = H2LE_16(signal[4][sample]);
|
||||
*buf16++ = H2LE_16(signal[5][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (2, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf16++ = H2LE_16(signal[0][sample]);
|
||||
*buf16++ = H2LE_16(signal[1][sample]);
|
||||
*buf16++ = H2LE_16(signal[2][sample]);
|
||||
*buf16++ = H2LE_16(signal[3][sample]);
|
||||
*buf16++ = H2LE_16(signal[4][sample]);
|
||||
*buf16++ = H2LE_16(signal[5][sample]);
|
||||
*buf16++ = H2LE_16(signal[6][sample]);
|
||||
*buf16++ = H2LE_16(signal[7][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
/* Three bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (3, 1)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
a_word = signal[0][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (3, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
a_word = signal[0][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
a_word = signal[1][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
/* Four bytes per sample. */
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 1)):
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 2)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 4)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 6)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
*buf32++ = H2LE_32(signal[4][sample]);
|
||||
*buf32++ = H2LE_32(signal[5][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
case (BYTES_CHANNEL_SELECTOR (4, 8)):
|
||||
for (sample = 0; sample < samples; sample++) {
|
||||
*buf32++ = H2LE_32(signal[0][sample]);
|
||||
*buf32++ = H2LE_32(signal[1][sample]);
|
||||
*buf32++ = H2LE_32(signal[2][sample]);
|
||||
*buf32++ = H2LE_32(signal[3][sample]);
|
||||
*buf32++ = H2LE_32(signal[4][sample]);
|
||||
*buf32++ = H2LE_32(signal[5][sample]);
|
||||
*buf32++ = H2LE_32(signal[6][sample]);
|
||||
*buf32++ = H2LE_32(signal[7][sample]);
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* General version. */
|
||||
switch (bytes_per_sample) {
|
||||
case 1:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf_++ = signal[channel][sample];
|
||||
return;
|
||||
|
||||
case 2:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf16++ = H2LE_16(signal[channel][sample]);
|
||||
return;
|
||||
|
||||
case 3:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++) {
|
||||
a_word = signal[channel][sample];
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word; a_word >>= 8;
|
||||
*buf_++ = (FLAC__byte)a_word;
|
||||
}
|
||||
return;
|
||||
|
||||
case 4:
|
||||
for (sample = 0; sample < samples; sample++)
|
||||
for (channel = 0; channel < channels; channel++)
|
||||
*buf32++ = H2LE_32(signal[channel][sample]);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the incoming audio signal to a byte stream and FLAC__MD5Update it.
|
||||
*/
|
||||
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
|
||||
{
|
||||
const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
|
||||
|
||||
/* overflow check */
|
||||
if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
|
||||
return false;
|
||||
if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
|
||||
return false;
|
||||
|
||||
if (ctx->capacity < bytes_needed) {
|
||||
if (0 == (ctx->internal_buf.p8 = safe_realloc_(ctx->internal_buf.p8, bytes_needed))) {
|
||||
if (0 == (ctx->internal_buf.p8 = safe_malloc_(bytes_needed))) {
|
||||
ctx->capacity = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ctx->capacity = bytes_needed;
|
||||
}
|
||||
|
||||
format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample);
|
||||
|
||||
FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2001-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "private/memory.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/alloc.h"
|
||||
|
||||
void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
|
||||
{
|
||||
void *x;
|
||||
|
||||
FLAC__ASSERT(0 != aligned_address);
|
||||
|
||||
#ifdef FLAC__ALIGN_MALLOC_DATA
|
||||
/* align on 32-byte (256-bit) boundary */
|
||||
x = safe_malloc_add_2op_(bytes, /*+*/31L);
|
||||
*aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
|
||||
#else
|
||||
x = safe_malloc_(bytes);
|
||||
*aligned_address = x;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
|
||||
{
|
||||
FLAC__int32 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__int32 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
|
||||
{
|
||||
FLAC__uint32 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__uint32 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
|
||||
{
|
||||
FLAC__uint64 *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__uint64 *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
|
||||
{
|
||||
unsigned *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
unsigned *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
|
||||
{
|
||||
FLAC__real *pu; /* unaligned pointer */
|
||||
union { /* union needed to comply with C99 pointer aliasing rules */
|
||||
FLAC__real *pa; /* aligned pointer */
|
||||
void *pv; /* aligned pointer alias */
|
||||
} u;
|
||||
|
||||
FLAC__ASSERT(elements > 0);
|
||||
FLAC__ASSERT(0 != unaligned_pointer);
|
||||
FLAC__ASSERT(0 != aligned_pointer);
|
||||
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
|
||||
|
||||
if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
|
||||
return false;
|
||||
|
||||
pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
|
||||
if(0 == pu) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if(*unaligned_pointer != 0)
|
||||
free(*unaligned_pointer);
|
||||
*unaligned_pointer = pu;
|
||||
*aligned_pointer = u.pa;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
|
||||
{
|
||||
if(!size1 || !size2)
|
||||
return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
|
||||
if(size1 > SIZE_MAX / size2)
|
||||
return 0;
|
||||
return malloc(size1*size2);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,282 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2006-2009 Josh Coalson
|
||||
* Copyright (C) 2011-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include "share/compat.h"
|
||||
#include "FLAC/assert.h"
|
||||
#include "FLAC/format.h"
|
||||
#include "private/window.h"
|
||||
|
||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||
|
||||
|
||||
void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
if (L & 1) {
|
||||
for (n = 0; n <= N/2; n++)
|
||||
window[n] = 2.0f * n / (float)N;
|
||||
for (; n <= N; n++)
|
||||
window[n] = 2.0f - 2.0f * n / (float)N;
|
||||
}
|
||||
else {
|
||||
for (n = 0; n <= L/2-1; n++)
|
||||
window[n] = 2.0f * n / (float)N;
|
||||
for (; n <= N; n++)
|
||||
window[n] = 2.0f - 2.0f * n / (float)N;
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N)));
|
||||
}
|
||||
|
||||
void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
/* 4-term -92dB side-lobe */
|
||||
void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++)
|
||||
window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
double k = ((double)n - N2) / N2;
|
||||
k = 1.0f - k * k;
|
||||
window[n] = (FLAC__real)(k * k);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
const double k = ((double)n - N2) / (stddev * N2);
|
||||
window[n] = (FLAC__real)exp(-0.5f * k * k);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N));
|
||||
}
|
||||
|
||||
void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N));
|
||||
}
|
||||
|
||||
void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
}
|
||||
|
||||
void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
FLAC__int32 n;
|
||||
|
||||
if (L & 1) {
|
||||
for (n = 1; n <= (L+1)/2; n++)
|
||||
window[n-1] = 2.0f * n / ((float)L + 1.0f);
|
||||
for (; n <= L; n++)
|
||||
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
|
||||
}
|
||||
else {
|
||||
for (n = 1; n <= L/2; n++)
|
||||
window[n-1] = 2.0f * n / ((float)L + 1.0f);
|
||||
for (; n <= L; n++)
|
||||
window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p)
|
||||
{
|
||||
if (p <= 0.0)
|
||||
FLAC__window_rectangle(window, L);
|
||||
else if (p >= 1.0)
|
||||
FLAC__window_hann(window, L);
|
||||
else {
|
||||
const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
|
||||
FLAC__int32 n;
|
||||
/* start with rectangle... */
|
||||
FLAC__window_rectangle(window, L);
|
||||
/* ...replace ends with hann */
|
||||
if (Np > 0) {
|
||||
for (n = 0; n <= Np; n++) {
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np));
|
||||
window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
|
||||
{
|
||||
const FLAC__int32 start_n = (FLAC__int32)(start * L);
|
||||
const FLAC__int32 end_n = (FLAC__int32)(end * L);
|
||||
const FLAC__int32 N = end_n - start_n;
|
||||
FLAC__int32 Np, n, i;
|
||||
|
||||
if (p <= 0.0f)
|
||||
FLAC__window_partial_tukey(window, L, 0.05f, start, end);
|
||||
else if (p >= 1.0f)
|
||||
FLAC__window_partial_tukey(window, L, 0.95f, start, end);
|
||||
else {
|
||||
|
||||
Np = (FLAC__int32)(p / 2.0f * N);
|
||||
|
||||
for (n = 0; n < start_n && n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
for (i = 1; n < (start_n+Np) && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
|
||||
for (; n < (end_n-Np) && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Np; n < end_n && n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
|
||||
for (; n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
|
||||
{
|
||||
const FLAC__int32 start_n = (FLAC__int32)(start * L);
|
||||
const FLAC__int32 end_n = (FLAC__int32)(end * L);
|
||||
FLAC__int32 Ns, Ne, n, i;
|
||||
|
||||
if (p <= 0.0f)
|
||||
FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
|
||||
else if (p >= 1.0f)
|
||||
FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
|
||||
else {
|
||||
|
||||
Ns = (FLAC__int32)(p / 2.0f * start_n);
|
||||
Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
|
||||
|
||||
for (n = 0, i = 1; n < Ns && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
|
||||
for (; n < start_n-Ns && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Ns; n < start_n && n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
|
||||
for (; n < end_n && n < L; n++)
|
||||
window[n] = 0.0f;
|
||||
for (i = 1; n < end_n+Ne && n < L; n++, i++)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
|
||||
for (; n < L - (Ne) && n < L; n++)
|
||||
window[n] = 1.0f;
|
||||
for (i = Ne; n < L; n++, i--)
|
||||
window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
|
||||
}
|
||||
}
|
||||
|
||||
void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
|
||||
{
|
||||
const FLAC__int32 N = L - 1;
|
||||
const double N2 = (double)N / 2.;
|
||||
FLAC__int32 n;
|
||||
|
||||
for (n = 0; n <= N; n++) {
|
||||
const double k = ((double)n - N2) / N2;
|
||||
window[n] = (FLAC__real)(1.0f - k * k);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
|
@ -0,0 +1,201 @@
|
|||
/* libFLAC - Free Lossless Audio Codec library
|
||||
* Copyright (C) 2013-2016 Xiph.Org Foundation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* - Neither the name of the Xiph.org Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
#include "share/windows_unicode_filenames.h"
|
||||
|
||||
/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
|
||||
static wchar_t *wchar_from_utf8(const char *str)
|
||||
{
|
||||
wchar_t *widestr;
|
||||
int len;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
if ((len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) == 0)
|
||||
return NULL;
|
||||
if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) == NULL)
|
||||
return NULL;
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, str, -1, widestr, len) == 0) {
|
||||
free(widestr);
|
||||
widestr = NULL;
|
||||
}
|
||||
|
||||
return widestr;
|
||||
}
|
||||
|
||||
|
||||
static FLAC__bool utf8_filenames = false;
|
||||
|
||||
|
||||
void flac_internal_set_utf8_filenames(FLAC__bool flag)
|
||||
{
|
||||
utf8_filenames = flag ? true : false;
|
||||
}
|
||||
|
||||
FLAC__bool flac_internal_get_utf8_filenames(void)
|
||||
{
|
||||
return utf8_filenames;
|
||||
}
|
||||
|
||||
/* file functions */
|
||||
|
||||
FILE* flac_internal_fopen_utf8(const char *filename, const char *mode)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return fopen(filename, mode);
|
||||
} else {
|
||||
wchar_t *wname = NULL;
|
||||
wchar_t *wmode = NULL;
|
||||
FILE *f = NULL;
|
||||
|
||||
do {
|
||||
if (!(wname = wchar_from_utf8(filename))) break;
|
||||
if (!(wmode = wchar_from_utf8(mode))) break;
|
||||
f = _wfopen(wname, wmode);
|
||||
} while(0);
|
||||
|
||||
free(wname);
|
||||
free(wmode);
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
int flac_internal_stat64_utf8(const char *path, struct __stat64 *buffer)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return _stat64(path, buffer);
|
||||
} else {
|
||||
wchar_t *wpath;
|
||||
int ret;
|
||||
|
||||
if (!(wpath = wchar_from_utf8(path))) return -1;
|
||||
ret = _wstat64(wpath, buffer);
|
||||
free(wpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int flac_internal_chmod_utf8(const char *filename, int pmode)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return _chmod(filename, pmode);
|
||||
} else {
|
||||
wchar_t *wname;
|
||||
int ret;
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ret = _wchmod(wname, pmode);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int flac_internal_utime_utf8(const char *filename, struct utimbuf *times)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return utime(filename, times);
|
||||
} else {
|
||||
wchar_t *wname;
|
||||
struct __utimbuf64 ut;
|
||||
int ret;
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ut.actime = times->actime;
|
||||
ut.modtime = times->modtime;
|
||||
ret = _wutime64(wname, &ut);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int flac_internal_unlink_utf8(const char *filename)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return _unlink(filename);
|
||||
} else {
|
||||
wchar_t *wname;
|
||||
int ret;
|
||||
|
||||
if (!(wname = wchar_from_utf8(filename))) return -1;
|
||||
ret = _wunlink(wname);
|
||||
free(wname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int flac_internal_rename_utf8(const char *oldname, const char *newname)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return rename(oldname, newname);
|
||||
} else {
|
||||
wchar_t *wold = NULL;
|
||||
wchar_t *wnew = NULL;
|
||||
int ret = -1;
|
||||
|
||||
do {
|
||||
if (!(wold = wchar_from_utf8(oldname))) break;
|
||||
if (!(wnew = wchar_from_utf8(newname))) break;
|
||||
ret = _wrename(wold, wnew);
|
||||
} while(0);
|
||||
|
||||
free(wold);
|
||||
free(wnew);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE WINAPI flac_internal_CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||||
{
|
||||
if (!utf8_filenames) {
|
||||
return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
} else {
|
||||
wchar_t *wname;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
|
||||
handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
free(wname);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
/* 7zTypes.h -- Basic types
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#ifdef _WIN32
|
||||
/* #include <windows.h> */
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef EXTERN_C_BEGIN
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C_BEGIN extern "C" {
|
||||
#define EXTERN_C_END }
|
||||
#else
|
||||
#define EXTERN_C_BEGIN
|
||||
#define EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* typedef DWORD WRes; */
|
||||
typedef unsigned WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#define UINT64_CONST(n) n
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MY_STD_CALL __stdcall
|
||||
#else
|
||||
#define MY_STD_CALL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_FAST_CALL __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_NO_INLINE
|
||||
#define MY_CDECL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
|
||||
#else
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
#define WSTRING_PATH_SEPARATOR L"/"
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,136 @@
|
|||
/* Alloc.c -- Memory allocation functions
|
||||
2015-02-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountMid = 0;
|
||||
int g_allocCountBig = 0;
|
||||
#endif
|
||||
|
||||
void *MyAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
{
|
||||
void *p = malloc(size);
|
||||
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void *MidAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void MidFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||
#endif
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#ifndef MEM_LARGE_PAGES
|
||||
#undef _7ZIP_LARGE_PAGES
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T g_LargePageSize = 0;
|
||||
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||
#endif
|
||||
|
||||
void SetLargePageSize()
|
||||
{
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T size = 0;
|
||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||
if (largePageMinimum == 0)
|
||||
return;
|
||||
size = largePageMinimum();
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
return;
|
||||
g_LargePageSize = size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void *BigAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||
{
|
||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||
#endif
|
||||
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
||||
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
|
||||
static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
|
||||
ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
|
|
@ -0,0 +1,37 @@
|
|||
/* Alloc.h -- Memory allocation functions
|
||||
2015-02-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __COMMON_ALLOC_H
|
||||
#define __COMMON_ALLOC_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
void *MyAlloc(size_t size);
|
||||
void MyFree(void *address);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void SetLargePageSize();
|
||||
|
||||
void *MidAlloc(size_t size);
|
||||
void MidFree(void *address);
|
||||
void *BigAlloc(size_t size);
|
||||
void BigFree(void *address);
|
||||
|
||||
#else
|
||||
|
||||
#define MidAlloc(size) MyAlloc(size)
|
||||
#define MidFree(address) MyFree(address)
|
||||
#define BigAlloc(size) MyAlloc(size)
|
||||
#define BigFree(address) MyFree(address)
|
||||
|
||||
#endif
|
||||
|
||||
extern ISzAlloc g_Alloc;
|
||||
extern ISzAlloc g_BigAlloc;
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,135 @@
|
|||
/* Bra.c -- Converters for RISC code
|
||||
2010-04-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src =
|
||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||
{
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* Bra.h -- Branch converters for executables
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BRA_H
|
||||
#define __BRA_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
||||
In:
|
||||
data - data buffer
|
||||
size - size of data
|
||||
ip - current virtual Instruction Pinter (IP) value
|
||||
state - state variable for x86 converter
|
||||
encoding - 0 (for decoding), 1 (for encoding)
|
||||
|
||||
Out:
|
||||
state - state variable for x86 converter
|
||||
|
||||
Returns:
|
||||
The number of processed bytes. If you call these functions with multiple calls,
|
||||
you must start next call with first byte after block of processed bytes.
|
||||
|
||||
Type Endian Alignment LookAhead
|
||||
|
||||
x86 little 1 4
|
||||
ARMT little 2 2
|
||||
ARM little 4 0
|
||||
PPC big 4 0
|
||||
SPARC big 4 0
|
||||
IA64 little 16 0
|
||||
|
||||
size must be >= Alignment + LookAhead, if it's not last block.
|
||||
If (size < Alignment + LookAhead), converter returns 0.
|
||||
|
||||
Example:
|
||||
|
||||
UInt32 ip = 0;
|
||||
for ()
|
||||
{
|
||||
; size must be >= Alignment + LookAhead, if it's not last block
|
||||
SizeT processed = Convert(data, size, ip, 1);
|
||||
data += processed;
|
||||
size -= processed;
|
||||
ip += processed;
|
||||
}
|
||||
*/
|
||||
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
|
||||
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||
{
|
||||
SizeT pos = 0;
|
||||
UInt32 mask = *state & 7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 5;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *p = data + pos;
|
||||
const Byte *limit = data + size;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT d = (SizeT)(p - data - pos);
|
||||
pos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
{
|
||||
*state = (d > 2 ? 0 : mask >> (unsigned)d);
|
||||
return pos;
|
||||
}
|
||||
if (d > 2)
|
||||
mask = 0;
|
||||
else
|
||||
{
|
||||
mask >>= (unsigned)d;
|
||||
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
|
||||
{
|
||||
mask = (mask >> 1) | 4;
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 cur = ip + (UInt32)pos;
|
||||
pos += 5;
|
||||
if (encoding)
|
||||
v += cur;
|
||||
else
|
||||
v -= cur;
|
||||
if (mask != 0)
|
||||
{
|
||||
unsigned sh = (mask & 6) << 2;
|
||||
if (Test86MSByte((Byte)(v >> sh)))
|
||||
{
|
||||
v ^= (((UInt32)0x100 << sh) - 1);
|
||||
if (encoding)
|
||||
v += cur;
|
||||
else
|
||||
v -= cur;
|
||||
}
|
||||
mask = 0;
|
||||
}
|
||||
p[1] = (Byte)v;
|
||||
p[2] = (Byte)(v >> 8);
|
||||
p[3] = (Byte)(v >> 16);
|
||||
p[4] = (Byte)(0 - ((v >> 24) & 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = (mask >> 1) | 4;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* BraIA64.c -- Converter for IA-64 code
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
static const Byte kBranchTable[32] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0
|
||||
};
|
||||
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 16)
|
||||
return 0;
|
||||
size -= 16;
|
||||
for (i = 0; i <= size; i += 16)
|
||||
{
|
||||
UInt32 instrTemplate = data[i] & 0x1F;
|
||||
UInt32 mask = kBranchTable[instrTemplate];
|
||||
UInt32 bitPos = 5;
|
||||
int slot;
|
||||
for (slot = 0; slot < 3; slot++, bitPos += 41)
|
||||
{
|
||||
UInt32 bytePos, bitRes;
|
||||
UInt64 instruction, instNorm;
|
||||
int j;
|
||||
if (((mask >> slot) & 1) == 0)
|
||||
continue;
|
||||
bytePos = (bitPos >> 3);
|
||||
bitRes = bitPos & 0x7;
|
||||
instruction = 0;
|
||||
for (j = 0; j < 6; j++)
|
||||
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
|
||||
|
||||
instNorm = instruction >> bitRes;
|
||||
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
|
||||
{
|
||||
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
|
||||
UInt32 dest;
|
||||
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
|
||||
|
||||
src <<= 4;
|
||||
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
|
||||
dest >>= 4;
|
||||
|
||||
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
|
||||
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
|
||||
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
|
||||
|
||||
instruction &= (1 << bitRes) - 1;
|
||||
instruction |= (instNorm << bitRes);
|
||||
for (j = 0; j < 6; j++)
|
||||
data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* Compiler.h
|
||||
2015-08-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_COMPILER_H
|
||||
#define __7Z_COMPILER_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#define RPC_NO_WINDOWS_H
|
||||
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
|
||||
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
|
||||
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#pragma warning(disable : 4996) // This function or variable may be unsafe
|
||||
#else
|
||||
#pragma warning(disable : 4511) // copy constructor could not be generated
|
||||
#pragma warning(disable : 4512) // assignment operator could not be generated
|
||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
#pragma warning(disable : 4710) // not inlined
|
||||
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define UNUSED_VAR(x) (void)x;
|
||||
/* #define UNUSED_VAR(x) x=x; */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,200 @@
|
|||
/* CpuArch.c -- CPU specific code
|
||||
2016-02-25: Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||||
#define USE_ASM
|
||||
#endif
|
||||
|
||||
#if !defined(USE_ASM) && _MSC_VER >= 1500
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||
static UInt32 CheckFlag(UInt32 flag)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm mov EDX, EAX;
|
||||
__asm xor EAX, flag;
|
||||
__asm push EAX;
|
||||
__asm popfd;
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm xor EAX, EDX;
|
||||
__asm push EDX;
|
||||
__asm popfd;
|
||||
__asm and flag, EAX;
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"movl %%EAX,%%EDX\n\t"
|
||||
"xorl %0,%%EAX\n\t"
|
||||
"push %%EAX\n\t"
|
||||
"popf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"xorl %%EDX,%%EAX\n\t"
|
||||
"push %%EDX\n\t"
|
||||
"popf\n\t"
|
||||
"andl %%EAX, %0\n\t":
|
||||
"=c" (flag) : "c" (flag) :
|
||||
"%eax", "%edx");
|
||||
#endif
|
||||
return flag;
|
||||
}
|
||||
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||
#else
|
||||
#define CHECK_CPUID_IS_SUPPORTED
|
||||
#endif
|
||||
|
||||
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||
{
|
||||
#ifdef USE_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
UInt32 a2, b2, c2, d2;
|
||||
__asm xor EBX, EBX;
|
||||
__asm xor ECX, ECX;
|
||||
__asm xor EDX, EDX;
|
||||
__asm mov EAX, function;
|
||||
__asm cpuid;
|
||||
__asm mov a2, EAX;
|
||||
__asm mov b2, EBX;
|
||||
__asm mov c2, ECX;
|
||||
__asm mov d2, EDX;
|
||||
|
||||
*a = a2;
|
||||
*b = b2;
|
||||
*c = c2;
|
||||
*d = d2;
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__ (
|
||||
#if defined(MY_CPU_AMD64) && defined(__PIC__)
|
||||
"mov %%rbx, %%rdi;"
|
||||
"cpuid;"
|
||||
"xchg %%rbx, %%rdi;"
|
||||
: "=a" (*a) ,
|
||||
"=D" (*b) ,
|
||||
#elif defined(MY_CPU_X86) && defined(__PIC__)
|
||||
"mov %%ebx, %%edi;"
|
||||
"cpuid;"
|
||||
"xchgl %%ebx, %%edi;"
|
||||
: "=a" (*a) ,
|
||||
"=D" (*b) ,
|
||||
#else
|
||||
"cpuid"
|
||||
: "=a" (*a) ,
|
||||
"=b" (*b) ,
|
||||
#endif
|
||||
"=c" (*c) ,
|
||||
"=d" (*d)
|
||||
: "0" (function)) ;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int CPUInfo[4];
|
||||
__cpuid(CPUInfo, function);
|
||||
*a = CPUInfo[0];
|
||||
*b = CPUInfo[1];
|
||||
*c = CPUInfo[2];
|
||||
*d = CPUInfo[3];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
{
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||
return True;
|
||||
}
|
||||
|
||||
static const UInt32 kVendors[][3] =
|
||||
{
|
||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||
};
|
||||
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||
{
|
||||
const UInt32 *v = kVendors[i];
|
||||
if (v[0] == p->vendor[0] &&
|
||||
v[1] == p->vendor[1] &&
|
||||
v[2] == p->vendor[2])
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
UInt32 family, model;
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return True;
|
||||
|
||||
family = x86cpuid_GetFamily(p.ver);
|
||||
model = x86cpuid_GetModel(p.ver);
|
||||
|
||||
firm = x86cpuid_GetFirm(&p);
|
||||
|
||||
switch (firm)
|
||||
{
|
||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
|
||||
/* In-Order Atom CPU */
|
||||
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|
||||
|| model == 0x26 /* 45 nm, Z6xx */
|
||||
|| model == 0x27 /* 32 nm, Z2460 */
|
||||
|| model == 0x35 /* 32 nm, Z2760 */
|
||||
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
|
||||
)));
|
||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||
#include <windows.h>
|
||||
static Bool CPU_Sys_Is_SSE_Supported()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionEx(&vi))
|
||||
return False;
|
||||
return (vi.dwMajorVersion >= 5);
|
||||
}
|
||||
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||
#else
|
||||
#define CHECK_SYS_SSE_SUPPORT
|
||||
#endif
|
||||
|
||||
Bool CPU_Is_Aes_Supported()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return False;
|
||||
return (p.c >> 25) & 1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,223 @@
|
|||
/* CpuArch.h -- CPU specific code
|
||||
2016-06-09: Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CPU_ARCH_H
|
||||
#define __CPU_ARCH_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||
MY_CPU_BE means that CPU is BIG ENDIAN.
|
||||
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
|
||||
|
||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||
*/
|
||||
|
||||
#if defined(_M_X64) \
|
||||
|| defined(_M_AMD64) \
|
||||
|| defined(__x86_64__) \
|
||||
|| defined(__AMD64__) \
|
||||
|| defined(__amd64__)
|
||||
#define MY_CPU_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_AMD64) \
|
||||
|| defined(_M_IA64) \
|
||||
|| defined(__AARCH64EL__) \
|
||||
|| defined(__AARCH64EB__)
|
||||
#define MY_CPU_64BIT
|
||||
#endif
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define MY_CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||
#define MY_CPU_X86_OR_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) \
|
||||
|| defined(_M_ARM) \
|
||||
|| defined(__ARMEL__) \
|
||||
|| defined(__THUMBEL__) \
|
||||
|| defined(__ARMEB__) \
|
||||
|| defined(__THUMBEB__)
|
||||
#define MY_CPU_32BIT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_ARM)
|
||||
#define MY_CPU_ARM_LE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_IA64)
|
||||
#define MY_CPU_IA64_LE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||
|| defined(MY_CPU_ARM_LE) \
|
||||
|| defined(MY_CPU_IA64_LE) \
|
||||
|| defined(__LITTLE_ENDIAN__) \
|
||||
|| defined(__ARMEL__) \
|
||||
|| defined(__THUMBEL__) \
|
||||
|| defined(__AARCH64EL__) \
|
||||
|| defined(__MIPSEL__) \
|
||||
|| defined(__MIPSEL) \
|
||||
|| defined(_MIPSEL) \
|
||||
|| defined(__BFIN__) \
|
||||
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||
#define MY_CPU_LE
|
||||
#endif
|
||||
|
||||
#if defined(__BIG_ENDIAN__) \
|
||||
|| defined(__ARMEB__) \
|
||||
|| defined(__THUMBEB__) \
|
||||
|| defined(__AARCH64EB__) \
|
||||
|| defined(__MIPSEB__) \
|
||||
|| defined(__MIPSEB) \
|
||||
|| defined(_MIPSEB) \
|
||||
|| defined(__m68k__) \
|
||||
|| defined(__s390__) \
|
||||
|| defined(__s390x__) \
|
||||
|| defined(__zarch__) \
|
||||
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||
Stop_Compiling_Bad_Endian
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||
/* || defined(__AARCH64EL__) */
|
||||
#define MY_CPU_LE_UNALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MY_CPU_LE_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
||||
|
||||
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
|
||||
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
|
||||
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
|
||||
|
||||
#else
|
||||
|
||||
#define GetUi16(p) ( (UInt16) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt16)((const Byte *)(p))[1] << 8) ))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[3] << 24))
|
||||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||
_ppp_[0] = (Byte)_vvv_; \
|
||||
_ppp_[1] = (Byte)(_vvv_ >> 8); }
|
||||
|
||||
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||
_ppp_[0] = (Byte)_vvv_; \
|
||||
_ppp_[1] = (Byte)(_vvv_ >> 8); \
|
||||
_ppp_[2] = (Byte)(_vvv_ >> 16); \
|
||||
_ppp_[3] = (Byte)(_vvv_ >> 24); }
|
||||
|
||||
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
|
||||
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
|
||||
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
|
||||
|
||||
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||
|
||||
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||||
|
||||
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
||||
|
||||
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
|
||||
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
|
||||
|
||||
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
|
||||
|
||||
#else
|
||||
|
||||
#define GetBe32(p) ( \
|
||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||
((const Byte *)(p))[3] )
|
||||
|
||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||
|
||||
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||
_ppp_[0] = (Byte)(_vvv_ >> 24); \
|
||||
_ppp_[1] = (Byte)(_vvv_ >> 16); \
|
||||
_ppp_[2] = (Byte)(_vvv_ >> 8); \
|
||||
_ppp_[3] = (Byte)_vvv_; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define GetBe16(p) ( (UInt16) ( \
|
||||
((UInt16)((const Byte *)(p))[0] << 8) | \
|
||||
((const Byte *)(p))[1] ))
|
||||
|
||||
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
} Cx86cpuid;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_FIRM_INTEL,
|
||||
CPU_FIRM_AMD,
|
||||
CPU_FIRM_VIA
|
||||
};
|
||||
|
||||
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
||||
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
|
||||
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
|
||||
#define x86cpuid_GetStepping(ver) (ver & 0xF)
|
||||
|
||||
Bool CPU_Is_InOrder();
|
||||
Bool CPU_Is_Aes_Supported();
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
/* Delta.c -- Delta converter
|
||||
2009-05-26 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Delta.h"
|
||||
|
||||
void Delta_Init(Byte *state)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < DELTA_STATE_SIZE; i++)
|
||||
state[i] = 0;
|
||||
}
|
||||
|
||||
static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < size; i++)
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
|
||||
{
|
||||
Byte buf[DELTA_STATE_SIZE];
|
||||
unsigned j = 0;
|
||||
MyMemCpy(buf, state, delta);
|
||||
{
|
||||
SizeT i;
|
||||
for (i = 0; i < size;)
|
||||
{
|
||||
for (j = 0; j < delta && i < size; i++, j++)
|
||||
{
|
||||
Byte b = data[i];
|
||||
data[i] = (Byte)(b - buf[j]);
|
||||
buf[j] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j == delta)
|
||||
j = 0;
|
||||
MyMemCpy(state, buf + j, delta - j);
|
||||
MyMemCpy(state + delta - j, buf, j);
|
||||
}
|
||||
|
||||
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
|
||||
{
|
||||
Byte buf[DELTA_STATE_SIZE];
|
||||
unsigned j = 0;
|
||||
MyMemCpy(buf, state, delta);
|
||||
{
|
||||
SizeT i;
|
||||
for (i = 0; i < size;)
|
||||
{
|
||||
for (j = 0; j < delta && i < size; i++, j++)
|
||||
{
|
||||
buf[j] = data[i] = (Byte)(buf[j] + data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j == delta)
|
||||
j = 0;
|
||||
MyMemCpy(state, buf + j, delta - j);
|
||||
MyMemCpy(state + delta - j, buf, j);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* Delta.h -- Delta converter
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __DELTA_H
|
||||
#define __DELTA_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define DELTA_STATE_SIZE 256
|
||||
|
||||
void Delta_Init(Byte *state);
|
||||
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
|
||||
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,117 @@
|
|||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2015-10-15 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZ_FIND_H
|
||||
#define __LZ_FIND_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
typedef UInt32 CLzRef;
|
||||
|
||||
typedef struct _CMatchFinder
|
||||
{
|
||||
Byte *buffer;
|
||||
UInt32 pos;
|
||||
UInt32 posLimit;
|
||||
UInt32 streamPos;
|
||||
UInt32 lenLimit;
|
||||
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||
|
||||
Byte streamEndWasReached;
|
||||
Byte btMode;
|
||||
Byte bigHash;
|
||||
Byte directInput;
|
||||
|
||||
UInt32 matchMaxLen;
|
||||
CLzRef *hash;
|
||||
CLzRef *son;
|
||||
UInt32 hashMask;
|
||||
UInt32 cutValue;
|
||||
|
||||
Byte *bufferBase;
|
||||
ISeqInStream *stream;
|
||||
|
||||
UInt32 blockSize;
|
||||
UInt32 keepSizeBefore;
|
||||
UInt32 keepSizeAfter;
|
||||
|
||||
UInt32 numHashBytes;
|
||||
size_t directInputRem;
|
||||
UInt32 historySize;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 hashSizeSum;
|
||||
SRes result;
|
||||
UInt32 crc[256];
|
||||
size_t numRefs;
|
||||
} CMatchFinder;
|
||||
|
||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||
|
||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||
|
||||
#define Inline_MatchFinder_IsFinishedOK(p) \
|
||||
((p)->streamEndWasReached \
|
||||
&& (p)->streamPos == (p)->pos \
|
||||
&& (!(p)->directInput || (p)->directInputRem == 0))
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p);
|
||||
|
||||
/* Conditions:
|
||||
historySize <= 3 GB
|
||||
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||
*/
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc);
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *distances, UInt32 maxLen);
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||
*/
|
||||
|
||||
typedef void (*Mf_Init_Func)(void *object);
|
||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||
|
||||
typedef struct _IMatchFinder
|
||||
{
|
||||
Mf_Init_Func Init;
|
||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||
Mf_GetMatches_Func GetMatches;
|
||||
Mf_Skip_Func Skip;
|
||||
} IMatchFinder;
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
||||
void MatchFinder_Init(CMatchFinder *p);
|
||||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
/* LzHash.h -- HASH functions for LZ algorithms
|
||||
2015-04-12 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZ_HASH_H
|
||||
#define __LZ_HASH_H
|
||||
|
||||
#define kHash2Size (1 << 10)
|
||||
#define kHash3Size (1 << 16)
|
||||
#define kHash4Size (1 << 20)
|
||||
|
||||
#define kFix3HashSize (kHash2Size)
|
||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||
|
||||
#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
|
||||
|
||||
#define HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
h2 = temp & (kHash2Size - 1); \
|
||||
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||
|
||||
#define HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
h2 = temp & (kHash2Size - 1); \
|
||||
temp ^= ((UInt32)cur[2] << 8); \
|
||||
h3 = temp & (kHash3Size - 1); \
|
||||
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||
|
||||
#define HASH5_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
h2 = temp & (kHash2Size - 1); \
|
||||
temp ^= ((UInt32)cur[2] << 8); \
|
||||
h3 = temp & (kHash3Size - 1); \
|
||||
temp ^= (p->crc[cur[3]] << 5); \
|
||||
h4 = temp & (kHash4Size - 1); \
|
||||
hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
|
||||
|
||||
/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||
#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||
|
||||
|
||||
#define MT_HASH2_CALC \
|
||||
h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||
|
||||
#define MT_HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
h2 = temp & (kHash2Size - 1); \
|
||||
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||
|
||||
#define MT_HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
h2 = temp & (kHash2Size - 1); \
|
||||
temp ^= ((UInt32)cur[2] << 8); \
|
||||
h3 = temp & (kHash3Size - 1); \
|
||||
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA86_H
|
||||
#define __LZMA86_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define LZMA86_SIZE_OFFSET (1 + 5)
|
||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||
|
||||
/*
|
||||
It's an example for LZMA + x86 Filter use.
|
||||
You can use .lzma86 extension, if you write that stream to file.
|
||||
.lzma86 header adds one additional byte to standard .lzma header.
|
||||
.lzma86 header (14 bytes):
|
||||
Offset Size Description
|
||||
0 1 = 0 - no filter, pure LZMA
|
||||
= 1 - x86 filter + LZMA
|
||||
1 1 lc, lp and pb in encoded form
|
||||
2 4 dictSize (little endian)
|
||||
6 8 uncompressed size (little endian)
|
||||
|
||||
|
||||
Lzma86_Encode
|
||||
-------------
|
||||
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
||||
|
||||
dictSize - The dictionary size in bytes. The maximum value is
|
||||
128 MB = (1 << 27) bytes for 32-bit version
|
||||
1 GB = (1 << 30) bytes for 64-bit version
|
||||
The default value is 16 MB = (1 << 24) bytes, for level = 5.
|
||||
It's recommended to use the dictionary that is larger than 4 KB and
|
||||
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||
For better compression ratio dictSize must be >= inSize.
|
||||
|
||||
filterMode:
|
||||
SZ_FILTER_NO - no Filter
|
||||
SZ_FILTER_YES - x86 Filter
|
||||
SZ_FILTER_AUTO - it tries both alternatives to select best.
|
||||
Encoder will use 2 or 3 passes:
|
||||
2 passes when FILTER_NO provides better compression.
|
||||
3 passes when FILTER_YES provides better compression.
|
||||
|
||||
Lzma86Encode allocates Data with MyAlloc functions.
|
||||
RAM Requirements for compressing:
|
||||
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
|
||||
filterMode FilterBlockSize
|
||||
SZ_FILTER_NO 0
|
||||
SZ_FILTER_YES inSize
|
||||
SZ_FILTER_AUTO inSize
|
||||
|
||||
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
enum ESzFilterMode
|
||||
{
|
||||
SZ_FILTER_NO,
|
||||
SZ_FILTER_YES,
|
||||
SZ_FILTER_AUTO
|
||||
};
|
||||
|
||||
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||
int level, UInt32 dictSize, int filterMode);
|
||||
|
||||
|
||||
/*
|
||||
Lzma86_GetUnpackSize:
|
||||
In:
|
||||
src - input data
|
||||
srcLen - input data size
|
||||
Out:
|
||||
unpackSize - size of uncompressed stream
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_INPUT_EOF - Error in headers
|
||||
*/
|
||||
|
||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
|
||||
|
||||
/*
|
||||
Lzma86_Decode:
|
||||
In:
|
||||
dest - output data
|
||||
destLen - output data size
|
||||
src - input data
|
||||
srcLen - input data size
|
||||
Out:
|
||||
destLen - processed output size
|
||||
srcLen - processed input size
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - unsupported file
|
||||
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
|
||||
*/
|
||||
|
||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
||||
2016-05-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Lzma86.h"
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Bra.h"
|
||||
#include "LzmaDec.h"
|
||||
|
||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
||||
{
|
||||
unsigned i;
|
||||
if (srcLen < LZMA86_HEADER_SIZE)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
*unpackSize = 0;
|
||||
for (i = 0; i < sizeof(UInt64); i++)
|
||||
*unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
||||
{
|
||||
SRes res;
|
||||
int useFilter;
|
||||
SizeT inSizePure;
|
||||
ELzmaStatus status;
|
||||
|
||||
if (*srcLen < LZMA86_HEADER_SIZE)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
|
||||
useFilter = src[0];
|
||||
|
||||
if (useFilter > 1)
|
||||
{
|
||||
*destLen = 0;
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
inSizePure = *srcLen - LZMA86_HEADER_SIZE;
|
||||
res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,
|
||||
src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);
|
||||
*srcLen = inSizePure + LZMA86_HEADER_SIZE;
|
||||
if (res != SZ_OK)
|
||||
return res;
|
||||
if (useFilter == 1)
|
||||
{
|
||||
UInt32 x86State;
|
||||
x86_Convert_Init(x86State);
|
||||
x86_Convert(dest, *destLen, 0, &x86State, 0);
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||
2016-05-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Lzma86.h"
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Bra.h"
|
||||
#include "LzmaEnc.h"
|
||||
|
||||
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
||||
|
||||
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||
int level, UInt32 dictSize, int filterMode)
|
||||
{
|
||||
size_t outSize2 = *destLen;
|
||||
Byte *filteredStream;
|
||||
Bool useFilter;
|
||||
int mainResult = SZ_ERROR_OUTPUT_EOF;
|
||||
CLzmaEncProps props;
|
||||
LzmaEncProps_Init(&props);
|
||||
props.level = level;
|
||||
props.dictSize = dictSize;
|
||||
|
||||
*destLen = 0;
|
||||
if (outSize2 < LZMA86_HEADER_SIZE)
|
||||
return SZ_ERROR_OUTPUT_EOF;
|
||||
|
||||
{
|
||||
int i;
|
||||
UInt64 t = srcLen;
|
||||
for (i = 0; i < 8; i++, t >>= 8)
|
||||
dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
|
||||
}
|
||||
|
||||
filteredStream = 0;
|
||||
useFilter = (filterMode != SZ_FILTER_NO);
|
||||
if (useFilter)
|
||||
{
|
||||
if (srcLen != 0)
|
||||
{
|
||||
filteredStream = (Byte *)MyAlloc(srcLen);
|
||||
if (filteredStream == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
memcpy(filteredStream, src, srcLen);
|
||||
}
|
||||
{
|
||||
UInt32 x86State;
|
||||
x86_Convert_Init(x86State);
|
||||
x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
size_t minSize = 0;
|
||||
Bool bestIsFiltered = False;
|
||||
|
||||
/* passes for SZ_FILTER_AUTO:
|
||||
0 - BCJ + LZMA
|
||||
1 - LZMA
|
||||
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
|
||||
*/
|
||||
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numPasses; i++)
|
||||
{
|
||||
size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
|
||||
size_t outPropsSize = 5;
|
||||
SRes curRes;
|
||||
Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
|
||||
if (curModeIsFiltered && !bestIsFiltered)
|
||||
break;
|
||||
if (useFilter && i == 0)
|
||||
curModeIsFiltered = True;
|
||||
|
||||
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
|
||||
curModeIsFiltered ? filteredStream : src, srcLen,
|
||||
&props, dest + 1, &outPropsSize, 0,
|
||||
NULL, &g_Alloc, &g_Alloc);
|
||||
|
||||
if (curRes != SZ_ERROR_OUTPUT_EOF)
|
||||
{
|
||||
if (curRes != SZ_OK)
|
||||
{
|
||||
mainResult = curRes;
|
||||
break;
|
||||
}
|
||||
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
|
||||
{
|
||||
minSize = outSizeProcessed;
|
||||
bestIsFiltered = curModeIsFiltered;
|
||||
mainResult = SZ_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
|
||||
*destLen = LZMA86_HEADER_SIZE + minSize;
|
||||
}
|
||||
if (useFilter)
|
||||
MyFree(filteredStream);
|
||||
return mainResult;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,227 @@
|
|||
/* LzmaDec.h -- LZMA Decoder
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_DEC_H
|
||||
#define __LZMA_DEC_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,78 @@
|
|||
/* LzmaEnc.h -- LZMA Encoder
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_ENC_H
|
||||
#define __LZMA_ENC_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaEncProps
|
||||
{
|
||||
int level; /* 0 <= level <= 9 */
|
||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||
default = (1 << 24) */
|
||||
UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
|
||||
Encoder uses this value to reduce dictionary size */
|
||||
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||
int numThreads; /* 1 or 2, default = 2 */
|
||||
} CLzmaEncProps;
|
||||
|
||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||
void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||
|
||||
|
||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||
|
||||
/* LzmaEnc_* functions can return the following exit codes:
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||
SZ_ERROR_WRITE - Write callback error.
|
||||
SZ_ERROR_PROGRESS - some break from progress callback
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
typedef void * CLzmaEncHandle;
|
||||
|
||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaEncode
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/* LzmaLib.c -- LZMA library wrapper
|
||||
2015-06-13 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "LzmaEnc.h"
|
||||
#include "LzmaLib.h"
|
||||
|
||||
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
|
||||
unsigned char *outProps, size_t *outPropsSize,
|
||||
int level, /* 0 <= level <= 9, default = 5 */
|
||||
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
|
||||
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||
int numThreads /* 1 or 2, default = 2 */
|
||||
)
|
||||
{
|
||||
CLzmaEncProps props;
|
||||
LzmaEncProps_Init(&props);
|
||||
props.level = level;
|
||||
props.dictSize = dictSize;
|
||||
props.lc = lc;
|
||||
props.lp = lp;
|
||||
props.pb = pb;
|
||||
props.fb = fb;
|
||||
props.numThreads = numThreads;
|
||||
|
||||
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
|
||||
NULL, &g_Alloc, &g_Alloc);
|
||||
}
|
||||
|
||||
|
||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
|
||||
const unsigned char *props, size_t propsSize)
|
||||
{
|
||||
ELzmaStatus status;
|
||||
return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/* LzmaLib.h -- LZMA library interface
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_LIB_H
|
||||
#define __LZMA_LIB_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define MY_STDAPI int MY_STD_CALL
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
/*
|
||||
RAM requirements for LZMA:
|
||||
for compression: (dictSize * 11.5 + 6 MB) + state_size
|
||||
for decompression: dictSize + state_size
|
||||
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||
by default (lc=3, lp=0), state_size = 16 KB.
|
||||
|
||||
LZMA properties (5 bytes) format
|
||||
Offset Size Description
|
||||
0 1 lc, lp and pb in encoded form.
|
||||
1 4 dictSize (little endian).
|
||||
*/
|
||||
|
||||
/*
|
||||
LzmaCompress
|
||||
------------
|
||||
|
||||
outPropsSize -
|
||||
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||
|
||||
LZMA Encoder will use defult values for any parameter, if it is
|
||||
-1 for any from: level, loc, lp, pb, fb, numThreads
|
||||
0 for dictSize
|
||||
|
||||
level - compression level: 0 <= level <= 9;
|
||||
|
||||
level dictSize algo fb
|
||||
0: 16 KB 0 32
|
||||
1: 64 KB 0 32
|
||||
2: 256 KB 0 32
|
||||
3: 1 MB 0 32
|
||||
4: 4 MB 0 32
|
||||
5: 16 MB 1 32
|
||||
6: 32 MB 1 32
|
||||
7+: 64 MB 1 64
|
||||
|
||||
The default value for "level" is 5.
|
||||
|
||||
algo = 0 means fast method
|
||||
algo = 1 means normal method
|
||||
|
||||
dictSize - The dictionary size in bytes. The maximum value is
|
||||
128 MB = (1 << 27) bytes for 32-bit version
|
||||
1 GB = (1 << 30) bytes for 64-bit version
|
||||
The default value is 16 MB = (1 << 24) bytes.
|
||||
It's recommended to use the dictionary that is larger than 4 KB and
|
||||
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||
|
||||
lc - The number of literal context bits (high bits of previous literal).
|
||||
It can be in the range from 0 to 8. The default value is 3.
|
||||
Sometimes lc=4 gives the gain for big files.
|
||||
|
||||
lp - The number of literal pos bits (low bits of current position for literals).
|
||||
It can be in the range from 0 to 4. The default value is 0.
|
||||
The lp switch is intended for periodical data when the period is equal to 2^lp.
|
||||
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
|
||||
better to set lc=0, if you change lp switch.
|
||||
|
||||
pb - The number of pos bits (low bits of current position).
|
||||
It can be in the range from 0 to 4. The default value is 2.
|
||||
The pb switch is intended for periodical data when the period is equal 2^pb.
|
||||
|
||||
fb - Word size (the number of fast bytes).
|
||||
It can be in the range from 5 to 273. The default value is 32.
|
||||
Usually, a big number gives a little bit better compression ratio and
|
||||
slower compression process.
|
||||
|
||||
numThreads - The number of thereads. 1 or 2. The default value is 2.
|
||||
Fast mode (algo = 0) can use only 1 thread.
|
||||
|
||||
Out:
|
||||
destLen - processed output size
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
|
||||
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
|
||||
int level, /* 0 <= level <= 9, default = 5 */
|
||||
unsigned dictSize, /* default = (1 << 24) */
|
||||
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||
int numThreads /* 1 or 2, default = 2 */
|
||||
);
|
||||
|
||||
/*
|
||||
LzmaUncompress
|
||||
--------------
|
||||
In:
|
||||
dest - output data
|
||||
destLen - output data size
|
||||
src - input data
|
||||
srcLen - input data size
|
||||
Out:
|
||||
destLen - processed output size
|
||||
srcLen - processed input size
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation arror
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
|
||||
*/
|
||||
|
||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
|
||||
const unsigned char *props, size_t propsSize);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
/* Precomp.h -- StdAfx
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_PRECOMP_H
|
||||
#define __7Z_PRECOMP_H
|
||||
|
||||
#include "Compiler.h"
|
||||
/* #include "7zTypes.h" */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,141 @@
|
|||
/* Sort.c -- Sort functions
|
||||
2014-04-05 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "Sort.h"
|
||||
|
||||
#define HeapSortDown(p, k, size, temp) \
|
||||
{ for (;;) { \
|
||||
size_t s = (k << 1); \
|
||||
if (s > size) break; \
|
||||
if (s < size && p[s + 1] > p[s]) s++; \
|
||||
if (temp >= p[s]) break; \
|
||||
p[k] = p[s]; k = s; \
|
||||
} p[k] = temp; }
|
||||
|
||||
void HeapSort(UInt32 *p, size_t size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
size_t i = size / 2;
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[i];
|
||||
size_t k = i;
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (--i != 0);
|
||||
}
|
||||
/*
|
||||
do
|
||||
{
|
||||
size_t k = 1;
|
||||
UInt32 temp = p[size];
|
||||
p[size--] = p[1];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (size > 1);
|
||||
*/
|
||||
while (size > 3)
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
size_t k = (p[3] > p[2]) ? 3 : 2;
|
||||
p[size--] = p[1];
|
||||
p[1] = p[k];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
p[size] = p[1];
|
||||
if (size > 2 && p[2] < temp)
|
||||
{
|
||||
p[1] = p[2];
|
||||
p[2] = temp;
|
||||
}
|
||||
else
|
||||
p[1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void HeapSort64(UInt64 *p, size_t size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
size_t i = size / 2;
|
||||
do
|
||||
{
|
||||
UInt64 temp = p[i];
|
||||
size_t k = i;
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (--i != 0);
|
||||
}
|
||||
/*
|
||||
do
|
||||
{
|
||||
size_t k = 1;
|
||||
UInt64 temp = p[size];
|
||||
p[size--] = p[1];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (size > 1);
|
||||
*/
|
||||
while (size > 3)
|
||||
{
|
||||
UInt64 temp = p[size];
|
||||
size_t k = (p[3] > p[2]) ? 3 : 2;
|
||||
p[size--] = p[1];
|
||||
p[1] = p[k];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
{
|
||||
UInt64 temp = p[size];
|
||||
p[size] = p[1];
|
||||
if (size > 2 && p[2] < temp)
|
||||
{
|
||||
p[1] = p[2];
|
||||
p[2] = temp;
|
||||
}
|
||||
else
|
||||
p[1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#define HeapSortRefDown(p, vals, n, size, temp) \
|
||||
{ size_t k = n; UInt32 val = vals[temp]; for (;;) { \
|
||||
size_t s = (k << 1); \
|
||||
if (s > size) break; \
|
||||
if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
|
||||
if (val >= vals[p[s]]) break; \
|
||||
p[k] = p[s]; k = s; \
|
||||
} p[k] = temp; }
|
||||
|
||||
void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
size_t i = size / 2;
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[i];
|
||||
HeapSortRefDown(p, vals, i, size, temp);
|
||||
}
|
||||
while (--i != 0);
|
||||
}
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
p[size--] = p[1];
|
||||
HeapSortRefDown(p, vals, 1, size, temp);
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,18 @@
|
|||
/* Sort.h -- Sort functions
|
||||
2014-04-05 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_SORT_H
|
||||
#define __7Z_SORT_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
void HeapSort(UInt32 *p, size_t size);
|
||||
void HeapSort64(UInt64 *p, size_t size);
|
||||
|
||||
/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#include "deps/chdr/chd.h"
|
||||
|
||||
/* tracks are padded to a multiple of this many frames */
|
||||
const uint32_t CD_TRACK_PADDING = 4;
|
||||
|
||||
struct CHDDisc : Disc
|
||||
{
|
||||
chd_file* chd;
|
||||
|
@ -10,7 +13,7 @@ struct CHDDisc : Disc
|
|||
|
||||
u32 hunkbytes;
|
||||
u32 sph;
|
||||
|
||||
|
||||
CHDDisc()
|
||||
{
|
||||
chd=0;
|
||||
|
@ -19,8 +22,8 @@ struct CHDDisc : Disc
|
|||
|
||||
bool TryOpen(const wchar* file);
|
||||
|
||||
~CHDDisc()
|
||||
{
|
||||
~CHDDisc()
|
||||
{
|
||||
if (hunk_mem)
|
||||
delete [] hunk_mem;
|
||||
if (chd)
|
||||
|
@ -32,32 +35,45 @@ struct CHDTrack : TrackFile
|
|||
{
|
||||
CHDDisc* disc;
|
||||
u32 StartFAD;
|
||||
u32 StartHunk;
|
||||
u32 Offset;
|
||||
u32 fmt;
|
||||
bool swap_bytes;
|
||||
|
||||
CHDTrack(CHDDisc* disc, u32 StartFAD,u32 StartHunk, u32 fmt)
|
||||
{
|
||||
this->disc=disc;
|
||||
CHDTrack(CHDDisc* disc, u32 StartFAD, u32 Offset, u32 fmt, bool swap_bytes)
|
||||
{
|
||||
this->disc=disc;
|
||||
this->StartFAD=StartFAD;
|
||||
this->StartHunk=StartHunk;
|
||||
this->Offset=Offset;
|
||||
this->fmt=fmt;
|
||||
this->swap_bytes = swap_bytes;
|
||||
}
|
||||
|
||||
virtual void Read(u32 FAD,u8* dst,SectorFormat* sector_type,u8* subcode,SubcodeFormat* subcode_type)
|
||||
virtual void Read(u32 FAD, u8* dst, SectorFormat* sector_type, u8* subcode, SubcodeFormat* subcode_type)
|
||||
{
|
||||
u32 fad_offs=FAD-StartFAD;
|
||||
u32 hunk=(fad_offs)/disc->sph + StartHunk;
|
||||
if (disc->old_hunk!=hunk)
|
||||
s32 fad_offs = FAD + Offset;
|
||||
u32 hunk = fad_offs / disc->sph;
|
||||
|
||||
if (disc->old_hunk != hunk)
|
||||
{
|
||||
chd_read(disc->chd,hunk,disc->hunk_mem); //CHDERR_NONE
|
||||
chd_read(disc->chd, hunk, disc->hunk_mem); //CHDERR_NONE
|
||||
disc->old_hunk = hunk;
|
||||
}
|
||||
|
||||
u32 hunk_ofs=fad_offs%disc->sph;
|
||||
u32 hunk_ofs = fad_offs%disc->sph;
|
||||
|
||||
memcpy(dst,disc->hunk_mem+hunk_ofs*(2352+96),fmt);
|
||||
|
||||
memcpy(dst, disc->hunk_mem + hunk_ofs * (2352+96), fmt);
|
||||
|
||||
if (swap_bytes)
|
||||
{
|
||||
for (int i = 0; i < fmt; i += 2)
|
||||
{
|
||||
u8 b = dst[i];
|
||||
dst[i] = dst[i + 1];
|
||||
dst[i + 1] = b;
|
||||
}
|
||||
}
|
||||
*sector_type=fmt==2352?SECFMT_2352:SECFMT_2048_MODE1;
|
||||
|
||||
|
||||
//While space is reserved for it, the images contain no actual subcodes
|
||||
//memcpy(subcode,disc->hunk_mem+hunk_ofs*(2352+96)+2352,96);
|
||||
*subcode_type=SUBFMT_NONE;
|
||||
|
@ -81,40 +97,53 @@ bool CHDDisc::TryOpen(const wchar* file)
|
|||
|
||||
sph = hunkbytes/(2352+96);
|
||||
|
||||
if (hunkbytes%(2352+96)!=0)
|
||||
if (hunkbytes%(2352+96)!=0)
|
||||
{
|
||||
printf("chd: hunkbytes is invalid, %d\n",hunkbytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
u32 tag;
|
||||
u8 flags;
|
||||
char temp[512];
|
||||
u32 temp_len;
|
||||
u32 total_frames=150;
|
||||
u32 total_frames = 150;
|
||||
|
||||
u32 total_secs=0;
|
||||
u32 total_hunks=0;
|
||||
u32 total_secs = 0;
|
||||
u32 Offset = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char type[64],subtype[32]="NONE",pgtype[32],pgsub[32];
|
||||
int tkid,frames,pregap=0,postgap=0;
|
||||
err=chd_get_metadata(chd,CDROM_TRACK_METADATA2_TAG,tracks.size(),temp,sizeof(temp),&temp_len,&tag,&flags);
|
||||
if (err==CHDERR_NONE)
|
||||
char type[16], subtype[16], pgtype[16], pgsub[16];
|
||||
int tkid=-1, frames=0, pregap=0, postgap=0, padframes=0;
|
||||
|
||||
err = chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, tracks.size(), temp, sizeof(temp), &temp_len, &tag, &flags);
|
||||
if (err == CHDERR_NONE)
|
||||
{
|
||||
//"TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"
|
||||
sscanf(temp,CDROM_TRACK_METADATA2_FORMAT,&tkid,type,subtype,&frames,&pregap,pgtype,pgsub,&postgap);
|
||||
sscanf(temp, CDROM_TRACK_METADATA2_FORMAT, &tkid, type, subtype, &frames, &pregap, pgtype, pgsub, &postgap);
|
||||
}
|
||||
else if (CHDERR_NONE== (err=chd_get_metadata(chd,CDROM_TRACK_METADATA_TAG,tracks.size(),temp,sizeof(temp),&temp_len,&tag,&flags)) )
|
||||
else if (CHDERR_NONE== (err = chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, tracks.size(), temp, sizeof(temp), &temp_len, &tag, &flags)) )
|
||||
{
|
||||
//CDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d"
|
||||
sscanf(temp,CDROM_TRACK_METADATA_FORMAT,&tkid,type,subtype,&frames);
|
||||
sscanf(temp, CDROM_TRACK_METADATA_FORMAT, &tkid, type, subtype, &frames);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("chd: Unable to find metadata, %d\n",err);
|
||||
break;
|
||||
err = chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, tracks.size(), temp, sizeof(temp), &temp_len, &tag, &flags);
|
||||
if (err != CHDERR_NONE)
|
||||
{
|
||||
err = chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, tracks.size(), temp, sizeof(temp), &temp_len, &tag, &flags);
|
||||
}
|
||||
if (err == CHDERR_NONE)
|
||||
{
|
||||
//GDROM_TRACK_METADATA_FORMAT "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PAD:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"
|
||||
sscanf(temp, GDROM_TRACK_METADATA_FORMAT, &tkid, type, subtype, &frames, &padframes, &pregap, pgtype, pgsub, &postgap);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tkid!=(tracks.size()+1) || (strcmp(type,"MODE1_RAW")!=0 && strcmp(type,"AUDIO")!=0 && strcmp(type,"MODE1")!=0) || strcmp(subtype,"NONE")!=0 || pregap!=0 || postgap!=0)
|
||||
|
@ -124,16 +153,19 @@ bool CHDDisc::TryOpen(const wchar* file)
|
|||
}
|
||||
printf("%s\n",temp);
|
||||
Track t;
|
||||
t.StartFAD=total_frames;
|
||||
total_frames+=frames;
|
||||
t.EndFAD=total_frames-1;
|
||||
t.ADDR=0;
|
||||
t.CTRL=strcmp(type,"AUDIO")==0?0:4;
|
||||
t.file = new CHDTrack(this,t.StartFAD,total_hunks,strcmp(type,"MODE1")?2352:2048);
|
||||
t.StartFAD = total_frames;
|
||||
total_frames += frames;
|
||||
t.EndFAD = total_frames - 1;
|
||||
t.ADDR = 0;
|
||||
t.CTRL = strcmp(type,"AUDIO") == 0 ? 0 : 4;
|
||||
|
||||
total_hunks+=frames/sph;
|
||||
if (frames%sph)
|
||||
total_hunks++;
|
||||
t.file = new CHDTrack(this, t.StartFAD, Offset - t.StartFAD, strcmp(type, "MODE1") ? 2352 : 2048,
|
||||
// audio tracks are byteswapped in CHDv5+
|
||||
t.CTRL == 0 && head->version >= 5);
|
||||
|
||||
// CHD files are padded, so we have to respect the offset
|
||||
int padded = (frames + CD_TRACK_PADDING - 1) / CD_TRACK_PADDING;
|
||||
Offset += padded * CD_TRACK_PADDING;
|
||||
|
||||
tracks.push_back(t);
|
||||
}
|
||||
|
@ -156,7 +188,7 @@ bool CHDDisc::TryOpen(const wchar* file)
|
|||
Disc* chd_parse(const wchar* file)
|
||||
{
|
||||
CHDDisc* rv = new CHDDisc();
|
||||
|
||||
|
||||
if (rv->TryOpen(file))
|
||||
return rv;
|
||||
else
|
||||
|
@ -164,4 +196,4 @@ Disc* chd_parse(const wchar* file)
|
|||
delete rv;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ include $(CLEAR_VARS)
|
|||
FOR_ANDROID := 1
|
||||
WEBUI := 1
|
||||
USE_GLES := 1
|
||||
CHD5_LZMA := 1
|
||||
CHD5_FLAC := 1
|
||||
|
||||
ifneq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
NOT_ARM := 1
|
||||
|
@ -52,6 +54,16 @@ LOCAL_CFLAGS := $(RZDCY_CFLAGS) -fPIC -fvisibility=hidden -ffunction-sections -
|
|||
LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections
|
||||
LOCAL_CPPFLAGS := $(RZDCY_CXXFLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections
|
||||
|
||||
# 7-Zip/LZMA settings (CHDv5)
|
||||
ifdef CHD5_LZMA
|
||||
LOCAL_CFLAGS += -D_7ZIP_ST -DCHD5_LZMA
|
||||
endif
|
||||
|
||||
# FLAC settings (CHDv5)
|
||||
ifdef CHD5_FLAC
|
||||
LOCAL_CFLAGS += -DCHD5_FLAC
|
||||
endif
|
||||
|
||||
# LOCAL_CFLAGS += -std=c++11
|
||||
LOCAL_CXXFLAGS += -std=c++11
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ AS=${CC_PREFIX}as
|
|||
STRIP=${CC_PREFIX}strip
|
||||
LD=${CC}
|
||||
|
||||
CHD5_LZMA := 1
|
||||
CHD5_FLAC := 1
|
||||
|
||||
MFLAGS :=
|
||||
ASFLAGS :=
|
||||
LDFLAGS :=
|
||||
|
@ -234,6 +237,15 @@ else
|
|||
$(error Unknown platform)
|
||||
endif
|
||||
|
||||
# 7-Zip/LZMA settings (CHDv5)
|
||||
ifdef CHD5_LZMA
|
||||
CFLAGS += -D_7ZIP_ST -DCHD5_LZMA
|
||||
endif
|
||||
|
||||
ifdef CHD5_FLAC
|
||||
CFLAGS += -DCHD5_FLAC
|
||||
endif
|
||||
|
||||
RZDCY_SRC_DIR = $(LOCAL_PATH)/../../core
|
||||
include $(RZDCY_SRC_DIR)/core.mk
|
||||
|
||||
|
|
|
@ -55,10 +55,35 @@
|
|||
<ClCompile Include="..\core\cfg\cfg.cpp" />
|
||||
<ClCompile Include="..\core\cfg\ini.cpp" />
|
||||
<ClCompile Include="..\core\deps\chdpsr\cdipsr.cpp" />
|
||||
<ClCompile Include="..\core\deps\chdr\chdr.cpp" />
|
||||
<ClCompile Include="..\core\deps\chdr\bitstream.c" />
|
||||
<ClCompile Include="..\core\deps\chdr\cdrom.c" />
|
||||
<ClCompile Include="..\core\deps\chdr\chd.c" />
|
||||
<ClCompile Include="..\core\deps\chdr\flac.c" />
|
||||
<ClCompile Include="..\core\deps\chdr\huffman.c" />
|
||||
<ClCompile Include="..\core\deps\coreio\coreio.cpp" />
|
||||
<ClCompile Include="..\core\deps\crypto\md5.cpp" />
|
||||
<ClCompile Include="..\core\deps\crypto\sha1.cpp" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\bitmath.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\bitreader.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\cpu.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\crc.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\fixed.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\fixed_intrin_sse2.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\fixed_intrin_ssse3.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\float.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\format.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\lpc.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\lpc_intrin_avx2.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\lpc_intrin_sse.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\lpc_intrin_sse2.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\lpc_intrin_sse41.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\md5.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\memory.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\metadata_iterators.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\metadata_object.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\stream_decoder.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\window.c" />
|
||||
<ClCompile Include="..\core\deps\flac\src\libFLAC\windows_unicode_filenames.c" />
|
||||
<ClCompile Include="..\core\deps\libelf\elf.cpp" />
|
||||
<ClCompile Include="..\core\deps\libelf\elf32.cpp" />
|
||||
<ClCompile Include="..\core\deps\libelf\elf64.cpp" />
|
||||
|
@ -96,6 +121,19 @@
|
|||
<ClCompile Include="..\core\deps\libwebsocket\server.c" />
|
||||
<ClCompile Include="..\core\deps\libwebsocket\service.c" />
|
||||
<ClCompile Include="..\core\deps\libwebsocket\sha-1.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Alloc.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Bra.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Bra86.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\BraIA64.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\CpuArch.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Delta.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\LzFind.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Lzma86Dec.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Lzma86Enc.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaDec.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaEnc.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaLib.c" />
|
||||
<ClCompile Include="..\core\deps\lzma\Sort.c" />
|
||||
<ClCompile Include="..\core\deps\zlib\adler32.c" />
|
||||
<ClCompile Include="..\core\deps\zlib\compress.c" />
|
||||
<ClCompile Include="..\core\deps\zlib\crc32.c" />
|
||||
|
@ -281,8 +319,12 @@
|
|||
<ClInclude Include="..\core\cfg\cfg.h" />
|
||||
<ClInclude Include="..\core\cfg\ini.h" />
|
||||
<ClInclude Include="..\core\deps\chdpsr\cdipsr.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\bitstream.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\cdrom.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\chd.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\coretypes.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\flac.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\huffman.h" />
|
||||
<ClInclude Include="..\core\deps\coreio\coreio.h" />
|
||||
<ClInclude Include="..\core\deps\crypto\md5.h" />
|
||||
<ClInclude Include="..\core\deps\crypto\sha1.h" />
|
||||
|
@ -676,8 +718,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -718,8 +760,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -760,8 +802,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -802,8 +844,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -846,8 +888,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -890,8 +932,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Full</Optimization>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;NDEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
|
@ -934,8 +976,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
@ -965,8 +1007,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
@ -996,8 +1038,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
@ -1027,8 +1069,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
@ -1063,8 +1105,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
@ -1099,8 +1141,8 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>DEF_CONSOLE;TARGET_NO_WEBUI;WIN32;_7ZIP_ST;CHD5_LZMA;CHD5_FLAC;PACKAGE_VERSION="1.3.2";FLAC__HAS_OGG=0;FLAC__NO_DLL;HAVE_LROUND;HAVE_STDINT_H;HAVE_STDLIB_H;_DEBUG;_CONSOLE;X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\core\;$(ProjectDir)..\core\khronos;$(ProjectDir)..\core\deps\flac\include;$(ProjectDir)..\core\deps\flac\src\libFLAC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
|
|
|
@ -97,9 +97,6 @@
|
|||
<ClCompile Include="..\core\deps\crypto\sha1.cpp">
|
||||
<Filter>deps\crypto</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\chdr.cpp">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\imgread\cdi.cpp">
|
||||
<Filter>imgread</Filter>
|
||||
</ClCompile>
|
||||
|
@ -429,6 +426,60 @@
|
|||
<ClCompile Include="..\core\cfg\ini.cpp">
|
||||
<Filter>cfg</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\chd.c">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\cdrom.c">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\flac.c">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\huffman.c">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\chdr\bitstream.c">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Alloc.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Bra.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Bra86.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\BraIA64.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\CpuArch.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Delta.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\LzFind.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Lzma86Dec.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Lzma86Enc.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaDec.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaEnc.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\LzmaLib.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\core\deps\lzma\Sort.c">
|
||||
<Filter>deps\lzma</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="hw">
|
||||
|
@ -566,6 +617,9 @@
|
|||
<Filter Include="hw\naomi">
|
||||
<UniqueIdentifier>{1752487d-0739-47bf-8c6b-1d38e6f389f7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="deps\lzma">
|
||||
<UniqueIdentifier>{9198fe3c-8215-431d-9adf-d36e81eda98d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\core\hw\aica\aica.h">
|
||||
|
@ -947,6 +1001,18 @@
|
|||
<Filter>hw\sh4\modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\core\version.h" />
|
||||
<ClInclude Include="..\core\deps\chdr\cdrom.h">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\core\deps\chdr\flac.h">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\core\deps\chdr\huffman.h">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\core\deps\chdr\bitstream.h">
|
||||
<Filter>deps\chdr</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\core\deps\zlib\Makefile">
|
||||
|
|
Loading…
Reference in New Issue