1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#define __NR_PIXBLOCK_PATTERN_C__
/*
* Pixel buffer rendering library
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
*
* This code is in public domain
*/
#include <glib/gmem.h>
#include "nr-pixops.h"
#include "nr-pixblock-pattern.h"
#define NR_NOISE_SIZE 1024
void
nr_pixblock_render_gray_noise (NRPixBlock *pb, NRPixBlock *mask)
{
static unsigned char *noise = NULL;
static unsigned int seed = 0;
unsigned int v;
NRRectL clip;
int x, y, bpp;
if (mask) {
if (mask->empty) return;
nr_rect_l_intersect (&clip, &pb->area, &mask->area);
if (nr_rect_l_test_empty(clip)) return;
} else {
clip = pb->area;
}
if (!noise) {
int i;
noise = g_new (unsigned char, NR_NOISE_SIZE);
for (i = 0; i < NR_NOISE_SIZE; i++) noise[i] = (rand () / (RAND_MAX >> 8)) & 0xff;
}
bpp = NR_PIXBLOCK_BPP (pb);
v = (rand () / (RAND_MAX >> 8)) & 0xff;
if (mask) {
for (y = clip.y0; y < clip.y1; y++) {
unsigned char *d, *m;
d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp;
m = NR_PIXBLOCK_PX (mask) + (y - mask->area.y0) * pb->rs + (clip.x0 - mask->area.x0);
for (x = clip.x0; x < clip.x1; x++) {
v = v ^ noise[seed];
switch (pb->mode) {
case NR_PIXBLOCK_MODE_A8:
d[0] = NR_COMPOSEA_111(m[0], d[0]);
break;
case NR_PIXBLOCK_MODE_R8G8B8:
d[0] = NR_COMPOSEN11_1111 (v, m[0], d[0]);
d[1] = NR_COMPOSEN11_1111 (v, m[0], d[1]);
d[2] = NR_COMPOSEN11_1111 (v, m[0], d[2]);
break;
case NR_PIXBLOCK_MODE_R8G8B8A8N:
if (m[0] != 0) {
unsigned int ca;
ca = NR_COMPOSEA_112(m[0], d[3]);
d[0] = NR_COMPOSENNN_111121 (v, m[0], d[0], d[3], ca);
d[1] = NR_COMPOSENNN_111121 (v, m[0], d[1], d[3], ca);
d[2] = NR_COMPOSENNN_111121 (v, m[0], d[2], d[3], ca);
d[3] = NR_NORMALIZE_21(ca);
}
break;
case NR_PIXBLOCK_MODE_R8G8B8A8P:
d[0] = NR_COMPOSENPP_1111 (v, m[0], d[0]);
d[1] = NR_COMPOSENPP_1111 (v, m[0], d[1]);
d[2] = NR_COMPOSENPP_1111 (v, m[0], d[2]);
d[3] = NR_COMPOSEA_111(d[3], m[0]);
break;
default:
break;
}
d += bpp;
m += 1;
if (++seed >= NR_NOISE_SIZE) {
int i;
i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE;
noise[i] ^= v;
seed = i % (NR_NOISE_SIZE >> 2);
}
}
}
} else {
for (y = clip.y0; y < clip.y1; y++) {
unsigned char *d;
d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp;
for (x = clip.x0; x < clip.x1; x++) {
v = v ^ noise[seed];
switch (pb->mode) {
case NR_PIXBLOCK_MODE_A8:
d[0] = 255;
break;
case NR_PIXBLOCK_MODE_R8G8B8:
d[0] = v;
d[1] = v;
d[2] = v;
break;
case NR_PIXBLOCK_MODE_R8G8B8A8N:
case NR_PIXBLOCK_MODE_R8G8B8A8P:
d[0] = v;
d[1] = v;
d[2] = v;
d[3] = 255;
default:
break;
}
d += bpp;
if (++seed >= NR_NOISE_SIZE) {
int i;
i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE;
noise[i] ^= v;
seed = i % (NR_NOISE_SIZE >> 2);
}
}
}
}
pb->empty = 0;
}
|