Revert "Use the NDK cpufeatures directly."

This reverts commit 8c2ed69cb2250633188d2e70f7b71d8cf22603b8.

Broke sdk (linux) build in git_mirror-aosp-master-with-vendor:

In file included from external/webp/src/dsp/lossless_neon.c:18:
prebuilts/clang/host/linux-x86/clang-2812033/bin/../lib64/clang/3.8.256229/include/arm_neon.h:28:2: error: "NEON support not enabled"

Change-Id: I7d8db62eec5362d6be34488eff35faad0aac52fa
diff --git a/README.android b/README.android
index 0b8b77e..a6b9910 100644
--- a/README.android
+++ b/README.android
@@ -10,6 +10,9 @@
   (e.g. bits.h) to leak into
 - Removed build files necessary for building via autoconf/automake tools
   These files are not required to build via Android.mk
+- Added a local copy of cpu-features.[hc] to src/dsp
+- Removed WEBP_ANDROID_NEON check in dsp.h to avoid breaking non-NEON builds
+  where the flags in Android.mk are not set correctly currently.
 - Marked variable "status" in WebPParseHeaders as volatile to work around
   b/25845393
 
diff --git a/src/Android.mk b/src/Android.mk
index 5f6b289..854314d 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -28,6 +28,7 @@
         dsp/cost_mips32.c \
         dsp/cost_mips_dsp_r2.c \
         dsp/cost_sse2.c \
+        dsp/cpu-features.c \
         dsp/cpu.c \
         dsp/enc.c \
         dsp/enc_avx2.c \
@@ -87,8 +88,6 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-LOCAL_WHOLE_STATIC_LIBRARIES += cpufeatures
-
 include $(BUILD_STATIC_LIBRARY)
 
 ###############################################
@@ -110,6 +109,7 @@
         dsp/alpha_processing_mips_dsp_r2.c \
         dsp/alpha_processing_sse2.c \
         dsp/alpha_processing_sse41.c \
+        dsp/cpu-features.c \
         dsp/cpu.c \
         dsp/dec.c \
         dsp/dec_clip_tables.c \
@@ -161,6 +161,4 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-LOCAL_WHOLE_STATIC_LIBRARIES += cpufeatures
-
 include $(BUILD_STATIC_LIBRARY)
diff --git a/src/dsp/cpu-features.c b/src/dsp/cpu-features.c
new file mode 100644
index 0000000..fa2c721
--- /dev/null
+++ b/src/dsp/cpu-features.c
@@ -0,0 +1,398 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <sys/system_properties.h>
+#ifdef __arm__
+#include <machine/cpu-features.h>
+#endif
+#include <pthread.h>
+#include "cpu-features.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static  pthread_once_t     g_once;
+static  AndroidCpuFamily   g_cpuFamily;
+static  uint64_t           g_cpuFeatures;
+static  int                g_cpuCount;
+
+static const int  android_cpufeatures_debug = 0;
+
+#ifdef __arm__
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_ARM
+#elif defined __i386__
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_X86
+#else
+#  define DEFAULT_CPU_FAMILY  ANDROID_CPU_FAMILY_UNKNOWN
+#endif
+
+#define  D(...) \
+    do { \
+        if (android_cpufeatures_debug) { \
+            printf(__VA_ARGS__); fflush(stdout); \
+        } \
+    } while (0)
+
+#ifdef __i386__
+static __inline__ void x86_cpuid(int func, int values[4])
+{
+    int a, b, c, d;
+    /* We need to preserve ebx since we're compiling PIC code */
+    /* this means we can't use "=b" for the second output register */
+    __asm__ __volatile__ ( \
+      "push %%ebx\n"
+      "cpuid\n" \
+      "mov %%ebx, %1\n"
+      "pop %%ebx\n"
+      : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+      : "a" (func) \
+    );
+    values[0] = a;
+    values[1] = b;
+    values[2] = c;
+    values[3] = d;
+}
+#endif
+
+/* Read the content of /proc/cpuinfo into a user-provided buffer.
+ * Return the length of the data, or -1 on error. Does *not*
+ * zero-terminate the content. Will not read more
+ * than 'buffsize' bytes.
+ */
+static int
+read_file(const char*  pathname, char*  buffer, size_t  buffsize)
+{
+    int  fd, len;
+
+    fd = open(pathname, O_RDONLY);
+    if (fd < 0)
+        return -1;
+
+    do {
+        len = read(fd, buffer, buffsize);
+    } while (len < 0 && errno == EINTR);
+
+    close(fd);
+
+    return len;
+}
+
+/* Extract the content of a the first occurence of a given field in
+ * the content of /proc/cpuinfo and return it as a heap-allocated
+ * string that must be freed by the caller.
+ *
+ * Return NULL if not found
+ */
+static char*
+extract_cpuinfo_field(char* buffer, int buflen, const char* field)
+{
+    int  fieldlen = strlen(field);
+    char* bufend = buffer + buflen;
+    char* result = NULL;
+    int len, ignore;
+    const char *p, *q;
+
+    /* Look for first field occurence, and ensures it starts the line.
+     */
+    p = buffer;
+    bufend = buffer + buflen;
+    for (;;) {
+        p = memmem(p, bufend-p, field, fieldlen);
+        if (p == NULL)
+            goto EXIT;
+
+        if (p == buffer || p[-1] == '\n')
+            break;
+
+        p += fieldlen;
+    }
+
+    /* Skip to the first column followed by a space */
+    p += fieldlen;
+    p  = memchr(p, ':', bufend-p);
+    if (p == NULL || p[1] != ' ')
+        goto EXIT;
+
+    /* Find the end of the line */
+    p += 2;
+    q = memchr(p, '\n', bufend-p);
+    if (q == NULL)
+        q = bufend;
+
+    /* Copy the line into a heap-allocated buffer */
+    len = q-p;
+    result = malloc(len+1);
+    if (result == NULL)
+        goto EXIT;
+
+    memcpy(result, p, len);
+    result[len] = '\0';
+
+EXIT:
+    return result;
+}
+
+/* Count the number of occurences of a given field prefix in /proc/cpuinfo.
+ */
+static int
+count_cpuinfo_field(char* buffer, int buflen, const char* field)
+{
+    int fieldlen = strlen(field);
+    const char* p = buffer;
+    const char* bufend = buffer + buflen;
+    const char* q;
+    int count = 0;
+
+    for (;;) {
+        const char* q;
+
+        p = memmem(p, bufend-p, field, fieldlen);
+        if (p == NULL)
+            break;
+
+        /* Ensure that the field is at the start of a line */
+        if (p > buffer && p[-1] != '\n') {
+            p += fieldlen;
+            continue;
+        }
+
+
+        /* skip any whitespace */
+        q = p + fieldlen;
+        while (q < bufend && (*q == ' ' || *q == '\t'))
+            q++;
+
+        /* we must have a colon now */
+        if (q < bufend && *q == ':') {
+            count += 1;
+            q ++;
+        }
+        p = q;
+    }
+
+    return count;
+}
+
+/* Like strlen(), but for constant string literals */
+#define STRLEN_CONST(x)  ((sizeof(x)-1)
+
+
+/* Checks that a space-separated list of items contains one given 'item'.
+ * Returns 1 if found, 0 otherwise.
+ */
+static int
+has_list_item(const char* list, const char* item)
+{
+    const char*  p = list;
+    int itemlen = strlen(item);
+
+    if (list == NULL)
+        return 0;
+
+    while (*p) {
+        const char*  q;
+
+        /* skip spaces */
+        while (*p == ' ' || *p == '\t')
+            p++;
+
+        /* find end of current list item */
+        q = p;
+        while (*q && *q != ' ' && *q != '\t')
+            q++;
+
+        if (itemlen == q-p && !memcmp(p, item, itemlen))
+            return 1;
+
+        /* skip to next item */
+        p = q;
+    }
+    return 0;
+}
+
+
+static void
+android_cpuInit(void)
+{
+    char cpuinfo[4096];
+    int  cpuinfo_len;
+
+    g_cpuFamily   = DEFAULT_CPU_FAMILY;
+    g_cpuFeatures = 0;
+    g_cpuCount    = 1;
+
+    cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo);
+    D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len,
+      cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo);
+
+    if (cpuinfo_len < 0)  /* should not happen */ {
+        return;
+    }
+
+    /* Count the CPU cores, the value may be 0 for single-core CPUs */
+    g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "processor");
+    if (g_cpuCount == 0) {
+        g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "Processor");
+        if (g_cpuCount == 0) {
+            g_cpuCount = 1;
+        }
+    }
+
+    D("found cpuCount = %d\n", g_cpuCount);
+
+#ifdef __ARM_ARCH__
+    {
+        char*  features = NULL;
+        char*  architecture = NULL;
+
+        /* Extract architecture from the "CPU Architecture" field.
+         * The list is well-known, unlike the the output of
+         * the 'Processor' field which can vary greatly.
+         *
+         * See the definition of the 'proc_arch' array in
+         * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
+         * same file.
+         */
+        char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
+
+        if (cpuArch != NULL) {
+            char*  end;
+            long   archNumber;
+            int    hasARMv7 = 0;
+
+            D("found cpuArch = '%s'\n", cpuArch);
+
+            /* read the initial decimal number, ignore the rest */
+            archNumber = strtol(cpuArch, &end, 10);
+
+            /* Here we assume that ARMv8 will be upwards compatible with v7
+                * in the future. Unfortunately, there is no 'Features' field to
+                * indicate that Thumb-2 is supported.
+                */
+            if (end > cpuArch && archNumber >= 7) {
+                hasARMv7 = 1;
+            }
+
+            /* Unfortunately, it seems that certain ARMv6-based CPUs
+             * report an incorrect architecture number of 7!
+             *
+             * See http://code.google.com/p/android/issues/detail?id=10812
+             *
+             * We try to correct this by looking at the 'elf_format'
+             * field reported by the 'Processor' field, which is of the
+             * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
+             * an ARMv6-one.
+             */
+            if (hasARMv7) {
+                char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len,
+                                                      "Processor");
+                if (cpuProc != NULL) {
+                    D("found cpuProc = '%s'\n", cpuProc);
+                    if (has_list_item(cpuProc, "(v6l)")) {
+                        D("CPU processor and architecture mismatch!!\n");
+                        hasARMv7 = 0;
+                    }
+                    free(cpuProc);
+                }
+            }
+
+            if (hasARMv7) {
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7;
+            }
+
+            /* The LDREX / STREX instructions are available from ARMv6 */
+            if (archNumber >= 6) {
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX;
+            }
+
+            free(cpuArch);
+        }
+
+        /* Extract the list of CPU features from 'Features' field */
+        char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
+
+        if (cpuFeatures != NULL) {
+
+            D("found cpuFeatures = '%s'\n", cpuFeatures);
+
+            if (has_list_item(cpuFeatures, "vfpv3"))
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
+
+            else if (has_list_item(cpuFeatures, "vfpv3d16"))
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3;
+
+            if (has_list_item(cpuFeatures, "neon")) {
+                /* Note: Certain kernels only report neon but not vfpv3
+                    *       in their features list. However, ARM mandates
+                    *       that if Neon is implemented, so must be VFPv3
+                    *       so always set the flag.
+                    */
+                g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON |
+                                 ANDROID_CPU_ARM_FEATURE_VFPv3;
+            }
+            free(cpuFeatures);
+        }
+    }
+#endif /* __ARM_ARCH__ */
+
+#ifdef __i386__
+    g_cpuFamily = ANDROID_CPU_FAMILY_X86;
+
+    int regs[4];
+
+/* According to http://en.wikipedia.org/wiki/CPUID */
+#define VENDOR_INTEL_b  0x756e6547
+#define VENDOR_INTEL_c  0x6c65746e
+#define VENDOR_INTEL_d  0x49656e69
+
+    x86_cpuid(0, regs);
+    int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
+                         regs[2] == VENDOR_INTEL_c &&
+                         regs[3] == VENDOR_INTEL_d);
+
+    x86_cpuid(1, regs);
+    if ((regs[2] & (1 << 9)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSSE3;
+    }
+    if ((regs[2] & (1 << 23)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
+    }
+    if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) {
+        g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
+    }
+#endif
+}
+
+
+AndroidCpuFamily
+android_getCpuFamily(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuFamily;
+}
+
+
+uint64_t
+android_getCpuFeatures(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuFeatures;
+}
+
+
+int
+android_getCpuCount(void)
+{
+    pthread_once(&g_once, android_cpuInit);
+    return g_cpuCount;
+}
diff --git a/src/dsp/cpu-features.h b/src/dsp/cpu-features.h
new file mode 100644
index 0000000..f20c0bc
--- /dev/null
+++ b/src/dsp/cpu-features.h
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// You can download Android source at
+// http://source.android.com/source/downloading.html
+// Original files are in ndk/sources/android/cpufeatures
+// Revision is Change-Id: I9a0629efba36a6023f05e5f092e7addcc1b7d2a9
+
+#ifndef CPU_FEATURES_H
+#define CPU_FEATURES_H
+
+#include <sys/cdefs.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+typedef enum {
+    ANDROID_CPU_FAMILY_UNKNOWN = 0,
+    ANDROID_CPU_FAMILY_ARM,
+    ANDROID_CPU_FAMILY_X86,
+
+    ANDROID_CPU_FAMILY_MAX  /* do not remove */
+
+} AndroidCpuFamily;
+
+/* Return family of the device's CPU */
+extern AndroidCpuFamily   android_getCpuFamily(void);
+
+enum {
+    ANDROID_CPU_ARM_FEATURE_ARMv7       = (1 << 0),
+    ANDROID_CPU_ARM_FEATURE_VFPv3       = (1 << 1),
+    ANDROID_CPU_ARM_FEATURE_NEON        = (1 << 2),
+    ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3),
+};
+
+enum {
+    ANDROID_CPU_X86_FEATURE_SSSE3  = (1 << 0),
+    ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1),
+    ANDROID_CPU_X86_FEATURE_MOVBE  = (1 << 2),
+};
+
+extern uint64_t    android_getCpuFeatures(void);
+
+/* Return the number of CPU cores detected on this device. */
+extern int         android_getCpuCount(void);
+
+__END_DECLS
+
+#endif /* CPU_FEATURES_H */
diff --git a/src/dsp/cpu.c b/src/dsp/cpu.c
index 8844cb4..a4e5eea 100644
--- a/src/dsp/cpu.c
+++ b/src/dsp/cpu.c
@@ -13,8 +13,8 @@
 
 #include "./dsp.h"
 
-#if defined(WEBP_ANDROID_NEON)
-#include <cpu-features.h>
+#if defined(__ANDROID__)
+#include "cpu-features.h"
 #endif
 
 //------------------------------------------------------------------------------
diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h
index 28222f1..b6e441d 100644
--- a/src/dsp/dsp.h
+++ b/src/dsp/dsp.h
@@ -71,9 +71,8 @@
 
 // The intrinsics currently cause compiler errors with arm-nacl-gcc and the
 // inline assembly would need to be modified for use with Native Client.
-#if (defined(__ARM_NEON__) || defined(WEBP_ANDROID_NEON) || \
-     defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
-    !defined(__native_client__)
+#if (defined(__ARM_NEON__) || defined(__aarch64__)) \
+    && !defined(__native_client__)
 #define WEBP_USE_NEON
 #endif