summaryrefslogtreecommitdiff
path: root/dmagick/Array.d
blob: b80902b1c373132a7f7fb843fbee9d6b487333ee (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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
 * Copyright: Mike Wey 2011
 * License:   zlib (See accompanying LICENSE file)
 * Authors:   Mike Wey
 * 
 * This module contains functions that operate on a array or list of images.
 */

module dmagick.Array;

import dmagick.Exception;
import dmagick.Geometry;
import dmagick.Image;
import dmagick.Options;

import dmagick.c.blob;
import dmagick.c.constitute;
import dmagick.c.image : MagickCoreImage = Image;

/**
 * Read a multi frame Image by reading from the file or
 * URL specified by filename.
 */
Image[] readImages(string filename)
{
	Options options = new Options();
	options.filename = filename;

	return readImages(options);
}

///ditto
Image[] readImages(string filename, Geometry size)
{
	Options options = new Options();
	options.filename = filename;
	options.size = size;

	return readImages(options);
}

/**
 * Reads a multi frame Image from an in-memory blob.
 * The Blob size, depth and magick format may also be specified.
 *
 * Some image formats require size to be specified,
 * the default depth Imagemagick uses is the Quantum size
 * it's compiled with. If it doesn't match the depth of the image
 * it may need to be specified.
 *
 * Imagemagick can usualy detect the image format, when the
 * format can't be detected a magick format must be specified.
 */
Image[] readImages(void[] blob)
{
	return readImages(blob, new Options());
}

///ditto
Image[] readImages(void[] blob, Geometry size)
{
	Options options = new Options();
	options.size = size;

	return readImages(blob, options);
}

///ditto
Image[] readImages(void[] blob, Geometry size, size_t depth)
{
	Options options = new Options();
	options.size = size;
	options.depth = depth;

	return readImages(blob, options);
}

///ditto
Image[] readImages(void[] blob, Geometry size, size_t depth, string magick)
{
	Options options = new Options();
	options.size = size;
	options.depth = depth;
	options.magick = magick;
	//Also set the filename to the image format
	options.filename = magick ~":";

	return readImages(blob, options);
}

///ditto
Image[] readImages(void[] blob, Geometry size, string magick)
{
	Options options = new Options();
	options.size = size;
	options.magick = magick;
	//Also set the filename to the image format
	options.filename = magick ~":";

	return readImages(blob, options);
}

/**
 * Create an ImageMagick ImageList.
 */
private void linkImages(Image[] images)
{
	for ( int i = 0; i < images.length; i++ )
	{
		if ( i > 0 )
			images[i].imageRef.previous = images[i-1].imageRef;

		if ( i < images.length-1 )
			images[i].imageRef.next = images[i+1].imageRef;
	}
}

/**
 * Actual implementation for files.
 */
private Image[] readImages(Options options)
{
	Image[] images;

	MagickCoreImage* image = ReadImage(options.imageInfo, DMagickExceptionInfo());

	do
	{
		images ~= new Image(image);

		image = image.next;
	}
	while ( image !is null )

	return images;
}

/**
 * Actual implementation for blobs.
 */
private Image[] readImages(void[] blob, Options options)
{
	Image[] images;

	MagickCoreImage* image = 
		BlobToImage(options.imageInfo, blob.ptr, blob.length, DMagickExceptionInfo());

	do
	{
		images ~= new Image(image);

		image = image.next;
	}
	while ( image !is null )

	unlinkImages(images);

	return images;
}

/**
 * Destroy the ImageMagick ImageList.
 */
private void unlinkImages(Image[] images)
{
	foreach ( image; images )
	{
		image.imageRef.next = null;
		image.imageRef.previous = null;
	}
}