summaryrefslogtreecommitdiff
path: root/dmagick
diff options
context:
space:
mode:
authorMike Wey2011-08-07 18:50:40 +0200
committerMike Wey2011-08-07 18:50:40 +0200
commit7a9174cc012e93fb0a4d15ef3dcf64f3695b829e (patch)
treec3a47e982b02cca9ac9356974da625ec56eea72c /dmagick
parentc7be75cbe983021f41f63a95ad07f422b6f34845 (diff)
Document the ImageView.
Diffstat (limited to 'dmagick')
-rw-r--r--dmagick/Image.d10
-rw-r--r--dmagick/ImageView.d182
2 files changed, 178 insertions, 14 deletions
diff --git a/dmagick/Image.d b/dmagick/Image.d
index 9a10364..7c422fc 100644
--- a/dmagick/Image.d
+++ b/dmagick/Image.d
@@ -2898,7 +2898,14 @@ class Image
imageRef = ImageRef(image);
}
- dmagick.ImageView.ImageView view(Geometry area)
+ /**
+ * Get a view into the image. The ImageView can be used to modify
+ * individual pixels of the image.
+ *
+ * Params:
+ * area = The area accessible through the view.
+ */
+ dmagick.ImageView.ImageView view(Geometry area = Geometry(cast(size_t)this.columns, cast(size_t)this.rows) )
{
return new dmagick.ImageView.ImageView(this, area);
}
@@ -4053,3 +4060,4 @@ version (Windows)
MagickCoreTerminus();
}
}
+
diff --git a/dmagick/ImageView.d b/dmagick/ImageView.d
index e5411a4..c5dcf1a 100644
--- a/dmagick/ImageView.d
+++ b/dmagick/ImageView.d
@@ -1,4 +1,10 @@
-module dmagick.ImageView;
+/**
+ * Copyright: Mike Wey 2011
+ * License: zlib (See accompanying LICENSE file)
+ * Authors: Mike Wey
+ */
+
+ module dmagick.ImageView;
import std.array;
import std.parallelism;
@@ -15,11 +21,43 @@ import dmagick.c.cache;
import dmagick.c.geometry;
import dmagick.c.pixel;
+/**
+ * The ImageView allows changing induvidual pixels with the slicing and
+ * indexing operators.
+ *
+ * --------------------
+ * ImageView view = image.view();
+ *
+ * //Assign a square.
+ * view[4..40][5..50] = new Color("red");
+ *
+ * //Reduce a view.
+ * view = view[10..view.extend.height-10][20..view.extend.width-20];
+ *
+ * //Assign a single row.
+ * view[30] = new Color("blue");
+ * //Or a column.
+ * view[][30] = new Color("blue");
+ * //And induvidual pixels.
+ * view[3][5] = new Color("green");
+ *
+ * //We can also use foreach.
+ * foreach ( row; view )
+ * {
+ * //This is executed in parallel.
+ * foreach ( ref pixel; row )
+ * pixel = new Color("black");
+ * }
+ * --------------------
+ */
class ImageView
{
Image image;
RectangleInfo extent;
+ /**
+ * Create a new view for image.
+ */
this(Image image, Geometry area)
{
if ( area.width + area.xOffset > image.columns ||
@@ -32,6 +70,36 @@ class ImageView
this.extent = area.rectangleInfo;
}
+ /**
+ * The width of the view.
+ */
+ @property size_t width() const
+ {
+ return extent.width;
+ }
+
+ /**
+ * The height of the view.
+ */
+ @property size_t height() const
+ {
+ return extent.height;
+ }
+
+ /**
+ * The height or the width of the view, depending on in which slice
+ * it's used.
+ *
+ * Bugs: dmd bug 3474: opDollar isn't implemented.
+ */
+ size_t opDollar() const
+ {
+ return extent.height;
+ }
+
+ /**
+ * Indexing operators yield or modify the value at a specified index.
+ */
Row opIndex(size_t row)
{
PixelPacket* pixels =
@@ -40,11 +108,21 @@ class ImageView
return Row(image, pixels[0 .. extent.width]);
}
+ ///ditto
+ void opIndexAssign(Color color, size_t index)
+ {
+ this[index][] = color;
+ }
+
+ /**
+ * Sliceing operators yield or modify the value in the specified slice.
+ */
ImageView opSlice()
{
return opSlice(0, extent.height);
}
+ ///ditto
ImageView opSlice(size_t upper, size_t lower)
{
RectangleInfo newExtent = extent;
@@ -55,6 +133,25 @@ class ImageView
return new Rows(image, Geometry(newExtent));
}
+ ///ditto
+ void opSliceAssign(Color color)
+ {
+ foreach ( row; this )
+ row[] = color;
+ }
+
+ ///ditto
+ void opSliceAssign(Color color, size_t upper, size_t lower)
+ {
+ foreach ( row; this[upper .. lower] )
+ row[] = color;
+ }
+
+ /**
+ * Support the usage of foreach to loop over the rows in the view.
+ * The foreach is executed in parallel.
+ */
+ //TODO: Should the foreach be parallel?
int opApply(int delegate(ref Row) dg)
{
shared(int) progress;
@@ -82,6 +179,11 @@ class ImageView
}
}
+
+/*
+ * A Rows object is returned when a ImageView is sliced, this is to support
+ * sliceing the columns with a sceond slice.
+ */
class Rows : ImageView
{
this(Image image, Geometry area)
@@ -89,6 +191,20 @@ class Rows : ImageView
super(image, area);
}
+ /*
+ * The height or the width of the view, depending on in which slice
+ * it's used.
+ *
+ * Bugs: dmd bug 3474: opDollar isn't implemented.
+ */
+ override size_t opDollar() const
+ {
+ return extent.width;
+ }
+
+ /*
+ * Indexing operators yield or modify the value at a specified index.
+ */
override Row opIndex(size_t column)
{
PixelPacket* pixels =
@@ -97,11 +213,15 @@ class Rows : ImageView
return Row(image, pixels[0 .. extent.width]);
}
+ /*
+ * Sliceing operators yield or modify the value in the specified slice.
+ */
override ImageView opSlice()
{
return opSlice(0, extent.width);
}
+ ///ditto
override ImageView opSlice(size_t left, size_t right)
{
RectangleInfo newExtent = extent;
@@ -113,6 +233,11 @@ class Rows : ImageView
}
}
+/**
+ * Row reprecents a singe row of pixels in an ImageView.
+ *
+ * Bugs: Only one row per thread is supported.
+ */
struct Row
{
Image image;
@@ -129,49 +254,80 @@ struct Row
SyncAuthenticPixels(image.imageRef, DMagickExceptionInfo());
}
+ /**
+ * The number of pixels in this row / column.
+ *
+ * Bugs: dmd bug 3474: opDollar isn't implemented.
+ */
+ @property size_t length() const
+ {
+ return pixels.length;
+ }
+
+ ///ditto
+ size_t opDollar() const
+ {
+ return pixels.length;
+ }
+
+ /**
+ * Indexing operators yield or modify the value at a specified index.
+ */
Color opIndex(size_t pixel)
{
return new Color(&(pixels[pixel]));
}
- void opIndexAssign(Color color, size_t i)
+ ///ditto
+ void opIndexAssign(Color color, size_t index)
{
- pixels[i] = color.pixelPacket;
+ pixels[index] = color.pixelPacket;
}
+ /**
+ * Sliceing operators yield or modify the value in the specified slice.
+ */
Row opSlice()
{
return this;
}
+ ///ditto
Row opSilce(size_t left, size_t right)
{
return Row(image, pixels[left .. right]);
}
+ ///ditto
void opSliceAssign(Color color)
{
opSliceAssign(color, 0, pixels.length);
}
+ ///ditto
void opSliceAssign(Color color, size_t left, size_t right)
{
foreach( i; left .. right )
this[i] = color;
}
- @property bool empty()
+ /**
+ * Support using foreach on a row.
+ */
+ int opApply(int delegate(ref Color) dg)
{
- return pixels.empty;
- }
+ foreach ( ref PixelPacket pixel; pixels )
+ {
+ Color color = new Color(pixel);
+ int result = dg(color);
- Color front()
- {
- return this[0];
- }
+ pixel = color.pixelPacket;
- void popFront()
- {
- pixels.popFront();
+ if ( result )
+ return result;
+ }
+
+ return 0;
}
}
+