1e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com/* 2e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * Copyright 2013 The LibYuv Project Authors. All rights reserved. 3e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * 4e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * Use of this source code is governed by a BSD-style license 5e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * that can be found in the LICENSE file in the root of the source 6e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * tree. An additional intellectual property rights grant can be found 7e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * in the file PATENTS. All contributing project authors may 8e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com * be found in the AUTHORS file in the root of the source tree. 9e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com */ 10e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 1176f86067a26810e6d7f3f8e65f136d808d4f144dfbarchard@google.com#include "./psnr.h" // NOLINT 12e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 13e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#ifdef _OPENMP 14e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#include <omp.h> 15e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 16e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#ifdef _MSC_VER 17e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#include <intrin.h> // For __cpuid() 18e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 19e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 2033d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com#ifdef __cplusplus 2133d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.comextern "C" { 2233d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com#endif 2333d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com 2476f86067a26810e6d7f3f8e65f136d808d4f144dfbarchard@google.comtypedef unsigned int uint32; // NOLINT 25e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#ifdef _MSC_VER 26e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comtypedef unsigned __int64 uint64; 27e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#else // COMPILER_MSVC 28e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) 29e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comtypedef unsigned long uint64; // NOLINT 30e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#else // defined(__LP64__) && !defined(__OpenBSD__) && !defined(__APPLE__) 31e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comtypedef unsigned long long uint64; // NOLINT 32e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif // __LP64__ 33e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif // _MSC_VER 34e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 35b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com// libyuv provides this function when linking library for jpeg support. 36b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com#if !defined(HAVE_JPEG) 37b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com 38e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if !defined(LIBYUV_DISABLE_NEON) && defined(__ARM_NEON__) 39e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#define HAS_SUMSQUAREERROR_NEON 40e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic uint32 SumSquareError_NEON(const uint8* src_a, 41e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* src_b, int count) { 42e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com volatile uint32 sse; 4333d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com asm volatile ( // NOLINT 44e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmov.u8 q7, #0 \n" 45e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmov.u8 q9, #0 \n" 46e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmov.u8 q8, #0 \n" 47e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmov.u8 q10, #0 \n" 48e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 49e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "1: \n" 50e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vld1.u8 {q0}, [%0]! \n" 51e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vld1.u8 {q1}, [%1]! \n" 52e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vsubl.u8 q2, d0, d2 \n" 53e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vsubl.u8 q3, d1, d3 \n" 54e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmlal.s16 q7, d4, d4 \n" 55e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmlal.s16 q8, d6, d6 \n" 56e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmlal.s16 q8, d5, d5 \n" 57e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmlal.s16 q10, d7, d7 \n" 58e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "subs %2, %2, #16 \n" 59e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "bhi 1b \n" 60e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 61e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vadd.u32 q7, q7, q8 \n" 62e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vadd.u32 q9, q9, q10 \n" 63e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vadd.u32 q10, q7, q9 \n" 64e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vpaddl.u32 q1, q10 \n" 65e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vadd.u64 d0, d2, d3 \n" 66e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "vmov.32 %3, d0[0] \n" 67e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : "+r"(src_a), 68e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "+r"(src_b), 69e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "+r"(count), 70e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "=r"(sse) 71e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : 7233d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com : "memory", "cc", "q0", "q1", "q2", "q3", "q7", "q8", "q9", "q10"); 73e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return sse; 74e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 75eed4149e10fdc63046262f44df6c5cfc5b364307fbarchard@google.com#elif !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) 76e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#define HAS_SUMSQUAREERROR_SSE2 77e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com__declspec(naked) 78e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic uint32 SumSquareError_SSE2(const uint8* /*src_a*/, 79e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* /*src_b*/, int /*count*/) { 80e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com __asm { 81e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com mov eax, [esp + 4] // src_a 82e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com mov edx, [esp + 8] // src_b 83e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com mov ecx, [esp + 12] // count 84e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pxor xmm0, xmm0 85e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pxor xmm5, xmm5 86e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sub edx, eax 87e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 88e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com wloop: 89e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com movdqu xmm1, [eax] 90e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com movdqu xmm2, [eax + edx] 91e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com lea eax, [eax + 16] 92e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com movdqu xmm3, xmm1 93e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com psubusb xmm1, xmm2 94e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com psubusb xmm2, xmm3 95e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com por xmm1, xmm2 96e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com movdqu xmm2, xmm1 97e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com punpcklbw xmm1, xmm5 98e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com punpckhbw xmm2, xmm5 99e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pmaddwd xmm1, xmm1 100e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pmaddwd xmm2, xmm2 101e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com paddd xmm0, xmm1 102e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com paddd xmm0, xmm2 103e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sub ecx, 16 104e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com ja wloop 105e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 106e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pshufd xmm1, xmm0, 0EEh 107e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com paddd xmm0, xmm1 108e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com pshufd xmm1, xmm0, 01h 109e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com paddd xmm0, xmm1 110e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com movd eax, xmm0 111e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com ret 112e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 113e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 114e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#elif !defined(LIBYUV_DISABLE_X86) && (defined(__x86_64__) || defined(__i386__)) 115e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#define HAS_SUMSQUAREERROR_SSE2 116e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic uint32 SumSquareError_SSE2(const uint8* src_a, 117e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* src_b, int count) { 118e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com uint32 sse; 11933d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com asm volatile ( // NOLINT 120e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pxor %%xmm0,%%xmm0 \n" 121e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pxor %%xmm5,%%xmm5 \n" 122e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "sub %0,%1 \n" 123e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 124e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "1: \n" 125e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "movdqu (%0),%%xmm1 \n" 126e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "movdqu (%0,%1,1),%%xmm2 \n" 127e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "lea 0x10(%0),%0 \n" 128e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "movdqu %%xmm1,%%xmm3 \n" 129e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "psubusb %%xmm2,%%xmm1 \n" 130e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "psubusb %%xmm3,%%xmm2 \n" 131e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "por %%xmm2,%%xmm1 \n" 132e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "movdqu %%xmm1,%%xmm2 \n" 133e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "punpcklbw %%xmm5,%%xmm1 \n" 134e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "punpckhbw %%xmm5,%%xmm2 \n" 135e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pmaddwd %%xmm1,%%xmm1 \n" 136e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pmaddwd %%xmm2,%%xmm2 \n" 137e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "paddd %%xmm1,%%xmm0 \n" 138e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "paddd %%xmm2,%%xmm0 \n" 139e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "sub $0x10,%2 \n" 140e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "ja 1b \n" 141e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 142e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pshufd $0xee,%%xmm0,%%xmm1 \n" 143e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "paddd %%xmm1,%%xmm0 \n" 144e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "pshufd $0x1,%%xmm0,%%xmm1 \n" 145e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "paddd %%xmm1,%%xmm0 \n" 146e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "movd %%xmm0,%3 \n" 147e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 148e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : "+r"(src_a), // %0 149e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "+r"(src_b), // %1 150e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "+r"(count), // %2 151e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "=g"(sse) // %3 152e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : 153e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : "memory", "cc" 154e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(__SSE2__) 155b432b7da2d8dd78db1fb4621f1be1a3c12d49cb2fbarchard@google.com , "xmm0", "xmm1", "xmm2", "xmm3", "xmm5" 156e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 15733d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com ); // NOLINT 158e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return sse; 159e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 160e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif // LIBYUV_DISABLE_X86 etc 161e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 162e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(HAS_SUMSQUAREERROR_SSE2) 163e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__) 164e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic __inline void __cpuid(int cpu_info[4], int info_type) { 16533d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com asm volatile ( // NOLINT 166e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "mov %%ebx, %%edi \n" 167e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "cpuid \n" 168e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "xchg %%edi, %%ebx \n" 169e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 17033d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com : "a"(info_type)); 171e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 172e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#elif defined(__i386__) || defined(__x86_64__) 173e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic __inline void __cpuid(int cpu_info[4], int info_type) { 17433d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com asm volatile ( // NOLINT 175e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com "cpuid \n" 176e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3]) 17733d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com : "a"(info_type)); 178e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 179e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 180e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 181e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic int CpuHasSSE2() { 182e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) 183e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com int cpu_info[4]; 184e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com __cpuid(cpu_info, 1); 185e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com if (cpu_info[3] & 0x04000000) { 186e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return 1; 187e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 188e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 189e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return 0; 190e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 191e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif // HAS_SUMSQUAREERROR_SSE2 192e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 193e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comstatic uint32 SumSquareError_C(const uint8* src_a, 194e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* src_b, int count) { 195e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com uint32 sse = 0u; 196e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com for (int x = 0; x < count; ++x) { 197e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com int diff = src_a[x] - src_b[x]; 198e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sse += static_cast<uint32>(diff * diff); 199e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 200e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return sse; 201e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 202e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com 203e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.comdouble ComputeSumSquareError(const uint8* src_a, 204e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* src_b, int count) { 205e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com uint32 (*SumSquareError)(const uint8* src_a, 206e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const uint8* src_b, int count) = SumSquareError_C; 207e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(HAS_SUMSQUAREERROR_NEON) 208e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com SumSquareError = SumSquareError_NEON; 209e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 210e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#if defined(HAS_SUMSQUAREERROR_SSE2) 211e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com if (CpuHasSSE2()) { 212e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com SumSquareError = SumSquareError_SSE2; 213e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 214e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 215e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com const int kBlockSize = 1 << 15; 216e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com uint64 sse = 0; 217e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#ifdef _OPENMP 218e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#pragma omp parallel for reduction(+: sse) 219e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com#endif 220e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com for (int i = 0; i < (count - (kBlockSize - 1)); i += kBlockSize) { 221e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sse += SumSquareError(src_a + i, src_b + i, kBlockSize); 222e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 223e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com src_a += count & ~(kBlockSize - 1); 224e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com src_b += count & ~(kBlockSize - 1); 225e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com int remainder = count & (kBlockSize - 1) & ~15; 226e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com if (remainder) { 227e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sse += SumSquareError(src_a, src_b, remainder); 228e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com src_a += remainder; 229e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com src_b += remainder; 230e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 231e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com remainder = count & 15; 232e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com if (remainder) { 233e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com sse += SumSquareError_C(src_a, src_b, remainder); 234e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com } 235e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com return static_cast<double>(sse); 236e424a9de7a97543aed7789bdec3795567288eafffbarchard@google.com} 237b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com#endif 238b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com 239b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com// PSNR formula: psnr = 10 * log10 (Peak Signal^2 * size / sse) 240b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com// Returns 128.0 (kMaxPSNR) if sse is 0 (perfect match). 241b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.comdouble ComputePSNR(double sse, double size) { 242b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com const double kMINSSE = 255.0 * 255.0 * size / pow(10.0, kMaxPSNR / 10.0); 243b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com if (sse <= kMINSSE) 244b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com sse = kMINSSE; // Produces max PSNR of 128 245b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com return 10.0 * log10(255.0 * 255.0 * size / sse); 246b7d674e305f53c83145405a9721a9e822afde004fbarchard@google.com} 24733d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com 24833d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com#ifdef __cplusplus 24933d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com} // extern "C" 25033d34eaad81ca9b3e05055f5a669c7ec3cd3fe61fbarchard@google.com#endif 251