blob: 671a6d778a2f4ca105f034a0d75bef100e55ae04 [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 "skcms_internal.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) {
int n = 100000;
const char* src = NULL;
const char* dst = NULL;
for (int i = 0; i < argc; i++) {
if (0 == strcmp(argv[i], "-n")) { n = atoi(argv[++i]); }
if (0 == strcmp(argv[i], "-s")) { src = argv[++i] ; }
if (0 == strcmp(argv[i], "-d")) { dst = argv[++i] ; }
}
// Default to sRGB -> Display P3.
skcms_ICCProfile src_profile = *skcms_sRGB_profile(),
dst_profile = *skcms_sRGB_profile();
dst_profile.toXYZD50 = (skcms_Matrix3x3){{
{ 0.51512146f , 0.29197692f , 0.15710449f},
{ 0.24119567f , 0.6922454f , 0.0665741f },
{-0.0010375976f, 0.041885376f, 0.7840728f },
}};
void *src_buf = NULL,
*dst_buf = NULL;
size_t src_len,
dst_len;
if (src) {
load_file(src, &src_buf, &src_len);
if (!skcms_Parse(src_buf, src_len, &src_profile)) {
return 1;
}
}
if (dst) {
load_file(dst, &dst_buf, &dst_len);
if (!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;
uint32_t palette[256];
for (int i = 0; i < 256; i++) {
palette[i] = (uint32_t)(255 - i%256) * 0x01010101;
}
clock_t start = clock();
bool all_ok = true;
for (int i = 0; i < n; i++) {
const skcms_AlphaFormat upm = skcms_AlphaFormat_Unpremul;
all_ok &= skcms_TransformWithPalette(src_pixels, src_fmt, upm, &src_profile,
dst_pixels, dst_fmt, upm, &dst_profile,
NPIXELS, palette);
src_fmt = (src_fmt + 3) % wrap;
do {
dst_fmt = (dst_fmt + 7) % wrap;
} while (needs_palette(dst_fmt));
}
clock_t ticks = clock() - start;
printf("%d loops in %g clock ticks, %.3g ns / pixel\n",
n, (double)ticks, (double)ticks / (CLOCKS_PER_SEC * 1e-9) / (n * NPIXELS));
if (src_buf) { free(src_buf); }
if (dst_buf) { free(dst_buf); }
return all_ok ? 0 : 1;
}