rmagick 1.10.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rmagick might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
- MANIFEST for RMagick-1.10.1 - 09:54:53 02/25/06
1
+ MANIFEST for RMagick-1.11.0 - 17:57:50 05/11/06
2
2
 
3
3
  configure
4
4
  README.html
@@ -28,12 +28,13 @@ examples/identify.rb
28
28
  examples/histogram.rb
29
29
  examples/describe.rb
30
30
  uninstall.rb
31
+ setup.rb
31
32
  rmagick.gemspec
32
33
  post-setup.rb
33
34
  post-install.rb
34
35
  post-clean.rb
35
36
  metaconfig.in
36
- install.rb
37
+ gem_config.rb
37
38
  configure.ac
38
39
  README.txt
39
40
  README-Mac-OSX.txt
@@ -1,4 +1,4 @@
1
- /* $Id: rmagick.h,v 1.105 2006/02/19 17:12:20 rmagick Exp $ */
1
+ /* $Id: rmagick.h,v 1.109 2006/05/07 21:41:11 rmagick Exp $ */
2
2
  /*=============================================================================
3
3
  | Copyright (C) 2006 by Timothy P. Hunter
4
4
  | Name: rmagick.h
@@ -115,8 +115,7 @@ typedef enum
115
115
  {
116
116
  False = 0,
117
117
  True = 1
118
- }
119
- boolean;
118
+ } boolean;
120
119
 
121
120
  typedef enum {
122
121
  AnyWeight,
@@ -274,6 +273,9 @@ EXTERN VALUE Class_FilterTypes;
274
273
  EXTERN VALUE Class_GravityType;
275
274
  EXTERN VALUE Class_ImageType;
276
275
  EXTERN VALUE Class_InterlaceType;
276
+ #if defined(HAVE_COMPAREIMAGELAYERS)
277
+ EXTERN VALUE Class_MagickLayerMethod;
278
+ #endif
277
279
  EXTERN VALUE Class_NoiseType;
278
280
  #if defined(HAVE_IMAGE_ORIENTATION)
279
281
  EXTERN VALUE Class_OrientationType;
@@ -324,14 +326,8 @@ EXTERN ID ID_y; // "y"
324
326
 
325
327
  /*
326
328
  Handle warnings & errors
327
-
328
- For ExceptionInfo structures in auto storage. Destroys the
329
- ExceptionInfo structure (releasing any IM storage) before
330
- calling rb_raise.
331
329
  */
332
- #define HANDLE_ERROR rm_handle_error(&exception);
333
- // For ExceptionInfo structures in images.
334
- #define HANDLE_ERROR_IMG(img) rm_handle_error(&((img)->exception));
330
+ #define CHECK_EXCEPTION() rm_check_exception(&exception, NULL, RetainOnError);
335
331
 
336
332
  /*
337
333
  Map the QuantumDepth to a StorageType.
@@ -593,6 +589,7 @@ extern VALUE ImageList_map(VALUE, VALUE, VALUE);
593
589
  extern VALUE ImageList_montage(VALUE);
594
590
  extern VALUE ImageList_morph(VALUE, VALUE);
595
591
  extern VALUE ImageList_mosaic(VALUE);
592
+ extern VALUE ImageList_optimize_layers(VALUE, VALUE);
596
593
  extern VALUE ImageList_quantize(int, VALUE*, VALUE);
597
594
  extern VALUE ImageList_to_blob(VALUE);
598
595
  extern VALUE ImageList_write(VALUE, VALUE);
@@ -769,6 +766,7 @@ extern VALUE Image_composite_affine(VALUE, VALUE, VALUE);
769
766
  extern VALUE Image_compress_colormap_bang(VALUE);
770
767
  extern VALUE Image_constitute(VALUE, VALUE, VALUE, VALUE, VALUE);
771
768
  extern VALUE Image_contrast(int, VALUE *, VALUE);
769
+ extern VALUE Image_contrast_stretch_channel(int, VALUE *, VALUE);
772
770
  extern VALUE Image_convolve(VALUE, VALUE, VALUE);
773
771
  extern VALUE Image_convolve_channel(int, VALUE *, VALUE);
774
772
  extern VALUE Image_copy(VALUE);
@@ -1022,18 +1020,28 @@ extern char *rm_string_value_ptr_len(volatile VALUE *, long *);
1022
1020
  extern int rm_strcasecmp(const char *, const char *);
1023
1021
  extern void rm_check_ary_len(VALUE, int);
1024
1022
  extern void rm_check_frozen(VALUE);
1023
+ extern int rm_check_num2dbl(VALUE);
1025
1024
  extern double rm_fuzz_to_dbl(VALUE);
1026
1025
  extern double rm_percentage(VALUE);
1026
+ extern double rm_str_to_pct(VALUE);
1027
1027
  extern VALUE rm_define_enum_type(char *);
1028
1028
  extern void rm_write_temp_image(Image *, char *);
1029
1029
  extern void rm_delete_temp_image(char *);
1030
1030
  extern void rm_not_implemented(void);
1031
- extern void rm_handle_error(ExceptionInfo *);
1032
- extern void rm_handle_all_errors(Image *);
1033
1031
  extern void rm_attr_write(VALUE, VALUE);
1034
1032
  extern void rm_get_geometry(VALUE, long *, long *, unsigned long *, unsigned long *, int *);
1035
1033
  extern void rm_split(Image *);
1036
1034
 
1035
+ typedef enum
1036
+ {
1037
+ RetainOnError = 0,
1038
+ DestroyOnError = 1
1039
+ } ErrorRetention;
1040
+
1041
+ extern void rm_check_image_exception(Image *, ErrorRetention);
1042
+ extern void rm_check_exception(ExceptionInfo *, Image *, ErrorRetention);
1043
+ extern void rm_ensure_result(Image *);
1044
+ extern Image *rm_clone_image(Image *);
1037
1045
  #if defined(HAVE_SETIMAGEPROGRESSMONITOR)
1038
1046
  extern MagickBooleanType rm_progress_monitor(const char *, const MagickOffsetType, const MagickSizeType, void *);
1039
1047
  #endif
@@ -15,12 +15,20 @@
15
15
  #undef HAVE_BLACKTHRESHOLDIMAGE
16
16
  /* Introduced in IM 6.0.1 */
17
17
  #undef HAVE_BLURIMAGECHANNEL
18
+ /* Introduced in IM 6.2.7 */
19
+ #undef HAVE_COALESCELAYER
18
20
  /* Introduced in GM 1.2 */
19
21
  #undef HAVE_CINEONLOGRGBCOLORSPACE
22
+ /* Introduced in IM 6.2.6 - Not available in GM */
23
+ #undef HAVE_CLEARMAGICKEXCEPTION
20
24
  /* Introduced in IM 6.0.0 */
21
25
  #undef HAVE_COLORDODGECOMPOSITEOP
22
26
  /* Introduced in IM 6.0.0, GM 1.1 */
23
27
  #undef HAVE_COMPAREIMAGECHANNELS
28
+ /* Introduced in IM 6.2.6 */
29
+ #undef HAVE_COMPAREIMAGELAYERS
30
+ /* Introduced in IM 6.2.6 */
31
+ #undef HAVE_CONTRASTSTRETCHIMAGECHANNEL
24
32
  /* Introduced in IM 6.0.1 */
25
33
  #undef HAVE_CONVOLVEIMAGECHANNEL
26
34
  /* Introduced in IM 5.5.7, GM 1.1 */
@@ -75,10 +83,12 @@
75
83
  #undef HAVE_GETMAGICKINFOARRAY
76
84
  /* Introduced in IM 6.0.1 */
77
85
  #undef HAVE_GETMAGICKINFOLIST
78
- /* Introduced in IM 6.1.5 */
79
- #undef HAVE_GETMULTILINETYPEMETRICS
80
86
  /* API changed in IM 6.1.3 */
81
87
  #undef HAVE_OLD_GETMAGICKINFOLIST
88
+ /* Introduced in IM 6.2.5 */
89
+ #undef HAVE_GETMAGICKRESOURCELIMIT
90
+ /* Introduced in IM 6.1.5 */
91
+ #undef HAVE_GETMULTILINETYPEMETRICS
82
92
  /* Introduced in IM 6.2.1 */
83
93
  #undef HAVE_GETNEXTIMAGEATTRIBUTE
84
94
  /* Introduced in IM 6.0.0 */
@@ -92,6 +102,8 @@
92
102
  #undef HAVE_GRAYSCALEPSEUDOCLASSIMAGE
93
103
  /* Introduced in IM 6.0.0 - Not available in GM */
94
104
  #undef HAVE_HSBCOLORSPACE
105
+ /* Introduced in IM 6.0.0 - Not available in GM */
106
+ #undef HAVE_INHERITEXCEPTION
95
107
  #undef HAVE_INDEXCHANNEL
96
108
  /* Introduced in IM 5.5.6 - Not available in GM */
97
109
  #undef HAVE_IMAGE_EXTRACT_INFO
@@ -1,4 +1,4 @@
1
- /* $Id: rmdraw.c,v 1.29 2006/02/19 17:12:20 rmagick Exp $ */
1
+ /* $Id: rmdraw.c,v 1.32 2006/05/07 21:58:32 rmagick Exp $ */
2
2
  /*============================================================================\
3
3
  | Copyright (C) 2006 by Timothy P. Hunter
4
4
  | Name: rmdraw.c
@@ -467,7 +467,7 @@ VALUE Draw_annotate(
467
467
 
468
468
  draw->info->affine = keep;
469
469
 
470
- HANDLE_ERROR_IMG(image)
470
+ rm_check_image_exception(image, RetainOnError);
471
471
 
472
472
  return self;
473
473
  }
@@ -640,7 +640,7 @@ Draw_draw(VALUE self, VALUE image_arg)
640
640
  magick_clone_string(&(draw->info->primitive), STRING_PTR(draw->primitives));
641
641
 
642
642
  (void) DrawImage(image, draw->info);
643
- HANDLE_ERROR_IMG(image)
643
+ rm_check_image_exception(image, RetainOnError);
644
644
 
645
645
  magick_free(draw->info->primitive);
646
646
  draw->info->primitive = NULL;
@@ -761,6 +761,10 @@ Draw_initialize(VALUE self)
761
761
  // Use the Info structure to create the DrawInfo structure
762
762
  Data_Get_Struct(info_obj, Info, info);
763
763
  draw->info = CloneDrawInfo(info, NULL);
764
+ if (!draw->info)
765
+ {
766
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
767
+ }
764
768
 
765
769
  draw->primitives = (VALUE)0;
766
770
  draw->tmpfile_ary = NULL;
@@ -1337,6 +1341,9 @@ get_type_metrics(
1337
1341
 
1338
1342
  if (!okay)
1339
1343
  {
1344
+ rm_check_image_exception(image, RetainOnError);
1345
+
1346
+ // Shouldn't get here...
1340
1347
  rb_raise(rb_eRuntimeError, "Can't measure text. Are the fonts installed? "
1341
1348
  "Is the FreeType library installed?");
1342
1349
  }
@@ -1,4 +1,4 @@
1
- /* $Id: rmfill.c,v 1.13 2005/12/31 14:40:50 rmagick Exp $ */
1
+ /* $Id: rmfill.c,v 1.14 2006/05/07 23:46:19 rmagick Exp $ */
2
2
  /*============================================================================\
3
3
  | Copyright (C) 2006 by Timothy P. Hunter
4
4
  | Name: rmfill.c
@@ -131,7 +131,7 @@ point_fill(
131
131
 
132
132
  if (!(row_pixels = SetImagePixels(image, 0, y, image->columns, 1)))
133
133
  {
134
- rb_raise(rb_eNoMemError, "not enough memory to continue");
134
+ rm_check_image_exception(image, RetainOnError);
135
135
  }
136
136
  for (x = 0; x < image->columns; x++)
137
137
  {
@@ -143,7 +143,7 @@ point_fill(
143
143
  }
144
144
  if (!SyncImagePixels(image))
145
145
  {
146
- rb_raise(Class_ImageMagickError, "can't set image pixels");
146
+ rm_check_image_exception(image, RetainOnError);
147
147
  }
148
148
  }
149
149
  }
@@ -209,13 +209,13 @@ vertical_fill(
209
209
 
210
210
  if (!(row_pixels = SetImagePixels(image, 0, y, image->columns, 1)))
211
211
  {
212
- rb_raise(rb_eNoMemError, "not enough memory to continue");
212
+ rm_check_image_exception(image, RetainOnError);
213
213
  }
214
214
 
215
215
  memcpy(row_pixels, (PixelPacket *)master, image->columns * sizeof(PixelPacket));
216
216
  if (!SyncImagePixels(image))
217
217
  {
218
- rb_raise(Class_ImageMagickError, "can't set image pixels");
218
+ rm_check_image_exception(image, RetainOnError);
219
219
  }
220
220
  }
221
221
 
@@ -279,12 +279,12 @@ horizontal_fill(
279
279
 
280
280
  if (!(col_pixels = SetImagePixels(image, x, 0, 1, image->rows)))
281
281
  {
282
- rb_raise(rb_eNoMemError, "not enough memory to continue");
282
+ rm_check_image_exception(image, RetainOnError);
283
283
  }
284
284
  memcpy(col_pixels, (PixelPacket *)master, image->rows * sizeof(PixelPacket));
285
285
  if (!SyncImagePixels(image))
286
286
  {
287
- rb_raise(Class_ImageMagickError, "can't set image pixels");
287
+ rm_check_image_exception(image, RetainOnError);
288
288
  }
289
289
  }
290
290
 
@@ -353,7 +353,7 @@ v_diagonal_fill(
353
353
 
354
354
  if (!(row_pixels = SetImagePixels(image, 0, y, image->columns, 1)))
355
355
  {
356
- rb_raise(rb_eNoMemError, "not enough memory to continue");
356
+ rm_check_image_exception(image, RetainOnError);
357
357
  }
358
358
  for (x = 0; x < image->columns; x++)
359
359
  {
@@ -365,7 +365,7 @@ v_diagonal_fill(
365
365
  }
366
366
  if (!SyncImagePixels(image))
367
367
  {
368
- rb_raise(Class_ImageMagickError, "can't set image pixels");
368
+ rm_check_image_exception(image, RetainOnError);
369
369
  }
370
370
  }
371
371
  }
@@ -434,7 +434,7 @@ h_diagonal_fill(
434
434
 
435
435
  if (!(row_pixels = SetImagePixels(image, 0, y, image->columns, 1)))
436
436
  {
437
- rb_raise(rb_eNoMemError, "not enough memory to continue");
437
+ rm_check_image_exception(image, RetainOnError);
438
438
  }
439
439
  for (x = 0; x < image->columns; x++)
440
440
  {
@@ -446,7 +446,7 @@ h_diagonal_fill(
446
446
  }
447
447
  if (!SyncImagePixels(image))
448
448
  {
449
- rb_raise(Class_ImageMagickError, "can't set image pixels");
449
+ rm_check_image_exception(image, RetainOnError);
450
450
  }
451
451
  }
452
452
  }
@@ -605,5 +605,8 @@ TextureFill_fill(VALUE self, VALUE image_obj)
605
605
  Data_Get_Struct(self, TextureFill, fill);
606
606
 
607
607
  TextureImage(image, fill->texture);
608
+ rm_check_image_exception(image, RetainOnError);
609
+
608
610
  return self;
609
611
  }
612
+
@@ -1,4 +1,4 @@
1
- /* $Id: rmilist.c,v 1.31 2006/02/03 23:26:05 rmagick Exp $ */
1
+ /* $Id: rmilist.c,v 1.39 2006/05/08 22:45:27 rmagick Exp $ */
2
2
  /*============================================================================\
3
3
  | Copyright (C) 2006 by Timothy P. Hunter
4
4
  | Name: rmilist.c
@@ -48,7 +48,7 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
48
48
  Data_Get_Struct(info_obj, Info, info);
49
49
 
50
50
  (void) AnimateImages(info, images);
51
- rm_handle_all_errors(images);
51
+ rm_check_image_exception(images, RetainOnError);
52
52
  rm_split(images);
53
53
 
54
54
  return self;
@@ -62,7 +62,7 @@ ImageList_animate(int argc, VALUE *argv, VALUE self)
62
62
  VALUE
63
63
  ImageList_append(VALUE self, VALUE stack_arg)
64
64
  {
65
- Image *images, *result;
65
+ Image *images, *new_image;
66
66
  unsigned int stack;
67
67
  ExceptionInfo exception;
68
68
 
@@ -74,11 +74,12 @@ ImageList_append(VALUE self, VALUE stack_arg)
74
74
  stack = RTEST(stack_arg);
75
75
 
76
76
  GetExceptionInfo(&exception);
77
- result = AppendImages(images, stack, &exception);
77
+ new_image = AppendImages(images, stack, &exception);
78
78
  rm_split(images);
79
- HANDLE_ERROR
79
+ rm_check_exception(&exception, new_image, DestroyOnError);
80
+ rm_ensure_result(new_image);
80
81
 
81
- return rm_image_new(result);
82
+ return rm_image_new(new_image);
82
83
  }
83
84
 
84
85
  /*
@@ -89,18 +90,19 @@ ImageList_append(VALUE self, VALUE stack_arg)
89
90
  VALUE
90
91
  ImageList_average(VALUE self)
91
92
  {
92
- Image *images, *result;
93
+ Image *images, *new_image;
93
94
  ExceptionInfo exception;
94
95
 
95
96
  // Convert the images array to an images sequence.
96
97
  images = rm_images_from_imagelist(self);
97
98
 
98
99
  GetExceptionInfo(&exception);
99
- result = AverageImages(images, &exception);
100
- rm_handle_all_errors(images);
100
+ new_image = AverageImages(images, &exception);
101
101
  rm_split(images);
102
+ rm_check_exception(&exception, new_image, DestroyOnError);
103
+ rm_ensure_result(new_image);
102
104
 
103
- return rm_image_new(result);
105
+ return rm_image_new(new_image);
104
106
  }
105
107
 
106
108
  /*
@@ -114,18 +116,19 @@ ImageList_average(VALUE self)
114
116
  VALUE
115
117
  ImageList_coalesce(VALUE self)
116
118
  {
117
- Image *images, *results;
119
+ Image *images, *new_images;
118
120
  ExceptionInfo exception;
119
121
 
120
122
  // Convert the image array to an image sequence.
121
123
  images = rm_images_from_imagelist(self);
122
124
 
123
125
  GetExceptionInfo(&exception);
124
- results = CoalesceImages(images, &exception);
126
+ new_images = CoalesceImages(images, &exception);
125
127
  rm_split(images);
126
- HANDLE_ERROR
128
+ rm_check_exception(&exception, new_images, DestroyOnError);
129
+ rm_ensure_result(new_images);
127
130
 
128
- return rm_imagelist_from_images(results);
131
+ return rm_imagelist_from_images(new_images);
129
132
  }
130
133
 
131
134
 
@@ -146,7 +149,8 @@ ImageList_deconstruct(VALUE self)
146
149
  GetExceptionInfo(&exception);
147
150
  new_images = DeconstructImages(images, &exception);
148
151
  rm_split(images);
149
- HANDLE_ERROR
152
+ rm_check_exception(&exception, new_images, DestroyOnError);
153
+ rm_ensure_result(new_images);
150
154
 
151
155
  return rm_imagelist_from_images(new_images);
152
156
  }
@@ -161,7 +165,6 @@ ImageList_display(VALUE self)
161
165
  Image *images;
162
166
  Info *info;
163
167
  volatile VALUE info_obj;
164
- unsigned int ok;
165
168
 
166
169
  // Convert the images array to an images sequence.
167
170
  images = rm_images_from_imagelist(self);
@@ -170,12 +173,9 @@ ImageList_display(VALUE self)
170
173
  info_obj = rm_info_new();
171
174
  Data_Get_Struct(info_obj, Info, info);
172
175
 
173
- ok = DisplayImages(info, images);
174
- if (!ok)
175
- {
176
- rm_handle_all_errors(images);
177
- }
176
+ (void) DisplayImages(info, images);
178
177
  rm_split(images);
178
+ rm_check_image_exception(images, RetainOnError);
179
179
 
180
180
  return self;
181
181
  }
@@ -196,12 +196,14 @@ ImageList_flatten_images(VALUE self)
196
196
  GetExceptionInfo(&exception);
197
197
  new_image = FlattenImages(images, &exception);
198
198
  rm_split(images);
199
- HANDLE_ERROR
199
+ rm_check_exception(&exception, new_image, DestroyOnError);
200
+ rm_ensure_result(new_image);
200
201
 
201
202
  return rm_image_new(new_image);
202
203
  }
203
204
 
204
205
 
206
+
205
207
  /*
206
208
  Method: ImageList#map
207
209
  Purpose: Call MapImages
@@ -210,7 +212,7 @@ ImageList_flatten_images(VALUE self)
210
212
  VALUE
211
213
  ImageList_map(VALUE self, VALUE map_image, VALUE dither_arg)
212
214
  {
213
- Image *images, *clone_images = NULL;
215
+ Image *images, *new_images = NULL;
214
216
  Image *map;
215
217
  unsigned int dither;
216
218
  volatile VALUE image, scene, new_imagelist;
@@ -225,19 +227,21 @@ ImageList_map(VALUE self, VALUE map_image, VALUE dither_arg)
225
227
  }
226
228
 
227
229
  // Convert image array to image sequence, clone image sequence.
228
- images = rm_images_from_imagelist(self);
229
230
  GetExceptionInfo(&exception);
230
- clone_images = CloneImageList(images, &exception);
231
+
232
+ images = rm_images_from_imagelist(self);
233
+ new_images = CloneImageList(images, &exception);
231
234
  rm_split(images);
232
- HANDLE_ERROR
235
+ rm_check_exception(&exception, new_images, DestroyOnError);
236
+ rm_ensure_result(new_images);
233
237
 
234
238
  // Call ImageMagick
235
239
  dither = !(dither_arg == Qfalse || dither_arg == Qnil);
236
- (void) MapImages(clone_images, map, dither);
237
- HANDLE_ERROR_IMG(clone_images)
240
+ (void) MapImages(new_images, map, dither);
241
+ rm_check_image_exception(new_images, DestroyOnError);
238
242
 
239
243
  // Set @scene in new ImageList object to same value as in self.
240
- new_imagelist = rm_imagelist_from_images(clone_images);
244
+ new_imagelist = rm_imagelist_from_images(new_images);
241
245
  scene = rb_iv_get(self, "@scene");
242
246
  (void) rm_imagelist_scene_eq(new_imagelist, scene);
243
247
 
@@ -255,7 +259,7 @@ ImageList_montage(VALUE self)
255
259
  {
256
260
  volatile VALUE montage_obj;
257
261
  Montage *montage;
258
- Image *montage_seq, *image_list;
262
+ Image *new_images, *images;
259
263
  ExceptionInfo exception;
260
264
 
261
265
  // Create a new instance of the Magick::Montage class
@@ -269,13 +273,13 @@ ImageList_montage(VALUE self)
269
273
 
270
274
  Data_Get_Struct(montage_obj, Montage, montage);
271
275
 
272
- image_list = rm_images_from_imagelist(self);
276
+ images = rm_images_from_imagelist(self);
273
277
 
274
278
  // If app specified a non-default composition operator, use it for all images.
275
279
  if (montage->compose != UndefinedCompositeOp)
276
280
  {
277
281
  Image *i;
278
- for (i = image_list; i; i = GetNextImageInList(i))
282
+ for (i = images; i; i = GetNextImageInList(i))
279
283
  {
280
284
  i->compose = montage->compose;
281
285
  }
@@ -284,11 +288,12 @@ ImageList_montage(VALUE self)
284
288
  GetExceptionInfo(&exception);
285
289
 
286
290
  // MontageImage can return more than one image.
287
- montage_seq = MontageImages(image_list, montage->info, &exception);
288
- rm_split(image_list);
289
- HANDLE_ERROR
291
+ new_images = MontageImages(images, montage->info, &exception);
292
+ rm_split(images);
293
+ rm_check_exception(&exception, new_images, DestroyOnError);
294
+ rm_ensure_result(new_images);
290
295
 
291
- return rm_imagelist_from_images(montage_seq);
296
+ return rm_imagelist_from_images(new_images);
292
297
  }
293
298
 
294
299
  /*
@@ -322,7 +327,8 @@ ImageList_morph(VALUE self, VALUE nimages)
322
327
  GetExceptionInfo(&exception);
323
328
  new_images = MorphImages(images, (unsigned long)number_images, &exception);
324
329
  rm_split(images);
325
- HANDLE_ERROR
330
+ rm_check_exception(&exception, new_images, DestroyOnError);
331
+ rm_ensure_result(new_images);
326
332
 
327
333
  return rm_imagelist_from_images(new_images);
328
334
  }
@@ -342,11 +348,64 @@ ImageList_mosaic(VALUE self)
342
348
  GetExceptionInfo(&exception);
343
349
  new_image = MosaicImages(images, &exception);
344
350
  rm_split(images);
345
- HANDLE_ERROR
351
+ rm_check_exception(&exception, new_image, DestroyOnError);
352
+ rm_ensure_result(new_image);
346
353
 
347
354
  return rm_image_new(new_image);
348
355
  }
349
356
 
357
+
358
+ /*
359
+ Method: ImageList#optimize_layers
360
+ Purpose: Equivalent to -layers option in 6.2.6
361
+ Returns: a new imagelist
362
+ */
363
+ VALUE
364
+ ImageList_optimize_layers(VALUE self, VALUE method)
365
+ {
366
+ #if defined(HAVE_COMPAREIMAGELAYERS)
367
+ Image *images, *new_images;
368
+ MagickLayerMethod mthd;
369
+ ExceptionInfo exception;
370
+
371
+ images = rm_images_from_imagelist(self);
372
+ GetExceptionInfo(&exception);
373
+ VALUE_TO_ENUM(method, mthd, MagickLayerMethod);
374
+
375
+ switch (mthd)
376
+ {
377
+ #if defined(HAVE_COALESCELAYER)
378
+ case CoalesceLayer:
379
+ new_images = CoalesceImages(images, &exception);
380
+ break;
381
+ case DisposeLayer:
382
+ new_images = DisposeImages(images, &exception);
383
+ break;
384
+ #endif
385
+ case OptimizeLayer:
386
+ new_images = OptimizeImageLayers(images, &exception);
387
+ break;
388
+ case OptimizePlusLayer:
389
+ new_images = OptimizePlusImageLayers(images, &exception);
390
+ break;
391
+ default:
392
+ new_images = CompareImageLayers(images, mthd, &exception);
393
+ break;
394
+ }
395
+
396
+ rm_split(images);
397
+ rm_check_exception(&exception, new_images, DestroyOnError);
398
+ rm_ensure_result(new_images);
399
+
400
+ return rm_imagelist_from_images(new_images);
401
+
402
+ #else
403
+ rm_not_implemented();
404
+ return (VALUE)0;
405
+ #endif
406
+ }
407
+
408
+
350
409
  /*
351
410
  External: rm_imagelist_new
352
411
  Purpose: create a new ImageList object with no images
@@ -371,6 +430,11 @@ rm_imagelist_from_images(Image *images)
371
430
  volatile VALUE new_imagelist;
372
431
  Image *image;
373
432
 
433
+ if (!images)
434
+ {
435
+ rb_bug("rm_imagelist_from_images called with NULL argument");
436
+ }
437
+
374
438
  new_imagelist = rm_imagelist_new();
375
439
 
376
440
  while (images)
@@ -498,9 +562,12 @@ ImageList_quantize(int argc, VALUE *argv, VALUE self)
498
562
  images = rm_images_from_imagelist(self);
499
563
  new_images = CloneImageList(images, &exception);
500
564
  rm_split(images);
501
- HANDLE_ERROR
565
+ rm_check_exception(&exception, new_images, DestroyOnError);
566
+ rm_ensure_result(new_images);
567
+
502
568
 
503
569
  QuantizeImages(&quantize_info, new_images);
570
+ rm_check_exception(&exception, new_images, DestroyOnError);
504
571
 
505
572
  // Create new ImageList object, convert mapped image sequence to images,
506
573
  // append to images array.
@@ -529,7 +596,7 @@ ImageList_to_blob(VALUE self)
529
596
  Image *images;
530
597
  Info *info;
531
598
  volatile VALUE info_obj;
532
- volatile VALUE blob_str;
599
+ volatile VALUE blob_str;
533
600
  void *blob = NULL;
534
601
  size_t length = 0;
535
602
  ExceptionInfo exception;
@@ -542,7 +609,8 @@ ImageList_to_blob(VALUE self)
542
609
 
543
610
  GetExceptionInfo(&exception);
544
611
  (void) SetImageInfo(info, True, &exception);
545
- HANDLE_ERROR
612
+ CHECK_EXCEPTION()
613
+
546
614
  if (*info->magick != '\0')
547
615
  {
548
616
  Image *img;
@@ -562,8 +630,12 @@ ImageList_to_blob(VALUE self)
562
630
  #else
563
631
  blob = ImageToBlob(info, images, &length, &exception);
564
632
  #endif
633
+ if (exception.severity != UndefinedException)
634
+ {
635
+ magick_free((void*)blob);
636
+ }
565
637
  rm_split(images);
566
- HANDLE_ERROR
638
+ CHECK_EXCEPTION()
567
639
 
568
640
  if (length == 0 || !blob)
569
641
  {
@@ -571,7 +643,7 @@ ImageList_to_blob(VALUE self)
571
643
  }
572
644
 
573
645
  blob_str = rb_str_new(blob, length);
574
- magick_free((void*)blob);
646
+ magick_free((void*)blob);
575
647
 
576
648
  return blob_str;
577
649
  }
@@ -649,7 +721,7 @@ ImageList_write(VALUE self, VALUE file)
649
721
 
650
722
  // Find out if the format supports multi-images files.
651
723
  m = GetMagickInfo(info->magick, &exception);
652
- HANDLE_ERROR
724
+ CHECK_EXCEPTION()
653
725
 
654
726
  // Tell WriteImage if we want a multi-images file.
655
727
  if (rm_imagelist_length(self) > 1 && m->adjoin)
@@ -661,7 +733,7 @@ ImageList_write(VALUE self, VALUE file)
661
733
  {
662
734
  (void) WriteImage(info, img);
663
735
  // images will be split before raising an exception
664
- rm_handle_all_errors(images);
736
+ rm_check_image_exception(images, RetainOnError);
665
737
  if (info->adjoin)
666
738
  {
667
739
  break;