ext/RMagick/rmimage.c in rmagick-1.9.2 vs ext/RMagick/rmimage.c in rmagick-1.9.3
- old
+ new
@@ -1,6 +1,6 @@
-/* $Id: rmimage.c,v 1.121 2005/09/13 23:37:21 rmagick Exp $ */
+/* $Id: rmimage.c,v 1.123 2005/09/26 23:37:04 rmagick Exp $ */
/*============================================================================\
| Copyright (C) 2005 by Timothy P. Hunter
| Name: rmimage.c
| Author: Tim Hunter
| Purpose: Image class method definitions for RMagick
@@ -1140,11 +1140,11 @@
hash = rb_hash_new();
for (x = 0; x < colors; x++)
{
pixel = Pixel_from_PixelPacket(&histogram[x].pixel);
- rb_hash_aset(hash, pixel, INT2NUM(histogram[x].count));
+ rb_hash_aset(hash, pixel, ULONG2NUM(histogram[x].count));
}
/*
The histogram array is specifically allocated by malloc because it is
supposed to be freed by the caller.
@@ -1153,34 +1153,59 @@
return hash;
#elif defined(HAVE_GETIMAGEHISTOGRAM)
- Image *image;
+ Image *image, *dc_copy = NULL;
volatile VALUE hash, pixel;
unsigned long x, colors;
ColorPacket *histogram;
ExceptionInfo exception;
Data_Get_Struct(self, Image, image);
GetExceptionInfo(&exception);
+ // If image not DirectClass make a DirectClass copy.
+ if (image->storage_class != DirectClass)
+ {
+ dc_copy = CloneImage(image, 0, 0, True, &exception);
+ HANDLE_ERROR
+ SyncImage(dc_copy);
+ magick_free(dc_copy->colormap);
+ dc_copy->colormap = NULL;
+ dc_copy->storage_class = DirectClass;
+ image = dc_copy;
+ }
+
histogram = GetImageHistogram(image, &colors, &exception);
+ if (dc_copy && (!histogram || exception.severity >= ErrorException))
+ {
+ DestroyImage(dc_copy);
+ }
+ if (!histogram)
+ {
+ rb_raise(rb_eNoMemError, "not enough memory to continue");
+ }
HANDLE_ERROR
hash = rb_hash_new();
for (x = 0; x < colors; x++)
{
pixel = Pixel_from_PixelPacket(&histogram[x].pixel);
- rb_hash_aset(hash, pixel, INT2NUM(histogram[x].count));
+ rb_hash_aset(hash, pixel, ULONG2NUM((unsigned long)histogram[x].count));
}
/*
Christy evidently didn't agree with Bob's memory management.
*/
RelinquishMagickMemory(histogram);
+ if (dc_copy)
+ {
+ DestroyImage(dc_copy);
+ }
+
return hash;
#else
rm_not_implemented();
return (VALUE)0;
#endif
@@ -2629,11 +2654,53 @@
Data_Get_Struct(self, Image, image);
VALUE_TO_ENUM(dispose, image->dispose, DisposeType);
return self;
}
+
/*
+ * Method: Image#distortion_channel(reconstructed_image, metric[, channel...])
+ * Purpose: Call GetImageChannelDistortion
+*/
+VALUE
+Image_distortion_channel(int argc, VALUE *argv, VALUE self)
+{
+#if defined(HAVE_GETIMAGECHANNELDISTORTION)
+ Image *image, *reconstruct;
+ ChannelType channels;
+ ExceptionInfo exception;
+ MetricType metric;
+ double distortion;
+
+ Data_Get_Struct(self, Image, image);
+
+ channels = extract_channels(&argc, argv);
+ if (argc > 2)
+ {
+ raise_ChannelType_error(argv[argc-1]);
+ }
+ if (argc < 2)
+ {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or more)", argc);
+ }
+
+ Data_Get_Struct(ImageList_cur_image(argv[0]), Image, reconstruct);
+ VALUE_TO_ENUM(argv[1], metric, MetricType);
+ GetExceptionInfo(&exception);
+ (void) GetImageChannelDistortion(image, reconstruct, channels
+ , metric, &distortion, &exception);
+ HANDLE_ERROR_IMG(image)
+ HANDLE_ERROR
+
+ return rb_float_new(distortion);
+#else
+ rm_not_implemented();
+ return (VALUE)0;
+#endif
+}
+
+/*
Method: Image#_dump(aDepth)
Purpose: implement marshalling
Returns: a string representing the dumped image
Notes: uses ImageToBlob - use the MIFF format
in the blob since it's the most general
@@ -3650,10 +3717,11 @@
return (VALUE)0;
#endif
}
+
/*
Method: Image#implode(amount=0.50)
Purpose: implode the image by the specified percentage
Returns: a new image
*/
@@ -3836,10 +3904,10 @@
rb_raise(rb_eStandardError, "ImportImagePixels failed with no explanation.");
}
// Everything worked. Replace the image with the clone and destroy the original.
DATA_PTR(self) = clone_image;
- DestroyImage(image);
+ DestroyImage(image);
return self;
#else
rm_not_implemented();