January 06, 2015
On Tuesday, 6 January 2015 at 14:28:52 UTC, Manu via Digitalmars-d wrote:
> I think an important facet of 'fast' image processing is in the loop
> that processes batches of pixels, rather than in the api that
> processes a single pixel.
> I've gone with accurate; that's the strategy throughout phobos.

Yeah, I agree. For fast on the CPU you want to use simd, and maybe one register for red, another for green, using saturating instructions, doing it differently on ARM vs x86 etc...

Besides, an accurate reference implementation is a good starting point and also very useful for unit testing a faster batch-oriented version later on.

> Here's a PR to see where I'm at:
> https://github.com/D-Programming-Language/phobos/pull/2845

Nice start. Most libraries use US-English "color", though. I guess phobos should try to be internally consistent (pick either UK or US vocabulary).
January 06, 2015
On 1/6/15 6:28 AM, Manu via Digitalmars-d wrote:
> I can't create look-up-tables at the moment, since '^^' doesn't work
> in CTFE! >_<

Assuming the exponent is integral, could you write a naive pow() function that works in ctfe? -- Andrei
January 06, 2015
On Tue, Jan 06, 2015 at 09:52:57AM -0800, Andrei Alexandrescu via Digitalmars-d wrote:
> On 1/6/15 6:28 AM, Manu via Digitalmars-d wrote:
> >I can't create look-up-tables at the moment, since '^^' doesn't work in CTFE! >_<
> 
> Assuming the exponent is integral, could you write a naive pow() function that works in ctfe? -- Andrei

I thought std.math already has an overload for pow() that works with
integral exponents?

In any case, a naïve CTFE implementation would be as simple as:

	T pow(T, U)(T t, U exp)
		if (isIntegral!U)
	{
		T result = 1;
		foreach (_; 0 .. abs(exp))
			result *= t;
		return (exp < 0) ? 1 / result : result;
	}

It's the non-integral exponents that require the currently-non-CTFE-able code, right?

In any case, pow() itself isn't the cause of non-CTFE-ability, since
Iain has so kindly provided "native" D implementations of pow() (and
most (all?) other standard math functions) in std.math; it's just that
floating-point primitives like isInfinite currently can't be CTFE'd
because they require access to the bit representation of the floats
which CTFE currently doesn't allow.

Implementing union painting in CTFE would singlehandedly solve (almost?) all of std.math CTFE issues, AFAICT.


T

-- 
Almost all proofs have bugs, but almost all theorems are true. -- Paul Pedersen
January 06, 2015
On Tuesday, 6 January 2015 at 18:09:19 UTC, H. S. Teoh via Digitalmars-d wrote:
> It's the non-integral exponents that require the currently-non-CTFE-able
> code, right?

http://en.wikipedia.org/wiki/Gamma_correction
January 06, 2015
On 1/6/2015 10:07 AM, H. S. Teoh via Digitalmars-d wrote:
> Implementing union painting in CTFE would singlehandedly solve (almost?)
> all of std.math CTFE issues, AFAICT.

I thought it did allow painting of the form *(cast(T*)&t).

January 06, 2015
On Tue, Jan 06, 2015 at 06:28:03PM +0000, via Digitalmars-d wrote:
> On Tuesday, 6 January 2015 at 18:09:19 UTC, H. S. Teoh via Digitalmars-d wrote:
> >It's the non-integral exponents that require the currently-non-CTFE-able code, right?
> 
> http://en.wikipedia.org/wiki/Gamma_correction

Right, integral exponents aren't the interesting (useful) case here.


T

-- 
Valentine's Day: an occasion for florists to reach into the wallets of nominal lovers in dire need of being reminded to profess their hypothetical love for their long-forgotten.
January 06, 2015
On Tue, Jan 06, 2015 at 10:44:38AM -0800, Walter Bright via Digitalmars-d wrote:
> On 1/6/2015 10:07 AM, H. S. Teoh via Digitalmars-d wrote:
> >Implementing union painting in CTFE would singlehandedly solve (almost?) all of std.math CTFE issues, AFAICT.
> 
> I thought it did allow painting of the form *(cast(T*)&t).

Was that a recent addition? I don't remember that working last year.

In any case, the current std.math code tries to achieve repainting via unions, which currently doesn't work in CTFE:

	ulong ctfeFunc(double d) {
		union U {
			double f;
			ulong  ul;
		}
		U u;
		u.f = d;
		return u.ul;	// <--- CTFE error
	}
	enum x = ctfeFunc(3.141592);


Maybe I remembered wrong, but the original std.math code relied on
*(cast(T*)&t) to work, but was rewritten to use union repainting, IIRC
because union painting is considered more likely to be implemented in
CTFE (? -- my guess; I could be wrong).

In any case, it's great news that repainting is now supported in CTFE. Hopefully this means more of std.math will be usable at compile-time soon!


T

-- 
"The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous
January 06, 2015
For inspiration:

http://golang.org/pkg/image/color/

January 07, 2015
On 7 January 2015 at 09:22, via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> For inspiration:
>
> http://golang.org/pkg/image/color/

Umm, is there something about this that you like? This looks... really terrible.
January 07, 2015
On 7 January 2015 at 00:28, Manu <turkeyman@gmail.com> wrote:
> On 6 January 2015 at 19:31, via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> On Tuesday, 6 January 2015 at 09:19:46 UTC, John Colvin wrote:
>>>
>>> What's wrong with old-fashioned `Fast` postfixes on entry points where a faster but less precise method is available? Or template arguments like std.algorithm.SortStrategy?
>>
>>
>> If this is for phobos it should follow a common model. But since a fast implementation might involve an object which builds a table before processing....
>>
>> Another problem is that "precise" is a very loose term if the conversion is for display or for composition in a shader. What you want depends on the kind of post processing that happens after this and how it affects the nonlinearities of human perception.
>
> I think an important facet of 'fast' image processing is in the loop
> that processes batches of pixels, rather than in the api that
> processes a single pixel.
> I've gone with accurate; that's the strategy throughout phobos.
>
> I can't create look-up-tables at the moment, since '^^' doesn't work in CTFE! >_<
>
> Here's a PR to see where I'm at: https://github.com/D-Programming-Language/phobos/pull/2845

I'd like to get some ideas from people what basic colour operations people would like/expect to see.

I'm also pondering which operators should be supported.
Do people think it makes any sense to support unary -? They're only
really useful in cases like normal maps, and don't make sense on
unsigned+normalised colour types.
What about unary ~? Bitwise not doesn't really have any meaning in
terms of colour, but it might make sense for the operator to calculate
the negative colour... although that kinda feels like operator abuse
to me.

What should happen when operators are applied to colours of differing colour space? I kinda feel like denying operators on colour space mismatch. It's not clear which format (left/right hand side) should be the preferred format for the operation/result...

I'm also questioning whether implicit assignment colour conversion should be allowed (and this kinda relates to restricting operators to like-types. Alternatively I can limit conversion to explicit cast operator or to!.

What about scalar operators, ie, to scale a colour? should the scalar argument be expected to match the datatype, or support float against all types for scaling? (slow! int->float->int conversion for a basic mul!)

What details have I missed?