Beispiel #1
0
void bresenham (BinaryData *binary, int x1, int y1, int x2, int y2, rgb_pixel_t pixel)
{
	int dx = x2 - x1, dy = y2 - y1, i, e;
	int incx = 1, incy = 1, inc1, inc2;
	int x, y;

	if (dx < 0)  dx = -dx;
	if (dy < 0)  dy = -dy;
	if (x2 < x1) incx = -1;
	if (y2 < y1) incy = -1;

	x = x1;
	y = y1;

	if (dx > dy)
	{
		bmp_set_pixel (binary->distance_curve, x, y, pixel);
		e = 2 * dy - dx;
		inc1 = 2 * (dy -dx);
		inc2 = 2 * dy;

		for (i = 0; i < dx; i++)
		{
			if (e >= 0)
			{
				y += incy;
				e += inc1;
			}

			else
				e += inc2;

			x += incx;
			bmp_set_pixel (binary->distance_curve, x, y, pixel);
		}
	}

	else
	{
		bmp_set_pixel (binary->distance_curve, x, y, pixel);
		e = 2 * dx - dy;
		inc1 = 2 * (dx - dy);
		inc2 = 2 * dx;

		for (i = 0; i < dy; i++)
		{
			if (e >= 0)
			{
				x += incx;
				e += inc1;
			}

			else
				e += inc2;

			y += incy;
			bmp_set_pixel (binary->distance_curve, x, y, pixel);
		}
	}
}
Beispiel #2
0
int main(int argc, char **argv)
{
    bmpfile_t *bmp;
    int i, j;
    char* infilename;
    FILE* infile;
    char* outfile;
    int width;
    int height;
    int depth;
    unsigned char red, green, blue; // 8-bits each
    //unsigned char pixel[3]; // 24-bits per pixel

    if (argc < 6) {
        printf("Usage: %s infile width height depth outfile.\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    infilename = argv[1];
    outfile = argv[5];

    infile = fopen(infilename, "rb");
    if (NULL == infile) {
        perror("Couldn't read infile");
        exit(EXIT_FAILURE);
    }

    width = atoi(argv[2]);
    height = atoi(argv[3]);
    depth = atoi(argv[4]);

    // should be depth/8 at 16-bit depth, but 32-bit depth works better
    char buffer[height * width * 3];
    printf("depth: %d\n", depth);
    if (fread(&buffer, 1, height * width * 3, infile) != height * width * 3) {
        fputs("infile dimensions don't match the size you supplied\n", stderr);
    }

    if ((bmp = bmp_create(width, height, depth)) == NULL) {
        printf("Invalid depth value: '%d'. Try 1, 4, 8, 16, 24, or 32.\n", depth);
        exit(EXIT_FAILURE);
    }

    for (i = 0; i < width; ++i) {
        for (j = 0; j < height; ++j) {

            red     = buffer[(width * j + i) * 3 + 0];
            green   = buffer[(width * j + i) * 3 + 1];
            blue    = buffer[(width * j + i) * 3 + 2];

            rgb_pixel_t bpixel = {blue, green, red, 0};
            bmp_set_pixel(bmp, i, j, bpixel);
        }
    }

    bmp_save(bmp, outfile);
    bmp_destroy(bmp);

    return 0;
}
Beispiel #3
0
// IMAGE FILE OPERATIONS >>>
void resetImage(int width, int height)
{
    int x, y;
    for (x = 1; x <= width; x++)
        for (y = 1; y <= height; y++)
            bmp_set_pixel(bmp, x, y, pixelB);
}
Beispiel #4
0
void test_bmpCreate(CuTest* tc)
{
	bmpfile_t* bmp;
	int i,j;
	int width = 64, height = 64, depth = 1; 
	bw_pixel_t pixel;
	pixel.uniColour = 128;
	CuAssertTrue(tc,NULL!=(bmp=bmp_create(64,64,1)));
	for (i = 10, j = 10; j < 64; ++i, ++j) {
		bmp_set_pixel(bmp, i, j, pixel);
		pixel.uniColour++;
		bmp_set_pixel(bmp, i + 1, j, pixel);
		bmp_set_pixel(bmp, i, j + 1, pixel);
	}	
	CuAssertTrue(tc,width==bmp_get_width(bmp));
	CuAssertTrue(tc,height==bmp_get_height(bmp));
	CuAssertTrue(tc,depth==bmp_get_depth(bmp));
	bmp_save(bmp, "testimage.bmp");
	bmp_destroy(bmp);
}
void naCreateABmp(JNIEnv* env, jclass clazz, jint width, jint height, jint depth) {
	bmpfile_t *bmp;
	int i, j;
	rgb_pixel_t pixel = {128, 64, 0, 0};
	if (NULL == (bmp = bmp_create(width, height, depth))) {
		LOGE(1, "Invalid depth value: %d. (valid values include 1, 4, 8, 16, 24, 32)\n", depth);
		return;
	}

	for (i = 10, j = 10; j < height; ++i, ++j) {
		bmp_set_pixel(bmp, i, j, pixel);
		pixel.red++;
		pixel.green++;
		pixel.blue++;
		bmp_set_pixel(bmp, i + 1, j, pixel);
		bmp_set_pixel(bmp, i, j + 1, pixel);
	}

	bmp_save(bmp, "/sdcard/test_bs_static.bmp");
	bmp_destroy(bmp);
}
Beispiel #6
0
void bmp_draw_line(BMPFile * bmp, uint32_t x1, uint32_t y1,
                   uint32_t x2, uint32_t y2, uint32_t color)
{
    uint32_t dx, dy;
    int32_t sx, sy, err, err2;

    if (x1 < x2) {
        sx = 1;
        dx = x2 - x1;
    } else {
        sx = -1;
        dx = x1 - x2;
    }

    if (y1 < y2) {
        sy = 1;
        dy = y2 - y1;
    } else {
        sy = -1;
        dy = y1 - y2;
    }

    err = dx - dy;

    for (;;)
    {
        bmp_set_pixel(bmp, x1, y1, color);

        if (x1 == x2 && y1 == y2)
            break;

        err2 = 2 * err;

        if (err2 > -1 * (int32_t) dy) {
            err -= dy;
            x1 += sx;
        }

        if (err2 < (int32_t) dx) {
            err += dx;
            y1 += sy;
        }
    }
}
void saveimage(){
    printf("Good hits: %llu\t Miss hits: %llu\t Bad hits: %llu\t %f\n", goodHits, missHits, badHits, (f32)goodHits/(badHits > 0 ? badHits : 1));

    bmpfile_t *bmp;

    f32 amax = __sec_reduce_max(h[0:hwid * hhei].a);
    amax = MAX(amax, 1);



    bmp = bmp_create(hwid, hhei, 24);

    printf("generating image");

    cilk_for(i32 i = 0; i < hwid * hhei; i++){
        const f32 a = log(h[i].a) / log(amax);

        f32 maxColor = MAX3(h[i].r, h[i].g, h[i].b);

        if(maxColor <= 0)
            maxColor = 1;

        const u8 r = (h[i].r / h[i].a) * 0xFF * a;
        const u8 g = (h[i].g / h[i].a) * 0xFF * a;
        const u8 b = (h[i].b / h[i].a) * 0xFF * a;

        const rgb_pixel_t pixel = {b, g, r, 0xFF};
        const u32 x = i % hwid;
        const u32 y = i / hwid;
        bmp_set_pixel(bmp, x, y, pixel);

        // progress bar
        if((i % ((hwid * hhei) / 20)) == 0)
            printf(".");
    }

    printf(" done\n");

    printf("saving image... ");
    bmp_save(bmp, "fractal.bmp");
    bmp_destroy(bmp);
    printf("done\n");
}
int main(int argc, char **argv) {

	bmpfile_t *bmp_resized = NULL;
	bmpfile_t *result = NULL;
	int width, height,num_threads, i, j;
	float scale;
	
	// Parse argv.
	scale = (float)atof(argv[2]);
	num_threads = atoi(argv[3]);
	
	omp_set_num_threads(num_threads);
	
	bmp_resized = bmp_scale( argv[1], scale, num_threads);
	width = bmp_get_dib(bmp_resized).width;
	height = bmp_get_dib(bmp_resized).height; 
	
	result = bmp_create(width, height, 8);	
	if( result != NULL){
	
	//printf(" about to make new file!\n");
	//#pragma omp parallel for private(j)
	for (i = 0; i < width; ++i) {
	
      for (j = 0; j < height; ++j) {
		int num = omp_get_thread_num();
		//printf("Thread %i has i = %i and j = %i\n", num, i, j);
		rgb_pixel_t *p = bmp_get_pixel(bmp_resized, i, j);
		bmp_set_pixel(result, i, j, *p);	
	  }

	}
	//printf("made new file!\n");
	bmp_save(result, "bmp_scale.bmp");
	}
	
	//printf("finished saving!\n");
    bmp_destroy(bmp_resized);
    return 0;
	

}
Beispiel #9
0
int draw_reconstruction_bitmap(PSIRT *psirt) {
	int i=0,j=0;
	double* pixel_intensity = reconstruction(psirt);
	// DESENHAR
	bmpfile_t *bmp = bmp_create(RES_X, RES_Y, 24);
	for (i = 0; i < RES_X; i++) {
		for (j = 0; j < RES_Y; j++) {
			double pixel = pixel_intensity[i + (j * RES_X)];

			// Alternativa 1: função linear simples
			int paint_of_choice = (pixel * 255);

			// Alternativa 2: função polinomial
			#ifdef REC_PAINT_POLY
			paint_of_choice = pow(pixel, 2) * 255;
			#endif

			// Alternativa 3: função exponencial
			#ifdef REC_PAINT_EXP
			paint_of_choice = pow(pixel, pixel) * 255;
			#endif

			// Alternativa 3: função customizada
			#ifdef REC_PAINT_CUSTOM
			paint_of_choice = 255;
			if (pixel < .2)
				paint_of_choice = 0;
			else if (pixel < .4)
				paint_of_choice = 255 / 4;
			#endif

			rgb_pixel_t pix = { paint_of_choice, paint_of_choice, paint_of_choice, 0 };
			bmp_set_pixel(bmp, i, j, pix);
		}
	}
	bmp_save(bmp, "psirt_output.bmp");
	bmp_destroy(bmp);
	free(pixel_intensity);
	return i;
}
Beispiel #10
0
bmpfile_t * complex_to_bmp (COMPLEX **c, int size)
{
	bmpfile_t *bmp = bmp_create (size, size, 8);

	for (int y = 0; y < size; y++)
	{
		for (int x = 0; x < size; x++)
		{
			unsigned char r = (c[y][x].real * 256.0 > 255.0) ? 
				255 : (unsigned char)(c[y][x].real * 256.0);
			unsigned char b = (c[y][x].imag * 256.0 > 255.0) ? 
				255 : (unsigned char)(c[y][x].imag * 256.0);
			unsigned char g = ((c[y][x].real * 128.0) + (c[y][x].imag * 128.0) > 255) ?
				255 : (unsigned char)(c[y][x].real * 128.0) + (c[y][x].imag * 128.0);

			rgb_pixel_t pixel = {r, g, b, 0};
			bmp_set_pixel (bmp, x, y, pixel);
		}
	}

	return bmp;
}
Beispiel #11
0
void bmp_draw_rectangle(BMPFile * bmp, uint32_t x1, uint32_t y1,
                        uint32_t x2, uint32_t y2, uint32_t color)
{
    int32_t x, y;
    uint32_t tmp;

    if (x1 > x2) {
        tmp = x1;
        x1 = x2;
        x2 = tmp;
    }

    if (y1 > y2) {
        tmp = y1;
        y1 = y2;
        y2 = tmp;
    }

    for(y = y1; y < y2; y++) {
        for(x = x1; x < x2; x++) {
            bmp_set_pixel(bmp, x, y, color);
        }
    }
}
Beispiel #12
0
void draw_projection_bitmap(PSIRT* psirt)
{
	bmpfile_t *bmp_proj = bmp_create(RES_X, RES_Y, 24);

	int i, j;
	for (i = 0; i < psirt->n_projections; i++)
	{
		for (j = 0; j < psirt->n_trajectories; j++)
		{
			Trajectory* t = psirt->projections[i]->lista_trajetorias[j];

			Vector2D begin, end, d;
			sum_void(t->source, t->direction, &begin);
			d.x = t->direction->x;
			d.y = t->direction->y;

			mult_constant_void(&d, -1);
			sum_void(t->source, &d, &end);

			// Desenhar linha
			double delta = (begin.y-end.y)/(begin.x-end.x);
			double x, y;

			int k = 0;
			for (k = -1000; k < 1000; k++)
			{
				x = k*0.001f;
				y = ( delta*(x-begin.x) ) + begin.y;
				rgb_pixel_t pix = {0,0,255,0};
				bmp_set_pixel(bmp_proj, x*RES_X+RES_X/2, y*RES_Y+RES_Y/2, pix);
			}
		}
	}
	bmp_save(bmp_proj, "projections_output.bmp");
	bmp_destroy(bmp_proj);
}
Beispiel #13
0
void bmp_draw_circle(BMPFile * bmp, uint32_t x, uint32_t y,
                     uint32_t radius, uint32_t color)
{
    int32_t f = 1 - radius;
    int32_t ddF_x = 1;
    int32_t ddF_y = -2 * radius;
    int32_t cx = 0;
    int32_t cy = radius;

    bmp_set_pixel(bmp, x, y + radius, color);
    bmp_set_pixel(bmp, x, y - radius, color);
    bmp_set_pixel(bmp, x + radius, y, color);
    bmp_set_pixel(bmp, x - radius, y, color);

    while(cx < cy)
    {
        // ddF_x == 2 * x + 1;
        // ddF_y == -2 * y;
        // f == x*x + y*y - radius*radius + 2*x - y + 1;
        if(f >= 0)
        {
            cy--;
            ddF_y += 2;
            f += ddF_y;
        }
        cx++;
        ddF_x += 2;
        f += ddF_x;
        bmp_set_pixel(bmp, x + cx, y + cy, color);
        bmp_set_pixel(bmp, x - cx, y + cy, color);
        bmp_set_pixel(bmp, x + cx, y - cy, color);
        bmp_set_pixel(bmp, x - cx, y - cy, color);
        bmp_set_pixel(bmp, x + cy, y + cx, color);
        bmp_set_pixel(bmp, x - cy, y + cx, color);
        bmp_set_pixel(bmp, x + cy, y - cx, color);
        bmp_set_pixel(bmp, x - cy, y - cx, color);
    }
}
bmpfile_t* bilinear_resize(bmpfile_t* bmp_read, float scale, int num_threads){

	bmpfile_t *bmp_resize = NULL;
	int width, height;
	int en_width, en_height;
	int i, j;

	width = bmp_get_dib(bmp_read).width;
	height = bmp_get_dib(bmp_read).height; 
	
	en_width = (int)(width * scale);
	en_height = (int)(height * scale);
	
	float x_ratio = ((float)(width-1))/en_width ;
    float y_ratio = ((float)(height-1))/en_height ;
	
	int temp[en_width*en_height];
	int pixels[ width*height];
	
	bmp_to_array( pixels, bmp_read, width, height);
	
	//printf(" after to array\n");
	bmp_resize = bmp_create(en_width, en_height, 8);
	
	// do bilinear interpolatin to get new picture
	if( bmp_resize != NULL){
	
	#pragma omp parallel for private(j)
    for (i = 0; i < en_width; ++i) {
	 
      for (j = 0; j < en_height; ++j) {
	        
			int x = (int)(x_ratio * i) ;
            int y = (int)(y_ratio * j) ;
            float x_diff = (x_ratio * i) - x ;
            float y_diff = (y_ratio * j) - y ;
			int index = (x*height + y);
         		
			rgb_pixel_t *a = get_8bpp_color(bmp_read, pixels[index]);
			rgb_pixel_t *b = get_8bpp_color(bmp_read, pixels[index+height]);
			rgb_pixel_t *c = get_8bpp_color(bmp_read, pixels[index+1]);		
			rgb_pixel_t *d = get_8bpp_color(bmp_read, pixels[index+height+1]);
			
			int ared = a->red;
			int agreen = a->green;
			int ablue = a->blue;
			int bred = b->red;
			int bgreen = b->green;
			int bblue = b->blue;
			int cred = c->red;
			int cgreen = c->green;
			int cblue = c->blue;
			int dred = d->red;
			int dgreen = d->green;
			int dblue = d->blue;
					
			int red = ared*(1-x_diff)*(1-y_diff) + bred*(x_diff)*(1-y_diff) + cred*y_diff*(1-x_diff) + dred*(x_diff*y_diff);
			int green = agreen*(1-x_diff)*(1-y_diff) + bgreen*(x_diff)*(1-y_diff) + cgreen*y_diff*(1-x_diff) + dgreen*(x_diff*y_diff);
			int blue = ablue*(1-x_diff)*(1-y_diff) + bblue*(x_diff)*(1-y_diff) + cblue*y_diff*(1-x_diff) + dblue*(x_diff*y_diff);

			rgb_pixel_t curr_pixel;
			curr_pixel.red = (uint8_t)red;
			curr_pixel.green = (uint8_t)green;
			curr_pixel.blue = (uint8_t)blue;
			curr_pixel.alpha = 0;
	
			bmp_set_pixel(bmp_resize, i, j, curr_pixel);
					
      }
    }
	}
//	printf("still resizing!\n");
	return bmp_resize;
}
Beispiel #15
0
void binary_draw_pixel (BinaryData *binary, unsigned char pixel_pos[2], rgb_pixel_t pixel)
{
	frame_inc (binary->frame, pixel_pos[0], pixel_pos[1]);
	bmp_set_pixel (binary->bmp, pixel_pos[0], pixel_pos[1], pixel);
}
int main(int argc, char** argv)
{
	// declare and initialize variables
	bmpfile_t *bmp_read = NULL,
			  *bmp_with_corners = NULL,
			  *bmp_gray = NULL;
	int x = 0,
		y = 0,
		u = 0,
		v = 0,
		a = 0,
		b = 0,
		width = 0,
		height = 0,
		window_x = 1,
		window_y = 1,
		threshold = 20;

	float** cornerness_map = NULL;
	
	// arg count must be at least 2 to have a filename arg
	if ( argc < 3 )
	{
		printf("Usage: %s input_file output_file [threshold]\n", argv[0]);
		return 1;
	}

	if ( argc >= 4 )
		threshold = atoi(argv[3]);

	// read in the BMP
	bmp_read = bmp_create_8bpp_from_file(argv[1]);

	// if bmp_read is null, the file wasn't found
	if ( !bmp_read )
	{
		printf("File %s could not be found\n", argv[1]);
		return 1;
	}

	// get the height and width so we can build our map and new image
	width = bmp_get_dib(bmp_read).width;
    height = bmp_get_dib(bmp_read).height;

	// construct the cornerness map
	cornerness_map = (float**) malloc( sizeof(float*) * width );
	for ( x = 0; x < width; x++ )
		cornerness_map[x] = (float*) malloc( sizeof(float) * height );

	// calculate V_u,v(x,y)
	for ( x = 0; x < width; x++ )	
	{
		for ( y = 0; y < height; y++ ) 
		{
			if ( x < 1 + HALF_WINDOW_WIDTH || x > width - 1 - (1 + HALF_WINDOW_WIDTH) || y < 1 + HALF_WINDOW_WIDTH || y > height - 1 - (1 + HALF_WINDOW_WIDTH) )
				cornerness_map[x][y] = 0;
			else
			{
				// the cornerness map should have the minumum V_u,v(x,y)
				float minV;
				float currV;
				minV = -1;
				for ( u = -1; u <= 1; u++ )	
				{
					for ( v = -1; v <= 1; v++ )	
					{
						if ( u != 0 || v != 0 )
						{
							currV = 0;
							for ( a = -HALF_WINDOW_WIDTH; a <= HALF_WINDOW_WIDTH; a++ )	
							{
								for ( b = -HALF_WINDOW_WIDTH; b <= HALF_WINDOW_WIDTH; b++ )	
								{
									rgb_pixel_t *pixel_A = bmp_get_pixel(bmp_read, x + u + a, y + v + b);
									float intensity_A = 0.2989 * (*pixel_A).red + 0.5870 * (*pixel_A).green + 0.1140 * (*pixel_A).blue;

									rgb_pixel_t *pixel_B = bmp_get_pixel(bmp_read, x + a, y + b);
									float intensity_B = 0.2989 * (*pixel_B).red + 0.5870 * (*pixel_B).green + 0.1140 * (*pixel_B).blue;

									currV += (intensity_A - intensity_B) * (intensity_A - intensity_B);
								}
							}
							if ( minV == -1 || currV < minV )
								minV = currV;
						}

					}
				}
				// only keep the values above the threshold
				if ( minV > threshold )
					cornerness_map[x][y] = minV;
				else 
					cornerness_map[x][y] = 0;
			}
		}
	}

	// image with corners highlighted
/*	bmp_with_corners = bmp_create(width, height, DEPTH);
	rgb_pixel_t highlight = {255,0,0,0};

	// modify original bmp to include highlight color
	printf("ncolors in bmp_read: %u\n", bmp_get_dib(bmp_read).ncolors);
	rgb_pixel_t* unusedColor;

	for ( x = 0; x < bmp_get_dib(bmp_read).ncolors; x++ )
		unusedColor = &(bmp_read->colors[x]);*/
	
	// draw picture without using nonmaximal supression
/*	for ( x = 0; x < width; x++ )
	{
		for ( y = 0; y < height; y++ )
		{
			if ( cornerness_map[x][y] > 0 )
			{
				bmp_set_pixel(bmp_with_corners, x, y, highlight);
			}
			else
			{
				rgb_pixel_t *pixel = bmp_get_pixel(bmp_read, x, y);
				bmp_set_pixel(bmp_with_corners, x, y, *pixel);
			}
		}
	}
*/
	 

	// draw picture with nonmaximal suppression
	rgb_pixel_t highlight = {255,0,0,0};
	for ( x = HALF_NEIGHBORHOOD_WIDTH; x < width - HALF_NEIGHBORHOOD_WIDTH; x++)
	{
		for ( y = HALF_NEIGHBORHOOD_WIDTH; y < height - HALF_NEIGHBORHOOD_WIDTH; y++ )
		{
			int value = cornerness_map[x][y];
			int isMax = 1;
			for ( u = x-HALF_NEIGHBORHOOD_WIDTH; u <= x+HALF_NEIGHBORHOOD_WIDTH; u++ )
			{
				for ( v = y-HALF_NEIGHBORHOOD_WIDTH; v <= y+HALF_NEIGHBORHOOD_WIDTH; v++ )
				{
					if ( u != x || v != y )
					{
						if ( isMax == 1 && cornerness_map[u][v] < value )
							isMax = 1;
						else
							isMax = 0;
					}
				}
			}
			if (isMax == 1)
				bmp_set_pixel(bmp_read, x, y, highlight);
/*			else
				bmp_set_pixel(bmp_with_corners, x, y, *bmp_get_pixel(bmp_read, x, y));*/
		}
	}

	bmp_save(bmp_read, argv[2]);

	// clean up
	bmp_destroy(bmp_read);
	bmp_destroy(bmp_with_corners);
	for ( x = 0; x < width; x++ )
		free(cornerness_map[x]);
	free(cornerness_map);

	return 0;
}
Beispiel #17
0
// AXIOM OPERATIONS >>>
void drawLine()
{
    int x1, y1, x2, y2;
    
    x1 = currX;
    y1 = currY;
    x2 = currX + ceil(length * cos(currH));
    y2 = currY + ceil(length * sin(currH));
    
    if (x1 == x2)
    {
        if (y2 > y1)
        {
            int i;
            for (i = y1; i <= y2; i++)
                bmp_set_pixel(bmp, x1, i, pixelW);
        }
        else
        {
            int i;
            for (i = y1; i >= y2; i--)
                bmp_set_pixel(bmp, x1, i, pixelW);
        }
    }
    else if (y1 == y2)
    {
        if (x2 > x1)
        {
            int i;
            for (i = x1; i <= x2; i++)
                bmp_set_pixel(bmp, i, y1, pixelW);
        }
        else
        {
            int i;
            for (i = x1; i >= x2; i--)
                bmp_set_pixel(bmp, i, y1, pixelW);
        }
    }
    else
    {
        if (x2 > x1)
        {
            int i;
            for (i = x1; i <= x2; i++)
            {
                int y;
                y = tan(currH) * (i - x2) + y1;
                bmp_set_pixel(bmp, i, y, pixelW);
            }
        }
        else
        {
            int i;
            for (i = x1; i >= x2; i--)
            {
                int y;
                y = tan(currH) * (i - x1) + y1;
                bmp_set_pixel(bmp, i, y, pixelW);
            }
        }
    }
    
    currX = x2;
    currY = y2;
}
Beispiel #18
0
int vista_fswc_grab()
{
	/* Allocate memory for the average bitmap buffer. */
	abitmap = calloc(config->width * config->height * 3, sizeof(avgbmp_t));
	if(!abitmap)
	{
		ERROR("Out of memory.");
		return(-1);
	}

	/* Grab (and do nothing with) the skipped frames. */
	for(frame = 0; frame < config->skipframes; frame++)
		if(src_grab(&src) == -1) break;

	/* Grab the requested number of frames. */
	for(frame = 0; frame < config->frames; frame++)
	{
		if(src_grab(&src) == -1) break;
		
		/* Add frame to the average bitmap. */
		switch(src.palette)
		{
		case SRC_PAL_PNG:
			fswc_add_image_png(&src, abitmap);
			break;
		case SRC_PAL_JPEG:
		case SRC_PAL_MJPEG:
			fswc_add_image_jpeg(&src, abitmap);
			break;
		case SRC_PAL_S561:
			fswc_add_image_s561(abitmap, src.img, src.length, src.width, src.height, src.palette);
			break;
		case SRC_PAL_RGB32:
			fswc_add_image_rgb32(&src, abitmap);
			break;
		case SRC_PAL_BGR32:
			fswc_add_image_bgr32(&src, abitmap);
			break;
		case SRC_PAL_RGB24:
			fswc_add_image_rgb24(&src, abitmap);
			break;
		case SRC_PAL_BGR24:
			fswc_add_image_bgr24(&src, abitmap);
			break;
		case SRC_PAL_BAYER:
		case SRC_PAL_SGBRG8:
		case SRC_PAL_SGRBG8:
			fswc_add_image_bayer(abitmap, src.img, src.length, src.width, src.height, src.palette);
			break;
		case SRC_PAL_YUYV:
		case SRC_PAL_UYVY:
			fswc_add_image_yuyv(&src, abitmap);
			break;
		case SRC_PAL_YUV420P:
			fswc_add_image_yuv420p(&src, abitmap);
			break;
		case SRC_PAL_NV12MB:
			fswc_add_image_nv12mb(&src, abitmap);
			break;
		case SRC_PAL_RGB565:
			fswc_add_image_rgb565(&src, abitmap);
			break;
		case SRC_PAL_RGB555:
			fswc_add_image_rgb555(&src, abitmap);
			break;
		case SRC_PAL_Y16:
			fswc_add_image_y16(&src, abitmap);
			break;
		case SRC_PAL_GREY:
			fswc_add_image_grey(&src, abitmap);
			break;
		}
	}
	
	/* Copy the average bitmap image to a gdImage. */
	original = gdImageCreateTrueColor(config->width, config->height);
	if(!original)
	{
		ERROR("Out of memory.");
		free(abitmap);
		return(-1);
	}
	
	pbitmap = abitmap;
	for(y = 0; y < config->height; y++)
		for(x = 0; x < config->width; x++)
		{
			int px = x;
			int py = y;
			int colour;
			
			colour  = (*(pbitmap++) / config->frames) << 16;
			colour += (*(pbitmap++) / config->frames) << 8;
			colour += (*(pbitmap++) / config->frames);
			
			gdImageSetPixel(original, px, py, colour);
		}
	
	free(abitmap);

        // scaling stuff just for Ian to learn the art of coding
        if((config->width != VISTA_WIDTH) ||
           (config->height != VISTA_HEIGHT)) {
		gdImage *im;	
		im = gdImageCreateTrueColor(VISTA_WIDTH, VISTA_HEIGHT);
		if(!im)
		{
			WARN("Out of memory.");
			return(-1);
		}
		gdImageCopyResampled(im, original, 0, 0, 0, 0,
	   		VISTA_WIDTH, VISTA_HEIGHT, gdImageSX(original), gdImageSY(original));
		gdImageDestroy(original);
        	original = im;
        }

	// convert the gdimage to a BMP
	bmp = bmp_create(VISTA_WIDTH, VISTA_HEIGHT, 24);
	rgb_pixel_t pixel = {128, 64, 0, 0};
	int c;
	for(y = 0; y < VISTA_HEIGHT; y++) {
		for(x = 0; x < VISTA_WIDTH; x++)
		{
			c = gdImageGetPixel(original, x, y);
			pixel.red = gdImageRed(original, c);
			pixel.green = gdImageGreen(original, c);
			pixel.blue = gdImageBlue(original, c);
			bmp_set_pixel(bmp, x, y, pixel);
		}
	}

	gdImageDestroy(original);
	bmp_save(bmp, "/tmp/hope.bmp");
	bmp_destroy(bmp);

	return 0;
}