Article: Functional image processing in D

2014-03-21 Thread Vladimir Panteleev

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.


Re: Article: Functional image processing in D

2014-03-21 Thread Andrea Fontana

Very interesting! Do you know http://www.antigrain.com/ ?

It is (was?) a very efficent c++ 2d library, heavily based on 
templates. Something like this in D with templates and lazy 
ranges should be impressive.



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.




Re: Article: Functional image processing in D

2014-03-21 Thread Rikki Cattermole
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.


Are you planning on adding a font rasterizer and can it work at 
CTFE?
If it does both I have some neat ideas for exporting of UML 
diagrams.


Re: Article: Functional image processing in D

2014-03-21 Thread Atila Neves

Wow, great stuff here. If anybody else asks me What is D good
for? again I'll point them to this.

Atila

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.


Re: Article: Functional image processing in D

2014-03-21 Thread Vladimir Panteleev

On Friday, 21 March 2014 at 12:27:57 UTC, Rikki Cattermole 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.


Are you planning on adding a font rasterizer


Parsing vector font files is a big undertaking. I'd likely use a 
text rendering library, such as FreeType. Hardcoding a small 
bitmap font for ASCII only is also a possibility.



and can it work at CTFE?


This program almost works:

string drawSmiley()
{
import std.range;
import std.math;

import ae.utils.graphics.draw;
import ae.utils.graphics.image;

auto smiley = Image!char(20, 20);
smiley.fill(' ');
smiley.fillCircle(10, 10, 10, '#');
smiley.fillCircle( 6, 6, 2, ' ');
smiley.fillCircle(14, 6, 2, ' ');
smiley.fillSector(10, 10, 6, 8, 0, PI, ' ');

	return smiley.h.iota.map!(y = 
smiley.scanline(y)).join(\n).idup;

}

pragma(msg, drawSmiley);

almost because fillSector calls atan2, which doesn't work in 
CTFE. :(


(And yeah, I totally did just declare an image with a colorspace 
of char.)


Re: Article: Functional image processing in D

2014-03-21 Thread bearophile

Vladimir Panteleev:


http://blog.thecybershadow.net/2014/03/21/functional-image-processing-in-d/


It looks nice. I suggest to not pack too much the code of the 
examples, so I suggest to put spaces around operators, etc.


It can be useful to add some benchmarks to compare its 
performance to equivalent regular foreach-based processing code 
in C/D.


Bye,
bearophile


Re: Article: Functional image processing in D

2014-03-21 Thread Meta
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 awesome. When I see examples of some of the amazing stuff 
you can do with D, I wonder if D is the new Lisp. Hugely 
under-appreciated and immensely powerful. Now if we can just 
correct the former...


Re: Article: Functional image processing in D

2014-03-21 Thread bearophile

Andrei Alexandrescu:


http://www.reddit.com/r/programming/comments/2101ti/functional_image_processing_in_d/


But I have suggested some improvements of the article :-(

Bye,
bearophile


Re: 1st draft of complete class-based std.random successor

2014-03-21 Thread ponce
On Thursday, 20 March 2014 at 21:17:33 UTC, Joseph Rushton 
Wakeling wrote:

On Thursday, 20 March 2014 at 08:30:09 UTC, ponce wrote:
Related: please consider using parts of SimpleRNG the 
excellent work of John D. Cook which provides many random 
distributions in a compact and documented way.


https://github.com/p0nce/gfm/blob/master/math/gfm/math/simplerng.d 
(here a port)


Good call, I'll take a close look at that.  Can you provide me 
with a link to the original project too?  (Yes, I can just 
Google it, I'm being lazy:-)


http://www.johndcook.com/SimpleRNG.h
http://www.johndcook.com/SimpleRNG.cpp

You will find that there is no license information.
But the author intended this as public domain, he will confirm if 
send an e-mail.


Re: Article: Functional image processing in D

2014-03-21 Thread Jakob Ovrum
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.


 * Any type is accepted for the colour type, even though certain 
basic assumptions are made, such as the colour type being 
assignable to itself.


 * Image.w/h/pixels should probably be read-only properties in 
the public interface.


 * Any particular reason that coordinate integers are signed? 
`isView` seems to prefer `size_t`.


 * `Warp` should probably have a `if (isView!V)` constraint.

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

 * 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.


 * The most common style for template parameter names (Phobos 
uses it, too) is just `Color`, not `COLOR`.


 * I know w and h are common abbreviations used in C, but 
they seem unnecessary in D - detrimental rather - if your code 
examples are anything to go by.


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.


Re: 1st draft of complete class-based std.random successor

2014-03-21 Thread Andrea Fontana

On Friday, 21 March 2014 at 16:01:28 UTC, ponce wrote:
On Thursday, 20 March 2014 at 21:17:33 UTC, Joseph Rushton 
Wakeling wrote:

On Thursday, 20 March 2014 at 08:30:09 UTC, ponce wrote:
Related: please consider using parts of SimpleRNG the 
excellent work of John D. Cook which provides many random 
distributions in a compact and documented way.


https://github.com/p0nce/gfm/blob/master/math/gfm/math/simplerng.d 
(here a port)


Good call, I'll take a close look at that.  Can you provide me 
with a link to the original project too?  (Yes, I can just 
Google it, I'm being lazy:-)


http://www.johndcook.com/SimpleRNG.h
http://www.johndcook.com/SimpleRNG.cpp

You will find that there is no license information.
But the author intended this as public domain, he will confirm 
if send an e-mail.


Hey he uses MWC algorithm! (but not the improved CMWC)



Re: Article: Functional image processing in D

2014-03-21 Thread Justin Whear
On Fri, 21 Mar 2014 11:04:57 +, 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.

Good writeup.  Excellent job linking to the Phobos docs and other 
articles.  I can see people clicking through to Voldemort Types, etc., 
making your article a gateway to the world of interesting things that D 
has to offer.


Re: Article: Functional image processing in D

2014-03-21 Thread Vladimir Panteleev

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.


Re: Article: Functional image processing in D

2014-03-21 Thread Jakob Ovrum
On Friday, 21 March 2014 at 17:03:17 UTC, Vladimir Panteleev 
wrote:
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.


Right, I only skimmed over the various aliases. It looks like 
only `parallel` does not use such an alias in the article, but as 
a higher order algorithm it's perfectly justified to use the 
separated style, especially when all the other higher order 
algorithms do it.


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.


What happens if negative values sneak into the code? Sounds 
dangerous.


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.


Bleh, I hope we can figure out some notion of lambda equality 
soon; string lambdas are terrible in so many ways.


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.


Referring to the overload sets with the `target` parameter?

(Looking at the source I also noticed some `isInputRange` checks 
are missing; `ElementType` only checks for a `front` property.)


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?


Aye, to be a sane hierarchy it would need to be redesigned so 
there are no circular dependencies, which does look rather 
non-trivial.


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).


Maybe parallelized blitting makes sense, though it would really 
require a use case where blit speed is a bottleneck to matter in 
the first place.


Re: Article: Functional image processing in D

2014-03-21 Thread Vladimir Panteleev

On Friday, 21 March 2014 at 17:24:02 UTC, Jakob Ovrum wrote:
What happens if negative values sneak into the code? Sounds 
dangerous.


Well, working with unsigned values correctly complicates the code 
by a good deal, for one. For example, if you want to draw a 
circle at (x,y) with radius r, then the first column of the 
bounding box is max(x-r,0). If you use unsigned coordinates, you 
have to write x-min(r,x) instead, which is a lot less intuitive. 
Not to mention, that it makes sense to draw a circle with 
negative center coordinates (you'll only see the fragment with 
non-negative coordinates).


There's also tricky bits like if you ever need to subtract a 
value from another, divide the result, then add something back. 
With a signed type you can get the expected positive number, even 
if the number being divided was negative. With an unsigned type, 
the subtraction can cause an underflow, with the (unsigned) 
division interpreting the result with a very large positive 
number instead of a small negative one.


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.


Referring to the overload sets with the `target` parameter?


Yes.

(Looking at the source I also noticed some `isInputRange` 
checks are missing; `ElementType` only checks for a `front` 
property.)


Thanks.

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).


Maybe parallelized blitting makes sense, though it would really 
require a use case where blit speed is a bottleneck to matter 
in the first place.


I agree, I think in most cases it makes sense to parallelize on a 
higher level.


Searching the web for parallel memcpy seems to confirm my 
suspicion that it's not practical, at least not for conventional 
CPUs.


Re: Article: Functional image processing in D

2014-03-21 Thread ponce

On Friday, 21 March 2014 at 18:40:10 UTC, ponce 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.


One more remarks:

Have you considered infinite View which, much like infinite 
InputRanges would lack lacking the w and h property?


It would allow:
   - infinite procedural()
   - support different border-modes when sampling outside of 
the allowed rectangle (eg. mirror, repeat, clamp_to_edge like 
OpenGL does with textures). This could be done with a function 
taking a View and returning an infinite View from it.

   - probably other uses I don't think of


Erm, so much typos. Corrected.
---
One more remark:

Have you considered an infinite View which, much like infinite
InputRanges would lack the w and h properties?

It would allow:
   - infinite procedural() View
   - support for different border-modes when sampling outside of 
the

allowed rectangle (eg. mirror, repeat, clamp_to_edge like OpenGL
does with textures). This could be done with a function taking a
View and returning an infinite View from it.
   - probably other uses I don't think of.
---


Re: Article: Functional image processing in D

2014-03-21 Thread ponce
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.


One more remarks:

Have you considered infinite View which, much like infinite 
InputRanges would lack lacking the w and h property?


It would allow:
   - infinite procedural()
   - support different border-modes when sampling outside of the 
allowed rectangle (eg. mirror, repeat, clamp_to_edge like OpenGL 
does with textures). This could be done with a function taking a 
View and returning an infinite View from it.

   - probably other uses I don't think of


Re: Article: Functional image processing in D

2014-03-21 Thread Walter Bright

On 3/21/2014 4:04 AM, 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.


Very, very nice.


Re: 1st draft of complete class-based std.random successor

2014-03-21 Thread Joseph Rushton Wakeling

On Thursday, 20 March 2014 at 00:39:43 UTC, bearophile wrote:
It's the best chance to improve naming, so do not throw it away 
for nothing:

https://d.puremagic.com/issues/show_bug.cgi?id=9106


I think the following patch should fix that for you:
https://github.com/WebDrake/std.random2/commit/fb5429de77b3c1f7fe3968fd0bd92209c9021f31

I've also made shuffle composable as per your request.  Looks 
good? :-)


Re: 1st draft of complete class-based std.random successor

2014-03-21 Thread bearophile

Joseph Rushton Wakeling:


I think the following patch should fix that for you:
https://github.com/WebDrake/std.random2/commit/fb5429de77b3c1f7fe3968fd0bd92209c9021f31

I've also made shuffle composable as per your request.  Looks 
good? :-)


Seems good. Onward! :-)

Bye,
bearophile


Re: Article: Functional image processing in D

2014-03-21 Thread Rikki Cattermole
On Friday, 21 March 2014 at 13:54:25 UTC, Vladimir Panteleev 
wrote:
On Friday, 21 March 2014 at 12:27:57 UTC, Rikki Cattermole 
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.


Are you planning on adding a font rasterizer


Parsing vector font files is a big undertaking. I'd likely use 
a text rendering library, such as FreeType. Hardcoding a small 
bitmap font for ASCII only is also a possibility.


Yeah it is quite a big one. But it may be well worth it to have 
it generate code at CTFE per font. Would be more efficient 
probably.



and can it work at CTFE?


This program almost works:

string drawSmiley()
{
import std.range;
import std.math;

import ae.utils.graphics.draw;
import ae.utils.graphics.image;

auto smiley = Image!char(20, 20);
smiley.fill(' ');
smiley.fillCircle(10, 10, 10, '#');
smiley.fillCircle( 6, 6, 2, ' ');
smiley.fillCircle(14, 6, 2, ' ');
smiley.fillSector(10, 10, 6, 8, 0, PI, ' ');

	return smiley.h.iota.map!(y = 
smiley.scanline(y)).join(\n).idup;

}

pragma(msg, drawSmiley);

almost because fillSector calls atan2, which doesn't work in 
CTFE. :(


(And yeah, I totally did just declare an image with a


Yeah I've noticed that some of phobos wasn't really designed with 
CTFE in mind *grumbles*. Maybe one day I'll look into getting 
that sorted out.

colorspace of char.)




Re: Article: Functional image processing in D

2014-03-21 Thread Vladimir Panteleev

On Friday, 21 March 2014 at 18:40:10 UTC, ponce 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.


One more remarks:

Have you considered infinite View which, much like infinite 
InputRanges would lack lacking the w and h property?


It would allow:
   - infinite procedural()
   - support different border-modes when sampling outside of 
the allowed rectangle (eg. mirror, repeat, clamp_to_edge like 
OpenGL does with textures). This could be done with a function 
taking a View and returning an infinite View from it.

   - probably other uses I don't think of


I've thought about it. Ultimately you'll want to crop it at some 
point or another, so I think it makes sense if there were 
operations you'd want to do on an infinite view where cropping 
will get in the way.


The library has a tiling view, which is infinite in concept but 
currently in effect it immediately crops the infinite view it 
creates.


I would probably have to rename the isView template to 
isFiniteView, and many operations expect a finite view...