summaryrefslogtreecommitdiff
path: root/dmagick/ImageView.d
blob: 5cad8375d235c64fdb1ab440ef6f664df39285ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
module dmagick.ImageView;

import std.array;

import dmagick.Color;
import dmagick.Exception;
import dmagick.Geometry;
import dmagick.Image;

import dmagick.c.cache;
import dmagick.c.geometry;
import dmagick.c.pixel;

class ImageView
{
	Image image;
	RectangleInfo extent;

	this(Image image, Geometry area)
	{
		if ( area.width + area.xOffset > image.columns ||
			area.height + area.yOffset > image.rows )
		{
			throw new OptionException("Specified area is larger than the image");
		}

		this.image = image;
		this.extent = area.rectangleInfo;
	}

	Row opIndex(size_t row)
	{
		PixelPacket* pixels = 
			GetAuthenticPixels(image.imageRef, extent.x, extent.y, 1, extent.width, DMagickExceptionInfo());

		return Row(image, pixels[0 .. extent.width]);
	}

	ImageView opSlice()
	{
		return opSlice(0, extent.height);
	}

	ImageView opSlice(size_t upper, size_t lower)
	{
		RectangleInfo newExtent = extent;

		newExtent.y += upper;
		newExtent.height = lower - upper;

		return new Rows(image, Geometry(newExtent));
	}

	int opApply(int delegate(ref Row) dg)
	{
		//Use UpdateImageViewIterator ?
	}
}

class Rows : ImageView
{
	this(Image image, Geometry area)
	{
		super(image, area);
	}

	override Row opIndex(size_t column)
	{
		PixelPacket* pixels = 
			GetAuthenticPixels(image.imageRef, extent.x, extent.y, extent.height, 1, DMagickExceptionInfo());

		return Row(image, pixels[0 .. extent.width]);
	}

	override ImageView opSlice()
	{
		return opSlice(0, extent.width);
	}

	override ImageView opSlice(size_t left, size_t right)
	{
		RectangleInfo newExtent = extent;

		newExtent.x += left;
		newExtent.width = right - left;

		return new ImageView(image, Geometry(newExtent));
	}
}

struct Row
{
	Image image;
	PixelPacket[] pixels;
	
	this(Image image, PixelPacket[] pixels)
	{
		this.image = image;
		this.pixels = pixels;
	}

	~this()
	{
		SyncAuthenticPixels(image.imageRef, DMagickExceptionInfo());
	}

	Color opIndex(size_t pixel)
	{
		return new Color(&(pixels[pixel]));
	}

	void opIndexAssign(Color color, size_t i)
	{
		pixels[i] = color.pixelPacket;
	}

	Row opSlice()
	{
		return this;
	}

	Row opSilce(size_t left, size_t right)
	{
		return Row(image, pixels[left .. right]);
	}

	void opSliceAssign(Color color)
	{
		opSliceAssign(color, 0, pixels.length);
	}

	void opSliceAssign(Color color, size_t left, size_t right)
	{
		foreach( i; left .. right )
			this[i] = color;
	}

	@property bool empty()
	{
		return pixels.empty;
	}

	Color front()
	{
		return this[0];
	}

	void popFront()
	{
		pixels.popFront();
	}
}