Blame tests/test_modifier_color.cpp

Packit 1f396d
#include <glib.h>
Packit 1f396d
Packit 1f396d
#include <clocale>
Packit 1f396d
#include <vector>
Packit 1f396d
#include <string>
Packit 1f396d
#include <map>
Packit 1f396d
#include <limits>
Packit 1f396d
Packit 1f396d
#include <cstdlib>
Packit 1f396d
#include <cstdio>
Packit 1f396d
#include <cmath>
Packit 1f396d
Packit 1f396d
#include "lensfun.h"
Packit 1f396d
Packit 1f396d
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
Packit 1f396d
#include <malloc.h>
Packit 1f396d
#endif
Packit 1f396d
#ifdef __APPLE__
Packit 1f396d
#include <sys/malloc.h>
Packit 1f396d
#endif
Packit 1f396d
Packit 1f396d
#include "common_code.hpp"
Packit 1f396d
Packit 1f396d
//TODO: find better place for cTypeToLfPixelFormat()
Packit 1f396d
template<typename T>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_U8;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat<unsigned char>()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_U8;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat<unsigned short>()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_U16;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat<unsigned int>()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_U32;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat<float>()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_F32;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
lfPixelFormat cTypeToLfPixelFormat<double>()
Packit 1f396d
{
Packit 1f396d
  return LF_PF_F64;
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
typedef struct
Packit 1f396d
{
Packit 1f396d
  void       *image;
Packit 1f396d
  size_t      img_width, img_height;
Packit 1f396d
  lfLens     *lens;
Packit 1f396d
  lfModifier *mod;
Packit 1f396d
} lfFixture;
Packit 1f396d
Packit 1f396d
typedef struct
Packit 1f396d
{
Packit 1f396d
  bool    reverse;
Packit 1f396d
  size_t  cpp;
Packit 1f396d
  gchar  *pixDesc;
Packit 1f396d
  int     comp_role;
Packit 1f396d
  size_t  alignment;
Packit 1f396d
} lfTestParams;
Packit 1f396d
Packit 1f396d
template<typename T>
Packit 1f396d
void generateImage(lfFixture *lfFix, lfTestParams *p, T *pixels)
Packit 1f396d
{
Packit 1f396d
  T halfmax = std::numeric_limits<T>::max() / T(2);
Packit 1f396d
  for(size_t i = 0; i < p->cpp * lfFix->img_width * lfFix->img_height; i++)
Packit 1f396d
    pixels[i] = halfmax;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
void generateImage<float>(lfFixture *lfFix, lfTestParams *p, float *pixels)
Packit 1f396d
{
Packit 1f396d
  for(size_t i = 0; i < p->cpp * lfFix->img_width * lfFix->img_height; i++)
Packit 1f396d
    pixels[i] = 0.5f;
Packit 1f396d
}
Packit 1f396d
template<>
Packit 1f396d
void generateImage<double>(lfFixture *lfFix, lfTestParams *p, double *pixels)
Packit 1f396d
{
Packit 1f396d
  for(size_t i = 0; i < p->cpp * lfFix->img_width * lfFix->img_height; i++)
Packit 1f396d
    pixels[i] = 0.5;
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
// setup a standard lens
Packit 1f396d
template<typename T>
Packit 1f396d
void mod_setup(lfFixture *lfFix, gconstpointer data)
Packit 1f396d
{
Packit 1f396d
  lfTestParams *p = (lfTestParams *)data;
Packit 1f396d
Packit 1f396d
  lfFix->lens             = new lfLens();
Packit 1f396d
  lfFix->lens->CropFactor = 1.0f;
Packit 1f396d
  lfFix->lens->Type       = LF_RECTILINEAR;
Packit 1f396d
Packit 1f396d
  // Canon EOS 5D Mark III + Canon EF 24-70mm f/2.8L II USM
Packit 1f396d
  lfLensCalibVignetting lensCalibVign = {LF_VIGNETTING_MODEL_PA, 24.0f, 2.8f, 1000.0f, { -0.5334f, -0.7926f, 0.5243f}};
Packit 1f396d
  lfFix->lens->AddCalibVignetting(&lensCalibVign);
Packit 1f396d
Packit 1f396d
  lfFix->img_height = 300;
Packit 1f396d
  lfFix->img_width  = 300;
Packit 1f396d
Packit Service 6d11ed
  lfFix->mod = new lfModifier(lfFix->lens, 1.0f, lfFix->img_width, lfFix->img_height);
Packit 1f396d
Packit 1f396d
  lfFix->mod->Initialize(
Packit 1f396d
    lfFix->lens, cTypeToLfPixelFormat<T>(),
Packit 1f396d
    24.0f, 2.8f, 1000.0f, 1.0f, LF_RECTILINEAR,
Packit 1f396d
    LF_MODIFY_VIGNETTING, p->reverse);
Packit 1f396d
Packit 1f396d
  lfFix->image = NULL;
Packit 1f396d
Packit 1f396d
  const size_t bufsize = p->cpp * lfFix->img_width * lfFix->img_height * sizeof(T);
Packit 1f396d
  if(p->alignment == 0)
Packit 1f396d
    lfFix->image = g_malloc(bufsize);
Packit 1f396d
  else
Packit 1f396d
    lfFix->image = lf_alloc_align(p->alignment, bufsize);
Packit 1f396d
Packit 1f396d
  generateImage<T>(lfFix, p, (T *)lfFix->image);
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
void mod_teardown(lfFixture *lfFix, gconstpointer data)
Packit 1f396d
{
Packit 1f396d
  lfTestParams *p = (lfTestParams *)data;
Packit 1f396d
Packit 1f396d
  if(p->alignment == 0)
Packit 1f396d
    g_free(lfFix->image);
Packit 1f396d
  else
Packit 1f396d
    lf_free_align(lfFix->image);
Packit 1f396d
Packit Service 6d11ed
  delete lfFix->mod;
Packit 1f396d
  delete lfFix->lens;
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
template<typename T>
Packit 1f396d
void test_mod_color(lfFixture *lfFix, gconstpointer data)
Packit 1f396d
{
Packit 1f396d
  lfTestParams *p = (lfTestParams *)data;
Packit 1f396d
Packit 1f396d
  for(size_t y = 0; y < lfFix->img_height; y++)
Packit 1f396d
  {
Packit 1f396d
    T *imgdata = (T *)lfFix->image + (size_t)p->cpp * y * lfFix->img_width;
Packit 1f396d
Packit 1f396d
    g_assert_true(
Packit 1f396d
      lfFix->mod->ApplyColorModification(
Packit 1f396d
        imgdata, 0.0, y, lfFix->img_width, 1,
Packit 1f396d
        p->comp_role, p->cpp * lfFix->img_width));
Packit 1f396d
  }
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
#ifdef _OPENMP
Packit 1f396d
template<typename T>
Packit 1f396d
void test_mod_color_parallel(lfFixture *lfFix, gconstpointer data)
Packit 1f396d
{
Packit 1f396d
  const lfTestParams *const p = (lfTestParams *)data;
Packit 1f396d
Packit 1f396d
  #pragma omp parallel for schedule(static)
Packit 1f396d
  for(size_t y = 0; y < lfFix->img_height; y++)
Packit 1f396d
  {
Packit 1f396d
    T *imgdata = (T *)lfFix->image + (size_t)p->cpp * y * lfFix->img_width;
Packit 1f396d
Packit 1f396d
    g_assert_true(
Packit 1f396d
      lfFix->mod->ApplyColorModification(
Packit 1f396d
        imgdata, 0.0, y, lfFix->img_width, 1,
Packit 1f396d
        p->comp_role, p->cpp * lfFix->img_width));
Packit 1f396d
  }
Packit 1f396d
}
Packit 1f396d
#endif
Packit 1f396d
Packit 1f396d
gchar *describe(lfTestParams *p, const char *prefix, const char *f)
Packit 1f396d
{
Packit 1f396d
  gchar alignment[32] = "";
Packit 1f396d
  g_snprintf(alignment, sizeof(alignment), "%lu-byte", p->alignment);
Packit 1f396d
Packit 1f396d
  return g_strdup_printf(
Packit 1f396d
           "/%s/%s/%s/%s/%s",
Packit 1f396d
           prefix,
Packit 1f396d
           p->reverse ? "Vignetting" : "DeVignetting",
Packit 1f396d
           p->pixDesc,
Packit 1f396d
           f,
Packit 1f396d
           p->alignment == 0 ? "unaligned" : alignment
Packit 1f396d
         );
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
template<typename T>
Packit 1f396d
void add_set_item(lfTestParams *p, const char *f)
Packit 1f396d
{
Packit 1f396d
  gchar *desc = NULL;
Packit 1f396d
Packit 1f396d
  desc = describe(p, "modifier/color/serialFor", f);
Packit 1f396d
  g_test_add(desc, lfFixture, p, mod_setup<T>, test_mod_color<T>, mod_teardown);
Packit 1f396d
  g_free(desc);
Packit 1f396d
  desc = NULL;
Packit 1f396d
Packit 1f396d
#ifdef _OPENMP
Packit 1f396d
  desc = describe(p, "modifier/color/parallelFor", f);
Packit 1f396d
  g_test_add(desc, lfFixture, p, mod_setup<T>, test_mod_color_parallel<T>, mod_teardown);
Packit 1f396d
  g_free(desc);
Packit 1f396d
  desc = NULL;
Packit 1f396d
#endif
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
void add_sets(lfTestParams *p)
Packit 1f396d
{
Packit 1f396d
  add_set_item<unsigned char>(p, "lf_u8");
Packit 1f396d
  add_set_item<unsigned short>(p, "lf_u16");
Packit 1f396d
  add_set_item<unsigned int>(p, "lf_u32");
Packit 1f396d
  add_set_item<float>(p, "lf_f32");
Packit 1f396d
  add_set_item<double>(p, "lf_f64");
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
void free_params(gpointer mem)
Packit 1f396d
{
Packit 1f396d
  lfTestParams *p = (lfTestParams *)mem;
Packit 1f396d
Packit 1f396d
  g_free(p->pixDesc);
Packit 1f396d
  g_free(mem);
Packit 1f396d
}
Packit 1f396d
Packit 1f396d
int main(int argc, char **argv)
Packit 1f396d
{
Packit 1f396d
  setlocale(LC_ALL, "");
Packit 1f396d
Packit 1f396d
  g_test_init(&argc, &argv, NULL);
Packit 1f396d
Packit 1f396d
  GSList *slist = NULL;
Packit 1f396d
Packit 1f396d
  std::vector<bool> reverse;
Packit 1f396d
  reverse.push_back(false);
Packit 1f396d
  reverse.push_back(true);
Packit 1f396d
Packit 1f396d
  for(std::vector<bool>::iterator it_reverse = reverse.begin(); it_reverse != reverse.end(); ++it_reverse)
Packit 1f396d
  {
Packit 1f396d
    std::map<std::string, int> pixDesc;
Packit 1f396d
    pixDesc["RGB"]  = LF_CR_3(RED, GREEN, BLUE);
Packit 1f396d
    pixDesc["RGBA"] = LF_CR_4(RED, GREEN, BLUE, UNKNOWN);
Packit 1f396d
    pixDesc["ARGB"] = LF_CR_4(UNKNOWN, RED, GREEN, BLUE);
Packit 1f396d
Packit 1f396d
    for(std::map<std::string, int>::iterator it_pixDesc = pixDesc.begin(); it_pixDesc != pixDesc.end(); ++it_pixDesc)
Packit 1f396d
    {
Packit 1f396d
      std::vector<size_t> align;
Packit 1f396d
      align.push_back(0);
Packit 1f396d
      align.push_back(4  * sizeof(float)); // SSE
Packit 1f396d
      //align.push_back(8  * sizeof(float)); // AVX
Packit 1f396d
      //align.push_back(16 * sizeof(float)); // AVX512
Packit 1f396d
Packit 1f396d
      for(std::vector<size_t>::iterator it_align = align.begin(); it_align != align.end(); ++it_align)
Packit 1f396d
      {
Packit 1f396d
        lfTestParams *p = (lfTestParams *)g_malloc(sizeof(lfTestParams));
Packit 1f396d
Packit 1f396d
        p->reverse   = *it_reverse;
Packit 1f396d
        p->cpp       = it_pixDesc->first.length();
Packit 1f396d
        p->pixDesc   = g_strdup(it_pixDesc->first.c_str());
Packit 1f396d
        p->comp_role = it_pixDesc->second;
Packit 1f396d
        p->alignment = *it_align;
Packit 1f396d
Packit 1f396d
        add_sets(p);
Packit 1f396d
Packit 1f396d
        slist = g_slist_append(slist, p);
Packit 1f396d
      }
Packit 1f396d
    }
Packit 1f396d
  }
Packit 1f396d
Packit 1f396d
  const int res = g_test_run();
Packit 1f396d
Packit 1f396d
  g_slist_free_full(slist, (GDestroyNotify)free_params);
Packit 1f396d
Packit 1f396d
  return res;
Packit 1f396d
}