jtest.c
#include <string.h>
#include <stdlib.h>
//#include <jni.h>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef uint8_t BYTE;
#define true 1
#define false 0
#include "jpeglib.h"
#define FB_DEVICE "/dev/graphics/fb0"
static int g_fd;
typedef struct{
int x;
int y;
}point;
typedef struct
{
int w; /* width */
int h; /* high */
int bpp; /* bits per pixel */
unsigned char *fbmem;
}screen;
int init_fb(screen *fb)
{
if ((g_fd = open(FB_DEVICE, O_RDWR)) < 0){
fprintf(stderr, "Open %s failed:%s\n", FB_DEVICE, strerror(errno));
return -1;
}
struct fb_var_screeninfo fb_var;
struct fb_fix_screeninfo fb_fix;
if (ioctl(g_fd, FBIOGET_VSCREENINFO, &fb_var) < 0){
fprintf(stderr, "fb ioctl failed:%s\n", strerror(errno));
return -1;
}
if (ioctl(g_fd, FBIOGET_FSCREENINFO, &fb_fix) < 0){
fprintf(stderr, "fb ioctl failed:%s\n", strerror(errno));
return -1;
}
fb->w = fb_fix.line_length / 4;
fb->h = fb_var.yres;
fb->bpp = fb_var.bits_per_pixel;
printf("--->^_^ %d, %d, %d, %d\n", fb_var.xres_virtual, fb_var.yres_virtual, fb_var.xoffset, fb_var.yoffset);
printf("--->^_^ %d\n", fb_fix.line_length);
#if 1
printf("width:%d\thign:%d\tbpp:%d\n",
fb->w, fb->h, fb->bpp);
#endif
fb->fbmem = mmap(0, fb->w * fb->h * fb->bpp /8,
PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
if (fb->fbmem == MAP_FAILED){
fprintf(stderr, "fb mmap failed:%s\n", strerror(errno));
return -1;
}
close(g_fd);
return 0;
}
int term_fb(screen *fb)
{
munmap(fb->fbmem, fb->w * fb->h * fb->bpp / 8);
return 0;
}
int generateJPEG(BYTE* data,int w, int h, const char* outfilename)
{
int nComponent = 3;
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);
FILE* f=fopen(outfilename,"wb");
if (f==NULL)
{
free(data);
return 0;
}
jpeg_stdio_dest(&jcs, f);
jcs.image_width = w;
jcs.image_height = h;
jcs.input_components = nComponent;
if (nComponent==1)
jcs.in_color_space = JCS_GRAYSCALE;
else
jcs.in_color_space = JCS_RGB;
jpeg_set_defaults(&jcs);
jpeg_set_quality (&jcs, 60, true);
jpeg_start_compress(&jcs, TRUE);
JSAMPROW row_pointer[1];
int row_stride;
row_stride = jcs.image_width*nComponent;
while (jcs.next_scanline < jcs.image_height) {
row_pointer[0] = & data[jcs.next_scanline*row_stride];
jpeg_write_scanlines(&jcs, row_pointer, 1);
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
fclose(f);
return 1;
}
BYTE* generateRGB24Data()
{
struct {
BYTE r;
BYTE g;
BYTE b;
} pRGB[100][199];
memset( pRGB, 0, sizeof(pRGB) );
int i=0, j=0;
for( i=50;i<70;i++ ){
for( j=70;j<140;j++ ){
pRGB[i][j].b = 0xff;
}
}
for( i=0;i<10;i++ ){
for( j=0;j<199;j++ ){
pRGB[i][j].r = 0xff;
}
}
BYTE* ret = (BYTE*)malloc(sizeof(BYTE)*100*199*3);
memcpy(ret, (BYTE*)pRGB, sizeof(pRGB));
return ret;
}
int main(void)
{
int i, j;
unsigned char *p;
int w, h;
//BYTE* data = generateRGB24Data();
screen fb_screen;
init_fb(&fb_screen);
w = fb_screen.w;
h = fb_screen.h;
p = (unsigned char *)malloc(w * h * 3);
printf("0x%x %x %x %x\n", *fb_screen.fbmem, *(fb_screen.fbmem + 1), \
*(fb_screen.fbmem + 2), *(fb_screen.fbmem + 3));
for(i = 0; i < h; i++){
for(j = 0; j < w; j++){
*(p + (i * w + j) * 3) = *(fb_screen.fbmem + (i * w + j) * 4 + 0);
*(p + (i * w + j) * 3 + 1) = *(fb_screen.fbmem + (i * w + j) * 4 + 1);
*(p + (i * w + j) * 3 + 2) = *(fb_screen.fbmem + (i * w + j) * 4 + 2);
}
}
generateJPEG(p, fb_screen.w, fb_screen.h, "/sdcard/test.jpg");
term_fb(&fb_screen);
free(p);
//free(data);
return 0;
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= jtest.c
LOCAL_MODULE:= jtest
#LOCAL_FORCE_STATIC_EXECUTABLE := true
#LOCAL_STATIC_LIBRARIES := libc
LOCAL_SHARED_LIBRARIES:= libjpeg libc
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug
include $(BUILD_EXECUTABLE)