Article: Functional image processing in D

Vladimir Panteleev vladimir at thecybershadow.net
Fri Mar 21 10:03:15 PDT 2014


On Friday, 21 March 2014 at 16:21:18 UTC, Jakob Ovrum wrote:
> On Friday, 21 March 2014 at 11:04:58 UTC, Vladimir Panteleev 
> wrote:
>> http://blog.thecybershadow.net/2014/03/21/functional-image-processing-in-d/
>>
>> Some highlights from a recent overhaul of the graphics package 
>> from my D library. It makes use of a number of D-specific 
>> language features, so I've tried to make the article 
>> accessible to people new to D as well.
>
> That's really cool. I have some notes though:
>
>  * All the function templates separate the template declaration 
> from the function declaration, when they can just use the 
> function template syntax.

Where this is done, it is on purpose. For example, the "invert" 
declaration as it appears in the article wouldn't be possible 
with the shorthand function template syntax.

>  * Any particular reason that coordinate integers are signed?

Yes. I've tried using unsigned coordinates in the past. It was 
awful.

My conclusion is that if you ever need to subtract values, you 
should use signed types.

> `isView` seems to prefer `size_t`.

int implicitly casts to size_t but not the other way around.

>  * `warp` exclusively uses string expression arguments...

Yeah. A lambda would need to receive x, y, w and h, and we don't 
have naryFun in Phobos. (It's there but commented out for some 
reason.)

To a small extent, I made some compromises for the first 
iteration for the sake of code looking good for the article, and 
maybe with the help of feedback improve on that.

For example, a problem I've struggled with is avoiding having two 
overloads for almost every function in image.d. I've tried 
multiple approaches: default arguments (in the form of *new 
Image!COLOR), templates, string mixins, UDAs, pointers, but they 
all were rather ugly or impractical. Some related compiler issues 
are 8074, 12386, 12425 and 12426 - fixing those might make some 
of those approaches more feasible.

>  * I'd recommend sticking to structs (often with AliasThis) 
> over mixins for as far as it goes, as it's much more 
> structured, thus easier to read and reason with.

That doesn't work if you need two-way communication. Although you 
can pass outer methods as aliases to the inner struct, but then 
you have to use crazy tricks to make methods of the inner struct 
static in respect to the inner struct but bound to the outer one 
via the alias. I've played with this quite a bit for 
ae.utils.serialization, but I don't think it fits here. Unless 
I'm missing something?

> It's always nice to know examples of high performance 
> range-based code. I noticed that the `View` concept does not 
> have the concept of stride or access to pixels using a single 
> absolute coordinate; maybe if that was the case, the `blitTo` 
> algorithm could be optimized to its conclusion, instead of 
> copying scanlines one by one.

That's what my previous design used. But ultimately, unless 
you're dealing with very narrow images, I don't think there will 
be a noticeable difference in performance. This design is more 
flexible, though (e.g. vjoiner can serve scanlines from different 
sources).

Thanks for the feedback.


More information about the Digitalmars-d-announce mailing list