comparison Meerwald-dir/wang_common.c @ 24:9f20bce6184e v0.7

move directories, support netpbm 11
author Peter Meerwald-Stadler <pmeerw@pmeerw.net>
date Fri, 20 Dec 2024 13:08:59 +0100
parents Meerwald/wang_common.c@bd669312f068
children
comparison
equal deleted inserted replaced
23:71dd4b96221b 24:9f20bce6184e
1 #include "dwt_util.h"
2 #include "wang_common.h"
3
4 Subband_data *subbands;
5 int n_subbands;
6
7 void init_subbands(Image_tree tree) {
8 int levels = 0;
9 int i;
10 Image_tree p = tree;
11
12 // determine # of detail subbands
13 while (p->coarse != NULL) {
14 levels++;
15 p = p->coarse;
16 }
17
18 // there are 3 detail subbands per level
19 n_subbands = 3 * levels;
20
21 // allocate memory for subband data
22 subbands = malloc(n_subbands * sizeof(Subband_data));
23
24 p = tree;
25 i = 0;
26 while (p->coarse != NULL) {
27 subbands[i++] = alloc_subband(HORIZONTAL, p->horizontal);
28 subbands[i++] = alloc_subband(VERTICAL, p->vertical);
29 subbands[i++] = alloc_subband(DIAGONAL, p->diagonal);
30
31 p = p->coarse;
32 }
33
34 }
35
36 Subband_data alloc_subband(int type, Image_tree tree) {
37 int i;
38 Subband_data p = malloc(sizeof(struct Subband_data_struct));
39
40 p->T = 0.0;
41 p->beta = 0.0;
42 p->Cmax = 0.0;
43 p->tree = tree;
44 p->level = tree->level;
45 p->width = tree->image->width;
46 p->height = tree->image->height;
47 p->size = p->height * p->width;
48 p->image = tree->image;
49 p->type = type;
50
51 p->selected = malloc(p->height * sizeof(char *));
52 p->selected[0] = calloc(p->size, sizeof(char));
53 for (i = 1; i < p->height; i++)
54 p->selected[i] = &(p->selected[0][i * p->width]);
55
56 return p;
57 }
58
59 void set_subband_beta(Subband_data subband, double beta) {
60 subband->beta = beta;
61 }
62
63 void set_subbands_beta(double beta) {
64 int i;
65
66 for (i = 0; i < n_subbands; i++)
67 set_subband_beta(subbands[i], beta);
68 }
69
70 void set_subbands_type_beta(int type, double beta) {
71 int i;
72
73 for (i = 0; i < n_subbands; i++)
74 if (subbands[i]->type == type)
75 set_subband_beta(subbands[i], beta);
76 }
77
78 void calc_subband_threshold(Subband_data subband) {
79 double max;
80 int i, j;
81
82 max = fabs(get_pixel(subband->image, 0, 0));
83 for (i = 0; i < subband->height; i++)
84 for (j = 0; j < subband->width; j++) {
85 Pixel p = fabs(get_pixel(subband->image, i, j));
86 if (p > max)
87 max = p;
88 }
89
90 subband->Cmax = max;
91 subband->T = max / 2.0;
92 }
93
94 void calc_subbands_threshold() {
95 int i;
96
97 for (i = 0; i < n_subbands; i++)
98 calc_subband_threshold(subbands[i]);
99 }
100
101 Subband_data select_subband() {
102 int max = 0;
103 int i;
104
105 for (i = 0; i < n_subbands; i++)
106 if ((subbands[i]->beta * subbands[i]->T) > (subbands[max]->beta * subbands[max]->T))
107 max = i;
108
109 return subbands[max];
110 }
111
112 int subband_coeff_isselected(Subband_data subband, int coeff) {
113 return subband->selected[0][coeff];
114 }
115
116 Pixel get_subband_coeff(Subband_data subband, int coeff) {
117 return subband->image->data[coeff];
118 }
119
120 void set_subband_coeff(Subband_data subband, int coeff, Pixel data) {
121 subband->image->data[coeff] = data;
122 }
123
124 int select_subband_coeff_from(Subband_data subband, int from) {
125 int i;
126
127 for (i = from; i < subband->size; i++)
128 if (!subband_coeff_isselected(subband, i) &&
129 get_subband_coeff(subband, i) > subband->T)
130 return i;
131
132 return -1;
133 }
134
135 int select_subband_coeff(Subband_data subband) {
136 return select_subband_coeff_from(subband, 0);
137 }
138
139 void mark_subband_coeff(Subband_data subband, int coeff) {
140 subband->selected[0][coeff] = 1;
141 }
142
143 void free_subband(Subband_data subband) {
144 free(subband->selected[0]);
145 free(subband->selected);
146 free(subband);
147 }
148
149 void free_subbands() {
150 int i;
151
152 for (i = 0; i < n_subbands; i++)
153 free_subband(subbands[i]);
154
155 free(subbands);
156 }
157
158 #define LARGE DBL_MAX
159
160 Pixel figure_orig_coeff(double T, double alpha, double beta, Pixel coeff) {
161 int p, p_min = 0;
162 double dist_min = LARGE;
163 double sign = (coeff >= 0) ? 1.0 : -1.0;
164
165 for (p = 1; p < 1.0 / (2.0 * alpha); p++) {
166 double dist, delta;
167
168 delta = (1.0 + 2.0 * p * alpha) * T;
169 dist = fabs(delta - fabs(coeff));
170
171 if (dist < dist_min) {
172 dist_min = dist;
173 p_min = p;
174 }
175 }
176
177 if (!p_min) p_min = 1;
178 return sign * (1.0 + 2.0 * p_min * alpha) * T;
179 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.