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
- /* $Id: rmimage.c,v 1.142 2006/02/24 00:15:03 rmagick Exp $ */
1
+ /* $Id: rmimage.c,v 1.145 2006/05/07 21:41:12 rmagick Exp $ */
2
2
  /*============================================================================\
3
3
  | Copyright (C) 2006 by Timothy P. Hunter
4
4
  | Name: rmimage.c
@@ -66,10 +66,12 @@ Image_adaptive_threshold(int argc, VALUE *argv, VALUE self)
66
66
  }
67
67
 
68
68
  Data_Get_Struct(self, Image, image);
69
- GetExceptionInfo(&exception);
70
69
 
70
+ GetExceptionInfo(&exception);
71
71
  new_image = AdaptiveThresholdImage(image, width, height, offset, &exception);
72
- HANDLE_ERROR
72
+ rm_check_exception(&exception, new_image, DestroyOnError);
73
+ rm_ensure_result(new_image);
74
+
73
75
  return rm_image_new(new_image);
74
76
  }
75
77
 
@@ -87,11 +89,13 @@ Image_add_noise(VALUE self, VALUE noise)
87
89
 
88
90
  Data_Get_Struct(self, Image, image);
89
91
 
90
- GetExceptionInfo(&exception);
91
92
  VALUE_TO_ENUM(noise, noise_type, NoiseType);
92
93
 
94
+ GetExceptionInfo(&exception);
93
95
  new_image = AddNoiseImage(image, noise_type, &exception);
94
- HANDLE_ERROR
96
+ rm_check_exception(&exception, new_image, DestroyOnError);
97
+ rm_ensure_result(new_image);
98
+
95
99
  return rm_image_new(new_image);
96
100
  }
97
101
 
@@ -122,12 +126,15 @@ Image_add_noise_channel(int argc, VALUE *argv, VALUE self)
122
126
  }
123
127
 
124
128
  Data_Get_Struct(self, Image, image);
125
- GetExceptionInfo(&exception);
129
+
126
130
  VALUE_TO_ENUM(argv[0], noise_type, NoiseType);
127
131
  channels &= ~OpacityChannel;
128
132
 
133
+ GetExceptionInfo(&exception);
129
134
  new_image = AddNoiseImageChannel(image, channels, noise_type, &exception);
130
- HANDLE_ERROR
135
+ rm_check_exception(&exception, new_image, DestroyOnError);
136
+ rm_ensure_result(new_image);
137
+
131
138
  return rm_image_new(new_image);
132
139
 
133
140
  #else
@@ -155,7 +162,9 @@ Image_affine_transform(VALUE self, VALUE affine)
155
162
 
156
163
  GetExceptionInfo(&exception);
157
164
  new_image = AffineTransformImage(image, &matrix, &exception);
158
- HANDLE_ERROR
165
+ rm_check_exception(&exception, new_image, DestroyOnError);
166
+ rm_ensure_result(new_image);
167
+
159
168
  return rm_image_new(new_image);
160
169
  }
161
170
 
@@ -269,8 +278,7 @@ Image_aset(VALUE self, VALUE key_arg, VALUE attr_arg)
269
278
  okay = SetImageAttribute(image, key, attr);
270
279
  if (!okay)
271
280
  {
272
- rb_warning("RMagick: SetImageAttribute failed "
273
- "(probably out of memory)");
281
+ rb_warning("SetImageAttribute failed (probably out of memory)");
274
282
  }
275
283
  }
276
284
  return self;
@@ -361,7 +369,6 @@ Image_bilevel_channel(int argc, VALUE *argv, VALUE self)
361
369
  #if defined(HAVE_BILEVELIMAGECHANNEL)
362
370
  Image *image, *new_image;
363
371
  ChannelType channels;
364
- ExceptionInfo exception;
365
372
 
366
373
  channels = extract_channels(&argc, argv);
367
374
 
@@ -374,12 +381,11 @@ Image_bilevel_channel(int argc, VALUE *argv, VALUE self)
374
381
  rb_raise(rb_eArgError, "no threshold specified");
375
382
  }
376
383
 
377
- GetExceptionInfo(&exception);
378
-
379
384
  Data_Get_Struct(self, Image, image);
380
- new_image = CloneImage(image, 0, 0, True, &exception);
385
+ new_image = rm_clone_image(image);
381
386
 
382
387
  (void)BilevelImageChannel(new_image, channels, NUM2DBL(argv[0]));
388
+ rm_check_image_exception(new_image, DestroyOnError);
383
389
 
384
390
  return rm_image_new(new_image);
385
391
 
@@ -442,7 +448,8 @@ Image_blur_channel(int argc, VALUE *argv, VALUE self)
442
448
 
443
449
  GetExceptionInfo(&exception);
444
450
  new_image = BlurImageChannel(image, channels, radius, sigma, &exception);
445
- HANDLE_ERROR
451
+ rm_check_exception(&exception, new_image, DestroyOnError);
452
+ rm_ensure_result(new_image);
446
453
 
447
454
  return rm_image_new(new_image);
448
455
  #else
@@ -493,7 +500,8 @@ static VALUE border(
493
500
 
494
501
  GetExceptionInfo(&exception);
495
502
  new_image = BorderImage(image, &rect, &exception);
496
- HANDLE_ERROR
503
+ rm_check_exception(&exception, new_image, DestroyOnError);
504
+ rm_ensure_result(new_image);
497
505
 
498
506
  if (bang)
499
507
  {
@@ -572,7 +580,8 @@ VALUE Image_bounding_box(VALUE self)
572
580
  Data_Get_Struct(self, Image, image);
573
581
  GetExceptionInfo(&exception);
574
582
  box = GetImageBoundingBox(image, &exception);
575
- HANDLE_ERROR
583
+ CHECK_EXCEPTION()
584
+
576
585
  return Rectangle_from_RectangleInfo(&box);
577
586
  }
578
587
 
@@ -629,7 +638,9 @@ Image_capture(
629
638
 
630
639
  // If an error occurs, IM will call our error handler and we raise an exception.
631
640
  image = XImportImage(image_info, &ximage_info);
632
- assert(image);
641
+ rm_check_image_exception(image, DestroyOnError);
642
+ rm_ensure_result(image);
643
+
633
644
 
634
645
  return rm_image_new(image);
635
646
  #else
@@ -729,21 +740,22 @@ Image_channel(VALUE self, VALUE channel_arg)
729
740
  {
730
741
  Image *image, *new_image;
731
742
  ChannelType channel;
732
- ExceptionInfo exception;
733
743
 
734
744
  Data_Get_Struct(self, Image, image);
735
745
 
736
746
  VALUE_TO_ENUM(channel_arg, channel, ChannelType);
737
747
 
738
- GetExceptionInfo(&exception);
739
- new_image = CloneImage(image, 0, 0, True, &exception);
740
- HANDLE_ERROR
748
+ new_image = rm_clone_image(image);
749
+
741
750
  #if defined(HAVE_SEPARATEIMAGECHANNEL)
742
751
  (void) SeparateImageChannel(new_image, channel);
743
752
  #else
744
753
  (void) ChannelImage(new_image, channel);
745
754
  #endif
746
- HANDLE_ERROR_IMG(new_image)
755
+
756
+ rm_check_image_exception(new_image, DestroyOnError);
757
+ rm_ensure_result(new_image);
758
+
747
759
  return rm_image_new(new_image);
748
760
  }
749
761
 
@@ -772,7 +784,7 @@ Image_channel_depth(int argc, VALUE *argv, VALUE self)
772
784
  GetExceptionInfo(&exception);
773
785
 
774
786
  channel_depth = GetImageChannelDepth(image, channels, &exception);
775
- HANDLE_ERROR
787
+ CHECK_EXCEPTION()
776
788
 
777
789
  return ULONG2NUM(channel_depth);
778
790
  #else
@@ -800,13 +812,10 @@ Image_channel_extrema(int argc, VALUE *argv, VALUE self)
800
812
  ChannelType channels;
801
813
  ExceptionInfo exception;
802
814
  unsigned long min, max;
803
- unsigned int okay;
804
815
  volatile VALUE ary;
805
816
 
806
817
  Data_Get_Struct(self, Image, image);
807
818
 
808
- GetExceptionInfo(&exception);
809
-
810
819
  channels = extract_channels(&argc, argv);
811
820
 
812
821
  // Ensure all arguments consumed.
@@ -815,13 +824,9 @@ Image_channel_extrema(int argc, VALUE *argv, VALUE self)
815
824
  raise_ChannelType_error(argv[argc-1]);
816
825
  }
817
826
 
818
- okay = GetImageChannelExtrema(image, channels, &min, &max, &exception);
819
- if (!okay)
820
- {
821
- rb_raise(rb_eRuntimeError, "GetImageChannelExtrema failed.");
822
- }
823
-
824
- HANDLE_ERROR
827
+ GetExceptionInfo(&exception);
828
+ (void) GetImageChannelExtrema(image, channels, &min, &max, &exception);
829
+ CHECK_EXCEPTION()
825
830
 
826
831
  ary = rb_ary_new2(2);
827
832
  rb_ary_store(ary, 0, ULONG2NUM(min));
@@ -836,7 +841,6 @@ Image_channel_extrema(int argc, VALUE *argv, VALUE self)
836
841
  ExceptionInfo exception;
837
842
  volatile VALUE ary;
838
843
  volatile VALUE type_name;
839
- MagickPassFail okay;
840
844
 
841
845
  if (argc == 0)
842
846
  {
@@ -858,12 +862,9 @@ Image_channel_extrema(int argc, VALUE *argv, VALUE self)
858
862
 
859
863
  GetExceptionInfo(&exception);
860
864
 
861
- okay = GetImageStatistics(image, &stats, &exception);
862
- HANDLE_ERROR
863
- if (okay == MagickFail)
864
- {
865
- rb_raise(rb_eRuntimeError, "GetImageStatistics failed.");
866
- }
865
+ (void) GetImageStatistics(image, &stats, &exception);
866
+ CHECK_EXCEPTION()
867
+
867
868
 
868
869
  ary = rb_ary_new2(2);
869
870
  switch(channel)
@@ -916,11 +917,9 @@ Image_channel_mean(int argc, VALUE *argv, VALUE self)
916
917
  ChannelType channels;
917
918
  ExceptionInfo exception;
918
919
  double mean, stddev;
919
- unsigned int okay;
920
920
  volatile VALUE ary;
921
921
 
922
922
  Data_Get_Struct(self, Image, image);
923
- GetExceptionInfo(&exception);
924
923
 
925
924
  channels = extract_channels(&argc, argv);
926
925
 
@@ -930,13 +929,9 @@ Image_channel_mean(int argc, VALUE *argv, VALUE self)
930
929
  raise_ChannelType_error(argv[argc-1]);
931
930
  }
932
931
 
933
- okay = GetImageChannelMean(image, channels, &mean, &stddev, &exception);
934
- if (!okay)
935
- {
936
- rb_raise(rb_eRuntimeError, "GetImageChannelMean failed.");
937
- }
938
-
939
- HANDLE_ERROR
932
+ GetExceptionInfo(&exception);
933
+ (void) GetImageChannelMean(image, channels, &mean, &stddev, &exception);
934
+ CHECK_EXCEPTION()
940
935
 
941
936
  ary = rb_ary_new2(2);
942
937
  rb_ary_store(ary, 0, rb_float_new(mean));
@@ -951,7 +946,6 @@ Image_channel_mean(int argc, VALUE *argv, VALUE self)
951
946
  ExceptionInfo exception;
952
947
  volatile VALUE ary;
953
948
  volatile VALUE type_name;
954
- MagickPassFail okay;
955
949
 
956
950
  if (argc == 0)
957
951
  {
@@ -973,12 +967,8 @@ Image_channel_mean(int argc, VALUE *argv, VALUE self)
973
967
 
974
968
  GetExceptionInfo(&exception);
975
969
 
976
- okay = GetImageStatistics(image, &stats, &exception);
977
- HANDLE_ERROR
978
- if (okay == MagickFail)
979
- {
980
- rb_raise(rb_eRuntimeError, "GetImageStatistics failed.");
981
- }
970
+ (void) GetImageStatistics(image, &stats, &exception);
971
+ CHECK_EXCEPTION()
982
972
 
983
973
  ary = rb_ary_new2(2);
984
974
  switch(channel)
@@ -1110,7 +1100,6 @@ Image_clip_mask_eq(VALUE self, VALUE mask)
1110
1100
  {
1111
1101
  Image *image, *mask_image;
1112
1102
  Image *clip_mask;
1113
- ExceptionInfo exception;
1114
1103
 
1115
1104
  rm_check_frozen(self);
1116
1105
  Data_Get_Struct(self, Image, image);
@@ -1118,15 +1107,13 @@ Image_clip_mask_eq(VALUE self, VALUE mask)
1118
1107
  if (mask != Qnil)
1119
1108
  {
1120
1109
  Data_Get_Struct(ImageList_cur_image(mask), Image, mask_image);
1121
- GetExceptionInfo(&exception);
1122
- clip_mask = CloneImage(mask_image, 0, 0, 1, &exception);
1123
- HANDLE_ERROR
1124
- SetImageClipMask(image, clip_mask);
1125
- HANDLE_ERROR_IMG(mask_image)
1110
+ clip_mask = rm_clone_image(mask_image);
1111
+
1112
+ (void) SetImageClipMask(image, clip_mask);
1126
1113
  }
1127
1114
  else
1128
1115
  {
1129
- SetImageClipMask(image, NULL);
1116
+ (void) SetImageClipMask(image, NULL);
1130
1117
  }
1131
1118
 
1132
1119
  return self;
@@ -1167,10 +1154,10 @@ Image_color_histogram(VALUE self)
1167
1154
  ExceptionInfo exception;
1168
1155
 
1169
1156
  Data_Get_Struct(self, Image, image);
1170
- GetExceptionInfo(&exception);
1171
1157
 
1158
+ GetExceptionInfo(&exception);
1172
1159
  histogram = GetColorHistogram(image, &colors, &exception);
1173
- HANDLE_ERROR
1160
+ CHECK_EXCEPTION()
1174
1161
 
1175
1162
  hash = rb_hash_new();
1176
1163
  for (x = 0; x < colors; x++)
@@ -1196,13 +1183,11 @@ Image_color_histogram(VALUE self)
1196
1183
  ExceptionInfo exception;
1197
1184
 
1198
1185
  Data_Get_Struct(self, Image, image);
1199
- GetExceptionInfo(&exception);
1200
1186
 
1201
1187
  // If image not DirectClass make a DirectClass copy.
1202
1188
  if (image->storage_class != DirectClass)
1203
1189
  {
1204
- dc_copy = CloneImage(image, 0, 0, True, &exception);
1205
- HANDLE_ERROR
1190
+ dc_copy = rm_clone_image(image);
1206
1191
  SyncImage(dc_copy);
1207
1192
  magick_free(dc_copy->colormap);
1208
1193
  dc_copy->colormap = NULL;
@@ -1210,16 +1195,23 @@ Image_color_histogram(VALUE self)
1210
1195
  image = dc_copy;
1211
1196
  }
1212
1197
 
1198
+ GetExceptionInfo(&exception);
1213
1199
  histogram = GetImageHistogram(image, &colors, &exception);
1214
- if (dc_copy && (!histogram || exception.severity >= ErrorException))
1200
+
1201
+ if (histogram == NULL)
1215
1202
  {
1216
- DestroyImage(dc_copy);
1203
+ if (dc_copy)
1204
+ {
1205
+ DestroyImage(dc_copy);
1206
+ }
1207
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
1217
1208
  }
1218
- if (!histogram)
1209
+ if (exception.severity != UndefinedException)
1219
1210
  {
1220
- rb_raise(rb_eNoMemError, "not enough memory to continue");
1211
+ RelinquishMagickMemory(histogram);
1212
+ rm_check_exception(&exception, dc_copy, DestroyOnError);
1221
1213
  }
1222
- HANDLE_ERROR
1214
+
1223
1215
 
1224
1216
  hash = rb_hash_new();
1225
1217
  for (x = 0; x < colors; x++)
@@ -1443,14 +1435,9 @@ Image_color_flood_fill(
1443
1435
  PixelPacket fill;
1444
1436
  long x, y;
1445
1437
  int fill_method;
1446
- ExceptionInfo exception;
1447
1438
 
1448
1439
  Data_Get_Struct(self, Image, image);
1449
1440
 
1450
- GetExceptionInfo(&exception);
1451
- new_image = CloneImage(image, 0, 0, True, &exception);
1452
- HANDLE_ERROR
1453
-
1454
1441
  // The target and fill args can be either a color name or
1455
1442
  // a Magick::Pixel.
1456
1443
  Color_to_PixelPacket(&target, target_color);
@@ -1477,8 +1464,12 @@ Image_color_flood_fill(
1477
1464
  rb_raise(rb_eNoMemError, "not enough memory to continue");
1478
1465
  }
1479
1466
  draw_info->fill = fill;
1467
+
1468
+ new_image = rm_clone_image(image);
1469
+
1480
1470
  (void) ColorFloodfillImage(new_image, draw_info, target, x, y, (PaintMethod)fill_method);
1481
- HANDLE_ERROR_IMG(new_image)
1471
+ // No need to check for error
1472
+
1482
1473
  DestroyDrawInfo(draw_info);
1483
1474
  return rm_image_new(new_image);
1484
1475
  }
@@ -1527,7 +1518,8 @@ Image_colorize(
1527
1518
 
1528
1519
  GetExceptionInfo(&exception);
1529
1520
  new_image = ColorizeImage(image, opacity, target, &exception);
1530
- HANDLE_ERROR
1521
+ rm_check_exception(&exception, new_image, DestroyOnError);
1522
+ rm_ensure_result(new_image);
1531
1523
 
1532
1524
  return rm_image_new(new_image);
1533
1525
  }
@@ -1656,7 +1648,7 @@ Image_colorspace_eq(VALUE self, VALUE colorspace)
1656
1648
  // SetImageColorspace was introduced in 5.5.7. It is essentially
1657
1649
  // identical to the code below. It either works or throws an exception.
1658
1650
  (void) SetImageColorspace(image, new_cs);
1659
- HANDLE_ERROR_IMG(image)
1651
+ // No need to check for errors
1660
1652
 
1661
1653
  #else
1662
1654
 
@@ -1674,17 +1666,12 @@ Image_colorspace_eq(VALUE self, VALUE colorspace)
1674
1666
  image->colorspace != GRAYColorspace)
1675
1667
  {
1676
1668
  TransformRGBImage(image, image->colorspace);
1677
- HANDLE_ERROR_IMG(image)
1678
1669
  }
1679
1670
  RGBTransformImage(image, new_cs);
1680
- HANDLE_ERROR_IMG(image)
1681
1671
  }
1682
- else if (new_cs == RGBColorspace ||
1683
- new_cs == TransparentColorspace ||
1684
- new_cs == GRAYColorspace)
1672
+ else if (new_cs == RGBColorspace || new_cs == TransparentColorspace || new_cs == GRAYColorspace)
1685
1673
  {
1686
1674
  TransformRGBImage(image, image->colorspace);
1687
- HANDLE_ERROR_IMG(image)
1688
1675
  }
1689
1676
  #endif
1690
1677
 
@@ -1740,12 +1727,14 @@ VALUE Image_compare_channel(
1740
1727
 
1741
1728
  GetExceptionInfo(&exception);
1742
1729
  difference_image = CompareImageChannels(image
1743
- , r_image
1744
- , channels
1745
- , metric_type
1746
- , &distortion
1747
- , &exception);
1748
- HANDLE_ERROR
1730
+ , r_image
1731
+ , channels
1732
+ , metric_type
1733
+ , &distortion
1734
+ , &exception);
1735
+ rm_check_exception(&exception, difference_image, DestroyOnError);
1736
+ rm_ensure_result(difference_image);
1737
+
1749
1738
 
1750
1739
  ary = rb_ary_new2(2);
1751
1740
  rb_ary_store(ary, 0, rm_image_new(difference_image));
@@ -1813,7 +1802,6 @@ static VALUE composite(
1813
1802
  CompositeOperator operator;
1814
1803
  GravityType gravity;
1815
1804
  MagickEnum *magick_enum;
1816
- ExceptionInfo exception;
1817
1805
  signed long x_offset;
1818
1806
  signed long y_offset;
1819
1807
 
@@ -1916,16 +1904,16 @@ static VALUE composite(
1916
1904
  {
1917
1905
  rm_check_frozen(self);
1918
1906
  (void) CompositeImage(image, operator, comp_image, x_offset, y_offset);
1919
- HANDLE_ERROR_IMG(image)
1907
+ rm_check_image_exception(image, RetainOnError);
1920
1908
  return self;
1921
1909
  }
1922
1910
  else
1923
1911
  {
1924
- GetExceptionInfo(&exception);
1925
- new_image = CloneImage(image, 0, 0, True, &exception);
1926
- HANDLE_ERROR
1912
+ new_image = rm_clone_image(image);
1913
+
1927
1914
  (void) CompositeImage(new_image, operator, comp_image, x_offset, y_offset);
1928
- HANDLE_ERROR_IMG(new_image)
1915
+ rm_check_image_exception(new_image, DestroyOnError);
1916
+
1929
1917
  return rm_image_new(new_image);
1930
1918
  }
1931
1919
  }
@@ -1961,17 +1949,16 @@ Image_composite_affine(
1961
1949
  {
1962
1950
  Image *image, *composite, *new_image;
1963
1951
  AffineMatrix affine;
1964
- ExceptionInfo exception;
1965
1952
 
1966
1953
  Data_Get_Struct(self, Image, image);
1967
1954
  Data_Get_Struct(source, Image, composite);
1968
1955
 
1969
- GetExceptionInfo(&exception);
1970
- new_image = CloneImage(image, 0, 0, True, &exception);
1971
- HANDLE_ERROR
1956
+ new_image = rm_clone_image(image);
1957
+
1972
1958
  AffineMatrix_to_AffineMatrix(&affine, affine_matrix);
1973
1959
  (void) DrawAffineImage(new_image, composite, &affine);
1974
- HANDLE_ERROR_IMG(new_image)
1960
+ rm_check_image_exception(new_image, DestroyOnError);
1961
+
1975
1962
  return rm_image_new(new_image);
1976
1963
  }
1977
1964
 
@@ -2013,7 +2000,8 @@ Image_compress_colormap_bang(VALUE self)
2013
2000
  rm_check_frozen(self);
2014
2001
  Data_Get_Struct(self, Image, image);
2015
2002
  (void) CompressImageColormap(image);
2016
- HANDLE_ERROR_IMG(image)
2003
+ rm_check_image_exception(image, RetainOnError);
2004
+
2017
2005
  return self;
2018
2006
  }
2019
2007
 
@@ -2052,9 +2040,6 @@ Image_constitute(VALUE class, VALUE width_arg, VALUE height_arg
2052
2040
  } pixels;
2053
2041
  int type;
2054
2042
  StorageType stg_type;
2055
- #if defined(HAVE_IMPORTIMAGEPIXELS)
2056
- unsigned int okay;
2057
- #endif
2058
2043
 
2059
2044
  class = class; // Suppress "never referenced" message from icc
2060
2045
 
@@ -2142,22 +2127,16 @@ Image_constitute(VALUE class, VALUE width_arg, VALUE height_arg
2142
2127
  #else
2143
2128
  SetImage(image, OpaqueOpacity);
2144
2129
  #endif
2145
- okay = ImportImagePixels(image, 0, 0, width, height, map, stg_type, (void *)pixels.v);
2146
- if (!okay)
2147
- {
2148
- // Save exception info, delete the image, then raise the exception.
2149
- exception = image->exception;
2150
- DestroyImage(image);
2151
- HANDLE_ERROR
2152
- }
2130
+ (void) ImportImagePixels(image, 0, 0, width, height, map, stg_type, (void *)pixels.v);
2131
+ rm_check_image_exception(image, DestroyOnError);
2153
2132
  #else
2154
2133
  image = ConstituteImage(width, height, map, stg_type, (void *)pixels.v, &exception);
2134
+ rm_check_exception(&exception, image, DestroyOnError);
2155
2135
  #endif
2156
2136
 
2157
2137
  DestroyConstitute();
2158
2138
 
2159
2139
  xfree((void *)pixels.v);
2160
- HANDLE_ERROR
2161
2140
 
2162
2141
  return rm_image_new(image);
2163
2142
  }
@@ -2174,7 +2153,6 @@ VALUE
2174
2153
  Image_contrast(int argc, VALUE *argv, VALUE self)
2175
2154
  {
2176
2155
  Image *image, *new_image;
2177
- ExceptionInfo exception;
2178
2156
  unsigned int sharpen = 0;
2179
2157
 
2180
2158
  if (argc > 1)
@@ -2187,12 +2165,89 @@ Image_contrast(int argc, VALUE *argv, VALUE self)
2187
2165
  }
2188
2166
 
2189
2167
  Data_Get_Struct(self, Image, image);
2190
- GetExceptionInfo(&exception);
2191
- new_image = CloneImage(image, 0, 0, True, &exception);
2192
- HANDLE_ERROR
2168
+ new_image = rm_clone_image(image);
2169
+
2193
2170
  (void) ContrastImage(new_image, sharpen);
2194
- HANDLE_ERROR_IMG(new_image)
2171
+ rm_check_image_exception(new_image, DestroyOnError);
2172
+
2173
+ return rm_image_new(new_image);
2174
+ }
2175
+
2176
+ /*
2177
+ Method: Image#contrast_stretch_channel(black_point <, white_point> <, channel...>)
2178
+ Purpose: Call ContrastStretchImageChannel
2179
+ Notes: If white_point is not specified then it is #pixels-black_point.
2180
+ Both black_point and white_point can be specified as Floats
2181
+ or as percentages, i.e. "10%"
2182
+ */
2183
+ VALUE
2184
+ Image_contrast_stretch_channel(int argc, VALUE *argv, VALUE self)
2185
+ {
2186
+ #if defined(HAVE_CONTRASTSTRETCHIMAGECHANNEL)
2187
+ Image *image, *new_image;
2188
+ ChannelType channels;
2189
+ double black_point, white_point;
2190
+ unsigned long pixels;
2191
+
2192
+ channels = extract_channels(&argc, argv);
2193
+ if (argc > 2)
2194
+ {
2195
+ raise_ChannelType_error(argv[argc-1]);
2196
+ }
2197
+
2198
+ Data_Get_Struct(self, Image, image);
2199
+
2200
+ pixels = image->columns * image->rows;
2201
+
2202
+ switch (argc)
2203
+ {
2204
+ case 2:
2205
+ if (rm_check_num2dbl(argv[0]))
2206
+ {
2207
+ black_point = NUM2DBL(argv[0]);
2208
+ }
2209
+ else
2210
+ {
2211
+ black_point = pixels * rm_str_to_pct(argv[0]);
2212
+ }
2213
+ if (rm_check_num2dbl(argv[1]))
2214
+ {
2215
+ white_point = NUM2DBL(argv[1]);
2216
+ }
2217
+ else
2218
+ {
2219
+ white_point = pixels * rm_str_to_pct(argv[1]);
2220
+ }
2221
+ break;
2222
+
2223
+ case 1:
2224
+ if (rm_check_num2dbl(argv[0]))
2225
+ {
2226
+ black_point = NUM2DBL(argv[0]);
2227
+ }
2228
+ else
2229
+ {
2230
+ black_point = pixels * rm_str_to_pct(argv[0]);
2231
+ }
2232
+ white_point = (double) pixels - black_point;
2233
+ break;
2234
+
2235
+ default:
2236
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
2237
+ break;
2238
+ }
2239
+
2240
+ new_image = rm_clone_image(image);
2241
+
2242
+ (void) ContrastStretchImageChannel(new_image, channels, black_point, white_point);
2243
+ rm_check_image_exception(new_image, DestroyOnError);
2244
+
2195
2245
  return rm_image_new(new_image);
2246
+
2247
+ #else
2248
+ rm_not_implemented();
2249
+ return (VALUE)0;
2250
+ #endif
2196
2251
  }
2197
2252
 
2198
2253
  /*
@@ -2229,7 +2284,8 @@ Image_convolve(
2229
2284
 
2230
2285
  new_image = ConvolveImage(image, order, (double *)kernel, &exception);
2231
2286
  xfree((double *)kernel);
2232
- HANDLE_ERROR
2287
+ rm_check_exception(&exception, new_image, DestroyOnError);
2288
+ rm_ensure_result(new_image);
2233
2289
 
2234
2290
  return rm_image_new(new_image);
2235
2291
  }
@@ -2284,7 +2340,8 @@ Image_convolve_channel(
2284
2340
 
2285
2341
  new_image = ConvolveImageChannel(image, channels, order, (double *)kernel, &exception);
2286
2342
  xfree((double *)kernel);
2287
- HANDLE_ERROR
2343
+ rm_check_exception(&exception, new_image, DestroyOnError);
2344
+ rm_ensure_result(new_image);
2288
2345
 
2289
2346
  return rm_image_new(new_image);
2290
2347
  #else
@@ -2312,15 +2369,10 @@ Image_copy(VALUE self)
2312
2369
  VALUE
2313
2370
  Image_init_copy(VALUE copy, VALUE orig)
2314
2371
  {
2315
- Image *image, *clone;
2316
- ExceptionInfo exception;
2372
+ Image *image;
2317
2373
 
2318
2374
  Data_Get_Struct(orig, Image, image);
2319
-
2320
- GetExceptionInfo(&exception);
2321
- clone = CloneImage(image, 0, 0, True, &exception);
2322
- HANDLE_ERROR
2323
- DATA_PTR(copy) = clone;
2375
+ DATA_PTR(copy) = rm_clone_image(image);
2324
2376
 
2325
2377
  return copy;
2326
2378
  }
@@ -2359,11 +2411,11 @@ Image_cycle_colormap(VALUE self, VALUE amount)
2359
2411
  Data_Get_Struct(self, Image, image);
2360
2412
  GetExceptionInfo(&exception);
2361
2413
 
2362
- new_image = CloneImage(image, 0, 0, True, &exception);
2363
- HANDLE_ERROR
2414
+ new_image = rm_clone_image(image);
2364
2415
  amt = NUM2INT(amount);
2365
2416
  (void) CycleColormapImage(new_image, amt);
2366
- HANDLE_ERROR_IMG(new_image)
2417
+ // No need to check for an error
2418
+
2367
2419
  return rm_image_new(new_image);
2368
2420
  }
2369
2421
 
@@ -2470,7 +2522,8 @@ Image_depth(VALUE self)
2470
2522
  GetExceptionInfo(&exception);
2471
2523
 
2472
2524
  depth = GetImageDepth(image, &exception);
2473
- HANDLE_ERROR
2525
+ CHECK_EXCEPTION()
2526
+
2474
2527
  return INT2FIX(depth);
2475
2528
  }
2476
2529
 
@@ -2494,7 +2547,9 @@ Image_despeckle(VALUE self)
2494
2547
  GetExceptionInfo(&exception);
2495
2548
 
2496
2549
  new_image = DespeckleImage(image, &exception);
2497
- HANDLE_ERROR
2550
+ rm_check_exception(&exception, new_image, DestroyOnError);
2551
+ rm_ensure_result(new_image);
2552
+
2498
2553
  return rm_image_new(new_image);
2499
2554
  }
2500
2555
 
@@ -2517,8 +2572,7 @@ VALUE Image_difference(VALUE self, VALUE other)
2517
2572
  Data_Get_Struct(ImageList_cur_image(other), Image, image2);
2518
2573
 
2519
2574
  (void) IsImagesEqual(image, image2);
2520
- HANDLE_ERROR_IMG(image)
2521
- HANDLE_ERROR_IMG(image2)
2575
+ // No need to check for error
2522
2576
 
2523
2577
  mean = rb_float_new(image->error.mean_error_per_pixel);
2524
2578
  nmean = rb_float_new(image->error.normalized_mean_error);
@@ -2597,14 +2651,14 @@ Image_dispatch(int argc, VALUE *argv, VALUE self)
2597
2651
  DispatchImage
2598
2652
  #endif
2599
2653
  (image, x, y, columns, rows, map, stg_type, (void *)pixels.v, &exception);
2600
- HANDLE_ERROR
2601
2654
 
2602
2655
  if (!okay)
2603
2656
  {
2604
- xfree((void *)pixels.v);
2605
- return pixels_ary;
2657
+ goto exit;
2606
2658
  }
2607
2659
 
2660
+ CHECK_EXCEPTION()
2661
+
2608
2662
  // Convert the pixel data to the appropriate Ruby type
2609
2663
  if (stg_type == FIX_STG_TYPE)
2610
2664
  {
@@ -2621,6 +2675,7 @@ Image_dispatch(int argc, VALUE *argv, VALUE self)
2621
2675
  }
2622
2676
  }
2623
2677
 
2678
+ exit:
2624
2679
  xfree((void *)pixels.v);
2625
2680
  return pixels_ary;
2626
2681
  }
@@ -2634,7 +2689,6 @@ VALUE Image_display(VALUE self)
2634
2689
  Image *image;
2635
2690
  Info *info;
2636
2691
  volatile VALUE info_obj;
2637
- unsigned int ok;
2638
2692
 
2639
2693
  Data_Get_Struct(self, Image, image);
2640
2694
  if (image->rows == 0 || image->columns == 0)
@@ -2645,11 +2699,8 @@ VALUE Image_display(VALUE self)
2645
2699
  info_obj = rm_info_new();
2646
2700
  Data_Get_Struct(info_obj, Info, info);
2647
2701
 
2648
- ok = DisplayImages(info, image);
2649
- if (!ok)
2650
- {
2651
- HANDLE_ERROR_IMG(image)
2652
- }
2702
+ (void) DisplayImages(info, image);
2703
+ rm_check_image_exception(image, RetainOnError);
2653
2704
 
2654
2705
  return self;
2655
2706
  }
@@ -2714,8 +2765,7 @@ Image_distortion_channel(int argc, VALUE *argv, VALUE self)
2714
2765
  GetExceptionInfo(&exception);
2715
2766
  (void) GetImageChannelDistortion(image, reconstruct, channels
2716
2767
  , metric, &distortion, &exception);
2717
- HANDLE_ERROR_IMG(image)
2718
- HANDLE_ERROR
2768
+ CHECK_EXCEPTION()
2719
2769
 
2720
2770
  return rb_float_new(distortion);
2721
2771
  #else
@@ -2752,10 +2802,15 @@ Image__dump(VALUE self, VALUE depth)
2752
2802
  GetExceptionInfo(&exception);
2753
2803
  blob = ImageToBlob(info, image, &length, &exception);
2754
2804
 
2755
- // Free ImageInfo first - HANDLE_ERROR may raise an exception
2805
+ // Free ImageInfo first - error handling may raise an exception
2756
2806
  DestroyImageInfo(info);
2757
2807
 
2758
- HANDLE_ERROR
2808
+ CHECK_EXCEPTION()
2809
+
2810
+ if (!blob)
2811
+ {
2812
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
2813
+ }
2759
2814
 
2760
2815
  // Create a header for the blob: ID and version
2761
2816
  // numbers, followed by the length of the magick
@@ -2865,7 +2920,9 @@ Image_edge(int argc, VALUE *argv, VALUE self)
2865
2920
  GetExceptionInfo(&exception);
2866
2921
 
2867
2922
  new_image = EdgeImage(image, radius, &exception);
2868
- HANDLE_ERROR
2923
+ rm_check_exception(&exception, new_image, DestroyOnError);
2924
+ rm_ensure_result(new_image);
2925
+
2869
2926
  return rm_image_new(new_image);
2870
2927
  }
2871
2928
 
@@ -2905,7 +2962,9 @@ effect_image(
2905
2962
 
2906
2963
  GetExceptionInfo(&exception);
2907
2964
  new_image = (effector)(image, radius, sigma, &exception);
2908
- HANDLE_ERROR
2965
+ rm_check_exception(&exception, new_image, DestroyOnError);
2966
+ rm_ensure_result(new_image);
2967
+
2909
2968
  return rm_image_new(new_image);
2910
2969
  }
2911
2970
 
@@ -2961,9 +3020,13 @@ Image_enhance(VALUE self)
2961
3020
  ExceptionInfo exception;
2962
3021
 
2963
3022
  Data_Get_Struct(self, Image, image);
3023
+
2964
3024
  GetExceptionInfo(&exception);
3025
+
2965
3026
  new_image = EnhanceImage(image, &exception);
2966
- HANDLE_ERROR
3027
+ rm_check_exception(&exception, new_image, DestroyOnError);
3028
+ rm_ensure_result(new_image);
3029
+
2967
3030
  return rm_image_new(new_image);
2968
3031
  }
2969
3032
 
@@ -2976,17 +3039,14 @@ Image_equalize(VALUE self)
2976
3039
  {
2977
3040
  Image *image, *new_image;
2978
3041
  ExceptionInfo exception;
2979
- unsigned int okay;
2980
3042
 
2981
3043
  Data_Get_Struct(self, Image, image);
2982
3044
  GetExceptionInfo(&exception);
2983
- new_image = CloneImage(image, 0, 0, True, &exception);
2984
- HANDLE_ERROR
2985
- okay = EqualizeImage(new_image);
2986
- if (!okay)
2987
- {
2988
- rb_warning("RMagick: couldn't get equalization map");
2989
- }
3045
+ new_image = rm_clone_image(image);
3046
+
3047
+ (void) EqualizeImage(new_image);
3048
+ rm_check_image_exception(new_image, DestroyOnError);
3049
+
2990
3050
  return rm_image_new(new_image);
2991
3051
  }
2992
3052
 
@@ -3010,6 +3070,8 @@ Image_erase_bang(VALUE self)
3010
3070
  SetImage(image, OpaqueOpacity);
3011
3071
  #endif
3012
3072
 
3073
+ rm_check_image_exception(image, RetainOnError);
3074
+
3013
3075
  return self;
3014
3076
  }
3015
3077
 
@@ -3076,7 +3138,7 @@ Image_export_pixels(int argc, VALUE *argv, VALUE self)
3076
3138
  if (!okay)
3077
3139
  {
3078
3140
  xfree((unsigned int *)pixels);
3079
- HANDLE_ERROR
3141
+ CHECK_EXCEPTION()
3080
3142
  // Should never get here...
3081
3143
  rb_raise(rb_eStandardError, "ExportImagePixels failed with no explanation.");
3082
3144
  }
@@ -3197,7 +3259,7 @@ Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
3197
3259
  {
3198
3260
  // Let GC have the string buffer.
3199
3261
  rb_str_resize(string, 0);
3200
- HANDLE_ERROR
3262
+ CHECK_EXCEPTION()
3201
3263
  // Should never get here...
3202
3264
  rb_raise(rb_eStandardError, "ExportImagePixels failed with no explanation.");
3203
3265
  }
@@ -3305,7 +3367,8 @@ flipflop(int bang, VALUE self, flipper_t flipflopper)
3305
3367
  GetExceptionInfo(&exception);
3306
3368
 
3307
3369
  new_image = (flipflopper)(image, &exception);
3308
- HANDLE_ERROR
3370
+ rm_check_exception(&exception, new_image, DestroyOnError);
3371
+ rm_ensure_result(new_image);
3309
3372
 
3310
3373
  if (bang)
3311
3374
  {
@@ -3397,7 +3460,7 @@ Image_format_eq(VALUE self, VALUE magick)
3397
3460
 
3398
3461
  mgk = STRING_PTR(magick);
3399
3462
  m = GetMagickInfo(mgk, &exception);
3400
- HANDLE_ERROR
3463
+ CHECK_EXCEPTION()
3401
3464
 
3402
3465
  if (!m)
3403
3466
  {
@@ -3479,7 +3542,9 @@ Image_frame(int argc, VALUE *argv, VALUE self)
3479
3542
 
3480
3543
  GetExceptionInfo(&exception);
3481
3544
  new_image = FrameImage(image, &frame_info, &exception);
3482
- HANDLE_ERROR
3545
+ rm_check_exception(&exception, new_image, DestroyOnError);
3546
+ rm_ensure_result(new_image);
3547
+
3483
3548
  return rm_image_new(new_image);
3484
3549
  }
3485
3550
 
@@ -3506,7 +3571,8 @@ Image_from_blob(VALUE class, VALUE blob_arg)
3506
3571
 
3507
3572
  GetExceptionInfo(&exception);
3508
3573
  images = BlobToImage(info, blob, (size_t)length, &exception);
3509
- HANDLE_ERROR
3574
+ rm_check_exception(&exception, images, DestroyOnError);
3575
+ rm_ensure_result(images);
3510
3576
 
3511
3577
  return array_from_images(images);
3512
3578
  }
@@ -3542,7 +3608,6 @@ Image_gamma_channel(int argc, VALUE *argv, VALUE self)
3542
3608
  #if defined(HAVE_GAMMAIMAGECHANNEL)
3543
3609
  Image *image, *new_image;
3544
3610
  ChannelType channels;
3545
- ExceptionInfo exception;
3546
3611
 
3547
3612
  channels = extract_channels(&argc, argv);
3548
3613
 
@@ -3556,12 +3621,11 @@ Image_gamma_channel(int argc, VALUE *argv, VALUE self)
3556
3621
  raise_ChannelType_error(argv[argc-1]);
3557
3622
  }
3558
3623
 
3559
- GetExceptionInfo(&exception);
3560
-
3561
3624
  Data_Get_Struct(self, Image, image);
3562
- new_image = CloneImage(image, 0, 0, True, &exception);
3625
+ new_image = rm_clone_image(image);
3563
3626
 
3564
3627
  (void)GammaImageChannel(new_image, channels, NUM2DBL(argv[0]));
3628
+ rm_check_image_exception(new_image, DestroyOnError);
3565
3629
 
3566
3630
  return rm_image_new(new_image);
3567
3631
 
@@ -3584,7 +3648,6 @@ Image_gamma_correct(int argc, VALUE *argv, VALUE self)
3584
3648
  {
3585
3649
  Image *image, *new_image;
3586
3650
  double red_gamma, green_gamma, blue_gamma, opacity_gamma;
3587
- ExceptionInfo exception;
3588
3651
  char gamma[50];
3589
3652
 
3590
3653
  switch(argc)
@@ -3624,12 +3687,12 @@ Image_gamma_correct(int argc, VALUE *argv, VALUE self)
3624
3687
 
3625
3688
  sprintf(gamma, "%f,%f,%f,%f", red_gamma, green_gamma, blue_gamma, opacity_gamma);
3626
3689
  Data_Get_Struct(self, Image, image);
3627
- GetExceptionInfo(&exception);
3628
3690
 
3629
- new_image = CloneImage(image, 0, 0, True, &exception);
3630
- HANDLE_ERROR
3691
+ new_image = rm_clone_image(image);
3692
+
3631
3693
  (void) GammaImage(new_image, gamma);
3632
- HANDLE_ERROR_IMG(new_image)
3694
+ rm_check_image_exception(new_image, DestroyOnError);
3695
+
3633
3696
  return rm_image_new(new_image);
3634
3697
  }
3635
3698
 
@@ -3679,7 +3742,7 @@ Image_gaussian_blur_channel(int argc, VALUE *argv, VALUE self)
3679
3742
 
3680
3743
  Data_Get_Struct(self, Image, image);
3681
3744
  new_image = GaussianBlurImageChannel(image, channels, radius, sigma, &exception);
3682
- HANDLE_ERROR
3745
+ rm_check_exception(&exception, new_image, DestroyOnError);
3683
3746
 
3684
3747
  return rm_image_new(new_image);
3685
3748
 
@@ -3767,7 +3830,7 @@ Image_get_pixels(
3767
3830
  // to change the pixels but I don't want to make "pixels" const.
3768
3831
  GetExceptionInfo(&exception);
3769
3832
  pixels = (PixelPacket *)AcquireImagePixels(image, x, y, columns, rows, &exception);
3770
- HANDLE_ERROR
3833
+ CHECK_EXCEPTION()
3771
3834
 
3772
3835
  // If the function failed, return a 0-length array.
3773
3836
  if (!pixels)
@@ -3807,7 +3870,8 @@ Image_get_one_pixel(VALUE self, VALUE x, VALUE y)
3807
3870
  Data_Get_Struct(self, Image, image);
3808
3871
  GetExceptionInfo(&exception);
3809
3872
  pixel = AcquireOnePixel(image, NUM2LONG(x), NUM2LONG(y), &exception);
3810
- HANDLE_ERROR
3873
+ CHECK_EXCEPTION()
3874
+
3811
3875
  return Pixel_from_PixelPacket(&pixel);
3812
3876
  }
3813
3877
  #endif
@@ -3828,7 +3892,8 @@ Image_gray_q(VALUE self)
3828
3892
  GetExceptionInfo(&exception);
3829
3893
 
3830
3894
  r = IsGrayImage(image, &exception);
3831
- HANDLE_ERROR
3895
+ CHECK_EXCEPTION()
3896
+
3832
3897
  return r ? Qtrue : Qfalse;
3833
3898
  }
3834
3899
 
@@ -3842,7 +3907,6 @@ Image_grayscale_pseudo_class(int argc, VALUE *argv, VALUE self)
3842
3907
  #if defined(HAVE_GRAYSCALEPSEUDOCLASSIMAGE)
3843
3908
  Image *image, *new_image;
3844
3909
  unsigned int optimize = True;
3845
- ExceptionInfo exception;
3846
3910
 
3847
3911
  switch(argc)
3848
3912
  {
@@ -3857,11 +3921,10 @@ Image_grayscale_pseudo_class(int argc, VALUE *argv, VALUE self)
3857
3921
 
3858
3922
  Data_Get_Struct(self, Image, image);
3859
3923
 
3860
- GetExceptionInfo(&exception);
3861
- new_image = CloneImage(image, 0, 0, True, &exception);
3862
- HANDLE_ERROR
3924
+ new_image = rm_clone_image(image);
3863
3925
 
3864
3926
  GrayscalePseudoClassImage(new_image, optimize);
3927
+ rm_check_image_exception(new_image, DestroyOnError);
3865
3928
 
3866
3929
  return rm_image_new(new_image);
3867
3930
 
@@ -3899,7 +3962,9 @@ Image_implode(int argc, VALUE *argv, VALUE self)
3899
3962
  GetExceptionInfo(&exception);
3900
3963
 
3901
3964
  new_image = ImplodeImage(image, amount, &exception);
3902
- HANDLE_ERROR
3965
+ rm_check_exception(&exception, new_image, DestroyOnError);
3966
+ rm_ensure_result(new_image);
3967
+
3903
3968
  return rm_image_new(new_image);
3904
3969
  }
3905
3970
 
@@ -4066,7 +4131,7 @@ Image_import_pixels(int argc, VALUE *argv, VALUE self)
4066
4131
 
4067
4132
  if (!okay)
4068
4133
  {
4069
- HANDLE_ERROR_IMG(image)
4134
+ rm_check_image_exception(image, RetainOnError);
4070
4135
  // Shouldn't get here...
4071
4136
  rb_raise(rb_eStandardError, "ImportImagePixels failed with no explanation.");
4072
4137
  }
@@ -4417,7 +4482,7 @@ Image_iptc_profile_eq(VALUE self, VALUE profile)
4417
4482
  DEF_ATTR_ACCESSOR(Image, iterations, int)
4418
4483
 
4419
4484
  /*
4420
- Method: Image#level(black_point=0.0, mid_point=1.0, white_point=MaxRGB)
4485
+ Method: Image#level(black_point=0.0, white_point=MaxRGB, gamma=1.0)
4421
4486
  Purpose: adjusts the levels of an image given these points: black, mid, and white
4422
4487
  Notes: all three arguments are optional
4423
4488
  */
@@ -4425,8 +4490,7 @@ VALUE
4425
4490
  Image_level(int argc, VALUE *argv, VALUE self)
4426
4491
  {
4427
4492
  Image *image, *new_image;
4428
- double black_point = 0.0, mid_point = 1.0, white_point = (double)MaxRGB;
4429
- ExceptionInfo exception;
4493
+ double black_point = 0.0, gamma = 1.0, white_point = (double)MaxRGB;
4430
4494
  char level[50];
4431
4495
 
4432
4496
  switch(argc)
@@ -4439,13 +4503,12 @@ Image_level(int argc, VALUE *argv, VALUE self)
4439
4503
  break;
4440
4504
  case 2:
4441
4505
  black_point = NUM2DBL(argv[0]);
4442
- mid_point = NUM2DBL(argv[1]);
4443
- white_point = MaxRGB - black_point;
4506
+ white_point = NUM2DBL(argv[1]);
4444
4507
  break;
4445
4508
  case 3:
4446
4509
  black_point = NUM2DBL(argv[0]);
4447
- mid_point = NUM2DBL(argv[1]);
4448
- white_point = NUM2DBL(argv[2]);
4510
+ white_point = NUM2DBL(argv[1]);
4511
+ gamma = NUM2DBL(argv[2]);
4449
4512
  break;
4450
4513
  default:
4451
4514
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
@@ -4453,27 +4516,27 @@ Image_level(int argc, VALUE *argv, VALUE self)
4453
4516
  }
4454
4517
 
4455
4518
  Data_Get_Struct(self, Image, image);
4456
- GetExceptionInfo(&exception);
4457
- new_image = CloneImage(image, 0, 0, True, &exception);
4458
- HANDLE_ERROR
4459
- sprintf(level, "%f,%f,%f", black_point, mid_point, white_point);
4519
+
4520
+ new_image = rm_clone_image(image);
4521
+
4522
+ sprintf(level, "%gx%g+%g", black_point, white_point, gamma);
4460
4523
  (void) LevelImage(new_image, level);
4461
- HANDLE_ERROR_IMG(new_image)
4524
+ rm_check_image_exception(new_image, DestroyOnError);
4525
+
4462
4526
  return rm_image_new(new_image);
4463
4527
  }
4464
4528
 
4465
4529
  /*
4466
- Method: Image#level_channel(aChannelType, black=0, mid=1.0, white=MaxRGB)
4530
+ Method: Image#level_channel(aChannelType, black=0, white=MaxRGB, gamma=1.0)
4467
4531
  Purpose: similar to Image#level but applies to a single channel only
4468
- Notes: black and white are 0-MaxRGB, mid is 0-10.
4532
+ Notes: black and white are 0-MaxRGB, gamma is 0-10.
4469
4533
  */
4470
4534
  VALUE
4471
4535
  Image_level_channel(int argc, VALUE *argv, VALUE self)
4472
4536
  {
4473
4537
  Image *image, *new_image;
4474
- double black_point = 0.0, mid_point = 1.0, white_point = (double)MaxRGB;
4538
+ double black_point = 0.0, gamma = 1.0, white_point = (double)MaxRGB;
4475
4539
  ChannelType channel;
4476
- ExceptionInfo exception;
4477
4540
 
4478
4541
  switch(argc)
4479
4542
  {
@@ -4485,13 +4548,12 @@ Image_level_channel(int argc, VALUE *argv, VALUE self)
4485
4548
  break;
4486
4549
  case 3:
4487
4550
  black_point = NUM2DBL(argv[1]);
4488
- mid_point = NUM2DBL(argv[2]);
4489
- white_point = MaxRGB - black_point;
4551
+ white_point = NUM2DBL(argv[2]);
4490
4552
  break;
4491
4553
  case 4:
4492
4554
  black_point = NUM2DBL(argv[1]);
4493
- mid_point = NUM2DBL(argv[2]);
4494
- white_point = NUM2DBL(argv[3]);
4555
+ white_point = NUM2DBL(argv[2]);
4556
+ gamma = NUM2DBL(argv[3]);
4495
4557
  break;
4496
4558
  default:
4497
4559
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
@@ -4500,16 +4562,12 @@ Image_level_channel(int argc, VALUE *argv, VALUE self)
4500
4562
 
4501
4563
  VALUE_TO_ENUM(argv[0], channel, ChannelType);
4502
4564
  Data_Get_Struct(self, Image, image);
4503
- GetExceptionInfo(&exception);
4504
- new_image = CloneImage(image, 0, 0, True, &exception);
4505
- HANDLE_ERROR
4506
-
4507
- (void) LevelImageChannel(new_image
4508
- , channel
4509
- , black_point
4510
- , mid_point
4511
- , white_point);
4512
- HANDLE_ERROR_IMG(new_image)
4565
+
4566
+ new_image = rm_clone_image(image);
4567
+
4568
+ (void) LevelImageChannel(new_image, channel, black_point, white_point, gamma);
4569
+ rm_check_image_exception(new_image, DestroyOnError);
4570
+
4513
4571
  return rm_image_new(new_image);
4514
4572
  }
4515
4573
 
@@ -4574,9 +4632,10 @@ Image__load(VALUE class, VALUE str)
4574
4632
  blob += offsetof(DumpedImage,magick) + mi.len;
4575
4633
  length -= offsetof(DumpedImage,magick) + mi.len;
4576
4634
  image = BlobToImage(info, blob, (size_t) length, &exception);
4577
-
4578
4635
  DestroyImageInfo(info);
4579
- HANDLE_ERROR
4636
+
4637
+ rm_check_exception(&exception, image, DestroyOnError);
4638
+ rm_ensure_result(image);
4580
4639
 
4581
4640
  return rm_image_new(image);
4582
4641
  }
@@ -4601,7 +4660,8 @@ magnify(int bang, VALUE self, magnifier_t magnifier)
4601
4660
  GetExceptionInfo(&exception);
4602
4661
 
4603
4662
  new_image = (magnifier)(image, &exception);
4604
- HANDLE_ERROR
4663
+ rm_check_exception(&exception, new_image, DestroyOnError);
4664
+ rm_ensure_result(new_image);
4605
4665
 
4606
4666
  if (bang)
4607
4667
  {
@@ -4637,7 +4697,6 @@ Image_map(int argc, VALUE *argv, VALUE self)
4637
4697
  {
4638
4698
  Image *image, *new_image;
4639
4699
  Image *map;
4640
- ExceptionInfo exception;
4641
4700
  volatile VALUE map_obj, map_arg;
4642
4701
  unsigned int dither = False;
4643
4702
 
@@ -4653,14 +4712,15 @@ Image_map(int argc, VALUE *argv, VALUE self)
4653
4712
  break;
4654
4713
  }
4655
4714
 
4656
- GetExceptionInfo(&exception);
4715
+
4657
4716
  Data_Get_Struct(self, Image, image);
4658
- new_image = CloneImage(image, 0, 0, True, &exception);
4659
- HANDLE_ERROR
4717
+ new_image = rm_clone_image(image);
4718
+
4660
4719
  map_obj = ImageList_cur_image(map_arg);
4661
4720
  Data_Get_Struct(map_obj, Image, map);
4662
4721
  (void) MapImage(new_image, map, dither);
4663
- HANDLE_ERROR_IMG(new_image)
4722
+ rm_check_image_exception(new_image, DestroyOnError);
4723
+
4664
4724
  return rm_image_new(new_image);
4665
4725
  }
4666
4726
 
@@ -4708,7 +4768,6 @@ Image_matte_flood_fill(
4708
4768
  VALUE method)
4709
4769
  {
4710
4770
  Image *image, *new_image;
4711
- ExceptionInfo exception;
4712
4771
  PixelPacket target;
4713
4772
  unsigned int op;
4714
4773
  long x, y;
@@ -4738,11 +4797,12 @@ Image_matte_flood_fill(
4738
4797
  , x, y, image->columns, image->rows);
4739
4798
  }
4740
4799
 
4741
- GetExceptionInfo(&exception);
4742
- new_image = CloneImage(image, 0, 0, True, &exception);
4743
- HANDLE_ERROR
4800
+
4801
+ new_image = rm_clone_image(image);
4802
+
4744
4803
  (void) MatteFloodfillImage(new_image, target, op, x, y, pm);
4745
- HANDLE_ERROR_IMG(new_image)
4804
+ rm_check_image_exception(new_image, DestroyOnError);
4805
+
4746
4806
  return rm_image_new(new_image);
4747
4807
  }
4748
4808
 
@@ -4775,7 +4835,9 @@ Image_median_filter(int argc, VALUE *argv, VALUE self)
4775
4835
  GetExceptionInfo(&exception);
4776
4836
 
4777
4837
  new_image = MedianFilterImage(image, radius, &exception);
4778
- HANDLE_ERROR
4838
+ rm_check_exception(&exception, new_image, DestroyOnError);
4839
+ rm_ensure_result(new_image);
4840
+
4779
4841
  return rm_image_new(new_image);
4780
4842
  }
4781
4843
 
@@ -4836,7 +4898,6 @@ VALUE
4836
4898
  Image_modulate(int argc, VALUE *argv, VALUE self)
4837
4899
  {
4838
4900
  Image *image, *new_image;
4839
- ExceptionInfo exception;
4840
4901
  double pct_brightness = 100.0,
4841
4902
  pct_saturation = 100.0,
4842
4903
  pct_hue = 100.0;
@@ -4864,11 +4925,12 @@ Image_modulate(int argc, VALUE *argv, VALUE self)
4864
4925
  }
4865
4926
  sprintf(modulate, "%f%%,%f%%,%f%%", pct_brightness, pct_saturation, pct_hue);
4866
4927
  Data_Get_Struct(self, Image, image);
4867
- GetExceptionInfo(&exception);
4868
- new_image = CloneImage(image, 0, 0, True, &exception);
4869
- HANDLE_ERROR
4928
+
4929
+ new_image = rm_clone_image(image);
4930
+
4870
4931
  (void) ModulateImage(new_image, modulate);
4871
- HANDLE_ERROR_IMG(new_image)
4932
+ rm_check_image_exception(new_image, DestroyOnError);
4933
+
4872
4934
  return rm_image_new(new_image);
4873
4935
  }
4874
4936
 
@@ -4926,7 +4988,8 @@ Image_monochrome_q(VALUE self)
4926
4988
  GetExceptionInfo(&exception);
4927
4989
 
4928
4990
  r = IsMonochromeImage(image, &exception);
4929
- HANDLE_ERROR
4991
+ CHECK_EXCEPTION()
4992
+
4930
4993
  return r ? Qtrue : Qfalse;
4931
4994
  }
4932
4995
 
@@ -4989,7 +5052,9 @@ Image_motion_blur(
4989
5052
 
4990
5053
  GetExceptionInfo(&exception);
4991
5054
  new_image = MotionBlurImage(image, radius, sigma, angle, &exception);
4992
- HANDLE_ERROR
5055
+ rm_check_exception(&exception, new_image, DestroyOnError);
5056
+ rm_ensure_result(new_image);
5057
+
4993
5058
  return rm_image_new(new_image);
4994
5059
  }
4995
5060
 
@@ -5004,7 +5069,6 @@ VALUE
5004
5069
  Image_negate(int argc, VALUE *argv, VALUE self)
5005
5070
  {
5006
5071
  Image *image, *new_image;
5007
- ExceptionInfo exception;
5008
5072
  unsigned int grayscale = False;
5009
5073
 
5010
5074
  if (argc == 1)
@@ -5017,11 +5081,12 @@ Image_negate(int argc, VALUE *argv, VALUE self)
5017
5081
  }
5018
5082
 
5019
5083
  Data_Get_Struct(self, Image, image);
5020
- GetExceptionInfo(&exception);
5021
- new_image = CloneImage(image, 0, 0, True, &exception);
5022
- HANDLE_ERROR
5084
+
5085
+ new_image = rm_clone_image(image);
5086
+
5023
5087
  (void) NegateImage(new_image, grayscale);
5024
- HANDLE_ERROR_IMG(new_image)
5088
+ rm_check_image_exception(new_image, DestroyOnError);
5089
+
5025
5090
  return rm_image_new(new_image);
5026
5091
  }
5027
5092
 
@@ -5037,7 +5102,6 @@ Image_negate_channel(int argc, VALUE *argv, VALUE self)
5037
5102
  #if defined(HAVE_NEGATEIMAGECHANNEL)
5038
5103
  Image *image, *new_image;
5039
5104
  ChannelType channels;
5040
- ExceptionInfo exception;
5041
5105
  unsigned int grayscale = False;
5042
5106
 
5043
5107
  channels = extract_channels(&argc, argv);
@@ -5052,13 +5116,12 @@ Image_negate_channel(int argc, VALUE *argv, VALUE self)
5052
5116
  grayscale = RTEST(argv[0]);
5053
5117
  }
5054
5118
 
5055
- GetExceptionInfo(&exception);
5056
-
5057
5119
  Data_Get_Struct(self, Image, image);
5058
- new_image = CloneImage(image, 0, 0, True, &exception);
5059
- HANDLE_ERROR
5120
+
5121
+ new_image = rm_clone_image(image);
5060
5122
 
5061
5123
  (void)NegateImageChannel(new_image, channels, grayscale);
5124
+ rm_check_image_exception(new_image, DestroyOnError);
5062
5125
 
5063
5126
  return rm_image_new(new_image);
5064
5127
 
@@ -5242,6 +5305,10 @@ Image_initialize(int argc, VALUE *argv, VALUE self)
5242
5305
  VALUE
5243
5306
  rm_image_new(Image *image)
5244
5307
  {
5308
+ if (!image)
5309
+ {
5310
+ rb_bug("rm_image_new called with NULL argument");
5311
+ }
5245
5312
  return Data_Wrap_Struct(Class_Image, NULL, DestroyImage, image);
5246
5313
  }
5247
5314
 
@@ -5254,18 +5321,14 @@ VALUE
5254
5321
  Image_normalize(VALUE self)
5255
5322
  {
5256
5323
  Image *image, *new_image;
5257
- ExceptionInfo exception;
5258
- unsigned int okay;
5259
5324
 
5260
5325
  Data_Get_Struct(self, Image, image);
5261
- GetExceptionInfo(&exception);
5262
- new_image = CloneImage(image, 0, 0, True, &exception);
5263
- HANDLE_ERROR
5264
- okay = NormalizeImage(new_image);
5265
- if (!okay)
5266
- {
5267
- rb_raise(rb_eRuntimeError, "NormalizeImage failed");
5268
- }
5326
+
5327
+ new_image = rm_clone_image(image);
5328
+
5329
+ (void) NormalizeImage(new_image);
5330
+ rm_check_image_exception(new_image, DestroyOnError);
5331
+
5269
5332
  return rm_image_new(new_image);
5270
5333
  }
5271
5334
 
@@ -5280,8 +5343,6 @@ Image_normalize_channel(int argc, VALUE *argv, VALUE self)
5280
5343
  #if defined(HAVE_NORMALIZEIMAGECHANNEL)
5281
5344
  Image *image, *new_image;
5282
5345
  ChannelType channels;
5283
- ExceptionInfo exception;
5284
- unsigned int okay;
5285
5346
 
5286
5347
  channels = extract_channels(&argc, argv);
5287
5348
  // Ensure all arguments consumed.
@@ -5291,15 +5352,12 @@ Image_normalize_channel(int argc, VALUE *argv, VALUE self)
5291
5352
  }
5292
5353
 
5293
5354
  Data_Get_Struct(self, Image, image);
5294
- GetExceptionInfo(&exception);
5295
- new_image = CloneImage(image, 0, 0, True, &exception);
5296
- HANDLE_ERROR
5297
5355
 
5298
- okay = NormalizeImageChannel(new_image, channels);
5299
- if (!okay)
5300
- {
5301
- rb_raise(rb_eRuntimeError, "NormalizeImageChannels failed");
5302
- }
5356
+ new_image = rm_clone_image(image);
5357
+
5358
+ (void) NormalizeImageChannel(new_image, channels);
5359
+ rm_check_image_exception(new_image, DestroyOnError);
5360
+
5303
5361
  return rm_image_new(new_image);
5304
5362
  #else
5305
5363
  rm_not_implemented();
@@ -5325,7 +5383,8 @@ Image_number_colors(VALUE self)
5325
5383
  GetExceptionInfo(&exception);
5326
5384
 
5327
5385
  n = (unsigned long) GetNumberColors(image, NULL, &exception);
5328
- HANDLE_ERROR
5386
+ CHECK_EXCEPTION()
5387
+
5329
5388
  return ULONG2NUM(n);
5330
5389
  }
5331
5390
 
@@ -5356,7 +5415,9 @@ Image_oil_paint(int argc, VALUE *argv, VALUE self)
5356
5415
  GetExceptionInfo(&exception);
5357
5416
 
5358
5417
  new_image = OilPaintImage(image, radius, &exception);
5359
- HANDLE_ERROR
5418
+ rm_check_exception(&exception, new_image, DestroyOnError);
5419
+ rm_ensure_result(new_image);
5420
+
5360
5421
  return rm_image_new(new_image);
5361
5422
  }
5362
5423
 
@@ -5372,22 +5433,20 @@ VALUE
5372
5433
  Image_opaque(VALUE self, VALUE target, VALUE fill)
5373
5434
  {
5374
5435
  Image *image, *new_image;
5375
- ExceptionInfo exception;
5376
5436
  PixelPacket target_pp;
5377
5437
  PixelPacket fill_pp;
5378
5438
 
5379
5439
  Data_Get_Struct(self, Image, image);
5380
5440
 
5381
- GetExceptionInfo(&exception);
5382
- new_image = CloneImage(image, 0, 0, True, &exception);
5383
- HANDLE_ERROR
5441
+ new_image = rm_clone_image(image);
5384
5442
 
5385
5443
  // Allow color name or Pixel
5386
5444
  Color_to_PixelPacket(&target_pp, target);
5387
5445
  Color_to_PixelPacket(&fill_pp, fill);
5388
5446
 
5389
5447
  (void) OpaqueImage(new_image, target_pp, fill_pp);
5390
- HANDLE_ERROR_IMG(new_image)
5448
+ rm_check_image_exception(new_image, DestroyOnError);
5449
+
5391
5450
  return rm_image_new(new_image);
5392
5451
  }
5393
5452
 
@@ -5407,7 +5466,8 @@ Image_opaque_q(VALUE self)
5407
5466
  GetExceptionInfo(&exception);
5408
5467
 
5409
5468
  r = IsOpaqueImage(image, &exception);
5410
- HANDLE_ERROR
5469
+ CHECK_EXCEPTION()
5470
+
5411
5471
  return r ? Qtrue : Qfalse;
5412
5472
  }
5413
5473
 
@@ -5450,16 +5510,18 @@ Image_ordered_dither(int argc, VALUE *argv, VALUE self)
5450
5510
 
5451
5511
 
5452
5512
  Data_Get_Struct(self, Image, image);
5513
+
5514
+ new_image = rm_clone_image(image);
5515
+
5453
5516
  GetExceptionInfo(&exception);
5454
5517
 
5455
- new_image = CloneImage(image, 0, 0, True, &exception);
5456
- HANDLE_ERROR
5457
5518
  #if defined(HAVE_RANDOMTHRESHOLDIMAGECHANNEL)
5458
5519
  (void) RandomThresholdImageChannel(new_image, AllChannels, thresholds, &exception);
5459
5520
  #else
5460
5521
  (void) RandomChannelThresholdImage(new_image, "all", thresholds, &exception);
5461
5522
  #endif
5462
- HANDLE_ERROR
5523
+ rm_check_exception(&exception, new_image, DestroyOnError);
5524
+
5463
5525
  return rm_image_new(new_image);
5464
5526
  }
5465
5527
 
@@ -5526,7 +5588,7 @@ Image_palette_q(VALUE self)
5526
5588
  GetExceptionInfo(&exception);
5527
5589
 
5528
5590
  r = IsPaletteImage(image, &exception);
5529
- HANDLE_ERROR
5591
+ CHECK_EXCEPTION()
5530
5592
 
5531
5593
  return r ? Qtrue : Qfalse;
5532
5594
  }
@@ -5589,7 +5651,7 @@ Image_pixel_color(
5589
5651
  {
5590
5652
  GetExceptionInfo(&exception);
5591
5653
  old_color = *AcquireImagePixels(image, x, y, 1, 1, &exception);
5592
- HANDLE_ERROR
5654
+ CHECK_EXCEPTION()
5593
5655
 
5594
5656
  // PseudoClass
5595
5657
  if (image->storage_class == PseudoClass)
@@ -5661,15 +5723,13 @@ Image_plasma(
5661
5723
  VALUE depth)
5662
5724
  {
5663
5725
  Image *image, *new_image;
5664
- ExceptionInfo exception;
5665
5726
  SegmentInfo segment;
5666
5727
  unsigned int okay;
5667
5728
 
5668
5729
  Data_Get_Struct(self, Image, image);
5669
- GetExceptionInfo(&exception);
5670
5730
 
5671
- new_image = CloneImage(image, 0, 0, True, &exception);
5672
- HANDLE_ERROR
5731
+ new_image = rm_clone_image(image);
5732
+
5673
5733
  segment.x1 = NUM2DBL(x1);
5674
5734
  segment.y1 = NUM2DBL(y1);
5675
5735
  segment.x2 = NUM2DBL(x2);
@@ -5697,8 +5757,6 @@ Image_posterize(int argc, VALUE *argv, VALUE self)
5697
5757
  Image *image, *new_image;
5698
5758
  MagickBooleanType dither = False;
5699
5759
  unsigned long levels = 4;
5700
- MagickBooleanType okay;
5701
- ExceptionInfo exception;
5702
5760
 
5703
5761
  switch(argc)
5704
5762
  {
@@ -5714,15 +5772,11 @@ Image_posterize(int argc, VALUE *argv, VALUE self)
5714
5772
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc);
5715
5773
  }
5716
5774
 
5717
- GetExceptionInfo(&exception);
5718
5775
  Data_Get_Struct(self, Image, image);
5719
- new_image = CloneImage(image, 0, 0, True, &exception);
5720
- HANDLE_ERROR
5721
- okay = PosterizeImage(new_image, levels, dither);
5722
- if (!okay)
5723
- {
5724
- rb_raise(rb_eRuntimeError, "PosterizeImage failed");
5725
- }
5776
+ new_image = rm_clone_image(image);
5777
+
5778
+ (void) PosterizeImage(new_image, levels, dither);
5779
+ rm_check_image_exception(new_image, DestroyOnError);
5726
5780
 
5727
5781
  return rm_image_new(new_image);
5728
5782
 
@@ -5750,7 +5804,8 @@ Image_preview(VALUE self, VALUE preview)
5750
5804
 
5751
5805
  Data_Get_Struct(self, Image, image);
5752
5806
  new_image = PreviewImage(image, preview_type, &exception);
5753
- HANDLE_ERROR
5807
+ rm_check_exception(&exception, new_image, DestroyOnError);
5808
+ rm_ensure_result(new_image);
5754
5809
 
5755
5810
  return rm_image_new(new_image);
5756
5811
  #else
@@ -5786,7 +5841,8 @@ Image_profile_bang(
5786
5841
  }
5787
5842
  (void) ProfileImage(image, STRING_PTR(name), (const unsigned char *)prof
5788
5843
  , (size_t)prof_l, True);
5789
- HANDLE_ERROR_IMG(image)
5844
+ rm_check_image_exception(image, RetainOnError);
5845
+
5790
5846
  return self;
5791
5847
  }
5792
5848
 
@@ -5817,6 +5873,9 @@ Image_quantum_depth(VALUE self)
5817
5873
  #else
5818
5874
  quantum_depth = GetImageQuantumDepth(image, MagickFalse);
5819
5875
  #endif
5876
+
5877
+ rm_check_image_exception(image, RetainOnError);
5878
+
5820
5879
  return ULONG2NUM(quantum_depth);
5821
5880
  #else
5822
5881
  rm_not_implemented();
@@ -5844,7 +5903,6 @@ Image_quantum_operator(int argc, VALUE *argv, VALUE self)
5844
5903
  QuantumOperator qop;
5845
5904
  ChannelType channel;
5846
5905
  double rvalue;
5847
- MagickPassFail okay;
5848
5906
  ExceptionInfo exception;
5849
5907
 
5850
5908
  Data_Get_Struct(self, Image, image);
@@ -5908,12 +5966,8 @@ Image_quantum_operator(int argc, VALUE *argv, VALUE self)
5908
5966
  }
5909
5967
 
5910
5968
  GetExceptionInfo(&exception);
5911
- okay = QuantumOperatorImage(image, channel, qop, rvalue, &exception);
5912
- HANDLE_ERROR
5913
- if (okay != MagickPass)
5914
- {
5915
- rb_raise(rb_eRuntimeError, "QuantumOperatorRegionImage failed.");
5916
- }
5969
+ (void) QuantumOperatorImage(image, channel, qop, rvalue, &exception);
5970
+ CHECK_EXCEPTION()
5917
5971
 
5918
5972
  return self;
5919
5973
 
@@ -5924,7 +5978,6 @@ Image_quantum_operator(int argc, VALUE *argv, VALUE self)
5924
5978
  double rvalue;
5925
5979
  ChannelType channel;
5926
5980
  ExceptionInfo exception;
5927
- unsigned int okay;
5928
5981
 
5929
5982
  Data_Get_Struct(self, Image, image);
5930
5983
 
@@ -5986,12 +6039,8 @@ Image_quantum_operator(int argc, VALUE *argv, VALUE self)
5986
6039
  }
5987
6040
 
5988
6041
  GetExceptionInfo(&exception);
5989
- okay = EvaluateImageChannel(image, channel, operator, rvalue, &exception);
5990
- HANDLE_ERROR
5991
- if (!okay)
5992
- {
5993
- rb_raise(rb_eRuntimeError, "EvaluateImageChannel failed.");
5994
- }
6042
+ (void) EvaluateImageChannel(image, channel, operator, rvalue, &exception);
6043
+ CHECK_EXCEPTION()
5995
6044
 
5996
6045
  return self;
5997
6046
 
@@ -6011,7 +6060,6 @@ VALUE
6011
6060
  Image_quantize(int argc, VALUE *argv, VALUE self)
6012
6061
  {
6013
6062
  Image *image, *new_image;
6014
- ExceptionInfo exception;
6015
6063
  QuantizeInfo quantize_info;
6016
6064
 
6017
6065
  Data_Get_Struct(self, Image, image);
@@ -6036,10 +6084,11 @@ Image_quantize(int argc, VALUE *argv, VALUE self)
6036
6084
  break;
6037
6085
  }
6038
6086
 
6039
- GetExceptionInfo(&exception);
6040
- new_image = CloneImage(image, 0, 0, True, &exception);
6041
- HANDLE_ERROR
6087
+ new_image = rm_clone_image(image);
6088
+
6042
6089
  QuantizeImage(&quantize_info, new_image);
6090
+ rm_check_image_exception(new_image, DestroyOnError);
6091
+
6043
6092
  return rm_image_new(new_image);
6044
6093
  }
6045
6094
 
@@ -6061,7 +6110,8 @@ Image_radial_blur(VALUE self, VALUE angle)
6061
6110
  GetExceptionInfo(&exception);
6062
6111
 
6063
6112
  new_image = RadialBlurImage(image, NUM2DBL(angle), &exception);
6064
- HANDLE_ERROR
6113
+ rm_check_exception(&exception, new_image, DestroyOnError);
6114
+ rm_ensure_result(new_image);
6065
6115
 
6066
6116
  return rm_image_new(new_image);
6067
6117
  #else
@@ -6105,12 +6155,11 @@ Image_random_channel_threshold(
6105
6155
  channel = STRING_PTR(channel_arg);
6106
6156
  thresholds = STRING_PTR(thresholds_arg);
6107
6157
 
6108
- GetExceptionInfo(&exception);
6109
- new_image = CloneImage(image, 0, 0, True, &exception);
6110
- HANDLE_ERROR
6158
+ new_image = rm_clone_image(image);
6111
6159
 
6160
+ GetExceptionInfo(&exception);
6112
6161
  (void) RandomChannelThresholdImage(new_image, channel, thresholds, &exception);
6113
- HANDLE_ERROR
6162
+ rm_check_exception(&exception, new_image, DestroyOnError);
6114
6163
 
6115
6164
  return rm_image_new(new_image);
6116
6165
  #else
@@ -6139,6 +6188,7 @@ Image_random_threshold_channel(
6139
6188
  volatile VALUE geom_str;
6140
6189
  ExceptionInfo exception;
6141
6190
 
6191
+
6142
6192
  Data_Get_Struct(self, Image, image);
6143
6193
 
6144
6194
  channels = extract_channels(&argc, argv);
@@ -6157,12 +6207,12 @@ Image_random_threshold_channel(
6157
6207
  geom_str = rb_funcall(argv[0], ID_to_s, 0);
6158
6208
  thresholds = STRING_PTR(geom_str);
6159
6209
 
6210
+ new_image = rm_clone_image(image);
6211
+
6160
6212
  GetExceptionInfo(&exception);
6161
- new_image = CloneImage(image, 0, 0, True, &exception);
6162
- HANDLE_ERROR
6163
6213
 
6164
6214
  (void) RandomThresholdImageChannel(new_image, channels, thresholds, &exception);
6165
- HANDLE_ERROR
6215
+ rm_check_exception(&exception, new_image, DestroyOnError);
6166
6216
 
6167
6217
  return rm_image_new(new_image);
6168
6218
 
@@ -6186,7 +6236,6 @@ VALUE
6186
6236
  Image_raise(int argc, VALUE *argv, VALUE self)
6187
6237
  {
6188
6238
  Image *image, *new_image;
6189
- ExceptionInfo exception;
6190
6239
  RectangleInfo rect = {0};
6191
6240
  int raised = True; // default
6192
6241
 
@@ -6210,11 +6259,11 @@ Image_raise(int argc, VALUE *argv, VALUE self)
6210
6259
 
6211
6260
  Data_Get_Struct(self, Image, image);
6212
6261
 
6213
- GetExceptionInfo(&exception);
6214
- new_image = CloneImage(image, 0, 0, True, &exception);
6215
- HANDLE_ERROR
6262
+ new_image = rm_clone_image(image);
6263
+
6216
6264
  (void) RaiseImage(new_image, &rect, raised);
6217
- HANDLE_ERROR_IMG(new_image)
6265
+ rm_check_image_exception(new_image, DestroyOnError);
6266
+
6218
6267
  return rm_image_new(new_image);
6219
6268
  }
6220
6269
 
@@ -6287,7 +6336,7 @@ rd_image(VALUE class, VALUE file, reader_t reader)
6287
6336
  GetExceptionInfo(&exception);
6288
6337
 
6289
6338
  images = (reader)(info, &exception);
6290
- HANDLE_ERROR
6339
+ rm_check_exception(&exception, images, DestroyOnError);
6291
6340
 
6292
6341
  return array_from_images(images);
6293
6342
  }
@@ -6344,9 +6393,10 @@ Image_read_inline(VALUE self, VALUE content)
6344
6393
  Data_Get_Struct(info_obj, Info, info);
6345
6394
 
6346
6395
  images = BlobToImage(info, blob, blob_l, &exception);
6347
- HANDLE_ERROR
6348
6396
  magick_free((void *)blob);
6349
6397
 
6398
+ rm_check_exception(&exception, images, DestroyOnError);
6399
+
6350
6400
  return array_from_images(images);
6351
6401
  }
6352
6402
 
@@ -6391,7 +6441,8 @@ Image_reduce_noise(VALUE self, VALUE radius)
6391
6441
  GetExceptionInfo(&exception);
6392
6442
 
6393
6443
  new_image = ReduceNoiseImage(image, NUM2DBL(radius), &exception);
6394
- HANDLE_ERROR
6444
+ rm_check_exception(&exception, new_image, DestroyOnError);
6445
+
6395
6446
  return rm_image_new(new_image);
6396
6447
  }
6397
6448
 
@@ -6487,7 +6538,8 @@ resize(int bang, int argc, VALUE *argv, VALUE self)
6487
6538
 
6488
6539
  GetExceptionInfo(&exception);
6489
6540
  new_image = ResizeImage(image, columns, rows, filter, blur, &exception);
6490
- HANDLE_ERROR
6541
+ rm_check_exception(&exception, new_image, DestroyOnError);
6542
+ rm_ensure_result(new_image);
6491
6543
 
6492
6544
  if (bang)
6493
6545
  {
@@ -6526,7 +6578,9 @@ Image_roll(VALUE self, VALUE x_offset, VALUE y_offset)
6526
6578
  GetExceptionInfo(&exception);
6527
6579
 
6528
6580
  new_image = RollImage(image, NUM2LONG(x_offset), NUM2LONG(y_offset), &exception);
6529
- HANDLE_ERROR
6581
+ rm_check_exception(&exception, new_image, DestroyOnError);
6582
+ rm_ensure_result(new_image);
6583
+
6530
6584
  return rm_image_new(new_image);
6531
6585
  }
6532
6586
 
@@ -6547,7 +6601,9 @@ rotate(int bang, VALUE self, VALUE degrees)
6547
6601
  GetExceptionInfo(&exception);
6548
6602
 
6549
6603
  new_image = RotateImage(image, NUM2DBL(degrees), &exception);
6550
- HANDLE_ERROR
6604
+ rm_check_exception(&exception, new_image, DestroyOnError);
6605
+ rm_ensure_result(new_image);
6606
+
6551
6607
  if (bang)
6552
6608
  {
6553
6609
  DATA_PTR(self) = new_image;
@@ -6660,7 +6716,8 @@ scale(int bang, int argc, VALUE *argv, VALUE self, scaler_t *scaler)
6660
6716
 
6661
6717
  GetExceptionInfo(&exception);
6662
6718
  new_image = (scaler)(image, columns, rows, &exception);
6663
- HANDLE_ERROR
6719
+ rm_check_exception(&exception, new_image, DestroyOnError);
6720
+ rm_ensure_result(new_image);
6664
6721
 
6665
6722
  if (bang)
6666
6723
  {
@@ -6686,18 +6743,14 @@ Image_set_channel_depth(VALUE self, VALUE channel_arg, VALUE depth)
6686
6743
  Image *image;
6687
6744
  ChannelType channel;
6688
6745
  unsigned long channel_depth;
6689
- MagickBooleanType okay;
6690
6746
 
6691
6747
  rm_check_frozen(self);
6692
6748
  Data_Get_Struct(self, Image, image);
6693
6749
  VALUE_TO_ENUM(channel_arg, channel, ChannelType);
6694
6750
  channel_depth = NUM2ULONG(depth);
6695
6751
 
6696
- okay = SetImageChannelDepth(image, channel, channel_depth);
6697
- if (!okay)
6698
- {
6699
- rb_raise(rb_eRuntimeError, "SetImageChannelDepth failed.");
6700
- }
6752
+ (void) SetImageChannelDepth(image, channel, channel_depth);
6753
+ rm_check_image_exception(image, RetainOnError);
6701
6754
 
6702
6755
  return self;
6703
6756
  #else
@@ -6734,7 +6787,8 @@ Image_sepiatone(int argc, VALUE *argv, VALUE self)
6734
6787
  }
6735
6788
 
6736
6789
  new_image = SepiaToneImage(image, threshold, &exception);
6737
- HANDLE_ERROR
6790
+ rm_check_exception(&exception, new_image, DestroyOnError);
6791
+ rm_ensure_result(new_image);
6738
6792
 
6739
6793
  return rm_image_new(new_image);
6740
6794
  #else
@@ -6756,8 +6810,6 @@ VALUE
6756
6810
  Image_segment(int argc, VALUE *argv, VALUE self)
6757
6811
  {
6758
6812
  Image *image, *new_image;
6759
- ExceptionInfo exception;
6760
-
6761
6813
  int colorspace = RGBColorspace; // These are the Magick++ defaults
6762
6814
  unsigned int verbose = False;
6763
6815
  double cluster_threshold = 1.0;
@@ -6781,11 +6833,13 @@ Image_segment(int argc, VALUE *argv, VALUE self)
6781
6833
  }
6782
6834
 
6783
6835
  Data_Get_Struct(self, Image, image);
6784
- GetExceptionInfo(&exception);
6785
- new_image = CloneImage(image, 0, 0, True, &exception);
6786
- HANDLE_ERROR
6836
+
6837
+ new_image = rm_clone_image(image);
6838
+
6787
6839
  (void) SegmentImage(new_image, colorspace, verbose, cluster_threshold, smoothing_threshold);
6788
- HANDLE_ERROR_IMG(new_image)
6840
+ rm_check_image_exception(new_image, DestroyOnError);
6841
+ rm_ensure_result(new_image);
6842
+
6789
6843
  return rm_image_new(new_image);
6790
6844
  }
6791
6845
 
@@ -6917,7 +6971,9 @@ Image_shade(int argc, VALUE *argv, VALUE self)
6917
6971
  GetExceptionInfo(&exception);
6918
6972
 
6919
6973
  new_image = ShadeImage(image, shading, azimuth, elevation, &exception);
6920
- HANDLE_ERROR
6974
+ rm_check_exception(&exception, new_image, DestroyOnError);
6975
+ rm_ensure_result(new_image);
6976
+
6921
6977
  return rm_image_new(new_image);
6922
6978
  }
6923
6979
 
@@ -6971,11 +7027,8 @@ Image_shadow(int argc, VALUE *argv, VALUE self)
6971
7027
  GetExceptionInfo(&exception);
6972
7028
 
6973
7029
  new_image = ShadowImage(image, opacity, sigma, x_offset, y_offset, &exception);
6974
- if (!new_image)
6975
- {
6976
- rb_raise(rb_eNoMemError, "not enough memory to continue");
6977
- }
6978
- HANDLE_ERROR_IMG(new_image)
7030
+ rm_check_exception(&exception, new_image, DestroyOnError);
7031
+ rm_ensure_result(new_image);
6979
7032
 
6980
7033
  return rm_image_new(new_image);
6981
7034
  #else
@@ -7026,14 +7079,13 @@ Image_sharpen_channel(int argc, VALUE *argv, VALUE self)
7026
7079
  raise_ChannelType_error(argv[argc-1]);
7027
7080
  }
7028
7081
 
7029
- GetExceptionInfo(&exception);
7030
-
7031
7082
  Data_Get_Struct(self, Image, image);
7032
- new_image = CloneImage(image, 0, 0, True, &exception);
7033
- HANDLE_ERROR
7034
7083
 
7035
- new_image = SharpenImageChannel(new_image, channels, radius, sigma, &exception);
7036
- HANDLE_ERROR
7084
+ new_image = rm_clone_image(image);
7085
+
7086
+ GetExceptionInfo(&exception);
7087
+ (void) SharpenImageChannel(new_image, channels, radius, sigma, &exception);
7088
+ rm_check_exception(&exception, new_image, DestroyOnError);
7037
7089
 
7038
7090
  return rm_image_new(new_image);
7039
7091
  #else
@@ -7091,7 +7143,9 @@ Image_shear(
7091
7143
  GetExceptionInfo(&exception);
7092
7144
 
7093
7145
  new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), &exception);
7094
- HANDLE_ERROR
7146
+ rm_check_exception(&exception, new_image, DestroyOnError);
7147
+ rm_ensure_result(new_image);
7148
+
7095
7149
  return rm_image_new(new_image);
7096
7150
  }
7097
7151
 
@@ -7109,10 +7163,8 @@ Image_sigmoidal_contrast_channel(int argc, VALUE *argv, VALUE self)
7109
7163
  double contrast = 3.0;
7110
7164
  double midpoint = 50.0;
7111
7165
  ChannelType channels;
7112
- ExceptionInfo exception;
7113
7166
 
7114
7167
  Data_Get_Struct(self, Image, image);
7115
- GetExceptionInfo(&exception);
7116
7168
 
7117
7169
  channels = extract_channels(&argc, argv);
7118
7170
 
@@ -7131,9 +7183,10 @@ Image_sigmoidal_contrast_channel(int argc, VALUE *argv, VALUE self)
7131
7183
  break;
7132
7184
  }
7133
7185
 
7134
- new_image = CloneImage(image, 0, 0, True, &exception);
7135
- HANDLE_ERROR
7186
+ new_image = rm_clone_image(image);
7187
+
7136
7188
  (void) SigmoidalContrastImageChannel(new_image, channels, sharpen, contrast, midpoint);
7189
+ rm_check_image_exception(new_image, DestroyOnError);
7137
7190
 
7138
7191
  return rm_image_new(new_image);
7139
7192
  #else
@@ -7174,7 +7227,6 @@ VALUE
7174
7227
  Image_solarize(int argc, VALUE *argv, VALUE self)
7175
7228
  {
7176
7229
  Image *image, *new_image;
7177
- ExceptionInfo exception;
7178
7230
  double threshold = 50.0;
7179
7231
 
7180
7232
  switch (argc)
@@ -7193,12 +7245,12 @@ Image_solarize(int argc, VALUE *argv, VALUE self)
7193
7245
  }
7194
7246
 
7195
7247
  Data_Get_Struct(self, Image, image);
7196
- GetExceptionInfo(&exception);
7197
7248
 
7198
- new_image = CloneImage(image, 0, 0, True, &exception);
7199
- HANDLE_ERROR
7249
+ new_image = rm_clone_image(image);
7250
+
7200
7251
  (void) SolarizeImage(new_image, threshold);
7201
- HANDLE_ERROR_IMG(new_image)
7252
+ rm_check_image_exception(new_image, DestroyOnError);
7253
+
7202
7254
  return rm_image_new(new_image);
7203
7255
  }
7204
7256
 
@@ -7294,11 +7346,8 @@ Image_splice(int argc, VALUE *argv, VALUE self)
7294
7346
  new_image = SpliceImage(image, &rectangle, &exception);
7295
7347
  image->background_color = old_color;
7296
7348
 
7297
- if (!new_image)
7298
- {
7299
- rb_raise(rb_eRuntimeError, "SpliceImage failed.");
7300
- }
7301
- HANDLE_ERROR
7349
+ rm_check_exception(&exception, new_image, DestroyOnError);
7350
+ rm_ensure_result(new_image);
7302
7351
 
7303
7352
  return rm_image_new(new_image);
7304
7353
 
@@ -7335,7 +7384,9 @@ Image_spread(int argc, VALUE *argv, VALUE self)
7335
7384
  GetExceptionInfo(&exception);
7336
7385
 
7337
7386
  new_image = SpreadImage(image, radius, &exception);
7338
- HANDLE_ERROR
7387
+ rm_check_exception(&exception, new_image, DestroyOnError);
7388
+ rm_ensure_result(new_image);
7389
+
7339
7390
  return rm_image_new(new_image);
7340
7391
  }
7341
7392
 
@@ -7353,17 +7404,12 @@ Image_statistics(VALUE self)
7353
7404
  Image *image;
7354
7405
  ExceptionInfo exception;
7355
7406
  ImageStatistics stats;
7356
- MagickPassFail okay;
7357
7407
 
7358
7408
  Data_Get_Struct(self, Image, image);
7359
7409
  GetExceptionInfo(&exception);
7360
7410
 
7361
- okay = GetImageStatistics(image, &stats, &exception);
7362
- HANDLE_ERROR
7363
- if (okay == MagickFail)
7364
- {
7365
- rb_raise(rb_eRuntimeError, "GetImageStatistics failed.");
7366
- }
7411
+ (void) GetImageStatistics(image, &stats, &exception);
7412
+ CHECK_EXCEPTION()
7367
7413
 
7368
7414
  return Statistics_new(&stats);
7369
7415
  #else
@@ -7401,7 +7447,9 @@ Image_stegano(
7401
7447
 
7402
7448
  GetExceptionInfo(&exception);
7403
7449
  new_image = SteganoImage(image, watermark, &exception);
7404
- HANDLE_ERROR
7450
+ rm_check_exception(&exception, new_image, DestroyOnError);
7451
+ rm_ensure_result(new_image);
7452
+
7405
7453
  return rm_image_new(new_image);
7406
7454
  }
7407
7455
 
@@ -7430,7 +7478,9 @@ Image_stereo(
7430
7478
 
7431
7479
  GetExceptionInfo(&exception);
7432
7480
  new_image = StereoImage(image, offset, &exception);
7433
- HANDLE_ERROR
7481
+ rm_check_exception(&exception, new_image, DestroyOnError);
7482
+ rm_ensure_result(new_image);
7483
+
7434
7484
  return rm_image_new(new_image);
7435
7485
  }
7436
7486
 
@@ -7582,7 +7632,9 @@ Image_swirl(VALUE self, VALUE degrees)
7582
7632
  GetExceptionInfo(&exception);
7583
7633
 
7584
7634
  new_image = SwirlImage(image, NUM2DBL(degrees), &exception);
7585
- HANDLE_ERROR
7635
+ rm_check_exception(&exception, new_image, DestroyOnError);
7636
+ rm_ensure_result(new_image);
7637
+
7586
7638
  return rm_image_new(new_image);
7587
7639
  }
7588
7640
 
@@ -7613,7 +7665,6 @@ Image_texture_flood_fill(
7613
7665
  DrawInfo *draw_info;
7614
7666
  long x, y;
7615
7667
  PaintMethod method;
7616
- ExceptionInfo exception;
7617
7668
 
7618
7669
  Data_Get_Struct(self, Image, image);
7619
7670
  Color_to_PixelPacket(&color, color_obj);
@@ -7641,13 +7692,8 @@ Image_texture_flood_fill(
7641
7692
  }
7642
7693
  Data_Get_Struct(texture, Image, texture_image);
7643
7694
 
7644
- GetExceptionInfo(&exception);
7645
-
7646
- draw_info->fill_pattern = CloneImage(texture_image, 0, 0, True, &exception);
7647
- HANDLE_ERROR
7648
-
7649
- new_image = CloneImage(image, 0, 0, True, &exception);
7650
- HANDLE_ERROR
7695
+ draw_info->fill_pattern = rm_clone_image(texture_image);
7696
+ new_image = rm_clone_image(image);
7651
7697
 
7652
7698
  // Hack: By-pass bug in ColorFloodfillImage that tests
7653
7699
  // the fill color even though the fill color isn't used.
@@ -7659,9 +7705,10 @@ Image_texture_flood_fill(
7659
7705
  }
7660
7706
 
7661
7707
  (void) ColorFloodfillImage(new_image, draw_info, color, x, y, method);
7662
- HANDLE_ERROR_IMG(new_image)
7663
7708
 
7664
7709
  DestroyDrawInfo(draw_info);
7710
+ rm_check_image_exception(new_image, DestroyOnError);
7711
+
7665
7712
 
7666
7713
  return rm_image_new(new_image);
7667
7714
  }
@@ -7676,14 +7723,14 @@ VALUE
7676
7723
  Image_threshold(VALUE self, VALUE threshold)
7677
7724
  {
7678
7725
  Image *image, *new_image;
7679
- ExceptionInfo exception;
7680
7726
 
7681
7727
  Data_Get_Struct(self, Image, image);
7682
- GetExceptionInfo(&exception);
7683
- new_image = CloneImage(image, 0, 0, True, &exception);
7684
- HANDLE_ERROR
7728
+
7729
+ new_image = rm_clone_image(image);
7730
+
7685
7731
  (void) ThresholdImage(new_image, NUM2DBL(threshold));
7686
- HANDLE_ERROR_IMG(new_image)
7732
+ rm_check_image_exception(new_image, DestroyOnError);
7733
+
7687
7734
  return rm_image_new(new_image);
7688
7735
  }
7689
7736
 
@@ -7702,7 +7749,6 @@ VALUE threshold_image(
7702
7749
  Image *image, *new_image;
7703
7750
  double red, green, blue, opacity;
7704
7751
  char ctarg[200];
7705
- ExceptionInfo exception;
7706
7752
 
7707
7753
  Data_Get_Struct(self, Image, image);
7708
7754
 
@@ -7734,12 +7780,10 @@ VALUE threshold_image(
7734
7780
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
7735
7781
  }
7736
7782
 
7737
- GetExceptionInfo(&exception);
7738
- new_image = CloneImage(image, 0, 0, True, &exception);
7739
- HANDLE_ERROR
7783
+ new_image = rm_clone_image(image);
7740
7784
 
7741
7785
  (thresholder)(new_image, ctarg);
7742
- HANDLE_ERROR_IMG(new_image)
7786
+ rm_check_image_exception(new_image, DestroyOnError);
7743
7787
 
7744
7788
  return rm_image_new(new_image);
7745
7789
  }
@@ -7794,7 +7838,8 @@ thumbnail(int bang, int argc, VALUE *argv, VALUE self)
7794
7838
 
7795
7839
  GetExceptionInfo(&exception);
7796
7840
  new_image = ThumbnailImage(image, columns, rows, &exception);
7797
- HANDLE_ERROR
7841
+ rm_check_exception(&exception, new_image, DestroyOnError);
7842
+ rm_ensure_result(new_image);
7798
7843
 
7799
7844
  if (bang)
7800
7845
  {
@@ -7957,12 +8002,8 @@ Image_tint(int argc, VALUE *argv, VALUE self)
7957
8002
  GetExceptionInfo(&exception);
7958
8003
 
7959
8004
  new_image = TintImage(image, opacity, *tint, &exception);
7960
- HANDLE_ERROR
7961
-
7962
- if (!new_image)
7963
- {
7964
- rb_raise(rb_eNoMemError, "not enough memory to continue");
7965
- }
8005
+ rm_check_exception(&exception, new_image, DestroyOnError);
8006
+ rm_ensure_result(new_image);
7966
8007
 
7967
8008
  return rm_image_new(new_image);
7968
8009
  #else
@@ -8004,14 +8045,15 @@ Image_to_blob(VALUE self)
8004
8045
  if (info->depth != 0)
8005
8046
  {
8006
8047
  (void) SetImageDepth(image, info->depth);
8007
- HANDLE_ERROR_IMG(image)
8048
+ rm_check_image_exception(image, RetainOnError);
8008
8049
  }
8009
8050
 
8010
8051
  GetExceptionInfo(&exception);
8011
8052
  if (*info->magick)
8012
8053
  {
8013
8054
  (void) SetImageInfo(info, True, &exception);
8014
- HANDLE_ERROR
8055
+ CHECK_EXCEPTION()
8056
+
8015
8057
  if (*info->magick == '\0')
8016
8058
  {
8017
8059
  return Qnil;
@@ -8021,7 +8063,8 @@ Image_to_blob(VALUE self)
8021
8063
 
8022
8064
  // Fix #2844 - libjpeg exits when image is 0x0
8023
8065
  magick_info = GetMagickInfo(image->magick, &exception);
8024
- HANDLE_ERROR
8066
+ CHECK_EXCEPTION()
8067
+
8025
8068
  if (magick_info)
8026
8069
  {
8027
8070
  if ( (!rm_strcasecmp(magick_info->name, "JPEG")
@@ -8034,7 +8077,8 @@ Image_to_blob(VALUE self)
8034
8077
  }
8035
8078
 
8036
8079
  blob = ImageToBlob(info, image, &length, &exception);
8037
- HANDLE_ERROR
8080
+ CHECK_EXCEPTION()
8081
+
8038
8082
  if (length == 0 || !blob)
8039
8083
  {
8040
8084
  return Qnil;
@@ -8071,7 +8115,8 @@ Image_to_color(VALUE self, VALUE pixel_arg)
8071
8115
 
8072
8116
  name[0] = '\0';
8073
8117
  (void) QueryColorname(image, pixel, AllCompliance, name, &exception);
8074
- HANDLE_ERROR
8118
+ CHECK_EXCEPTION()
8119
+
8075
8120
  return rb_str_new2(name);
8076
8121
 
8077
8122
  }
@@ -8102,7 +8147,6 @@ Image_transparent(int argc, VALUE *argv, VALUE self)
8102
8147
  {
8103
8148
  Image *image, *new_image;
8104
8149
  PixelPacket color;
8105
- ExceptionInfo exception;
8106
8150
  unsigned int opacity = TransparentOpacity;
8107
8151
 
8108
8152
  Data_Get_Struct(self, Image, image);
@@ -8123,11 +8167,11 @@ Image_transparent(int argc, VALUE *argv, VALUE self)
8123
8167
  break;
8124
8168
  }
8125
8169
 
8126
- GetExceptionInfo(&exception);
8127
- new_image = CloneImage(image, 0, 0, True, &exception);
8128
- HANDLE_ERROR
8170
+ new_image = rm_clone_image(image);
8171
+
8129
8172
  (void) TransparentImage(new_image, color, opacity);
8130
- HANDLE_ERROR_IMG(new_image)
8173
+ rm_check_image_exception(new_image, DestroyOnError);
8174
+
8131
8175
  return rm_image_new(new_image);
8132
8176
  }
8133
8177
 
@@ -8150,16 +8194,11 @@ trimmer(int bang, VALUE self)
8150
8194
  GetExceptionInfo(&exception);
8151
8195
 
8152
8196
  geometry = GetImageBoundingBox(image, &exception);
8153
- HANDLE_ERROR
8197
+ CHECK_EXCEPTION()
8154
8198
 
8155
8199
  new_image = CropImage(image, &geometry, &exception);
8156
- HANDLE_ERROR
8157
- HANDLE_ERROR_IMG(new_image)
8158
- if (!new_image)
8159
- {
8160
- rb_raise(rb_eRuntimeError, "CropImage failed - "
8161
- "probably not enough memory to complete the operation");
8162
- }
8200
+ rm_check_exception(&exception, new_image, DestroyOnError);
8201
+ rm_ensure_result(new_image);
8163
8202
 
8164
8203
  if (bang)
8165
8204
  {
@@ -8219,7 +8258,8 @@ VALUE Image_image_type(VALUE self)
8219
8258
  Data_Get_Struct(self, Image, image);
8220
8259
  GetExceptionInfo(&exception);
8221
8260
  type = GetImageType(image, &exception);
8222
- HANDLE_ERROR
8261
+ CHECK_EXCEPTION()
8262
+
8223
8263
  return ImageType_new(type);
8224
8264
  }
8225
8265
 
@@ -8320,7 +8360,9 @@ Image_unsharp_mask(int argc, VALUE *argv, VALUE self)
8320
8360
 
8321
8361
  GetExceptionInfo(&exception);
8322
8362
  new_image = UnsharpMaskImage(image, radius, sigma, amount, threshold, &exception);
8323
- HANDLE_ERROR
8363
+ rm_check_exception(&exception, new_image, DestroyOnError);
8364
+ rm_ensure_result(new_image);
8365
+
8324
8366
  return rm_image_new(new_image);
8325
8367
  }
8326
8368
 
@@ -8351,7 +8393,9 @@ Image_unsharp_mask_channel(int argc, VALUE *argv, VALUE self)
8351
8393
  GetExceptionInfo(&exception);
8352
8394
  new_image = UnsharpMaskImageChannel(image, channels, radius, sigma, amount
8353
8395
  , threshold, &exception);
8354
- HANDLE_ERROR
8396
+ rm_check_exception(&exception, new_image, DestroyOnError);
8397
+ rm_ensure_result(new_image);
8398
+
8355
8399
  return rm_image_new(new_image);
8356
8400
  #else
8357
8401
  rm_not_implemented();
@@ -8399,11 +8443,8 @@ Image_vignette(int argc, VALUE *argv, VALUE self)
8399
8443
  GetExceptionInfo(&exception);
8400
8444
 
8401
8445
  new_image = VignetteImage(image, radius, sigma, horz_radius, vert_radius, &exception);
8402
- HANDLE_ERROR
8403
- if (!new_image)
8404
- {
8405
- rb_raise(rb_eRuntimeError, "VignetteImage failed");
8406
- }
8446
+ rm_check_exception(&exception, new_image, DestroyOnError);
8447
+ rm_ensure_result(new_image);
8407
8448
 
8408
8449
  return rm_image_new(new_image);
8409
8450
 
@@ -8479,7 +8520,9 @@ Image_wave(int argc, VALUE *argv, VALUE self)
8479
8520
  GetExceptionInfo(&exception);
8480
8521
 
8481
8522
  new_image = WaveImage(image, amplitude, wavelength, &exception);
8482
- HANDLE_ERROR
8523
+ rm_check_exception(&exception, new_image, DestroyOnError);
8524
+ rm_ensure_result(new_image);
8525
+
8483
8526
  return rm_image_new(new_image);
8484
8527
  }
8485
8528
 
@@ -8546,7 +8589,8 @@ Image_write(VALUE self, VALUE file)
8546
8589
 
8547
8590
  GetExceptionInfo(&exception);
8548
8591
  (void) SetImageInfo(info, True, &exception);
8549
- HANDLE_ERROR
8592
+ CHECK_EXCEPTION()
8593
+
8550
8594
  if (*info->magick == '\0')
8551
8595
  {
8552
8596
  return Qnil;
@@ -8556,7 +8600,7 @@ Image_write(VALUE self, VALUE file)
8556
8600
 
8557
8601
  info->adjoin = False;
8558
8602
  (void) WriteImage(info, image);
8559
- HANDLE_ERROR_IMG(image)
8603
+ rm_check_image_exception(image, RetainOnError);
8560
8604
 
8561
8605
  return self;
8562
8606
  }
@@ -8764,8 +8808,9 @@ xform_image(
8764
8808
  new_image = (xformer)(image, &rect, &exception);
8765
8809
 
8766
8810
  // An exception can occur in either the old or the new images
8767
- HANDLE_ERROR
8768
- HANDLE_ERROR_IMG(new_image)
8811
+ rm_check_image_exception(image, RetainOnError);
8812
+ rm_check_exception(&exception, new_image, DestroyOnError);
8813
+ rm_ensure_result(new_image);
8769
8814
 
8770
8815
  if (bang)
8771
8816
  {