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