From: cristy Date: Mon, 7 Nov 2011 12:14:23 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~6675 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c7c8114646c716205506e520149923fb52d2942d;p=imagemagick --- diff --git a/MagickCore/shear.c b/MagickCore/shear.c index 62720c6ac..942616ed8 100644 --- a/MagickCore/shear.c +++ b/MagickCore/shear.c @@ -33,11 +33,11 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% The XShearImage, and YShearImage methods are based on the paper "A Fast +% The XShearImage() and YShearImage() methods are based on the paper "A Fast % Algorithm for General Raster Rotatation" by Alan W. Paeth, Graphics -% Interface '86 (Vancouver). RotateImage is adapted from a similar method -% based on the Paeth paper written by Michael Halle of the Spatial Imaging -% Group, MIT Media Lab. +% Interface '86 (Vancouver). ShearRotateImage() is adapted from a similar +% method based on the Paeth paper written by Michael Halle of the Spatial +% Imaging Group, MIT Media Lab. % */ @@ -2056,3 +2056,167 @@ MagickExport Image *ShearImage(const Image *image,const double x_shear, shear_image->page.height=0; return(shear_image); } + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S h e a r R o t a t e I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ShearRotateImage() creates a new image that is a rotated copy of an existing +% one. Positive angles rotate counter-clockwise (right-hand rule), while +% negative angles rotate clockwise. Rotated images are usually larger than +% the originals and have 'empty' triangular corners. X axis. Empty +% triangles left over from shearing the image are filled with the background +% color defined by member 'background_color' of the image. ShearRotateImage +% allocates the memory necessary for the new Image structure and returns a +% pointer to the new image. +% +% ShearRotateImage() is based on the paper "A Fast Algorithm for General +% Raster Rotatation" by Alan W. Paeth. ShearRotateImage is adapted from a +% similar method based on the Paeth paper written by Michael Halle of the +% Spatial Imaging Group, MIT Media Lab. +% +% The format of the ShearRotateImage method is: +% +% Image *ShearRotateImage(const Image *image,const double degrees, +% ExceptionInfo *exception) +% +% A description of each parameter follows. +% +% o image: the image. +% +% o degrees: Specifies the number of degrees to rotate the image. +% +% o exception: return any errors or warnings in this structure. +% +*/ +MagickExport Image *ShearRotateImage(const Image *image,const double degrees, + ExceptionInfo *exception) +{ + Image + *integral_image, + *rotate_image; + + MagickBooleanType + status; + + MagickRealType + angle; + + PointInfo + shear; + + RectangleInfo + border_info; + + size_t + height, + rotations, + width, + y_width; + + ssize_t + x_offset, + y_offset; + + /* + Adjust rotation angle. + */ + assert(image != (Image *) NULL); + assert(image->signature == MagickSignature); + if (image->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + angle=degrees; + while (angle < -45.0) + angle+=360.0; + for (rotations=0; angle > 45.0; rotations++) + angle-=90.0; + rotations%=4; + /* + Calculate shear equations. + */ + integral_image=IntegralRotateImage(image,rotations,exception); + if (integral_image == (Image *) NULL) + ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); + shear.x=(-tan((double) DegreesToRadians(angle)/2.0)); + shear.y=sin((double) DegreesToRadians(angle)); + if ((shear.x == 0.0) && (shear.y == 0.0)) + return(integral_image); + if (SetImageStorageClass(integral_image,DirectClass,exception) == MagickFalse) + { + integral_image=DestroyImage(integral_image); + return(integral_image); + } + if (integral_image->matte == MagickFalse) + (void) SetImageAlphaChannel(integral_image,OpaqueAlphaChannel,exception); + /* + Compute image size. + */ + width=image->columns; + height=image->rows; + if ((rotations == 1) || (rotations == 3)) + { + width=image->rows; + height=image->columns; + } + y_width=width+(ssize_t) floor(fabs(shear.x)*height+0.5); + x_offset=(ssize_t) ceil((double) width+((fabs(shear.y)*height)-width)/2.0- + 0.5); + y_offset=(ssize_t) ceil((double) height+((fabs(shear.y)*y_width)-height)/2.0- + 0.5); + /* + Surround image with a border. + */ + integral_image->border_color=integral_image->background_color; + integral_image->compose=CopyCompositeOp; + border_info.width=(size_t) x_offset; + border_info.height=(size_t) y_offset; + rotate_image=BorderImage(integral_image,&border_info,image->compose, + exception); + integral_image=DestroyImage(integral_image); + if (rotate_image == (Image *) NULL) + ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); + /* + Rotate the image. + */ + status=XShearImage(rotate_image,shear.x,width,height,x_offset,(ssize_t) + (rotate_image->rows-height)/2,exception); + if (status == MagickFalse) + { + rotate_image=DestroyImage(rotate_image); + return((Image *) NULL); + } + status=YShearImage(rotate_image,shear.y,y_width,height,(ssize_t) + (rotate_image->columns-y_width)/2,y_offset,exception); + if (status == MagickFalse) + { + rotate_image=DestroyImage(rotate_image); + return((Image *) NULL); + } + status=XShearImage(rotate_image,shear.x,y_width,rotate_image->rows,(ssize_t) + (rotate_image->columns-y_width)/2,0,exception); + if (status == MagickFalse) + { + rotate_image=DestroyImage(rotate_image); + return((Image *) NULL); + } + status=CropToFitImage(&rotate_image,shear.x,shear.y,(MagickRealType) width, + (MagickRealType) height,MagickTrue,exception); + if (status == MagickFalse) + { + rotate_image=DestroyImage(rotate_image); + return((Image *) NULL); + } + rotate_image->compose=image->compose; + rotate_image->page.width=0; + rotate_image->page.height=0; + return(rotate_image); +} diff --git a/MagickCore/shear.h b/MagickCore/shear.h index 3d8a2c3ac..f1871c1b9 100644 --- a/MagickCore/shear.h +++ b/MagickCore/shear.h @@ -26,7 +26,8 @@ extern MagickExport Image *AffineTransformImage(const Image *,const AffineMatrix *,ExceptionInfo *), *DeskewImage(const Image *,const double,ExceptionInfo *), *RotateImage(const Image *,const double,ExceptionInfo *), - *ShearImage(const Image *,const double,const double,ExceptionInfo *); + *ShearImage(const Image *,const double,const double,ExceptionInfo *), + *ShearRotateImage(const Image *,const double,ExceptionInfo *); #if defined(__cplusplus) || defined(c_plusplus) }