( left_.percent() == right_.percent() ) &&
( left_.aspect() == right_.aspect() ) &&
( left_.greater() == right_.greater() ) &&
- ( left_.less() == right_.less() )
+ ( left_.less() == right_.less() ) &&
+ ( left_.fillArea() == right_.fillArea() )
);
}
int Magick::operator != ( const Magick::Geometry& left_,
_percent( false ),
_aspect( false ),
_greater( false ),
- _less( false )
+ _less( false ),
+ _fillArea( false )
{
}
_percent( false ),
_aspect( false ),
_greater( false ),
- _less( false )
+ _less( false ),
+ _fillArea( false )
{
*this = geometry_; // Use assignment operator
}
_percent( false ),
_aspect( false ),
_greater( false ),
- _less( false )
+ _less( false ),
+ _fillArea( false )
{
*this = geometry_; // Use assignment operator
}
_percent( geometry_._percent ),
_aspect( geometry_._aspect ),
_greater( geometry_._greater ),
- _less( geometry_._less )
+ _less( geometry_._less ),
+ _fillArea( geometry_._fillArea )
{
}
_percent( false ),
_aspect( false ),
_greater( false ),
- _less( false )
+ _less( false ),
+ _fillArea( false )
{
}
_aspect = geometry_._aspect;
_greater = geometry_._greater;
_less = geometry_._less;
+ _fillArea = geometry_._fillArea;
}
return *this;
}
isValid( true );
}
- if ( ( flags & XNegative ) != 0 )
+ if ( ( flags & XNegative ) != 0 )
_xNegative = true;
if ( ( flags & YNegative ) != 0 )
if ( ( flags & GreaterValue ) != 0 )
_greater = true;
+ if ( ( flags & MinimumValue ) != 0 )
+ _fillArea = true;
+
return *this;
}
if ( _less )
geometry += '<';
+ if ( _fillArea )
+ geometry += '^';
+
return geometry;
}
_percent(false),
_aspect(false),
_greater(false),
- _less(false)
-{
+ _less(false),
+ _fillArea(false)
+{
}
// Return an ImageMagick RectangleInfo struct
void less ( bool less_ );
bool less ( void ) const;
+ // Resize the image based on the smallest fitting dimension (^)
+ void fillArea ( bool fillArea_ );
+ bool fillArea ( void ) const;
+
// Does object contain valid geometry?
void isValid ( bool isValid_ );
bool isValid ( void ) const;
operator MagickCore::RectangleInfo() const;
private:
- size_t _width;
- size_t _height;
- ::ssize_t _xOff;
- ::ssize_t _yOff;
- bool _xNegative;
- bool _yNegative;
- bool _isValid;
- bool _percent; // Interpret width & height as percentages (%)
- bool _aspect; // Force exact size (!)
- bool _greater; // Re-size only if larger than geometry (>)
- bool _less; // Re-size only if smaller than geometry (<)
+ size_t _width;
+ size_t _height;
+ ::ssize_t _xOff;
+ ::ssize_t _yOff;
+ bool _xNegative;
+ bool _yNegative;
+ bool _isValid;
+ bool _percent; // Interpret width & height as percentages (%)
+ bool _aspect; // Force exact size (!)
+ bool _greater; // Resize only if larger than geometry (>)
+ bool _less; // Resize only if smaller than geometry (<)
+ bool _fillArea; // Resize the image based on the smallest fitting dimension (^)
};
} // namespace Magick
return _less;
}
+// Resize the image based on the smallest fitting dimension (^)
+inline void Magick::Geometry::fillArea ( bool fillArea_ )
+{
+ _fillArea = fillArea_;
+}
+inline bool Magick::Geometry::fillArea ( void ) const
+{
+ return _fillArea;
+}
#endif // Magick_Geometry_header
using MagickCore::AdaptiveBlurImage;
using MagickCore::AdaptiveThresholdImage;
using MagickCore::AddNoiseImage;
- using MagickCore::AddNoiseImage;
using MagickCore::AffineMatrix;
using MagickCore::AffineTransformImage;
using MagickCore::AnnotateImage;
using MagickCore::BlobToImage;
using MagickCore::BlobWarning;
using MagickCore::BlurImage;
- using MagickCore::BlurImage;
using MagickCore::BorderImage;
using MagickCore::CacheError;
using MagickCore::CacheFatalError;
using MagickCore::EnhanceImage;
using MagickCore::EqualizeImage;
using MagickCore::EvaluateImage;
- using MagickCore::EvaluateImage;
using MagickCore::ExceptionInfo;
using MagickCore::ExceptionType;
using MagickCore::ExportImagePixels;
using MagickCore::FrameInfo;
using MagickCore::FxImage;
using MagickCore::GammaImage;
- using MagickCore::GammaImage;
using MagickCore::GaussianBlurImage;
using MagickCore::GaussianBlurImage;
using MagickCore::GetAffineMatrix;
using MagickCore::KernelInfo;
using MagickCore::LessValue;
using MagickCore::LevelImage;
- using MagickCore::LevelImage;
using MagickCore::LocaleCompare;
using MagickCore::LogMagickEvent;
using MagickCore::MagickCoreTerminus;
using MagickCore::MagnifyImage;
using MagickCore::MergeImageLayers;
using MagickCore::MinifyImage;
+ using MagickCore::MinimumValue;
using MagickCore::MissingDelegateError;
using MagickCore::MissingDelegateFatalError;
using MagickCore::MissingDelegateWarning;
histogram_array=(MagickCore::PixelInfo *)
MagickCore::RelinquishMagickMemory(histogram_array);
}
-
+
+ // Combines one or more images into a single image. The grayscale value of
+ // the pixels of each image in the sequence is assigned in order to the
+ // specified channels of the combined image. The typical ordering would be
+ // image 1 => Red, 2 => Green, 3 => Blue, etc.
+ template <class InputIterator >
+ void combineImages( Image *combinedImage_,
+ InputIterator first_,
+ InputIterator last_,
+ const ChannelType channel_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickCore::Image* image = CombineImages( first_->image(), channel_, &exceptionInfo );
+ unlinkImages( first_, last_ );
+ combinedImage_->replaceImage( image );
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
// Break down an image sequence into constituent parts. This is
// useful for creating GIF or MNG animation sequences.
template <class InputIterator, class Container >
(void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
}
+ // Applies a value to the image with an arithmetic, relational,
+ // or logical operator to an image. Use these operations to lighten or darken
+ // an image, to increase or decrease contrast in an image, or to produce the
+ // "negative" of an image.
+ template <class InputIterator >
+ void evaluateImages( Image *evaluatedImage_,
+ InputIterator first_,
+ InputIterator last_,
+ const MagickEvaluateOperator operator_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickCore::Image* image = EvaluateImages( first_->image(), operator_, &exceptionInfo );
+ unlinkImages( first_, last_ );
+ evaluatedImage_->replaceImage( image );
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
// Merge a sequence of image frames which represent image layers.
// This is useful for combining Photoshop layers into a single image.
template <class InputIterator>
(void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
}
+ // Composes all the image layers from the current given
+ // image onward to produce a single image of the merged layers.
+ template <class InputIterator >
+ void mergeImageLayers( Image *mergedImage_,
+ InputIterator first_,
+ InputIterator last_,
+ const LayerMethod method_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+ linkImages( first_, last_ );
+ MagickCore::Image* image = MergeImageLayers( first_->image(), method_, &exceptionInfo );
+ unlinkImages( first_, last_ );
+ mergedImage_->replaceImage( image );
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
// Create a composite image by combining several separate images.
template <class Container, class InputIterator>
void montageImages( Container *montageImages_,
(void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
}
+ // Compares each image the GIF disposed forms of the previous image in
+ // the sequence. From this it attempts to select the smallest cropped
+ // image to replace each frame, while preserving the results of the
+ // GIF animation.
+ template <class InputIterator, class Container >
+ void optimizeImageLayers( Container *optimizedImages_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+
+ linkImages( first_, last_ );
+ MagickCore::Image* images = OptimizeImageLayers( first_->image(), &exceptionInfo );
+
+ unlinkImages( first_, last_ );
+
+ optimizedImages_->clear();
+
+ insertImages( optimizedImages_, images );
+
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
+ // optimizeImagePlusLayers is exactly as optimizeImageLayers, but may
+ // also add or even remove extra frames in the animation, if it improves
+ // the total number of pixels in the resulting GIF animation.
+ template <class InputIterator, class Container >
+ void optimizePlusImageLayers( Container *optimizedImages_,
+ InputIterator first_,
+ InputIterator last_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+
+ linkImages( first_, last_ );
+ MagickCore::Image* images = OptimizePlusImageLayers( first_->image(), &exceptionInfo );
+
+ unlinkImages( first_, last_ );
+
+ optimizedImages_->clear();
+
+ insertImages( optimizedImages_, images );
+
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
// Quantize colors in images using current quantization settings
// Set measureError_ to true in order to measure quantization error
template <class InputIterator>
(void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
}
+ // Returns a separate grayscale image for each channel specified.
+ template <class Container >
+ void separateImages( Container *separatedImages_,
+ const Image &image_,
+ const ChannelType channel_ ) {
+ MagickCore::ExceptionInfo exceptionInfo;
+ MagickCore::GetExceptionInfo( &exceptionInfo );
+
+ MagickCore::Image* images = MagickCore::SeparateImages( image_.constImage(), channel_, &exceptionInfo );
+
+ separatedImages_->clear();
+
+ insertImages( separatedImages_, images );
+
+ throwException( exceptionInfo );
+ (void) MagickCore::DestroyExceptionInfo( &exceptionInfo );
+ }
+
// Write Images
template <class InputIterator>
void writeImages( InputIterator first_,
(memcmp(cache_info->channel_map,clone_info->channel_map,length) == 0) &&
(cache_info->metacontent_extent == clone_info->metacontent_extent))
{
- size_t
- extent;
-
- /*
- Identical pixel cache morphology.
- */
- extent=cache_info->columns*cache_info->number_channels*cache_info->rows;
-#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
- (void) memcpy(clone_info->pixels,cache_info->pixels,extent*
- sizeof(*cache_info->pixels));
-#else
- {
- register size_t
- i;
-
- #pragma omp parallel for
- for (i=0; i < extent; i++)
- clone_info->pixels[i]=cache_info->pixels[i];
- }
-#endif
+ CopyPixels(clone_info->pixels,cache_info->pixels,cache_info->columns*
+ cache_info->number_channels*cache_info->rows);
if (cache_info->metacontent_extent != 0)
(void) memcpy(clone_info->metacontent,cache_info->metacontent,
cache_info->columns*cache_info->rows*clone_info->metacontent_extent*
*/
MagickPrivate unsigned char *NTResourceToBlob(const char *id)
{
+
+#ifndef MAGICKCORE_LIBRARY_NAME
char
path[MaxTextExtent];
+#endif
DWORD
length;
assert(id != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
+#ifdef MAGICKCORE_LIBRARY_NAME
+ handle=GetModuleHandle(MAGICKCORE_LIBRARY_NAME);
+#else
(void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
DirectorySeparator,GetClientName());
if (IsPathAccessible(path) != MagickFalse)
handle=GetModuleHandle(path);
else
handle=GetModuleHandle(0);
+#endif
if (!handle)
return((unsigned char *) NULL);
resource=FindResource(handle,id,"IMAGEMAGICK");
extern "C" {
#endif
+static inline void CopyPixels(Quantum *destination,const Quantum *source,
+ const MagickSizeType number_pixels)
+{
+#if !defined(MAGICKCORE_OPENMP_SUPPORT) || (MAGICKCORE_QUANTUM_DEPTH <= 8)
+ (void) memcpy(destination,source,(size_t) number_pixels*sizeof(*source));
+#else
+ register MagickSizeType
+ i;
+
+ #pragma omp parallel for
+ for (i=0; i < number_pixels; i++)
+ destination[i]=source[i];
+#endif
+}
+
static inline double PerceptibleReciprocal(const double x)
{
double