blob: b59906022ac772c3ee7d571dc11154aec191869d [file] [log] [blame]
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// A simple bench harness for skcms_Transform(), mostly to run in a profiler.
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "skcms.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define expect(cond) if (!(cond)) exit(1)
static void load_file(const char* filename, void** buf, size_t* len) {
FILE* fp = fopen(filename, "rb");
expect(fp);
expect(fseek(fp, 0L, SEEK_END) == 0);
long size = ftell(fp);
expect(size > 0);
*len = (size_t)size;
rewind(fp);
*buf = malloc(*len);
expect(*buf);
size_t bytes_read = fread(*buf, 1, *len, fp);
expect(bytes_read == *len);
}
// Just to keep us on our toes, we transform a non-power-of-two number of pixels.
#define NPIXELS 255
static float src_pixels[NPIXELS * 4],
dst_pixels[NPIXELS * 4];
int main(int argc, char** argv) {
bool running_under_profiler = false;
const char* XPC_SERVICE_NAME = getenv("XPC_SERVICE_NAME");
if (XPC_SERVICE_NAME && NULL != strstr(XPC_SERVICE_NAME, "Instruments")) {
running_under_profiler = true;
}
int loops = argc > 1 ? atoi(argv[1]) : 100000;
void *src_buf, *dst_buf;
size_t src_len, dst_len;
load_file(argc > 2 ? argv[2] : "profiles/mobile/sRGB_parametric.icc", &src_buf, &src_len);
load_file(argc > 3 ? argv[3] : "profiles/mobile/Display_P3_parametric.icc", &dst_buf, &dst_len);
skcms_ICCProfile src_profile, dst_profile;
if (!skcms_Parse(src_buf, src_len, &src_profile) ||
!skcms_Parse(dst_buf, dst_len, &dst_profile)) {
return 1;
}
// We'll rotate through pixel formats to get samples from all the various stages.
skcms_PixelFormat src_fmt = skcms_PixelFormat_RGB_565,
dst_fmt = skcms_PixelFormat_RGB_565;
const int wrap = skcms_PixelFormat_BGRA_ffff+1;
clock_t start = clock();
for (int i = 0; running_under_profiler || i < loops; i++) {
(void)skcms_Transform(src_pixels, src_fmt, &src_profile,
dst_pixels, dst_fmt, &dst_profile,
NPIXELS);
src_fmt = (src_fmt + 3) % wrap;
dst_fmt = (dst_fmt + 7) % wrap;
}
clock_t ticks = clock() - start;
printf("%d loops in %g ticks, %.3g ns / pixel\n",
loops, (double)ticks, (double)ticks / (CLOCKS_PER_SEC * 1e-9) / (loops * NPIXELS));
free(src_buf);
free(dst_buf);
return 0;
}