[poppler] test: update-cache.c, NONE, 1.1 read-cache.c, NONE,
1.1 Makefile, 1.10, 1.11 test-poppler.c, 1.5,
1.6 buffer-diff.c, 1.3, 1.4
Jeff Muizelaar
jrmuizel at kemper.freedesktop.org
Wed Sep 6 16:28:55 PDT 2006
Update of /cvs/poppler/test
In directory kemper:/tmp/cvs-serv12204
Modified Files:
Makefile test-poppler.c buffer-diff.c
Added Files:
update-cache.c read-cache.c
Log Message:
Add support for a reference cache file that contains SHA1 hashes of the
reference images. Having the cache avoids the performance hit of reading and
decompressing the reference pngs.
--- NEW FILE: update-cache.c ---
#include <stdlib.h>
#include <stdio.h>
#include <glob.h>
#include <string.h>
#include <openssl/sha.h>
#include <libgen.h>
#include "read-png.h"
#include "read-cache.h"
static void hash_image(FILE *cache, const char *path)
{
unsigned int width, height, stride;
unsigned char *buf, *buf_diff;
unsigned char hash[SHA_DIGEST_LENGTH];
unsigned int buffer_length;
read_png_status_t status;
char *path_copy = strdup(path);
char *name = basename(path_copy);
status = read_png_argb32 (path, &buf, &width, &height, &stride);
buffer_length = height * stride;
printf("%d %d %d\n", width, height, stride);
SHA1(buf, buffer_length, hash);
int i;
for (i=0; i<sizeof(hash); i++) {
printf("%02x", hash[i]);
}
printf("\n");
/* write the NULL character as well */
fwrite(name, 1, strlen(name)+1, cache);
fwrite(hash, 1, sizeof(hash), cache);
free(path_copy);
free(buf);
}
int main(int argc, char **argv)
{
glob_t globbuf;
int i;
FILE *cache;
if (argc > 1) {
/* search in directory of first argument for cache file */
cache = cache_open(argv[1], "w+");
} else {
cache = cache_open("test/", "w+");
}
if (!cache) {
printf("could not open cache\n");
exit(1);
}
if (argc > 1) {
for (i=1; i<argc; i++) {
char *glob_pat;
asprintf(&glob_pat, "%s*-ref.png", argv[i]);
printf("pat: %s\n", glob_pat);
glob(glob_pat, 0, NULL, &globbuf);
int j;
for (j=0; j<globbuf.gl_pathc; j++) {
printf("%s\n", globbuf.gl_pathv[j]);
hash_image(cache, globbuf.gl_pathv[j]);
}
globfree(&globbuf);
free(glob_pat);
}
} else {
glob("tests/*.pdf*-ref.png", 0, NULL, &globbuf);
for (i=0; i<globbuf.gl_pathc; i++) {
printf("%s\n", globbuf.gl_pathv[i]);
hash_image(cache, globbuf.gl_pathv[i]);
}
globfree(&globbuf);
}
fclose(cache);
return 0;
}
--- NEW FILE: read-cache.c ---
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
#include <openssl/sha.h>
#include "read-cache.h"
unsigned char *cache;
unsigned char *cache_end;
unsigned char *current_cache_entry;
void cache_init(const char *path)
{
FILE *f = cache_open(path, "r");
if (!f) {
printf("no cache\n");
return;
}
struct stat buf;
fstat(fileno(f), &buf);
cache = malloc(buf.st_size);
fread(cache, 1, buf.st_size, f);
fclose(f);
/* set the current entry to the begining of the cache */
current_cache_entry = cache;
cache_end = cache + buf.st_size;
}
FILE *cache_open(const char *path, const char *mode)
{
FILE *cache;
char *cache_path;
char *path_copy = strdup(path);
char *dir = dirname(path_copy);
asprintf(&cache_path, "%s/cache", dir);
cache = fopen(cache_path, mode);
free(cache_path);
free(path_copy);
return cache;
}
#define MIN(a, b) (a) < (b) ? (a) : (b)
static void print_hash(const unsigned char *hash)
{
int i;
for (i=0; i<SHA_DIGEST_LENGTH; i++) {
printf("%02x", hash[i]);
}
printf("\n");
}
int cache_compare(const char *path, const unsigned char *buffer, unsigned int length)
{
char *path_copy = strdup(path);
char *name = basename(path_copy);
int match = 0;
//printf("compare: %s\n", path);
int name_length = strlen(name);
while (current_cache_entry < cache_end) {
int cache_length = strlen(current_cache_entry);
int min_length = MIN(cache_length, name_length);
int result = memcmp(name, current_cache_entry, min_length);
if (result == 0) {
unsigned char *cache_hash = current_cache_entry + cache_length + 1;
unsigned char hash[SHA_DIGEST_LENGTH];
//printf("found entry\n");
SHA1(buffer, length, hash);
print_hash(cache_hash);
print_hash(hash);
current_cache_entry = cache_hash + SHA_DIGEST_LENGTH;
match = memcmp(hash, cache_hash, SHA_DIGEST_LENGTH) == 0 ? 1 : 0;
//printf("match %d\n", match);
break;
} else if (result < 0) {
//printf("moving to next entry: %s vs. %s did not match\n", name, current_cache_entry);
current_cache_entry += cache_length + 1 + SHA_DIGEST_LENGTH;
break;
} else {
//printf("trying next entry: %s vs. %s did not match\n", name, current_cache_entry);
current_cache_entry += cache_length + 1 + SHA_DIGEST_LENGTH;
}
}
free(path_copy);
return match;
}
Index: Makefile
===================================================================
RCS file: /cvs/poppler/test/Makefile,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- Makefile 18 Jun 2006 01:44:20 -0000 1.10
+++ Makefile 6 Sep 2006 23:28:53 -0000 1.11
@@ -1,4 +1,4 @@
-CFLAGS = $(shell pkg-config --cflags poppler-glib pango gdk-2.0) -g
+CFLAGS = $(shell pkg-config --cflags poppler-glib pango gdk-2.0) -g -Wall -O2
LDLIBS = $(shell pkg-config --libs poppler-glib)
PDFS = $(addprefix tests/, mask.pdf text.pdf image.pdf type3.pdf cropbox.pdf inline-image.pdf degenerate-path.pdf)
@@ -7,13 +7,16 @@
POPPLER_DEPS = $(POPPLER_DIR)/poppler/libpoppler.la
endif
-all : test-poppler $(PDFS)
+all : test-poppler update-cache $(PDFS)
-test-poppler: buffer-diff.o read-png.o test-poppler.o write-png.o xmalloc.o $(POPPLER_DEPS)
+test-poppler: buffer-diff.o read-png.o test-poppler.o write-png.o xmalloc.o read-cache.o $(POPPLER_DEPS)
ifdef POPPLER_DIR
- $(POPPLER_DIR)/libtool --mode=link gcc -g -O2 -lpng -o $@ $^ $(POPPLER_DIR)/poppler/libpoppler.la $(POPPLER_DIR)/glib/libpoppler-glib.la
+ $(POPPLER_DIR)/libtool --mode=link gcc -Wall -g -O2 -lpng -lssl -o $@ $^ $(POPPLER_DIR)/poppler/libpoppler.la $(POPPLER_DIR)/glib/libpoppler-glib.la
endif
+update-cache: update-cache.o read-cache.o read-png.o xmalloc.o
+ $(CC) -Wall $^ -o $@ -lpng -lssl
+
clean :
rm test-poppler *.o tests/*out.png
Index: test-poppler.c
===================================================================
RCS file: /cvs/poppler/test/test-poppler.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- test-poppler.c 12 Apr 2006 05:29:11 -0000 1.5
+++ test-poppler.c 6 Sep 2006 23:28:53 -0000 1.6
@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <poppler.h>
#include <glob.h>
-
+#include "read-cache.h"
#define FAIL(msg) \
do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0)
@@ -18,7 +18,18 @@
POPPLER_TEST_FAILURE
} poppler_test_status_t;
-poppler_test_status_t gdk_pixbuf_compare(GdkPixbuf *pixbuf, char *pdf_file, int page_index)
+int ilog10(int a)
+{
+ int l = 10;
+ int log = 0;
+ while (a >= l) {
+ l *= 10;
+ log++;
+ }
+ return log;
+}
+
+poppler_test_status_t gdk_pixbuf_compare(GdkPixbuf *pixbuf, char *page_name)
{
char *png_name, *ref_name, *diff_name;
char *srcdir;
@@ -29,10 +40,9 @@
srcdir = getenv ("srcdir");
if (!srcdir)
srcdir = ".";
-
- asprintf (&png_name, "%s-%d-%s%s", pdf_file, page_index, backend, POPPLER_TEST_PNG_SUFFIX);
- asprintf (&ref_name, "%s/%s-%d-%s%s", srcdir, pdf_file, page_index, backend, POPPLER_TEST_REF_SUFFIX);
- asprintf (&diff_name, "%s-%d-%s%s", pdf_file, page_index, backend, POPPLER_TEST_DIFF_SUFFIX);
+ asprintf (&png_name, "%s-%s%s", page_name, backend, POPPLER_TEST_PNG_SUFFIX);
+ asprintf (&ref_name, "%s/%s-%s%s", srcdir, page_name, backend, POPPLER_TEST_REF_SUFFIX);
+ asprintf (&diff_name, "%s-%s%s", page_name, backend, POPPLER_TEST_DIFF_SUFFIX);
#ifdef PNG_SAVE
gdk_pixbuf_save (pixbuf, png_name, "png", &error, NULL);
pixels_changed = image_diff (png_name, ref_name, diff_name);
@@ -67,16 +77,19 @@
return pixels_changed ? POPPLER_TEST_FAILURE : POPPLER_TEST_SUCCESS;
}
-poppler_test_status_t poppler_test_page(char *pdf_file, PopplerDocument *document, int page_index) {
+poppler_test_status_t poppler_test_page(char *pdf_file, PopplerDocument *document, int page_index, int n_pages) {
GdkPixbuf *pixbuf, *thumb;
double width, height;
PopplerPage *page;
poppler_test_status_t ret;
-
- char thumb_file[strlen(pdf_file) + strlen("-thumb") + 1];
- strcpy(thumb_file, pdf_file);
- strcat(thumb_file, "-thumb");
-
+ char *page_format;
+ char *page_name;
+ char *thumb_name;
+
+ asprintf(&page_format, "%%s-%%0%dd", ilog10(n_pages)+1);
+ asprintf(&page_name, page_format, pdf_file, page_index);
+ asprintf(&thumb_name, "%s-thumb", page_name);
+
page = poppler_document_get_page (document, page_index);
if (!page)
FAIL ("page not found");
@@ -87,17 +100,19 @@
gdk_pixbuf_fill (pixbuf, 0x00106000);
poppler_page_render_to_pixbuf (page, 0, 0, width, height, 1.0, 0, pixbuf);
- ret = gdk_pixbuf_compare(pixbuf, pdf_file, page_index);
+ ret = gdk_pixbuf_compare(pixbuf, page_name);
thumb = poppler_page_get_thumbnail(page);
if (thumb)
- ret |= gdk_pixbuf_compare(thumb, thumb_file, page_index);
+ ret |= gdk_pixbuf_compare(thumb, thumb_name);
if (thumb)
g_object_unref (G_OBJECT (thumb));
g_object_unref (G_OBJECT (page));
g_object_unref (G_OBJECT (pixbuf));
+ free(page_format);
+ free(page_name);
return ret;
}
@@ -125,7 +140,7 @@
for (i=0; i<n_pages; i++) {
printf("%s-%d ", pdf_file, i);
fflush(stdout);
- if (poppler_test_page(pdf_file, document, i))
+ if (poppler_test_page(pdf_file, document, i, n_pages))
printf("FAIL\n");
else
printf("PASS\n");
@@ -140,10 +155,12 @@
int i;
g_type_init ();
if (argc > 1) {
+ cache_init(argv[1]);
for (i=1; i<argc; i++) {
poppler_test(argv[i]);
}
} else {
+ cache_init("tests/");
glob("tests/*.pdf", 0, NULL, &globbuf);
for (i=0; i<globbuf.gl_pathc; i++) {
poppler_test(globbuf.gl_pathv[i]);
Index: buffer-diff.c
===================================================================
RCS file: /cvs/poppler/test/buffer-diff.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- buffer-diff.c 12 Apr 2006 05:29:11 -0000 1.3
+++ buffer-diff.c 6 Sep 2006 23:28:53 -0000 1.4
@@ -66,6 +66,7 @@
int channel;
uint32_t value_a, value_b;
int pixel_differs = 0;
+ //XXX: it looks like this might overread...
value_a = *(uint32_t*)(&(row_a[x*4]));
value_b = *(uint32_t*)(&(row_b[x*4]));
if (value_a != value_b) {
@@ -93,6 +94,21 @@
return pixels_changed;
}
+static void copy_file(const char *filename_a, const char *filename_b)
+{
+ char buf[4096];
+ FILE *filea = fopen(filename_a, "r");
+ FILE *fileb = fopen (filename_b, "wb");
+ int count = sizeof(buf);
+ while (count == sizeof(buf)) {
+ count = fread(buf, 1, sizeof(buf), filea);
+ fwrite(buf, 1, count, fileb);
+ }
+ fclose(filea);
+ fclose(fileb);
+
+}
+
int
image_buf_diff (char *buf_a, int width_a, int height_a, int stride_a,
const char *filename_a,
@@ -104,6 +120,12 @@
unsigned char *buf_b, *buf_diff;
read_png_status_t status;
+ if (cache_compare(filename_b, buf_a, height_a * stride_a)) {
+ copy_file(filename_b, filename_a);
+ xunlink (filename_diff);
+ return 0;
+ }
+
status = read_png_argb32 (filename_b, &buf_b, &width_b, &height_b, &stride_b);
if (status) {
// write out the buffer on failure
@@ -140,16 +162,7 @@
write_png_argb32 (buf_a, png_file, width_a, height_a, stride_a);
fclose (png_file);
} else {
- char buf[4096];
- FILE *ref_file = fopen(filename_b, "r");
- FILE *png_file = fopen (filename_a, "wb");
- int count = sizeof(buf);
- while (count == sizeof(buf)) {
- count = fread(buf, 1, sizeof(buf), ref_file);
- fwrite(buf, 1, count, png_file);
- }
- fclose(ref_file);
- fclose(png_file);
+ copy_file(filename_b, filename_a);
xunlink (filename_diff);
}
More information about the poppler
mailing list