/* * (c) SPDsoft 1993 + ATIC * Display a JFIF file using Silicon Graphics gl * version 2 * Uses IJG code v6b */ #include #include #include #include #include #include #include #include #include #ifndef PATH_SEP # define PATH_SEP '/' #endif #define ALPHA_OPAC 0x00 #define SCREEN_W G_prefs.screen_w #define SCREEN_H G_prefs.screen_h #define Boolean int #define Output if (G_prefs.Verbose) printf #ifndef MIN #define MIN(a,b) ((a)>(b)?(b):(a)) #endif typedef struct { char *AppName; Boolean Foreground; Boolean FullScreen; Boolean FillScreen; Boolean Growable; Boolean KeepAspectRatio; Boolean Verbose; int SlideShow; long screen_w; long screen_h; } pref; /* * Prototypes */ void init_graphics(void); void redraw(void); void usage(char *name); void fatalError(char *str); void get_options(int argc,char *argv[]); /* * JPEG Prototypes */ static void my_error_exit (j_common_ptr cinfo); int read_JPEG_file (char * filename); extern char *optarg; extern int optind,opterr; unsigned image_H; unsigned image_W; int f; unsigned char *framebuffer, *pix; pref G_prefs; static char __ident[] = "@(#)(c) SPDsoft, (Uses IJG code v6b), Jul 1998"; #define VERS_STR ((char*)&__ident[4]) /*****************************************************/ void usage(char *name) { fprintf(stderr, "usage: %s [-b|-F|-g|-G][-s sec][-f][-v][-h][files...]" "\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", name, "-f: Don't fork (run in foreground)", "-b: Full screen", "-F: Fill full screen", "-g: Growable, Keep aspect ratio", "-G: Growable", "-s: Slide Show (seconds)", "-v: Version, debug", "-h: This text. Note: Press to go to next image" ); exit(-1); } void fatalError(char *str) { fprintf(stderr, "%s: Fatal Error: %s. bye...\n",G_prefs.AppName,str); fprintf(stderr, "%s: %s\n",G_prefs.AppName,strerror(errno)); exit(-2); } struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; static void my_error_exit (j_common_ptr cinfo) { my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1); } int read_JPEG_file (char * filename) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE *infile; /* source file */ JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ register JSAMPROW inptr; int j; if (filename != NULL) { if ((infile = fopen(filename, "rb")) == NULL) { fatalError(filename); } } else infile = stdin; cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress(&cinfo); fclose(infile); return NULL; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); (void) jpeg_read_header(&cinfo, TRUE); jpeg_start_decompress(&cinfo); image_H = cinfo.output_height; image_W = cinfo.output_width; row_stride = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* * Framebuffer */ Output("%03d %s\t%u\t%u\t",f,filename,image_H,image_W ); if((( image_W > SCREEN_W ) || ( image_H > SCREEN_H))&&(G_prefs.FullScreen)) G_prefs.FillScreen=1; framebuffer = (unsigned char *)calloc( (size_t)image_H * (size_t)image_W , (size_t)4); if ((framebuffer==NULL)||(buffer==NULL)) fatalError("Out of memory"); pix = framebuffer + (size_t)4*image_W*(image_H-1); /* * Draw to framebuffer */ if ( cinfo.output_components != 1 ) { Output("RGB image\n"); while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); for (j=0, inptr=*buffer; j dglopen(display,DGLTSOCKET)) { fatalError("Can't open dgl socket"); } } #endif qdevice(ESCKEY); qdevice(REDRAW); qdevice(WINSHUT); qdevice(WINQUIT); savescrn = scrnselect(getwscrn()); G_prefs.screen_w = getgdesc(GD_XPMAX); G_prefs.screen_h = getgdesc(GD_YPMAX); scrnselect(savescrn); if (( G_prefs.screen_w == -1 ) || ( G_prefs.screen_h == -1 )) fatalError("getgdesc failed"); if(G_prefs.Foreground) foreground(); } void redraw(void) { long gw_x, gw_y; if(G_prefs.FullScreen) { clear(); if(G_prefs.FillScreen) { lrectwrite( 0,(image_H-1),(image_W-1),0, (unsigned long *)framebuffer); } else lrectwrite( (Screencoord)(SCREEN_W-image_W+1)/2, (Screencoord)(SCREEN_H+image_H-1)/2, (Screencoord)(SCREEN_W+image_W-1)/2, (Screencoord)(SCREEN_H-image_H+1)/2, (unsigned long *)framebuffer); } else { if(G_prefs.Growable) { getsize(&gw_x, &gw_y); viewport(0,(Screencoord)gw_x-1,0,(Screencoord)gw_y-1); rectzoom( (float)gw_x/(float)image_W, (float)gw_y/(float)image_H); } lrectwrite( 0,(image_H-1),(image_W-1),0, (unsigned long *)framebuffer); } }