diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | src/bmp.c | 21 | ||||
-rw-r--r-- | src/gif.c | 15 | ||||
-rw-r--r-- | src/jpeg.c | 4 | ||||
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/meh.h | 8 | ||||
-rw-r--r-- | src/png.c | 24 | ||||
-rw-r--r-- | src/xlib.c | 16 |
8 files changed, 83 insertions, 37 deletions
@@ -6,7 +6,6 @@ SRCFILES := $(wildcard src/*.c) OBJFILES := $(SRCFILES:%.c=%.o) DEPFILES := $(OBJFILES:%.o=%.d) CLEANFILES := $(CLEANFILES) $(DEPFILES) $(OBJFILES) meh -CFLAGS := $(CFLAGS) -O3 -Wall -g -ggdb LIBS := -lX11 -ljpeg -lpng -lgif meh: $(OBJFILES) @@ -112,8 +112,7 @@ void rgb16(unsigned char *buf, unsigned short c){ static int readrow(struct image *img, unsigned char *row, unsigned char *buf){ struct bmp_t *b = (struct bmp_t *)img; - int x; - int i = 0; + unsigned int x, i = 0; if(b->bpp == 24 || b->bpp == 32){ for(x = 0; x < img->width * 3; x+=3){ buf[x + 2] = row[i++]; @@ -149,21 +148,25 @@ static int readrow(struct image *img, unsigned char *row, unsigned char *buf){ int bmp_read(struct image *img){ struct bmp_t *b = (struct bmp_t *)img; + unsigned int i, y; + unsigned int dy; + unsigned char *row; FILE *f = img->f; - fseek(f, b->bitmapoffset, SEEK_SET); - int i, y; - int dy = img->width * 3; + row = malloc(b->rowwidth); + dy = img->width * 3; i = img->height * dy; - unsigned char row[b->rowwidth]; + + fseek(f, b->bitmapoffset, SEEK_SET); for(y = img->height; y; y--){ i -= dy; - if(fread(row, 1, b->rowwidth, f) != b->rowwidth) - return 1; - if(readrow(img, row, &img->buf[i])) + if(fread(row, 1, b->rowwidth, f) != b->rowwidth || readrow(img, row, &img->buf[i])){ + free(row); return 1; + } } + free(row); return 0; } @@ -17,12 +17,25 @@ struct gif_t{ GifFileType *gif; }; +static int isgif(FILE *f){ + return (getc(f) == 'G' && getc(f) == 'I' && getc(f) == 'F'); +} + static struct image *gif_open(FILE *f){ struct gif_t *g; GifFileType *gif; + rewind(f); + if(!isgif(f)) + return NULL; + + /* HACK HACK HACK */ + rewind(f); lseek(fileno(f), 0L, SEEK_SET); if(!(gif = DGifOpenFileHandle(fileno(f)))){ + /* HACK AND HOPE */ + rewind(f); + lseek(fileno(f), 0L, SEEK_SET); return NULL; } g = malloc(sizeof(struct gif_t)); @@ -36,7 +49,7 @@ static struct image *gif_open(FILE *f){ } static int gif_read(struct image *img){ - int i, j = 0; + unsigned int i, j = 0; struct gif_t *g = (struct gif_t *)img; GifColorType *colormap; SavedImage *s; @@ -49,7 +49,7 @@ static struct image *jpeg_open(FILE *f){ j->cinfo.do_fancy_upsampling = 0; j->cinfo.do_block_smoothing = 0; j->cinfo.quantize_colors = 0; - j->cinfo.dct_method = JDCT_IFAST; + j->cinfo.dct_method = JDCT_FASTEST; jpeg_calc_output_dimensions(&j->cinfo); @@ -62,7 +62,7 @@ static struct image *jpeg_open(FILE *f){ static int jpeg_read(struct image *img){ struct jpeg_t *j = (struct jpeg_t *)img; JSAMPARRAY buffer; - int row_stride; + unsigned int row_stride; int a = 0, b; unsigned int x, y; @@ -22,7 +22,7 @@ struct imageformat *formats[] = { &libjpeg, &gif, &libpng, - &giflib, + &giflib, /* HACK! make gif last (uses read()) */ NULL }; @@ -34,21 +34,15 @@ void usage(){ exit(1); } -struct image *imgopen(const char *filename){ +struct image *imgopen(FILE *f){ struct image *img = NULL; struct imageformat **fmt = formats; - FILE *f; - if((f = fopen(filename, "rb")) == NULL){ - fprintf(stderr, "Cannot open '%s'\n", filename); - return NULL; - } for(fmt = formats; *fmt; fmt++){ if((img = (*fmt)->open(f))){ img->fmt = *fmt; return img; } } - fprintf(stderr, "Unknown file type: '%s'\n", filename); return NULL; } @@ -96,6 +90,7 @@ void run(){ int width = 0, height = 0; struct image *img = NULL; int redraw = 0; + FILE *f = NULL; for(;;){ XEvent event; @@ -157,7 +152,21 @@ void run(){ if(redraw){ if(!img){ const char *firstimg = filename; - while(!(img = imgopen(filename))){ + while(!img){ + if(f){ + fclose(f); + f = NULL; + } + if(!(f = fopen(filename, "rb"))) + fprintf(stderr, "Cannot open '%s'\n", filename); + + if(f){ + if((img = imgopen(f))) + break; + else + fprintf(stderr, "Invalid format '%s'\n", filename); + } + filename = direction(); if(filename == firstimg){ fprintf(stderr, "No valid images to view\n"); @@ -173,6 +182,10 @@ void run(){ if(img->fmt->read(img)){ fprintf(stderr, "read error!\n"); } + if(f){ + fclose(f); + f = NULL; + } continue; /* Allow for some events to be read, read is slow */ } drawimage(img, width, height); @@ -10,15 +10,15 @@ struct imageformat{ struct image{ unsigned char *buf; - int width, height; + unsigned int width, height; FILE *f; struct imageformat *fmt; }; #include "X11/Xlib.h" -XImage *ximage(struct image *img, int width, int height); -void setaspect(int w, int h); +XImage *ximage(struct image *img, unsigned int width, unsigned int height); +void setaspect(unsigned int w, unsigned int h); void xinit(); -void drawimage(struct image *img, int width, int height); +void drawimage(struct image *img, unsigned int width, unsigned int height); @@ -13,8 +13,23 @@ struct png_t{ int numpasses; }; +static unsigned char png_head[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; + +static int ispng(FILE *f){ + unsigned char buf[8]; + if(fread(buf, 1, 8, f) != 8) + return 0; + return !memcmp(buf, png_head, 8); +} + struct image *png_open(FILE *f){ - struct png_t *p = malloc(sizeof(struct png_t)); + struct png_t *p; + + rewind(f); + if(!ispng(f)) + return NULL; + + p = malloc(sizeof(struct png_t)); if((p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL){ free(p); return NULL; @@ -68,15 +83,16 @@ struct image *png_open(FILE *f){ } int png_read(struct image *img){ + unsigned int y; struct png_t *p = (struct png_t *)img; if(setjmp(png_jmpbuf(p->png_ptr))){ png_destroy_read_struct(&p->png_ptr, &p->info_ptr, &p->end_info); return 1; } - int y; while(p->numpasses--){ - for(y = 0; y < img->height; y++) - png_read_row(p->png_ptr, &img->buf[y * (img->width) * 3], NULL); + for(y = 0; y < img->height; y++){ + png_read_row(p->png_ptr, &img->buf[y * img->width * 3], NULL); + } } png_destroy_read_struct(&p->png_ptr, &p->info_ptr, &p->end_info); return 0; @@ -1,6 +1,7 @@ #include <assert.h> #include <stdio.h> +#include <string.h> #include <stdlib.h> #include <X11/Xlib.h> @@ -28,13 +29,14 @@ static unsigned int getshift(unsigned int mask){ #endif } -XImage *ximage(struct image *img, int width, int height) { +XImage *ximage(struct image *img, unsigned int width, unsigned int height) { int depth; XImage *ximg = NULL; Visual *vis; unsigned int rshift, gshift, bshift; - int i; - int x,y; + unsigned int i; + unsigned int x,y; + unsigned int j = 0; depth = DefaultDepth(display, screen); vis = DefaultVisual(display, screen); @@ -45,7 +47,7 @@ XImage *ximage(struct image *img, int width, int height) { if (depth >= 24) { unsigned int dx; - size_t numNewBufBytes = (4 * width * height); + size_t numNewBufBytes = ((sizeof(u_int32_t)) * (width) * (height)); u_int32_t *newBuf = malloc(numNewBufBytes); dx = 1024 * img->width / width; @@ -57,7 +59,7 @@ XImage *ximage(struct image *img, int width, int height) { g = (img->buf[(i >> 10)*3+1] << gshift) & vis->green_mask; b = (img->buf[(i >> 10)*3+2] << bshift) & vis->blue_mask; - newBuf[y * width + x] = r | g | b; + newBuf[j++] = r | g | b; i += dx; } } @@ -107,7 +109,7 @@ XImage *ximage(struct image *img, int width, int height) { } -void drawimage(struct image *img, int width, int height){ +void drawimage(struct image *img, unsigned int width, unsigned int height){ static struct image *lastimg = NULL; static int lastwidth = 0, lastheight = 0; static XImage *ximg = NULL; @@ -151,7 +153,7 @@ void drawimage(struct image *img, int width, int height){ } -void setaspect(int w, int h){ +void setaspect(unsigned int w, unsigned int h){ XSizeHints *hints = XAllocSizeHints(); hints->flags = PAspect; hints->min_aspect.x = hints->max_aspect.x = w; |