Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Mathis Rosenhauer
libaec
Commits
8ee20f33
Commit
8ee20f33
authored
Sep 13, 2012
by
Mathis Rosenhauer
Browse files
fix signed handling
parent
082c9c46
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/Makefile
View file @
8ee20f33
...
...
@@ -43,6 +43,9 @@ check: encode decode test_szcomp
./encode
-c
-b4
-B32
-R128
-J8
../data/example_data
>
../data/test.aee
./decode
-b4
-B32
-R128
-J8
../data/test.aee
cmp ../data/test ../data/example_data
./encode
-c
-s
-b4
-B32
-R128
-J8
../data/example_data
>
../data/test.aee
./decode
-s
-b4
-B32
-R128
-J8
../data/test.aee
cmp ../data/test ../data/example_data
./encode
-c
-b
512
-B8
-R128
-J8
../data/example_data
>
../data/test.aee
./decode
-b
512
-B8
-R128
-J8
../data/test.aee
cmp ../data/test ../data/example_data
...
...
src/aed.c
View file @
8ee20f33
...
...
@@ -119,30 +119,39 @@ static void put_8(ae_streamp strm, int64_t data)
static
inline
void
u_put
(
ae_streamp
strm
,
int64_t
sample
)
{
int64_t
x
,
d
,
th
,
D
;
decode_state
*
state
;
int64_t
x
,
d
,
th
,
D
,
lower
;
decode_state
*
state
=
strm
->
state
;
state
=
strm
->
state
;
if
(
state
->
pp
&&
(
state
->
samples_out
%
state
->
ref_int
!=
0
))
{
d
=
sample
;
x
=
state
->
last_out
;
th
=
MIN
(
x
-
state
->
xmin
,
state
->
xmax
-
x
);
lower
=
x
-
state
->
xmin
;
th
=
MIN
(
lower
,
state
->
xmax
-
x
);
if
(
d
<=
2
*
th
)
if
(
d
<=
2
*
th
)
{
if
(
d
&
1
)
D
=
-
(
d
+
1
)
/
2
;
else
D
=
d
/
2
;
}
else
{
if
(
th
==
x
)
if
(
th
==
lower
)
D
=
d
-
th
;
else
D
=
th
-
d
;
}
sample
=
x
+
D
;
}
else
{
if
(
strm
->
flags
&
AE_DATA_SIGNED
)
{
int
m
=
64
-
strm
->
bit_per_sample
;
/* Reference samples have to be sign extended */
sample
=
(
sample
<<
m
)
>>
m
;
}
}
state
->
last_out
=
sample
;
state
->
put_sample
(
strm
,
sample
);
state
->
samples_out
++
;
...
...
src/aee.c
View file @
8ee20f33
...
...
@@ -88,56 +88,97 @@ static inline void emitfs(encode_state *state, int fs)
}
}
static
inline
void
emitblock
(
ae_streamp
strm
,
int
k
,
int
skip
)
#define EMITBLOCK(ref) \
static inline void emitblock_##ref(ae_streamp strm, int k) \
{ \
int b; \
uint64_t a; \
encode_state *state = strm->state; \
uint32_t *in = state->block_p + ref; \
uint32_t *in_end = state->block_p + strm->block_size; \
uint64_t mask = (1ULL << k) - 1; \
uint8_t *o = state->cds_p; \
int p = state->bit_p; \
\
a = *o; \
\
while(in < in_end) \
{ \
a <<= 56; \
p = (p % 8) + 56; \
\
while (p > k && in < in_end) \
{ \
p -= k; \
a += ((uint64_t)(*in++) & mask) << p; \
} \
\
for (b = 56; b > (p & ~7); b -= 8) \
*o++ = a >> b; \
a >>= b; \
} \
\
*o = a; \
state->cds_p = o; \
state->bit_p = p % 8; \
}
EMITBLOCK
(
0
);
EMITBLOCK
(
1
);
static
void
preprocess_unsigned
(
ae_streamp
strm
)
{
int
i
;
u
int64_t
acc
;
int64_t
theta
,
Delta
,
prev
;
encode_state
*
state
=
strm
->
state
;
uint32_t
*
in
=
state
->
block_p
+
skip
;
uint32_t
*
in_end
=
state
->
block_p
+
strm
->
block_size
;
uint64_t
mask
=
(
1ULL
<<
k
)
-
1
;
uint8_t
*
out
=
state
->
cds_p
;
acc
=
*
out
;
/* Insert reference samples into first block of Reference Sample
* Interval.
*/
prev
=
state
->
block_buf
[
0
];
while
(
in
<
in_end
)
for
(
i
=
1
;
i
<
strm
->
rsi
*
strm
->
block_size
;
i
++
)
{
acc
<<=
56
;
state
->
bit_p
=
(
state
->
bit_p
%
8
)
+
56
;
theta
=
MIN
(
prev
,
state
->
xmax
-
prev
);
Delta
=
(
int64_t
)
state
->
block_buf
[
i
]
-
prev
;
prev
=
state
->
block_buf
[
i
];
while
(
state
->
bit_p
>
k
&&
in
<
in_end
)
if
(
0
<=
Delta
&&
Delta
<=
theta
)
{
state
->
bit_p
-=
k
;
acc
+=
((
uint64_t
)(
*
in
++
)
&
mask
)
<<
state
->
bit_p
;
state
->
block_buf
[
i
]
=
2
*
Delta
;
}
else
if
(
-
theta
<=
Delta
&&
Delta
<
0
)
{
state
->
block_buf
[
i
]
=
2
*
(
Delta
<
0
?
-
(
uint64_t
)
Delta
:
Delta
)
-
1
;
}
else
{
state
->
block_buf
[
i
]
=
theta
+
(
Delta
<
0
?
-
(
uint64_t
)
Delta
:
Delta
);
}
for
(
i
=
56
;
i
>
(
state
->
bit_p
&
~
7
);
i
-=
8
)
*
out
++
=
acc
>>
i
;
acc
>>=
i
;
}
*
out
=
acc
;
state
->
cds_p
=
out
;
state
->
bit_p
%=
8
;
}
static
inline
void
preprocess
(
ae_streamp
strm
)
static
void
preprocess
_signed
(
ae_streamp
strm
)
{
int
i
;
int64_t
theta
,
Delta
,
last_in
;
int
i
,
m
;
int64_t
theta
,
Delta
,
prev
,
sample
;
encode_state
*
state
=
strm
->
state
;
/* Insert reference samples into first block of Reference Sample
* Interval.
*/
last_in
=
state
->
block_buf
[
0
];
m
=
64
-
strm
->
bit_per_sample
;
prev
=
((
int64_t
)
state
->
block_buf
[
0
]
<<
m
)
>>
m
;
for
(
i
=
1
;
i
<
strm
->
rsi
*
strm
->
block_size
;
i
++
)
{
theta
=
MIN
(
last_in
-
state
->
xmin
,
state
->
xmax
-
last_in
);
Delta
=
(
int64_t
)
state
->
block_buf
[
i
]
-
last_in
;
last_in
=
state
->
block_buf
[
i
];
theta
=
MIN
(
prev
-
state
->
xmin
,
state
->
xmax
-
prev
);
sample
=
((
int64_t
)
state
->
block_buf
[
i
]
<<
m
)
>>
m
;
Delta
=
sample
-
prev
;
prev
=
sample
;
if
(
0
<=
Delta
&&
Delta
<=
theta
)
{
state
->
block_buf
[
i
]
=
2
*
Delta
;
...
...
@@ -196,7 +237,7 @@ static int m_get_block(ae_streamp strm)
state
->
get_block
(
strm
);
if
(
strm
->
flags
&
AE_DATA_PREPROCESS
)
preprocess
(
strm
);
state
->
preprocess
(
strm
);
return
m_check_zero_block
(
strm
);
}
...
...
@@ -270,7 +311,7 @@ static int m_get_block_cautious(ae_streamp strm)
while
(
++
state
->
i
<
strm
->
rsi
*
strm
->
block_size
);
if
(
strm
->
flags
&
AE_DATA_PREPROCESS
)
preprocess
(
strm
);
state
->
preprocess
(
strm
);
return
m_check_zero_block
(
strm
);
}
...
...
@@ -323,16 +364,16 @@ static inline int m_check_zero_block(ae_streamp strm)
static
inline
int
m_select_code_option
(
ae_streamp
strm
)
{
int
i
,
j
,
k
,
this_bs
,
looked_bothways
,
direction
;
int64_t
split_len
,
uncomp_len
;
int64_t
split_len_min
,
fs_len
;
int64_t
d
,
se_len
;
u
int64_t
split_len
,
uncomp_len
;
u
int64_t
split_len_min
,
fs_len
;
u
int64_t
d
,
se_len
;
encode_state
*
state
=
strm
->
state
;
/* Length of this block minus reference sample (if present) */
this_bs
=
strm
->
block_size
-
state
->
ref
;
split_len_min
=
INT64_MAX
;
i
=
state
->
k
;
split_len_min
=
U
INT64_MAX
;
i
=
k
=
state
->
k
;
direction
=
1
;
looked_bothways
=
0
;
...
...
@@ -341,26 +382,26 @@ static inline int m_select_code_option(ae_streamp strm)
*/
for
(;;)
{
fs_len
=
(
int64_t
)(
state
->
block_p
[
1
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
2
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
3
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
4
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
5
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
6
]
>>
i
)
+
(
int64_t
)(
state
->
block_p
[
7
]
>>
i
);
fs_len
=
(
u
int64_t
)(
state
->
block_p
[
1
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
2
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
3
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
4
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
5
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
6
]
>>
i
)
+
(
u
int64_t
)(
state
->
block_p
[
7
]
>>
i
);
if
(
state
->
ref
==
0
)
fs_len
+=
(
int64_t
)(
state
->
block_p
[
0
]
>>
i
);
fs_len
+=
(
u
int64_t
)(
state
->
block_p
[
0
]
>>
i
);
if
(
strm
->
block_size
>
8
)
for
(
j
=
8
;
j
<
strm
->
block_size
;
j
++
)
fs_len
+=
(
int64_t
)(
state
->
block_p
[
j
]
>>
i
);
fs_len
+=
(
u
int64_t
)(
state
->
block_p
[
j
]
>>
i
);
split_len
=
fs_len
+
this_bs
*
(
i
+
1
);
if
(
split_len
<
split_len_min
)
{
if
(
split_len_min
<
INT64_MAX
)
if
(
split_len_min
<
U
INT64_MAX
)
{
/* We are moving towards the minimum so it cant be in
* the other direction.
...
...
@@ -442,16 +483,17 @@ static inline int m_select_code_option(ae_streamp strm)
se_len
=
1
;
for
(
i
=
0
;
i
<
strm
->
block_size
;
i
+=
2
)
{
d
=
(
int64_t
)
state
->
block_p
[
i
]
+
(
int64_t
)
state
->
block_p
[
i
+
1
];
d
=
(
uint64_t
)
state
->
block_p
[
i
]
+
(
uint64_t
)
state
->
block_p
[
i
+
1
];
/* we have to worry about overflow here */
if
(
d
>
split_len_min
)
{
se_len
=
INT64_MAX
;
se_len
=
U
INT64_MAX
;
break
;
}
else
{
se_len
+=
d
*
(
d
+
1
)
/
2
+
(
int64_t
)
state
->
block_p
[
i
+
1
];
se_len
+=
d
*
(
d
+
1
)
/
2
+
(
u
int64_t
)
state
->
block_p
[
i
+
1
];
}
}
...
...
@@ -493,13 +535,18 @@ static inline int m_encode_splitting(ae_streamp strm)
emit
(
state
,
k
+
1
,
state
->
id_len
);
if
(
state
->
ref
)
{
emit
(
state
,
state
->
block_p
[
0
],
strm
->
bit_per_sample
);
for
(
i
=
state
->
ref
;
i
<
strm
->
block_size
;
i
++
)
emitfs
(
state
,
state
->
block_p
[
i
]
>>
k
);
if
(
k
)
emitblock
(
strm
,
k
,
state
->
ref
);
for
(
i
=
1
;
i
<
strm
->
block_size
;
i
++
)
emitfs
(
state
,
state
->
block_p
[
i
]
>>
k
);
if
(
k
)
emitblock_1
(
strm
,
k
);
}
else
{
for
(
i
=
0
;
i
<
strm
->
block_size
;
i
++
)
emitfs
(
state
,
state
->
block_p
[
i
]
>>
k
);
if
(
k
)
emitblock_0
(
strm
,
k
);
}
return
m_flush_block
(
strm
);
}
...
...
@@ -509,7 +556,7 @@ static inline int m_encode_uncomp(ae_streamp strm)
encode_state
*
state
=
strm
->
state
;
emit
(
state
,
(
1
<<
state
->
id_len
)
-
1
,
state
->
id_len
);
emitblock
(
strm
,
strm
->
bit_per_sample
,
0
);
emitblock
_0
(
strm
,
strm
->
bit_per_sample
);
return
m_flush_block
(
strm
);
}
...
...
@@ -674,11 +721,13 @@ int ae_encode_init(ae_streamp strm)
{
state
->
xmin
=
-
(
1ULL
<<
(
strm
->
bit_per_sample
-
1
));
state
->
xmax
=
(
1ULL
<<
(
strm
->
bit_per_sample
-
1
))
-
1
;
state
->
preprocess
=
preprocess_signed
;
}
else
{
state
->
xmin
=
0
;
state
->
xmax
=
(
1ULL
<<
strm
->
bit_per_sample
)
-
1
;
state
->
preprocess
=
preprocess_unsigned
;
}
state
->
block_buf
=
(
uint32_t
*
)
malloc
(
strm
->
rsi
...
...
src/aee.h
View file @
8ee20f33
...
...
@@ -11,6 +11,7 @@ typedef struct internal_state {
int
(
*
mode
)(
ae_streamp
);
void
(
*
get_block
)(
ae_streamp
);
uint32_t
(
*
get_sample
)(
ae_streamp
);
void
(
*
preprocess
)(
ae_streamp
);
int
id_len
;
/* bit length of code option identification key */
int64_t
xmin
;
/* minimum integer for preprocessing */
...
...
src/decode.c
View file @
8ee20f33
...
...
@@ -27,7 +27,7 @@ int main(int argc, char *argv[])
strm
.
flags
=
AE_DATA_MSB
|
AE_DATA_PREPROCESS
;
opterr
=
0
;
while
((
c
=
getopt
(
argc
,
argv
,
"cb:B:J:R:"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"
s
cb:B:J:R:"
))
!=
-
1
)
switch
(
c
)
{
case
'b'
:
...
...
@@ -45,6 +45,9 @@ int main(int argc, char *argv[])
case
'c'
:
cflag
=
1
;
break
;
case
's'
:
strm
.
flags
|=
AE_DATA_SIGNED
;
break
;
case
'?'
:
if
(
optopt
==
'b'
)
fprintf
(
stderr
,
"Option -%c requires an argument.
\n
"
,
optopt
);
...
...
src/encode.c
View file @
8ee20f33
...
...
@@ -27,7 +27,7 @@ int main(int argc, char *argv[])
strm
.
flags
=
AE_DATA_MSB
|
AE_DATA_PREPROCESS
;
opterr
=
0
;
while
((
c
=
getopt
(
argc
,
argv
,
"cb:B:R:J:"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"
s
cb:B:R:J:"
))
!=
-
1
)
switch
(
c
)
{
case
'b'
:
...
...
@@ -45,6 +45,9 @@ int main(int argc, char *argv[])
case
'c'
:
cflag
=
1
;
break
;
case
's'
:
strm
.
flags
|=
AE_DATA_SIGNED
;
break
;
case
'?'
:
if
(
optopt
==
'b'
)
fprintf
(
stderr
,
"Option -%c requires an argument.
\n
"
,
optopt
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment