Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: m-labs/flickernoise
base: d4ef921
...
head fork: m-labs/flickernoise
compare: c064b09
  • 5 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
Commits on Jan 15, 2012
Werner Almesberger wpwrak 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 wpwrak 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 wpwrak pixbuf: also compare modification time of file when looking for cache…
… hits
bcdd6c5
Werner Almesberger wpwrak pixbuf: new function pixbuf_update to return up to date version of a …
…pixbuf
4607dc9
Werner Almesberger wpwrak performance: use image cache and don't recompile if only images have …
…changed
c064b09
18 src/compiler/compiler.c
View
@@ -570,20 +570,22 @@ void patch_free(struct patch *p)
free(p);
}
-int patch_images_uptodate(const struct patch *p)
+struct patch *patch_refresh(struct patch *p)
{
- const struct image *img;
- struct stat st;
+ struct image *img;
+ struct pixbuf *pixbuf;
for(img = p->images; img != p->images+IMAGE_COUNT; img++) {
if(!img->pixbuf)
continue;
- if(lstat(img->filename, &st) < 0)
- return 0;
- if(st.st_mtime != img->st.st_mtime)
- return 0;
+ pixbuf = pixbuf_update(img->pixbuf);
+ if(!pixbuf)
+ return NULL;
+ pixbuf_dec_ref(img->pixbuf);
+ img->pixbuf = pixbuf;
}
- return 1;
+ p->ref++;
+ return p;
}
#endif
8 src/compiler/compiler.h
View
@@ -247,16 +247,10 @@ struct patch {
typedef void (*report_message)(const char *);
-static inline struct patch *patch_clone(struct patch *p)
-{
- p->ref++;
- return p;
-}
-
struct patch *patch_compile(const char *basedir, const char *patch_code, report_message rmc);
struct patch *patch_compile_filename(const char *filename, const char *patch_code, report_message rmc);
struct patch *patch_copy(struct patch *p);
void patch_free(struct patch *p);
-int patch_images_uptodate(const struct patch *p);
+struct patch *patch_refresh(struct patch *p);
#endif /* __COMPILER_H */
5 src/gui/performance.c
View
@@ -334,9 +334,8 @@ static struct patch *cache_lookup(const struct patch_info *pi)
for(c = cache; c; c = c->next)
if(c->st.st_mtime == pi->st.st_mtime &&
- !strcmp(c->filename, pi->filename) &&
- patch_images_uptodate(c->p))
- return patch_clone(c->p);
+ !strcmp(c->filename, pi->filename))
+ return patch_refresh(c->p);
return NULL;
}
16 src/pixbuf/loaderjpeg.c
View
@@ -37,25 +37,20 @@ static void my_error_exit(j_common_ptr cinfo)
longjmp(myerr->setjmp_buffer, 1);
}
-struct pixbuf *pixbuf_load_jpeg(char *filename)
+struct pixbuf *pixbuf_load_jpeg(FILE *file)
{
- struct pixbuf *ret;
- FILE *fd;
+ struct pixbuf *ret = NULL;
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
unsigned char *pixels;
int i;
unsigned char **row_pointers;
- ret = NULL;
- fd = fopen(filename, "rb");
- if(fd == NULL) goto free0;
-
cinfo.err = jpeg_std_error((struct jpeg_error_mgr *)&jerr);
jerr.pub.error_exit = my_error_exit;
if(setjmp(jerr.setjmp_buffer)) goto free2;
jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, fd);
+ jpeg_stdio_src(&cinfo, file);
jpeg_read_header(&cinfo, TRUE);
cinfo.out_color_space = JCS_RGB;
@@ -76,7 +71,6 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
ret = pixbuf_new(cinfo.image_width, cinfo.image_height);
if(ret == NULL) goto free5;
- ret->filename = strdup(filename);
if(!pixbuf_dither(ret->pixels, row_pointers, cinfo.image_width, cinfo.image_height, 0)) {
pixbuf_dec_ref(ret);
ret = NULL;
@@ -91,7 +85,5 @@ struct pixbuf *pixbuf_load_jpeg(char *filename)
free(pixels);
free2:
jpeg_destroy_decompress(&cinfo);
- fclose(fd);
-free0:
return ret;
-}
+}
14 src/pixbuf/loaderpng.c
View
@@ -29,10 +29,9 @@
#warning Floating point PNG is slow
#endif
-struct pixbuf *pixbuf_load_png(char *filename)
+struct pixbuf *pixbuf_load_png(FILE *file)
{
struct pixbuf *ret;
- FILE *fd;
unsigned char header[8];
png_structp png_ptr;
png_infop info_ptr;
@@ -44,9 +43,7 @@ struct pixbuf *pixbuf_load_png(char *filename)
int y;
ret = NULL;
- fd = fopen(filename, "r");
- if(fd == NULL) goto free0;
- fread(header, 1, 8, fd);
+ fread(header, 1, 8, file);
if(png_sig_cmp(header, 0, 8)) goto free1;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
@@ -55,7 +52,7 @@ struct pixbuf *pixbuf_load_png(char *filename)
if(info_ptr == NULL) goto free2;
if(setjmp(png_jmpbuf(png_ptr))) goto free3;
- png_init_io(png_ptr, fd);
+ png_init_io(png_ptr, file);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
@@ -81,7 +78,6 @@ struct pixbuf *pixbuf_load_png(char *filename)
ret = pixbuf_new(width, height);
if(ret == NULL) goto free4;
- ret->filename = strdup(filename);
if(!pixbuf_dither(ret->pixels, row_pointers, width, height, color_type == PNG_COLOR_TYPE_RGBA)) {
pixbuf_dec_ref(ret);
ret = NULL;
@@ -97,7 +93,5 @@ struct pixbuf *pixbuf_load_png(char *filename)
free2:
png_destroy_read_struct(&png_ptr, NULL, NULL);
free1:
- fclose(fd);
-free0:
return ret;
-}
+}
8 src/pixbuf/loaders.h
View
@@ -18,9 +18,11 @@
#ifndef __PIXBUF_LOADERS_H
#define __PIXBUF_LOADERS_H
+#include <stdio.h>
+
#include "pixbuf.h"
-struct pixbuf *pixbuf_load_png(char *filename);
-struct pixbuf *pixbuf_load_jpeg(char *filename);
+struct pixbuf *pixbuf_load_png(FILE *file);
+struct pixbuf *pixbuf_load_jpeg(FILE *file);
-#endif /* __PIXBUF_LOADERS_H */
+#endif /* __PIXBUF_LOADERS_H */
86 src/pixbuf/manager.c
View
@@ -16,7 +16,9 @@
*/
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
+#include <sys/stat.h>
#include "pixbuf.h"
#include "loaders.h"
@@ -41,13 +43,14 @@ struct pixbuf *pixbuf_new(int width, int height)
struct pixbuf *pixbuf_search(char *filename)
{
struct pixbuf *p;
-
- p = head;
- while(p != NULL) {
- if((p->filename != NULL) && (strcmp(p->filename, filename) == 0))
+ struct stat st;
+
+ if(lstat(filename, &st) < 0)
+ return NULL;
+ for(p = head; p; p = p->next)
+ if(strcmp(p->filename, filename) == 0 &&
+ st.st_mtime == p->st.st_mtime)
return p;
- p = p->next;
- }
return NULL;
}
@@ -59,43 +62,60 @@ void pixbuf_inc_ref(struct pixbuf *p)
void pixbuf_dec_ref(struct pixbuf *p)
{
- struct pixbuf *prev;
+ struct pixbuf **anchor;
- if(p != NULL) {
- p->refcnt--;
- if(p->refcnt == 0) {
- if(p == head) {
- head = head->next;
- free(p->filename);
- free(p);
- } else {
- prev = head;
- while(prev->next != p)
- prev = prev->next;
- prev->next = p->next;
- free(p->filename);
- free(p);
- }
- }
- }
+ if(!p)
+ return;
+ if(--p->refcnt)
+ return;
+ for(anchor = &head; *anchor != p; anchor = &(*anchor)->next);
+ *anchor = p->next;
+ free(p->filename);
+ free(p);
}
struct pixbuf *pixbuf_get(char *filename)
{
struct pixbuf *p;
-
+ FILE *file;
+
p = pixbuf_search(filename);
if(p != NULL) {
pixbuf_inc_ref(p);
return p;
}
-
+
+ file = fopen(filename, "rb");
+ if(!file)
+ return NULL;
+
/* try all loaders */
- p = pixbuf_load_png(filename);
- if(p != NULL) return p;
- p = pixbuf_load_jpeg(filename);
- if(p != NULL) return p;
-
- /* no loader was successful */
- return NULL;
+ p = pixbuf_load_png(file);
+ if(!p) {
+ rewind(file);
+ p = pixbuf_load_jpeg(file);
+ }
+ if(p) {
+ p->filename = strdup(filename);
+ fstat(fileno(file), &p->st);
+ if(!p->filename) {
+ free(p);
+ p = NULL;
+ }
+ }
+ fclose(file);
+ return p;
+}
+
+struct pixbuf *pixbuf_update(struct pixbuf *p)
+{
+ struct stat st;
+
+ if(lstat(p->filename, &st) < 0)
+ return NULL;
+ if(st.st_mtime == p->st.st_mtime) {
+ p->refcnt++;
+ return p;
+ }
+ return pixbuf_get(p->filename);
}
4 src/pixbuf/pixbuf.h
View
@@ -18,9 +18,12 @@
#ifndef __PIXBUF_PIXBUF_H
#define __PIXBUF_PIXBUF_H
+#include <sys/stat.h>
+
struct pixbuf {
int refcnt;
char *filename;
+ struct stat st;
struct pixbuf *next;
int width, height;
unsigned short pixels[];
@@ -32,5 +35,6 @@ void pixbuf_inc_ref(struct pixbuf *p);
void pixbuf_dec_ref(struct pixbuf *p);
struct pixbuf *pixbuf_get(char *filename);
+struct pixbuf *pixbuf_update(struct pixbuf *p);
#endif /* __PIXBUF_PIXBUF_H */

No commit comments for this range

Something went wrong with that request. Please try again.