
inline void pixel_move(bitmap src,struct coord srcp, bitmap dest, struct coord destp, struct coord size);
{
	if (dest.y >= 0 && dest.y < size.y
			dest.x >= 0 && dest.x < size.x) {
		out[dest.y][dest.x] = in[src.y][src.x]; //fixme
	}
}

px_transform im_shift(struct coord in, struct coord *out, void* param)
{
	struct coord *shift= (struct coord*)param;
	out->x = in.x+shift->x;
	out->y = in.y+shift->y;
}

px_transform im_scale(struct coord in, struct coord *out, void* param)
{
	double *scale= (double*)param;
	out->x = (int)(in.x * scale[0]);
	out->y = (int)(in.y * scale[1]);
}

px_transform im_rot(struct coord in, struct coord *out, void* param)
{
	double *rot = (double*)param;
	double c = cos(rot);
	double s = sin(rot);
	out->x = (int)(in.x*c + in.y*s);
	out->y = (int)(in.x*s + in.y*c);;
}

int transform_slave(int rank, int nproc, struct coord size, px_transform xform, void* param)
{
	struct coord src;
	struct coord* dest_row;
	rank--; nproc--;	//proc 0 doesn't execute this
	dest_row = malloc(sizeof(struct coord)*width);
	for(src.y=rank; src.y < size.y; src.y +=nproc) {
		for(src.x=0; src.x < size.x; src.x++) {
			xform(src,dest_row+src.x, param);		
		}
		MPI_Send(dest_row,size.x,MPI_INT_INT, XFORM_MSTR, ROW_TAG, MPI_COMM_WORLD);
	}
	free(dest_row);
	return 0;
}

int transform_master(int nproc, struct coord size, bitmap in, bitmap out)
{
	MPI_Status stat;
	struct coord src;
	struct coord* dest_row, dest;
	dest_row = malloc(sizeof(struct coord)*width);
	for(src.y=0; src.y < size.y; src.y++) {
		MPI_Recv(dest_row,size.x,MPI_INT_INT, src.y%(nproc-1)+1, ROW_TAG, MPI_COMM_WORLD, &stat);
		for(src.x=0; src.x < size.x; src.x++) {
			pixel_move(in,src,out,dest_row[src.x],size);
		}
	}
	free(dest_row);
	return 0;
}

int transform_seq(struct coord size, bitmap in, bitmap out,px_transform xform, void* param)
{
	struct coord src;
	struct coord dest;
	for(src.y=0; src.y < size.y; src.y++) {
		for(src.x=0; src.x < size.x; src.x++) {
			xform(src,&dest, param);
			pixel_move(in,src,out,dest,size);			
		}
	}
}
