47 #define _tolower tolower
48 #define _toupper toupper
54 #define DEFAULT_LEVELS 240
55 #define MAXIMUM_LEVELS 1024
57 static int get_pic ();
58 static void update_pic();
93 } visual_type_table[] = {
95 {
"staticgray", StaticGray},
96 {
"grayscale", GrayScale},
97 {
"staticgrey", StaticGray},
98 {
"greyscale", GrayScale},
99 {
"staticcolor", StaticColor},
100 {
"pseudocolor", PseudoColor},
101 {
"truecolor", TrueColor},
102 {
"directcolor", DirectColor}
108 image_information *i;
227 char ** infnames = NULL;
228 char * display_name = NULL;
229 char * window_geometry = NULL;
230 int n_malloced, num_imgs = 0, using_stdin;
232 int nfile = 0, forkflg = 0, dflag = 0, gflag = 0, wflag = 0;
233 int vflag = 0, aflag = 0, bin_flag = 0, mono_flag = 0;
234 int quit_flag = 0, tflag = 0, TVflag = 0;
236 int flip_book_frams_sec = 30;
237 int sharing_flag = False;
239 char *tv_command = NULL;
240 char *vis_type = NULL, *title_string = NULL;
241 int visual_type = -1;
242 int status, done = 0, rle_cnt = -1;
243 image_information *img, *previous_img;
244 double image_gamma = 0.0;
249 "% =%-window-geometry!s a%- d%-display!s D%- f%- \n\
250 g%-gamma!F iI%-gamma!F j%-jump-scans%d m%-maxframes/sec%d n%-levels!d \n\
251 q%- s%- S%- t%-title!s T%-delay%dcommand%s v%- wW%- x%-visual!s file%*s",
252 &wflag
, &window_geometry
,
254 &dflag
, &display_name
,
260 &flip_book
, &flip_book_frams_sec
,
265 &tflag
, &title_string
,
266 &TVflag
, &tv_delay
, &tv_command
,
270 &nfile
, &infnames
) == 0 )
273 if (TVflag && flip_book) {
274 fprintf(stderr,
"%s: -T and -m cannot be used together\n",
progname);
291 using_stdin = ( nfile ? False : True );
292 n_malloced = ( using_stdin ? 1 : nfile );
294 img_info = (image_information *)malloc(n_malloced *
295 sizeof(image_information) );
298 perror(
"malloc returned NULL");
303 if (isdigit (vis_type[0]) ) {
304 visual_type = atoi (vis_type);
311 for (ptr = vis_type; *ptr !=
'\0'; ptr++) {
312 if (isupper(*ptr)) *ptr = _tolower(*ptr);
315 for (i = 0; i <
COUNT_OF (visual_type_table); i++) {
316 if (strcmp (visual_type_table[i].string, vis_type) == 0) {
317 visual_type = visual_type_table[i].type;
323 if ( visual_type < 0 || visual_type > 5 ) {
324 fprintf ( stderr,
"Bad visual type %s, ignoring request\n",
346 if ( num_imgs >= n_malloced && (! TVflag || num_imgs == 1) )
349 ++n_malloced *
sizeof(image_information) );
352 fprintf(stderr,
"%s: Out of memory!\n",
progname);
355 if ( TVflag && num_imgs > 0 )
366 if (
iflag == 2 && image_gamma != 0.0 ) img
->gamma = 1.0 / image_gamma;
370 img
->mono_img = ( mono_flag || bin_flag ? True : False );
381 if ( (flip_book || TVflag) && img != &
img_info[0] )
383 previous_img = img - 1;
384 #define INHERIT( thing ) img->thing = previous_img->thing
430 else previous_img = NULL;
432 if ( !using_stdin ) {
438 if ( strcmp( *infnames,
"-" ) == 0 )
449 if (img
->fd == NULL) {
477 if ( tflag && title_string )
480 status = get_pic( img, window_geometry, previous_img );
490 fprintf(stderr,
"%s: Out of Memory! Trying to continue\n",
progname);
520 fprintf(stderr,
"%s: Cannot flip-book, sorry...\n",
progname);
524 if ( TVflag && !done ) {
526 system( tv_command );
546 XCloseDisplay(
dpy );
562 (
void)setpgrp( 0, getpid() );
564 update_pic (
img_info, num_imgs, flip_book, flip_book_frams_sec );
570 update_pic (
img_info, num_imgs, flip_book, flip_book_frams_sec );
572 XCloseDisplay(
dpy );
578 register image_information *img;
579 int x, y, width, height, img_h;
590 if ( xo && (x < xo) && width > 0 && height > 0) {
593 XClearArea(
dpy, img
->window, x, y, w, height, False );
599 if ( yo && (y < yo) && width > 0 && height > 0) {
602 XClearArea(
dpy, img
->window, x, y, width, h, False );
609 if (x + width > xo + iw && height > 0) {
610 int w = x + width - xo - iw;
611 XClearArea(
dpy, img
->window, xo + iw, y, w, height, False );
617 if (y + height > yo + ih && width > 0) {
618 int h = y + height - yo - ih;
619 XClearArea(
dpy, img
->window, x, yo + ih, width, h, False );
623 if ( width <= 0 || height <= 0 )
631 if (y - yo < ih - img_h && width > 0) {
632 int h = (ih - img_h) - ( y - yo );
633 XClearArea(
dpy, img
->window, x, y, width, h, False );
643 int offset = x % BitmapPad (
dpy);
648 if ( width <= 0 || height <= 0 )
653 x-xo, y-yo, width, height, x, y );
656 x-xo
, y-yo
, x
, y
, width
, height
);
664 get_pic( img, window_geometry, previous_img )
665 register image_information *img, *previous_img;
666 char *window_geometry;
668 int image_xmax, image_ymax;
669 int x11_y, scan_y, view_w, view_h;
670 unsigned char *save_scan[3], *read_scan[3];
672 register int image_y;
673 register int y_base, lines_buffered, lines_blitted;
688 image_xmax = img_hdr
.xmax;
689 image_ymax = img_hdr
.ymax;
693 img
->w = image_xmax - img_hdr
.xmin + 1;
694 img
->h = image_ymax - img_hdr
.ymin + 1;
702 for (i = 3; i < img_hdr
.ncolors; i++)
718 ((img
->fd == stdin) ? 1 : img
->h));
725 fprintf(stderr,
"%s: dpy_channels > img_channels, %d > %d\n",
progname,
742 char *buf = (
char *)malloc( strlen( img
->filename ) + 8 );
758 if ( img
->w != previous_img
->w || img
->h != previous_img
->h ||
762 "%s: Images %s and %s dont match in size or channels\n",
770 fprintf( stderr,
"%s: Images %s and %s have different colormaps\n",
778 if ( !previous_img ) {
786 perror(
"malloc for fancy icon");
802 if ( !previous_img || previous_img
->pixmap == NULL )
842 if ( !previous_img ) {
844 (
unsigned char *) malloc ( (img
->h + 1) * img
->w *
848 perror (
"malloc for scanline buffer failed");
853 save_scan[i] = save_scan[i - 1] + img
->w;
859 if ( read_scan[0] == NULL ) {
860 perror (
"malloc for read_scan buffer failed");
864 read_scan[i] = read_scan[i - 1] + img
->w;
867 read_scan[0] = save_scan[0],
868 read_scan[1] = save_scan[1],
869 read_scan[2] = save_scan[2];
872 save_scan[0] = read_scan[0],
873 save_scan[1] = read_scan[1],
874 save_scan[2] = read_scan[2];
895 x11_y = view_h - (image_y - img_hdr
.ymin) - 1;
896 scan_y = image_ymax - image_y;
903 if ( x11_y >= 0 && x11_y < img
->h ) {
915 while ( XCheckTypedEvent(
dpy, Expose, &event ) ) {
916 image_information *eimg;
919 for (eimg =
img_info; eimg <= img; eimg++ )
920 if ( eimg
->window == event.xany.window )
923 if ( img >
img_info && lines_blitted == 0 )
930 event.xexpose.width
, event.xexpose.height
,
931 (eimg == img) ? lines_blitted : eimg
->h );
935 if (lines_buffered >= buffer_scans) {
936 y_base -= lines_buffered - 1;
939 0
, y_base
, 0
, y_base
, view_w
,
942 lines_blitted += lines_buffered;
944 lines_buffered
, lines_blitted
);
954 save_scan[i] = save_scan[i - 1] + img
->w;
961 read_scan[0] = save_scan[0], read_scan[1] = save_scan[1],
962 read_scan[2] = save_scan[2];
964 save_scan[0] = read_scan[0], save_scan[1] = read_scan[1],
965 save_scan[2] = read_scan[2];
968 if ( lines_buffered > 0 ) {
969 y_base -= lines_buffered - 1;
972 0
, y_base
, 0
, y_base
, view_w
,
975 lines_blitted += lines_buffered;
977 lines_buffered
, img
->h );
991 free ( read_scan[0] );
1007 #define ACTION_MAGNIFY 0
1008 #define ACTION_UNMAGNIFY 1
1009 #define ACTION_PAN 2
1010 #define ACTION_SWITCH_MAG_MODE 3
1011 #define ACTION_FLIP_FORWARD 4
1012 #define ACTION_FLIP_STEP 5
1013 #define ACTION_FLIP_BACKWARD 6
1014 #define ACTION_FLIP_SPEED 7
1015 #define ACTION_PIXEL_INFO 8
1016 #define ACTION_CYCLE 9
1017 #define ACTION_CYCLE_TO_AND_FRO 10
1018 #define ACTION_RESIZE 11
1036 void mag_pan( img, action, bx, by, new_mag_fact )
1037 image_information *img;
1038 int action, bx, by, new_mag_fact;
1045 int opan_x = 0, opan_y = 0;
1046 int blit_w = 0, blit_h = 0;
1080 #define SWAP(v1, v2) { int tmp = (v1); (v1) = (v2); (v2) = tmp; }
1228 int src_x, src_y, dst_x, dst_y;
1229 int pwidth = opan_x - img
->pan_x;
1230 int phight = opan_y - img
->pan_y;
1232 pwidth = img
->pan_w - (( pwidth < 0 ) ? - pwidth : pwidth);
1233 phight = img
->pan_h - (( phight < 0 ) ? - phight : phight);
1245 dst_x = 0; src_x = blit_w - width;}
1248 src_x = 0; dst_x = blit_w - width;}
1252 dst_y = 0; src_y = blit_h - hight;}
1255 src_y = 0; dst_y = blit_h - hight;}
1265 if ( src_x == dst_x && src_y == dst_y )
1277 img
->gc, src_x, src_y, width, hight, dst_x, dst_y );
1285 0
, 0
, 0
, 0
, blit_w
, dst_y
);
1288 if (hight < blit_h) {
1292 blit_w, blit_h - hight, img
->image );
1295 blit_w
, blit_h - hight
);
1300 if (hight && width < img
->win_w) {
1304 0, dst_y, blit_w - width, hight, img
->image );
1307 0
, dst_y
, 0
, dst_y
, blit_w - width
, hight
);
1311 if (hight && width < blit_w) {
1315 width, dst_y, blit_w - width, hight, img
->image );
1319 blit_w - width
, hight
);
1333 if ( redither || ( redraw && !img
->pixmap ) )
1341 0
, 0
, 0
, 0
, blit_w
, blit_h
);
1352 image_information *img, *img_info;
1353 int flip_book_udelay, n;
1358 if (mask) *found_event = False;
1360 if ( img == &img_info[n - 1] )
1362 for ( ; img < &img_info[n]; img++ ) {
1366 if (mask && XCheckMaskEvent(
dpy, mask, event )){
1367 *found_event = True;
1372 if (mask && *found_event)
1374 else return img - 1;
1379 image_information *img, *img_info;
1380 int flip_book_udelay, n;
1385 if (mask) *found_event = False;
1387 if ( img == img_info )
1388 img = &img_info[n - 1];
1389 for ( ; img >= &img_info[0]; img-- ) {
1393 if (mask && XCheckMaskEvent(
dpy, mask, event )){
1394 *found_event = True;
1399 if (mask && *found_event)
1401 else return img + 1;
1406 image_information *img, *img_info;
1415 (img, img_info, flip_book_udelay, n, ButtonPressMask|KeyPressMask,
1416 &event, &found_event);
1418 }
while ( !found_event );
1425 image_information *img;
1438 if ( old_w < iw || new_w < iw || old_h < ih || new_h < ih ) {
1449 update_pic( img_info, n, flip_book, flip_book_frams_sec )
1450 image_information *img_info;
1451 int n, flip_book_frams_sec;
1457 register image_information *img;
1461 image_information *flip_frame = NULL;
1464 int flip_book_udelay = 0;
1467 img = flip_frame = img_info;
1474 XNextEvent(
dpy, &event);
1478 (flip_book_frams_sec) ? 1000000 / flip_book_frams_sec : 0;
1481 for ( img = img_info; img < &img_info[n]; img++ )
1482 if ( img
->window == event.xany.window )
1485 switch (event.type) {
1488 i = event.xbutton.button - Button1;
1493 action =
flip_action[i][event.xbutton.state & ShiftMask];
1515 &rx, &ry, &x, &y, &mask))
1517 if (!(mask&(Button1Mask|Button2Mask|Button3Mask)))
1525 if ((first || x != lx || y != ly) &&
1526 (x >= 0 && x < img
->w &&
1527 y >= 0 && y < img
->h)) {
1529 first = 0; lx = x; ly = y;
1543 int height = DisplayHeight(
dpy,
screen)/4;
1546 s = flip_book_frams_sec;
1551 int rx, ry, x, y, inc;
1555 &rx, &ry, &x, &y, &mask)) {
1556 if (!(mask&(Button1Mask|Button2Mask|Button3Mask)))
1561 inc = (ly - y) * 100 / height;
1564 if ((first || flip_book_frams_sec + inc != s ) ) {
1565 s = flip_book_frams_sec + inc;
1566 s = (s < 0) ? 0 : s;
1567 s = (s > 100) ? 100 : s;
1575 flip_book_frams_sec = s;
1583 n
, ButtonPressMask|KeyPressMask
,
1584 &event
, &found_event
);
1588 flip_forward = False;
1595 n
, ButtonPressMask|KeyPressMask
,
1596 &event
, &found_event
);
1600 flip_forward = True;
1607 if ( flip_forward ) {
1608 if ( flip_frame == &img_info[n-1] )
1609 img = flip_frame = img_info;
1611 img = flip_frame = flip_frame + 1;
1614 if ( flip_frame == img_info )
1615 img = flip_frame = &img_info[n-1];
1617 img = flip_frame = flip_frame - 1;
1628 ( img
, img_info
, n
, flip_forward
, flip_book_udelay
);
1636 img = (* (flip_forward ?
1639 (img, img_info, flip_book_udelay,
1640 n, ButtonPressMask |KeyPressMask,
1641 &event, &found_event);
1643 flip_forward = !flip_forward;
1645 img = (flip_forward) ? img + 1 : img - 1;
1648 }
while( !found_event );
1656 mag_pan ( img, action, event.xbutton.x, event.xbutton.y,
1660 mag_pan ( img, action, event.xbutton.x, event.xbutton.y,
1664 mag_pan ( img, action, event.xbutton.x, event.xbutton.y,
1669 mag_pan ( img, action, event.xbutton.x, event.xbutton.y,
1681 event.xexpose.width
, event.xexpose.height
,
1686 case ConfigureNotify:
1688 int new_w = event.xconfigure.width;
1689 int new_h = event.xconfigure.height;
1691 if ( !flip_book && (img
->win_w != new_w || img
->win_h != new_h )) {
1705 char *symstr, *XKeysymToString( );
1708 XComposeStatus stat;
1712 length = XLookupString( (XKeyEvent *)&event, string, 256, &keysym, &stat );
1713 string [length] =
'\0';
1714 symstr = XKeysymToString( keysym );
1715 shifted_key = event.xkey.state & ShiftMask;
1717 if ( length == 1 && (string[0] ==
'q' || string[0] ==
'Q' ||
1718 string[0] ==
'\003' ))
1724 case '1':
case '2':
case '3':
case '4':
1725 case '5':
case '6':
case '7':
case '8':
1735 img = (* (flip_forward ?
1738 (img, img_info, flip_book_udelay,
1739 n, ButtonPressMask |KeyPressMask,
1740 &event, &found_event);
1742 flip_forward = !flip_forward;
1744 img = (flip_forward) ? img + 1 : img - 1;
1747 }
while( !found_event );
1755 flip_forward = (string[0] ==
'c');
1757 (img
, img_info
, n
, flip_forward
, flip_book_udelay
);
1763 4, 20,
"hi there", strlen (
"hi there") );
1773 for (img = flip_frame; img < &img_info[n]; img++ )
1776 if ( flip_forward ) {
1777 if ( flip_frame == &img_info[n] )
1778 img = flip_frame = img_info;
1783 if ( flip_frame == img_info )
1784 img = flip_frame = &img_info[n-1];
1786 img = flip_frame = flip_frame - 1;
1795 if ( flip_forward ) {
1796 if ( flip_frame == &img_info[n-1] )
1797 img = flip_frame = img_info;
1799 img = flip_frame = flip_frame + 1;
1802 if ( flip_frame == img_info )
1803 img = flip_frame = &img_info[n-1];
1805 img = flip_frame = flip_frame - 1;
1816 if ( !flip_forward ) {
1817 if ( flip_frame == &img_info[n-1] )
1818 img = flip_frame = img_info;
1820 img = flip_frame = flip_frame + 1;
1823 if ( flip_frame == img_info )
1824 img = flip_frame = &img_info[n-1];
1826 img = flip_frame = flip_frame - 1;
1841 if ( string[0] ==
'i' )
1848 handled_key = False;
1850 else handled_key = False;
1852 DPRINTF(stderr,
"%s %x, %s String '%s' - %d\n", symstr, keysym,
1853 ( shifted_key )?
"shifted":
"unshifted", string, length );
1862 if ( !strcmp( symstr,
"Left" ) || !strcmp( symstr,
"F30" ) )
1865 if ( !strcmp( symstr,
"Up" ) || !strcmp( symstr,
"F28" ) )
1868 if ( !strcmp( symstr,
"Right" ) || !strcmp( symstr,
"F32" ) )
1873 if ( !strcmp( symstr,
"Down" ) || !strcmp( symstr,
"F34" ) )
1882 case VisibilityNotify:
1888 case ReparentNotify:
1889 case ConfigureRequest:
1893 XRefreshKeyboardMapping( &event.xmapping );
1897 fprintf(stderr,
"%s: Event type %x?\n",
progname, event.type);
1931 for ( ; img < &img_info[n]; img++ )
1936 if ( img_info[0]
.window == dead_window )
1939 for ( img = &img_info[0] ; img < &img_info[n]; img++ )
unsigned char * scan_data
Boolean use_shared_pixmaps
#define ACTION_FLIP_BACKWARD
void allocate_pixmap(image_information *img, Boolean reallocate)
void MapPixWindow(image_information *img, int use_top)
int XCopyImage(XImage *image, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
void free_X_pixmap(image_information *img, Pixmap pix)
#define ACTION_CYCLE_TO_AND_FRO
void UnmapPixWindow(image_information *img)
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
int eq_cmap(register rle_pixel **cm1, int len1, register rle_pixel **cm2, int len2)
void check_mono_color(image_information *img, rle_hdr *img_hdr)
void choose_scanline_converter(image_information *img)
static int flip_action[3][2]
void main(int argc, char **argv)
void open_x_display(char *display_name)
int rle_get_setup(rle_hdr *the_hdr)
image_information * action_flip_forward(image_information *img, image_information *img_info, int flip_book_udelay, int n, unsigned long mask, XEvent *event, Boolean *found_event)
int rle_getrow(rle_hdr *the_hdr, scanline)
void calc_view_origin(image_information *img)
int rle_get_error(int code, const char *pgmname, const char *fname)
void init_img_info(image_information *i)
int scanargs(int argc, char **argv, const char *format,...)
void init_color(register image_information *img)
void find_appropriate_visual(register image_information *img)
void map_rgb_to_rgb(image_information *img, rle_pixel **in_rows, rle_pixel **out_rows)
static int button_action[3][2]
#define ACTION_FLIP_SPEED
void create_windows(register image_information *img, char *window_geometry)
void handle_exposure(register image_information *img, int x, int y, int width, int height, int img_h)
FILE * rle_open_f_noexit(char *prog_name, char *file_name, char *mode)
void set_timer(unsigned n)
char * rle_getcom(char *name, rle_hdr *the_hdr) const
#define ACTION_PIXEL_INFO
#define ACTION_SWITCH_MAG_MODE
#define SAVED_RLE_ROW(img, y)
#define RLE_CLR_BIT(glob, bit)
void destroy_X_image(image_information *img, XImage *image)
void get_dither_colors(register image_information *img, rle_hdr *img_hdr)
void set_circle_cursor(Window window)
void set_watch_cursor(Window window)
void determine_icon_size(int image_width, int image_height, int *icon_width, int *icon_height, int *icon_factor)
void map_rgb_to_bw(image_information *img, rle_pixel **rows, register rle_pixel *bw_row)
#define ACTION_FLIP_FORWARD
VOID_FUNCTION * MAG_scanline
void DrawSpeedWindow(image_information *img, int s)
image_information * img_info
image_information * action_flip_book_cycle(image_information *img, image_information *img_info, int n, Boolean flip_forward, int flip_book_udelay)
#define COUNT_OF(_array_)
void put_X_image(image_information *img, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
int allocate_ximage(image_information *img, Boolean reallocate)
image_information * action_flip_backward(image_information *img, image_information *img_info, int flip_book_udelay, int n, unsigned long mask, XEvent *event, Boolean *found_event)
VOID_FUNCTION * map_scanline
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
void DrawPixWindow(image_information *img, int x, int y)
void free_image_colors(image_information *img)
XImage * get_X_image(image_information *img, int width, int height, Boolean share)
int resize_window(image_information *img, int new_w, int new_h)
void set_left_ptr_cursor(Window window)