Coverage Report

Created: 2025-06-22 08:04

/src/aom/av1/encoder/dwt.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2018, Alliance for Open Media. All rights reserved.
3
 *
4
 * This source code is subject to the terms of the BSD 2 Clause License and
5
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
 * was not distributed with this source code in the LICENSE file, you can
7
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8
 * Media Patent License 1.0 was not distributed with this source code in the
9
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10
 */
11
12
#include <assert.h>
13
#include <stdlib.h>
14
#include <math.h>
15
16
#include "config/av1_rtcd.h"
17
#include "av1/encoder/dwt.h"
18
19
// Note: block length must be even for this implementation
20
static void analysis_53_row(int length, tran_low_t *x, tran_low_t *lowpass,
21
0
                            tran_low_t *highpass) {
22
0
  int n;
23
0
  tran_low_t r, *a, *b;
24
25
0
  n = length >> 1;
26
0
  b = highpass;
27
0
  a = lowpass;
28
0
  while (--n) {
29
0
    *a++ = (r = *x++) * 2;
30
0
    *b++ = *x - ((r + x[1] + 1) >> 1);
31
0
    x++;
32
0
  }
33
0
  *a = (r = *x++) * 2;
34
0
  *b = *x - r;
35
36
0
  n = length >> 1;
37
0
  b = highpass;
38
0
  a = lowpass;
39
0
  r = *highpass;
40
0
  while (n--) {
41
0
    *a++ += (r + (*b) + 1) >> 1;
42
0
    r = *b++;
43
0
  }
44
0
}
45
46
static void analysis_53_col(int length, tran_low_t *x, tran_low_t *lowpass,
47
0
                            tran_low_t *highpass) {
48
0
  int n;
49
0
  tran_low_t r, *a, *b;
50
51
0
  n = length >> 1;
52
0
  b = highpass;
53
0
  a = lowpass;
54
0
  while (--n) {
55
0
    *a++ = (r = *x++);
56
0
    *b++ = (((*x) * 2) - (r + x[1]) + 2) >> 2;
57
0
    x++;
58
0
  }
59
0
  *a = (r = *x++);
60
0
  *b = (*x - r + 1) >> 1;
61
62
0
  n = length >> 1;
63
0
  b = highpass;
64
0
  a = lowpass;
65
0
  r = *highpass;
66
0
  while (n--) {
67
0
    *a++ += (r + (*b) + 1) >> 1;
68
0
    r = *b++;
69
0
  }
70
0
}
71
72
static void dyadic_analyze_53_uint8_input(int levels, int width, int height,
73
                                          const uint8_t *x, int pitch_x,
74
                                          tran_low_t *c, int pitch_c,
75
0
                                          int dwt_scale_bits, int hbd) {
76
0
  int lv, i, j, nh, nw, hh = height, hw = width;
77
0
  tran_low_t buffer[2 * DWT_MAX_LENGTH];
78
79
0
  if (hbd) {
80
0
    const uint16_t *x16 = CONVERT_TO_SHORTPTR(x);
81
0
    for (i = 0; i < height; i++) {
82
0
      for (j = 0; j < width; j++) {
83
0
        c[i * pitch_c + j] = x16[i * pitch_x + j] << dwt_scale_bits;
84
0
      }
85
0
    }
86
0
  } else {
87
0
    for (i = 0; i < height; i++) {
88
0
      for (j = 0; j < width; j++) {
89
0
        c[i * pitch_c + j] = x[i * pitch_x + j] << dwt_scale_bits;
90
0
      }
91
0
    }
92
0
  }
93
94
0
  for (lv = 0; lv < levels; lv++) {
95
0
    nh = hh;
96
0
    hh = (hh + 1) >> 1;
97
0
    nw = hw;
98
0
    hw = (hw + 1) >> 1;
99
0
    if ((nh < 2) || (nw < 2)) return;
100
0
    for (i = 0; i < nh; i++) {
101
0
      memcpy(buffer, &c[i * pitch_c], nw * sizeof(tran_low_t));
102
0
      analysis_53_row(nw, buffer, &c[i * pitch_c], &c[i * pitch_c] + hw);
103
0
    }
104
0
    for (j = 0; j < nw; j++) {
105
0
      for (i = 0; i < nh; i++) buffer[i + nh] = c[i * pitch_c + j];
106
0
      analysis_53_col(nh, buffer + nh, buffer, buffer + hh);
107
0
      for (i = 0; i < nh; i++) c[i * pitch_c + j] = buffer[i];
108
0
    }
109
0
  }
110
0
}
111
112
void av1_fdwt8x8_uint8_input_c(const uint8_t *input, tran_low_t *output,
113
0
                               int stride, int hbd) {
114
0
  dyadic_analyze_53_uint8_input(4, 8, 8, input, stride, output, 8, 2, hbd);
115
0
}
116
117
0
static int haar_ac_sad(const tran_low_t *output, int bw, int bh, int stride) {
118
0
  int acsad = 0;
119
120
0
  for (int r = 0; r < bh; ++r)
121
0
    for (int c = 0; c < bw; ++c) {
122
0
      if (r >= bh / 2 || c >= bw / 2) acsad += abs(output[r * stride + c]);
123
0
    }
124
0
  return acsad;
125
0
}
126
127
static int haar_ac_sad_8x8_uint8_input(const uint8_t *input, int stride,
128
0
                                       int hbd) {
129
0
  tran_low_t output[64];
130
131
0
  av1_fdwt8x8_uint8_input(input, output, stride, hbd);
132
0
  return haar_ac_sad(output, 8, 8, 8);
133
0
}
134
135
int64_t av1_haar_ac_sad_mxn_uint8_input(const uint8_t *input, int stride,
136
                                        int hbd, int num_8x8_rows,
137
0
                                        int num_8x8_cols) {
138
0
  int64_t wavelet_energy = 0;
139
0
  for (int r8 = 0; r8 < num_8x8_rows; ++r8) {
140
0
    for (int c8 = 0; c8 < num_8x8_cols; ++c8) {
141
0
      wavelet_energy += haar_ac_sad_8x8_uint8_input(
142
0
          input + c8 * 8 + r8 * 8 * stride, stride, hbd);
143
0
    }
144
0
  }
145
0
  return wavelet_energy;
146
0
}