www.pudn.com > rgb_4p_jpg.rar > rgb_4p_jpg.c


/* 
 * Copyright (C) 2003 Samsung Electronics 
         SW.LEE 
    This program is under GPL2v

arm-linux-gcc -static -o jpg rgb_4p_jpg.c  -I/opt/host/armv4l/armv4l-redhat-linux/include/ -ljpeg  -L/opt/host/armv4l/armv4l-redhat-linux/lib/

*/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#include "../MiscDriver/userapp.h"
camif_param_t camif_cfg;

#define CAM_WIDTH 240
#define CAM_HEIGHT 180
#define FB_WIDTH 240
#define FB_HEIGHT 320

#define CODEC_NAME  "/dev/misc/preview"

static int cam_fp = -1;
static struct jpeg_compress_struct cinfo;
static int quality = 100;
static struct jpeg_error_mgr jerr;

static unsigned char *row_rgb = NULL;
static unsigned char *rgb = NULL;

static void fmalloc(int width, int height, int bpp)
{
	if (bpp == 16 ) { 
		bpp = 2;
	}
	else  {
		bpp = 4;
	}
	row_rgb = (unsigned char*)malloc(width*3);
	rgb = (unsigned char*)malloc(width*height*bpp);
	if ( !rgb || !row_rgb) printf("Memory Allocation Failed \n");
}


static void ffree(void)
{
	if (row_rgb) free(row_rgb);
	if (rgb)  free(rgb);
}


static inline void save_jpg(int width, int height, int bpp, int iter)
{
	int x, y;
	FILE *jpg_fp = NULL;
	char file_name[100];
	unsigned char *base;
	int Bytes;
	JSAMPROW row_pointer[1];

	switch (bpp) { 
		case 16: Bytes = 2; break;
		case 24: Bytes = 4; break;
		default: 
			printf("Wrong Param BPP: %d \n",bpp);
			return ;
	}
	row_pointer[0] = (JSAMPROW)row_rgb;

	 /* read from device */
	if (read(cam_fp, rgb, width*height*Bytes) < 0) {
		perror("read()");
		goto err;
	}
	sprintf(&file_name[0], "cap%d.jpg", iter);
	/* file create/open, note to "wb" */
	jpg_fp = fopen(&file_name[0], "wb");
	if (!jpg_fp) {
		perror(&file_name[0]);
		goto err;
	}
	printf("save to \"%s\"\n", file_name);
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
	jpeg_stdio_dest(&cinfo, jpg_fp);
	cinfo.image_width = width;
	cinfo.image_height = height;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo, quality, TRUE);
	jpeg_start_compress(&cinfo, TRUE);
	
	if (bpp == 16){
		/* RGB565 -> RGB888, compress */
		unsigned short *rgb16 = (unsigned short*)rgb;
		for (y = 0; y < height; y++) {
			base = row_rgb;
			for (x = 0; x < width; x++) {
				*base++ = ((*(rgb16 + y*width + x) & 0xf800) >> 8) & 0xff;
				*base++ = ((*(rgb16 + y*width + x) & 0x07e0) >> 3) & 0xff;
				*base++ = ((*(rgb16 + y*width + x) & 0x001f) << 3) & 0xff;
			}
			jpeg_write_scanlines(&cinfo, row_pointer, 1);
		}
	}
	else {
		unsigned char *rgb8;
		unsigned char *start; 
		for (y = 0; y < height; y++) {
			rgb8 =  rgb + y * width * 4;
			start = row_rgb;
			for (x = 0; x < width*4 ; x += 4) {
				*start++ = *(rgb8 + 2  + x);
				*start++ = *(rgb8 + 1  +x );
				*start++ = *(rgb8 + x);
			}
			jpeg_write_scanlines(&cinfo, row_pointer, 1);
		}
	}

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);
	fclose(jpg_fp);
err:
}

static int cam_init(void)
{
	int dev_fp = -1;

	dev_fp = open(CODEC_NAME, O_RDWR);
	if (dev_fp < 0) {
		perror(CODEC_NAME);
		return -1;
	}
	return dev_fp;
}


static inline void clear(char *dest)
{
	memset(dest, 0, FB_WIDTH*FB_HEIGHT*2);
}


static inline void print_fps(struct timeval *s, struct timeval *e)
{
	unsigned long time;
	unsigned long sec;
	unsigned long usec;
	int fps = 0;

	sec = e->tv_sec - s->tv_sec;
	if (e->tv_usec > s->tv_usec)
		usec = e->tv_usec - s->tv_usec;
	else {
		usec = e->tv_usec + 1000000 - s->tv_usec;	
		sec--;
	}
	time = sec * 1000 + (usec+1) / 1000;
	fps = 1000 / (time / 30);
	printf("%d fps\n", fps);
}

int main(int argc, char *argv[])
{
	unsigned int frames = 0;
	struct timeval start_tv, end_tv;
	struct timezone tz;
	int width, height, bpp;
	int goal;
	int found = 0;

	camif_cfg.dst_x = width  = atoi(argv[1]);
	camif_cfg.dst_y = height = atoi(argv[2]);
	bpp = atoi(argv[3]);
	if ((bpp!=16) && (bpp!=24)) {
		printf("BPP must be 16 or 24\n");
		return 0;
	}
	if (bpp == 16) 
		camif_cfg.bpp = 16;
	else 
		camif_cfg.bpp = 24;
	goal = atoi(argv[4]);
	camif_cfg.flip = atoi(argv[5]);

	if ((cam_fp = cam_init()) < 0) goto err;
	printf("DISPLAY: BPP(%d) width(%d), height(%d)\n", 
			bpp, width, height);
	fflush(stdout);
	if (ioctl(cam_fp, CMD_CAMERA_INIT, &camif_cfg)) {
		perror("ioctl");
		goto err;
	}
	gettimeofday(&start_tv, &tz);
	fmalloc(width, height, camif_cfg.bpp);
	write(cam_fp,"O",2);
	while (!found) {
			frames ++;
			save_jpg(width, height,camif_cfg.bpp, frames);
			if (frames == goal)  {
				found = 1;
				break;
			}
			if ((frames % 30) == 0) {
				gettimeofday(&end_tv, &tz);
				print_fps(&start_tv, &end_tv);
				gettimeofday(&start_tv, &tz);
			}
	}
	write(cam_fp,"X",2);
	ffree();
err:
	if (cam_fp) close(cam_fp);
	return 0;
}