114 const double x_shear,
const double y_shear,
115 const double width,
const double height,
136 extent[0].
x=(double) (-width/2.0);
137 extent[0].
y=(double) (-height/2.0);
138 extent[1].
x=(double) width/2.0;
139 extent[1].
y=(double) (-height/2.0);
140 extent[2].
x=(double) (-width/2.0);
141 extent[2].
y=(double) height/2.0;
142 extent[3].
x=(double) width/2.0;
143 extent[3].
y=(double) height/2.0;
144 for (i=0; i < 4; i++)
146 extent[i].
x+=x_shear*extent[i].
y;
147 extent[i].
y+=y_shear*extent[i].
x;
149 extent[i].
x+=x_shear*extent[i].
y;
150 extent[i].
x+=(double) (*image)->columns/2.0;
151 extent[i].
y+=(
double) (*image)->rows/2.0;
155 for (i=1; i < 4; i++)
157 if (min.
x > extent[i].
x)
159 if (min.
y > extent[i].
y)
161 if (max.
x < extent[i].
x)
163 if (max.
y < extent[i].
y)
172 crop_image=
CropImage(*image,&geometry,exception);
173 if (crop_image == (
Image *) NULL)
175 crop_image->
page=page;
217 MatrixInfo *destination_matrixs,
const ssize_t sign,
size_t *projection)
233 q=destination_matrixs;
248 for (i=0; i < (ssize_t) step; i++)
292 #if defined(MAGICKCORE_OPENMP_SUPPORT) 293 #pragma omp parallel for schedule(static) \ 294 magick_number_threads(image,image,GetMatrixColumns(p),1) 318 delta=(ssize_t) element-(ssize_t) neighbor;
326 const double threshold,
size_t *projection,
ExceptionInfo *exception)
332 *destination_matrixs,
352 for (width=1; width < ((image->
columns+7)/8); width<<=1) ;
356 sizeof(
unsigned short),exception);
357 if ((source_matrixs == (
MatrixInfo *) NULL) ||
360 if (destination_matrixs != (
MatrixInfo *) NULL)
372 for (j=0; j < 256; j++)
375 for (count=0; c != 0; c>>=1)
377 bits[j]=(
unsigned short) count;
381 #if defined(MAGICKCORE_OPENMP_SUPPORT) 382 #pragma omp parallel for schedule(static) shared(status) \ 383 magick_number_threads(image,image,image->rows,1) 385 for (y=0; y < (ssize_t) image->
rows; y++)
404 if (p == (
const Quantum *) NULL)
411 i=(ssize_t) (image->
columns+7)/8;
412 for (x=0; x < (ssize_t) image->
columns; x++)
436 RadonProjection(image,source_matrixs,destination_matrixs,-1,projection);
438 #if defined(MAGICKCORE_OPENMP_SUPPORT) 439 #pragma omp parallel for schedule(static) shared(status) \ 440 magick_number_threads(image,image,image->rows,1) 442 for (y=0; y < (ssize_t) image->
rows; y++)
461 if (p == (
const Quantum *) NULL)
469 for (x=0; x < (ssize_t) image->
columns; x++)
493 RadonProjection(image,source_matrixs,destination_matrixs,1,projection);
523 for (y=0; y < (ssize_t) image->
rows; y++)
531 if ((y >= offset) && (y < ((ssize_t) image->
rows-offset)))
534 if (p == (
const Quantum *) NULL)
536 for (x=0; x < (ssize_t) image->
columns; x++)
538 if ((x >= offset) && (x < ((ssize_t) image->
columns-offset)))
551 background.
red/count);
553 background.
green/count);
555 background.
blue/count);
558 background.
alpha/count);
599 for (width=1; width < ((image->
columns+7)/8); width<<=1) ;
601 sizeof(*projection));
602 if (projection == (
size_t *) NULL)
612 for (i=0; i < (ssize_t) (2*width-1); i++)
614 if (projection[i] > max_projection)
616 skew=i-(ssize_t) width+1;
617 max_projection=projection[i];
624 " Deskew angle: %g",degrees);
629 if (clone_image == (
Image *) NULL)
630 return((
Image *) NULL);
644 affine_matrix.
tx=0.0;
645 affine_matrix.
ty=0.0;
651 return(deskew_image);
660 if (deskew_image == (
Image *) NULL)
661 return((
Image *) NULL);
663 if (median_image == (
Image *) NULL)
666 return((
Image *) NULL);
672 "%.20gx%.20g%+.20g%+.20g",(double) geometry.
width,(
double)
673 geometry.
height,(double) geometry.
x,(
double) geometry.
y);
674 crop_image=
CropImage(deskew_image,&geometry,exception);
709 #define RotateImageTag "Rotate/Image" 730 assert(image != (
Image *) NULL);
755 if (rotate_image == (
Image *) NULL)
756 return((
Image *) NULL);
758 return(rotate_image);
782 #if defined(MAGICKCORE_OPENMP_SUPPORT) 783 #pragma omp parallel for schedule(static) shared(status) \ 784 magick_number_threads(image,rotate_image,image->rows/tile_height,1) 786 for (tile_y=0; tile_y < (ssize_t) image->
rows; tile_y+=(ssize_t) tile_height)
794 for ( ; tile_x < (ssize_t) image->
columns; tile_x+=(ssize_t) tile_width)
813 if ((tile_x+(ssize_t) tile_width) > (ssize_t) image->
columns)
814 width=(
size_t) (tile_width-(tile_x+tile_width-image->
columns));
816 if ((tile_y+(ssize_t) tile_height) > (ssize_t) image->
rows)
817 height=(
size_t) (tile_height-(tile_y+tile_height-image->
rows));
820 if (p == (
const Quantum *) NULL)
825 for (y=0; y < (ssize_t) width; y++)
836 (rotate_image->
columns-(tile_y+height)),y+tile_x,height,1,
844 for (x=0; x < (ssize_t) height; x++)
895 #if defined(MAGICKCORE_OPENMP_SUPPORT) 896 #pragma omp parallel for schedule(static) shared(status) \ 897 magick_number_threads(image,rotate_image,image->rows,1) 899 for (y=0; y < (ssize_t) image->
rows; y++)
917 1),image->
columns,1,exception);
924 for (x=0; x < (ssize_t) image->
columns; x++)
962 page.
y=(ssize_t) (page.
height-rotate_image->
rows-page.
y);
979 #if defined(MAGICKCORE_OPENMP_SUPPORT) 980 #pragma omp parallel for schedule(static) shared(status) \ 981 magick_number_threads(image,rotate_image,image->rows/tile_height,1) 983 for (tile_y=0; tile_y < (ssize_t) image->
rows; tile_y+=(ssize_t) tile_height)
991 for ( ; tile_x < (ssize_t) image->
columns; tile_x+=(ssize_t) tile_width)
1010 if ((tile_x+(ssize_t) tile_width) > (ssize_t) image->
columns)
1011 width=(
size_t) (tile_width-(tile_x+tile_width-image->
columns));
1013 if ((tile_y+(ssize_t) tile_height) > (ssize_t) image->
rows)
1014 height=(
size_t) (tile_height-(tile_y+tile_height-image->
rows));
1017 if (p == (
const Quantum *) NULL)
1022 for (y=0; y < (ssize_t) width; y++)
1033 rotate_image->
rows-(tile_x+width)),height,1,exception);
1040 for (x=0; x < (ssize_t) height; x++)
1059 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1060 #pragma omp critical (MagickCore_IntegralRotateImage) 1083 page.
y=(ssize_t) (page.
height-rotate_image->
rows-page.
y);
1092 rotate_image->
page=page;
1095 return(rotate_image);
1135 const size_t width,
const size_t height,
const ssize_t x_offset,
1138 #define XShearImageTag "XShear/Image" 1164 assert(image != (
Image *) NULL);
1172 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1173 #pragma omp parallel for schedule(static) shared(progress,status) \ 1174 magick_number_threads(image,image,height,1) 1176 for (y=0; y < (ssize_t) height; y++)
1210 displacement=degrees*(double) (y-height/2.0);
1211 if (displacement == 0.0)
1213 if (displacement > 0.0)
1217 displacement*=(-1.0);
1221 area=(double) (displacement-step);
1233 if (step > x_offset)
1236 for (i=0; i < (ssize_t) width; i++)
1238 if ((x_offset+i) < step)
1254 &background,(
double) background.
alpha,area,&destination);
1257 for (i=0; i < (step-1); i++)
1271 for (i=0; i < (ssize_t) width; i++)
1275 if ((
size_t) (x_offset+width+step-i) > image->
columns)
1284 &background,(
double) background.
alpha,area,&destination);
1287 for (i=0; i < (step-1); i++)
1302 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1352 const size_t width,
const size_t height,
const ssize_t x_offset,
1355 #define YShearImageTag "YShear/Image" 1381 assert(image != (
Image *) NULL);
1389 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1390 #pragma omp parallel for schedule(static) shared(progress,status) \ 1391 magick_number_threads(image,image,width,1) 1393 for (x=0; x < (ssize_t) width; x++)
1427 displacement=degrees*(double) (x-width/2.0);
1428 if (displacement == 0.0)
1430 if (displacement > 0.0)
1434 displacement*=(-1.0);
1438 area=(double) (displacement-step);
1450 if (step > y_offset)
1453 for (i=0; i < (ssize_t) height; i++)
1455 if ((y_offset+i) < step)
1472 &background,(
double) background.
alpha,area,&destination);
1475 for (i=0; i < (step-1); i++)
1489 for (i=0; i < (ssize_t) height; i++)
1493 if ((
size_t) (y_offset+height+step-i) > image->
rows)
1503 &background,(
double) background.
alpha,area,&destination);
1506 for (i=0; i < (step-1); i++)
1521 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1590 assert(image != (
Image *) NULL);
1596 if ((x_shear != 0.0) && (fmod(x_shear,90.0) == 0.0))
1598 if ((y_shear != 0.0) && (fmod(y_shear,90.0) == 0.0))
1604 if (integral_image == (
Image *) NULL)
1608 if ((shear.
x == 0.0) && (shear.
y == 0.0))
1609 return(integral_image);
1613 return(integral_image);
1631 border_info.
width=(size_t) bounds.
x;
1632 border_info.
height=(
size_t) bounds.
y;
1635 if (shear_image == (
Image *) NULL)
1643 (ssize_t) (shear_image->
rows-image->
rows)/2,exception);
1647 return((
Image *) NULL);
1654 return((
Image *) NULL);
1664 return(shear_image);
1735 assert(image != (
Image *) NULL);
1741 angle=fmod(degrees,360.0);
1744 for (rotations=0; angle > 45.0; rotations++)
1751 if (integral_image == (
Image *) NULL)
1755 if ((shear.
x == 0.0) && (shear.
y == 0.0))
1756 return(integral_image);
1760 return(integral_image);
1767 width=integral_image->
columns;
1768 height=integral_image->
rows;
1769 bounds.
width=(size_t) floor(fabs((
double) height*shear.
x)+width+0.5);
1770 bounds.
height=(size_t) floor(fabs((
double) bounds.
width*shear.
y)+height+0.5);
1771 shear_width=(size_t) floor(fabs((
double) bounds.
height*shear.
x)+
1774 width : bounds.
width-shear_width+2)/2.0+0.5));
1781 border_info.
width=(size_t) bounds.
x;
1782 border_info.
height=(
size_t) bounds.
y;
1786 if (rotate_image == (
Image *) NULL)
1791 status=
XShearImage(rotate_image,shear.
x,width,height,bounds.
x,(ssize_t)
1792 (rotate_image->
rows-height)/2,exception);
1796 return((
Image *) NULL);
1803 return((
Image *) NULL);
1807 bounds.
height)/2,exception);
1811 return((
Image *) NULL);
1821 return(rotate_image);
MagickDoubleType MagickRealType
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
MagickExport Image * DeskewImage(const Image *image, const double threshold, ExceptionInfo *exception)
MagickProgressMonitor progress_monitor
static void GetImageBackgroundColor(Image *image, const ssize_t offset, ExceptionInfo *exception)
MagickExport Image * ShearRotateImage(const Image *image, const double degrees, ExceptionInfo *exception)
static MagickBooleanType RadonTransform(const Image *image, const double threshold, size_t *projection, ExceptionInfo *exception)
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static PixelTrait GetPixelAlphaTraits(const Image *magick_restrict image)
static Quantum GetPixelRed(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType NullMatrix(MatrixInfo *matrix_info)
MagickExport MagickStatusType ParseAbsoluteGeometry(const char *geometry, RectangleInfo *region_info)
static void RadonProjection(const Image *image, MatrixInfo *source_matrixs, MatrixInfo *destination_matrixs, const ssize_t sign, size_t *projection)
MagickPrivate void GetPixelCacheTileSize(const Image *, size_t *, size_t *)
MagickExport MagickBooleanType SetImageArtifact(Image *image, const char *artifact, const char *value)
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
static MagickBooleanType XShearImage(Image *image, const double degrees, const size_t width, const size_t height, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
static void SetPixelViaPixelInfo(const Image *magick_restrict image, const PixelInfo *magick_restrict pixel_info, Quantum *magick_restrict pixel)
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
static long StringToLong(const char *magick_restrict value)
MagickExport size_t GetMatrixColumns(const MatrixInfo *matrix_info)
MagickExport MagickBooleanType GetMatrixElement(const MatrixInfo *matrix_info, const ssize_t x, const ssize_t y, void *value)
static Quantum ClampToQuantum(const MagickRealType quantum)
MagickExport void GetPixelInfo(const Image *image, PixelInfo *pixel)
MagickExport MagickBooleanType SetMatrixElement(const MatrixInfo *matrix_info, const ssize_t x, const ssize_t y, const void *value)
MagickExport Image * AffineTransformImage(const Image *image, const AffineMatrix *affine_matrix, ExceptionInfo *exception)
#define MagickCoreSignature
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelOption alpha_type, ExceptionInfo *exception)
MagickExport Image * IntegralRotateImage(const Image *image, size_t rotations, ExceptionInfo *exception)
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
static double DegreesToRadians(const double degrees)
static Quantum GetPixelGreen(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
MagickExport MagickBooleanType IsStringTrue(const char *value)
static void CompositePixelInfoAreaBlend(const PixelInfo *p, const double alpha, const PixelInfo *q, const double beta, const double area, PixelInfo *composite)
static void GetPixelInfoPixel(const Image *magick_restrict image, const Quantum *magick_restrict pixel, PixelInfo *magick_restrict pixel_info)
static MagickBooleanType YShearImage(Image *image, const double degrees, const size_t width, const size_t height, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
MagickExport Quantum * QueueCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(Image *image, const VirtualPixelMethod virtual_pixel_method, ExceptionInfo *exception)
MagickExport MatrixInfo * AcquireMatrixInfo(const size_t columns, const size_t rows, const size_t stride, ExceptionInfo *exception)
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
static size_t GetPixelChannels(const Image *magick_restrict image)
static ssize_t CastDoubleToLong(const double value)
char filename[MagickPathExtent]
#define GetMagickModule()
#define ThrowImageException(severity, tag)
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
MagickExport Image * ShearImage(const Image *image, const double x_shear, const double y_shear, ExceptionInfo *exception)
static double RadiansToDegrees(const double radians)
MagickExport RectangleInfo GetImageBoundingBox(const Image *image, ExceptionInfo *exception)
MagickExport Image * BorderImage(const Image *image, const RectangleInfo *border_info, const CompositeOperator compose, ExceptionInfo *exception)
static void SetPixelChannel(const Image *magick_restrict image, const PixelChannel channel, const Quantum quantum, Quantum *magick_restrict pixel)
MagickExport void * RelinquishMagickMemory(void *memory)
static MagickBooleanType CropToFitImage(Image **image, const double x_shear, const double y_shear, const double width, const double height, const MagickBooleanType rotate, ExceptionInfo *exception)
CompositeOperator compose
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
static Quantum GetPixelBlue(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
PixelInfo background_color
MagickExport Image * DestroyImage(Image *image)
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
MagickExport Image * StatisticImage(const Image *image, const StatisticType type, const size_t width, const size_t height, ExceptionInfo *exception)
MagickExport MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
MagickExport size_t GetMatrixRows(const MatrixInfo *matrix_info)
MagickExport MatrixInfo * DestroyMatrixInfo(MatrixInfo *matrix_info)