From 7a9174cc012e93fb0a4d15ef3dcf64f3695b829e Mon Sep 17 00:00:00 2001 From: Mike Wey Date: Sun, 7 Aug 2011 18:50:40 +0200 Subject: Document the ImageView. --- dmagick/ImageView.d | 182 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 169 insertions(+), 13 deletions(-) (limited to 'dmagick/ImageView.d') 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; } } + -- cgit v1.2.3