aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bmp.c4
-rw-r--r--src/gif.c3
-rw-r--r--src/jpeg.c20
-rw-r--r--src/main.c53
-rw-r--r--src/meh.h4
-rw-r--r--src/png.c4
-rw-r--r--src/xlib.c10
7 files changed, 67 insertions, 31 deletions
diff --git a/src/bmp.c b/src/bmp.c
index 4024521..33ba589 100644
--- a/src/bmp.c
+++ b/src/bmp.c
@@ -169,6 +169,9 @@ int bmp_read(struct image *img){
}
free(row);
+
+ img->state = LOADED;
+
return 0;
}
@@ -180,6 +183,7 @@ void bmp_close(struct image *img){
struct imageformat bmp = {
bmp_open,
+ NULL,
bmp_read,
bmp_close
};
diff --git a/src/gif.c b/src/gif.c
index 8da6554..17e5d4d 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -77,6 +77,8 @@ static int gif_read(struct image *img){
img->buf[j++] = colormap[idx].Blue;
}
+ img->state = LOADED;
+
return 0;
}
@@ -88,6 +90,7 @@ void gif_close(struct image *img){
struct imageformat giflib = {
gif_open,
+ NULL,
gif_read,
gif_close
};
diff --git a/src/jpeg.c b/src/jpeg.c
index 0406c00..4271975 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -43,7 +43,6 @@ static struct image *jpeg_open(FILE *f){
j = malloc(sizeof(struct jpeg_t));
j->f = f;
- rewind(f);
j->cinfo.err = jpeg_std_error(&j->jerr.pub);
j->jerr.pub.error_exit = error_longjmp;
@@ -51,8 +50,16 @@ static struct image *jpeg_open(FILE *f){
return NULL;
}
+ j->jerr.pub.error_exit = error_exit;
+ return (struct image *)j;
+}
+
+void jpeg_prep(struct image *img){
+ struct jpeg_t *j = (struct jpeg_t *)img;
+
jpeg_create_decompress(&j->cinfo);
- jpeg_stdio_src(&j->cinfo, f);
+ rewind(j->f);
+ jpeg_stdio_src(&j->cinfo, j->f);
jpeg_read_header(&j->cinfo, TRUE);
/* parameters */
@@ -60,17 +67,15 @@ static struct image *jpeg_open(FILE *f){
j->cinfo.do_block_smoothing = 0;
j->cinfo.quantize_colors = 0;
j->cinfo.dct_method = JDCT_FASTEST;
- //j->cinfo.scale_denom = 1; /* TODO: This should be changed for initial display of really large jpegs */
+ j->cinfo.scale_denom = img->state < FASTLOADED ? 8 : 1; /* TODO: This should be changed done only for large jpegs */
jpeg_calc_output_dimensions(&j->cinfo);
j->img.bufwidth = j->cinfo.output_width;
j->img.bufheight = j->cinfo.output_height;
-
- j->jerr.pub.error_exit = error_exit;
- return (struct image *)j;
}
+
static int jpeg_read(struct image *img){
struct jpeg_t *j = (struct jpeg_t *)img;
unsigned int row_stride;
@@ -110,6 +115,8 @@ static int jpeg_read(struct image *img){
}
jpeg_finish_decompress(&j->cinfo);
+ img->state = j->cinfo.scale_denom == 1 ? LOADED : FASTLOADED;
+
return 0;
}
@@ -121,6 +128,7 @@ void jpeg_close(struct image *img){
struct imageformat libjpeg = {
jpeg_open,
+ jpeg_prep,
jpeg_read,
jpeg_close
};
diff --git a/src/main.c b/src/main.c
index 49b4cef..cddb436 100644
--- a/src/main.c
+++ b/src/main.c
@@ -197,25 +197,42 @@ int doredraw(struct image **i){
}
}
- setaspect((*i)->bufwidth, (*i)->bufheight);
+ (*i)->buf = NULL;
+ (*i)->state = NONE;
+ }else{
+ imgstate dstate = (*i)->state + 1;
+ if(dstate == LOADED || dstate == FASTLOADED){
+ if((*i)->fmt->prep){
+ (*i)->fmt->prep(*i);
+ }
+ setaspect((*i)->bufwidth, (*i)->bufheight);
- (*i)->buf = malloc(3 * (*i)->bufwidth * (*i)->bufheight);
- TDEBUG_START
- if((*i)->fmt->read(*i)){
- fprintf(stderr, "read error!\n");
- }
- TDEBUG_END("read")
- (*i)->fmt->close(*i);
- (*i)->state = LOADED;
- }else if(width && height){
- imgstate state = (*i)->state;
- if(state == LOADED){
- (*i)->ximg = getimage(*i, width, height);
- (*i)->state = SCALED;
- }else if(state == SCALED){
- assert((*i)->ximg);
- drawimage((*i)->ximg, width, height);
- (*i)->state = DRAWN;
+ if((*i)->buf)
+ free((*i)->buf);
+ (*i)->buf = malloc(3 * (*i)->bufwidth * (*i)->bufheight);
+
+ TDEBUG_START
+ if((*i)->fmt->read(*i)){
+ fprintf(stderr, "read error!\n");
+ }
+ TDEBUG_END("read");
+
+ if((*i)->state == LOADED){
+ /* We are done with the format's methods */
+ (*i)->fmt->close(*i);
+ }
+
+ /* state should be set by format */
+ assert((*i)->state == LOADED || (*i)->state == FASTLOADED);
+ }else if(width && height){
+ if(dstate == SCALED || dstate == FASTSCALED){
+ (*i)->ximg = getimage(*i, width, height, dstate == FASTSCALED);
+ (*i)->state = dstate;
+ }else if(dstate == DRAWN || dstate == FASTDRAWN){
+ assert((*i)->ximg);
+ drawimage((*i)->ximg, width, height);
+ (*i)->state = dstate;
+ }
}
}
return (*i)->state != DRAWN;
diff --git a/src/meh.h b/src/meh.h
index a17d730..8465887 100644
--- a/src/meh.h
+++ b/src/meh.h
@@ -7,6 +7,7 @@ struct image;
struct imageformat{
struct image *(*open)(FILE *);
+ void (*prep)(struct image *);
int (*read)(struct image *);
void (*close)(struct image *);
};
@@ -30,11 +31,10 @@ struct image{
XImage *ximg;
};
-XImage *ximage(struct image *img, unsigned int width, unsigned int height);
void setaspect(unsigned int w, unsigned int h);
void xinit();
void drawimage(XImage *ximg, unsigned int width, unsigned int height);
-XImage *getimage(struct image *img, unsigned int width, unsigned int height);
+XImage *getimage(struct image *img, unsigned int width, unsigned int height, int fast);
#ifdef TDEBUG
#define TDEBUG_START \
diff --git a/src/png.c b/src/png.c
index 6f567b1..9aab2f8 100644
--- a/src/png.c
+++ b/src/png.c
@@ -97,6 +97,9 @@ int png_read(struct image *img){
png_read_image(p->png_ptr, row_pointers);
free(row_pointers);
+
+ img->state = LOADED;
+
return 0;
}
@@ -108,6 +111,7 @@ void png_close(struct image *img){
struct imageformat libpng = {
png_open,
+ NULL,
png_read,
png_close
};
diff --git a/src/xlib.c b/src/xlib.c
index 7dfa69b..ca0a1b5 100644
--- a/src/xlib.c
+++ b/src/xlib.c
@@ -25,7 +25,7 @@ void scale(struct image *img, XImage *ximg);
void linearscale(struct image *img, XImage *ximg);
XShmSegmentInfo *shminfo;
-XImage *ximage(struct image *img, unsigned int width, unsigned int height) {
+XImage *ximage(struct image *img, unsigned int width, unsigned int height, int fast){
int depth;
XImage *ximg = NULL;
Visual *vis;
@@ -71,7 +71,7 @@ XImage *ximage(struct image *img, unsigned int width, unsigned int height) {
ximg->data = malloc(ximg->bytes_per_line * ximg->height);
XInitImage(ximg);
}
- scale(img, ximg);
+ (fast ? linearscale : scale)(img, ximg);
}else{
/* TODO other depths */
fprintf(stderr, "This program does not yet support display depths <24.\n");
@@ -82,11 +82,11 @@ XImage *ximage(struct image *img, unsigned int width, unsigned int height) {
return ximg;
}
-XImage *getimage(struct image *img, unsigned int width, unsigned int height){
+XImage *getimage(struct image *img, unsigned int width, unsigned int height, int fast){
if(width * img->bufheight > height * img->bufwidth){
- return ximage(img, img->bufwidth * height / img->bufheight, height);
+ return ximage(img, img->bufwidth * height / img->bufheight, height, fast);
}else{
- return ximage(img, width, img->bufheight * width / img->bufwidth);
+ return ximage(img, width, img->bufheight * width / img->bufwidth, fast);
}
}