1 | /* ------------- */ |
---|
2 | /* --- mca.c --- */ |
---|
3 | /* ------------- */ |
---|
4 | |
---|
5 | /* |
---|
6 | * Copyright (c) 2016 Lionel Lacassagne, LIP6, UPMC, CNRS |
---|
7 | * Init : 2016/03/03 |
---|
8 | * modif : 2016/03/07 |
---|
9 | */ |
---|
10 | |
---|
11 | #include <stdio.h> |
---|
12 | #include <stdlib.h> |
---|
13 | #include <string.h> |
---|
14 | #include <math.h> |
---|
15 | #include <malloc.h> |
---|
16 | |
---|
17 | #include "nrc_os_config.h" |
---|
18 | #include "config.h" |
---|
19 | #include "nrc.h" |
---|
20 | |
---|
21 | #if TARGET_OS == GIETVM |
---|
22 | #include <giet_config.h> |
---|
23 | #endif |
---|
24 | |
---|
25 | #include "util.h" |
---|
26 | #include "ecc_common.h" |
---|
27 | #include "ecc_features.h" |
---|
28 | #include "mca_matrix_dist.h" |
---|
29 | |
---|
30 | #include "palette.h" |
---|
31 | #include "bmpNR.h" |
---|
32 | #include "str_ext.h" |
---|
33 | |
---|
34 | |
---|
35 | // -- local -- |
---|
36 | #include "mca.h" |
---|
37 | |
---|
38 | |
---|
39 | // ----------------------- |
---|
40 | void MCA_Error(char * msg) |
---|
41 | // ----------------------- |
---|
42 | { |
---|
43 | printf("MCA ERROR: %s\n", msg); |
---|
44 | exit(1); |
---|
45 | } |
---|
46 | |
---|
47 | |
---|
48 | // ------------------------------- |
---|
49 | MCA * MCA_pConstructor_Empty(void) |
---|
50 | // ------------------------------- |
---|
51 | { |
---|
52 | MCA * mca; |
---|
53 | mca = (MCA *) malloc(sizeof(MCA)); |
---|
54 | |
---|
55 | if (mca == NULL) { |
---|
56 | MCA_Error("allocation failed in MCA_pConstructor_Empty"); |
---|
57 | } |
---|
58 | return mca; |
---|
59 | } |
---|
60 | |
---|
61 | |
---|
62 | // --------------------------------------- |
---|
63 | void MCA_Set_ImageX(MCA * mca, uint8 ** X) |
---|
64 | // --------------------------------------- |
---|
65 | { |
---|
66 | mca->X = X; |
---|
67 | } |
---|
68 | |
---|
69 | |
---|
70 | // -------------------------------------- |
---|
71 | void MCA_Set_ImageL(MCA * mca, uint32 ** E) |
---|
72 | // -------------------------------------- |
---|
73 | { |
---|
74 | mca->E = E; |
---|
75 | } |
---|
76 | |
---|
77 | |
---|
78 | // ------------------------------------ |
---|
79 | void MCA_Set_Width(MCA * mca, int width) |
---|
80 | // ------------------------------------ |
---|
81 | { |
---|
82 | mca->width = width; |
---|
83 | |
---|
84 | mca->j0 = 0; |
---|
85 | mca->j1 = width - 1; |
---|
86 | } |
---|
87 | |
---|
88 | |
---|
89 | // -------------------------------------- |
---|
90 | void MCA_Set_Height(MCA * mca, int height) |
---|
91 | // -------------------------------------- |
---|
92 | { |
---|
93 | mca->height = height; |
---|
94 | |
---|
95 | mca->i0 = 0; |
---|
96 | mca->i1 = height - 1; |
---|
97 | } |
---|
98 | |
---|
99 | |
---|
100 | // ----------------------------------------------- |
---|
101 | void MCA_Set_Size(MCA * mca, int width, int height) |
---|
102 | // ----------------------------------------------- |
---|
103 | { |
---|
104 | MCA_Set_Width(mca, width); |
---|
105 | MCA_Set_Height(mca, height); |
---|
106 | } |
---|
107 | |
---|
108 | |
---|
109 | // ---------------------------------------------------- |
---|
110 | void MCA_Set_Dimension(MCA * mca, int width, int height) |
---|
111 | // ---------------------------------------------------- |
---|
112 | { |
---|
113 | MCA_Set_Width(mca, width); |
---|
114 | MCA_Set_Height(mca, height); |
---|
115 | } |
---|
116 | |
---|
117 | |
---|
118 | // ------------------------------ |
---|
119 | void MCA_Set_NP(MCA * mca, int np) |
---|
120 | // ------------------------------ |
---|
121 | { |
---|
122 | mca->np = np; |
---|
123 | } |
---|
124 | |
---|
125 | |
---|
126 | // ------------------------------------------------------------------ |
---|
127 | uint32 MCA_CalcMaxLabels(int connection, uint32 height, uint32 width) |
---|
128 | // ------------------------------------------------------------------ |
---|
129 | { |
---|
130 | uint32 nemax = 0; |
---|
131 | |
---|
132 | if (connection == 4) { |
---|
133 | nemax = ((height + 1) / 2) * ((width + 1) / 2) + (height / 2) * (width / 2); // 4C |
---|
134 | } |
---|
135 | if (connection == 8) { |
---|
136 | nemax = ((height + 1) / 2) * ((width + 1) / 2); // 8C |
---|
137 | } |
---|
138 | return nemax; |
---|
139 | } |
---|
140 | |
---|
141 | |
---|
142 | // --------------------------- |
---|
143 | void MCA_Initialize(MCA * mca) |
---|
144 | // --------------------------- |
---|
145 | { |
---|
146 | // input |
---|
147 | int np = mca->np; |
---|
148 | int width = mca->width; |
---|
149 | int height = mca->height; |
---|
150 | |
---|
151 | // variables |
---|
152 | int i0_par, i1_par, i1_par_previous; |
---|
153 | int j0_par, j1_par; |
---|
154 | int height_par, height_mod; |
---|
155 | |
---|
156 | int pw2; |
---|
157 | int32 ne_par; // quantite par bande |
---|
158 | uint32 nemax_par; // la puissance de 2 >= |
---|
159 | uint32 e0_par, e1_par; // indice par bande [start..end] |
---|
160 | int nb_level; |
---|
161 | |
---|
162 | MCA ** mcas; |
---|
163 | MCA * mca_par; |
---|
164 | |
---|
165 | MCA_VERBOSE1(printf("*** %s ***\n", __func__)); |
---|
166 | MCA_VERBOSE2(printf(" height = %d\n", height)); |
---|
167 | MCA_VERBOSE2(printf(" width = %d\n", width)); |
---|
168 | |
---|
169 | // array of pointers to mca workers |
---|
170 | mcas = (MCA **) malloc(np * sizeof(MCA *)); |
---|
171 | if (mcas == NULL) { |
---|
172 | MCA_Error("MCA_Initialize1"); |
---|
173 | } |
---|
174 | mca->mcas = mcas; |
---|
175 | |
---|
176 | // hauteur de chaque bande |
---|
177 | height_par = height / np; |
---|
178 | height_mod = height % np; |
---|
179 | |
---|
180 | MCA_VERBOSE2(printf(" height_par = %d x %d + %d\n", height_par, np, height_mod)); |
---|
181 | MCA_VERBOSE2(printf(" ========================\n")); |
---|
182 | |
---|
183 | i1_par_previous = 0; |
---|
184 | |
---|
185 | // puissance de 2 de chaque bande |
---|
186 | ne_par = height_par * width + 1; |
---|
187 | MCA_VERBOSE2(printf(" ne_par = %d\n", ne_par)); |
---|
188 | pw2 = i32log2(ne_par); |
---|
189 | if (ne_par > (1 << pw2)) { |
---|
190 | pw2++; |
---|
191 | } |
---|
192 | nemax_par = 1 << pw2; |
---|
193 | mca->alpha = pw2; |
---|
194 | |
---|
195 | MCA_VERBOSE2(printf(" nemax_par = %d\n", nemax_par)); |
---|
196 | |
---|
197 | nb_level = i32log2(np); |
---|
198 | if ((1 << nb_level) < np) { |
---|
199 | nb_level++; |
---|
200 | } |
---|
201 | |
---|
202 | #if PYR_BARRIERS |
---|
203 | // ------------------------------------------ |
---|
204 | // -- Allocation des barriÚres pyramidales -- |
---|
205 | // ------------------------------------------ |
---|
206 | |
---|
207 | pthread_barrier_t * barriers = NULL; |
---|
208 | if (nb_level > 0) { |
---|
209 | barriers = malloc(sizeof(pthread_barrier_t) * nb_level); |
---|
210 | |
---|
211 | // Initially all threads are active except thread 0 |
---|
212 | int nb_active = np - 1; |
---|
213 | pthread_barrier_init(&barriers[0], NULL, nb_active); |
---|
214 | for (int i = 1; i < nb_level; i++) { |
---|
215 | // thread 0 never does any merge |
---|
216 | for (int p = 1; p < np; p++) { |
---|
217 | if ((p + (1 << (i - 1))) % (1 << i) == 0) { |
---|
218 | // thread inactive at level i |
---|
219 | nb_active -= 1; |
---|
220 | } |
---|
221 | } |
---|
222 | pthread_barrier_init(&barriers[i], NULL, nb_active); |
---|
223 | } |
---|
224 | } |
---|
225 | #endif |
---|
226 | |
---|
227 | for (int p = 0; p < np; p++) { |
---|
228 | |
---|
229 | // ----------------- // |
---|
230 | // -- constructor -- // |
---|
231 | // ----------------- // |
---|
232 | MCA_VERBOSE3(printf("-- p = %d ----------------\n", p)); |
---|
233 | |
---|
234 | // alloc of mca workers into array of pointers |
---|
235 | mca_par = MCA_pConstructor_Empty(); |
---|
236 | if (mca_par == NULL) { |
---|
237 | MCA_Error("MCA_Initialize2\n"); |
---|
238 | } |
---|
239 | mcas[p] = mca_par; |
---|
240 | mca_par->p = p; |
---|
241 | mca_par->mca = mca; // pointer to master |
---|
242 | #if TARGET_OS == GIETVM |
---|
243 | int x, y; // cluster coordinates |
---|
244 | // We have p == 4 => x = 0; y = 1 |
---|
245 | x = (p / NB_PROCS_MAX) / Y_SIZE; |
---|
246 | y = (p / NB_PROCS_MAX) % Y_SIZE; |
---|
247 | MCA_VERBOSE3(printf("p = %d (x = %d, y = %d)\n", p, x, y)); |
---|
248 | #endif |
---|
249 | |
---|
250 | // ------------------------------------- // |
---|
251 | // -- calcul des parametres: passe #1 -- // |
---|
252 | // ------------------------------------- // |
---|
253 | |
---|
254 | // hauteur de chaque bande |
---|
255 | if (p == 0) { |
---|
256 | i0_par = 0; |
---|
257 | } |
---|
258 | else { |
---|
259 | i0_par = i1_par_previous + 1; |
---|
260 | } |
---|
261 | if (height_mod) { |
---|
262 | i1_par = i0_par + height_par; |
---|
263 | height_mod = height_mod - 1; |
---|
264 | } |
---|
265 | else { |
---|
266 | i1_par = i0_par + height_par - 1; |
---|
267 | } |
---|
268 | i1_par_previous = i1_par; |
---|
269 | |
---|
270 | MCA_VERBOSE3(printf("i0_par = %d\n", i0_par)); |
---|
271 | MCA_VERBOSE3(printf("i1_par = %d\n", i1_par)); |
---|
272 | |
---|
273 | // etiquettes |
---|
274 | if (p == 0) { |
---|
275 | e0_par = 1; |
---|
276 | e1_par = nemax_par - 1; |
---|
277 | } |
---|
278 | else { |
---|
279 | e0_par = p * nemax_par; |
---|
280 | e1_par = e0_par + nemax_par - 1; |
---|
281 | } |
---|
282 | |
---|
283 | MCA_VERBOSE3(printf("e0_par = %d\n", e0_par)); |
---|
284 | MCA_VERBOSE3(printf("e1_par = %d\n", e1_par)); |
---|
285 | |
---|
286 | mca_par->width = width; |
---|
287 | mca_par->height = height_par; |
---|
288 | mca_par->i0 = i0_par; |
---|
289 | mca_par->i1 = i1_par; |
---|
290 | mca_par->j0 = 0; |
---|
291 | mca_par->j1 = width - 1; |
---|
292 | mca_par->e0 = e0_par; |
---|
293 | mca_par->e1 = e1_par; |
---|
294 | mca_par->alpha = pw2; |
---|
295 | mca_par->np = np; |
---|
296 | // Pour les barriÚres pyramidales |
---|
297 | mca_par->nb_level = nb_level; |
---|
298 | #if PYR_BARRIERS |
---|
299 | mca_par->barriers = barriers; |
---|
300 | #else |
---|
301 | mca_par->barriers = NULL; |
---|
302 | #endif |
---|
303 | mca_par->F = NULL; // default init |
---|
304 | mca_par->stats = NULL; // default init |
---|
305 | |
---|
306 | // ---------------- // |
---|
307 | // -- allocation -- // |
---|
308 | // ---------------- // |
---|
309 | #if TARGET_OS == GIETVM |
---|
310 | mca_par->X = remote_ui8matrix(i0_par, i1_par, 0, width - 1, x, y); |
---|
311 | mca_par->E = remote_dist_ui32matrix(i0_par, i1_par, 0, width - 1, x, y); // distributed matrix with border |
---|
312 | |
---|
313 | if (p == 0) { |
---|
314 | mca_par->T = remote_ui32vector(e0_par - 1, e1_par, x, y); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot |
---|
315 | mca_par->stats = remote_RegionStatsVector(e0_par - 1, e1_par, x, y); |
---|
316 | } |
---|
317 | else { |
---|
318 | mca_par->T = remote_ui32vector(e0_par, e1_par, x, y); |
---|
319 | mca_par->stats = remote_RegionStatsVector(e0_par, e1_par, x, y); |
---|
320 | } |
---|
321 | |
---|
322 | mca_par->D = (uint32 **) remote_vvector(0, np - 1, x, y); |
---|
323 | mca_par->F = (RegionStats **) remote_vvector(0, np - 1, x, y); |
---|
324 | #else // !GIETVM |
---|
325 | mca_par->X = ui8matrix (i0_par, i1_par, 0, width - 1); |
---|
326 | mca_par->E = dist_ui32matrix(i0_par, i1_par, 0, width - 1); // distributed matrix with border |
---|
327 | |
---|
328 | if (p == 0) { |
---|
329 | mca_par->T = ui32vector(e0_par - 1, e1_par); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot |
---|
330 | mca_par->stats = RegionStatsVector(e0_par - 1, e1_par); |
---|
331 | } |
---|
332 | else { |
---|
333 | mca_par->T = ui32vector(e0_par, e1_par); |
---|
334 | mca_par->stats = RegionStatsVector(e0_par, e1_par); |
---|
335 | } |
---|
336 | |
---|
337 | mca_par->D = (uint32 **) vvector(0, np - 1); |
---|
338 | mca_par->F = (RegionStats **) vvector(0, np - 1); |
---|
339 | #endif |
---|
340 | MCA_VERBOSE3(printf("X = %p\n", mca_par->X)); |
---|
341 | MCA_VERBOSE3(printf("E = %p\n", mca_par->E)); |
---|
342 | MCA_VERBOSE3(printf("T = %p\n", mca_par->T)); |
---|
343 | MCA_VERBOSE3(printf("D = %p\n", mca_par->D)); |
---|
344 | } // p |
---|
345 | |
---|
346 | |
---|
347 | for (int p = 0; p < np; p++) { |
---|
348 | MCA * mca_par = mcas[p]; |
---|
349 | |
---|
350 | uint32 * T = mca_par->T; |
---|
351 | uint32 e0 = mca_par->e0; |
---|
352 | uint32 e1 = mca_par->e1; |
---|
353 | |
---|
354 | MCA_VERBOSE3(printf("p = %d T[%d..%d]\n", p, e0, e1)); |
---|
355 | if (p == 0) { |
---|
356 | set_ui32vector_j(T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot |
---|
357 | } |
---|
358 | else { |
---|
359 | set_ui32vector_j(T, e0, e1); |
---|
360 | } |
---|
361 | MCA_VERBOSE3(printf("\n")); |
---|
362 | } |
---|
363 | |
---|
364 | MCA_VERBOSE3(printf("display des tables d'EQ\n")); |
---|
365 | for (int p = 0; p < np; p++) { |
---|
366 | MCA * mca_par = mcas[p]; |
---|
367 | |
---|
368 | uint32 * T = mca_par->T; |
---|
369 | uint32 e0 = mca_par->e0; |
---|
370 | uint32 e1 = mca_par->e1; |
---|
371 | |
---|
372 | MCA_VERBOSE3(printf("p = %d T[%d..%d]\n", p, e0, e1)); |
---|
373 | if (p == 0) { |
---|
374 | MCA_VERBOSE3(display_ui32vector_number(T, e0 - 1, e0 + 10, "%5d", "T")); |
---|
375 | } |
---|
376 | else { |
---|
377 | MCA_VERBOSE3(display_ui32vector_number(T, e0, e0 + 10, "%5d", "T")); |
---|
378 | } |
---|
379 | MCA_VERBOSE3(printf("\n")); |
---|
380 | } |
---|
381 | //exit(-1); |
---|
382 | |
---|
383 | // ------------------------------------------------------------- // |
---|
384 | // -- calcul des parametres: passe #2 = parametres distribues -- // |
---|
385 | // ------------------------------------------------------------- // |
---|
386 | |
---|
387 | // table d'indirection distribuee D |
---|
388 | MCA_VERBOSE3(printf("nemax_par = %d\n", nemax_par)); |
---|
389 | for (int p = 0; p < np; p++) { |
---|
390 | MCA * mca_p = mcas[p]; |
---|
391 | uint32 ** D = mca_p->D; |
---|
392 | RegionStats ** F = mca_p->F; |
---|
393 | |
---|
394 | for (int k = 0; k < np; k++) { |
---|
395 | MCA * mca_k = mcas[k]; |
---|
396 | uint32 * T = mca_k->T; |
---|
397 | D[k] = T + k * nemax_par; // il faut soustraire le "MSB" |
---|
398 | RegionStats * stat = mca_k->stats; |
---|
399 | F[k] = stat + k * nemax_par; // il faut soustraire le "MSB" |
---|
400 | } // k |
---|
401 | } // p |
---|
402 | |
---|
403 | MCA_VERBOSE3(printf("table d'indirection distribuee D\n")); |
---|
404 | |
---|
405 | for (int p = 0; p < np; p++) { |
---|
406 | MCA_VERBOSE3(printf("== p = %d ==========\n", p)); |
---|
407 | |
---|
408 | MCA * mca_p = mcas[p]; |
---|
409 | uint32 ** D = mca_p->D; |
---|
410 | |
---|
411 | for (int k = 0; k < np; k++) { |
---|
412 | MCA * mca_k = mcas[k]; |
---|
413 | uint32 * T = mca_k->T; |
---|
414 | |
---|
415 | uint32 e0 = mca_k->e0; |
---|
416 | uint32 e1 = mca_k->e1; |
---|
417 | MCA_VERBOSE3(display_ui32vector_number(T, e0, e0 + 9, "%5d", "T")); |
---|
418 | MCA_VERBOSE3(display_ui32vector(D[k], 0, 9, "%5d", "D\n")); |
---|
419 | } |
---|
420 | MCA_VERBOSE3(printf("\n")); |
---|
421 | } |
---|
422 | |
---|
423 | for (int p = 0; p < np; p++) { |
---|
424 | if (p > 0) { |
---|
425 | //printf("i0_(%d) = %d i1_{%d} = %d\n", p, mcas[p]->i0, p-1, mcas[p-1]->i1); |
---|
426 | mcas[p]->E[mcas[p]->i0 - 1] = mcas[p - 1]->E[mcas[p - 1]->i1]; |
---|
427 | |
---|
428 | /*printf("E[%2d] = E[%2d] = %p\n", mcas[p ]->i0 - 1, |
---|
429 | mcas[p - 1]->i1, |
---|
430 | mcas[p - 1]->E[mcas[p - 1]->i1]);*/ |
---|
431 | } |
---|
432 | if (p < np - 1) { |
---|
433 | //printf("i1_(%d) = %d i0_{%d} = %d\n", p, mcas[p]->i1, p+1, mcas[p-1]->i0); |
---|
434 | mcas[p]->E[mcas[p]->i1 + 1] = mcas[p + 1]->E[mcas[p + 1]->i0]; |
---|
435 | |
---|
436 | /*printf("E[%2d] = E[%2d] = %p\n", mcas[p ]->i1 + 1, |
---|
437 | mcas[p + 1]->i0, |
---|
438 | mcas[p + 1]->E[mcas[p + 1]->i1]);*/ |
---|
439 | } |
---|
440 | } |
---|
441 | } |
---|
442 | |
---|
443 | |
---|
444 | // ----------------------------------- |
---|
445 | void MCA_Display_Parameters(MCA * mca) |
---|
446 | // ----------------------------------- |
---|
447 | { |
---|
448 | int np = mca->np; |
---|
449 | |
---|
450 | MCA ** mcas = mca->mcas; |
---|
451 | MCA * mca_par; |
---|
452 | (void) mca_par; |
---|
453 | |
---|
454 | MCA_VERBOSE1(printf("*** MCA_Display_Parameters ***\n")); |
---|
455 | |
---|
456 | MCA_VERBOSE2(printf(" height = %d\n", mca->height)); |
---|
457 | MCA_VERBOSE2(printf(" width = %d\n", mca->width)); |
---|
458 | MCA_VERBOSE2(printf(" np = %d\n", mca->np)); |
---|
459 | |
---|
460 | for (int p = 0; p < np; p++) { |
---|
461 | mca_par = mcas[p]; |
---|
462 | |
---|
463 | MCA_VERBOSE3(printf("Display MCA[%d]\n", p)); |
---|
464 | MCA_VERBOSE3(printf("p = %d\n", mca_par->p)); |
---|
465 | MCA_VERBOSE3(printf("i0 = %8d i1 = %8d\n", mca_par->i0, mca_par->i1)); |
---|
466 | MCA_VERBOSE3(printf("j0 = %8d j1 = %8d\n", mca_par->j0, mca_par->j1)); |
---|
467 | MCA_VERBOSE3(printf("e0 = %8d e1 = %8d\n", mca_par->e0, mca_par->e1)); |
---|
468 | } |
---|
469 | } |
---|
470 | |
---|
471 | |
---|
472 | // ------------------------- |
---|
473 | void MCA_Finalize(MCA * mca) |
---|
474 | // ------------------------- |
---|
475 | { |
---|
476 | int np = mca->np; |
---|
477 | |
---|
478 | MCA ** mcas = mca->mcas; |
---|
479 | MCA * mca_par; |
---|
480 | |
---|
481 | int i0, i1; |
---|
482 | int j0, j1; |
---|
483 | uint32 e0, e1; |
---|
484 | |
---|
485 | MCA_VERBOSE1(printf("*** MCA_Finalize ***\n")); |
---|
486 | |
---|
487 | #if PYR_BARRIERS |
---|
488 | free(mcas[0]->barriers); |
---|
489 | #endif |
---|
490 | |
---|
491 | for (int p = 0; p < np; p++) { |
---|
492 | mca_par = mcas[p]; |
---|
493 | |
---|
494 | i0 = mca_par->i0; |
---|
495 | i1 = mca_par->i1; |
---|
496 | j0 = mca_par->j0; |
---|
497 | j1 = mca_par->j1; |
---|
498 | e0 = mca_par->e0; |
---|
499 | e1 = mca_par->e1; |
---|
500 | |
---|
501 | // ---------- // |
---|
502 | // -- free -- // |
---|
503 | // ---------- // |
---|
504 | |
---|
505 | free_ui8matrix (mca_par->X, i0, i1, j0, j1); |
---|
506 | free_dist_ui32matrix(mca_par->E, i0, i1, j0, j1); |
---|
507 | |
---|
508 | if (p == 0) { |
---|
509 | free_ui32vector(mca_par->T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot |
---|
510 | free_RegionStatsVector(mca_par->stats, e0 - 1, e1); |
---|
511 | } |
---|
512 | else { |
---|
513 | free_ui32vector(mca_par->T, e0, e1); |
---|
514 | free_RegionStatsVector(mca_par->stats, e0, e1); |
---|
515 | } |
---|
516 | |
---|
517 | free_vvector((void **) mca_par->D, 0, np - 1); |
---|
518 | free_vvector((void **) mca_par->F, 0, np - 1); |
---|
519 | free(mca_par); |
---|
520 | } |
---|
521 | free(mcas); |
---|
522 | free(mca); |
---|
523 | } |
---|
524 | |
---|
525 | |
---|
526 | // ------------------------------- |
---|
527 | void MCA_Scatter_ImageX(MCA * mca) |
---|
528 | // ------------------------------- |
---|
529 | { |
---|
530 | // diffusion de l'image binaire source |
---|
531 | |
---|
532 | int np = mca->np; |
---|
533 | uint8 ** X = mca->mca->X; |
---|
534 | |
---|
535 | if (mca->p == 0) { |
---|
536 | MCA_VERBOSE1(printf("*** MCA_Scatter_ImageX ***\n")); |
---|
537 | } |
---|
538 | |
---|
539 | int i0 = mca->i0; |
---|
540 | int i1 = mca->i1; |
---|
541 | int width = mca->width; |
---|
542 | |
---|
543 | uint8 ** X_par = mca->X; |
---|
544 | uint32 ** E_par = mca->E; |
---|
545 | |
---|
546 | //printf("copie de [%d..%d]x[%d..%d]\n", i0, i1, 0, width - 1); |
---|
547 | for (int i = i0; i <= i1; i++) { |
---|
548 | for (int j = 0; j <= width - 1; j++) { |
---|
549 | X_par[i][j] = X[i][j]; |
---|
550 | E_par[i][j] = 0; // inutile normalement car ecriture de 0 |
---|
551 | } |
---|
552 | } |
---|
553 | } |
---|
554 | |
---|
555 | |
---|
556 | // ------------------------------ |
---|
557 | void MCA_Gather_ImageL(MCA * mca) |
---|
558 | // ------------------------------ |
---|
559 | { |
---|
560 | // recuperation de l'image d'etiquettes |
---|
561 | int np = mca->np; |
---|
562 | uint32 ** E = mca->mca->E; |
---|
563 | |
---|
564 | if (mca->p == 0) { |
---|
565 | MCA_VERBOSE1(printf("*** MCA_Gather_ImageL ***\n")); |
---|
566 | } |
---|
567 | |
---|
568 | int i0 = mca->i0; |
---|
569 | int i1 = mca->i1; |
---|
570 | int width = mca->width; |
---|
571 | |
---|
572 | uint32 ** E_par = mca->E; |
---|
573 | |
---|
574 | for (int i = i0; i <= i1; i++) { |
---|
575 | for (int j = 0; j <= width - 1; j++) { |
---|
576 | E[i][j] = E_par[i][j]; |
---|
577 | } |
---|
578 | } |
---|
579 | } |
---|
580 | |
---|
581 | |
---|
582 | // Local Variables: |
---|
583 | // tab-width: 4 |
---|
584 | // c-basic-offset: 4 |
---|
585 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) |
---|
586 | // indent-tabs-mode: nil |
---|
587 | // End: |
---|
588 | |
---|
589 | // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 |
---|
590 | |
---|
591 | |
---|