dep/libchdr: Update to a03e693
This commit is contained in:
parent
ef6e18a1b2
commit
6b8486674f
|
@ -1,4 +1,5 @@
|
||||||
add_library(libchdr
|
add_library(libchdr
|
||||||
|
include/dr_libs/dr_flac.h
|
||||||
include/libchdr/bitstream.h
|
include/libchdr/bitstream.h
|
||||||
include/libchdr/cdrom.h
|
include/libchdr/cdrom.h
|
||||||
include/libchdr/chd.h
|
include/libchdr/chd.h
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -347,7 +347,7 @@ struct _chd_verify_result
|
||||||
FUNCTION PROTOTYPES
|
FUNCTION PROTOTYPES
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _MSC_VER
|
||||||
#ifdef CHD_DLL
|
#ifdef CHD_DLL
|
||||||
#ifdef CHD_DLL_EXPORTS
|
#ifdef CHD_DLL_EXPORTS
|
||||||
#define CHD_EXPORT __declspec(dllexport)
|
#define CHD_EXPORT __declspec(dllexport)
|
||||||
|
@ -355,7 +355,6 @@ struct _chd_verify_result
|
||||||
#define CHD_EXPORT __declspec(dllimport)
|
#define CHD_EXPORT __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// Static library.
|
|
||||||
#define CHD_EXPORT
|
#define CHD_EXPORT
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -393,6 +392,8 @@ CHD_EXPORT const char *chd_error_string(chd_error err);
|
||||||
/* return a pointer to the extracted CHD header data */
|
/* return a pointer to the extracted CHD header data */
|
||||||
CHD_EXPORT const chd_header *chd_get_header(chd_file *chd);
|
CHD_EXPORT const chd_header *chd_get_header(chd_file *chd);
|
||||||
|
|
||||||
|
/* read CHD header data from file into the pointed struct */
|
||||||
|
CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
/* Configure CHDR features here */
|
/* Configure CHDR features here */
|
||||||
#define WANT_RAW_DATA_SECTOR 1
|
#define WANT_RAW_DATA_SECTOR 1
|
||||||
#define WANT_SUBCODE 0
|
#define WANT_SUBCODE 1
|
||||||
#define NEED_CACHE_HUNK 0
|
#define NEED_CACHE_HUNK 1
|
||||||
#define VERIFY_BLOCK_CRC 0
|
#define VERIFY_BLOCK_CRC 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,12 +4,21 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef __LIBRETRO__
|
#ifdef USE_LIBRETRO_VFS
|
||||||
#include <streams/file_stream_transforms.h>
|
#include <streams/file_stream_transforms.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
|
||||||
|
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||||
|
#undef UINT32
|
||||||
|
#undef UINT16
|
||||||
|
#undef UINT8
|
||||||
|
#undef INT32
|
||||||
|
#undef INT16
|
||||||
|
#undef INT8
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef uint64_t UINT64;
|
typedef uint64_t UINT64;
|
||||||
typedef uint32_t UINT32;
|
typedef uint32_t UINT32;
|
||||||
typedef uint16_t UINT16;
|
typedef uint16_t UINT16;
|
||||||
|
@ -22,17 +31,33 @@ typedef int8_t INT8;
|
||||||
|
|
||||||
#define core_file FILE
|
#define core_file FILE
|
||||||
#define core_fopen(file) fopen(file, "rb")
|
#define core_fopen(file) fopen(file, "rb")
|
||||||
#define core_fseek fseek
|
|
||||||
|
#if defined USE_LIBRETRO_VFS
|
||||||
|
#define core_fseek fseek
|
||||||
|
#define core_ftell ftell
|
||||||
|
#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WIN64__)
|
||||||
|
#define core_fseek _fseeki64
|
||||||
|
#define core_ftell _ftelli64
|
||||||
|
#elif defined(_LARGEFILE_SOURCE) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
|
||||||
|
#define core_fseek fseeko64
|
||||||
|
#define core_ftell ftello64
|
||||||
|
#elif defined(__PS3__) && !defined(__PSL1GHT__) || defined(__SWITCH__)
|
||||||
|
#define core_fseek(x,y,z) fseek(x,(off_t)y,z)
|
||||||
|
#define core_ftell(x) (off_t)ftell(x)
|
||||||
|
#else
|
||||||
|
#define core_fseek fseeko
|
||||||
|
#define core_ftell ftello
|
||||||
|
#endif
|
||||||
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
|
#define core_fread(fc, buff, len) fread(buff, 1, len, fc)
|
||||||
#define core_fclose fclose
|
#define core_fclose fclose
|
||||||
#define core_ftell ftell
|
|
||||||
static inline size_t core_fsize(core_file *f)
|
static UINT64 core_fsize(core_file *f)
|
||||||
{
|
{
|
||||||
long rv;
|
UINT64 rv;
|
||||||
long p = ftell(f);
|
UINT64 p = core_ftell(f);
|
||||||
fseek(f, 0, SEEK_END);
|
core_fseek(f, 0, SEEK_END);
|
||||||
rv = ftell(f);
|
rv = core_ftell(f);
|
||||||
fseek(f, p, SEEK_SET);
|
core_fseek(f, p, SEEK_SET);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#define __FLAC_H__
|
#define __FLAC_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <FLAC/all.h>
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* TYPE DEFINITIONS
|
* TYPE DEFINITIONS
|
||||||
|
@ -24,14 +23,14 @@
|
||||||
typedef struct _flac_decoder flac_decoder;
|
typedef struct _flac_decoder flac_decoder;
|
||||||
struct _flac_decoder {
|
struct _flac_decoder {
|
||||||
/* output state */
|
/* output state */
|
||||||
FLAC__StreamDecoder* decoder; /* actual encoder */
|
void * decoder; /* actual encoder */
|
||||||
uint32_t sample_rate; /* decoded sample rate */
|
uint32_t sample_rate; /* decoded sample rate */
|
||||||
uint8_t channels; /* decoded number of channels */
|
uint8_t channels; /* decoded number of channels */
|
||||||
uint8_t bits_per_sample; /* decoded bits per sample */
|
uint8_t bits_per_sample; /* decoded bits per sample */
|
||||||
uint32_t compressed_offset; /* current offset in compressed data */
|
uint32_t compressed_offset; /* current offset in compressed data */
|
||||||
const FLAC__byte * compressed_start; /* start of compressed data */
|
const uint8_t * compressed_start; /* start of compressed data */
|
||||||
uint32_t compressed_length; /* length of compressed data */
|
uint32_t compressed_length; /* length of compressed data */
|
||||||
const FLAC__byte * compressed2_start; /* start of compressed data */
|
const uint8_t * compressed2_start; /* start of compressed data */
|
||||||
uint32_t compressed2_length; /* length 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) */
|
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_offset; /* current position in uncompressed data */
|
||||||
|
@ -42,7 +41,7 @@ struct _flac_decoder {
|
||||||
|
|
||||||
/* ======================> flac_decoder */
|
/* ======================> flac_decoder */
|
||||||
|
|
||||||
void flac_decoder_init(flac_decoder* decoder);
|
int flac_decoder_init(flac_decoder* decoder);
|
||||||
void flac_decoder_free(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_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);
|
int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uint32_t num_samples, int swap_endian);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="..\msvc\vsprops\Configurations.props" />
|
<Import Project="..\msvc\vsprops\Configurations.props" />
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)'!='DebugUWP' And '$(Configuration)'!='ReleaseUWP'">
|
<ItemGroup Condition="'$(Configuration)'!='DebugUWP' And '$(Configuration)'!='ReleaseUWP'">
|
||||||
<ProjectReference Include="..\libFLAC\libFLAC.vcxproj">
|
<ProjectReference Include="..\libFLAC\libFLAC.vcxproj">
|
||||||
<Project>{97cbd3cb-cbc7-4d52-abde-f0ae7b794a5d}</Project>
|
<Project>{97cbd3cb-cbc7-4d52-abde-f0ae7b794a5d}</Project>
|
||||||
|
@ -13,7 +12,6 @@
|
||||||
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
|
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\libchdr_bitstream.c" />
|
<ClCompile Include="src\libchdr_bitstream.c" />
|
||||||
<ClCompile Include="src\libchdr_cdrom.c" />
|
<ClCompile Include="src\libchdr_cdrom.c" />
|
||||||
|
@ -22,6 +20,7 @@
|
||||||
<ClCompile Include="src\libchdr_huffman.c" />
|
<ClCompile Include="src\libchdr_huffman.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="include\dr_libs\dr_flac.h" />
|
||||||
<ClInclude Include="include\libchdr\bitstream.h" />
|
<ClInclude Include="include\libchdr\bitstream.h" />
|
||||||
<ClInclude Include="include\libchdr\cdrom.h" />
|
<ClInclude Include="include\libchdr\cdrom.h" />
|
||||||
<ClInclude Include="include\libchdr\chd.h" />
|
<ClInclude Include="include\libchdr\chd.h" />
|
||||||
|
@ -30,13 +29,10 @@
|
||||||
<ClInclude Include="include\libchdr\flac.h" />
|
<ClInclude Include="include\libchdr\flac.h" />
|
||||||
<ClInclude Include="include\libchdr\huffman.h" />
|
<ClInclude Include="include\libchdr\huffman.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{425D6C99-D1C8-43C2-B8AC-4D7B1D941017}</ProjectGuid>
|
<ProjectGuid>{425D6C99-D1C8-43C2-B8AC-4D7B1D941017}</ProjectGuid>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Import Project="..\msvc\vsprops\StaticLibrary.props" />
|
<Import Project="..\msvc\vsprops\StaticLibrary.props" />
|
||||||
|
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||||
|
@ -44,6 +40,5 @@
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
<Import Project="..\msvc\vsprops\Targets.props" />
|
<Import Project="..\msvc\vsprops\Targets.props" />
|
||||||
</Project>
|
</Project>
|
|
@ -15,5 +15,6 @@
|
||||||
<ClInclude Include="include\libchdr\huffman.h" />
|
<ClInclude Include="include\libchdr\huffman.h" />
|
||||||
<ClInclude Include="include\libchdr\bitstream.h" />
|
<ClInclude Include="include\libchdr\bitstream.h" />
|
||||||
<ClInclude Include="include\libchdr\cdrom.h" />
|
<ClInclude Include="include\libchdr\cdrom.h" />
|
||||||
|
<ClInclude Include="include\dr_libs\dr_flac.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -15,7 +15,7 @@
|
||||||
schemes will differ after track 1!
|
schemes will differ after track 1!
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <libchdr/cdrom.h>
|
#include <libchdr/cdrom.h>
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
|
|
||||||
#include "LzmaEnc.h"
|
#include "LzmaEnc.h"
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||||
|
#define __MACTYPES__
|
||||||
|
#endif
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#undef TRUE
|
#undef TRUE
|
||||||
|
@ -430,7 +433,7 @@ static void *lzma_fast_alloc(void *p, size_t size)
|
||||||
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
|
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
|
||||||
if (addr==NULL)
|
if (addr==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||||
{
|
{
|
||||||
if (codec->allocptr[scan] == NULL)
|
if (codec->allocptr[scan] == NULL)
|
||||||
{
|
{
|
||||||
|
@ -794,8 +797,7 @@ static chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* flac decoder init */
|
/* flac decoder init */
|
||||||
flac_decoder_init(&cdfl->decoder);
|
if (flac_decoder_init(&cdfl->decoder))
|
||||||
if (cdfl->decoder.decoder == NULL)
|
|
||||||
return CHDERR_OUT_OF_MEMORY;
|
return CHDERR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
return CHDERR_NONE;
|
return CHDERR_NONE;
|
||||||
|
@ -1161,7 +1163,7 @@ static inline int chd_compressed(chd_header* header) {
|
||||||
static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
|
static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int hunknum;
|
uint32_t hunknum;
|
||||||
int repcount = 0;
|
int repcount = 0;
|
||||||
uint8_t lastcomp = 0;
|
uint8_t lastcomp = 0;
|
||||||
uint32_t last_self = 0;
|
uint32_t last_self = 0;
|
||||||
|
@ -1383,8 +1385,15 @@ CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent,
|
||||||
EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
|
EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
|
||||||
|
|
||||||
/* if we need a parent, make sure we have one */
|
/* if we need a parent, make sure we have one */
|
||||||
if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
|
if (parent == NULL)
|
||||||
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
{
|
||||||
|
/* Detect parent requirement for versions below 5 */
|
||||||
|
if (newchd->header.version < 5 && newchd->header.flags & CHDFLAGS_HAS_PARENT)
|
||||||
|
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
||||||
|
/* Detection for version 5 and above - if parentsha1 != 0, we have a parent */
|
||||||
|
else if (newchd->header.version >= 5 && memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
|
||||||
|
EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
|
||||||
|
}
|
||||||
|
|
||||||
/* make sure we have a valid parent */
|
/* make sure we have a valid parent */
|
||||||
if (parent != NULL)
|
if (parent != NULL)
|
||||||
|
@ -1561,6 +1570,12 @@ CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent,
|
||||||
chd_error err;
|
chd_error err;
|
||||||
core_file *file = NULL;
|
core_file *file = NULL;
|
||||||
|
|
||||||
|
if (filename == NULL)
|
||||||
|
{
|
||||||
|
err = CHDERR_INVALID_PARAMETER;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* choose the proper mode */
|
/* choose the proper mode */
|
||||||
switch(mode)
|
switch(mode)
|
||||||
{
|
{
|
||||||
|
@ -1677,6 +1692,9 @@ CHD_EXPORT void chd_close(chd_file *chd)
|
||||||
if (chd->file_cache)
|
if (chd->file_cache)
|
||||||
free(chd->file_cache);
|
free(chd->file_cache);
|
||||||
|
|
||||||
|
if (chd->parent)
|
||||||
|
chd_close(chd->parent);
|
||||||
|
|
||||||
/* free our memory */
|
/* free our memory */
|
||||||
free(chd);
|
free(chd);
|
||||||
}
|
}
|
||||||
|
@ -1750,6 +1768,41 @@ CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
|
||||||
return &chd->header;
|
return &chd->header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
chd_read_header - read CHD header data
|
||||||
|
from file into the pointed struct
|
||||||
|
-------------------------------------------------*/
|
||||||
|
CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header)
|
||||||
|
{
|
||||||
|
chd_error err = CHDERR_NONE;
|
||||||
|
chd_file chd;
|
||||||
|
|
||||||
|
/* punt if NULL */
|
||||||
|
if (filename == NULL || header == NULL)
|
||||||
|
EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
/* open the file */
|
||||||
|
chd.file = core_fopen(filename);
|
||||||
|
if (chd.file == NULL)
|
||||||
|
EARLY_EXIT(err = CHDERR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
/* attempt to read the header */
|
||||||
|
err = header_read(&chd, header);
|
||||||
|
if (err != CHDERR_NONE)
|
||||||
|
EARLY_EXIT(err);
|
||||||
|
|
||||||
|
/* validate the header */
|
||||||
|
err = header_validate(header);
|
||||||
|
if (err != CHDERR_NONE)
|
||||||
|
EARLY_EXIT(err);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (chd.file != NULL)
|
||||||
|
core_fclose(chd.file);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
CORE DATA READ/WRITE
|
CORE DATA READ/WRITE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
@ -2124,9 +2177,9 @@ static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
|
||||||
static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
|
static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
#else
|
#else
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
#endif
|
#endif
|
||||||
if (chd->file_cache != NULL)
|
if (chd->file_cache != NULL)
|
||||||
{
|
{
|
||||||
|
@ -2344,13 +2397,33 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
|
||||||
return hunk_read_into_memory(chd, blockoffs, dest);
|
return hunk_read_into_memory(chd, blockoffs, dest);
|
||||||
|
|
||||||
case COMPRESSION_PARENT:
|
case COMPRESSION_PARENT:
|
||||||
#if 0
|
if (chd->parent == NULL)
|
||||||
/* TODO */
|
|
||||||
if (m_parent_missing)
|
|
||||||
return CHDERR_REQUIRES_PARENT;
|
return CHDERR_REQUIRES_PARENT;
|
||||||
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
|
UINT8 units_in_hunk = chd->header.hunkbytes / chd->header.unitbytes;
|
||||||
#endif
|
|
||||||
return CHDERR_DECOMPRESSION_ERROR;
|
/* blockoffs is aligned to units_in_hunk */
|
||||||
|
if (blockoffs % units_in_hunk == 0) {
|
||||||
|
return hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, dest);
|
||||||
|
/* blockoffs is not aligned to units_in_hunk */
|
||||||
|
} else {
|
||||||
|
UINT32 unit_in_hunk = blockoffs % units_in_hunk;
|
||||||
|
UINT8 *buf = malloc(chd->header.hunkbytes);
|
||||||
|
/* Read first half of hunk which contains blockoffs */
|
||||||
|
err = hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, buf);
|
||||||
|
if (err != CHDERR_NONE) {
|
||||||
|
free(buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
memcpy(dest, buf + unit_in_hunk * chd->header.unitbytes, (units_in_hunk - unit_in_hunk) * chd->header.unitbytes);
|
||||||
|
/* Read second half of hunk which contains blockoffs */
|
||||||
|
err = hunk_read_into_memory(chd->parent, (blockoffs / units_in_hunk) + 1, buf);
|
||||||
|
if (err != CHDERR_NONE) {
|
||||||
|
free(buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
memcpy(dest + (units_in_hunk - unit_in_hunk) * chd->header.unitbytes, buf, unit_in_hunk * chd->header.unitbytes);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return CHDERR_NONE;
|
return CHDERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -2375,7 +2448,7 @@ static chd_error map_read(chd_file *chd)
|
||||||
UINT8 cookie[MAP_ENTRY_SIZE];
|
UINT8 cookie[MAP_ENTRY_SIZE];
|
||||||
UINT32 count;
|
UINT32 count;
|
||||||
chd_error err;
|
chd_error err;
|
||||||
int i;
|
UINT32 i;
|
||||||
|
|
||||||
/* first allocate memory */
|
/* first allocate memory */
|
||||||
chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
|
chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
|
||||||
|
@ -2545,8 +2618,6 @@ static void zlib_codec_free(void *codec)
|
||||||
/* deinit the streams */
|
/* deinit the streams */
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
inflateEnd(&data->inflater);
|
inflateEnd(&data->inflater);
|
||||||
|
|
||||||
/* free our fast memory */
|
/* free our fast memory */
|
||||||
|
|
|
@ -8,40 +8,37 @@
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <libchdr/flac.h>
|
#include <libchdr/flac.h>
|
||||||
|
#define DR_FLAC_IMPLEMENTATION
|
||||||
|
#define DR_FLAC_NO_STDIO
|
||||||
|
#include <dr_libs/dr_flac.h>
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* FLAC DECODER
|
* FLAC DECODER
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static FLAC__StreamDecoderReadStatus flac_decoder_read_callback_static(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
|
static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes);
|
||||||
FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC__byte buffer[], size_t *bytes);
|
static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin);
|
||||||
static void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
|
static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata);
|
||||||
static FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
|
static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes);
|
||||||
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) */
|
/* getters (valid after reset) */
|
||||||
static uint32_t sample_rate(flac_decoder *decoder) { return decoder->sample_rate; }
|
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 channels(flac_decoder *decoder) { return decoder->channels; }
|
||||||
static uint8_t bits_per_sample(flac_decoder *decoder) { return decoder->bits_per_sample; }
|
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
|
* flac_decoder - constructor
|
||||||
*-------------------------------------------------
|
*-------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void flac_decoder_init(flac_decoder *decoder)
|
int flac_decoder_init(flac_decoder *decoder)
|
||||||
{
|
{
|
||||||
decoder->decoder = FLAC__stream_decoder_new();
|
decoder->decoder = NULL;
|
||||||
decoder->sample_rate = 0;
|
decoder->sample_rate = 0;
|
||||||
decoder->channels = 0;
|
decoder->channels = 0;
|
||||||
decoder->bits_per_sample = 0;
|
decoder->bits_per_sample = 0;
|
||||||
|
@ -53,6 +50,7 @@ void flac_decoder_init(flac_decoder *decoder)
|
||||||
decoder->uncompressed_offset = 0;
|
decoder->uncompressed_offset = 0;
|
||||||
decoder->uncompressed_length = 0;
|
decoder->uncompressed_length = 0;
|
||||||
decoder->uncompressed_swap = 0;
|
decoder->uncompressed_swap = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
@ -63,7 +61,8 @@ void flac_decoder_init(flac_decoder *decoder)
|
||||||
void flac_decoder_free(flac_decoder* decoder)
|
void flac_decoder_free(flac_decoder* decoder)
|
||||||
{
|
{
|
||||||
if ((decoder != NULL) && (decoder->decoder != NULL))
|
if ((decoder != NULL) && (decoder->decoder != NULL))
|
||||||
FLAC__stream_decoder_delete(decoder->decoder);
|
drflac_close(decoder->decoder);
|
||||||
|
decoder->decoder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
@ -75,17 +74,11 @@ void flac_decoder_free(flac_decoder* decoder)
|
||||||
static int flac_decoder_internal_reset(flac_decoder* decoder)
|
static int flac_decoder_internal_reset(flac_decoder* decoder)
|
||||||
{
|
{
|
||||||
decoder->compressed_offset = 0;
|
decoder->compressed_offset = 0;
|
||||||
if (FLAC__stream_decoder_init_stream(decoder->decoder,
|
flac_decoder_free(decoder);
|
||||||
&flac_decoder_read_callback_static,
|
decoder->decoder = drflac_open_with_metadata(
|
||||||
NULL,
|
flac_decoder_read_callback, flac_decoder_seek_callback,
|
||||||
&flac_decoder_tell_callback_static,
|
flac_decoder_metadata_callback, decoder, NULL);
|
||||||
NULL,
|
return (decoder->decoder != 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
@ -114,16 +107,16 @@ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
|
||||||
};
|
};
|
||||||
memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
|
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[0x08] = decoder->custom_header[0x0a] = (block_size*num_channels) >> 8;
|
||||||
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = block_size & 0xff;
|
decoder->custom_header[0x09] = decoder->custom_header[0x0b] = (block_size*num_channels) & 0xff;
|
||||||
decoder->custom_header[0x12] = sample_rate >> 12;
|
decoder->custom_header[0x12] = sample_rate >> 12;
|
||||||
decoder->custom_header[0x13] = sample_rate >> 4;
|
decoder->custom_header[0x13] = sample_rate >> 4;
|
||||||
decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
decoder->custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
||||||
|
|
||||||
/* configure the header ahead of the provided buffer */
|
/* configure the header ahead of the provided buffer */
|
||||||
decoder->compressed_start = (const FLAC__byte *)(decoder->custom_header);
|
decoder->compressed_start = (const uint8_t *)(decoder->custom_header);
|
||||||
decoder->compressed_length = sizeof(decoder->custom_header);
|
decoder->compressed_length = sizeof(decoder->custom_header);
|
||||||
decoder->compressed2_start = (const FLAC__byte *)(buffer);
|
decoder->compressed2_start = (const uint8_t *)(buffer);
|
||||||
decoder->compressed2_length = length;
|
decoder->compressed2_length = length;
|
||||||
return flac_decoder_internal_reset(decoder);
|
return flac_decoder_internal_reset(decoder);
|
||||||
}
|
}
|
||||||
|
@ -143,43 +136,20 @@ int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uin
|
||||||
decoder->uncompressed_length = num_samples;
|
decoder->uncompressed_length = num_samples;
|
||||||
decoder->uncompressed_swap = swap_endian;
|
decoder->uncompressed_swap = swap_endian;
|
||||||
|
|
||||||
|
#define BUFFER 2352 /* bytes per CD audio sector */
|
||||||
|
int16_t buffer[BUFFER];
|
||||||
|
uint32_t buf_samples = BUFFER / channels(decoder);
|
||||||
/* loop until we get everything we want */
|
/* loop until we get everything we want */
|
||||||
while (decoder->uncompressed_offset < decoder->uncompressed_length)
|
while (decoder->uncompressed_offset < decoder->uncompressed_length) {
|
||||||
if (!FLAC__stream_decoder_process_single(decoder->decoder))
|
uint32_t frames = (num_samples < buf_samples ? num_samples : buf_samples);
|
||||||
|
if (!drflac_read_pcm_frames_s16(decoder->decoder, frames, buffer))
|
||||||
return 0;
|
return 0;
|
||||||
|
flac_decoder_write_callback(decoder, buffer, frames*sizeof(*buffer)*channels(decoder));
|
||||||
|
num_samples -= frames;
|
||||||
|
}
|
||||||
return 1;
|
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
|
* finish - finish up the decode
|
||||||
*-------------------------------------------------
|
*-------------------------------------------------
|
||||||
|
@ -188,15 +158,21 @@ bool flac_decoder::decode(int16_t **samples, uint32_t num_samples, bool swap_end
|
||||||
uint32_t flac_decoder_finish(flac_decoder* decoder)
|
uint32_t flac_decoder_finish(flac_decoder* decoder)
|
||||||
{
|
{
|
||||||
/* get the final decoding position and move forward */
|
/* get the final decoding position and move forward */
|
||||||
FLAC__uint64 position = 0;
|
drflac *flac = decoder->decoder;
|
||||||
FLAC__stream_decoder_get_decode_position(decoder->decoder, &position);
|
uint64_t position = decoder->compressed_offset;
|
||||||
FLAC__stream_decoder_finish(decoder->decoder);
|
|
||||||
|
/* ugh... there's no function to obtain bytes used in drflac :-/ */
|
||||||
|
position -= DRFLAC_CACHE_L2_LINES_REMAINING(&flac->bs) * sizeof(drflac_cache_t);
|
||||||
|
position -= DRFLAC_CACHE_L1_BITS_REMAINING(&flac->bs) / 8;
|
||||||
|
position -= flac->bs.unalignedByteCount;
|
||||||
|
|
||||||
/* adjust position if we provided the header */
|
/* adjust position if we provided the header */
|
||||||
if (position == 0)
|
if (position == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (decoder->compressed_start == (const FLAC__byte *)(decoder->custom_header))
|
if (decoder->compressed_start == (const uint8_t *)(decoder->custom_header))
|
||||||
position -= decoder->compressed_length;
|
position -= decoder->compressed_length;
|
||||||
|
|
||||||
|
flac_decoder_free(decoder);
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,39 +184,31 @@ uint32_t flac_decoder_finish(flac_decoder* decoder)
|
||||||
|
|
||||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
#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)
|
static size_t flac_decoder_read_callback(void *userdata, void *buffer, size_t bytes)
|
||||||
{
|
{
|
||||||
return flac_decoder_read_callback(client_data, buffer, bytes);
|
flac_decoder* decoder = (flac_decoder*)userdata;
|
||||||
}
|
uint8_t *dst = buffer;
|
||||||
|
|
||||||
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 */
|
/* copy from primary buffer first */
|
||||||
uint32_t outputpos = 0;
|
uint32_t outputpos = 0;
|
||||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length)
|
if (outputpos < bytes && decoder->compressed_offset < decoder->compressed_length)
|
||||||
{
|
{
|
||||||
uint32_t bytes_to_copy = MIN(*bytes - outputpos, decoder->compressed_length - decoder->compressed_offset);
|
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);
|
memcpy(&dst[outputpos], decoder->compressed_start + decoder->compressed_offset, bytes_to_copy);
|
||||||
outputpos += bytes_to_copy;
|
outputpos += bytes_to_copy;
|
||||||
decoder->compressed_offset += bytes_to_copy;
|
decoder->compressed_offset += bytes_to_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* once we're out of that, copy from the secondary buffer */
|
/* once we're out of that, copy from the secondary buffer */
|
||||||
if (outputpos < *bytes && decoder->compressed_offset < decoder->compressed_length + decoder->compressed2_length)
|
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));
|
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);
|
memcpy(&dst[outputpos], decoder->compressed2_start + decoder->compressed_offset - decoder->compressed_length, bytes_to_copy);
|
||||||
outputpos += bytes_to_copy;
|
outputpos += bytes_to_copy;
|
||||||
decoder->compressed_offset += bytes_to_copy;
|
decoder->compressed_offset += bytes_to_copy;
|
||||||
}
|
}
|
||||||
*bytes = outputpos;
|
|
||||||
|
|
||||||
/* return based on whether we ran out of data */
|
return outputpos;
|
||||||
return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
@ -248,30 +216,18 @@ FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC
|
||||||
*-------------------------------------------------
|
*-------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
static void flac_decoder_metadata_callback(void *userdata, drflac_metadata *metadata)
|
||||||
{
|
{
|
||||||
flac_decoder *fldecoder;
|
flac_decoder *decoder = userdata;
|
||||||
|
|
||||||
/* ignore all but STREAMINFO metadata */
|
/* ignore all but STREAMINFO metadata */
|
||||||
if (metadata->type != FLAC__METADATA_TYPE_STREAMINFO)
|
if (metadata->type != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* parse out the data we care about */
|
/* parse out the data we care about */
|
||||||
fldecoder = (flac_decoder *)(client_data);
|
decoder->sample_rate = metadata->data.streaminfo.sampleRate;
|
||||||
fldecoder->sample_rate = metadata->data.stream_info.sample_rate;
|
decoder->bits_per_sample = metadata->data.streaminfo.bitsPerSample;
|
||||||
fldecoder->bits_per_sample = metadata->data.stream_info.bits_per_sample;
|
decoder->channels = metadata->data.streaminfo.channels;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
@ -280,53 +236,67 @@ FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__Stre
|
||||||
*-------------------------------------------------
|
*-------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FLAC__StreamDecoderWriteStatus flac_decoder_write_callback_static(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
static void flac_decoder_write_callback(void *userdata, void *buffer, size_t bytes)
|
||||||
{
|
|
||||||
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 sampnum, chan;
|
||||||
int shift, blocksize;
|
int shift, blocksize;
|
||||||
flac_decoder * decoder = (flac_decoder *)client_data;
|
flac_decoder * decoder = (flac_decoder *)userdata;
|
||||||
|
int16_t *sampbuf = (int16_t *)buffer;
|
||||||
assert(frame->header.channels == channels(decoder));
|
int sampch = channels(decoder);
|
||||||
|
uint32_t offset = decoder->uncompressed_offset;
|
||||||
|
uint16_t usample;
|
||||||
|
|
||||||
/* interleaved case */
|
/* interleaved case */
|
||||||
shift = decoder->uncompressed_swap ? 8 : 0;
|
shift = decoder->uncompressed_swap ? 8 : 0;
|
||||||
blocksize = frame->header.blocksize;
|
blocksize = bytes / (sampch * sizeof(sampbuf[0]));
|
||||||
if (decoder->uncompressed_start[1] == NULL)
|
if (decoder->uncompressed_start[1] == NULL)
|
||||||
{
|
{
|
||||||
int16_t *dest = decoder->uncompressed_start[0] + decoder->uncompressed_offset * frame->header.channels;
|
int16_t *dest = decoder->uncompressed_start[0] + offset * sampch;
|
||||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
|
||||||
for (chan = 0; chan < frame->header.channels; chan++)
|
for (chan = 0; chan < sampch; chan++) {
|
||||||
*dest++ = (int16_t)((((uint16_t)buffer[chan][sampnum]) << shift) | (((uint16_t)buffer[chan][sampnum]) >> shift));
|
usample = (uint16_t)*sampbuf++;
|
||||||
|
*dest++ = (int16_t)((usample << shift) | (usample >> shift));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non-interleaved case */
|
/* non-interleaved case */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (sampnum = 0; sampnum < blocksize && decoder->uncompressed_offset < decoder->uncompressed_length; sampnum++, decoder->uncompressed_offset++)
|
for (sampnum = 0; sampnum < blocksize && offset < decoder->uncompressed_length; sampnum++, offset++)
|
||||||
for (chan = 0; chan < frame->header.channels; chan++)
|
for (chan = 0; chan < sampch; chan++) {
|
||||||
|
usample = (uint16_t)*sampbuf++;
|
||||||
if (decoder->uncompressed_start[chan] != NULL)
|
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) );
|
decoder->uncompressed_start[chan][offset] = (int16_t) ((usample << shift) | (usample >> shift));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
decoder->uncompressed_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @fn void flac_decoder::error_callback_static(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
/*-------------------------------------------------
|
||||||
*
|
* seek_callback - handle seeks on the output
|
||||||
* @brief -------------------------------------------------
|
* stream
|
||||||
* 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)
|
static drflac_bool32 flac_decoder_seek_callback(void *userdata, int offset, drflac_seek_origin origin)
|
||||||
{
|
{
|
||||||
|
flac_decoder * decoder = (flac_decoder *)userdata;
|
||||||
|
uint32_t length = decoder->compressed_length + decoder->compressed2_length;
|
||||||
|
|
||||||
|
if (origin == drflac_seek_origin_start) {
|
||||||
|
uint32_t pos = offset;
|
||||||
|
if (pos <= length) {
|
||||||
|
decoder->compressed_offset = pos;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (origin == drflac_seek_origin_current) {
|
||||||
|
uint32_t pos = decoder->compressed_offset + offset;
|
||||||
|
if (pos <= length) {
|
||||||
|
decoder->compressed_offset = pos;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,6 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -181,7 +180,8 @@ uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* b
|
||||||
|
|
||||||
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf)
|
||||||
{
|
{
|
||||||
int numbits, curnode;
|
int numbits;
|
||||||
|
uint32_t curnode;
|
||||||
enum huffman_error error;
|
enum huffman_error error;
|
||||||
|
|
||||||
/* bits per entry depends on the maxbits */
|
/* bits per entry depends on the maxbits */
|
||||||
|
@ -247,7 +247,7 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
|
||||||
int last = 0;
|
int last = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int index;
|
int index;
|
||||||
int curcode;
|
uint32_t curcode;
|
||||||
uint8_t rlefullbits = 0;
|
uint8_t rlefullbits = 0;
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
enum huffman_error error;
|
enum huffman_error error;
|
||||||
|
@ -317,7 +317,7 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
|
||||||
|
|
||||||
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder)
|
enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder)
|
||||||
{
|
{
|
||||||
int i;
|
uint32_t i;
|
||||||
uint32_t lowerweight;
|
uint32_t lowerweight;
|
||||||
uint32_t upperweight;
|
uint32_t upperweight;
|
||||||
/* compute the number of data items in the histogram */
|
/* compute the number of data items in the histogram */
|
||||||
|
@ -381,7 +381,7 @@ static int huffman_tree_node_compare(const void *item1, const void *item2)
|
||||||
|
|
||||||
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight)
|
int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight)
|
||||||
{
|
{
|
||||||
int curcode;
|
uint32_t curcode;
|
||||||
int nextalloc;
|
int nextalloc;
|
||||||
int listitems = 0;
|
int listitems = 0;
|
||||||
int maxbits = 0;
|
int maxbits = 0;
|
||||||
|
@ -478,7 +478,8 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint
|
||||||
|
|
||||||
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder)
|
enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder)
|
||||||
{
|
{
|
||||||
int curcode, codelen;
|
uint32_t curcode;
|
||||||
|
int codelen;
|
||||||
uint32_t curstart = 0;
|
uint32_t curstart = 0;
|
||||||
/* build up a histogram of bit lengths */
|
/* build up a histogram of bit lengths */
|
||||||
uint32_t bithisto[33] = { 0 };
|
uint32_t bithisto[33] = { 0 };
|
||||||
|
@ -519,7 +520,7 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode
|
||||||
|
|
||||||
void huffman_build_lookup_table(struct huffman_decoder* decoder)
|
void huffman_build_lookup_table(struct huffman_decoder* decoder)
|
||||||
{
|
{
|
||||||
int curcode;
|
uint32_t curcode;
|
||||||
/* iterate over all codes */
|
/* iterate over all codes */
|
||||||
for (curcode = 0; curcode < decoder->numcodes; curcode++)
|
for (curcode = 0; curcode < decoder->numcodes; curcode++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue