|
Packit Service |
df60bb |
#include <config.h>
|
|
Packit Service |
df60bb |
#include <assert.h>
|
|
Packit Service |
df60bb |
#include <setjmp.h>
|
|
Packit Service |
df60bb |
#include <stdlib.h>
|
|
Packit Service |
df60bb |
#include <stdio.h>
|
|
Packit Service |
df60bb |
#include <string.h>
|
|
Packit Service |
df60bb |
#include <math.h>
|
|
Packit Service |
df60bb |
#include <limits.h>
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef HAVE_DIRENT_H
|
|
Packit Service |
df60bb |
#include <dirent.h>
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
#ifdef HAVE_UNISTD_H
|
|
Packit Service |
df60bb |
#include <unistd.h>
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
#ifdef HAVE_SYS_STAT_H
|
|
Packit Service |
df60bb |
#include <sys/stat.h>
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
#ifdef HAVE_SYS_TYPES_H
|
|
Packit Service |
df60bb |
#include <sys/types.h>
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
# include "readdir.h"
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#include "gd.h"
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#include "gdtest.h"
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* max is already defined in windows/msvc */
|
|
Packit Service |
df60bb |
#ifndef max
|
|
Packit Service |
df60bb |
static inline int max(int a, int b) {return a > b ? a : b;}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
void gdSilence(int priority, const char *format, va_list args)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
(void)priority;
|
|
Packit Service |
df60bb |
(void)format;
|
|
Packit Service |
df60bb |
(void)args;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef HAVE_LIBPNG
|
|
Packit Service |
df60bb |
gdImagePtr gdTestImageFromPng(const char *filename)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
gdImagePtr image;
|
|
Packit Service |
df60bb |
FILE *fp;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* If the path is relative, then assume it's in the tests/ dir. */
|
|
Packit Service |
df60bb |
if (filename[0] == '/' || filename[0] == '.'
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
|| filename[1] == ':'
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
) {
|
|
Packit Service |
df60bb |
fp = fopen(filename, "rb");
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
fp = gdTestFileOpen(filename);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (fp == NULL) {
|
|
Packit Service |
df60bb |
return NULL;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
image = gdImageCreateFromPng(fp);
|
|
Packit Service |
df60bb |
fclose(fp);
|
|
Packit Service |
df60bb |
return image;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
static char *tmpdir_base;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* This is kind of hacky, but it's meant to be simple. */
|
|
Packit Service |
df60bb |
static void _clean_dir(const char *dir)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
DIR *d;
|
|
Packit Service |
df60bb |
struct dirent *de;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
d = opendir(dir);
|
|
Packit Service |
df60bb |
if (d == NULL)
|
|
Packit Service |
df60bb |
return;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (chdir(dir) != 0)
|
|
Packit Service |
df60bb |
goto done;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
while ((de = readdir(d)) != NULL) {
|
|
Packit Service |
df60bb |
struct stat st;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
|
|
Packit Service |
df60bb |
continue;
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
WIN32_FILE_ATTRIBUTE_DATA data;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (!GetFileAttributesEx(de->d_name, GetFileExInfoStandard, &data)) {
|
|
Packit Service |
df60bb |
continue;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
Packit Service |
df60bb |
_clean_dir(de->d_name);
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
unlink(de->d_name);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#else
|
|
Packit Service |
df60bb |
if (lstat(de->d_name, &st) != 0)
|
|
Packit Service |
df60bb |
continue;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (S_ISDIR(st.st_mode))
|
|
Packit Service |
df60bb |
_clean_dir(de->d_name);
|
|
Packit Service |
df60bb |
else
|
|
Packit Service |
df60bb |
unlink(de->d_name);
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (chdir("..")) {
|
|
Packit Service |
df60bb |
/* Ignore. */;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
done:
|
|
Packit Service |
df60bb |
closedir(d);
|
|
Packit Service |
df60bb |
rmdir(dir);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
static void tmpdir_cleanup(void)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
_clean_dir(tmpdir_base);
|
|
Packit Service |
df60bb |
free(tmpdir_base);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
char* strrstr (char* haystack, char* needle)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
int needle_length = strlen(needle);
|
|
Packit Service |
df60bb |
char * haystack_end = haystack + strlen(haystack) - needle_length;
|
|
Packit Service |
df60bb |
char * p;
|
|
Packit Service |
df60bb |
int i;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
for(p = haystack_end; p >= haystack; --p)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
for(i = 0; i < needle_length; ++i) {
|
|
Packit Service |
df60bb |
if(p[i] != needle[i])
|
|
Packit Service |
df60bb |
goto next;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
return p;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
next:;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
static MyGetSystemTimeAsFileTime get_time_func(void)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
MyGetSystemTimeAsFileTime timefunc = NULL;
|
|
Packit Service |
df60bb |
HMODULE hMod = GetModuleHandle("kernel32.dll");
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (hMod) {
|
|
Packit Service |
df60bb |
/* Max possible resolution <1us, win8/server2012 */
|
|
Packit Service |
df60bb |
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if(!timefunc) {
|
|
Packit Service |
df60bb |
/* 100ns blocks since 01-Jan-1641 */
|
|
Packit Service |
df60bb |
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return timefunc;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
static MyGetSystemTimeAsFileTime timefunc = NULL;
|
|
Packit Service |
df60bb |
static int getfilesystemtime(struct timeval *tv)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
FILETIME ft;
|
|
Packit Service |
df60bb |
unsigned __int64 ff = 0;
|
|
Packit Service |
df60bb |
ULARGE_INTEGER fft;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (timefunc == NULL) {
|
|
Packit Service |
df60bb |
timefunc = get_time_func();
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
timefunc(&ft;;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/*
|
|
Packit Service |
df60bb |
* Do not cast a pointer to a FILETIME structure to either a
|
|
Packit Service |
df60bb |
* ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
|
|
Packit Service |
df60bb |
* via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
|
|
Packit Service |
df60bb |
*/
|
|
Packit Service |
df60bb |
fft.HighPart = ft.dwHighDateTime;
|
|
Packit Service |
df60bb |
fft.LowPart = ft.dwLowDateTime;
|
|
Packit Service |
df60bb |
ff = fft.QuadPart;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
ff /= 10Ui64; /* convert to microseconds */
|
|
Packit Service |
df60bb |
ff -= 11644473600000000Ui64; /* convert to unix epoch */
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
tv->tv_sec = (long)(ff / 1000000Ui64);
|
|
Packit Service |
df60bb |
tv->tv_usec = (long)(ff % 1000000Ui64);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
static char *
|
|
Packit Service |
df60bb |
mkdtemp (char *tmpl)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
Packit Service |
df60bb |
static const int NLETTERS = sizeof (letters) - 1;
|
|
Packit Service |
df60bb |
static int counter = 0;
|
|
Packit Service |
df60bb |
char *XXXXXX;
|
|
Packit Service |
df60bb |
struct timeval tv;
|
|
Packit Service |
df60bb |
_int64 value;
|
|
Packit Service |
df60bb |
int count;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* find the last occurrence of "XXXXXX" */
|
|
Packit Service |
df60bb |
XXXXXX = strrstr(tmpl, "XXXXXX");
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) {
|
|
Packit Service |
df60bb |
errno = EINVAL;
|
|
Packit Service |
df60bb |
return NULL;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Get some more or less random data. */
|
|
Packit Service |
df60bb |
getfilesystemtime(&tv;;
|
|
Packit Service |
df60bb |
value = (tv.tv_usec ^ tv.tv_sec) + counter++;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
for (count = 0; count < 100; value += 7777, ++count) {
|
|
Packit Service |
df60bb |
_int64 v = value;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Fill in the random bits. */
|
|
Packit Service |
df60bb |
XXXXXX[0] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
v /= NLETTERS;
|
|
Packit Service |
df60bb |
XXXXXX[1] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
v /= NLETTERS;
|
|
Packit Service |
df60bb |
XXXXXX[2] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
v /= NLETTERS;
|
|
Packit Service |
df60bb |
XXXXXX[3] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
v /= NLETTERS;
|
|
Packit Service |
df60bb |
XXXXXX[4] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
v /= NLETTERS;
|
|
Packit Service |
df60bb |
XXXXXX[5] = letters[v % NLETTERS];
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* tmpl is in UTF-8 on Windows, thus use g_mkdir() */
|
|
Packit Service |
df60bb |
if (mkdir(tmpl) == 0) {
|
|
Packit Service |
df60bb |
return tmpl;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
printf("failed to create directory\n");
|
|
Packit Service |
df60bb |
if (errno != EEXIST)
|
|
Packit Service |
df60bb |
/* Any other error will apply also to other names we might
|
|
Packit Service |
df60bb |
* try, and there are 2^32 or so of them, so give up now.
|
|
Packit Service |
df60bb |
*/
|
|
Packit Service |
df60bb |
return NULL;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* We got out of the loop because we ran out of combinations to try. */
|
|
Packit Service |
df60bb |
errno = EEXIST;
|
|
Packit Service |
df60bb |
return NULL;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
const char *gdTestTempDir(void)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
if (tmpdir_base == NULL) {
|
|
Packit Service |
df60bb |
char *tmpdir;
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
char tmpdir_root[MAX_PATH];
|
|
Packit Service |
df60bb |
size_t tmpdir_root_len = GetTempPath(MAX_PATH, tmpdir_root);
|
|
Packit Service |
df60bb |
gdTestAssert(!(tmpdir_root_len > MAX_PATH || (tmpdir_root_len == 0)));
|
|
Packit Service |
df60bb |
gdTestAssert((tmpdir_root_len + 30 < MAX_PATH));
|
|
Packit Service |
df60bb |
#else
|
|
Packit Service |
df60bb |
char *tmpdir_root;
|
|
Packit Service |
df60bb |
tmpdir_root = getenv("TMPDIR");
|
|
Packit Service |
df60bb |
if (tmpdir_root == NULL)
|
|
Packit Service |
df60bb |
tmpdir_root = "/tmp";
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* The constant here is a lazy over-estimate. */
|
|
Packit Service |
df60bb |
tmpdir = malloc(strlen(tmpdir_root) + 30);
|
|
Packit Service |
df60bb |
gdTestAssert(tmpdir != NULL);
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
sprintf(tmpdir, "%sgdtest.XXXXXX", tmpdir_root);
|
|
Packit Service |
df60bb |
#else
|
|
Packit Service |
df60bb |
sprintf(tmpdir, "%s/gdtest.XXXXXX", tmpdir_root);
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
tmpdir_base = mkdtemp(tmpdir);
|
|
Packit Service |
df60bb |
gdTestAssert(tmpdir_base != NULL);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
atexit(tmpdir_cleanup);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return tmpdir_base;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
char *gdTestTempFile(const char *template)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
const char *tempdir = gdTestTempDir();
|
|
Packit Service |
df60bb |
char *ret;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
char *tmpfilename;
|
|
Packit Service |
df60bb |
UINT error;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
ret = malloc(MAX_PATH);
|
|
Packit Service |
df60bb |
gdTestAssert(ret != NULL);
|
|
Packit Service |
df60bb |
if (template == NULL) {
|
|
Packit Service |
df60bb |
error = GetTempFileName(tempdir,
|
|
Packit Service |
df60bb |
"gdtest",
|
|
Packit Service |
df60bb |
0,
|
|
Packit Service |
df60bb |
ret);
|
|
Packit Service |
df60bb |
gdTestAssert(error != 0);
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
sprintf(ret, "%s\\%s", tempdir, template);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#else
|
|
Packit Service |
df60bb |
if (template == NULL) {
|
|
Packit Service |
df60bb |
template = "gdtemp.XXXXXX";
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
ret = malloc(strlen(tempdir) + 10 + strlen(template));
|
|
Packit Service |
df60bb |
gdTestAssert(ret != NULL);
|
|
Packit Service |
df60bb |
sprintf(ret, "%s/%s", tempdir, template);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (strstr(template, "XXXXXX") != NULL) {
|
|
Packit Service |
df60bb |
int fd = mkstemp(ret);
|
|
Packit Service |
df60bb |
gdTestAssert(fd != -1);
|
|
Packit Service |
df60bb |
close(fd);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
return ret;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
FILE *gdTestTempFp(void)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
char *file = gdTestTempFile(NULL);
|
|
Packit Service |
df60bb |
FILE *fp = fopen(file, "wb");
|
|
Packit Service |
df60bb |
gdTestAssert(fp != NULL);
|
|
Packit Service |
df60bb |
free(file);
|
|
Packit Service |
df60bb |
return fp;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
char *gdTestFilePathV(const char *path, va_list args)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
size_t len;
|
|
Packit Service |
df60bb |
const char *p;
|
|
Packit Service |
df60bb |
char *file;
|
|
Packit Service |
df60bb |
va_list args_len;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Figure out how much space we need. */
|
|
Packit Service |
df60bb |
va_copy(args_len, args);
|
|
Packit Service |
df60bb |
len = strlen(GDTEST_TOP_DIR) + 1;
|
|
Packit Service |
df60bb |
p = path;
|
|
Packit Service |
df60bb |
do {
|
|
Packit Service |
df60bb |
len += strlen(p) + 1;
|
|
Packit Service |
df60bb |
} while ((p = va_arg(args_len, const char *)) != NULL);
|
|
Packit Service |
df60bb |
va_end(args_len);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Now build the path. */
|
|
Packit Service |
df60bb |
file = malloc(len);
|
|
Packit Service |
df60bb |
gdTestAssert(file != NULL);
|
|
Packit Service |
df60bb |
strcpy(file, GDTEST_TOP_DIR);
|
|
Packit Service |
df60bb |
p = path;
|
|
Packit Service |
df60bb |
do {
|
|
Packit Service |
df60bb |
#ifdef _WIN32
|
|
Packit Service |
df60bb |
strcat(file, "\\");
|
|
Packit Service |
df60bb |
#else
|
|
Packit Service |
df60bb |
strcat(file, "/");
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
strcat(file, p);
|
|
Packit Service |
df60bb |
} while ((p = va_arg(args, const char *)) != NULL);
|
|
Packit Service |
df60bb |
va_end(args);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return file;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
char *gdTestFilePathX(const char *path, ...)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
va_list args;
|
|
Packit Service |
df60bb |
va_start(args, path);
|
|
Packit Service |
df60bb |
return gdTestFilePathV(path, args);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
FILE *gdTestFileOpenX(const char *path, ...)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
va_list args;
|
|
Packit Service |
df60bb |
FILE *fp;
|
|
Packit Service |
df60bb |
char *file;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
va_start(args, path);
|
|
Packit Service |
df60bb |
file = gdTestFilePathV(path, args);
|
|
Packit Service |
df60bb |
fp = fopen(file, "rb");
|
|
Packit Service |
df60bb |
gdTestAssert(fp != NULL);
|
|
Packit Service |
df60bb |
free(file);
|
|
Packit Service |
df60bb |
return fp;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Compare two buffers, returning the number of pixels that are
|
|
Packit Service |
df60bb |
* different and the maximum difference of any single color channel in
|
|
Packit Service |
df60bb |
* result_ret.
|
|
Packit Service |
df60bb |
*
|
|
Packit Service |
df60bb |
* This function should be rewritten to compare all formats supported by
|
|
Packit Service |
df60bb |
* cairo_format_t instead of taking a mask as a parameter.
|
|
Packit Service |
df60bb |
*/
|
|
Packit Service |
df60bb |
void gdTestImageDiff(gdImagePtr buf_a, gdImagePtr buf_b,
|
|
Packit Service |
df60bb |
gdImagePtr buf_diff, CuTestImageResult *result_ret)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
int x, y;
|
|
Packit Service |
df60bb |
int c1, c2;
|
|
Packit Service |
df60bb |
# define UP_DIFF(var) result_ret->max_diff = max((var), result_ret->max_diff)
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
for (y = 0; y < gdImageSY(buf_a); y++) {
|
|
Packit Service |
df60bb |
for (x = 0; x < gdImageSX(buf_a); x++) {
|
|
Packit Service |
df60bb |
c1 = gdImageGetTrueColorPixel(buf_a, x, y);
|
|
Packit Service |
df60bb |
c2 = gdImageGetTrueColorPixel(buf_b, x, y);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* check if the pixels are the same */
|
|
Packit Service |
df60bb |
if (c1 != c2) {
|
|
Packit Service |
df60bb |
int r1,b1,g1,a1,r2,b2,g2,a2;
|
|
Packit Service |
df60bb |
unsigned int diff_a,diff_r,diff_g,diff_b;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
a1 = gdTrueColorGetAlpha(c1);
|
|
Packit Service |
df60bb |
a2 = gdTrueColorGetAlpha(c2);
|
|
Packit Service |
df60bb |
diff_a = abs (a1 - a2);
|
|
Packit Service |
df60bb |
diff_a *= 4; /* emphasize */
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (diff_a) {
|
|
Packit Service |
df60bb |
diff_a += 128; /* make sure it's visible */
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
if (diff_a > gdAlphaMax) {
|
|
Packit Service |
df60bb |
diff_a = gdAlphaMax/2;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
r1 = gdTrueColorGetRed(c1);
|
|
Packit Service |
df60bb |
r2 = gdTrueColorGetRed(c2);
|
|
Packit Service |
df60bb |
diff_r = abs (r1 - r2);
|
|
Packit Service |
df60bb |
// diff_r *= 4; /* emphasize */
|
|
Packit Service |
df60bb |
if (diff_r) {
|
|
Packit Service |
df60bb |
diff_r += gdRedMax/2; /* make sure it's visible */
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
if (diff_r > 255) {
|
|
Packit Service |
df60bb |
diff_r = 255;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
UP_DIFF(diff_r);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
g1 = gdTrueColorGetGreen(c1);
|
|
Packit Service |
df60bb |
g2 = gdTrueColorGetGreen(c2);
|
|
Packit Service |
df60bb |
diff_g = abs (g1 - g2);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
diff_g *= 4; /* emphasize */
|
|
Packit Service |
df60bb |
if (diff_g) {
|
|
Packit Service |
df60bb |
diff_g += gdGreenMax/2; /* make sure it's visible */
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
if (diff_g > 255) {
|
|
Packit Service |
df60bb |
diff_g = 255;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
UP_DIFF(diff_g);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
b1 = gdTrueColorGetBlue(c1);
|
|
Packit Service |
df60bb |
b2 = gdTrueColorGetBlue(c2);
|
|
Packit Service |
df60bb |
diff_b = abs (b1 - b2);
|
|
Packit Service |
df60bb |
diff_b *= 4; /* emphasize */
|
|
Packit Service |
df60bb |
if (diff_b) {
|
|
Packit Service |
df60bb |
diff_b += gdBlueMax/2; /* make sure it's visible */
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
if (diff_b > 255) {
|
|
Packit Service |
df60bb |
diff_b = 255;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
UP_DIFF(diff_b);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
result_ret->pixels_changed++;
|
|
Packit Service |
df60bb |
if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(diff_r, diff_g, diff_b, diff_a));
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(255,255,255,0));
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
# undef UP_DIFF
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Return the largest difference between two corresponding pixels and
|
|
Packit Service |
df60bb |
* channels. */
|
|
Packit Service |
df60bb |
unsigned int gdMaxPixelDiff(gdImagePtr a, gdImagePtr b)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
int diff = 0;
|
|
Packit Service |
df60bb |
int x, y;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (a == NULL || b == NULL || a->sx != b->sx || a->sy != b->sy)
|
|
Packit Service |
df60bb |
return UINT_MAX;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
for (x = 0; x < a->sx; x++) {
|
|
Packit Service |
df60bb |
for (y = 0; y < a->sy; y++) {
|
|
Packit Service |
df60bb |
int c1, c2;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
c1 = gdImageGetTrueColorPixel(a, x, y);
|
|
Packit Service |
df60bb |
c2 = gdImageGetTrueColorPixel(b, x, y);
|
|
Packit Service |
df60bb |
if (c1 == c2) continue;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
diff = max(diff, abs(gdTrueColorGetAlpha(c1) - gdTrueColorGetAlpha(c2)));
|
|
Packit Service |
df60bb |
diff = max(diff, abs(gdTrueColorGetRed(c1) - gdTrueColorGetRed(c2)));
|
|
Packit Service |
df60bb |
diff = max(diff, abs(gdTrueColorGetGreen(c1) - gdTrueColorGetGreen(c2)));
|
|
Packit Service |
df60bb |
diff = max(diff, abs(gdTrueColorGetBlue(c1) - gdTrueColorGetBlue(c2)));
|
|
Packit Service |
df60bb |
}/* for */
|
|
Packit Service |
df60bb |
}/* for */
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return diff;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef HAVE_LIBPNG
|
|
Packit Service |
df60bb |
int gdTestImageCompareToImage(const char* file, unsigned int line, const char* message,
|
|
Packit Service |
df60bb |
gdImagePtr expected, gdImagePtr actual)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
unsigned int width_a, height_a;
|
|
Packit Service |
df60bb |
unsigned int width_b, height_b;
|
|
Packit Service |
df60bb |
gdImagePtr surface_diff = NULL;
|
|
Packit Service |
df60bb |
CuTestImageResult result = {0, 0};
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
(void)message;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (!actual) {
|
|
Packit Service |
df60bb |
_gdTestErrorMsg(file, line, "Image is NULL\n");
|
|
Packit Service |
df60bb |
goto fail;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
width_a = gdImageSX(expected);
|
|
Packit Service |
df60bb |
height_a = gdImageSY(expected);
|
|
Packit Service |
df60bb |
width_b = gdImageSX(actual);
|
|
Packit Service |
df60bb |
height_b = gdImageSY(actual);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (width_a != width_b || height_a != height_b) {
|
|
Packit Service |
df60bb |
_gdTestErrorMsg(file, line,
|
|
Packit Service |
df60bb |
"Image size mismatch: (%ux%u) vs. (%ux%u)\n for %s vs. buffer\n",
|
|
Packit Service |
df60bb |
width_a, height_a,
|
|
Packit Service |
df60bb |
width_b, height_b,
|
|
Packit Service |
df60bb |
file);
|
|
Packit Service |
df60bb |
goto fail;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
surface_diff = gdImageCreateTrueColor(width_a, height_a);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
gdTestImageDiff(expected, actual, surface_diff, &result);
|
|
Packit Service |
df60bb |
if (result.pixels_changed>0) {
|
|
Packit Service |
df60bb |
char file_diff[255];
|
|
Packit Service |
df60bb |
char file_out[1024];
|
|
Packit Service |
df60bb |
FILE *fp;
|
|
Packit Service |
df60bb |
int len, p;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
_gdTestErrorMsg(file, line,
|
|
Packit Service |
df60bb |
"Total pixels changed: %d with a maximum channel difference of %d.\n",
|
|
Packit Service |
df60bb |
result.pixels_changed,
|
|
Packit Service |
df60bb |
result.max_diff
|
|
Packit Service |
df60bb |
);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
p = len = strlen(file);
|
|
Packit Service |
df60bb |
p--;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
/* Use only the filename (and store it in the bld dir not the src dir
|
|
Packit Service |
df60bb |
*/
|
|
Packit Service |
df60bb |
while(p > 0 && (file[p] != '/' && file[p] != '\\')) {
|
|
Packit Service |
df60bb |
p--;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
sprintf(file_diff, "%s_%u_diff.png", file + p + 1, line);
|
|
Packit Service |
df60bb |
sprintf(file_out, "%s_%u_out.png", file + p + 1, line);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fp = fopen(file_diff, "wb");
|
|
Packit Service |
df60bb |
if (!fp) goto fail;
|
|
Packit Service |
df60bb |
gdImagePng(surface_diff,fp);
|
|
Packit Service |
df60bb |
fclose(fp);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fp = fopen(file_out, "wb");
|
|
Packit Service |
df60bb |
if (!fp) goto fail;
|
|
Packit Service |
df60bb |
gdImagePng(actual, fp);
|
|
Packit Service |
df60bb |
fclose(fp);
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
if (surface_diff) {
|
|
Packit Service |
df60bb |
gdImageDestroy(surface_diff);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
return 1;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fail:
|
|
Packit Service |
df60bb |
if (surface_diff) {
|
|
Packit Service |
df60bb |
gdImageDestroy(surface_diff);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
return 1;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
#ifdef HAVE_LIBPNG
|
|
Packit Service |
df60bb |
int gdTestImageCompareToFile(const char* file, unsigned int line, const char* message,
|
|
Packit Service |
df60bb |
const char *expected_file, gdImagePtr actual)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
gdImagePtr expected = 0;
|
|
Packit Service |
df60bb |
int res = 1;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
expected = gdTestImageFromPng(expected_file);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (!expected) {
|
|
Packit Service |
df60bb |
_gdTestErrorMsg(file, line, "Cannot open PNG <%s>\n", expected_file);
|
|
Packit Service |
df60bb |
res = 0;
|
|
Packit Service |
df60bb |
} else {
|
|
Packit Service |
df60bb |
res = gdTestImageCompareToImage(file, line, message, expected, actual);
|
|
Packit Service |
df60bb |
gdImageDestroy(expected);
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
return res;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
#endif
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
static int failureCount = 0;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
int gdNumFailures() {
|
|
Packit Service |
df60bb |
return failureCount;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
int _gdTestAssert(const char* file, unsigned int line, int condition)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
if (condition) return 1;
|
|
Packit Service |
df60bb |
_gdTestErrorMsg(file, line, "Assert failed in <%s:%i>\n", file, line);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
++failureCount;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
int _gdTestAssertMsg(const char* file, unsigned int line, int condition, const char* message, ...)
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
va_list args;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
if (condition) return 1;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fprintf(stderr, "%s:%u: ", file, line);
|
|
Packit Service |
df60bb |
va_start(args, message);
|
|
Packit Service |
df60bb |
vfprintf(stderr, message, args);
|
|
Packit Service |
df60bb |
va_end(args);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fflush(stderr);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
++failureCount;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
int _gdTestErrorMsg(const char* file, unsigned int line, const char* format, ...) /* {{{ */
|
|
Packit Service |
df60bb |
{
|
|
Packit Service |
df60bb |
va_list args;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
fprintf(stderr, "%s:%u: ", file, line);
|
|
Packit Service |
df60bb |
va_start(args, format);
|
|
Packit Service |
df60bb |
vfprintf(stderr, format, args);
|
|
Packit Service |
df60bb |
va_end(args);
|
|
Packit Service |
df60bb |
fflush(stderr);
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
++failureCount;
|
|
Packit Service |
df60bb |
|
|
Packit Service |
df60bb |
return 0;
|
|
Packit Service |
df60bb |
}
|
|
Packit Service |
df60bb |
/* }}} */
|