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 21#include "config.h" 22#include "lossless_videodsp.h" 23#include "libavcodec/mathops.h" 24 25// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size 26#define pb_7f (~0UL / 255 * 0x7f) 27#define pb_80 (~0UL / 255 * 0x80) 28 29static void add_bytes_c(uint8_t *dst, uint8_t *src, ptrdiff_t w) 30{ 31 long i; 32 33 for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { 34 long a = *(long *) (src + i); 35 long b = *(long *) (dst + i); 36 *(long *) (dst + i) = ((a & pb_7f) + (b & pb_7f)) ^ ((a ^ b) & pb_80); 37 } 38 for (; i < w; i++) 39 dst[i + 0] += src[i + 0]; 40} 41 42static void add_median_pred_c(uint8_t *dst, const uint8_t *src1, 43 const uint8_t *diff, ptrdiff_t w, 44 int *left, int *left_top) 45{ 46 int i; 47 uint8_t l, lt; 48 49 l = *left; 50 lt = *left_top; 51 52 for (i = 0; i < w; i++) { 53 l = mid_pred(l, src1[i], (l + src1[i] - lt) & 0xFF) + diff[i]; 54 lt = src1[i]; 55 dst[i] = l; 56 } 57 58 *left = l; 59 *left_top = lt; 60} 61 62static int add_left_pred_c(uint8_t *dst, const uint8_t *src, ptrdiff_t w, 63 int acc) 64{ 65 int i; 66 67 for (i = 0; i < w - 1; i++) { 68 acc += src[i]; 69 dst[i] = acc; 70 i++; 71 acc += src[i]; 72 dst[i] = acc; 73 } 74 75 for (; i < w; i++) { 76 acc += src[i]; 77 dst[i] = acc; 78 } 79 80 return acc; 81} 82 83static int add_left_pred_int16_c(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc){ 84 int i; 85 86 for(i=0; i<w-1; i++){ 87 acc+= src[i]; 88 dst[i]= acc &= mask; 89 i++; 90 acc+= src[i]; 91 dst[i]= acc &= mask; 92 } 93 94 for(; i<w; i++){ 95 acc+= src[i]; 96 dst[i]= acc &= mask; 97 } 98 99 return acc; 100} 101 102static void add_gradient_pred_c(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width){ 103 int A, B, C, i; 104 105 for (i = 0; i < width; i++) { 106 A = src[i - stride]; 107 B = src[i - (stride + 1)]; 108 C = src[i - 1]; 109 src[i] = (A - B + C + src[i]) & 0xFF; 110 } 111} 112 113void ff_llviddsp_init(LLVidDSPContext *c) 114{ 115 c->add_bytes = add_bytes_c; 116 c->add_median_pred = add_median_pred_c; 117 c->add_left_pred = add_left_pred_c; 118 119 c->add_left_pred_int16 = add_left_pred_int16_c; 120 c->add_gradient_pred = add_gradient_pred_c; 121 122#if ARCH_PPC 123 ff_llviddsp_init_ppc(c); 124#elif ARCH_X86 125 ff_llviddsp_init_x86(c); 126#endif 127} 128