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;
}