Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / lossless_videodsp.c
CommitLineData
2ba45a60
DM
1/*
2 * Lossless video DSP utils
3 *
4 * This file is part of FFmpeg.
5 *
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.
10 *
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.
15 *
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
19 */
20#include "avcodec.h"
21#include "lossless_videodsp.h"
22#include "libavcodec/mathops.h"
23
24static void add_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, int w){
25 long i;
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);
32 }
33 for(; i<w; i++)
34 dst[i] = (dst[i] + src[i]) & mask;
35}
36
37static void diff_int16_c(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, unsigned mask, int w){
38 long i;
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;
46 }
47 }else
48#endif
49 {
50 unsigned long pw_lsb = (mask >> 1) * 0x0001000100010001ULL;
51 unsigned long pw_msb = pw_lsb + 0x0001000100010001ULL;
52
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);
57 }
58 }
59 for (; i<w; i++)
60 dst[i] = (src1[i] - src2[i]) & mask;
61}
62
63static 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){
64 int i;
65 uint16_t l, lt;
66
67 l = *left;
68 lt = *left_top;
69
70 for(i=0; i<w; i++){
71 l = (mid_pred(l, src[i], (l + src[i] - lt) & mask) + diff[i]) & mask;
72 lt = src[i];
73 dst[i] = l;
74 }
75
76 *left = l;
77 *left_top = lt;
78}
79
80static 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){
81 int i;
82 uint16_t l, lt;
83
84 l = *left;
85 lt = *left_top;
86
87 for(i=0; i<w; i++){
88 const int pred = mid_pred(l, src1[i], (l + src1[i] - lt) & mask);
89 lt = src1[i];
90 l = src2[i];
91 dst[i] = (l - pred) & mask;
92 }
93
94 *left = l;
95 *left_top = lt;
96}
97
98static int add_hfyu_left_pred_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, int w, unsigned acc){
99 int i;
100
101 for(i=0; i<w-1; i++){
102 acc+= src[i];
103 dst[i]= acc & mask;
104 i++;
105 acc+= src[i];
106 dst[i]= acc & mask;
107 }
108
109 for(; i<w; i++){
110 acc+= src[i];
111 dst[i]= acc & mask;
112 }
113
114 return acc;
115}
116
117
118void ff_llviddsp_init(LLVidDSPContext *c, AVCodecContext *avctx)
119{
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;
125
126 if (ARCH_X86)
127 ff_llviddsp_init_x86(c, avctx);
128}