comparison elbg.c @ 11955:d94cbfa7a170 libavcodec

elbg: remove VLAs
author mru
date Fri, 25 Jun 2010 18:51:25 +0000
parents 7dd2a45249a9
children 25e9cb2b9477
comparison
equal deleted inserted replaced
11954:4aae15516d2c 11955:d94cbfa7a170
51 int *utility; 51 int *utility;
52 int *utility_inc; 52 int *utility_inc;
53 int *nearest_cb; 53 int *nearest_cb;
54 int *points; 54 int *points;
55 AVLFG *rand_state; 55 AVLFG *rand_state;
56 int *scratchbuf;
56 } elbg_data; 57 } elbg_data;
57 58
58 static inline int distance_limited(int *a, int *b, int dim, int limit) 59 static inline int distance_limited(int *a, int *b, int dim, int limit)
59 { 60 {
60 int i, dist=0; 61 int i, dist=0;
115 } 116 }
116 117
117 /** 118 /**
118 * Implementation of the simple LBG algorithm for just two codebooks 119 * Implementation of the simple LBG algorithm for just two codebooks
119 */ 120 */
120 static int simple_lbg(int dim, 121 static int simple_lbg(elbg_data *elbg,
122 int dim,
121 int *centroid[3], 123 int *centroid[3],
122 int newutility[3], 124 int newutility[3],
123 int *points, 125 int *points,
124 cell *cells) 126 cell *cells)
125 { 127 {
126 int i, idx; 128 int i, idx;
127 int numpoints[2] = {0,0}; 129 int numpoints[2] = {0,0};
128 int newcentroid[2][dim]; 130 int *newcentroid[2] = {
131 elbg->scratchbuf + 3*dim,
132 elbg->scratchbuf + 4*dim
133 };
129 cell *tempcell; 134 cell *tempcell;
130 135
131 memset(newcentroid, 0, sizeof(newcentroid)); 136 memset(newcentroid[0], 0, 2 * dim * sizeof(*newcentroid[0]));
132 137
133 newutility[0] = 138 newutility[0] =
134 newutility[1] = 0; 139 newutility[1] = 0;
135 140
136 for (tempcell = cells; tempcell; tempcell=tempcell->next) { 141 for (tempcell = cells; tempcell; tempcell=tempcell->next) {
156 161
157 static void get_new_centroids(elbg_data *elbg, int huc, int *newcentroid_i, 162 static void get_new_centroids(elbg_data *elbg, int huc, int *newcentroid_i,
158 int *newcentroid_p) 163 int *newcentroid_p)
159 { 164 {
160 cell *tempcell; 165 cell *tempcell;
161 int min[elbg->dim]; 166 int *min = newcentroid_i;
162 int max[elbg->dim]; 167 int *max = newcentroid_p;
163 int i; 168 int i;
164 169
165 for (i=0; i< elbg->dim; i++) { 170 for (i=0; i< elbg->dim; i++) {
166 min[i]=INT_MAX; 171 min[i]=INT_MAX;
167 max[i]=0; 172 max[i]=0;
172 min[i]=FFMIN(min[i], elbg->points[tempcell->index*elbg->dim + i]); 177 min[i]=FFMIN(min[i], elbg->points[tempcell->index*elbg->dim + i]);
173 max[i]=FFMAX(max[i], elbg->points[tempcell->index*elbg->dim + i]); 178 max[i]=FFMAX(max[i], elbg->points[tempcell->index*elbg->dim + i]);
174 } 179 }
175 180
176 for (i=0; i<elbg->dim; i++) { 181 for (i=0; i<elbg->dim; i++) {
177 newcentroid_i[i] = min[i] + (max[i] - min[i])/3; 182 int ni = min[i] + (max[i] - min[i])/3;
178 newcentroid_p[i] = min[i] + (2*(max[i] - min[i]))/3; 183 int np = min[i] + (2*(max[i] - min[i]))/3;
184 newcentroid_i[i] = ni;
185 newcentroid_p[i] = np;
179 } 186 }
180 } 187 }
181 188
182 /** 189 /**
183 * Add the points in the low utility cell to its closest cell. Split the high 190 * Add the points in the low utility cell to its closest cell. Split the high
246 */ 253 */
247 static void try_shift_candidate(elbg_data *elbg, int idx[3]) 254 static void try_shift_candidate(elbg_data *elbg, int idx[3])
248 { 255 {
249 int j, k, olderror=0, newerror, cont=0; 256 int j, k, olderror=0, newerror, cont=0;
250 int newutility[3]; 257 int newutility[3];
251 int newcentroid[3][elbg->dim]; 258 int *newcentroid[3] = {
252 int *newcentroid_ptrs[3]; 259 elbg->scratchbuf,
260 elbg->scratchbuf + elbg->dim,
261 elbg->scratchbuf + 2*elbg->dim
262 };
253 cell *tempcell; 263 cell *tempcell;
254
255 newcentroid_ptrs[0] = newcentroid[0];
256 newcentroid_ptrs[1] = newcentroid[1];
257 newcentroid_ptrs[2] = newcentroid[2];
258 264
259 for (j=0; j<3; j++) 265 for (j=0; j<3; j++)
260 olderror += elbg->utility[idx[j]]; 266 olderror += elbg->utility[idx[j]];
261 267
262 memset(newcentroid[2], 0, elbg->dim*sizeof(int)); 268 memset(newcentroid[2], 0, elbg->dim*sizeof(int));
275 newutility[2] = eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[0]]); 281 newutility[2] = eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[0]]);
276 newutility[2] += eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[2]]); 282 newutility[2] += eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[2]]);
277 283
278 newerror = newutility[2]; 284 newerror = newutility[2];
279 285
280 newerror += simple_lbg(elbg->dim, newcentroid_ptrs, newutility, elbg->points, 286 newerror += simple_lbg(elbg, elbg->dim, newcentroid, newutility, elbg->points,
281 elbg->cells[idx[1]]); 287 elbg->cells[idx[1]]);
282 288
283 if (olderror > newerror) { 289 if (olderror > newerror) {
284 shift_codebook(elbg, idx, newcentroid_ptrs); 290 shift_codebook(elbg, idx, newcentroid);
285 291
286 elbg->error += newerror - olderror; 292 elbg->error += newerror - olderror;
287 293
288 for (j=0; j<3; j++) 294 for (j=0; j<3; j++)
289 update_utility_and_n_cb(elbg, idx[j], newutility[j]); 295 update_utility_and_n_cb(elbg, idx[j], newutility[j]);
364 elbg->cells = av_malloc(numCB*sizeof(cell *)); 370 elbg->cells = av_malloc(numCB*sizeof(cell *));
365 elbg->utility = av_malloc(numCB*sizeof(int)); 371 elbg->utility = av_malloc(numCB*sizeof(int));
366 elbg->nearest_cb = closest_cb; 372 elbg->nearest_cb = closest_cb;
367 elbg->points = points; 373 elbg->points = points;
368 elbg->utility_inc = av_malloc(numCB*sizeof(int)); 374 elbg->utility_inc = av_malloc(numCB*sizeof(int));
375 elbg->scratchbuf = av_malloc(5*dim*sizeof(int));
369 376
370 elbg->rand_state = rand_state; 377 elbg->rand_state = rand_state;
371 378
372 do { 379 do {
373 free_cells = list_buffer; 380 free_cells = list_buffer;
423 av_free(size_part); 430 av_free(size_part);
424 av_free(elbg->utility); 431 av_free(elbg->utility);
425 av_free(list_buffer); 432 av_free(list_buffer);
426 av_free(elbg->cells); 433 av_free(elbg->cells);
427 av_free(elbg->utility_inc); 434 av_free(elbg->utility_inc);
428 } 435 av_free(elbg->scratchbuf);
436 }