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();