📄 snow.c
字号:
#define slice_buffer_get_line(slice_buf, line_num) ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] : slice_buffer_load_line((slice_buf), (line_num)))
static void iterative_me(SnowContext *s);
static void slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, DWTELEM * base_buffer)
{
int i;
buf->base_buffer = base_buffer;
buf->line_count = line_count;
buf->line_width = line_width;
buf->data_count = max_allocated_lines;
buf->line = (DWTELEM * *) av_mallocz (sizeof(DWTELEM *) * line_count);
buf->data_stack = (DWTELEM * *) av_malloc (sizeof(DWTELEM *) * max_allocated_lines);
for (i = 0; i < max_allocated_lines; i++)
{
buf->data_stack[i] = (DWTELEM *) av_malloc (sizeof(DWTELEM) * line_width);
}
buf->data_stack_top = max_allocated_lines - 1;
}
static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line)
{
int offset;
DWTELEM * buffer;
assert(buf->data_stack_top >= 0);
if (buf->line[line])
return buf->line[line];
offset = buf->line_width * line;
buffer = buf->data_stack[buf->data_stack_top];
buf->data_stack_top--;
buf->line[line] = buffer;
return buffer;
}
static void slice_buffer_release(slice_buffer * buf, int line)
{
int offset;
DWTELEM * buffer;
assert(line >= 0 && line < buf->line_count);
assert(buf->line[line]);
offset = buf->line_width * line;
buffer = buf->line[line];
buf->data_stack_top++;
buf->data_stack[buf->data_stack_top] = buffer;
buf->line[line] = NULL;
}
static void slice_buffer_flush(slice_buffer * buf)
{
int i;
for (i = 0; i < buf->line_count; i++)
{
if (buf->line[i])
{
slice_buffer_release(buf, i);
}
}
}
static void slice_buffer_destroy(slice_buffer * buf)
{
int i;
slice_buffer_flush(buf);
for (i = buf->data_count - 1; i >= 0; i--)
{
assert(buf->data_stack[i]);
av_freep(&buf->data_stack[i]);
}
assert(buf->data_stack);
av_freep(&buf->data_stack);
assert(buf->line);
av_freep(&buf->line);
}
#ifdef __sgi
// Avoid a name clash on SGI IRIX
#undef qexp
#endif
#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
static uint8_t qexp[QROOT];
static inline int mirror(int v, int m){
while((unsigned)v > (unsigned)m){
v=-v;
if(v<0) v+= 2*m;
}
return v;
}
static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
int i;
if(v){
const int a= FFABS(v);
const int e= av_log2(a);
#if 1
const int el= FFMIN(e, 10);
put_rac(c, state+0, 0);
for(i=0; i<el; i++){
put_rac(c, state+1+i, 1); //1..10
}
for(; i<e; i++){
put_rac(c, state+1+9, 1); //1..10
}
put_rac(c, state+1+FFMIN(i,9), 0);
for(i=e-1; i>=el; i--){
put_rac(c, state+22+9, (a>>i)&1); //22..31
}
for(; i>=0; i--){
put_rac(c, state+22+i, (a>>i)&1); //22..31
}
if(is_signed)
put_rac(c, state+11 + el, v < 0); //11..21
#else
put_rac(c, state+0, 0);
if(e<=9){
for(i=0; i<e; i++){
put_rac(c, state+1+i, 1); //1..10
}
put_rac(c, state+1+i, 0);
for(i=e-1; i>=0; i--){
put_rac(c, state+22+i, (a>>i)&1); //22..31
}
if(is_signed)
put_rac(c, state+11 + e, v < 0); //11..21
}else{
for(i=0; i<e; i++){
put_rac(c, state+1+FFMIN(i,9), 1); //1..10
}
put_rac(c, state+1+FFMIN(i,9), 0);
for(i=e-1; i>=0; i--){
put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
}
if(is_signed)
put_rac(c, state+11 + FFMIN(e,10), v < 0); //11..21
}
#endif
}else{
put_rac(c, state+0, 1);
}
}
static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
if(get_rac(c, state+0))
return 0;
else{
int i, e, a;
e= 0;
while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
e++;
}
a= 1;
for(i=e-1; i>=0; i--){
a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
}
if(is_signed && get_rac(c, state+11 + FFMIN(e,10))) //11..21
return -a;
else
return a;
}
}
static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
int i;
int r= log2>=0 ? 1<<log2 : 1;
assert(v>=0);
assert(log2>=-4);
while(v >= r){
put_rac(c, state+4+log2, 1);
v -= r;
log2++;
if(log2>0) r+=r;
}
put_rac(c, state+4+log2, 0);
for(i=log2-1; i>=0; i--){
put_rac(c, state+31-i, (v>>i)&1);
}
}
static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
int i;
int r= log2>=0 ? 1<<log2 : 1;
int v=0;
assert(log2>=-4);
while(get_rac(c, state+4+log2)){
v+= r;
log2++;
if(log2>0) r+=r;
}
for(i=log2-1; i>=0; i--){
v+= get_rac(c, state+31-i)<<i;
}
return v;
}
static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){
const int mirror_left= !highpass;
const int mirror_right= (width&1) ^ highpass;
const int w= (width>>1) - 1 + (highpass & width);
int i;
#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref)))
if(mirror_left){
dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse);
dst += dst_step;
src += src_step;
}
for(i=0; i<w; i++){
dst[i*dst_step] = LIFT(src[i*src_step], ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift), inverse);
}
if(mirror_right){
dst[w*dst_step] = LIFT(src[w*src_step], ((mul*2*ref[w*ref_step]+add)>>shift), inverse);
}
}
#ifndef lift5
static av_always_inline void lift5(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){
const int mirror_left= !highpass;
const int mirror_right= (width&1) ^ highpass;
const int w= (width>>1) - 1 + (highpass & width);
int i;
if(mirror_left){
int r= 3*2*ref[0];
r += r>>4;
r += r>>8;
dst[0] = LIFT(src[0], ((r+add)>>shift), inverse);
dst += dst_step;
src += src_step;
}
for(i=0; i<w; i++){
int r= 3*(ref[i*ref_step] + ref[(i+1)*ref_step]);
r += r>>4;
r += r>>8;
dst[i*dst_step] = LIFT(src[i*src_step], ((r+add)>>shift), inverse);
}
if(mirror_right){
int r= 3*2*ref[w*ref_step];
r += r>>4;
r += r>>8;
dst[w*dst_step] = LIFT(src[w*src_step], ((r+add)>>shift), inverse);
}
}
#endif
#ifndef liftS
static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){
const int mirror_left= !highpass;
const int mirror_right= (width&1) ^ highpass;
const int w= (width>>1) - 1 + (highpass & width);
int i;
assert(shift == 4);
#define LIFTS(src, ref, inv) ((inv) ? (src) - (((ref) - 4*(src))>>shift): (16*4*(src) + 4*(ref) + 8 + (5<<27))/(5*16) - (1<<23))
if(mirror_left){
dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse);
dst += dst_step;
src += src_step;
}
for(i=0; i<w; i++){
dst[i*dst_step] = LIFTS(src[i*src_step], mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add, inverse);
}
if(mirror_right){
dst[w*dst_step] = LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse);
}
}
#endif
static void inplace_lift(DWTELEM *dst, int width, int *coeffs, int n, int shift, int start, int inverse){
int x, i;
for(x=start; x<width; x+=2){
int64_t sum=0;
for(i=0; i<n; i++){
int x2= x + 2*i - n + 1;
if (x2< 0) x2= -x2;
else if(x2>=width) x2= 2*width-x2-2;
sum += coeffs[i]*(int64_t)dst[x2];
}
if(inverse) dst[x] -= (sum + (1<<shift)/2)>>shift;
else dst[x] += (sum + (1<<shift)/2)>>shift;
}
}
static void inplace_liftV(DWTELEM *dst, int width, int height, int stride, int *coeffs, int n, int shift, int start, int inverse){
int x, y, i;
for(y=start; y<height; y+=2){
for(x=0; x<width; x++){
int64_t sum=0;
for(i=0; i<n; i++){
int y2= y + 2*i - n + 1;
if (y2< 0) y2= -y2;
else if(y2>=height) y2= 2*height-y2-2;
sum += coeffs[i]*(int64_t)dst[x + y2*stride];
}
if(inverse) dst[x + y*stride] -= (sum + (1<<shift)/2)>>shift;
else dst[x + y*stride] += (sum + (1<<shift)/2)>>shift;
}
}
}
#define SCALEX 1
#define LX0 0
#define LX1 1
#define N1 4
#define SHIFT1 4
#define COEFFS1 (int[]){1,-9,-9,1}
#define N2 4
#define SHIFT2 4
#define COEFFS2 (int[]){-1,5,5,-1}
#define N3 0
#define SHIFT3 1
#define COEFFS3 NULL
#define N4 0
#define SHIFT4 1
#define COEFFS4 NULL
static void horizontal_decomposeX(DWTELEM *b, int width){
DWTELEM temp[width];
const int width2= width>>1;
const int w2= (width+1)>>1;
int x;
inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 0);
inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 0);
inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 0);
inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 0);
for(x=0; x<width2; x++){
temp[x ]= b[2*x ];
temp[x+w2]= b[2*x + 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -