magickwand 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +2 -0
- data/Rakefile +28 -0
- data/ext/magickwand/extconf.rb +81 -0
- data/ext/magickwand/gc.c +464 -0
- data/ext/magickwand/magickwand.c +152 -0
- data/ext/magickwand/magickwand.h +91 -0
- data/ext/magickwand/utility.c +819 -0
- data/ext/magickwand/wand.c +2296 -0
- data/lib/magickwand.rb +28 -0
- data/test/Button_0.gif +0 -0
- data/test/Button_1.gif +0 -0
- data/test/Button_2.gif +0 -0
- data/test/Button_3.gif +0 -0
- data/test/Button_4.gif +0 -0
- data/test/Button_5.gif +0 -0
- data/test/Button_6.gif +0 -0
- data/test/Button_7.gif +0 -0
- data/test/Button_8.gif +0 -0
- data/test/Button_9.gif +0 -0
- data/test/bridges.jpg +0 -0
- data/test/test_magickwand.rb +1100 -0
- metadata +78 -0
@@ -0,0 +1,152 @@
|
|
1
|
+
/*
|
2
|
+
* magickwand.c
|
3
|
+
* $Id: magickwand.c 146 2009-05-31 22:00:57Z rmagick $
|
4
|
+
* Copyright (C) 2009 Timothy Paul Hunter
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
#define MAIN 1
|
10
|
+
#include "magickwand.h"
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
/*
|
16
|
+
* Handle transferring ImageMagick memory allocations/frees to Ruby.
|
17
|
+
* These functions have the same signature as the equivalent C functions.
|
18
|
+
*/
|
19
|
+
static void *mwr_malloc(size_t size)
|
20
|
+
{
|
21
|
+
return xmalloc((long)size);
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
static void *mwr_realloc(void *ptr, size_t size)
|
28
|
+
{
|
29
|
+
return xrealloc(ptr, (long)size);
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
static void mwr_free(void *ptr)
|
36
|
+
{
|
37
|
+
xfree(ptr);
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
/*
|
44
|
+
* Copy MagickWand configure options to a constant hash
|
45
|
+
*/
|
46
|
+
static void ImageMagick_config(void)
|
47
|
+
{
|
48
|
+
volatile VALUE key, value;
|
49
|
+
volatile VALUE config_hash;
|
50
|
+
char **config;
|
51
|
+
char *option;
|
52
|
+
unsigned long n, n_config;
|
53
|
+
unsigned long qdepth, qrange;
|
54
|
+
|
55
|
+
config_hash = rb_hash_new();
|
56
|
+
|
57
|
+
config = MagickQueryConfigureOptions("*", &n_config);
|
58
|
+
for (n = 0; n < n_config; n++)
|
59
|
+
{
|
60
|
+
key = rb_str_new2(config[n]);
|
61
|
+
rb_obj_freeze(key);
|
62
|
+
option = MagickQueryConfigureOption(config[n]);
|
63
|
+
value = rb_str_new2(option);
|
64
|
+
rb_obj_freeze(value);
|
65
|
+
rb_hash_aset(config_hash, key, value);
|
66
|
+
}
|
67
|
+
|
68
|
+
rb_obj_freeze(config_hash);
|
69
|
+
rb_define_const(mwr_mMagickWand, "IMAGEMAGICK_CONFIG", config_hash);
|
70
|
+
|
71
|
+
(void) GetMagickQuantumDepth(&qdepth);
|
72
|
+
rb_define_const(mwr_mMagickWand, "QUANTUM_DEPTH", LONG2FIX((long)qdepth));
|
73
|
+
|
74
|
+
(void) GetMagickQuantumRange(&qrange);
|
75
|
+
rb_define_const(mwr_mMagickWand, "QUANTUM_RANGE", LONG2FIX((long)qrange));
|
76
|
+
|
77
|
+
rb_define_const(mwr_mMagickWand, "QUANTUM_SIZE", INT2FIX((int)sizeof(Quantum)));
|
78
|
+
|
79
|
+
}
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
static VALUE magickwand_list_fonts(VALUE mod)
|
85
|
+
{
|
86
|
+
unsigned long n, nfonts;
|
87
|
+
char **fonts;
|
88
|
+
volatile VALUE font_ary;
|
89
|
+
|
90
|
+
font_ary = rb_ary_new();
|
91
|
+
fonts = MagickQueryFonts("*", &nfonts);
|
92
|
+
for (n = 0; n < nfonts; n++)
|
93
|
+
{
|
94
|
+
rb_ary_push(font_ary, rb_str_new2(fonts[n]));
|
95
|
+
}
|
96
|
+
return font_ary;
|
97
|
+
mod = mod;
|
98
|
+
}
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
/*
|
104
|
+
* MagickWand.option_values(option-name)
|
105
|
+
* returns the valid values of the specified option, or all options
|
106
|
+
* if option-name is omitted. Values returned in a hash. The key
|
107
|
+
* is the option name and the value is an array of option values.
|
108
|
+
*/
|
109
|
+
static VALUE magickwand_option_values(int argc, VALUE *argv, VALUE mod)
|
110
|
+
{
|
111
|
+
volatile VALUE option;
|
112
|
+
char *name = NULL;
|
113
|
+
|
114
|
+
(void) rb_scan_args(argc, argv, "01", &option);
|
115
|
+
if (option != Qnil)
|
116
|
+
{
|
117
|
+
option = rb_String(option);
|
118
|
+
name = StringValuePtr(option);
|
119
|
+
}
|
120
|
+
return mwr_option_values_to_hash(name);
|
121
|
+
mod = mod;
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
/*
|
128
|
+
* Initialize the MagickWand environment. Create the MagickWand module.
|
129
|
+
*/
|
130
|
+
void Init_magickwand(void)
|
131
|
+
{
|
132
|
+
volatile VALUE version;
|
133
|
+
|
134
|
+
MagickWandGenesis();
|
135
|
+
SetMagickMemoryMethods(mwr_malloc, mwr_realloc, mwr_free);
|
136
|
+
|
137
|
+
mwr_mMagickWand = rb_define_module("MagickWand");
|
138
|
+
|
139
|
+
version = rb_str_new2(MAGICKWAND_VERSION);
|
140
|
+
rb_obj_freeze(version);
|
141
|
+
rb_define_const(mwr_mMagickWand, "VERSION", version);
|
142
|
+
rb_define_module_function(mwr_mMagickWand, "list_fonts", magickwand_list_fonts, 0);
|
143
|
+
rb_define_module_function(mwr_mMagickWand, "option_values", magickwand_option_values, -1);
|
144
|
+
|
145
|
+
ImageMagick_config();
|
146
|
+
|
147
|
+
mwr_init_Wand();
|
148
|
+
mwr_init_GC();
|
149
|
+
mwr_init_ImageMagickError();
|
150
|
+
mwr_init_FatalImageMagickError();
|
151
|
+
|
152
|
+
}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
/*
|
2
|
+
* magickwand.h
|
3
|
+
* $Id: magickwand.h 25 2009-04-28 23:11:33Z rmagick $
|
4
|
+
* Copyright (C) 2009 Timothy Paul Hunter
|
5
|
+
*/
|
6
|
+
|
7
|
+
#if !defined(MAGICKWAND_H)
|
8
|
+
#define MAGICKWAND_H 1
|
9
|
+
|
10
|
+
#include <stdio.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include "wand/MagickWand.h"
|
13
|
+
#include "ruby.h"
|
14
|
+
|
15
|
+
#undef EXTERN
|
16
|
+
#if defined(MAIN)
|
17
|
+
#define EXTERN
|
18
|
+
#else
|
19
|
+
#define EXTERN extern
|
20
|
+
#endif
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
/*
|
25
|
+
* Types
|
26
|
+
*/
|
27
|
+
typedef struct
|
28
|
+
{
|
29
|
+
MagickWand *magickwand;
|
30
|
+
} Wand;
|
31
|
+
|
32
|
+
|
33
|
+
typedef struct
|
34
|
+
{
|
35
|
+
DrawingWand *drawingwand;
|
36
|
+
} GC;
|
37
|
+
|
38
|
+
|
39
|
+
// What to do when an option value is not in the list of defined option values
|
40
|
+
typedef enum {
|
41
|
+
IgnoreUndefinedOption,
|
42
|
+
RaiseUndefinedOption
|
43
|
+
} OnUndefinedOption;
|
44
|
+
|
45
|
+
|
46
|
+
/*
|
47
|
+
* Extern variables
|
48
|
+
*/
|
49
|
+
VALUE mwr_mMagickWand;
|
50
|
+
VALUE mwr_cWand;
|
51
|
+
VALUE mwr_cGC;
|
52
|
+
VALUE mwr_eImageMagickError;
|
53
|
+
VALUE mwr_eFatalImageMagickError;
|
54
|
+
|
55
|
+
|
56
|
+
/*
|
57
|
+
* Extern functions
|
58
|
+
*/
|
59
|
+
extern void mwr_init_GC(void);
|
60
|
+
extern void mwr_init_Wand(void);
|
61
|
+
extern void mwr_init_ImageMagickError(void);
|
62
|
+
extern void mwr_init_FatalImageMagickError(void);
|
63
|
+
extern void mwr_check_magickwand_error(MagickWand *);
|
64
|
+
extern void mwr_check_pixelwand_error(PixelWand *);
|
65
|
+
extern void mwr_check_drawingwand_error(DrawingWand *);
|
66
|
+
extern void mwr_check_error(ExceptionInfo *);
|
67
|
+
extern MagickBooleanType mwr_get_option(VALUE, const char *, VALUE *);
|
68
|
+
extern char *mwr_imagetype_to_s(ImageType);
|
69
|
+
extern VALUE mwr_pixelpacket_to_hex(Image *, PixelPacket *);
|
70
|
+
extern void mwr_option_value_error(const char *, const char *);
|
71
|
+
extern VALUE mwr_option_values_to_hash(char *);
|
72
|
+
extern AlignType mwr_string_to_aligntype(VALUE, AlignType, OnUndefinedOption);
|
73
|
+
extern ChannelType mwr_string_to_channeltype(VALUE, ChannelType, OnUndefinedOption);
|
74
|
+
extern ColorspaceType mwr_string_to_colorspacetype(VALUE, ColorspaceType, OnUndefinedOption);
|
75
|
+
extern CompositeOperator mwr_string_to_composetype(VALUE, CompositeOperator, OnUndefinedOption);
|
76
|
+
extern CompressionType mwr_string_to_compressiontype(VALUE, CompressionType, OnUndefinedOption);
|
77
|
+
extern DecorationType mwr_string_to_decorationtype(VALUE, DecorationType, OnUndefinedOption);
|
78
|
+
extern FilterTypes mwr_string_to_filtertypes(VALUE, FilterTypes, OnUndefinedOption);
|
79
|
+
extern GravityType mwr_string_to_gravitytype(VALUE, GravityType, OnUndefinedOption);
|
80
|
+
extern ImageType mwr_string_to_imagetype(VALUE, ImageType, OnUndefinedOption);
|
81
|
+
extern MetricType mwr_string_to_metrictype(VALUE, MetricType, OnUndefinedOption);
|
82
|
+
extern StorageType mwr_string_to_storagetype(VALUE, StorageType, OnUndefinedOption);
|
83
|
+
extern StretchType mwr_string_to_stretchtype(VALUE, StretchType, OnUndefinedOption);
|
84
|
+
extern StyleType mwr_string_to_styletype(VALUE, StyleType, OnUndefinedOption);
|
85
|
+
extern unsigned long mwr_string_to_weight(VALUE, unsigned long, OnUndefinedOption);
|
86
|
+
extern char *mwr_format_size(const MagickSizeType, char *);
|
87
|
+
extern void mwr_get_pixelpacket_from_pixelwand(PixelPacket *, PixelWand *);
|
88
|
+
extern void mwr_get_pixelwand_from_pixelpacket(PixelWand *, PixelPacket *);
|
89
|
+
extern void mwr_process_options(VALUE, VALUE);
|
90
|
+
extern VALUE mwr_gc_new(void);
|
91
|
+
#endif
|
@@ -0,0 +1,819 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
* utility.c
|
4
|
+
* $Id: utility.c 144 2009-05-31 20:51:53Z rmagick $
|
5
|
+
* Copyright (C) 2009 Timothy Paul Hunter
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include <math.h>
|
9
|
+
#include <ctype.h>
|
10
|
+
#include "magickwand.h"
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
#define ENUMERATOR_STR(type) case type: str = #type; break
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
typedef struct
|
21
|
+
{
|
22
|
+
const char *name;
|
23
|
+
long type;
|
24
|
+
} ValueList;
|
25
|
+
|
26
|
+
|
27
|
+
typedef struct {
|
28
|
+
char *name;
|
29
|
+
ValueList *value;
|
30
|
+
} OptionList;
|
31
|
+
|
32
|
+
|
33
|
+
static ValueList align_types[] = {
|
34
|
+
{ "center", (long) CenterAlign },
|
35
|
+
{ "end", (long) RightAlign },
|
36
|
+
{ "left", (long) LeftAlign },
|
37
|
+
{ "middle", (long) CenterAlign },
|
38
|
+
{ "right", (long) RightAlign },
|
39
|
+
{ "start", (long) LeftAlign },
|
40
|
+
{ NULL, (long) UndefinedAlign } };
|
41
|
+
static ValueList channel_types[] = {
|
42
|
+
{ "all", (long) AllChannels },
|
43
|
+
{ "alpha", (long) OpacityChannel },
|
44
|
+
{ "black", (long) BlackChannel },
|
45
|
+
{ "blue", (long) BlueChannel },
|
46
|
+
{ "cyan", (long) CyanChannel },
|
47
|
+
{ "default", (long) DefaultChannels},
|
48
|
+
{ "gray", (long) GrayChannel },
|
49
|
+
{ "green", (long) GreenChannel },
|
50
|
+
{ "hue", (long) RedChannel },
|
51
|
+
{ "index", (long) IndexChannel },
|
52
|
+
{ "lightness", (long) BlueChannel },
|
53
|
+
{ "luminance", (long) BlueChannel },
|
54
|
+
{ "luminosity", (long) BlueChannel }, /* deprecated */
|
55
|
+
{ "magenta", (long) MagentaChannel },
|
56
|
+
{ "matte", (long) OpacityChannel },
|
57
|
+
{ "opacity", (long) OpacityChannel },
|
58
|
+
{ "red", (long) RedChannel },
|
59
|
+
{ "saturation", (long) GreenChannel },
|
60
|
+
{ "yellow", (long) YellowChannel },
|
61
|
+
{ NULL, (long) UndefinedChannel} };
|
62
|
+
static ValueList colorspace_types[] = {
|
63
|
+
{ "cmy", (long) CMYColorspace },
|
64
|
+
{ "cmyk", (long) CMYKColorspace },
|
65
|
+
{ "gray", (long) GRAYColorspace },
|
66
|
+
{ "hsb", (long) HSBColorspace },
|
67
|
+
{ "hsl", (long) HSLColorspace },
|
68
|
+
{ "hwb", (long) HWBColorspace },
|
69
|
+
{ "lab", (long) LabColorspace },
|
70
|
+
{ "log", (long) LogColorspace },
|
71
|
+
{ "ohta", (long) OHTAColorspace },
|
72
|
+
{ "rec601luma", (long) Rec601LumaColorspace },
|
73
|
+
{ "rec601ycbcr", (long) Rec601YCbCrColorspace },
|
74
|
+
{ "rec709luma", (long) Rec709LumaColorspace },
|
75
|
+
{ "rec709ycbcr", (long) Rec709YCbCrColorspace },
|
76
|
+
{ "rgb", (long) RGBColorspace },
|
77
|
+
{ "srgb", (long) sRGBColorspace },
|
78
|
+
{ "transparent", (long) TransparentColorspace },
|
79
|
+
{ "xyz", (long) XYZColorspace },
|
80
|
+
{ "ycbcr", (long) YCbCrColorspace },
|
81
|
+
{ "ycc", (long) YCCColorspace },
|
82
|
+
{ "yiq", (long) YIQColorspace },
|
83
|
+
{ "ypbpr", (long) YPbPrColorspace },
|
84
|
+
{ "yuv", (long) YUVColorspace },
|
85
|
+
{ NULL, (long) UndefinedColorspace } };
|
86
|
+
static ValueList compose_types[] = {
|
87
|
+
{ "add", (long) AddCompositeOp },
|
88
|
+
{ "atop", (long) AtopCompositeOp },
|
89
|
+
{ "blend", (long) BlendCompositeOp },
|
90
|
+
{ "bumpmap", (long) BumpmapCompositeOp },
|
91
|
+
{ "changemask", (long) ChangeMaskCompositeOp },
|
92
|
+
{ "clear", (long) ClearCompositeOp },
|
93
|
+
{ "colorburn", (long) ColorBurnCompositeOp },
|
94
|
+
{ "colordodge", (long) ColorDodgeCompositeOp },
|
95
|
+
{ "colorize", (long) ColorizeCompositeOp },
|
96
|
+
{ "copyblack", (long) CopyBlackCompositeOp },
|
97
|
+
{ "copyblue", (long) CopyBlueCompositeOp },
|
98
|
+
{ "copycyan", (long) CopyCyanCompositeOp },
|
99
|
+
{ "copygreen", (long) CopyGreenCompositeOp },
|
100
|
+
{ "copy", (long) CopyCompositeOp },
|
101
|
+
{ "copymagenta", (long) CopyMagentaCompositeOp },
|
102
|
+
{ "copyopacity", (long) CopyOpacityCompositeOp },
|
103
|
+
{ "copyred", (long) CopyRedCompositeOp },
|
104
|
+
{ "copyyellow", (long) CopyYellowCompositeOp },
|
105
|
+
{ "darken", (long) DarkenCompositeOp },
|
106
|
+
{ "divide", (long) DivideCompositeOp },
|
107
|
+
{ "dst", (long) DstCompositeOp },
|
108
|
+
{ "difference", (long) DifferenceCompositeOp },
|
109
|
+
{ "displace", (long) DisplaceCompositeOp },
|
110
|
+
{ "dissolve", (long) DissolveCompositeOp },
|
111
|
+
{ "dstatop", (long) DstAtopCompositeOp },
|
112
|
+
{ "dstin", (long) DstInCompositeOp },
|
113
|
+
{ "dstout", (long) DstOutCompositeOp },
|
114
|
+
{ "dstover", (long) DstOverCompositeOp },
|
115
|
+
{ "dst", (long) DstCompositeOp },
|
116
|
+
{ "exclusion", (long) ExclusionCompositeOp },
|
117
|
+
{ "hardlight", (long) HardLightCompositeOp },
|
118
|
+
{ "hue", (long) HueCompositeOp },
|
119
|
+
{ "in", (long) InCompositeOp },
|
120
|
+
{ "lighten", (long) LightenCompositeOp },
|
121
|
+
{ "linearlight", (long) LinearLightCompositeOp },
|
122
|
+
{ "luminize", (long) LuminizeCompositeOp },
|
123
|
+
{ "minus", (long) MinusCompositeOp },
|
124
|
+
{ "modulate", (long) ModulateCompositeOp },
|
125
|
+
{ "multiply", (long) MultiplyCompositeOp },
|
126
|
+
{ "none", (long) NoCompositeOp },
|
127
|
+
{ "out", (long) OutCompositeOp },
|
128
|
+
{ "overlay", (long) OverlayCompositeOp },
|
129
|
+
{ "over", (long) OverCompositeOp },
|
130
|
+
{ "plus", (long) PlusCompositeOp },
|
131
|
+
{ "replace", (long) ReplaceCompositeOp },
|
132
|
+
{ "saturate", (long) SaturateCompositeOp },
|
133
|
+
{ "screen", (long) ScreenCompositeOp },
|
134
|
+
{ "softlight", (long) SoftLightCompositeOp },
|
135
|
+
{ "src", (long) SrcCompositeOp },
|
136
|
+
{ "srcatop", (long) SrcAtopCompositeOp },
|
137
|
+
{ "srcin", (long) SrcInCompositeOp },
|
138
|
+
{ "srcout", (long) SrcOutCompositeOp },
|
139
|
+
{ "srcover", (long) SrcOverCompositeOp },
|
140
|
+
{ "src", (long) SrcCompositeOp },
|
141
|
+
{ "subtract", (long) SubtractCompositeOp },
|
142
|
+
{ "threshold", (long) ThresholdCompositeOp },
|
143
|
+
{ "xor", (long) XorCompositeOp },
|
144
|
+
{ NULL, (long) UndefinedCompositeOp } };
|
145
|
+
static ValueList compression_types[] = {
|
146
|
+
{ "bzip", (long) BZipCompression },
|
147
|
+
{ "dxt1", (long) DXT1Compression },
|
148
|
+
{ "dxt3", (long) DXT3Compression },
|
149
|
+
{ "dxt5", (long) DXT5Compression },
|
150
|
+
{ "fax", (long) FaxCompression },
|
151
|
+
{ "group4", (long) Group4Compression },
|
152
|
+
{ "jpeg", (long) JPEGCompression },
|
153
|
+
{ "jpeg2000", (long) JPEG2000Compression },
|
154
|
+
{ "lossless", (long) LosslessJPEGCompression },
|
155
|
+
{ "losslessjpeg", (long) LosslessJPEGCompression },
|
156
|
+
{ "lzw", (long) LZWCompression },
|
157
|
+
{ "none", (long) NoCompression },
|
158
|
+
{ "rle", (long) RLECompression },
|
159
|
+
{ "zip", (long) ZipCompression },
|
160
|
+
{ "runlengthencoded", (long) RLECompression },
|
161
|
+
{ NULL, (long) UndefinedCompression } };
|
162
|
+
static ValueList decoration_types[] = {
|
163
|
+
{ "linethrough", (long) LineThroughDecoration },
|
164
|
+
{ "none", (long) NoDecoration },
|
165
|
+
{ "overline", (long) OverlineDecoration },
|
166
|
+
{ "underline", (long) UnderlineDecoration },
|
167
|
+
{ NULL, (long) UndefinedDecoration } };
|
168
|
+
static ValueList filter_types[] = {
|
169
|
+
{"bartlett", (long) BartlettFilter},
|
170
|
+
{"bessel", (long) BesselFilter},
|
171
|
+
{"blackman", (long) BlackmanFilter},
|
172
|
+
{"bohman", (long) BohmanFilter},
|
173
|
+
{"box", (long) BoxFilter},
|
174
|
+
{"catrom", (long) CatromFilter},
|
175
|
+
{"cubic", (long) CubicFilter},
|
176
|
+
{"gaussian", (long) GaussianFilter},
|
177
|
+
{"hamming", (long) HammingFilter},
|
178
|
+
{"hanning", (long) HanningFilter},
|
179
|
+
{"hermite", (long) HermiteFilter},
|
180
|
+
{"kaiser", (long) KaiserFilter},
|
181
|
+
{"lagrange", (long) LagrangeFilter},
|
182
|
+
{"lanczos", (long) LanczosFilter},
|
183
|
+
{"mitchell", (long) MitchellFilter},
|
184
|
+
{"parzen", (long) ParzenFilter},
|
185
|
+
{"point", (long) PointFilter},
|
186
|
+
{"quadratic", (long) QuadraticFilter},
|
187
|
+
{"sinc", (long) SincFilter},
|
188
|
+
{"triangle", (long) TriangleFilter},
|
189
|
+
{"welsh", (long) WelshFilter},
|
190
|
+
{NULL, (long) UndefinedFilter} };
|
191
|
+
|
192
|
+
static ValueList image_types[] = {
|
193
|
+
{ "bilevel", (long) BilevelType },
|
194
|
+
{ "colorseparation", (long) ColorSeparationType },
|
195
|
+
{ "colorseparationmatte", (long) ColorSeparationMatteType },
|
196
|
+
{ "grayscale", (long) GrayscaleType },
|
197
|
+
{ "grayscalematte", (long) GrayscaleMatteType },
|
198
|
+
{ "optimize", (long) OptimizeType },
|
199
|
+
{ "palette", (long) PaletteType },
|
200
|
+
{ "palettebilevelmatte", (long) PaletteBilevelMatteType },
|
201
|
+
{ "palettematte", (long) PaletteMatteType },
|
202
|
+
{ "truecolormatte", (long) TrueColorMatteType },
|
203
|
+
{ "truecolor", (long) TrueColorType },
|
204
|
+
{ NULL, (long) UndefinedType } };
|
205
|
+
|
206
|
+
static ValueList gravity_types[] = {
|
207
|
+
{ "none", (long) UndefinedGravity },
|
208
|
+
{ "center", (long) CenterGravity },
|
209
|
+
{ "east", (long) EastGravity },
|
210
|
+
{ "forget", (long) ForgetGravity },
|
211
|
+
{ "northeast", (long) NorthEastGravity },
|
212
|
+
{ "north", (long) NorthGravity },
|
213
|
+
{ "northwest", (long) NorthWestGravity },
|
214
|
+
{ "southeast", (long) SouthEastGravity },
|
215
|
+
{ "south", (long) SouthGravity },
|
216
|
+
{ "southwest", (long) SouthWestGravity },
|
217
|
+
{ "west", (long) WestGravity },
|
218
|
+
{ "static", (long) StaticGravity },
|
219
|
+
{ NULL, (long) UndefinedGravity } };
|
220
|
+
static ValueList metric_types[] = {
|
221
|
+
{ "ae", (long) AbsoluteErrorMetric },
|
222
|
+
{ "mae", (long) MeanAbsoluteErrorMetric },
|
223
|
+
{ "mepp", (long) MeanErrorPerPixelMetric },
|
224
|
+
{ "mse", (long) MeanSquaredErrorMetric },
|
225
|
+
{ "pae", (long) PeakAbsoluteErrorMetric },
|
226
|
+
{ "psnr", (long) PeakSignalToNoiseRatioMetric },
|
227
|
+
{ "rmse", (long) RootMeanSquaredErrorMetric },
|
228
|
+
{ NULL, (long) UndefinedMetric } };
|
229
|
+
static ValueList storage_types[] = {
|
230
|
+
{ "char", (long) CharPixel },
|
231
|
+
{ "double", (long) DoublePixel },
|
232
|
+
{ "float", (long) FloatPixel },
|
233
|
+
{ "integer", (long) IntegerPixel },
|
234
|
+
{ "long", (long) LongPixel },
|
235
|
+
{ "quantum", (long) QuantumPixel },
|
236
|
+
{ "short", (long) ShortPixel },
|
237
|
+
{ NULL, (long) UndefinedPixel } };
|
238
|
+
static ValueList stretch_types[] = {
|
239
|
+
{ "any", (long) AnyStretch },
|
240
|
+
{ "condensed", (long) CondensedStretch },
|
241
|
+
{ "expanded", (long) ExpandedStretch },
|
242
|
+
{ "extracondensed", (long) ExtraCondensedStretch },
|
243
|
+
{ "extraexpanded", (long) ExtraExpandedStretch },
|
244
|
+
{ "normal", (long) NormalStretch },
|
245
|
+
{ "semicondensed", (long) SemiCondensedStretch },
|
246
|
+
{ "semiexpanded", (long) SemiExpandedStretch },
|
247
|
+
{ "ultracondensed", (long) UltraCondensedStretch },
|
248
|
+
{ "ultraexpanded", (long) UltraExpandedStretch },
|
249
|
+
{ NULL, (long) UndefinedStretch } };
|
250
|
+
static ValueList style_types[] = {
|
251
|
+
{ "any", (long) AnyStyle },
|
252
|
+
{ "italic", (long) ItalicStyle },
|
253
|
+
{ "normal", (long) NormalStyle },
|
254
|
+
{ "oblique", (long) ObliqueStyle },
|
255
|
+
{ NULL, (long) UndefinedStyle } };
|
256
|
+
static ValueList weight_types[] = {
|
257
|
+
{ "any", 0L },
|
258
|
+
{ "light", 100L },
|
259
|
+
{ "normal", 400L },
|
260
|
+
{ "bold", 700L },
|
261
|
+
{ NULL, 0L } };
|
262
|
+
|
263
|
+
static OptionList option_list[] = {
|
264
|
+
{"align", align_types},
|
265
|
+
{"channel", channel_types},
|
266
|
+
{"colorspace", colorspace_types},
|
267
|
+
{"compose", compose_types},
|
268
|
+
{"compress", compression_types},
|
269
|
+
{"decoration", decoration_types},
|
270
|
+
{"filter", filter_types},
|
271
|
+
{"gravity", gravity_types},
|
272
|
+
{"metric", metric_types},
|
273
|
+
{"type", image_types},
|
274
|
+
{"storage_type", storage_types},
|
275
|
+
{"stretch", stretch_types},
|
276
|
+
{"style", style_types},
|
277
|
+
{"weight", weight_types},
|
278
|
+
{NULL, NULL} };
|
279
|
+
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
/*
|
284
|
+
* lowercase up to 'lim' characters in a string
|
285
|
+
*/
|
286
|
+
static void downcase(char *out, size_t lim, const char *in)
|
287
|
+
{
|
288
|
+
char c;
|
289
|
+
size_t n;
|
290
|
+
|
291
|
+
for (n = 0; (n < lim) && (c = *in++); n++)
|
292
|
+
{
|
293
|
+
*out++ = tolower(c);
|
294
|
+
}
|
295
|
+
*out = '\0';
|
296
|
+
}
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
VALUE mwr_option_values_to_hash(char *option_name)
|
301
|
+
{
|
302
|
+
volatile VALUE option_values_hash;
|
303
|
+
volatile VALUE option_sym, values;
|
304
|
+
volatile VALUE value;
|
305
|
+
OptionList *o;
|
306
|
+
ValueList *v;
|
307
|
+
char name[100];
|
308
|
+
|
309
|
+
if (option_name != NULL)
|
310
|
+
{
|
311
|
+
downcase(name, sizeof(name), option_name);
|
312
|
+
}
|
313
|
+
|
314
|
+
option_values_hash = rb_hash_new();
|
315
|
+
for (o = option_list; o->name != NULL; o++)
|
316
|
+
{
|
317
|
+
if (!option_name || strcmp(name, o->name) == 0)
|
318
|
+
{
|
319
|
+
option_sym = ID2SYM(rb_intern(o->name));
|
320
|
+
values = rb_ary_new();
|
321
|
+
for (v = o->value; v->name != NULL; v++)
|
322
|
+
{
|
323
|
+
value = rb_str_new2(v->name);
|
324
|
+
rb_obj_freeze(value);
|
325
|
+
rb_ary_push(values, value);
|
326
|
+
}
|
327
|
+
rb_obj_freeze(values);
|
328
|
+
rb_hash_aset(option_values_hash, option_sym, values);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
rb_obj_freeze(option_values_hash);
|
333
|
+
return option_values_hash;
|
334
|
+
}
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
/*
|
341
|
+
* Raise an undefined option value exception
|
342
|
+
*/
|
343
|
+
void mwr_option_value_error(const char *option, const char *value)
|
344
|
+
{
|
345
|
+
rb_raise(rb_eArgError, "invalid value for :%s '%s'", option, value);
|
346
|
+
}
|
347
|
+
|
348
|
+
|
349
|
+
|
350
|
+
|
351
|
+
/*
|
352
|
+
* return the enum that matches the name. Return last enum in list if no match.
|
353
|
+
*/
|
354
|
+
static long string_to_enum(const char *option, ValueList *elist, VALUE s, long defval, OnUndefinedOption undef)
|
355
|
+
{
|
356
|
+
char ns[100];
|
357
|
+
ValueList *e;
|
358
|
+
|
359
|
+
if (s == Qnil)
|
360
|
+
{
|
361
|
+
return defval;
|
362
|
+
}
|
363
|
+
|
364
|
+
downcase(ns, sizeof(ns), StringValuePtr(s));
|
365
|
+
for (e = elist; e->name != NULL; e++)
|
366
|
+
{
|
367
|
+
if (strcmp(ns, e->name) == 0)
|
368
|
+
{
|
369
|
+
break;
|
370
|
+
}
|
371
|
+
}
|
372
|
+
|
373
|
+
if (e->name == NULL && undef == RaiseUndefinedOption)
|
374
|
+
{
|
375
|
+
mwr_option_value_error(option, StringValuePtr(s));
|
376
|
+
}
|
377
|
+
return e->type;
|
378
|
+
}
|
379
|
+
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
AlignType mwr_string_to_aligntype(VALUE s, AlignType defval, OnUndefinedOption undef)
|
384
|
+
{
|
385
|
+
return (AlignType) string_to_enum("align", align_types, s, (long)defval, undef);
|
386
|
+
}
|
387
|
+
|
388
|
+
ChannelType mwr_string_to_channeltype(VALUE s, ChannelType defval, OnUndefinedOption undef)
|
389
|
+
{
|
390
|
+
return (ChannelType) string_to_enum("channel", channel_types, s, (long)defval, undef);
|
391
|
+
}
|
392
|
+
|
393
|
+
ColorspaceType mwr_string_to_colorspacetype(VALUE s, ColorspaceType defval, OnUndefinedOption undef)
|
394
|
+
{
|
395
|
+
return (ColorspaceType) string_to_enum("colorspace", colorspace_types, s, (long)defval, undef);
|
396
|
+
}
|
397
|
+
|
398
|
+
CompositeOperator mwr_string_to_composetype(VALUE s, CompositeOperator defval, OnUndefinedOption undef)
|
399
|
+
{
|
400
|
+
return (CompositeOperator) string_to_enum("compose", compose_types, s, (long)defval, undef);
|
401
|
+
}
|
402
|
+
|
403
|
+
CompressionType mwr_string_to_compressiontype(VALUE s, CompressionType defval, OnUndefinedOption undef)
|
404
|
+
{
|
405
|
+
return (CompressionType) string_to_enum("compress", compression_types, s, (long)defval, undef);
|
406
|
+
}
|
407
|
+
|
408
|
+
DecorationType mwr_string_to_decorationtype(VALUE s, DecorationType defval, OnUndefinedOption undef)
|
409
|
+
{
|
410
|
+
return (DecorationType) string_to_enum("decoration", decoration_types, s, (long)defval, undef);
|
411
|
+
}
|
412
|
+
|
413
|
+
FilterTypes mwr_string_to_filtertypes(VALUE s, FilterTypes defval, OnUndefinedOption undef)
|
414
|
+
{
|
415
|
+
return (FilterTypes) string_to_enum("filter", filter_types, s, (long)defval, undef);
|
416
|
+
}
|
417
|
+
|
418
|
+
GravityType mwr_string_to_gravitytype(VALUE s, GravityType defval, OnUndefinedOption undef)
|
419
|
+
{
|
420
|
+
return (GravityType) string_to_enum("gravity", gravity_types, s, (long)defval, undef);
|
421
|
+
}
|
422
|
+
|
423
|
+
ImageType mwr_string_to_imagetype(VALUE s, ImageType defval, OnUndefinedOption undef)
|
424
|
+
{
|
425
|
+
return (ImageType) string_to_enum("type", image_types, s, (long)defval, undef);
|
426
|
+
}
|
427
|
+
|
428
|
+
MetricType mwr_string_to_metrictype(VALUE s, MetricType defval, OnUndefinedOption undef)
|
429
|
+
{
|
430
|
+
return (MetricType) string_to_enum("type", metric_types, s, (long)defval, undef);
|
431
|
+
}
|
432
|
+
|
433
|
+
StorageType mwr_string_to_storagetype(VALUE s, StorageType defval, OnUndefinedOption undef)
|
434
|
+
{
|
435
|
+
return (StretchType) string_to_enum("storage_type", storage_types, s, (long)defval, undef);
|
436
|
+
}
|
437
|
+
|
438
|
+
StretchType mwr_string_to_stretchtype(VALUE s, StretchType defval, OnUndefinedOption undef)
|
439
|
+
{
|
440
|
+
return (StretchType) string_to_enum("stretch", stretch_types, s, (long)defval, undef);
|
441
|
+
}
|
442
|
+
|
443
|
+
StyleType mwr_string_to_styletype(VALUE s, StyleType defval, OnUndefinedOption undef)
|
444
|
+
{
|
445
|
+
return (StyleType) string_to_enum("style", style_types, s, (long)defval, undef);
|
446
|
+
}
|
447
|
+
|
448
|
+
unsigned long mwr_string_to_weight(VALUE s, unsigned long defval, OnUndefinedOption undef)
|
449
|
+
{
|
450
|
+
return (unsigned long) string_to_enum("weight", weight_types, s, (long)defval, undef);
|
451
|
+
}
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
/*
|
456
|
+
* return ImageType enum as string (for #inspect)
|
457
|
+
*/
|
458
|
+
char *mwr_imagetype_to_s(ImageType type)
|
459
|
+
{
|
460
|
+
char *str;
|
461
|
+
|
462
|
+
switch (type)
|
463
|
+
{
|
464
|
+
ENUMERATOR_STR(UndefinedType);
|
465
|
+
ENUMERATOR_STR(BilevelType);
|
466
|
+
ENUMERATOR_STR(GrayscaleType);
|
467
|
+
ENUMERATOR_STR(GrayscaleMatteType);
|
468
|
+
ENUMERATOR_STR(PaletteType);
|
469
|
+
ENUMERATOR_STR(PaletteMatteType);
|
470
|
+
ENUMERATOR_STR(TrueColorType);
|
471
|
+
ENUMERATOR_STR(TrueColorMatteType);
|
472
|
+
ENUMERATOR_STR(ColorSeparationType);
|
473
|
+
ENUMERATOR_STR(ColorSeparationMatteType);
|
474
|
+
ENUMERATOR_STR(OptimizeType);
|
475
|
+
ENUMERATOR_STR(PaletteBilevelMatteType);
|
476
|
+
default:
|
477
|
+
str = "UndefinedType";
|
478
|
+
break;
|
479
|
+
}
|
480
|
+
|
481
|
+
return str;
|
482
|
+
}
|
483
|
+
|
484
|
+
|
485
|
+
|
486
|
+
|
487
|
+
/*
|
488
|
+
* If the option is present store its value in *value and return
|
489
|
+
* MagickTrue, otherwise store Qnil and return MagickFalse.
|
490
|
+
*
|
491
|
+
* Do _not_ delete keys from the options hash. We don't own it!
|
492
|
+
*/
|
493
|
+
MagickBooleanType mwr_get_option(VALUE options, const char *name, VALUE *value)
|
494
|
+
{
|
495
|
+
volatile VALUE key;
|
496
|
+
|
497
|
+
if (options != Qnil)
|
498
|
+
{
|
499
|
+
key = ID2SYM(rb_intern(name));
|
500
|
+
if (rb_funcall(options, rb_intern("has_key?"), 1, key) == Qtrue)
|
501
|
+
{
|
502
|
+
*value = rb_hash_aref(options, key);
|
503
|
+
return MagickTrue;
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
*value = Qnil;
|
508
|
+
return MagickFalse;
|
509
|
+
}
|
510
|
+
|
511
|
+
|
512
|
+
|
513
|
+
|
514
|
+
extern void mwr_get_pixelpacket_from_pixelwand(PixelPacket *pixelpacket, PixelWand *pixelwand)
|
515
|
+
{
|
516
|
+
pixelpacket->red = PixelGetRedQuantum(pixelwand);
|
517
|
+
pixelpacket->green = PixelGetGreenQuantum(pixelwand);
|
518
|
+
pixelpacket->blue = PixelGetBlueQuantum(pixelwand);
|
519
|
+
pixelpacket->opacity = PixelGetOpacityQuantum(pixelwand);
|
520
|
+
}
|
521
|
+
|
522
|
+
|
523
|
+
|
524
|
+
|
525
|
+
extern void mwr_get_pixelwand_from_pixelpacket(PixelWand *pixelwand, PixelPacket *pixelpacket)
|
526
|
+
{
|
527
|
+
PixelSetRedQuantum(pixelwand, pixelpacket->red);
|
528
|
+
PixelSetGreenQuantum(pixelwand, pixelpacket->green);
|
529
|
+
PixelSetBlueQuantum(pixelwand, pixelpacket->blue);
|
530
|
+
PixelSetOpacityQuantum(pixelwand, pixelpacket->opacity);
|
531
|
+
}
|
532
|
+
|
533
|
+
|
534
|
+
|
535
|
+
|
536
|
+
/*
|
537
|
+
* Return the hex representation of the pixel as a Ruby string.
|
538
|
+
* (The PixelWand method always returns the rgb() representation.)
|
539
|
+
*/
|
540
|
+
extern VALUE mwr_pixelpacket_to_hex(Image *image, PixelPacket *pixelpacket)
|
541
|
+
{
|
542
|
+
char name[MaxTextExtent];
|
543
|
+
MagickPixelPacket mpp;
|
544
|
+
|
545
|
+
memset(&mpp, 0, sizeof(mpp));
|
546
|
+
if (image)
|
547
|
+
{
|
548
|
+
mpp.depth = image->depth;
|
549
|
+
mpp.matte = image->matte;
|
550
|
+
mpp.colorspace = image->colorspace;
|
551
|
+
}
|
552
|
+
else
|
553
|
+
{
|
554
|
+
mpp.depth = QuantumDepth;
|
555
|
+
mpp.matte = MagickFalse;
|
556
|
+
mpp.colorspace = RGBColorspace;
|
557
|
+
}
|
558
|
+
mpp.red = (MagickRealType) pixelpacket->red;
|
559
|
+
mpp.green = (MagickRealType) pixelpacket->green;
|
560
|
+
mpp.blue = (MagickRealType) pixelpacket->blue;
|
561
|
+
mpp.opacity = (MagickRealType) pixelpacket->opacity;
|
562
|
+
mpp.index = 0.0;
|
563
|
+
(void) GetColorTuple(&mpp, MagickTrue, name);
|
564
|
+
return rb_str_new2(name);
|
565
|
+
}
|
566
|
+
|
567
|
+
|
568
|
+
|
569
|
+
|
570
|
+
|
571
|
+
/*
|
572
|
+
* Similar but not identical to FormatMagickSize
|
573
|
+
*/
|
574
|
+
extern char *mwr_format_size(const MagickSizeType size, char *buff)
|
575
|
+
{
|
576
|
+
double d;
|
577
|
+
|
578
|
+
if (size >= 1073741824)
|
579
|
+
{
|
580
|
+
d = size / 1073741824.0;
|
581
|
+
sprintf(buff, "%ggb", d);
|
582
|
+
}
|
583
|
+
else if (size >= 1048576)
|
584
|
+
{
|
585
|
+
d = size / 1048576.0;
|
586
|
+
sprintf(buff, "%gmb", d);
|
587
|
+
}
|
588
|
+
else if (size >= 1024)
|
589
|
+
{
|
590
|
+
d = size / 1024.0;
|
591
|
+
sprintf(buff, "%gkb", d);
|
592
|
+
}
|
593
|
+
else
|
594
|
+
{
|
595
|
+
sprintf(buff, "%g", (double)size);
|
596
|
+
}
|
597
|
+
|
598
|
+
return buff;
|
599
|
+
}
|
600
|
+
|
601
|
+
|
602
|
+
|
603
|
+
|
604
|
+
/*
|
605
|
+
* Calls the set_<option> private method.
|
606
|
+
*/
|
607
|
+
static VALUE call_option_setter(VALUE args)
|
608
|
+
{
|
609
|
+
volatile VALUE option, value, obj;
|
610
|
+
char setter[100];
|
611
|
+
|
612
|
+
option = rb_ary_entry(args, 0);
|
613
|
+
value = rb_ary_entry(args, 1);
|
614
|
+
obj = rb_ary_entry(args, 2);
|
615
|
+
|
616
|
+
(void) sprintf(setter, "set_%.90s", rb_id2name(SYM2ID(option)));
|
617
|
+
|
618
|
+
return rb_funcall(obj, rb_intern(setter), 1, value);
|
619
|
+
}
|
620
|
+
|
621
|
+
|
622
|
+
|
623
|
+
|
624
|
+
/*
|
625
|
+
* Called if an exception was raised by call_option_setter (above).
|
626
|
+
*/
|
627
|
+
static VALUE rescue_option(VALUE args, VALUE errinfo)
|
628
|
+
{
|
629
|
+
volatile VALUE option;
|
630
|
+
volatile VALUE err_class;
|
631
|
+
volatile VALUE msg;
|
632
|
+
|
633
|
+
option = rb_ary_entry(args, 0);
|
634
|
+
err_class = CLASS_OF(errinfo);
|
635
|
+
if (err_class == rb_eNoMethodError)
|
636
|
+
{
|
637
|
+
/* Do not diagnose undefined options. */
|
638
|
+
#if 0
|
639
|
+
rb_raise(rb_eArgError, "undefined option :%s", rb_id2name(SYM2ID(option)));
|
640
|
+
#else
|
641
|
+
return Qnil;
|
642
|
+
#endif
|
643
|
+
}
|
644
|
+
|
645
|
+
msg = rb_funcall(errinfo, rb_intern("message"), 0, 0);
|
646
|
+
rb_raise(err_class, "%s", StringValuePtr(msg));
|
647
|
+
return Qnil; // dummy
|
648
|
+
}
|
649
|
+
|
650
|
+
|
651
|
+
|
652
|
+
|
653
|
+
/*
|
654
|
+
* Called with each key, value pair in the options hash.
|
655
|
+
* The key is the option to be set. The value is the option value.
|
656
|
+
* If the option setter needs > 1 argument, the value s/b an array.
|
657
|
+
* begin
|
658
|
+
* __send__(set_option, value)
|
659
|
+
* rescue NoMethodError
|
660
|
+
* raise(ArgumentError, "undefined option :#{option}")
|
661
|
+
* end
|
662
|
+
*/
|
663
|
+
static int begin_option(VALUE option, VALUE value, VALUE obj)
|
664
|
+
{
|
665
|
+
VALUE args;
|
666
|
+
|
667
|
+
args = rb_ary_new2(3);
|
668
|
+
rb_ary_push(args, option);
|
669
|
+
rb_ary_push(args, value);
|
670
|
+
rb_ary_push(args, obj);
|
671
|
+
(void) rb_rescue(call_option_setter, args, rescue_option, args);
|
672
|
+
return 0;
|
673
|
+
}
|
674
|
+
|
675
|
+
|
676
|
+
|
677
|
+
|
678
|
+
/*
|
679
|
+
* Iterate over the options hash.
|
680
|
+
*/
|
681
|
+
void mwr_process_options(VALUE obj, VALUE options)
|
682
|
+
{
|
683
|
+
if (options != Qnil)
|
684
|
+
{
|
685
|
+
rb_hash_foreach(options, begin_option, obj);
|
686
|
+
}
|
687
|
+
}
|
688
|
+
|
689
|
+
|
690
|
+
|
691
|
+
|
692
|
+
/*
|
693
|
+
* issue warning or raise appropriate exception
|
694
|
+
*/
|
695
|
+
static void raise_wand_error(ExceptionType severity, char *exception)
|
696
|
+
{
|
697
|
+
if (severity < ErrorException)
|
698
|
+
{
|
699
|
+
rb_warning("MagickWand: %s", exception);
|
700
|
+
}
|
701
|
+
else if (severity < FatalErrorException)
|
702
|
+
{
|
703
|
+
|
704
|
+
rb_raise(mwr_eImageMagickError, "%s", exception);
|
705
|
+
}
|
706
|
+
else
|
707
|
+
{
|
708
|
+
rb_raise(mwr_eFatalImageMagickError, "%s", exception);
|
709
|
+
}
|
710
|
+
}
|
711
|
+
|
712
|
+
|
713
|
+
|
714
|
+
|
715
|
+
/*
|
716
|
+
* The exception strings are allocated out of Ruby managed memory and will
|
717
|
+
* be GC'd normally.
|
718
|
+
*/
|
719
|
+
void mwr_check_magickwand_error(MagickWand *magickwand)
|
720
|
+
{
|
721
|
+
ExceptionType severity;
|
722
|
+
char *exception;
|
723
|
+
|
724
|
+
severity = MagickGetExceptionType(magickwand);
|
725
|
+
|
726
|
+
if (severity > UndefinedException)
|
727
|
+
{
|
728
|
+
exception = MagickGetException(magickwand, &severity);
|
729
|
+
MagickClearException(magickwand);
|
730
|
+
raise_wand_error(severity, exception);
|
731
|
+
}
|
732
|
+
}
|
733
|
+
|
734
|
+
|
735
|
+
|
736
|
+
|
737
|
+
void mwr_check_pixelwand_error(PixelWand *pixelwand)
|
738
|
+
{
|
739
|
+
ExceptionType severity;
|
740
|
+
char *exception;
|
741
|
+
|
742
|
+
severity = PixelGetExceptionType(pixelwand);
|
743
|
+
|
744
|
+
if (severity > UndefinedException)
|
745
|
+
{
|
746
|
+
exception = PixelGetException(pixelwand, &severity);
|
747
|
+
PixelClearException(pixelwand);
|
748
|
+
raise_wand_error(severity, exception);
|
749
|
+
}
|
750
|
+
}
|
751
|
+
|
752
|
+
|
753
|
+
|
754
|
+
|
755
|
+
void mwr_check_drawingwand_error(DrawingWand *drawingwand)
|
756
|
+
{
|
757
|
+
ExceptionType severity;
|
758
|
+
char *exception;
|
759
|
+
|
760
|
+
severity = DrawGetExceptionType(drawingwand);
|
761
|
+
|
762
|
+
if (severity > UndefinedException)
|
763
|
+
{
|
764
|
+
exception = DrawGetException(drawingwand, &severity);
|
765
|
+
DrawClearException(drawingwand);
|
766
|
+
raise_wand_error(severity, exception);
|
767
|
+
}
|
768
|
+
}
|
769
|
+
|
770
|
+
|
771
|
+
|
772
|
+
|
773
|
+
void mwr_check_error(ExceptionInfo *exception)
|
774
|
+
{
|
775
|
+
char buffer[2010];
|
776
|
+
|
777
|
+
if (exception->severity > UndefinedException)
|
778
|
+
{
|
779
|
+
buffer[0] = '\0';
|
780
|
+
if (exception->reason)
|
781
|
+
{
|
782
|
+
strncpy(buffer, GetLocaleExceptionMessage(exception->severity, exception->reason), 1000);
|
783
|
+
}
|
784
|
+
if (exception->description)
|
785
|
+
{
|
786
|
+
sprintf(buffer+strlen(buffer), " (%.1000s)", GetLocaleExceptionMessage(exception->severity, exception->description));
|
787
|
+
}
|
788
|
+
|
789
|
+
if (exception->severity < ErrorException)
|
790
|
+
{
|
791
|
+
rb_warning("MagickWand: %s", buffer);
|
792
|
+
}
|
793
|
+
else if (exception->severity < FatalErrorException)
|
794
|
+
{
|
795
|
+
|
796
|
+
rb_raise(mwr_eImageMagickError, "%s", buffer);
|
797
|
+
}
|
798
|
+
else
|
799
|
+
{
|
800
|
+
rb_raise(mwr_eFatalImageMagickError, "%s", buffer);
|
801
|
+
}
|
802
|
+
}
|
803
|
+
}
|
804
|
+
|
805
|
+
|
806
|
+
|
807
|
+
|
808
|
+
void mwr_init_ImageMagickError(void)
|
809
|
+
{
|
810
|
+
mwr_eImageMagickError = rb_define_class_under(mwr_mMagickWand, "ImageMagickError", rb_eStandardError);
|
811
|
+
}
|
812
|
+
|
813
|
+
|
814
|
+
|
815
|
+
|
816
|
+
void mwr_init_FatalImageMagickError(void)
|
817
|
+
{
|
818
|
+
mwr_eFatalImageMagickError = rb_define_class_under(mwr_mMagickWand, "FatalImageMagickError", rb_eStandardError);
|
819
|
+
}
|