load slide image on-demand
On Sat, Jun 04, 2016 at 05:28:31PM +0200, Markus Teich wrote:
> Hiltjo Posthuma wrote:
> > previously an image file would be opened but only ffread when advancing to
> > the slide, but when the slide was not used it gave an error:
> >
> > 	/usr/local/bin/2ff: failed to convert image/png
>
> Heyho Hiltjo,
>
> thanks for the patch. Unfortunately it does not work if the first slide contains
> an image (ffopen is only called in advance). I think it would be good to merge
> ffopen and ffread instead into a single function ffload. This makes the `LOADED`
> state clearer and also enforces that the fd is closed in the same function where
> it is opened. This ffload function should then be called in advance() replacing
> the ffread() calls if the image is not loaded yet and once in load() for the
> first slide if it is an image.
>
Ah yes, sorry for the oversight.
> If you want to take this new approach, go for it, otherwise I'll look into it
> myself.
>
I have attached a patch that does this, I hope you'll like it.
Also I'm not sure if we need the below code in advance(), I have removed it in
the patch:
        if (slidecount > idx + 1 && slides[idx + 1].img)
                ffread(slides[idx + 1].img);
        if (0 < idx && slides[idx - 1].img)
                ffread(slides[idx - 1].img);
That seems to preload the next and previous slide image right? A minor issue I
notice also is that images seem to flicker, it uses XPutImage directly to
xw.win. Maybe it can be replaced with a backbuffer then XCopyArea? What do you
think?
In advance() it should also not always be needed to rescale the image.
--
Kind regards,
Hiltjo
From 97bebdcab4003f9acdfdd4bdf424449299ffd61d Mon Sep 17 00:00:00 2001
From: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat, 4 Jun 2016 21:34:25 +0200
Subject: [PATCH] merge ffread and ffopen into one function
			
			
This commit is contained in:
		
							parent
							
								
									44a50ad948
								
							
						
					
					
						commit
						fd303ee9c1
					
				
							
								
								
									
										79
									
								
								sent.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								sent.c
									
									
									
									
									
								
							@ -89,9 +89,8 @@ typedef struct {
 | 
				
			|||||||
	const Arg arg;
 | 
						const Arg arg;
 | 
				
			||||||
} Shortcut;
 | 
					} Shortcut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Image *ffopen(char *filename);
 | 
					 | 
				
			||||||
static void fffree(Image *img);
 | 
					static void fffree(Image *img);
 | 
				
			||||||
static void ffread(Image *img);
 | 
					static Image *ffread(char *filename);
 | 
				
			||||||
static void ffprepare(Image *img);
 | 
					static void ffprepare(Image *img);
 | 
				
			||||||
static void ffscale(Image *img);
 | 
					static void ffscale(Image *img);
 | 
				
			||||||
static void ffdraw(Image *img);
 | 
					static void ffdraw(Image *img);
 | 
				
			||||||
@ -159,14 +158,27 @@ filter(int fd, const char *cmd)
 | 
				
			|||||||
	return fds[0];
 | 
						return fds[0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image *
 | 
					void
 | 
				
			||||||
ffopen(char *filename)
 | 
					fffree(Image *img)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						free(img->buf);
 | 
				
			||||||
 | 
						if (img->ximg)
 | 
				
			||||||
 | 
							XDestroyImage(img->ximg);
 | 
				
			||||||
 | 
						free(img);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Image *
 | 
				
			||||||
 | 
					ffread(char *filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t y, x;
 | 
				
			||||||
 | 
						uint16_t *row;
 | 
				
			||||||
 | 
						uint8_t opac, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
 | 
				
			||||||
 | 
						size_t rowlen, off, nbytes, i;
 | 
				
			||||||
 | 
						ssize_t count;
 | 
				
			||||||
	unsigned char hdr[16];
 | 
						unsigned char hdr[16];
 | 
				
			||||||
	char *bin = NULL;
 | 
						char *bin = NULL;
 | 
				
			||||||
	regex_t regex;
 | 
						regex_t regex;
 | 
				
			||||||
	Image *img;
 | 
						Image *img;
 | 
				
			||||||
	size_t i;
 | 
					 | 
				
			||||||
	int tmpfd, fd;
 | 
						int tmpfd, fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < LEN(filters); i++) {
 | 
						for (i = 0; i < LEN(filters); i++) {
 | 
				
			||||||
@ -178,13 +190,11 @@ ffopen(char *filename)
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!bin)
 | 
						if (!bin)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fd = open(filename, O_RDONLY)) < 0) {
 | 
						if ((fd = open(filename, O_RDONLY)) < 0)
 | 
				
			||||||
		die("sent: Unable to open file %s:", filename);
 | 
							die("sent: Unable to open file %s:", filename);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tmpfd = fd;
 | 
						tmpfd = fd;
 | 
				
			||||||
	fd = filter(fd, bin);
 | 
						fd = filter(fd, bin);
 | 
				
			||||||
@ -192,10 +202,7 @@ ffopen(char *filename)
 | 
				
			|||||||
		die("sent: Unable to filter %s:", filename);
 | 
							die("sent: Unable to filter %s:", filename);
 | 
				
			||||||
	close(tmpfd);
 | 
						close(tmpfd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (read(fd, hdr, 16) != 16)
 | 
						if (read(fd, hdr, 16) != 16 || memcmp("farbfeld", hdr, 8))
 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (memcmp("farbfeld", hdr, 8))
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	img = calloc(1, sizeof(Image));
 | 
						img = calloc(1, sizeof(Image));
 | 
				
			||||||
@ -203,31 +210,6 @@ ffopen(char *filename)
 | 
				
			|||||||
	img->bufwidth = ntohl(*(uint32_t *)&hdr[8]);
 | 
						img->bufwidth = ntohl(*(uint32_t *)&hdr[8]);
 | 
				
			||||||
	img->bufheight = ntohl(*(uint32_t *)&hdr[12]);
 | 
						img->bufheight = ntohl(*(uint32_t *)&hdr[12]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return img;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
fffree(Image *img)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	free(img->buf);
 | 
					 | 
				
			||||||
	if (img->ximg)
 | 
					 | 
				
			||||||
		XDestroyImage(img->ximg);
 | 
					 | 
				
			||||||
	free(img);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
ffread(Image *img)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint32_t y, x;
 | 
					 | 
				
			||||||
	uint16_t *row;
 | 
					 | 
				
			||||||
	uint8_t opac;
 | 
					 | 
				
			||||||
	uint8_t fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
 | 
					 | 
				
			||||||
	size_t rowlen, off, nbytes;
 | 
					 | 
				
			||||||
	ssize_t count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (img->state & LOADED)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (img->buf)
 | 
						if (img->buf)
 | 
				
			||||||
		free(img->buf);
 | 
							free(img->buf);
 | 
				
			||||||
	/* internally the image is stored in 888 format */
 | 
						/* internally the image is stored in 888 format */
 | 
				
			||||||
@ -237,9 +219,8 @@ ffread(Image *img)
 | 
				
			|||||||
	/* scratch buffer to read row by row */
 | 
						/* scratch buffer to read row by row */
 | 
				
			||||||
	rowlen = img->bufwidth * 2 * strlen("RGBA");
 | 
						rowlen = img->bufwidth * 2 * strlen("RGBA");
 | 
				
			||||||
	row = malloc(rowlen);
 | 
						row = malloc(rowlen);
 | 
				
			||||||
	if (!row) {
 | 
						if (!row)
 | 
				
			||||||
		die("sent: Unable to malloc buffer for image row.\n");
 | 
							die("sent: Unable to malloc buffer for image row.\n");
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* extract window background color channels for transparency */
 | 
						/* extract window background color channels for transparency */
 | 
				
			||||||
	bg_r = (sc[ColBg].pixel >> 16) % 256;
 | 
						bg_r = (sc[ColBg].pixel >> 16) % 256;
 | 
				
			||||||
@ -270,6 +251,8 @@ ffread(Image *img)
 | 
				
			|||||||
	free(row);
 | 
						free(row);
 | 
				
			||||||
	close(img->fd);
 | 
						close(img->fd);
 | 
				
			||||||
	img->state |= LOADED;
 | 
						img->state |= LOADED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return img;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -444,13 +427,11 @@ load(FILE *fp)
 | 
				
			|||||||
				memmove(s->lines[s->linecount], &s->lines[s->linecount][1], blen);
 | 
									memmove(s->lines[s->linecount], &s->lines[s->linecount][1], blen);
 | 
				
			||||||
			s->linecount++;
 | 
								s->linecount++;
 | 
				
			||||||
		} while ((p = fgets(buf, sizeof(buf), fp)) && strcmp(buf, "\n") != 0);
 | 
							} while ((p = fgets(buf, sizeof(buf), fp)) && strcmp(buf, "\n") != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		slidecount++;
 | 
							slidecount++;
 | 
				
			||||||
		if (!p)
 | 
							if (!p)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (slidecount && slides[0].embed && slides[0].embed[0])
 | 
					 | 
				
			||||||
		slides[0].img = ffopen(slides[0].embed);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -462,13 +443,7 @@ advance(const Arg *arg)
 | 
				
			|||||||
		if (slides[idx].img)
 | 
							if (slides[idx].img)
 | 
				
			||||||
			slides[idx].img->state &= ~(DRAWN | SCALED);
 | 
								slides[idx].img->state &= ~(DRAWN | SCALED);
 | 
				
			||||||
		idx = new_idx;
 | 
							idx = new_idx;
 | 
				
			||||||
		if (!slides[idx].img && slides[idx].embed && slides[idx].embed[0])
 | 
					 | 
				
			||||||
			slides[idx].img = ffopen(slides[idx].embed);
 | 
					 | 
				
			||||||
		xdraw();
 | 
							xdraw();
 | 
				
			||||||
		if (slidecount > idx + 1 && slides[idx + 1].img)
 | 
					 | 
				
			||||||
			ffread(slides[idx + 1].img);
 | 
					 | 
				
			||||||
		if (0 < idx && slides[idx - 1].img)
 | 
					 | 
				
			||||||
			ffread(slides[idx - 1].img);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -514,7 +489,11 @@ void
 | 
				
			|||||||
xdraw()
 | 
					xdraw()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int height, width, i;
 | 
						unsigned int height, width, i;
 | 
				
			||||||
	Image *im = slides[idx].img;
 | 
						Image *im;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!slides[idx].img && slides[idx].embed && slides[idx].embed[0])
 | 
				
			||||||
 | 
							slides[idx].img = ffread(slides[idx].embed);
 | 
				
			||||||
 | 
						im = slides[idx].img;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getfontsize(&slides[idx], &width, &height);
 | 
						getfontsize(&slides[idx], &width, &height);
 | 
				
			||||||
	XClearWindow(xw.dpy, xw.win);
 | 
						XClearWindow(xw.dpy, xw.win);
 | 
				
			||||||
@ -532,8 +511,6 @@ xdraw()
 | 
				
			|||||||
			         0);
 | 
								         0);
 | 
				
			||||||
		drw_map(d, xw.win, 0, 0, xw.w, xw.h);
 | 
							drw_map(d, xw.win, 0, 0, xw.w, xw.h);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (!(im->state & LOADED))
 | 
					 | 
				
			||||||
			ffread(im);
 | 
					 | 
				
			||||||
		if (!(im->state & SCALED))
 | 
							if (!(im->state & SCALED))
 | 
				
			||||||
			ffprepare(im);
 | 
								ffprepare(im);
 | 
				
			||||||
		if (!(im->state & DRAWN))
 | 
							if (!(im->state & DRAWN))
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user