Skip to content

Instantly share code, notes, and snippets.

@marcel-valdez
Created September 18, 2012 21:33
Show Gist options
  • Save marcel-valdez/3746070 to your computer and use it in GitHub Desktop.
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
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);
}
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