Example #1
0
TEST(FlatInput, UpdatedData) {
	const int width = 2;
	const int height = 4;

	float data[width * height] = {
		0.0, 1.0,
		0.5, 0.5,
		0.7, 0.2,
		1.0, 0.6,
	};
	float out_data[width * height];

	EffectChainTester tester(NULL, width, height);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
	expect_equal(data, out_data, width, height);

	data[6] = 0.3;
	input->invalidate_pixel_data();

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
	expect_equal(data, out_data, width, height);
}
Example #2
0
TEST(FlatInput, PBO) {
	const int width = 3;
	const int height = 2;

	float data[width * height] = {
		0.0, 1.0, 0.5,
		0.5, 0.5, 0.2,
	};
	float expected_data[4 * width * height] = {
		0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,  0.5, 0.5, 0.5, 1.0,
		0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,  0.2, 0.2, 0.2, 1.0,
	};
	float out_data[4 * width * height];

	GLuint pbo;
	glGenBuffers(1, &pbo);
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
	glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(float), data, GL_STREAM_DRAW);
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

	EffectChainTester tester(NULL, width, height);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
	input->set_pixel_data((float *)BUFFER_OFFSET(0), pbo);
	tester.get_chain()->add_input(input);

	tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
	expect_equal(expected_data, out_data, 4 * width, height);

	glDeleteBuffers(1, &pbo);
}
Example #3
0
TEST(PaddingEffectTest, WhiteBorderColor) {
	float data[2 * 2] = {
		1.0f, 0.5f,
		0.8f, 0.3f,
	};
	float expected_data[4 * 4] = {
		1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 0.5f, 1.0f,
		1.0f, 0.8f, 0.3f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f,
	};
	float out_data[4 * 4];

        EffectChainTester tester(NULL, 4, 4);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 4));
	CHECK(effect->set_int("height", 4));
	CHECK(effect->set_float("left", 1.0f));
	CHECK(effect->set_float("top", 1.0f));

	RGBATuple border_color(1.0f, 1.0f, 1.0f, 1.0f);
	CHECK(effect->set_vec4("border_color", (float *)&border_color));

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
	expect_equal(expected_data, out_data, 4, 4);
}
Example #4
0
TEST(FlatInput, Pitch) {
	const int pitch = 3;
	const int width = 2;
	const int height = 4;

	float data[pitch * height] = {
		0.0, 1.0, 999.0f,
		0.5, 0.5, 999.0f,
		0.7, 0.2, 999.0f,
		1.0, 0.6, 999.0f,
	};
	float expected_data[4 * width * height] = {
		0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,
		0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,
		0.7, 0.7, 0.7, 1.0,  0.2, 0.2, 0.2, 1.0,
		1.0, 1.0, 1.0, 1.0,  0.6, 0.6, 0.6, 1.0,
	};
	float out_data[4 * width * height];

	EffectChainTester tester(NULL, width, height);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
	input->set_pitch(pitch);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
	expect_equal(expected_data, out_data, 4 * width, height);
}
Example #5
0
TEST(PaddingEffectTest, BorderColorIsInLinearGamma) {
	float data[4 * 1] = {
		0.2f, 0.4f, 0.6f, 0.8f,
	};
	float expected_data[4 * 2] = {
		0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from data[].
		0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from the border color.
	};
	float out_data[4 * 2];

        EffectChainTester tester(NULL, 1, 2);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_RGBA_PREMULTIPLIED_ALPHA, GL_FLOAT, 1, 1);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 1));
	CHECK(effect->set_int("height", 2));
	CHECK(effect->set_float("left", 0.0f));
	CHECK(effect->set_float("top", 0.0f));

	RGBATuple border_color(0.2f, 0.4f, 0.6f, 0.8f);  // Same as the pixel in data[].
	CHECK(effect->set_vec4("border_color", (float *)&border_color));

	tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_601, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
	expect_equal(expected_data, out_data, 4, 2);
}
Example #6
0
TEST(PaddingEffectTest, BorderOffsetTopAndBottom) {
	float data[2 * 2] = {
		1.0f, 0.5f,
		0.8f, 0.3f,
	};
	float expected_data[4 * 4] = {
		0.0f, 0.000f, 0.000f, 0.0f,
		0.0f, 0.750f, 0.375f, 0.0f,
		0.0f, 0.800f, 0.300f, 0.0f,
		0.0f, 0.200f, 0.075f, 0.0f,  // Repeated pixels, 25% opacity.
	};
	float out_data[4 * 4];

        EffectChainTester tester(NULL, 4, 4);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 4));
	CHECK(effect->set_int("height", 4));
	CHECK(effect->set_float("left", 1.0f));
	CHECK(effect->set_float("top", 1.0f));
	CHECK(effect->set_float("border_offset_top", 0.25f));
	CHECK(effect->set_float("border_offset_bottom", 0.25f));

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
	expect_equal(expected_data, out_data, 4, 4);
}
Example #7
0
TEST(PaddingEffectTest, BorderOffsetLeftAndRight) {
	float data[3 * 2] = {
		1.0f, 0.5f, 0.6f,
		0.8f, 0.3f, 0.2f,
	};
	float expected_data[4 * 2] = {
		0.750f, 0.5f, 0.3f, 0.0f,
		0.600f, 0.3f, 0.1f, 0.0f
	};
	float out_data[4 * 2];

        EffectChainTester tester(NULL, 4, 2);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 3, 2);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 4));
	CHECK(effect->set_int("height", 2));
	CHECK(effect->set_float("left", 0.0f));
	CHECK(effect->set_float("top", 0.0f));
	CHECK(effect->set_float("border_offset_left", 0.25f));
	CHECK(effect->set_float("border_offset_right", -0.5f));

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
	expect_equal(expected_data, out_data, 4, 2);
}
Example #8
0
TEST(PaddingEffectTest, NonIntegerOffset) {
	float data[4 * 1] = {
		0.25f, 0.50f, 0.75f, 1.0f,
	};
	float expected_data[5 * 2] = {
		0.1875f, 0.4375f, 0.6875f, 0.9375f, 0.25f,
		0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
	};
	float out_data[5 * 2];

        EffectChainTester tester(NULL, 5, 2);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 4, 1);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 5));
	CHECK(effect->set_int("height", 2));
	CHECK(effect->set_float("left", 0.25f));
	CHECK(effect->set_float("top", 0.0f));

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
	expect_equal(expected_data, out_data, 5, 2);
}
Example #9
0
TEST(PaddingEffectTest, AlphaIsCorrectEvenWithNonLinearInputsAndOutputs) {
	float data[2 * 1] = {
		1.0f,
		0.8f,
	};
	float expected_data[4 * 4] = {
		1.0f, 1.0f, 1.0f, 0.5f,
		1.0f, 1.0f, 1.0f, 1.0f,
		0.8f, 0.8f, 0.8f, 1.0f,
		1.0f, 1.0f, 1.0f, 0.5f,
	};
	float out_data[4 * 4];

	EffectChainTester tester(NULL, 1, 4);

	ImageFormat format;
	format.color_space = COLORSPACE_REC_601_625;
	format.gamma_curve = GAMMA_REC_709;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 2);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 1));
	CHECK(effect->set_int("height", 4));
	CHECK(effect->set_float("left", 0.0f));
	CHECK(effect->set_float("top", 1.0f));

	RGBATuple border_color(1.0f, 1.0f, 1.0f, 0.5f);
	CHECK(effect->set_vec4("border_color", (float *)&border_color));

	tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_709, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
	expect_equal(expected_data, out_data, 4, 4);
}
Example #10
0
TEST(PaddingEffectTest, DifferentXAndYOffset) {
	float data[1 * 1] = {
		1.0f
	};
	float expected_data[3 * 3] = {
		0.0f, 0.0f, 0.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 0.0f,
	};
	float out_data[3 * 3];

        EffectChainTester tester(NULL, 3, 3);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 1);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
	CHECK(effect->set_int("width", 3));
	CHECK(effect->set_int("height", 3));
	CHECK(effect->set_float("left", 2.0f));
	CHECK(effect->set_float("top", 1.0f));

	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
	expect_equal(expected_data, out_data, 3, 3);
}
Example #11
0
void MltInput::set_pixel_data(const unsigned char* data)
{
	assert(input);
	if (isRGB) {
		FlatInput* flat = (FlatInput*) input;
		flat->set_pixel_data(data);
	} else {
		YCbCrInput* ycbcr = (YCbCrInput*) input;
		ycbcr->set_pixel_data(0, data);
		ycbcr->set_pixel_data(1, &data[m_width * m_height]);
		ycbcr->set_pixel_data(2, &data[m_width * m_height + (m_width / m_ycbcr_format.chroma_subsampling_x * m_height / m_ycbcr_format.chroma_subsampling_y)]);
	}
}
Example #12
0
TEST(FlatInput, ExternalTexture) {
	const int size = 5;

	float data[3 * size] = {
		0.0, 0.0, 0.0,
		0.5, 0.0, 0.0,
		0.0, 0.5, 0.0,
		0.0, 0.0, 0.7,
		0.0, 0.3, 0.7,
	};
	float expected_data[4 * size] = {
		0.0, 0.0, 0.0, 1.0,
		0.5, 0.0, 0.0, 1.0,
		0.0, 0.5, 0.0, 1.0,
		0.0, 0.0, 0.7, 1.0,
		0.0, 0.3, 0.7, 1.0,
	};
	float out_data[4 * size];

	EffectChainTester tester(NULL, 1, size, FORMAT_RGB, COLORSPACE_sRGB, GAMMA_LINEAR);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	ResourcePool pool;
	GLuint tex = pool.create_2d_texture(GL_RGB8, 1, size);
	check_error();
	glBindTexture(GL_TEXTURE_2D, tex);
	check_error();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	check_error();
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	check_error();
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, size, GL_RGB, GL_FLOAT, data);
	check_error();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	check_error();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	check_error();

	FlatInput *input = new FlatInput(format, FORMAT_RGB, GL_FLOAT, 1, size);
	input->set_texture_num(tex);
	tester.get_chain()->add_input(input);

	tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);

	pool.release_2d_texture(tex);

	expect_equal(expected_data, out_data, 4, size);
}
Example #13
0
TEST(ResampleEffectTest, DownscaleByTwoGetsCorrectPixelCenters) {
	const int size = 5;

	// This isn't a perfect dot, since the Lanczos filter has a slight
	// sharpening effect; the most important thing is that we have kept
	// the texel center right (everything is nicely symmetric).
	// The approximate magnitudes have been checked against ImageMagick.
	float expected_data[size * size] = {
		 0.0045, -0.0067, -0.0598, -0.0067,  0.0045, 
		-0.0067,  0.0099,  0.0886,  0.0099, -0.0067, 
		-0.0598,  0.0886,  0.7930,  0.0886, -0.0598, 
		-0.0067,  0.0099,  0.0886,  0.0099, -0.0067, 
		 0.0045, -0.0067, -0.0598, -0.0067,  0.0045, 
	};
	float data[size * size * 4], out_data[size * size];

	for (int y = 0; y < size * 2; ++y) {
		for (int x = 0; x < size * 2; ++x) {
			float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
			weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
			data[y * (size * 2) + x] = weight;
		}
	}

	EffectChainTester tester(NULL, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size * 2, size * 2);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
	ASSERT_TRUE(resample_effect->set_int("width", size));
	ASSERT_TRUE(resample_effect->set_int("height", size));
	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);

	expect_equal(expected_data, out_data, size, size);
}
Example #14
0
TEST(ResampleEffectTest, HeavyResampleGetsSumRight) {
	// Do only one resample pass, more specifically the last one, which goes to
	// our fp32 output. This allows us to analyze the precision without intermediate
	// fp16 rounding.
	const int swidth = 1, sheight = 1280;
	const int dwidth = 1, dheight = 64;

	float data[swidth * sheight], out_data[dwidth * dheight], expected_data[dwidth * dheight];
	for (int y = 0; y < sheight; ++y) {
		for (int x = 0; x < swidth; ++x) {
			data[y * swidth + x] = 1.0f;
		}
	}
	for (int y = 0; y < dheight; ++y) {
		for (int x = 0; x < dwidth; ++x) {
			expected_data[y * dwidth + x] = 1.0f;
		}
	}

	EffectChainTester tester(NULL, dwidth, dheight, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, GL_RGBA32F);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, swidth, sheight);
	input->set_pixel_data(data);

	tester.get_chain()->add_input(input);
	Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
	ASSERT_TRUE(resample_effect->set_int("width", dwidth));
	ASSERT_TRUE(resample_effect->set_int("height", dheight));
	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);

	// Require that we are within 10-bit accuracy. Note that this is for
	// one pass only; some cards that don't have correct fp32 -> fp16
	// rounding in the intermediate framebuffers will go outside this after
	// a 2D resize. This limit is tight enough that it will be good enough
	// for 8-bit accuracy, though.
	expect_equal(expected_data, out_data, dwidth, dheight, 0.5 / 1023.0);
}
Example #15
0
TEST(ResampleEffectTest, UpscaleByTwoGetsCorrectPixelCenters) {
	const int size = 5;

	float data[size * size] = {
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 1.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
	};
	float expected_data[size * size * 4], out_data[size * size * 4];

	for (int y = 0; y < size * 2; ++y) {
		for (int x = 0; x < size * 2; ++x) {
			float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
			weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
			expected_data[y * (size * 2) + x] = weight;
		}
	}

	EffectChainTester tester(NULL, size * 2, size * 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
	ASSERT_TRUE(resample_effect->set_int("width", size * 2));
	ASSERT_TRUE(resample_effect->set_int("height", size * 2));
	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);

	expect_equal(expected_data, out_data, size * 2, size * 2);
}
Example #16
0
TEST(ResampleEffectTest, UpscaleByThreeGetsCorrectPixelCenters) {
	const int size = 5;

	float data[size * size] = {
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 1.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
		0.0, 0.0, 0.0, 0.0, 0.0,
	};
	float out_data[size * size * 9];

	EffectChainTester tester(NULL, size * 3, size * 3, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);

	ImageFormat format;
	format.color_space = COLORSPACE_sRGB;
	format.gamma_curve = GAMMA_LINEAR;

	FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
	input->set_pixel_data(data);
	tester.get_chain()->add_input(input);

	Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
	ASSERT_TRUE(resample_effect->set_int("width", size * 3));
	ASSERT_TRUE(resample_effect->set_int("height", size * 3));
	tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);

	// We only bother checking that the middle pixel is still correct,
	// and that symmetry holds.
	EXPECT_FLOAT_EQ(1.0, out_data[7 * (size * 3) + 7]);
	for (unsigned y = 0; y < size * 3; ++y) {
		for (unsigned x = 0; x < size * 3; ++x) {
			EXPECT_FLOAT_EQ(out_data[y * (size * 3) + x], out_data[(size * 3 - y - 1) * (size * 3) + x]);
			EXPECT_FLOAT_EQ(out_data[y * (size * 3) + x], out_data[y * (size * 3) + (size * 3 - x - 1)]);
		}
	}
}