|
发表于 2004-9-15 12:48:22
|
显示全部楼层
[code:1]
#include <stdio.h>
#include <jpeglib.h>
#include <setjmp.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#include <gdk/gdk.h>
GdkWindow *gdk_win;
GdkGC *gdk_gc;
void create_jpeg_viewer_win()
{
GdkWindowAttr attr;
int attributes_mask = 1;
gdk_init(NULL,NULL);
gdk_rgb_init();
attr.override_redirect = TRUE;
attr.window_type = GDK_WINDOW_TEMP;
attr.wclass = GDK_INPUT_OUTPUT;
attr.event_mask = GDK_ALL_EVENTS_MASK;
attr.x=0;
attr.y=0;
attr.width = 800;
attr.height = 600;
gdk_win = gdk_window_new (NULL, &attr, attributes_mask);
gdk_window_show (gdk_win);
gdk_window_move(gdk_win,0,0);
gdk_gc=gdk_gc_new(gdk_win);
}
struct handle_error
{
struct jpeg_error_mgr err_mgr;
jmp_buf jump_buffer;
};
typedef struct handle_error * my_error_ptr;
METHODDEF(void)
exit_while_error (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->jump_buffer, 1);
}
static void * jpeg_malloc_image(int w, int h)
{
void *temp=NULL;
size_t size=w*h*3;
if(w>32767||h>32767)
return NULL;
temp = (void *)malloc(size);
if(temp)
{
memset(temp,0,size);
return temp;
}
else
return NULL;
}
static unsigned char *load_jpeg(char *filename, int *w, int *h)
{
FILE *jpegfp;
struct jpeg_decompress_struct cinfo;
unsigned char *rgbdata,*line[16],*ptr;
int x,y,i;
struct handle_error jerr;
cinfo.err = jpeg_std_error(&(jerr.err_mgr));
jerr.err_mgr.error_exit = exit_while_error;
if(setjmp(jerr.jump_buffer))
{
jpeg_destroy_decompress(&cinfo);
return 0;
}
jpegfp=fopen(filename,"rb");
if(!jpegfp)
{
printf("error open %s\n",filename);
return NULL;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, jpegfp);
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_start_decompress(&cinfo);
*w = cinfo.output_width;
*h = cinfo.output_height;
rgbdata = jpeg_malloc_image(*w, *h);
if (!rgbdata)
{
jpeg_destroy_decompress(&cinfo);
return NULL;
}
ptr = rgbdata;
if (cinfo.rec_outbuf_height > 16)
{
return NULL;
}
if (cinfo.output_components == 3)
{
for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
{
line[i] = ptr;
ptr += *w * 3;
}
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
}
}
else if (cinfo.output_components == 1)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
{
if ((line[i] = (void *)malloc(*w)) == NULL)
{
int t = 0;
for (t = 0; t < i; t++)
free(line[t]);
jpeg_destroy_decompress(&cinfo);
return NULL;
}
}
for (y = 0; y < *h; y += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
for (i = 0; i < cinfo.rec_outbuf_height; i++)
{
for (x = 0; x < *w; x++)
{
*ptr++ = line[i][x];
*ptr++ = line[i][x];
*ptr++ = line[i][x];
}
}
}
for (i = 0; i < cinfo.rec_outbuf_height; i++)
free(line[i]);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(jpegfp);
return rgbdata;
}
void show_jpeg_pic(char *filename)
{
unsigned char *rgbdata;
int w,h,i;
rgbdata=load_jpeg(filename,&w,&h);
gdk_window_resize(gdk_win,w,h);
if(rgbdata)
{
gdk_draw_rgb_image(gdk_win,gdk_gc,0,0,
w,h,GDK_RGB_DITHER_NONE,rgbdata,w*3);
free(rgbdata);
}
gdk_flush();
}
int main(int argc,char **argv)
{
create_jpeg_viewer_win(0,0,800,450);
show_jpeg_pic(argv[1]);
getchar();
return;
}
[/code:1]
gcc xxx.c -ljpeg `gtk-config --libs --cflags` |
|