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=3; i >= 0; 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) 320 delta=(ssize_t) element-(ssize_t) neighbor;
328 const double threshold,
size_t *projection,
ExceptionInfo *exception)
334 *destination_matrixs,
354 for (width=1; width < ((image->
columns+7)/8); width<<=1) ;
358 sizeof(
unsigned short),exception);
359 if ((source_matrixs == (
MatrixInfo *) NULL) ||
362 if (destination_matrixs != (
MatrixInfo *) NULL)
374 for (j=0; j < 256; j++)
377 for (count=0; c != 0; c>>=1)
379 bits[j]=(
unsigned short) count;
383 #if defined(MAGICKCORE_OPENMP_SUPPORT) 384 #pragma omp parallel for schedule(static) shared(status) \ 385 magick_number_threads(image,image,image->rows,1) 387 for (y=0; y < (ssize_t) image->
rows; y++)
406 if (p == (
const Quantum *) NULL)
413 i=(ssize_t) (image->
columns+7)/8;
414 for (x=0; x < (ssize_t) image->
columns; x++)
438 RadonProjection(image,source_matrixs,destination_matrixs,-1,projection);
440 #if defined(MAGICKCORE_OPENMP_SUPPORT) 441 #pragma omp parallel for schedule(static) shared(status) \ 442 magick_number_threads(image,image,image->rows,1) 444 for (y=0; y < (ssize_t) image->
rows; y++)
463 if (p == (
const Quantum *) NULL)
471 for (x=0; x < (ssize_t) image->
columns; x++)
495 RadonProjection(image,source_matrixs,destination_matrixs,1,projection);
525 for (y=0; y < (ssize_t) image->
rows; y++)
533 if ((y >= offset) && (y < ((ssize_t) image->
rows-offset)))
536 if (p == (
const Quantum *) NULL)
538 for (x=0; x < (ssize_t) image->
columns; x++)
540 if ((x >= offset) && (x < ((ssize_t) image->
columns-offset)))
553 background.
red/count);
555 background.
green/count);
557 background.
blue/count);
560 background.
alpha/count);
601 for (width=1; width < ((image->
columns+7)/8); width<<=1) ;
603 sizeof(*projection));
604 if (projection == (
size_t *) NULL)
614 for (i=0; i < (ssize_t) (2*width-1); i++)
616 if (projection[i] > max_projection)
618 skew=i-(ssize_t) width+1;
619 max_projection=projection[i];
626 " Deskew angle: %g",degrees);
631 if (clone_image == (
Image *) NULL)
632 return((
Image *) NULL);
646 affine_matrix.
tx=0.0;
647 affine_matrix.
ty=0.0;
653 return(deskew_image);
662 if (deskew_image == (
Image *) NULL)
663 return((
Image *) NULL);
665 if (median_image == (
Image *) NULL)
668 return((
Image *) NULL);
674 "%.20gx%.20g%+.20g%+.20g",(double) geometry.
width,(
double)
675 geometry.
height,(double) geometry.
x,(
double) geometry.
y);
676 crop_image=
CropImage(deskew_image,&geometry,exception);
711 #define RotateImageTag "Rotate/Image" 732 assert(image != (
Image *) NULL);
757 if (rotate_image == (
Image *) NULL)
758 return((
Image *) NULL);
760 return(rotate_image);
784 #if defined(MAGICKCORE_OPENMP_SUPPORT) 785 #pragma omp parallel for schedule(static) shared(status) \ 786 magick_number_threads(image,rotate_image,image->rows/tile_height,1) 788 for (tile_y=0; tile_y < (ssize_t) image->
rows; tile_y+=(ssize_t) tile_height)
796 for ( ; tile_x < (ssize_t) image->
columns; tile_x+=(ssize_t) tile_width)
815 if ((tile_width+tile_x) > image->
columns)
816 width=(
size_t) (tile_width-(tile_x+tile_width-image->
columns));
818 if ((tile_height+tile_y) > image->
rows)
819 height=(
size_t) (tile_height-(tile_y+tile_height-image->
rows));
822 if (p == (
const Quantum *) NULL)
827 for (y=0; y < (ssize_t) width; y++)
838 (rotate_image->
columns-(tile_y+height)),y+tile_x,height,1,
846 for (x=0; x < (ssize_t) height; x++)
897 #if defined(MAGICKCORE_OPENMP_SUPPORT) 898 #pragma omp parallel for schedule(static) shared(status) \ 899 magick_number_threads(image,rotate_image,image->rows,1) 901 for (y=0; y < (ssize_t) image->
rows; y++)
919 1),image->
columns,1,exception);
926 for (x=0; x < (ssize_t) image->
columns; x++)
964 page.
y=(ssize_t) (page.
height-rotate_image->
rows-page.
y);
981 #if defined(MAGICKCORE_OPENMP_SUPPORT) 982 #pragma omp parallel for schedule(static) shared(status) \ 983 magick_number_threads(image,rotate_image,image->rows/tile_height,1) 985 for (tile_y=0; tile_y < (ssize_t) image->
rows; tile_y+=(ssize_t) tile_height)
993 for ( ; tile_x < (ssize_t) image->
columns; tile_x+=(ssize_t) tile_width)
1012 if ((tile_width+tile_x) > image->
columns)
1013 width=(
size_t) (tile_width-(tile_x+tile_width-image->
columns));
1015 if ((tile_height+tile_y) > image->
rows)
1016 height=(
size_t) (tile_height-(tile_y+tile_height-image->
rows));
1019 if (p == (
const Quantum *) NULL)
1024 for (y=0; y < (ssize_t) width; y++)
1035 rotate_image->
rows-(tile_x+width)),height,1,exception);
1042 for (x=0; x < (ssize_t) height; x++)
1061 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1062 #pragma omp critical (MagickCore_IntegralRotateImage) 1085 page.
y=(ssize_t) (page.
height-rotate_image->
rows-page.
y);
1094 rotate_image->
page=page;
1097 return(rotate_image);
1137 const size_t width,
const size_t height,
const ssize_t x_offset,
1140 #define XShearImageTag "XShear/Image" 1166 assert(image != (
Image *) NULL);
1174 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1175 #pragma omp parallel for schedule(static) shared(progress,status) \ 1176 magick_number_threads(image,image,height,1) 1178 for (y=0; y < (ssize_t) height; y++)
1212 displacement=degrees*(double) (y-height/2.0);
1213 if (displacement == 0.0)
1215 if (displacement > 0.0)
1219 displacement*=(-1.0);
1223 area=(double) (displacement-step);
1235 if (step > x_offset)
1238 for (i=0; i < (ssize_t) width; i++)
1240 if ((x_offset+i) < step)
1256 &background,(
double) background.
alpha,area,&destination);
1259 for (i=0; i < (step-1); i++)
1273 for (i=0; i < (ssize_t) width; i++)
1277 if ((
size_t) (x_offset+width+step-i) > image->
columns)
1286 &background,(
double) background.
alpha,area,&destination);
1289 for (i=0; i < (step-1); i++)
1304 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1354 const size_t width,
const size_t height,
const ssize_t x_offset,
1357 #define YShearImageTag "YShear/Image" 1383 assert(image != (
Image *) NULL);
1391 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1392 #pragma omp parallel for schedule(static) shared(progress,status) \ 1393 magick_number_threads(image,image,width,1) 1395 for (x=0; x < (ssize_t) width; x++)
1429 displacement=degrees*(double) (x-width/2.0);
1430 if (displacement == 0.0)
1432 if (displacement > 0.0)
1436 displacement*=(-1.0);
1440 area=(double) (displacement-step);
1452 if (step > y_offset)
1455 for (i=0; i < (ssize_t) height; i++)
1457 if ((y_offset+i) < step)
1474 &background,(
double) background.
alpha,area,&destination);
1477 for (i=0; i < (step-1); i++)
1491 for (i=0; i < (ssize_t) height; i++)
1495 if ((
size_t) (y_offset+height+step-i) > image->
rows)
1505 &background,(
double) background.
alpha,area,&destination);
1508 for (i=0; i < (step-1); i++)
1523 #if defined(MAGICKCORE_OPENMP_SUPPORT) 1592 assert(image != (
Image *) NULL);
1598 if ((x_shear != 0.0) && (fmod(x_shear,90.0) == 0.0))
1600 if ((y_shear != 0.0) && (fmod(y_shear,90.0) == 0.0))
1606 if (integral_image == (
Image *) NULL)
1610 if ((shear.
x == 0.0) && (shear.
y == 0.0))
1611 return(integral_image);
1615 return(integral_image);
1633 border_info.
width=(size_t) bounds.
x;
1634 border_info.
height=(
size_t) bounds.
y;
1637 if (shear_image == (
Image *) NULL)
1645 (ssize_t) (shear_image->
rows-image->
rows)/2,exception);
1649 return((
Image *) NULL);
1656 return((
Image *) NULL);
1666 return(shear_image);
1737 assert(image != (
Image *) NULL);
1743 angle=fmod(degrees,360.0);
1746 for (rotations=0; angle > 45.0; rotations++)
1753 if (integral_image == (
Image *) NULL)
1757 if ((shear.
x == 0.0) && (shear.
y == 0.0))
1758 return(integral_image);
1762 return(integral_image);
1769 width=integral_image->
columns;
1770 height=integral_image->
rows;
1771 bounds.
width=(size_t) floor(fabs((
double) height*shear.
x)+width+0.5);
1772 bounds.
height=(size_t) floor(fabs((
double) bounds.
width*shear.
y)+height+0.5);
1773 shear_width=(size_t) floor(fabs((
double) bounds.
height*shear.
x)+
1776 width : bounds.
width-shear_width+2)/2.0+0.5));
1783 border_info.
width=(size_t) bounds.
x;
1784 border_info.
height=(
size_t) bounds.
y;
1788 if (rotate_image == (
Image *) NULL)
1793 status=
XShearImage(rotate_image,shear.
x,width,height,bounds.
x,(ssize_t)
1794 (rotate_image->
rows-height)/2,exception);
1798 return((
Image *) NULL);
1805 return((
Image *) NULL);
1809 bounds.
height)/2,exception);
1813 return((
Image *) NULL);
1823 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)
static ssize_t CastDoubleToLong(const double x)
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)
MagickExport MagickBooleanType IsEventLogging(void)
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)
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)
#define magick_unreferenced(x)
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)