quant.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2018 Google Inc. All Rights Reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the COPYING file in the root of the source
  5. // tree. An additional intellectual property rights grant can be found
  6. // in the file PATENTS. All contributing project authors may
  7. // be found in the AUTHORS file in the root of the source tree.
  8. // -----------------------------------------------------------------------------
  9. #ifndef WEBP_DSP_QUANT_H_
  10. #define WEBP_DSP_QUANT_H_
  11. #include "../dsp/dsp.h"
  12. #include "../webp/types.h"
  13. #if defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && \
  14. !defined(WEBP_HAVE_NEON_RTCD)
  15. #include <arm_neon.h>
  16. #define IsFlat IsFlat_NEON
  17. static uint32x2_t horizontal_add_uint32x4(const uint32x4_t a) {
  18. const uint64x2_t b = vpaddlq_u32(a);
  19. return vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
  20. vreinterpret_u32_u64(vget_high_u64(b)));
  21. }
  22. static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
  23. int thresh) {
  24. const int16x8_t tst_ones = vdupq_n_s16(-1);
  25. uint32x4_t sum = vdupq_n_u32(0);
  26. for (int i = 0; i < num_blocks; ++i) {
  27. // Set DC to zero.
  28. const int16x8_t a_0 = vsetq_lane_s16(0, vld1q_s16(levels), 0);
  29. const int16x8_t a_1 = vld1q_s16(levels + 8);
  30. const uint16x8_t b_0 = vshrq_n_u16(vtstq_s16(a_0, tst_ones), 15);
  31. const uint16x8_t b_1 = vshrq_n_u16(vtstq_s16(a_1, tst_ones), 15);
  32. sum = vpadalq_u16(sum, b_0);
  33. sum = vpadalq_u16(sum, b_1);
  34. levels += 16;
  35. }
  36. return thresh >= (int32_t)vget_lane_u32(horizontal_add_uint32x4(sum), 0);
  37. }
  38. #else
  39. #define IsFlat IsFlat_C
  40. static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
  41. int thresh) {
  42. int score = 0;
  43. while (num_blocks-- > 0) { // TODO(skal): refine positional scoring?
  44. int i;
  45. for (i = 1; i < 16; ++i) { // omit DC, we're only interested in AC
  46. score += (levels[i] != 0);
  47. if (score > thresh) return 0;
  48. }
  49. levels += 16;
  50. }
  51. return 1;
  52. }
  53. #endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) &&
  54. // !defined(WEBP_HAVE_NEON_RTCD)
  55. #endif // WEBP_DSP_QUANT_H_