Created
September 18, 2012 21:33
-
-
Save marcel-valdez/3746070 to your computer and use it in GitHub Desktop.
código maestro para paralelización del algoritmo de escalamiento de imagen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void scale_master(int* image_data_ptr, int height, int width, int proc_count, int new_height, int new_width) { | |
/* El proceso maestro no es un 'worker' */ | |
int worker_count = proc_count - 1; | |
/* Se calcula el numero de renglones por 'worker' */ | |
int rows_slice = height / worker_count; | |
/* Se calcular el remanente para el ultimo proceso */ | |
int remainder = height % worker_count; | |
/* Se aloja memoria para la imagen 'trasladada' */ | |
int* new_image_data_ptr; | |
/* Inicializar datos */ | |
int opData[] = { width, height, new_height, new_width }; | |
/* Enviar renglones a cada proceso */ | |
int proc; | |
for(proc = 1; proc <= worker_count; proc++) { | |
/* Enviar primero los datos sobre los renglones a enviar*/ | |
send(opData, length(op_data), proc); | |
/* Obtener la direccion de memoria de los renglones que le corresponden al esclavo */ | |
int* row_data = &image_data_ptr[(proc - 1) * rows_slice * width]; | |
/* Obtener el tamano de los datos a enviar al esclavo */ | |
int current_rows_slice = (proc == worker_count) ? rows_slice + remainder : rows_slice; | |
int slave_data_size = current_rows_slice * width; | |
/* Enviar los renglones tal cual.*/ | |
send(row_data, slave_data_size, Pproc); | |
} | |
/* Recibir datos de los esclavos */ | |
int i; | |
for(i = 1; i <= worker_count; i++) { | |
int* rows_to_receive_ptr = &new_image_data_ptr[rows_slice * new_width * (i - 1)]; | |
int current_rows_slice = (i == worker_count) ? rows_slice + remainder : rows_slice; | |
recv(rows_to_receive_ptr, current_rows_slice * width, Pi); | |
} | |
display_image(new_image_data_ptr); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void scale_slave(int my_proc_idx, int total_procs) { | |
/* numero total de esclavos */ | |
int total_workers = total_procs - 1; | |
/* direccion de memoria de los datos de los renglones */ | |
int* rows_ptr; | |
/* obtener los datos que se recibiran del maestro: altura, anchura y delta X */ | |
int op_data[4]; | |
recv(op_data, 4, Pmaster); | |
int width = op_data[0], height = op_data[1], new_width = op_data[2], new_height = op_data[3]; | |
/* cantidad de renglones que me toca calcular */ | |
int rows_slice = (height / total_workers); | |
rows_slice += my_proc_idx == total_workers ? (height % total_workers) : 0; | |
/* Nueva altura del scaling */ | |
int new_rows_slice = (rows_slice) * (height / new_height); | |
/* obtener renglones del maestro */ | |
recv(rows_ptr, rows_slice * width, Pmaster); | |
/* calcular nuevos pixeles */ | |
scale_section(rows_ptr, width, rows_slice, new_width, new_rows_slice); | |
/* regresar pixeles al proceso maestro */ | |
send(rows_ptr, rows_slice * width, Pmaster); | |
} | |
int* scale_section (int* src_pixels, int src_width, int src_height, int dest_width, int dest_height) | |
{ | |
int* tmp_pixels; | |
/* Se hace el escalamiento horizontal */ | |
if(src_width != dest_width) { | |
tmp_pixels = malloc(dest_width * src_height * sizeof(int)); | |
/* se hace roll de 16 bits para hacer una division de ints (no de doubles) sin perder precision numerica */ | |
unsigned int delta_x = (src_width << 16) / dest_width; /* se asume que src_width no sera mayor a 2^16 */ | |
unsigned int scaled_pos_x = delta >> 1; /* se prepara la variable para conteo */ | |
for (int x = 0; x < dest_width; x++) { | |
int dest_index = x; | |
int src_index = scaled_pos_x >> 16; /* Se quitan los bits sobrantes de la division */ | |
for(int i = 0; i < src_height; i++) { | |
tmp_pixels[dest_index] = src_pixels[src_index]; | |
/* dest_index: el pixel en el siguiente renglon destino */ | |
dest_index += dest_width; | |
/* src_index: el pixel en el siguiente renglon original */ | |
src_index += src_width; | |
} | |
scaled_pos_x += delta_x; | |
} | |
}else { | |
tmp_pixels = src_pixels; | |
} | |
int* dest_pixels; | |
/* Se hace el escalamiento vertical */ | |
if(dest_height != src_height) | |
{ | |
/* se hace roll de 16-bits para hacer una division de ints (no de doubles) sin perder precision numerica */ | |
unsigned int delta_y = (src_height << 16) / dest_height; | |
unsigned int scaled_pos_y = delta_y >> 1; | |
int dest_index = 0; | |
int old_offset = 0; | |
int src_index = 0; | |
dest_pixels = malloc(dest_width * dest_height * sizeof(int)); | |
for (int y = 0; y < dest_height; y++) | |
{ | |
int offset = scaled_pos_y >> 16; | |
/* src_index solamente va incrementar si el offset != old_offset */ | |
src_index += (offset - old_offset) * dest_width; | |
System.arraycopy(tmp_pixels, src_index, dest_pixels, dest_index, dest_width); | |
/* store offset */ | |
old_offset = offset; | |
/* next offset */ | |
scaled_pos_y += delta_y; | |
/* indice de */ | |
dest_index += dest_width; | |
} | |
}else | |
{ | |
dest_pixels = tmp_pixels; | |
} | |
return dest_pixels; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment