Line data Source code
1 : /*
2 : * Copyright (c) 2016, 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 :
14 : #include "aom/aom_integer.h"
15 : #include "aom_ports/mem.h"
16 : #include "aom_dsp/blend.h"
17 : #include "aom_dsp/aom_dsp_common.h"
18 :
19 : #include "./aom_dsp_rtcd.h"
20 :
21 : // Blending with alpha mask. Mask values come from the range [0, 64],
22 : // as described for AOM_BLEND_A64 in aom_dsp/blend.h. src0 or src1 can
23 : // be the same as dst, or dst can be different from both sources.
24 :
25 0 : void aom_blend_a64_mask_c(uint8_t *dst, uint32_t dst_stride,
26 : const uint8_t *src0, uint32_t src0_stride,
27 : const uint8_t *src1, uint32_t src1_stride,
28 : const uint8_t *mask, uint32_t mask_stride, int h,
29 : int w, int subh, int subw) {
30 : int i, j;
31 :
32 0 : assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
33 0 : assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
34 :
35 0 : assert(h >= 1);
36 0 : assert(w >= 1);
37 0 : assert(IS_POWER_OF_TWO(h));
38 0 : assert(IS_POWER_OF_TWO(w));
39 :
40 0 : if (subw == 0 && subh == 0) {
41 0 : for (i = 0; i < h; ++i) {
42 0 : for (j = 0; j < w; ++j) {
43 0 : const int m = mask[i * mask_stride + j];
44 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
45 : src1[i * src1_stride + j]);
46 : }
47 : }
48 0 : } else if (subw == 1 && subh == 1) {
49 0 : for (i = 0; i < h; ++i) {
50 0 : for (j = 0; j < w; ++j) {
51 0 : const int m = ROUND_POWER_OF_TWO(
52 : mask[(2 * i) * mask_stride + (2 * j)] +
53 : mask[(2 * i + 1) * mask_stride + (2 * j)] +
54 : mask[(2 * i) * mask_stride + (2 * j + 1)] +
55 : mask[(2 * i + 1) * mask_stride + (2 * j + 1)],
56 : 2);
57 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
58 : src1[i * src1_stride + j]);
59 : }
60 : }
61 0 : } else if (subw == 1 && subh == 0) {
62 0 : for (i = 0; i < h; ++i) {
63 0 : for (j = 0; j < w; ++j) {
64 0 : const int m = AOM_BLEND_AVG(mask[i * mask_stride + (2 * j)],
65 : mask[i * mask_stride + (2 * j + 1)]);
66 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
67 : src1[i * src1_stride + j]);
68 : }
69 : }
70 : } else {
71 0 : for (i = 0; i < h; ++i) {
72 0 : for (j = 0; j < w; ++j) {
73 0 : const int m = AOM_BLEND_AVG(mask[(2 * i) * mask_stride + j],
74 : mask[(2 * i + 1) * mask_stride + j]);
75 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
76 : src1[i * src1_stride + j]);
77 : }
78 : }
79 : }
80 0 : }
81 :
82 : #if CONFIG_HIGHBITDEPTH
83 0 : void aom_highbd_blend_a64_mask_c(uint8_t *dst_8, uint32_t dst_stride,
84 : const uint8_t *src0_8, uint32_t src0_stride,
85 : const uint8_t *src1_8, uint32_t src1_stride,
86 : const uint8_t *mask, uint32_t mask_stride,
87 : int h, int w, int subh, int subw, int bd) {
88 : int i, j;
89 0 : uint16_t *dst = CONVERT_TO_SHORTPTR(dst_8);
90 0 : const uint16_t *src0 = CONVERT_TO_SHORTPTR(src0_8);
91 0 : const uint16_t *src1 = CONVERT_TO_SHORTPTR(src1_8);
92 : (void)bd;
93 :
94 0 : assert(IMPLIES(src0 == dst, src0_stride == dst_stride));
95 0 : assert(IMPLIES(src1 == dst, src1_stride == dst_stride));
96 :
97 0 : assert(h >= 1);
98 0 : assert(w >= 1);
99 0 : assert(IS_POWER_OF_TWO(h));
100 0 : assert(IS_POWER_OF_TWO(w));
101 :
102 0 : assert(bd == 8 || bd == 10 || bd == 12);
103 :
104 0 : if (subw == 0 && subh == 0) {
105 0 : for (i = 0; i < h; ++i) {
106 0 : for (j = 0; j < w; ++j) {
107 0 : const int m = mask[i * mask_stride + j];
108 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
109 : src1[i * src1_stride + j]);
110 : }
111 : }
112 0 : } else if (subw == 1 && subh == 1) {
113 0 : for (i = 0; i < h; ++i) {
114 0 : for (j = 0; j < w; ++j) {
115 0 : const int m = ROUND_POWER_OF_TWO(
116 : mask[(2 * i) * mask_stride + (2 * j)] +
117 : mask[(2 * i + 1) * mask_stride + (2 * j)] +
118 : mask[(2 * i) * mask_stride + (2 * j + 1)] +
119 : mask[(2 * i + 1) * mask_stride + (2 * j + 1)],
120 : 2);
121 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
122 : src1[i * src1_stride + j]);
123 : }
124 : }
125 0 : } else if (subw == 1 && subh == 0) {
126 0 : for (i = 0; i < h; ++i) {
127 0 : for (j = 0; j < w; ++j) {
128 0 : const int m = AOM_BLEND_AVG(mask[i * mask_stride + (2 * j)],
129 : mask[i * mask_stride + (2 * j + 1)]);
130 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
131 : src1[i * src1_stride + j]);
132 : }
133 : }
134 : } else {
135 0 : for (i = 0; i < h; ++i) {
136 0 : for (j = 0; j < w; ++j) {
137 0 : const int m = AOM_BLEND_AVG(mask[(2 * i) * mask_stride + j],
138 : mask[(2 * i + 1) * mask_stride + j]);
139 0 : dst[i * dst_stride + j] = AOM_BLEND_A64(m, src0[i * src0_stride + j],
140 : src1[i * src1_stride + j]);
141 : }
142 : }
143 : }
144 0 : }
145 : #endif // CONFIG_HIGHBITDEPTH
|