/* write a color bar with (roughly) logarithmic scale as BMP image to FILE.
 */
static void
write_scale(apr_file_t *file)
{
  int x;
  word value = 0, inc = 1;

  /* write header to file */
  write_bitmap_header(file, 64, 1);

  for (x = 0; x < 64; ++x)
    {
      apr_size_t written;
      byte color[3] = { 128, 128, 128 };

      select_color(color, value);
      if (value + (int)inc < 0x10000)
        {
          value += inc;
          if (value >= 8 * inc)
            inc *= 2;
        }

      written = sizeof(color);
      apr_file_write(file, color, &written);
    }
}
/* Write the cluster read map for all files in INFO as BMP image to FILE.
 * If MAX_X is not 0, scale all lines to MAX_X pixels.  Use POOL for
 * allocations.
 */
static void
write_bitmap(apr_array_header_t *info,
             int max_x,
             apr_file_t *file,
             apr_pool_t *pool)
{
  int ysize = info->nelts;
  int xsize = 0;
  int x, y;
  apr_size_t row_size;
  apr_size_t written;
  color_t *line, *scaled_line;
  svn_boolean_t do_scale = max_x > 0;

  /* xsize = max cluster number */
  for (y = 0; y < ysize; ++y)
    if (xsize < APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts)
      xsize = APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts;

  /* limit picture dimensions (16k pixels in each direction) */
  if (xsize >= 0x4000)
    xsize = 0x3fff;
  if (ysize >= 0x4000)
    ysize = 0x3fff;
  if (max_x == 0)
    max_x = xsize;

  /* rows in BMP files must be aligned to 4 bytes */
  row_size = APR_ALIGN(max_x * sizeof(color_t), 4);

  /**/
  line = apr_pcalloc(pool, xsize * sizeof(color_t));
  scaled_line = apr_pcalloc(pool, row_size);

  /* write header to file */
  write_bitmap_header(file, max_x, ysize);

  /* write all rows */
  for (y = 0; y < ysize; ++y)
    {
      file_stats_t *file_info = APR_ARRAY_IDX(info, y, file_stats_t *);
      int block_count = file_info->read_map->nelts;
      for (x = 0; x < xsize; ++x)
        {
          color_t color = { 128, 128, 128 };
          if (x < block_count)
            {
              word count = APR_ARRAY_IDX(file_info->read_map, x, word);
              select_color(color, count);
            }

          memcpy(line[x], color, sizeof(color));
        }

      scale_line(scaled_line, max_x, line, block_count ? block_count : 1);

      written = row_size;
      apr_file_write(file, do_scale ? scaled_line : line, &written);
    }
}
Exemple #3
0
int generate_mandelbrot_simple(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;

	// Allocate buffer for picture data
	pixel_data_t *data = calloc(WIDTH * HEIGHT, sizeof(pixel_data_t));
	if (data)
	{
		// Create and open the output file
		FILE *file = fopen(filename, "wb");
		if (file)
		{
			// write the header
			write_bitmap_header(file, WIDTH, HEIGHT);

			// init time measurement
			start = current_time_millis();

			// calculate the data for the picture
			calc_mandelbrot(data, WIDTH, HEIGHT, 0, 0, WIDTH, HEIGHT);

			// write the data to the file
			fwrite(data, sizeof(pixel_data_t), WIDTH * HEIGHT, file);

			// close the file
			fclose(file);

			// print the measured time
			end = current_time_millis();
			printf("%.2f seconds\n", (double) (end - start) / 1000);

			// success
			return_code = EXIT_SUCCESS;
		}
		else
		{
			printf("Could not create the output file: %s\n", strerror(errno));
		}

		// free buffer
		free(data);
	}
	else
	{
		printf("Could not allocate memory for buffer.\n");
	}

	return return_code;
}
Exemple #4
0
int generate_mandelbrot_loop(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;
	
	// Create and open the output file, write header
	FILE *file = fopen(filename, "wb");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// close file handler
	fclose(file);
	
	// init time measurement
	start = current_time_millis();
	//return -1;
	// Loop
	int i;

	for (i=1; i<=MAX_PROCESSES; i++) {
		
		// Slicing: Slice width, height and offsets
		int sliceWidth   = WIDTH;
		int sliceHeight  = HEIGHT/MAX_PROCESSES;
		int widthOffset  = 0;
		int heightOffset = (i-1) * sliceHeight;
		
		// Allocate buffers for picture data
		pixel_data_t *data = calloc(sliceWidth * sliceHeight, sizeof(pixel_data_t));
		if (data)
		{
			// Open the output file
			FILE *file = fopen(filename, "a+");
			if (file)
			{
				// calculate the data for the picture
				calc_mandelbrot(data, WIDTH, HEIGHT, widthOffset, heightOffset, sliceWidth, sliceHeight);
				// write the data to the file
				fwrite(data, sizeof(pixel_data_t), sliceWidth * sliceHeight, file);

				// close the file
				fclose(file);
			}
			else
			{
				printf("Could not open the output file: %s\n", strerror(errno));
				return return_code;
			}

			// free buffer
			free(data);
		}
		else
		{
			printf("Could not allocate memory for buffer.\n");
			return return_code;
		}
	
	}

	// print the measured time
	end = current_time_millis();
	printf("\n%.2f seconds\n", (double) (end - start) / 1000);
	
	// success
	return_code = EXIT_SUCCESS;

	return return_code;
}
Exemple #5
0
int generate_mandelbrot_parallel(const char* filename)
{
	int return_code = EXIT_FAILURE;
	unsigned long start, end;
	
	// Create and open the output file, write header
	FILE *file = fopen(filename, "wb+");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// store header size for later offset
	long headerOffset = ftell(file);
	
	// close file handler
	fclose(file);

	// init time measurement
	start = current_time_millis();

	// set up loop and forking variables
	int i, status;
	pid_t pid = 1, wpid;

	for (i=0; i<=MAX_PROCESSES; i++) {
		if (pid>0) { // in parent process -> fork
			pid = fork();
		}
		if (pid<0) { // error while forking -> exit program
			printf("Error while forking: %s\n", strerror(errno));
			return return_code;
		} else if (pid==0) { // in child process -> do image generation work
			
			// Slicing: Slice the dimensions of the image into equally sized, horizontal stripes
			int sliceWidth   = WIDTH;
			int sliceHeight  = HEIGHT/MAX_PROCESSES;
			int widthOffset  = 0;
			int heightOffset = (i-1) * sliceHeight;
		
			// Allocate buffers for picture data
			pixel_data_t *data = calloc(sliceWidth * sliceHeight, sizeof(pixel_data_t));
			if (data)
			{
				// Open the output file
				FILE *file = fopen(filename, "rb+");
				if (file)
				{
					// calculate the data for the picture
					calc_mandelbrot(data, WIDTH, HEIGHT, widthOffset, heightOffset, sliceWidth, sliceHeight);

					// seek right position
					// SizeOfPixel * NumberOfPixels * PositionOfTheCurrentSlice + HeaderSize
					long byteoffset = sizeof(pixel_data_t)*sliceWidth*sliceHeight*(i-1) + headerOffset;
					fseek(file, byteoffset, SEEK_SET);
				
					// write the data to the file
					fwrite(data, sizeof(pixel_data_t), sliceWidth * sliceHeight, file);

					// close the file
					fclose(file);
					
					// exit the process, return to main
					exit(1);
				}
				else
				{
					printf("Could not open the output file: %s\n", strerror(errno));
					return return_code;
				}

				// free buffer
				free(data);
			}
			else
			{
				printf("Could not allocate memory for buffer.\n");
				return return_code;
			}
		}
	
	}

	// wait for children to finish
	for (i=0; i<MAX_PROCESSES; i++) {
		wait(&status);
	}
	
	//re-write header in case it got overwritten - yes we know this is a bug. we don't know how to solve it. this gets around the symptoms, it's as good as we got it
	file = fopen(filename, "rb+");
	if (!file) {
		printf("Could not create the output file: %s\n", strerror(errno));
		return return_code;
	}
	fseek(file, 0, SEEK_SET);
	// write header
	write_bitmap_header(file, WIDTH, HEIGHT);
	
	// close file handler
	fclose(file);

	// print the measured time
	end = current_time_millis();
	printf("\n%.2f seconds\n", (double) (end - start) / 1000);
	
	// success
	return_code = EXIT_SUCCESS;

	return return_code;
}