mirror of
https://codeberg.org/ashley/poke.git
synced 2024-11-10 03:28:35 +01:00
add alac source code - part 4 :3
This commit is contained in:
parent
a15b2d6068
commit
2ab7ae1a8e
3 changed files with 813 additions and 0 deletions
362
alac/codec/ag_dec.c
Normal file
362
alac/codec/ag_dec.c
Normal file
|
@ -0,0 +1,362 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
File: ag_dec.c
|
||||||
|
|
||||||
|
Contains: Adaptive Golomb decode routines.
|
||||||
|
|
||||||
|
Copyright: (c) 2001-2011 Apple, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aglib.h"
|
||||||
|
#include "ALACBitUtilities.h"
|
||||||
|
#include "ALACAudioTypes.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#if __GNUC__ && TARGET_OS_MAC
|
||||||
|
#if __POWERPC__
|
||||||
|
#include <ppc_intrinsics.h>
|
||||||
|
#else
|
||||||
|
#include <libkern/OSByteOrder.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CODE_TO_LONG_MAXBITS 32
|
||||||
|
#define N_MAX_MEAN_CLAMP 0xffff
|
||||||
|
#define N_MEAN_CLAMP_VAL 0xffff
|
||||||
|
#define REPORT_VAL 40
|
||||||
|
|
||||||
|
#if __GNUC__
|
||||||
|
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define ALWAYS_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
|
||||||
|
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
|
||||||
|
if it is ugly but the performance gains are well worth it.
|
||||||
|
- WSK 5/19/04
|
||||||
|
*/
|
||||||
|
|
||||||
|
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth)
|
||||||
|
{
|
||||||
|
/* Use
|
||||||
|
fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data,
|
||||||
|
but use
|
||||||
|
fullwidth = full image width, sectorwidth = sector (patch) width
|
||||||
|
for such as image (2-dim.) data.
|
||||||
|
*/
|
||||||
|
set_ag_params( params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT );
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun)
|
||||||
|
{
|
||||||
|
params->mb = params->mb0 = m;
|
||||||
|
params->pb = p;
|
||||||
|
params->kb = k;
|
||||||
|
params->wb = (1u<<params->kb)-1;
|
||||||
|
params->qb = QB-params->pb;
|
||||||
|
params->fw = f;
|
||||||
|
params->sw = s;
|
||||||
|
params->maxrun = maxrun;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRAGMA_MARK
|
||||||
|
#pragma mark -
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
|
||||||
|
static inline int32_t lead( int32_t m )
|
||||||
|
{
|
||||||
|
long j;
|
||||||
|
unsigned long c = (1ul << 31);
|
||||||
|
|
||||||
|
for(j=0; j < 32; j++)
|
||||||
|
{
|
||||||
|
if((c & m) != 0)
|
||||||
|
break;
|
||||||
|
c >>= 1;
|
||||||
|
}
|
||||||
|
return (j);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
x += 3;
|
||||||
|
result = lead(x);
|
||||||
|
|
||||||
|
return 31 - result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
|
||||||
|
{
|
||||||
|
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
|
||||||
|
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
|
||||||
|
return value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRAGMA_MARK
|
||||||
|
#pragma mark -
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define get_next_fromlong(inlong, suff) ((inlong) >> (32 - (suff)))
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32_t ALWAYS_INLINE
|
||||||
|
getstreambits( uint8_t *in, int32_t bitoffset, int32_t numbits )
|
||||||
|
{
|
||||||
|
uint32_t load1, load2;
|
||||||
|
uint32_t byteoffset = bitoffset / 8;
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
//Assert( numbits <= 32 );
|
||||||
|
|
||||||
|
load1 = read32bit( in + byteoffset );
|
||||||
|
|
||||||
|
if ( (numbits + (bitoffset & 0x7)) > 32)
|
||||||
|
{
|
||||||
|
int32_t load2shift;
|
||||||
|
|
||||||
|
result = load1 << (bitoffset & 0x7);
|
||||||
|
load2 = (uint32_t) in[byteoffset+4];
|
||||||
|
load2shift = (8-(numbits + (bitoffset & 0x7)-32));
|
||||||
|
load2 >>= load2shift;
|
||||||
|
result >>= (32-numbits);
|
||||||
|
result |= load2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = load1 >> (32-numbits-(bitoffset & 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
// a shift of >= "the number of bits in the type of the value being shifted" results in undefined
|
||||||
|
// behavior so don't try to shift by 32
|
||||||
|
if ( numbits != (sizeof(result) * 8) )
|
||||||
|
result &= ~(0xfffffffful << numbits);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int32_t dyn_get(unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k)
|
||||||
|
{
|
||||||
|
uint32_t tempbits = *bitPos;
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t pre = 0, v;
|
||||||
|
uint32_t streamlong;
|
||||||
|
|
||||||
|
streamlong = read32bit( in + (tempbits >> 3) );
|
||||||
|
streamlong <<= (tempbits & 7);
|
||||||
|
|
||||||
|
/* find the number of bits in the prefix */
|
||||||
|
{
|
||||||
|
uint32_t notI = ~streamlong;
|
||||||
|
pre = lead( notI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pre >= MAX_PREFIX_16)
|
||||||
|
{
|
||||||
|
pre = MAX_PREFIX_16;
|
||||||
|
tempbits += pre;
|
||||||
|
streamlong <<= pre;
|
||||||
|
result = get_next_fromlong(streamlong,MAX_DATATYPE_BITS_16);
|
||||||
|
tempbits += MAX_DATATYPE_BITS_16;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// all of the bits must fit within the long we have loaded
|
||||||
|
//Assert(pre+1+k <= 32);
|
||||||
|
|
||||||
|
tempbits += pre;
|
||||||
|
tempbits += 1;
|
||||||
|
streamlong <<= pre+1;
|
||||||
|
v = get_next_fromlong(streamlong, k);
|
||||||
|
tempbits += k;
|
||||||
|
|
||||||
|
result = pre*m + v-1;
|
||||||
|
|
||||||
|
if(v<2) {
|
||||||
|
result -= (v-1);
|
||||||
|
tempbits -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*bitPos = tempbits;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int32_t dyn_get_32bit( uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits )
|
||||||
|
{
|
||||||
|
uint32_t tempbits = *bitPos;
|
||||||
|
uint32_t v;
|
||||||
|
uint32_t streamlong;
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
streamlong = read32bit( in + (tempbits >> 3) );
|
||||||
|
streamlong <<= (tempbits & 7);
|
||||||
|
|
||||||
|
/* find the number of bits in the prefix */
|
||||||
|
{
|
||||||
|
uint32_t notI = ~streamlong;
|
||||||
|
result = lead( notI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result >= MAX_PREFIX_32)
|
||||||
|
{
|
||||||
|
result = getstreambits(in, tempbits+MAX_PREFIX_32, maxbits);
|
||||||
|
tempbits += MAX_PREFIX_32 + maxbits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* all of the bits must fit within the long we have loaded*/
|
||||||
|
//Assert(k<=14);
|
||||||
|
//Assert(result<MAX_PREFIX_32);
|
||||||
|
//Assert(result+1+k <= 32);
|
||||||
|
|
||||||
|
tempbits += result;
|
||||||
|
tempbits += 1;
|
||||||
|
|
||||||
|
if (k != 1)
|
||||||
|
{
|
||||||
|
streamlong <<= result+1;
|
||||||
|
v = get_next_fromlong(streamlong, k);
|
||||||
|
tempbits += k;
|
||||||
|
tempbits -= 1;
|
||||||
|
result = result*m;
|
||||||
|
|
||||||
|
if(v>=2)
|
||||||
|
{
|
||||||
|
result += (v-1);
|
||||||
|
tempbits += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*bitPos = tempbits;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dyn_decomp( AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits )
|
||||||
|
{
|
||||||
|
uint8_t *in;
|
||||||
|
int32_t *outPtr = pc;
|
||||||
|
uint32_t bitPos, startPos, maxPos;
|
||||||
|
uint32_t j, m, k, n, c, mz;
|
||||||
|
int32_t del, zmode;
|
||||||
|
uint32_t mb;
|
||||||
|
uint32_t pb_local = params->pb;
|
||||||
|
uint32_t kb_local = params->kb;
|
||||||
|
uint32_t wb_local = params->wb;
|
||||||
|
int32_t status;
|
||||||
|
|
||||||
|
RequireAction( (bitstream != nil) && (pc != nil) && (outNumBits != nil), return kALAC_ParamError; );
|
||||||
|
*outNumBits = 0;
|
||||||
|
|
||||||
|
in = bitstream->cur;
|
||||||
|
startPos = bitstream->bitIndex;
|
||||||
|
maxPos = bitstream->byteSize * 8;
|
||||||
|
bitPos = startPos;
|
||||||
|
|
||||||
|
mb = params->mb0;
|
||||||
|
zmode = 0;
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
status = ALAC_noErr;
|
||||||
|
|
||||||
|
while (c < numSamples)
|
||||||
|
{
|
||||||
|
// bail if we've run off the end of the buffer
|
||||||
|
RequireAction( bitPos < maxPos, status = kALAC_ParamError; goto Exit; );
|
||||||
|
|
||||||
|
m = (mb)>>QBSHIFT;
|
||||||
|
k = lg3a(m);
|
||||||
|
|
||||||
|
k = arithmin(k, kb_local);
|
||||||
|
m = (1<<k)-1;
|
||||||
|
|
||||||
|
n = dyn_get_32bit( in, &bitPos, m, k, maxSize );
|
||||||
|
|
||||||
|
// least significant bit is sign bit
|
||||||
|
{
|
||||||
|
uint32_t ndecode = n + zmode;
|
||||||
|
int32_t multiplier = (- (ndecode&1));
|
||||||
|
|
||||||
|
multiplier |= 1;
|
||||||
|
del = ((ndecode+1) >> 1) * (multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
*outPtr++ = del;
|
||||||
|
|
||||||
|
c++;
|
||||||
|
|
||||||
|
mb = pb_local*(n+zmode) + mb - ((pb_local*mb)>>QBSHIFT);
|
||||||
|
|
||||||
|
// update mean tracking
|
||||||
|
if (n > N_MAX_MEAN_CLAMP)
|
||||||
|
mb = N_MEAN_CLAMP_VAL;
|
||||||
|
|
||||||
|
zmode = 0;
|
||||||
|
|
||||||
|
if (((mb << MMULSHIFT) < QB) && (c < numSamples))
|
||||||
|
{
|
||||||
|
zmode = 1;
|
||||||
|
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
|
||||||
|
mz = ((1<<k)-1) & wb_local;
|
||||||
|
|
||||||
|
n = dyn_get(in, &bitPos, mz, k);
|
||||||
|
|
||||||
|
RequireAction(c+n <= numSamples, status = kALAC_ParamError; goto Exit; );
|
||||||
|
|
||||||
|
for(j=0; j < n; j++)
|
||||||
|
{
|
||||||
|
*outPtr++ = 0;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n >= 65535)
|
||||||
|
zmode = 0;
|
||||||
|
|
||||||
|
mb = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
*outNumBits = (bitPos - startPos);
|
||||||
|
BitBufferAdvance( bitstream, *outNumBits );
|
||||||
|
RequireAction( bitstream->cur <= bitstream->end, status = kALAC_ParamError; );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
370
alac/codec/ag_enc.c
Normal file
370
alac/codec/ag_enc.c
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
File: ag_enc.c
|
||||||
|
|
||||||
|
Contains: Adaptive Golomb encode routines.
|
||||||
|
|
||||||
|
Copyright: (c) 2001-2011 Apple, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "aglib.h"
|
||||||
|
#include "ALACBitUtilities.h"
|
||||||
|
#include "EndianPortable.h"
|
||||||
|
#include "ALACAudioTypes.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#if __GNUC__ && TARGET_OS_MAC
|
||||||
|
#if __POWERPC__
|
||||||
|
#include <ppc_intrinsics.h>
|
||||||
|
#else
|
||||||
|
#include <libkern/OSByteOrder.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CODE_TO_LONG_MAXBITS 32
|
||||||
|
#define N_MAX_MEAN_CLAMP 0xffff
|
||||||
|
#define N_MEAN_CLAMP_VAL 0xffff
|
||||||
|
#define REPORT_VAL 40
|
||||||
|
|
||||||
|
#if __GNUC__
|
||||||
|
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define ALWAYS_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
|
||||||
|
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
|
||||||
|
if it is ugly but the performance gains are well worth it.
|
||||||
|
- WSK 5/19/04
|
||||||
|
*/
|
||||||
|
|
||||||
|
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
|
||||||
|
static inline int32_t lead( int32_t m )
|
||||||
|
{
|
||||||
|
long j;
|
||||||
|
unsigned long c = (1ul << 31);
|
||||||
|
|
||||||
|
for(j=0; j < 32; j++)
|
||||||
|
{
|
||||||
|
if((c & m) != 0)
|
||||||
|
break;
|
||||||
|
c >>= 1;
|
||||||
|
}
|
||||||
|
return (j);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
x += 3;
|
||||||
|
result = lead(x);
|
||||||
|
|
||||||
|
return 31 - result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t ALWAYS_INLINE abs_func( int32_t a )
|
||||||
|
{
|
||||||
|
// note: the CW PPC intrinsic __abs() turns into these instructions so no need to try and use it
|
||||||
|
int32_t isneg = a >> 31;
|
||||||
|
int32_t xorval = a ^ isneg;
|
||||||
|
int32_t result = xorval-isneg;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
|
||||||
|
{
|
||||||
|
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
|
||||||
|
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PRAGMA_MARK
|
||||||
|
#pragma mark -
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int32_t dyn_code(int32_t m, int32_t k, int32_t n, uint32_t *outNumBits)
|
||||||
|
{
|
||||||
|
uint32_t div, mod, de;
|
||||||
|
uint32_t numBits;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
//Assert( n >= 0 );
|
||||||
|
|
||||||
|
div = n/m;
|
||||||
|
|
||||||
|
if(div >= MAX_PREFIX_16)
|
||||||
|
{
|
||||||
|
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
|
||||||
|
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mod = n%m;
|
||||||
|
de = (mod == 0);
|
||||||
|
numBits = div + k + 1 - de;
|
||||||
|
value = (((1<<div)-1)<<(numBits-div)) + mod + 1 - de;
|
||||||
|
|
||||||
|
// if coding this way is bigger than doing escape, then do escape
|
||||||
|
if (numBits > MAX_PREFIX_16 + MAX_DATATYPE_BITS_16)
|
||||||
|
{
|
||||||
|
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
|
||||||
|
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outNumBits = numBits;
|
||||||
|
|
||||||
|
return (int32_t) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int32_t dyn_code_32bit(int32_t maxbits, uint32_t m, uint32_t k, uint32_t n, uint32_t *outNumBits, uint32_t *outValue, uint32_t *overflow, uint32_t *overflowbits)
|
||||||
|
{
|
||||||
|
uint32_t div, mod, de;
|
||||||
|
uint32_t numBits;
|
||||||
|
uint32_t value;
|
||||||
|
int32_t didOverflow = 0;
|
||||||
|
|
||||||
|
div = n/m;
|
||||||
|
|
||||||
|
if (div < MAX_PREFIX_32)
|
||||||
|
{
|
||||||
|
mod = n - (m * div);
|
||||||
|
|
||||||
|
de = (mod == 0);
|
||||||
|
numBits = div + k + 1 - de;
|
||||||
|
value = (((1<<div)-1)<<(numBits-div)) + mod + 1 - de;
|
||||||
|
if (numBits > 25)
|
||||||
|
goto codeasescape;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
codeasescape:
|
||||||
|
numBits = MAX_PREFIX_32;
|
||||||
|
value = (((1<<MAX_PREFIX_32)-1));
|
||||||
|
*overflow = n;
|
||||||
|
*overflowbits = maxbits;
|
||||||
|
didOverflow = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*outNumBits = numBits;
|
||||||
|
*outValue = value;
|
||||||
|
|
||||||
|
return didOverflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void ALWAYS_INLINE dyn_jam_noDeref(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t *i = (uint32_t *)(out + (bitPos >> 3));
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t curr;
|
||||||
|
uint32_t shift;
|
||||||
|
|
||||||
|
//Assert( numBits <= 32 );
|
||||||
|
|
||||||
|
curr = *i;
|
||||||
|
curr = Swap32NtoB( curr );
|
||||||
|
|
||||||
|
shift = 32 - (bitPos & 7) - numBits;
|
||||||
|
|
||||||
|
mask = ~0u >> (32 - numBits); // mask must be created in two steps to avoid compiler sequencing ambiguity
|
||||||
|
mask <<= shift;
|
||||||
|
|
||||||
|
value = (value << shift) & mask;
|
||||||
|
value |= curr & ~mask;
|
||||||
|
|
||||||
|
*i = Swap32BtoN( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void ALWAYS_INLINE dyn_jam_noDeref_large(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t * i = (uint32_t *)(out + (bitPos>>3));
|
||||||
|
uint32_t w;
|
||||||
|
uint32_t curr;
|
||||||
|
uint32_t mask;
|
||||||
|
int32_t shiftvalue = (32 - (bitPos&7) - numBits);
|
||||||
|
|
||||||
|
//Assert(numBits <= 32);
|
||||||
|
|
||||||
|
curr = *i;
|
||||||
|
curr = Swap32NtoB( curr );
|
||||||
|
|
||||||
|
if (shiftvalue < 0)
|
||||||
|
{
|
||||||
|
uint8_t tailbyte;
|
||||||
|
uint8_t *tailptr;
|
||||||
|
|
||||||
|
w = value >> -shiftvalue;
|
||||||
|
mask = ~0u >> -shiftvalue;
|
||||||
|
w |= (curr & ~mask);
|
||||||
|
|
||||||
|
tailptr = ((uint8_t *)i) + 4;
|
||||||
|
tailbyte = (value << ((8+shiftvalue))) & 0xff;
|
||||||
|
*tailptr = (uint8_t)tailbyte;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = ~0u >> (32 - numBits);
|
||||||
|
mask <<= shiftvalue; // mask must be created in two steps to avoid compiler sequencing ambiguity
|
||||||
|
|
||||||
|
w = (value << shiftvalue) & mask;
|
||||||
|
w |= curr & ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
*i = Swap32BtoN( w );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t dyn_comp( AGParamRecPtr params, int32_t * pc, BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits )
|
||||||
|
{
|
||||||
|
unsigned char * out;
|
||||||
|
uint32_t bitPos, startPos;
|
||||||
|
uint32_t m, k, n, c, mz, nz;
|
||||||
|
uint32_t numBits;
|
||||||
|
uint32_t value;
|
||||||
|
int32_t del, zmode;
|
||||||
|
uint32_t overflow, overflowbits;
|
||||||
|
int32_t status;
|
||||||
|
|
||||||
|
// shadow the variables in params so there's not the dereferencing overhead
|
||||||
|
uint32_t mb, pb, kb, wb;
|
||||||
|
int32_t rowPos = 0;
|
||||||
|
int32_t rowSize = params->sw;
|
||||||
|
int32_t rowJump = (params->fw) - rowSize;
|
||||||
|
int32_t * inPtr = pc;
|
||||||
|
|
||||||
|
*outNumBits = 0;
|
||||||
|
RequireAction( (bitSize >= 1) && (bitSize <= 32), return kALAC_ParamError; );
|
||||||
|
|
||||||
|
out = bitstream->cur;
|
||||||
|
startPos = bitstream->bitIndex;
|
||||||
|
bitPos = startPos;
|
||||||
|
|
||||||
|
mb = params->mb = params->mb0;
|
||||||
|
pb = params->pb;
|
||||||
|
kb = params->kb;
|
||||||
|
wb = params->wb;
|
||||||
|
zmode = 0;
|
||||||
|
|
||||||
|
c=0;
|
||||||
|
status = ALAC_noErr;
|
||||||
|
|
||||||
|
while (c < numSamples)
|
||||||
|
{
|
||||||
|
m = mb >> QBSHIFT;
|
||||||
|
k = lg3a(m);
|
||||||
|
if ( k > kb)
|
||||||
|
{
|
||||||
|
k = kb;
|
||||||
|
}
|
||||||
|
m = (1<<k)-1;
|
||||||
|
|
||||||
|
del = *inPtr++;
|
||||||
|
rowPos++;
|
||||||
|
|
||||||
|
n = (abs_func(del) << 1) - ((del >> 31) & 1) - zmode;
|
||||||
|
//Assert( 32-lead(n) <= bitSize );
|
||||||
|
|
||||||
|
if ( dyn_code_32bit(bitSize, m, k, n, &numBits, &value, &overflow, &overflowbits) )
|
||||||
|
{
|
||||||
|
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||||
|
bitPos += numBits;
|
||||||
|
dyn_jam_noDeref_large(out, bitPos, overflowbits, overflow);
|
||||||
|
bitPos += overflowbits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||||
|
bitPos += numBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
c++;
|
||||||
|
if ( rowPos >= rowSize)
|
||||||
|
{
|
||||||
|
rowPos = 0;
|
||||||
|
inPtr += rowJump;
|
||||||
|
}
|
||||||
|
|
||||||
|
mb = pb * (n + zmode) + mb - ((pb *mb)>>QBSHIFT);
|
||||||
|
|
||||||
|
// update mean tracking if it's overflowed
|
||||||
|
if (n > N_MAX_MEAN_CLAMP)
|
||||||
|
mb = N_MEAN_CLAMP_VAL;
|
||||||
|
|
||||||
|
zmode = 0;
|
||||||
|
|
||||||
|
RequireAction(c <= numSamples, status = kALAC_ParamError; goto Exit; );
|
||||||
|
|
||||||
|
if (((mb << MMULSHIFT) < QB) && (c < numSamples))
|
||||||
|
{
|
||||||
|
zmode = 1;
|
||||||
|
nz = 0;
|
||||||
|
|
||||||
|
while(c<numSamples && *inPtr == 0)
|
||||||
|
{
|
||||||
|
/* Take care of wrap-around globals. */
|
||||||
|
++inPtr;
|
||||||
|
++nz;
|
||||||
|
++c;
|
||||||
|
if ( ++rowPos >= rowSize)
|
||||||
|
{
|
||||||
|
rowPos = 0;
|
||||||
|
inPtr += rowJump;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nz >= 65535)
|
||||||
|
{
|
||||||
|
zmode = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
|
||||||
|
mz = ((1<<k)-1) & wb;
|
||||||
|
|
||||||
|
value = dyn_code(mz, k, nz, &numBits);
|
||||||
|
dyn_jam_noDeref(out, bitPos, numBits, value);
|
||||||
|
bitPos += numBits;
|
||||||
|
|
||||||
|
mb = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*outNumBits = (bitPos - startPos);
|
||||||
|
BitBufferAdvance( bitstream, *outNumBits );
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return status;
|
||||||
|
}
|
81
alac/codec/aglib.h
Normal file
81
alac/codec/aglib.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
File: aglib.h
|
||||||
|
|
||||||
|
Copyright: (C) 2001-2011 Apple, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AGLIB_H
|
||||||
|
#define AGLIB_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define QBSHIFT 9
|
||||||
|
#define QB (1<<QBSHIFT)
|
||||||
|
#define PB0 40
|
||||||
|
#define MB0 10
|
||||||
|
#define KB0 14
|
||||||
|
#define MAX_RUN_DEFAULT 255
|
||||||
|
|
||||||
|
#define MMULSHIFT 2
|
||||||
|
#define MDENSHIFT (QBSHIFT - MMULSHIFT - 1)
|
||||||
|
#define MOFF ((1<<(MDENSHIFT-2)))
|
||||||
|
|
||||||
|
#define BITOFF 24
|
||||||
|
|
||||||
|
/* Max. prefix of 1's. */
|
||||||
|
#define MAX_PREFIX_16 9
|
||||||
|
#define MAX_PREFIX_TOLONG_16 15
|
||||||
|
#define MAX_PREFIX_32 9
|
||||||
|
|
||||||
|
/* Max. bits in 16-bit data type */
|
||||||
|
#define MAX_DATATYPE_BITS_16 16
|
||||||
|
|
||||||
|
typedef struct AGParamRec
|
||||||
|
{
|
||||||
|
uint32_t mb, mb0, pb, kb, wb, qb;
|
||||||
|
uint32_t fw, sw;
|
||||||
|
|
||||||
|
uint32_t maxrun;
|
||||||
|
|
||||||
|
// fw = 1, sw = 1;
|
||||||
|
|
||||||
|
} AGParamRec, *AGParamRecPtr;
|
||||||
|
|
||||||
|
struct BitBuffer;
|
||||||
|
|
||||||
|
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth);
|
||||||
|
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun);
|
||||||
|
|
||||||
|
int32_t dyn_comp(AGParamRecPtr params, int32_t * pc, struct BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits);
|
||||||
|
int32_t dyn_decomp(AGParamRecPtr params, struct BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //#ifndef AGLIB_H
|
Loading…
Reference in a new issue