blob: 389cf2049fa6ab78e1c3d04f843d40c3c26ff6c8 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xubde4ac82016-11-28 15:26:06 -08002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xubde4ac82016-11-28 15:26:06 -08004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <math.h>
13#include <stdlib.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
16#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_ports/mem.h"
20
Yaowu Xuf883b422016-08-30 14:01:10 -070021void aom_plane_add_noise_c(uint8_t *start, char *noise, char blackclamp[16],
Yaowu Xuc27fc142016-08-22 16:08:15 -070022 char whiteclamp[16], char bothclamp[16],
23 unsigned int width, unsigned int height, int pitch) {
24 unsigned int i, j;
25
26 for (i = 0; i < height; ++i) {
27 uint8_t *pos = start + i * pitch;
28 char *ref = (char *)(noise + (rand() & 0xff)); // NOLINT
29
30 for (j = 0; j < width; ++j) {
31 int v = pos[j];
32
33 v = clamp(v - blackclamp[0], 0, 255);
34 v = clamp(v + bothclamp[0], 0, 255);
35 v = clamp(v - whiteclamp[0], 0, 255);
36
37 pos[j] = v + ref[j];
38 }
39 }
40}
41
42static double gaussian(double sigma, double mu, double x) {
43 return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
44 (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
45}
46
Yaowu Xuf883b422016-08-30 14:01:10 -070047int aom_setup_noise(double sigma, int size, char *noise) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070048 char char_dist[256];
49 int next = 0, i, j;
50
51 // set up a 256 entry lookup that matches gaussian distribution
52 for (i = -32; i < 32; ++i) {
53 const int a_i = (int)(0.5 + 256 * gaussian(sigma, 0, i));
54 if (a_i) {
55 for (j = 0; j < a_i; ++j) {
56 char_dist[next + j] = (char)i;
57 }
58 next = next + j;
59 }
60 }
61
62 // Rounding error - might mean we have less than 256.
63 for (; next < 256; ++next) {
64 char_dist[next] = 0;
65 }
66
67 for (i = 0; i < size; ++i) {
68 noise[i] = char_dist[rand() & 0xff]; // NOLINT
69 }
70
71 // Returns the highest non 0 value used in distribution.
72 return -char_dist[0];
73}