4706 lines
167 KiB
C
4706 lines
167 KiB
C
/*
|
|
* Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
|
|
*
|
|
* This file is part of FFmpeg.
|
|
*
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "avcodec.h"
|
|
#include "common.h"
|
|
#include "dsputil.h"
|
|
#include "snow.h"
|
|
|
|
#include "rangecoder.h"
|
|
|
|
#include "mpegvideo.h"
|
|
|
|
#undef NDEBUG
|
|
#include <assert.h>
|
|
|
|
static const int8_t quant3[256]={
|
|
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,
|
|
};
|
|
static const int8_t quant3b[256]={
|
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
|
};
|
|
static const int8_t quant3bA[256]={
|
|
0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
|
|
};
|
|
static const int8_t quant5[256]={
|
|
0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
|
|
};
|
|
static const int8_t quant7[256]={
|
|
0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
|
|
};
|
|
static const int8_t quant9[256]={
|
|
0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
|
|
};
|
|
static const int8_t quant11[256]={
|
|
0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
|
|
-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
|
|
};
|
|
static const int8_t quant13[256]={
|
|
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
|
|
-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
|
|
};
|
|
|
|
#if 0 //64*cubic
|
|
static const uint8_t obmc32[1024]={
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0,
|
|
0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0,
|
|
0, 0, 1, 2, 2, 3, 4, 6, 7, 8, 9,10,11,12,12,12,12,12,12,11,10, 9, 8, 7, 6, 4, 3, 2, 2, 1, 0, 0,
|
|
0, 1, 1, 2, 3, 5, 6, 8,10,11,13,14,15,16,17,18,18,17,16,15,14,13,11,10, 8, 6, 5, 3, 2, 1, 1, 0,
|
|
0, 1, 1, 3, 4, 6, 8,10,13,15,17,19,20,22,22,23,23,22,22,20,19,17,15,13,10, 8, 6, 4, 3, 1, 1, 0,
|
|
0, 1, 2, 4, 6, 8,10,13,16,19,21,23,25,27,28,29,29,28,27,25,23,21,19,16,13,10, 8, 6, 4, 2, 1, 0,
|
|
0, 1, 2, 4, 7,10,13,16,19,22,25,28,31,33,34,35,35,34,33,31,28,25,22,19,16,13,10, 7, 4, 2, 1, 0,
|
|
0, 1, 3, 5, 8,11,15,19,22,26,30,33,36,38,40,41,41,40,38,36,33,30,26,22,19,15,11, 8, 5, 3, 1, 0,
|
|
0, 1, 3, 6, 9,12,17,21,25,30,34,38,41,44,45,46,46,45,44,41,38,34,30,25,21,17,12, 9, 6, 3, 1, 0,
|
|
0, 1, 3, 6,10,14,19,23,28,33,38,42,45,48,51,52,52,51,48,45,42,38,33,28,23,19,14,10, 6, 3, 1, 0,
|
|
0, 1, 4, 7,11,15,20,25,31,36,41,45,49,52,55,56,56,55,52,49,45,41,36,31,25,20,15,11, 7, 4, 1, 0,
|
|
0, 2, 4, 7,12,16,22,27,33,38,44,48,52,56,58,60,60,58,56,52,48,44,38,33,27,22,16,12, 7, 4, 2, 0,
|
|
0, 1, 4, 8,12,17,22,28,34,40,45,51,55,58,61,62,62,61,58,55,51,45,40,34,28,22,17,12, 8, 4, 1, 0,
|
|
0, 2, 4, 8,12,18,23,29,35,41,46,52,56,60,62,64,64,62,60,56,52,46,41,35,29,23,18,12, 8, 4, 2, 0,
|
|
0, 2, 4, 8,12,18,23,29,35,41,46,52,56,60,62,64,64,62,60,56,52,46,41,35,29,23,18,12, 8, 4, 2, 0,
|
|
0, 1, 4, 8,12,17,22,28,34,40,45,51,55,58,61,62,62,61,58,55,51,45,40,34,28,22,17,12, 8, 4, 1, 0,
|
|
0, 2, 4, 7,12,16,22,27,33,38,44,48,52,56,58,60,60,58,56,52,48,44,38,33,27,22,16,12, 7, 4, 2, 0,
|
|
0, 1, 4, 7,11,15,20,25,31,36,41,45,49,52,55,56,56,55,52,49,45,41,36,31,25,20,15,11, 7, 4, 1, 0,
|
|
0, 1, 3, 6,10,14,19,23,28,33,38,42,45,48,51,52,52,51,48,45,42,38,33,28,23,19,14,10, 6, 3, 1, 0,
|
|
0, 1, 3, 6, 9,12,17,21,25,30,34,38,41,44,45,46,46,45,44,41,38,34,30,25,21,17,12, 9, 6, 3, 1, 0,
|
|
0, 1, 3, 5, 8,11,15,19,22,26,30,33,36,38,40,41,41,40,38,36,33,30,26,22,19,15,11, 8, 5, 3, 1, 0,
|
|
0, 1, 2, 4, 7,10,13,16,19,22,25,28,31,33,34,35,35,34,33,31,28,25,22,19,16,13,10, 7, 4, 2, 1, 0,
|
|
0, 1, 2, 4, 6, 8,10,13,16,19,21,23,25,27,28,29,29,28,27,25,23,21,19,16,13,10, 8, 6, 4, 2, 1, 0,
|
|
0, 1, 1, 3, 4, 6, 8,10,13,15,17,19,20,22,22,23,23,22,22,20,19,17,15,13,10, 8, 6, 4, 3, 1, 1, 0,
|
|
0, 1, 1, 2, 3, 5, 6, 8,10,11,13,14,15,16,17,18,18,17,16,15,14,13,11,10, 8, 6, 5, 3, 2, 1, 1, 0,
|
|
0, 0, 1, 2, 2, 3, 4, 6, 7, 8, 9,10,11,12,12,12,12,12,12,11,10, 9, 8, 7, 6, 4, 3, 2, 2, 1, 0, 0,
|
|
0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0,
|
|
0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
//error:0.000022
|
|
};
|
|
static const uint8_t obmc16[256]={
|
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
0, 1, 1, 2, 4, 5, 5, 6, 6, 5, 5, 4, 2, 1, 1, 0,
|
|
0, 1, 4, 6, 9,11,13,15,15,13,11, 9, 6, 4, 1, 0,
|
|
0, 2, 6,11,15,20,24,26,26,24,20,15,11, 6, 2, 0,
|
|
0, 4, 9,15,23,29,34,38,38,34,29,23,15, 9, 4, 0,
|
|
0, 5,11,20,29,38,45,49,49,45,38,29,20,11, 5, 0,
|
|
1, 5,13,24,34,45,53,57,57,53,45,34,24,13, 5, 1,
|
|
1, 6,15,26,38,49,57,62,62,57,49,38,26,15, 6, 1,
|
|
1, 6,15,26,38,49,57,62,62,57,49,38,26,15, 6, 1,
|
|
1, 5,13,24,34,45,53,57,57,53,45,34,24,13, 5, 1,
|
|
0, 5,11,20,29,38,45,49,49,45,38,29,20,11, 5, 0,
|
|
0, 4, 9,15,23,29,34,38,38,34,29,23,15, 9, 4, 0,
|
|
0, 2, 6,11,15,20,24,26,26,24,20,15,11, 6, 2, 0,
|
|
0, 1, 4, 6, 9,11,13,15,15,13,11, 9, 6, 4, 1, 0,
|
|
0, 1, 1, 2, 4, 5, 5, 6, 6, 5, 5, 4, 2, 1, 1, 0,
|
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
//error:0.000033
|
|
};
|
|
#elif 1 // 64*linear
|
|
static const uint8_t obmc32[1024]={
|
|
0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
|
|
0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
|
|
0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
|
|
0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
|
|
4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
|
|
4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
|
|
4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
|
|
4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
|
|
4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
|
|
4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
|
|
4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
|
|
4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
|
|
8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
|
|
8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
|
|
8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
|
|
8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
|
|
8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24, 8,
|
|
8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20, 8,
|
|
8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20, 8,
|
|
8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20, 8,
|
|
4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16, 4,
|
|
4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16, 4,
|
|
4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16, 4,
|
|
4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12, 4,
|
|
4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12, 4,
|
|
4, 8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16, 8, 4,
|
|
4, 8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12, 8, 4,
|
|
4, 8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12, 8, 4,
|
|
0, 4, 8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12, 8, 4, 0,
|
|
0, 4, 8, 8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12, 8, 8, 4, 0,
|
|
0, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12, 8, 8, 8, 4, 4, 4, 0,
|
|
0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0,
|
|
//error:0.000020
|
|
};
|
|
static const uint8_t obmc16[256]={
|
|
0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
|
|
4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
|
|
4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
|
|
8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
|
|
8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
|
|
12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
|
|
12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
|
|
16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
|
|
16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
|
|
12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
|
|
12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
|
|
8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28, 8,
|
|
8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20, 8,
|
|
4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16, 4,
|
|
4, 8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16, 8, 4,
|
|
0, 4, 4, 8, 8, 12, 12, 16, 16, 12, 12, 8, 8, 4, 4, 0,
|
|
//error:0.000015
|
|
};
|
|
#else //64*cos
|
|
static const uint8_t obmc32[1024]={
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0,
|
|
0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 9,10,11,11,12,12,12,12,11,11,10, 9, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0,
|
|
0, 0, 1, 2, 3, 5, 6, 8, 9,11,12,14,15,16,17,17,17,17,16,15,14,12,11, 9, 8, 6, 5, 3, 2, 1, 0, 0,
|
|
0, 1, 1, 2, 4, 6, 8,10,12,15,17,19,20,21,22,23,23,22,21,20,19,17,15,12,10, 8, 6, 4, 2, 1, 1, 0,
|
|
0, 1, 2, 3, 5, 8,10,13,16,19,21,24,26,27,28,29,29,28,27,26,24,21,19,16,13,10, 8, 5, 3, 2, 1, 0,
|
|
0, 1, 2, 4, 6, 9,12,16,19,23,26,29,31,33,34,35,35,34,33,31,29,26,23,19,16,12, 9, 6, 4, 2, 1, 0,
|
|
0, 1, 3, 5, 7,11,15,19,23,26,30,34,37,39,40,41,41,40,39,37,34,30,26,23,19,15,11, 7, 5, 3, 1, 0,
|
|
0, 1, 3, 5, 9,12,17,21,26,30,35,38,42,44,46,47,47,46,44,42,38,35,30,26,21,17,12, 9, 5, 3, 1, 0,
|
|
0, 1, 3, 6, 9,14,19,24,29,34,38,43,46,49,51,52,52,51,49,46,43,38,34,29,24,19,14, 9, 6, 3, 1, 0,
|
|
0, 1, 3, 6,11,15,20,26,31,37,42,46,50,53,56,57,57,56,53,50,46,42,37,31,26,20,15,11, 6, 3, 1, 0,
|
|
0, 1, 3, 7,11,16,21,27,33,39,44,49,53,57,59,60,60,59,57,53,49,44,39,33,27,21,16,11, 7, 3, 1, 0,
|
|
0, 1, 4, 7,12,17,22,28,34,40,46,51,56,59,61,63,63,61,59,56,51,46,40,34,28,22,17,12, 7, 4, 1, 0,
|
|
0, 1, 4, 7,12,17,23,29,35,41,47,52,57,60,63,64,64,63,60,57,52,47,41,35,29,23,17,12, 7, 4, 1, 0,
|
|
0, 1, 4, 7,12,17,23,29,35,41,47,52,57,60,63,64,64,63,60,57,52,47,41,35,29,23,17,12, 7, 4, 1, 0,
|
|
0, 1, 4, 7,12,17,22,28,34,40,46,51,56,59,61,63,63,61,59,56,51,46,40,34,28,22,17,12, 7, 4, 1, 0,
|
|
0, 1, 3, 7,11,16,21,27,33,39,44,49,53,57,59,60,60,59,57,53,49,44,39,33,27,21,16,11, 7, 3, 1, 0,
|
|
0, 1, 3, 6,11,15,20,26,31,37,42,46,50,53,56,57,57,56,53,50,46,42,37,31,26,20,15,11, 6, 3, 1, 0,
|
|
0, 1, 3, 6, 9,14,19,24,29,34,38,43,46,49,51,52,52,51,49,46,43,38,34,29,24,19,14, 9, 6, 3, 1, 0,
|
|
0, 1, 3, 5, 9,12,17,21,26,30,35,38,42,44,46,47,47,46,44,42,38,35,30,26,21,17,12, 9, 5, 3, 1, 0,
|
|
0, 1, 3, 5, 7,11,15,19,23,26,30,34,37,39,40,41,41,40,39,37,34,30,26,23,19,15,11, 7, 5, 3, 1, 0,
|
|
0, 1, 2, 4, 6, 9,12,16,19,23,26,29,31,33,34,35,35,34,33,31,29,26,23,19,16,12, 9, 6, 4, 2, 1, 0,
|
|
0, 1, 2, 3, 5, 8,10,13,16,19,21,24,26,27,28,29,29,28,27,26,24,21,19,16,13,10, 8, 5, 3, 2, 1, 0,
|
|
0, 1, 1, 2, 4, 6, 8,10,12,15,17,19,20,21,22,23,23,22,21,20,19,17,15,12,10, 8, 6, 4, 2, 1, 1, 0,
|
|
0, 0, 1, 2, 3, 5, 6, 8, 9,11,12,14,15,16,17,17,17,17,16,15,14,12,11, 9, 8, 6, 5, 3, 2, 1, 0, 0,
|
|
0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 9,10,11,11,12,12,12,12,11,11,10, 9, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0,
|
|
0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
//error:0.000022
|
|
};
|
|
static const uint8_t obmc16[256]={
|
|
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 4, 3, 2, 1, 0, 0,
|
|
0, 1, 3, 6, 8,11,13,14,14,13,11, 8, 6, 3, 1, 0,
|
|
0, 2, 6,10,15,20,24,26,26,24,20,15,10, 6, 2, 0,
|
|
0, 3, 8,16,23,30,35,38,38,35,30,23,16, 8, 3, 0,
|
|
1, 4,11,20,30,39,46,49,49,46,39,30,20,11, 4, 1,
|
|
1, 5,13,24,35,46,54,58,58,54,46,35,24,13, 5, 1,
|
|
0, 5,14,26,38,49,58,63,63,58,49,38,26,14, 5, 0,
|
|
0, 5,14,26,38,49,58,63,63,58,49,38,26,14, 5, 0,
|
|
1, 5,13,24,35,46,54,58,58,54,46,35,24,13, 5, 1,
|
|
1, 4,11,20,30,39,46,49,49,46,39,30,20,11, 4, 1,
|
|
0, 3, 8,16,23,30,35,38,38,35,30,23,16, 8, 3, 0,
|
|
0, 2, 6,10,15,20,24,26,26,24,20,15,10, 6, 2, 0,
|
|
0, 1, 3, 6, 8,11,13,14,14,13,11, 8, 6, 3, 1, 0,
|
|
0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 4, 3, 2, 1, 0, 0,
|
|
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
|
//error:0.000022
|
|
};
|
|
#endif
|
|
|
|
//linear *64
|
|
static const uint8_t obmc8[64]={
|
|
4, 12, 20, 28, 28, 20, 12, 4,
|
|
12, 36, 60, 84, 84, 60, 36, 12,
|
|
20, 60,100,140,140,100, 60, 20,
|
|
28, 84,140,196,196,140, 84, 28,
|
|
28, 84,140,196,196,140, 84, 28,
|
|
20, 60,100,140,140,100, 60, 20,
|
|
12, 36, 60, 84, 84, 60, 36, 12,
|
|
4, 12, 20, 28, 28, 20, 12, 4,
|
|
//error:0.000000
|
|
};
|
|
|
|
//linear *64
|
|
static const uint8_t obmc4[16]={
|
|
16, 48, 48, 16,
|
|
48,144,144, 48,
|
|
48,144,144, 48,
|
|
16, 48, 48, 16,
|
|
//error:0.000000
|
|
};
|
|
|
|
static const uint8_t *obmc_tab[4]={
|
|
obmc32, obmc16, obmc8, obmc4
|
|
};
|
|
|
|
static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
|
|
|
|
typedef struct BlockNode{
|
|
int16_t mx;
|
|
int16_t my;
|
|
uint8_t ref;
|
|
uint8_t color[3];
|
|
uint8_t type;
|
|
//#define TYPE_SPLIT 1
|
|
#define BLOCK_INTRA 1
|
|
#define BLOCK_OPT 2
|
|
//#define TYPE_NOCOLOR 4
|
|
uint8_t level; //FIXME merge into type?
|
|
}BlockNode;
|
|
|
|
static const BlockNode null_block= { //FIXME add border maybe
|
|
.color= {128,128,128},
|
|
.mx= 0,
|
|
.my= 0,
|
|
.ref= 0,
|
|
.type= 0,
|
|
.level= 0,
|
|
};
|
|
|
|
#define LOG2_MB_SIZE 4
|
|
#define MB_SIZE (1<<LOG2_MB_SIZE)
|
|
|
|
typedef struct x_and_coeff{
|
|
int16_t x;
|
|
uint16_t coeff;
|
|
} x_and_coeff;
|
|
|
|
typedef struct SubBand{
|
|
int level;
|
|
int stride;
|
|
int width;
|
|
int height;
|
|
int qlog; ///< log(qscale)/log[2^(1/6)]
|
|
DWTELEM *buf;
|
|
int buf_x_offset;
|
|
int buf_y_offset;
|
|
int stride_line; ///< Stride measured in lines, not pixels.
|
|
x_and_coeff * x_coeff;
|
|
struct SubBand *parent;
|
|
uint8_t state[/*7*2*/ 7 + 512][32];
|
|
}SubBand;
|
|
|
|
typedef struct Plane{
|
|
int width;
|
|
int height;
|
|
SubBand band[MAX_DECOMPOSITIONS][4];
|
|
}Plane;
|
|
|
|
typedef struct SnowContext{
|
|
// MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independant of MpegEncContext, so this will be removed then (FIXME/XXX)
|
|
|
|
AVCodecContext *avctx;
|
|
RangeCoder c;
|
|
DSPContext dsp;
|
|
AVFrame new_picture;
|
|
AVFrame input_picture; ///< new_picture with the internal linesizes
|
|
AVFrame current_picture;
|
|
AVFrame last_picture[MAX_REF_FRAMES];
|
|
AVFrame mconly_picture;
|
|
// uint8_t q_context[16];
|
|
uint8_t header_state[32];
|
|
uint8_t block_state[128 + 32*128];
|
|
int keyframe;
|
|
int always_reset;
|
|
int version;
|
|
int spatial_decomposition_type;
|
|
int last_spatial_decomposition_type;
|
|
int temporal_decomposition_type;
|
|
int spatial_decomposition_count;
|
|
int temporal_decomposition_count;
|
|
int max_ref_frames;
|
|
int ref_frames;
|
|
int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
|
|
uint32_t *ref_scores[MAX_REF_FRAMES];
|
|
DWTELEM *spatial_dwt_buffer;
|
|
int colorspace_type;
|
|
int chroma_h_shift;
|
|
int chroma_v_shift;
|
|
int spatial_scalability;
|
|
int qlog;
|
|
int last_qlog;
|
|
int lambda;
|
|
int lambda2;
|
|
int pass1_rc;
|
|
int mv_scale;
|
|
int last_mv_scale;
|
|
int qbias;
|
|
int last_qbias;
|
|
#define QBIAS_SHIFT 3
|
|
int b_width;
|
|
int b_height;
|
|
int block_max_depth;
|
|
int last_block_max_depth;
|
|
Plane plane[MAX_PLANES];
|
|
BlockNode *block;
|
|
#define ME_CACHE_SIZE 1024
|
|
int me_cache[ME_CACHE_SIZE];
|
|
int me_cache_generation;
|
|
slice_buffer sb;
|
|
|
|
MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independant of MpegEncContext, so this will be removed then (FIXME/XXX)
|
|
}SnowContext;
|
|
|
|
typedef struct {
|
|
DWTELEM *b0;
|
|
DWTELEM *b1;
|
|
DWTELEM *b2;
|
|
DWTELEM *b3;
|
|
int y;
|
|
} dwt_compose_t;
|
|
|
|
#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)))
|
|
//#define slice_buffer_get_line(slice_buf, 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;
|
|
|
|
// av_log(NULL, AV_LOG_DEBUG, "Cache hit: %d\n", line);
|
|
|
|
assert(buf->data_stack_top >= 0);
|
|
// assert(!buf->line[line]);
|
|
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;
|
|
|
|
// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_load_line: line: %d remaining: %d\n", line, buf->data_stack_top + 1);
|
|
|
|
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;
|
|
|
|
// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_release: line: %d remaining: %d\n", line, buf->data_stack_top + 1);
|
|
}
|
|
|
|
static void slice_buffer_flush(slice_buffer * buf)
|
|
{
|
|
int i;
|
|
for (i = 0; i < buf->line_count; i++)
|
|
{
|
|
if (buf->line[i])
|
|
{
|
|
// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_flush: line: %d \n", 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
|
|
|
|
#if 0 // more accurate 9/7
|
|
#define N1 2
|
|
#define SHIFT1 14
|
|
#define COEFFS1 (int[]){-25987,-25987}
|
|
#define N2 2
|
|
#define SHIFT2 19
|
|
#define COEFFS2 (int[]){-27777,-27777}
|
|
#define N3 2
|
|
#define SHIFT3 15
|
|
#define COEFFS3 (int[]){28931,28931}
|
|
#define N4 2
|
|
#define SHIFT4 15
|
|
#define COEFFS4 (int[]){14533,14533}
|
|
#elif 1 // 13/7 CRF
|
|
#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
|
|
#elif 1 // 3/5
|
|
#define LX0 1
|
|
#define LX1 0
|
|
#define SCALEX 0.5
|
|
#define N1 2
|
|
#define SHIFT1 1
|
|
#define COEFFS1 (int[]){1,1}
|
|
#define N2 2
|
|
#define SHIFT2 2
|
|
#define COEFFS2 (int[]){-1,-1}
|
|
#define N3 0
|
|
#define SHIFT3 0
|
|
#define COEFFS3 NULL
|
|
#define N4 0
|
|
#define SHIFT4 0
|
|
#define COEFFS4 NULL
|
|
#elif 1 // 11/5
|
|
#define N1 0
|
|
#define SHIFT1 1
|
|
#define COEFFS1 NULL
|
|
#define N2 2
|
|
#define SHIFT2 2
|
|
#define COEFFS2 (int[]){-1,-1}
|
|
#define N3 2
|
|
#define SHIFT3 0
|
|
#define COEFFS3 (int[]){-1,-1}
|
|
#define N4 4
|
|
#define SHIFT4 7
|
|
#define COEFFS4 (int[]){-5,29,29,-5}
|
|
#define SCALEX 4
|
|
#elif 1 // 9/7 CDF
|
|
#define N1 2
|
|
#define SHIFT1 7
|
|
#define COEFFS1 (int[]){-203,-203}
|
|
#define N2 2
|
|
#define SHIFT2 12
|
|
#define COEFFS2 (int[]){-217,-217}
|
|
#define N3 2
|
|
#define SHIFT3 7
|
|
#define COEFFS3 (int[]){113,113}
|
|
#define N4 2
|
|
#define SHIFT4 9
|
|
#define COEFFS4 (int[]){227,227}
|
|
#define SCALEX 1
|
|
#elif 1 // 7/5 CDF
|
|
#define N1 0
|
|
#define SHIFT1 1
|
|
#define COEFFS1 NULL
|
|
#define N2 2
|
|
#define SHIFT2 2
|
|
#define COEFFS2 (int[]){-1,-1}
|
|
#define N3 2
|
|
#define SHIFT3 0
|
|
#define COEFFS3 (int[]){-1,-1}
|
|
#define N4 2
|
|
#define SHIFT4 4
|
|
#define COEFFS4 (int[]){3,3}
|
|
#elif 1 // 9/7 MN
|
|
#define N1 4
|
|
#define SHIFT1 4
|
|
#define COEFFS1 (int[]){1,-9,-9,1}
|
|
#define N2 2
|
|
#define SHIFT2 2
|
|
#define COEFFS2 (int[]){1,1}
|
|
#define N3 0
|
|
#define SHIFT3 1
|
|
#define COEFFS3 NULL
|
|
#define N4 0
|
|
#define SHIFT4 1
|
|
#define COEFFS4 NULL
|
|
#else // 13/7 CRF
|
|
#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
|
|
#endif
|
|
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];
|
|
}
|
|
if(width&1)
|
|
temp[x ]= b[2*x ];
|
|
memcpy(b, temp, width*sizeof(int));
|
|
}
|
|
|
|
static void horizontal_composeX(DWTELEM *b, int width){
|
|
DWTELEM temp[width];
|
|
const int width2= width>>1;
|
|
int x;
|
|
const int w2= (width+1)>>1;
|
|
|
|
memcpy(temp, b, width*sizeof(int));
|
|
for(x=0; x<width2; x++){
|
|
b[2*x ]= temp[x ];
|
|
b[2*x + 1]= temp[x+w2];
|
|
}
|
|
if(width&1)
|
|
b[2*x ]= temp[x ];
|
|
|
|
inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 1);
|
|
inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 1);
|
|
inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 1);
|
|
inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 1);
|
|
}
|
|
|
|
static void spatial_decomposeX(DWTELEM *buffer, int width, int height, int stride){
|
|
int x, y;
|
|
|
|
for(y=0; y<height; y++){
|
|
for(x=0; x<width; x++){
|
|
buffer[y*stride + x] *= SCALEX;
|
|
}
|
|
}
|
|
|
|
for(y=0; y<height; y++){
|
|
horizontal_decomposeX(buffer + y*stride, width);
|
|
}
|
|
|
|
inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 0);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 0);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 0);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 0);
|
|
}
|
|
|
|
static void spatial_composeX(DWTELEM *buffer, int width, int height, int stride){
|
|
int x, y;
|
|
|
|
inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 1);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 1);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 1);
|
|
inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 1);
|
|
|
|
for(y=0; y<height; y++){
|
|
horizontal_composeX(buffer + y*stride, width);
|
|
}
|
|
|
|
for(y=0; y<height; y++){
|
|
for(x=0; x<width; x++){
|
|
buffer[y*stride + x] /= SCALEX;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void horizontal_decompose53i(DWTELEM *b, int width){
|
|
DWTELEM temp[width];
|
|
const int width2= width>>1;
|
|
int x;
|
|
const int w2= (width+1)>>1;
|
|
|
|
for(x=0; x<width2; x++){
|
|
temp[x ]= b[2*x ];
|
|
temp[x+w2]= b[2*x + 1];
|
|
}
|
|
if(width&1)
|
|
temp[x ]= b[2*x ];
|
|
#if 0
|
|
{
|
|
int A1,A2,A3,A4;
|
|
A2= temp[1 ];
|
|
A4= temp[0 ];
|
|
A1= temp[0+width2];
|
|
A1 -= (A2 + A4)>>1;
|
|
A4 += (A1 + 1)>>1;
|
|
b[0+width2] = A1;
|
|
b[0 ] = A4;
|
|
for(x=1; x+1<width2; x+=2){
|
|
A3= temp[x+width2];
|
|
A4= temp[x+1 ];
|
|
A3 -= (A2 + A4)>>1;
|
|
A2 += (A1 + A3 + 2)>>2;
|
|
b[x+width2] = A3;
|
|
b[x ] = A2;
|
|
|
|
A1= temp[x+1+width2];
|
|
A2= temp[x+2 ];
|
|
A1 -= (A2 + A4)>>1;
|
|
A4 += (A1 + A3 + 2)>>2;
|
|
b[x+1+width2] = A1;
|
|
b[x+1 ] = A4;
|
|
}
|
|
A3= temp[width-1];
|
|
A3 -= A2;
|
|
A2 += (A1 + A3 + 2)>>2;
|
|
b[width -1] = A3;
|
|
b[width2-1] = A2;
|
|
}
|
|
#else
|
|
lift(b+w2, temp+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
|
|
lift(b , temp , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
|
|
#endif
|
|
}
|
|
|
|
static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] -= (b0[i] + b2[i])>>1;
|
|
}
|
|
}
|
|
|
|
static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] += (b0[i] + b2[i] + 2)>>2;
|
|
}
|
|
}
|
|
|
|
static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int stride){
|
|
int y;
|
|
DWTELEM *b0= buffer + mirror(-2-1, height-1)*stride;
|
|
DWTELEM *b1= buffer + mirror(-2 , height-1)*stride;
|
|
|
|
for(y=-2; y<height; y+=2){
|
|
DWTELEM *b2= buffer + mirror(y+1, height-1)*stride;
|
|
DWTELEM *b3= buffer + mirror(y+2, height-1)*stride;
|
|
|
|
{START_TIMER
|
|
if(y+1<(unsigned)height) horizontal_decompose53i(b2, width);
|
|
if(y+2<(unsigned)height) horizontal_decompose53i(b3, width);
|
|
STOP_TIMER("horizontal_decompose53i")}
|
|
|
|
{START_TIMER
|
|
if(y+1<(unsigned)height) vertical_decompose53iH0(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_decompose53iL0(b0, b1, b2, width);
|
|
STOP_TIMER("vertical_decompose53i*")}
|
|
|
|
b0=b2;
|
|
b1=b3;
|
|
}
|
|
}
|
|
|
|
static void horizontal_decompose97i(DWTELEM *b, int width){
|
|
DWTELEM temp[width];
|
|
const int w2= (width+1)>>1;
|
|
|
|
lift (temp+w2, b +1, b , 1, 2, 2, width, -W_AM, W_AO, W_AS, 1, 0);
|
|
liftS(temp , b , temp+w2, 1, 2, 1, width, -W_BM, W_BO, W_BS, 0, 0);
|
|
lift5(b +w2, temp+w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
|
|
lift (b , temp , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
|
|
}
|
|
|
|
|
|
static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] -= (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
|
|
}
|
|
}
|
|
|
|
static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
#ifdef lift5
|
|
b1[i] += (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
|
|
#else
|
|
int r= 3*(b0[i] + b2[i]);
|
|
r+= r>>4;
|
|
r+= r>>8;
|
|
b1[i] += (r+W_CO)>>W_CS;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
#ifdef liftS
|
|
b1[i] -= (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS;
|
|
#else
|
|
b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + 8*5 + (5<<27)) / (5*16) - (1<<23);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] += (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS;
|
|
}
|
|
}
|
|
|
|
static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int stride){
|
|
int y;
|
|
DWTELEM *b0= buffer + mirror(-4-1, height-1)*stride;
|
|
DWTELEM *b1= buffer + mirror(-4 , height-1)*stride;
|
|
DWTELEM *b2= buffer + mirror(-4+1, height-1)*stride;
|
|
DWTELEM *b3= buffer + mirror(-4+2, height-1)*stride;
|
|
|
|
for(y=-4; y<height; y+=2){
|
|
DWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
|
|
DWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
|
|
|
|
{START_TIMER
|
|
if(y+3<(unsigned)height) horizontal_decompose97i(b4, width);
|
|
if(y+4<(unsigned)height) horizontal_decompose97i(b5, width);
|
|
if(width>400){
|
|
STOP_TIMER("horizontal_decompose97i")
|
|
}}
|
|
|
|
{START_TIMER
|
|
if(y+3<(unsigned)height) vertical_decompose97iH0(b3, b4, b5, width);
|
|
if(y+2<(unsigned)height) vertical_decompose97iL0(b2, b3, b4, width);
|
|
if(y+1<(unsigned)height) vertical_decompose97iH1(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_decompose97iL1(b0, b1, b2, width);
|
|
|
|
if(width>400){
|
|
STOP_TIMER("vertical_decompose97i")
|
|
}}
|
|
|
|
b0=b2;
|
|
b1=b3;
|
|
b2=b4;
|
|
b3=b5;
|
|
}
|
|
}
|
|
|
|
void ff_spatial_dwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
|
|
int level;
|
|
|
|
for(level=0; level<decomposition_count; level++){
|
|
switch(type){
|
|
case DWT_97: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break;
|
|
case DWT_53: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break;
|
|
case DWT_X: spatial_decomposeX (buffer, width>>level, height>>level, stride<<level); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void horizontal_compose53i(DWTELEM *b, int width){
|
|
DWTELEM temp[width];
|
|
const int width2= width>>1;
|
|
const int w2= (width+1)>>1;
|
|
int x;
|
|
|
|
#if 0
|
|
int A1,A2,A3,A4;
|
|
A2= temp[1 ];
|
|
A4= temp[0 ];
|
|
A1= temp[0+width2];
|
|
A1 -= (A2 + A4)>>1;
|
|
A4 += (A1 + 1)>>1;
|
|
b[0+width2] = A1;
|
|
b[0 ] = A4;
|
|
for(x=1; x+1<width2; x+=2){
|
|
A3= temp[x+width2];
|
|
A4= temp[x+1 ];
|
|
A3 -= (A2 + A4)>>1;
|
|
A2 += (A1 + A3 + 2)>>2;
|
|
b[x+width2] = A3;
|
|
b[x ] = A2;
|
|
|
|
A1= temp[x+1+width2];
|
|
A2= temp[x+2 ];
|
|
A1 -= (A2 + A4)>>1;
|
|
A4 += (A1 + A3 + 2)>>2;
|
|
b[x+1+width2] = A1;
|
|
b[x+1 ] = A4;
|
|
}
|
|
A3= temp[width-1];
|
|
A3 -= A2;
|
|
A2 += (A1 + A3 + 2)>>2;
|
|
b[width -1] = A3;
|
|
b[width2-1] = A2;
|
|
#else
|
|
lift(temp , b , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 1);
|
|
lift(temp+w2, b+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 1);
|
|
#endif
|
|
for(x=0; x<width2; x++){
|
|
b[2*x ]= temp[x ];
|
|
b[2*x + 1]= temp[x+w2];
|
|
}
|
|
if(width&1)
|
|
b[2*x ]= temp[x ];
|
|
}
|
|
|
|
static void vertical_compose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] += (b0[i] + b2[i])>>1;
|
|
}
|
|
}
|
|
|
|
static void vertical_compose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] -= (b0[i] + b2[i] + 2)>>2;
|
|
}
|
|
}
|
|
|
|
static void spatial_compose53i_buffered_init(dwt_compose_t *cs, slice_buffer * sb, int height, int stride_line){
|
|
cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height-1) * stride_line);
|
|
cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height-1) * stride_line);
|
|
cs->y = -1;
|
|
}
|
|
|
|
static void spatial_compose53i_init(dwt_compose_t *cs, DWTELEM *buffer, int height, int stride){
|
|
cs->b0 = buffer + mirror(-1-1, height-1)*stride;
|
|
cs->b1 = buffer + mirror(-1 , height-1)*stride;
|
|
cs->y = -1;
|
|
}
|
|
|
|
static void spatial_compose53i_dy_buffered(dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){
|
|
int y= cs->y;
|
|
|
|
DWTELEM *b0= cs->b0;
|
|
DWTELEM *b1= cs->b1;
|
|
DWTELEM *b2= slice_buffer_get_line(sb, mirror(y+1, height-1) * stride_line);
|
|
DWTELEM *b3= slice_buffer_get_line(sb, mirror(y+2, height-1) * stride_line);
|
|
|
|
{START_TIMER
|
|
if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
|
|
STOP_TIMER("vertical_compose53i*")}
|
|
|
|
{START_TIMER
|
|
if(y-1<(unsigned)height) horizontal_compose53i(b0, width);
|
|
if(y+0<(unsigned)height) horizontal_compose53i(b1, width);
|
|
STOP_TIMER("horizontal_compose53i")}
|
|
|
|
cs->b0 = b2;
|
|
cs->b1 = b3;
|
|
cs->y += 2;
|
|
}
|
|
|
|
static void spatial_compose53i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){
|
|
int y= cs->y;
|
|
DWTELEM *b0= cs->b0;
|
|
DWTELEM *b1= cs->b1;
|
|
DWTELEM *b2= buffer + mirror(y+1, height-1)*stride;
|
|
DWTELEM *b3= buffer + mirror(y+2, height-1)*stride;
|
|
|
|
{START_TIMER
|
|
if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width);
|
|
STOP_TIMER("vertical_compose53i*")}
|
|
|
|
{START_TIMER
|
|
if(y-1<(unsigned)height) horizontal_compose53i(b0, width);
|
|
if(y+0<(unsigned)height) horizontal_compose53i(b1, width);
|
|
STOP_TIMER("horizontal_compose53i")}
|
|
|
|
cs->b0 = b2;
|
|
cs->b1 = b3;
|
|
cs->y += 2;
|
|
}
|
|
|
|
static void spatial_compose53i(DWTELEM *buffer, int width, int height, int stride){
|
|
dwt_compose_t cs;
|
|
spatial_compose53i_init(&cs, buffer, height, stride);
|
|
while(cs.y <= height)
|
|
spatial_compose53i_dy(&cs, buffer, width, height, stride);
|
|
}
|
|
|
|
|
|
void ff_snow_horizontal_compose97i(DWTELEM *b, int width){
|
|
DWTELEM temp[width];
|
|
const int w2= (width+1)>>1;
|
|
|
|
lift (temp , b , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 1);
|
|
lift5(temp+w2, b +w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 1);
|
|
liftS(b , temp , temp+w2, 2, 1, 1, width, -W_BM, W_BO, W_BS, 0, 1);
|
|
lift (b+1 , temp+w2, b , 2, 1, 2, width, -W_AM, W_AO, W_AS, 1, 1);
|
|
}
|
|
|
|
static void vertical_compose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
|
|
}
|
|
}
|
|
|
|
static void vertical_compose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
#ifdef lift5
|
|
b1[i] -= (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS;
|
|
#else
|
|
int r= 3*(b0[i] + b2[i]);
|
|
r+= r>>4;
|
|
r+= r>>8;
|
|
b1[i] -= (r+W_CO)>>W_CS;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void vertical_compose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
#ifdef liftS
|
|
b1[i] += (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS;
|
|
#else
|
|
b1[i] += (W_BM*(b0[i] + b2[i])+4*b1[i]+W_BO)>>W_BS;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void vertical_compose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
b1[i] -= (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS;
|
|
}
|
|
}
|
|
|
|
void ff_snow_vertical_compose97i(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){
|
|
int i;
|
|
|
|
for(i=0; i<width; i++){
|
|
#ifndef lift5
|
|
int r;
|
|
#endif
|
|
b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
|
|
#ifdef lift5
|
|
b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
|
|
#else
|
|
r= 3*(b2[i] + b4[i]);
|
|
r+= r>>4;
|
|
r+= r>>8;
|
|
b3[i] -= (r+W_CO)>>W_CS;
|
|
#endif
|
|
#ifdef liftS
|
|
b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS;
|
|
#else
|
|
b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
|
|
#endif
|
|
b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
|
|
}
|
|
}
|
|
|
|
static void spatial_compose97i_buffered_init(dwt_compose_t *cs, slice_buffer * sb, int height, int stride_line){
|
|
cs->b0 = slice_buffer_get_line(sb, mirror(-3-1, height-1) * stride_line);
|
|
cs->b1 = slice_buffer_get_line(sb, mirror(-3 , height-1) * stride_line);
|
|
cs->b2 = slice_buffer_get_line(sb, mirror(-3+1, height-1) * stride_line);
|
|
cs->b3 = slice_buffer_get_line(sb, mirror(-3+2, height-1) * stride_line);
|
|
cs->y = -3;
|
|
}
|
|
|
|
static void spatial_compose97i_init(dwt_compose_t *cs, DWTELEM *buffer, int height, int stride){
|
|
cs->b0 = buffer + mirror(-3-1, height-1)*stride;
|
|
cs->b1 = buffer + mirror(-3 , height-1)*stride;
|
|
cs->b2 = buffer + mirror(-3+1, height-1)*stride;
|
|
cs->b3 = buffer + mirror(-3+2, height-1)*stride;
|
|
cs->y = -3;
|
|
}
|
|
|
|
static void spatial_compose97i_dy_buffered(DSPContext *dsp, dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){
|
|
int y = cs->y;
|
|
|
|
DWTELEM *b0= cs->b0;
|
|
DWTELEM *b1= cs->b1;
|
|
DWTELEM *b2= cs->b2;
|
|
DWTELEM *b3= cs->b3;
|
|
DWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line);
|
|
DWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line);
|
|
|
|
{START_TIMER
|
|
if(y>0 && y+4<height){
|
|
dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
|
|
}else{
|
|
if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
|
|
if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
|
|
if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
|
|
}
|
|
if(width>400){
|
|
STOP_TIMER("vertical_compose97i")}}
|
|
|
|
{START_TIMER
|
|
if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width);
|
|
if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width);
|
|
if(width>400 && y+0<(unsigned)height){
|
|
STOP_TIMER("horizontal_compose97i")}}
|
|
|
|
cs->b0=b2;
|
|
cs->b1=b3;
|
|
cs->b2=b4;
|
|
cs->b3=b5;
|
|
cs->y += 2;
|
|
}
|
|
|
|
static void spatial_compose97i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){
|
|
int y = cs->y;
|
|
DWTELEM *b0= cs->b0;
|
|
DWTELEM *b1= cs->b1;
|
|
DWTELEM *b2= cs->b2;
|
|
DWTELEM *b3= cs->b3;
|
|
DWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
|
|
DWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
|
|
|
|
{START_TIMER
|
|
if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
|
|
if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
|
|
if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
|
|
if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
|
|
if(width>400){
|
|
STOP_TIMER("vertical_compose97i")}}
|
|
|
|
{START_TIMER
|
|
if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width);
|
|
if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width);
|
|
if(width>400 && b0 <= b2){
|
|
STOP_TIMER("horizontal_compose97i")}}
|
|
|
|
cs->b0=b2;
|
|
cs->b1=b3;
|
|
cs->b2=b4;
|
|
cs->b3=b5;
|
|
cs->y += 2;
|
|
}
|
|
|
|
static void spatial_compose97i(DWTELEM *buffer, int width, int height, int stride){
|
|
dwt_compose_t cs;
|
|
spatial_compose97i_init(&cs, buffer, height, stride);
|
|
while(cs.y <= height)
|
|
spatial_compose97i_dy(&cs, buffer, width, height, stride);
|
|
}
|
|
|
|
static void ff_spatial_idwt_buffered_init(dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count){
|
|
int level;
|
|
for(level=decomposition_count-1; level>=0; level--){
|
|
switch(type){
|
|
case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
|
|
case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
|
|
/* not slicified yet */
|
|
case DWT_X: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/
|
|
av_log(NULL, AV_LOG_ERROR, "spatial_composeX neither buffered nor slicified yet.\n"); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ff_spatial_idwt_init(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
|
|
int level;
|
|
for(level=decomposition_count-1; level>=0; level--){
|
|
switch(type){
|
|
case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
|
|
case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
|
|
/* not slicified yet */
|
|
case DWT_X: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ff_spatial_idwt_slice(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){
|
|
const int support = type==1 ? 3 : 5;
|
|
int level;
|
|
if(type==2) return;
|
|
|
|
for(level=decomposition_count-1; level>=0; level--){
|
|
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
|
|
switch(type){
|
|
case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
|
|
break;
|
|
case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
|
|
break;
|
|
case DWT_X: break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ff_spatial_idwt_buffered_slice(DSPContext *dsp, dwt_compose_t *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y){
|
|
const int support = type==1 ? 3 : 5;
|
|
int level;
|
|
if(type==2) return;
|
|
|
|
for(level=decomposition_count-1; level>=0; level--){
|
|
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
|
|
switch(type){
|
|
case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
|
|
break;
|
|
case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
|
|
break;
|
|
case DWT_X: break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ff_spatial_idwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
|
|
if(type==2){
|
|
int level;
|
|
for(level=decomposition_count-1; level>=0; level--)
|
|
spatial_composeX (buffer, width>>level, height>>level, stride<<level);
|
|
}else{
|
|
dwt_compose_t cs[MAX_DECOMPOSITIONS];
|
|
int y;
|
|
ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count);
|
|
for(y=0; y<height; y+=4)
|
|
ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y);
|
|
}
|
|
}
|
|
|
|
static int encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){
|
|
const int w= b->width;
|
|
const int h= b->height;
|
|
int x, y;
|
|
|
|
if(1){
|
|
int run=0;
|
|
int runs[w*h];
|
|
int run_index=0;
|
|
int max_index;
|
|
|
|
for(y=0; y<h; y++){
|
|
for(x=0; x<w; x++){
|
|
int v, p=0;
|
|
int /*ll=0, */l=0, lt=0, t=0, rt=0;
|
|
v= src[x + y*stride];
|
|
|
|
if(y){
|
|
t= src[x + (y-1)*stride];
|
|
if(x){
|
|
lt= src[x - 1 + (y-1)*stride];
|
|
}
|
|
if(x + 1 < w){
|
|