2 * Lossless video DSP utils
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "lossless_videodsp.h"
22 #include "libavcodec/mathops.h"
24 static void add_int16_c(uint16_t *dst
, const uint16_t *src
, unsigned mask
, int w
){
26 unsigned long pw_lsb
= (mask
>> 1) * 0x0001000100010001ULL
;
27 unsigned long pw_msb
= pw_lsb
+ 0x0001000100010001ULL
;
28 for (i
= 0; i
<= w
- (int)sizeof(long)/2; i
+= sizeof(long)/2) {
29 long a
= *(long*)(src
+i
);
30 long b
= *(long*)(dst
+i
);
31 *(long*)(dst
+i
) = ((a
&pw_lsb
) + (b
&pw_lsb
)) ^ ((a
^b
)&pw_msb
);
34 dst
[i
] = (dst
[i
] + src
[i
]) & mask
;
37 static void diff_int16_c(uint16_t *dst
, const uint16_t *src1
, const uint16_t *src2
, unsigned mask
, int w
){
39 #if !HAVE_FAST_UNALIGNED
40 if((long)src2
& (sizeof(long)-1)){
41 for(i
=0; i
+3<w
; i
+=4){
42 dst
[i
+0] = (src1
[i
+0]-src2
[i
+0]) & mask
;
43 dst
[i
+1] = (src1
[i
+1]-src2
[i
+1]) & mask
;
44 dst
[i
+2] = (src1
[i
+2]-src2
[i
+2]) & mask
;
45 dst
[i
+3] = (src1
[i
+3]-src2
[i
+3]) & mask
;
50 unsigned long pw_lsb
= (mask
>> 1) * 0x0001000100010001ULL
;
51 unsigned long pw_msb
= pw_lsb
+ 0x0001000100010001ULL
;
53 for (i
= 0; i
<= w
- (int)sizeof(long)/2; i
+= sizeof(long)/2) {
54 long a
= *(long*)(src1
+i
);
55 long b
= *(long*)(src2
+i
);
56 *(long*)(dst
+i
) = ((a
|pw_msb
) - (b
&pw_lsb
)) ^ ((a
^b
^pw_msb
)&pw_msb
);
60 dst
[i
] = (src1
[i
] - src2
[i
]) & mask
;
63 static void add_hfyu_median_pred_int16_c(uint16_t *dst
, const uint16_t *src
, const uint16_t *diff
, unsigned mask
, int w
, int *left
, int *left_top
){
71 l
= (mid_pred(l
, src
[i
], (l
+ src
[i
] - lt
) & mask
) + diff
[i
]) & mask
;
80 static void sub_hfyu_median_pred_int16_c(uint16_t *dst
, const uint16_t *src1
, const uint16_t *src2
, unsigned mask
, int w
, int *left
, int *left_top
){
88 const int pred
= mid_pred(l
, src1
[i
], (l
+ src1
[i
] - lt
) & mask
);
91 dst
[i
] = (l
- pred
) & mask
;
98 static int add_hfyu_left_pred_int16_c(uint16_t *dst
, const uint16_t *src
, unsigned mask
, int w
, unsigned acc
){
101 for(i
=0; i
<w
-1; i
++){
118 void ff_llviddsp_init(LLVidDSPContext
*c
, AVCodecContext
*avctx
)
120 c
->add_int16
= add_int16_c
;
121 c
->diff_int16
= diff_int16_c
;
122 c
->add_hfyu_left_pred_int16
= add_hfyu_left_pred_int16_c
;
123 c
->add_hfyu_median_pred_int16
= add_hfyu_median_pred_int16_c
;
124 c
->sub_hfyu_median_pred_int16
= sub_hfyu_median_pred_int16_c
;
127 ff_llviddsp_init_x86(c
, avctx
);