Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 8 files changed
  • 0 comments
  • 1 contributor
Jan 15, 2012
Werner Almesberger pixbuf: open and close file in pixbuf_get instead of loaders
This removes a bit of redundancy and will avoid races when adding
timestamping.
1110f14
Werner Almesberger pixbuf: simplify manager.c and catch strdup() failure
This patch makes the following three changes:

- check for strdup() failure
- remove check for filename == NULL, since this can no longer happen
- simplify pixbuf_dec_ref
db00ead
Werner Almesberger pixbuf: also compare modification time of file when looking for cache…
… hits
bcdd6c5
Werner Almesberger pixbuf: new function pixbuf_update to return up to date version of a …
…pixbuf
4607dc9
Werner Almesberger performance: use image cache and don't recompile if only images have …
…changed
c064b09
18  src/compiler/compiler.c
@@ -570,20 +570,22 @@ void patch_free(struct patch *p)
570 570
 	free(p);
571 571
 }
572 572
 
573  
-int patch_images_uptodate(const struct patch *p)
  573
+struct patch *patch_refresh(struct patch *p)
574 574
 {
575  
-	const struct image *img;
576  
-	struct stat st;
  575
+	struct image *img;
  576
+	struct pixbuf *pixbuf;
577 577
 
578 578
 	for(img = p->images; img != p->images+IMAGE_COUNT; img++) {
579 579
 		if(!img->pixbuf)
580 580
 			continue;
581  
-		if(lstat(img->filename, &st) < 0)
582  
-			return 0;
583  
-		if(st.st_mtime != img->st.st_mtime)
584  
-			return 0;
  581
+		pixbuf = pixbuf_update(img->pixbuf);
  582
+		if(!pixbuf)
  583
+			return NULL;
  584
+		pixbuf_dec_ref(img->pixbuf);
  585
+		img->pixbuf = pixbuf;
585 586
 	}
586  
-	return 1;
  587
+	p->ref++;
  588
+	return p;
587 589
 }
588 590
 
589 591
 #endif
8  src/compiler/compiler.h
@@ -247,16 +247,10 @@ struct patch {
247 247
 
248 248
 typedef void (*report_message)(const char *);
249 249
 
250  
-static inline struct patch *patch_clone(struct patch *p)
251  
-{
252  
-	p->ref++;
253  
-	return p;
254  
-}
255  
-
256 250
 struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
257 251
 struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
258 252
 struct patch *patch_copy(struct patch *p);
259 253
 void patch_free(struct patch *p);
260  
-int patch_images_uptodate(const struct patch *p);
  254
+struct patch *patch_refresh(struct patch *p);
261 255
 
262 256
 #endif /* __COMPILER_H */
5  src/gui/performance.c
@@ -334,9 +334,8 @@ static struct patch *cache_lookup(const struct patch_info *pi)
334 334
 
335 335
 	for(c = cache; c; c = c->next)
336 336
 		if(c->st.st_mtime == pi->st.st_mtime &&
337  
-		    !strcmp(c->filename, pi->filename) &&
338  
-		    patch_images_uptodate(c->p))
339  
-			return patch_clone(c->p);
  337
+		    !strcmp(c->filename, pi->filename))
  338
+			return patch_refresh(c->p);
340 339
 	return NULL;
341 340
 }
342 341
 
16  src/pixbuf/loaderjpeg.c
@@ -37,25 +37,20 @@ static void my_error_exit(j_common_ptr cinfo)
37 37
 	longjmp(myerr->setjmp_buffer, 1);
38 38
 }
39 39
 
40  
-struct pixbuf *pixbuf_load_jpeg(char *filename)
  40
+struct pixbuf *pixbuf_load_jpeg(FILE *file)
41 41
 {
42  
-	struct pixbuf *ret;
43  
-	FILE *fd;
  42
+	struct pixbuf *ret = NULL;
44 43
 	struct jpeg_decompress_struct cinfo;
45 44
 	struct my_error_mgr jerr;
46 45
 	unsigned char *pixels;
47 46
 	int i;
48 47
 	unsigned char **row_pointers;
49 48
 	
50  
-	ret = NULL;
51  
-	fd = fopen(filename, "rb");
52  
-	if(fd == NULL) goto free0;
53  
-	
54 49
 	cinfo.err = jpeg_std_error((struct jpeg_error_mgr *)&jerr);
55 50
 	jerr.pub.error_exit = my_error_exit;
56 51
 	if(setjmp(jerr.setjmp_buffer)) goto free2;
57 52
 	jpeg_create_decompress(&cinfo);
58  
-	jpeg_stdio_src(&cinfo, fd);
  53
+	jpeg_stdio_src(&cinfo, file);
59 54
 	jpeg_read_header(&cinfo, TRUE);
60 55
 		
61 56
 	cinfo.out_color_space = JCS_RGB;
@@ -76,7 +71,6 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
76 71
 
77 72
 	ret = pixbuf_new(cinfo.image_width, cinfo.image_height);
78 73
 	if(ret == NULL) goto free5;
79  
-	ret->filename = strdup(filename);
80 74
 	if(!pixbuf_dither(ret->pixels, row_pointers, cinfo.image_width, cinfo.image_height, 0)) {
81 75
 		pixbuf_dec_ref(ret);
82 76
 		ret = NULL;
@@ -91,7 +85,5 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
91 85
 	free(pixels);
92 86
 free2:
93 87
 	jpeg_destroy_decompress(&cinfo);
94  
-	fclose(fd);
95  
-free0:
96 88
 	return ret;
97  
-}
  89
+}
14  src/pixbuf/loaderpng.c
@@ -29,10 +29,9 @@
29 29
 #warning Floating point PNG is slow
30 30
 #endif
31 31
 
32  
-struct pixbuf *pixbuf_load_png(char *filename)
  32
+struct pixbuf *pixbuf_load_png(FILE *file)
33 33
 {
34 34
 	struct pixbuf *ret;
35  
-	FILE *fd;
36 35
 	unsigned char header[8];
37 36
 	png_structp png_ptr;
38 37
 	png_infop info_ptr;
@@ -44,9 +43,7 @@ struct pixbuf *pixbuf_load_png(char *filename)
44 43
 	int y;
45 44
 
46 45
 	ret = NULL;
47  
-	fd = fopen(filename, "r");
48  
-	if(fd == NULL) goto free0;
49  
-	fread(header, 1, 8, fd);
  46
+	fread(header, 1, 8, file);
50 47
 	if(png_sig_cmp(header, 0, 8)) goto free1;
51 48
 
52 49
 	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
@@ -55,7 +52,7 @@ struct pixbuf *pixbuf_load_png(char *filename)
55 52
 	if(info_ptr == NULL) goto free2;
56 53
 
57 54
 	if(setjmp(png_jmpbuf(png_ptr))) goto free3;
58  
-	png_init_io(png_ptr, fd);
  55
+	png_init_io(png_ptr, file);
59 56
 	png_set_sig_bytes(png_ptr, 8);
60 57
 	png_read_info(png_ptr, info_ptr);
61 58
 
@@ -81,7 +78,6 @@ struct pixbuf *pixbuf_load_png(char *filename)
81 78
 
82 79
 	ret = pixbuf_new(width, height);
83 80
 	if(ret == NULL) goto free4;
84  
-	ret->filename = strdup(filename);
85 81
 	if(!pixbuf_dither(ret->pixels, row_pointers, width, height, color_type == PNG_COLOR_TYPE_RGBA)) {
86 82
 		pixbuf_dec_ref(ret);
87 83
 		ret = NULL;
@@ -97,7 +93,5 @@ struct pixbuf *pixbuf_load_png(char *filename)
97 93
 free2:
98 94
 	png_destroy_read_struct(&png_ptr, NULL, NULL);
99 95
 free1:
100  
-	fclose(fd);
101  
-free0:
102 96
 	return ret;
103  
-}
  97
+}
8  src/pixbuf/loaders.h
@@ -18,9 +18,11 @@
18 18
 #ifndef __PIXBUF_LOADERS_H
19 19
 #define __PIXBUF_LOADERS_H
20 20
 
  21
+#include <stdio.h>
  22
+
21 23
 #include "pixbuf.h"
22 24
 
23  
-struct pixbuf *pixbuf_load_png(char *filename);
24  
-struct pixbuf *pixbuf_load_jpeg(char *filename);
  25
+struct pixbuf *pixbuf_load_png(FILE *file);
  26
+struct pixbuf *pixbuf_load_jpeg(FILE *file);
25 27
 
26  
-#endif /* __PIXBUF_LOADERS_H */
  28
+#endif /* __PIXBUF_LOADERS_H */
86  src/pixbuf/manager.c
@@ -16,7 +16,9 @@
16 16
  */
17 17
 
18 18
 #include <stdlib.h>
  19
+#include <stdio.h>
19 20
 #include <string.h>
  21
+#include <sys/stat.h>
20 22
 
21 23
 #include "pixbuf.h"
22 24
 #include "loaders.h"
@@ -41,13 +43,14 @@ struct pixbuf *pixbuf_new(int width, int height)
41 43
 struct pixbuf *pixbuf_search(char *filename)
42 44
 {
43 45
 	struct pixbuf *p;
44  
-	
45  
-	p = head;
46  
-	while(p != NULL) {
47  
-		if((p->filename != NULL) && (strcmp(p->filename, filename) == 0))
  46
+	struct stat st;
  47
+
  48
+	if(lstat(filename, &st) < 0)
  49
+		return NULL;
  50
+	for(p = head; p; p = p->next)
  51
+		if(strcmp(p->filename, filename) == 0 &&
  52
+		    st.st_mtime == p->st.st_mtime)
48 53
 			return p;
49  
-		p = p->next;
50  
-	}
51 54
 	return NULL;
52 55
 }
53 56
 
@@ -59,43 +62,60 @@ void pixbuf_inc_ref(struct pixbuf *p)
59 62
 
60 63
 void pixbuf_dec_ref(struct pixbuf *p)
61 64
 {
62  
-	struct pixbuf *prev;
  65
+	struct pixbuf **anchor;
63 66
 	
64  
-	if(p != NULL) {
65  
-		p->refcnt--;
66  
-		if(p->refcnt == 0) {
67  
-			if(p == head) {
68  
-				head = head->next;
69  
-				free(p->filename);
70  
-				free(p);
71  
-			} else {
72  
-				prev = head;
73  
-				while(prev->next != p)
74  
-					prev = prev->next;
75  
-				prev->next = p->next;
76  
-				free(p->filename);
77  
-				free(p);
78  
-			}
79  
-		}
80  
-	}
  67
+	if(!p)
  68
+		return;
  69
+	if(--p->refcnt)
  70
+		return;
  71
+	for(anchor = &head; *anchor != p; anchor = &(*anchor)->next);
  72
+	*anchor = p->next;
  73
+	free(p->filename);
  74
+	free(p);
81 75
 }
82 76
 
83 77
 struct pixbuf *pixbuf_get(char *filename)
84 78
 {
85 79
 	struct pixbuf *p;
86  
-	
  80
+	FILE *file;
  81
+
87 82
 	p = pixbuf_search(filename);
88 83
 	if(p != NULL) {
89 84
 		pixbuf_inc_ref(p);
90 85
 		return p;
91 86
 	}
92  
-	
  87
+
  88
+	file = fopen(filename, "rb");
  89
+	if(!file)
  90
+		return NULL;
  91
+
93 92
 	/* try all loaders */
94  
-	p = pixbuf_load_png(filename);
95  
-	if(p != NULL) return p;
96  
-	p = pixbuf_load_jpeg(filename);
97  
-	if(p != NULL) return p;
98  
-	
99  
-	/* no loader was successful */
100  
-	return NULL;
  93
+	p = pixbuf_load_png(file);
  94
+	if(!p) {
  95
+		rewind(file);
  96
+		p = pixbuf_load_jpeg(file);
  97
+	}
  98
+	if(p) {
  99
+		p->filename = strdup(filename);
  100
+		fstat(fileno(file), &p->st);
  101
+		if(!p->filename) {
  102
+			free(p);
  103
+			p = NULL;
  104
+		}
  105
+	}
  106
+	fclose(file);
  107
+	return p;
  108
+}
  109
+
  110
+struct pixbuf *pixbuf_update(struct pixbuf *p)
  111
+{
  112
+	struct stat st;
  113
+
  114
+	if(lstat(p->filename, &st) < 0)
  115
+		return NULL;
  116
+	if(st.st_mtime == p->st.st_mtime) {
  117
+		p->refcnt++;
  118
+		return p;
  119
+	}
  120
+	return pixbuf_get(p->filename);
101 121
 }
4  src/pixbuf/pixbuf.h
@@ -18,9 +18,12 @@
18 18
 #ifndef __PIXBUF_PIXBUF_H
19 19
 #define __PIXBUF_PIXBUF_H
20 20
 
  21
+#include <sys/stat.h>
  22
+
21 23
 struct pixbuf {
22 24
 	int refcnt;
23 25
 	char *filename;
  26
+	struct stat st;
24 27
 	struct pixbuf *next;
25 28
 	int width, height;
26 29
 	unsigned short pixels[];
@@ -32,5 +35,6 @@ void pixbuf_inc_ref(struct pixbuf *p);
32 35
 void pixbuf_dec_ref(struct pixbuf *p);
33 36
 
34 37
 struct pixbuf *pixbuf_get(char *filename);
  38
+struct pixbuf *pixbuf_update(struct pixbuf *p);
35 39
 
36 40
 #endif /* __PIXBUF_PIXBUF_H */

No commit comments for this range

Something went wrong with that request. Please try again.