1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include "config.h" 20#include "libavutil/attributes.h" 21#include "huffyuvencdsp.h" 22#include "mathops.h" 23 24// 0x00010001 or 0x0001000100010001 or whatever, depending on the cpu's native arithmetic size 25#define pw_1 (ULONG_MAX / UINT16_MAX) 26 27static void diff_int16_c(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, unsigned mask, int w){ 28 long i; 29#if !HAVE_FAST_UNALIGNED 30 if((long)src2 & (sizeof(long)-1)){ 31 for(i=0; i+3<w; i+=4){ 32 dst[i+0] = (src1[i+0]-src2[i+0]) & mask; 33 dst[i+1] = (src1[i+1]-src2[i+1]) & mask; 34 dst[i+2] = (src1[i+2]-src2[i+2]) & mask; 35 dst[i+3] = (src1[i+3]-src2[i+3]) & mask; 36 } 37 }else 38#endif 39 { 40 unsigned long pw_lsb = (mask >> 1) * pw_1; 41 unsigned long pw_msb = pw_lsb + pw_1; 42 43 for (i = 0; i <= w - (int)sizeof(long)/2; i += sizeof(long)/2) { 44 long a = *(long*)(src1+i); 45 long b = *(long*)(src2+i); 46 *(long*)(dst+i) = ((a|pw_msb) - (b&pw_lsb)) ^ ((a^b^pw_msb)&pw_msb); 47 } 48 } 49 for (; i<w; i++) 50 dst[i] = (src1[i] - src2[i]) & mask; 51} 52 53static 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){ 54 int i; 55 uint16_t l, lt; 56 57 l = *left; 58 lt = *left_top; 59 60 for(i=0; i<w; i++){ 61 const int pred = mid_pred(l, src1[i], (l + src1[i] - lt) & mask); 62 lt = src1[i]; 63 l = src2[i]; 64 dst[i] = (l - pred) & mask; 65 } 66 67 *left = l; 68 *left_top = lt; 69} 70 71av_cold void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c, AVCodecContext *avctx) 72{ 73 c->diff_int16 = diff_int16_c; 74 c->sub_hfyu_median_pred_int16 = sub_hfyu_median_pred_int16_c; 75 76#if ARCH_X86 77 ff_huffyuvencdsp_init_x86(c, avctx); 78#endif 79} 80