/* * (c) SPDsoft 1993 + ATIC * Display a JFIF file using Silicon Graphics gl * version 0.4 * Uses IJG code v6b or ImageMagick 5.x * */ #include #include #include #include #include #include #include #include #ifdef USE_MAGICK #include #else #include #include #endif #ifndef PATH_SEP # define PATH_SEP '/' #endif #define ALPHA_OPAC 0x00 #define YSTEREO 491 #define YOFFSET_LEFT (1024 - (YSTEREO+1)) #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 Stereo; Boolean Crossed; Boolean Anaglyph; Boolean Nosetmon; Boolean Growable; Boolean KeepAspectRatio; Boolean Verbose; int SlideShow; long screen_w; long screen_h; } pref; /* * Prototypes */ void init_graphics(void); int event_loop(void); void redraw(void); void usage(char *name); void fatalError(char *str); void get_options(int argc,char *argv[]); int is_stereo(void); #ifndef USE_MAGICK /* * JPEG Prototypes */ static void my_error_exit (j_common_ptr cinfo); #endif int read_file (char * filename, unsigned char **fb, unsigned char **fb2); extern char *optarg; extern int optind,opterr; unsigned image_H; unsigned image_W; long monitor; long mouse; long offset=0; int f; #define framebuffer_r framebuffer unsigned char *framebuffer, *framebuffer_l, *pix, *pix2; pref G_prefs; #ifndef USE_MAGICK static char __ident[] = "@(#)(c) SPDsoft, (Uses IJG code v6b), 0.4 Sep 2004"; #else static char __ident[] = "@(#)(c) SPDsoft, (Uses ImageMagick), 0.4 Sep 2004"; #endif #define VERS_STR ((char*)&__ident[4]) /*****************************************************/ void usage(char *name) { fprintf(stderr, "usage: %s [-b|-F|-g|-G][-s sec][-fvhxa][-3|-4 left right|files...]" "\n%s\n%s\n%s\n%s\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", "-3: Stereo", "-4: Stereo w/o setmon", "-x: Stereo crossed (r|l)", "-a: Stereo anaglyph to grayscale", "-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)); if((G_prefs.Stereo||G_prefs.Crossed)&&(!G_prefs.Nosetmon)) { /* restore to original display, cursor range */ /* setmonitor ((short)monitor);*/ setmonitor (HZ76); setvaluator (MOUSEY, mouse , 0, (short) SCREEN_H); } exit(-2); } #ifndef USE_MAGICK 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); } #endif #ifdef USE_MAGICK int read_file (char * filename, unsigned char **fb, unsigned char **fb2) { Image *image; ImageInfo *image_info; ExceptionInfo exception; PixelPacket q; int i,j; image_info=CloneImageInfo((ImageInfo *) NULL); if (filename != NULL) { (void) strcpy(image_info->filename,filename); } else { (void) strcpy(image_info->filename,"-"); } image=ReadImage(image_info,&exception); image_H=image->rows; image_W=image->columns; if (( NULL != fb2 )&&(!G_prefs.Anaglyph)) image_W /=2 ; /* * Framebuffer */ Output("%03d %s\t%u\t%u\t",f,filename,image_H,image_W ); if (G_prefs.Verbose) fflush(stdout); if((( image_W > SCREEN_W ) || ( image_H > SCREEN_H))&&(G_prefs.FullScreen)) G_prefs.FillScreen=1; *fb = (unsigned char *)calloc( (size_t)image_H * (size_t)image_W , (size_t)4); if (*fb==NULL) fatalError("Out of memory"); pix = *fb + (size_t)4*image_W*(image_H-1); if ( NULL != fb2 ) { *fb2 = (unsigned char *)calloc( (size_t)image_H * (size_t)image_W , (size_t)4); if (*fb2==NULL) fatalError("Out of memory"); pix2 = *fb2 + (size_t)4*image_W*(image_H-1); } /* * Draw to framebuffer */ for(i=0; ialloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); if (( NULL != fb2 )&&(!G_prefs.Anaglyph)) image_W /=2 ; /* * 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; *fb = (unsigned char *)calloc( (size_t)image_H * (size_t)image_W , (size_t)4); if ((*fb==NULL)||(buffer==NULL)) fatalError("Out of memory"); pix = *fb + (size_t)4*image_W*(image_H-1); w=cinfo.output_width; if ( NULL != fb2 ) { *fb2 = (unsigned char *)calloc( (size_t)image_H * (size_t)image_W , (size_t)4); if (*fb2==NULL) fatalError("Out of memory"); pix2 = *fb2 + (size_t)4*image_W*(image_H-1); if (!G_prefs.Anaglyph) w=cinfo.output_width/2; } /* * 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 0xAABBGGRR */ *pix++ = ALPHA_OPAC; /* *pix++ = (char)inptr[2];*/ /* *pix++ = (char)inptr[1];*/ /* *pix++ = 0x00;*/ *pix++ = (char)inptr[1]; *pix++ = (char)inptr[1]; *pix++ = (char)inptr[1]; *pix2++ = ALPHA_OPAC; /* *pix2++ = 0x00;*/ /* *pix2++ = 0x00;*/ /* *pix2++ = (char)inptr[0];*/ *pix2++ = (char)inptr[0]; *pix2++ = (char)inptr[0]; *pix2++ = (char)inptr[0]; } else { *pix++ = ALPHA_OPAC; *pix++ = (char)inptr[2]; *pix++ = (char)inptr[1]; *pix++ = (char)inptr[0]; } inptr += 3; } pix -= 8* image_W; if (( NULL != fb2 )&&(!G_prefs.Anaglyph)) { for (j=0; j dglopen(display,DGLTSOCKET)) { fatalError("Can't open dgl socket"); } } #endif qdevice(ESCKEY); qdevice(REDRAW); qdevice(WINSHUT); qdevice(WINQUIT); if (G_prefs.Stereo||G_prefs.Crossed||G_prefs.Anaglyph) { qdevice(LEFTARROWKEY); qdevice(RIGHTARROWKEY); } 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) { if(G_prefs.Stereo||G_prefs.Crossed||G_prefs.Anaglyph) { float sx=2.0,sy=1.0; Screencoord mx, my; if ( image_H > (YSTEREO+1) ) { sy= (float)(YSTEREO+1)/(float)image_H; sx= 2.0 * sy; my = 0; mx = ((Screencoord) SCREEN_W - (Screencoord) ((float)image_W * sx )) / 2.0; } else if ( image_W > (SCREEN_W/2) ) { sx= (float) SCREEN_W / (float)image_W; sy= sx/2.0; mx= 0; my = ((Screencoord) (YSTEREO+1) - (Screencoord) ((float)image_H * sy )) / 2.0; } else { my = (Screencoord)(YSTEREO+1 - image_H)/2; mx = (Screencoord)(SCREEN_W - image_W * 2)/2; } rectzoom( sx, sy ); /* viewport (0, SCREEN_W, YOFFSET_LEFT, SCREEN_H);*/ clear(); lrectwrite( mx - (Screencoord)offset, my + YOFFSET_LEFT, mx + image_W-1 - (Screencoord)offset, my + image_H-1 + YOFFSET_LEFT, (unsigned long *)framebuffer_l); /* viewport (0, SCREEN_W, 0, YSTEREO);*/ lrectwrite( mx + (Screencoord)offset, my, mx + image_W-1 + (Screencoord)offset, my + image_H-1, (unsigned long *)framebuffer_r); } else { 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); } } /* --------------------------------------------------------------------- */ int is_stereo(void) { /* This routine returns 1 if Hardware is STEREO READY, 0 IF NOT*/ #ifdef PRE_IRIX33 /* for: pre-IRIX 3.3 systems, */ /* is read/write or read-onl:*/ long rw1, rw2; rw1 = getvideo(DE_R1); rw2 = rw1 ^= DER1_STEREO; setvideo(DE_R1, rw2); rw2 = getvideo(DE_R1); if (! (rw1 == rw2)) return(1); rw1 = rw2 ^= DER1_STEREO; setvideo(DE_R1, rw2); rw2 = getvideo(DE_R1); return ( ! (rw1 == rw2 ) ) ; #else return(getgdesc(GD_STEREO)); #endif }