13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%       TTTTT  RRRR    AAA   N   N  SSSSS  FFFFF   OOO   RRRR   M   M         %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         T    R   R  A   A  NN  N  SS     F      O   O  R   R  MM MM         %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         T    RRRR   AAAAA  N N N   SSS   FFF    O   O  RRRR   M M M         %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         T    R R    A   A  N  NN     SS  F      O   O  R R    M   M         %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         T    R  R   A   A  N   N  SSSSS  F       OOO   R  R   M   M         %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                    MagickCore Image Transform Methods                       %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-view.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace-private.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite.h"
50fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy#include "MagickCore/distort.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/effect.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/layer.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resize.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/thread-private.h"
684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/transform.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
75fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%   A u t o O r i e n t I m a g e                                             %
76fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
77fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
78fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
79fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
81fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%  AutoOrientImage() adjusts an image so that its orientation is suitable for
82fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%  viewing (i.e. top-left orientation).
83fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
84fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%  The format of the AutoOrientImage method is:
85fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
86fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%      Image *AutoOrientImage(const Image *image,
87fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%        const OrientationType orientation,ExceptionInfo *exception)
88fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
89fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%  A description of each parameter follows:
90fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
91fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%    o image: The image.
92fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
93fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%    o orientation: Current image orientation.
94fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
95fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%    o exception: Return any errors or warnings in this structure.
96fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%
97fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy*/
98fa5f6c7d8951fffaccad70fa706701129f0a82bfcristyMagickExport Image *AutoOrientImage(const Image *image,
99fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  const OrientationType orientation,ExceptionInfo *exception)
100fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy{
101fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  Image
102fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    *orient_image;
103fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy
104fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  assert(image != (const Image *) NULL);
105e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
106fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  assert(exception != (ExceptionInfo *) NULL);
107e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
108fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  orient_image=(Image *) NULL;
109fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  switch(orientation)
110fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  {
111fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case UndefinedOrientation:
112fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case TopLeftOrientation:
113fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    default:
114fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
115fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=CloneImage(image,0,0,MagickTrue,exception);
116fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
117fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
118fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case TopRightOrientation:
119fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
120fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=FlopImage(image,exception);
121fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
122fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
123fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case BottomRightOrientation:
124fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
125fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=RotateImage(image,180.0,exception);
126fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
127fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
128fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case BottomLeftOrientation:
129fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
130fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=FlipImage(image,exception);
131fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
132fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
133fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case LeftTopOrientation:
134fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
135fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=TransposeImage(image,exception);
136fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
137fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
138fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case RightTopOrientation:
139fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
140fb34829977c27700229cd27c8a262deaeefd4cfecristy      orient_image=RotateImage(image,90.0,exception);
141fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
142fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
143fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case RightBottomOrientation:
144fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
145fb34829977c27700229cd27c8a262deaeefd4cfecristy      orient_image=TransverseImage(image,exception);
146fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
147fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
148fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    case LeftBottomOrientation:
149fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    {
150fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      orient_image=RotateImage(image,270.0,exception);
151fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy      break;
152fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    }
153fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  }
154fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  if (orient_image != (Image *) NULL)
155fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy    orient_image->orientation=TopLeftOrientation;
156fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy  return(orient_image);
157fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy}
158fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy
159fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy/*
160fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
162fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
163fa5f6c7d8951fffaccad70fa706701129f0a82bfcristy%                                                                             %
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C h o p I m a g e                                                         %
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17000f953722c2a11066e14e969e9b0a611abf01e8bcristy%  ChopImage() removes a region of an image and collapses the image to occupy
17100f953722c2a11066e14e969e9b0a611abf01e8bcristy%  the removed portion.
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ChopImage method is:
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ChopImage(const Image *image,const RectangleInfo *chop_info)
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o chop_info: Define the region of the image to chop.
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ChopImage(const Image *image,const RectangleInfo *chop_info,
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define ChopImageTag  "Chop/Image"
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
192c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
193c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *chop_view,
194c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
195c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *chop_image;
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20000f953722c2a11066e14e969e9b0a611abf01e8bcristy    status;
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
202c2b1fb8afe233b177178e0ac55e86d266165090bcristy  MagickOffsetType
203c2b1fb8afe233b177178e0ac55e86d266165090bcristy    progress;
204c2b1fb8afe233b177178e0ac55e86d266165090bcristy
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent;
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2089d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
2099d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
2109d314ff2c17a77996c05413c2013880387e50f0ecristy
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Check chop geometry.
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
215e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
219e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(chop_info != (RectangleInfo *) NULL);
221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (((chop_info->x+(ssize_t) chop_info->width) < 0) ||
222bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((chop_info->y+(ssize_t) chop_info->height) < 0) ||
223bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (chop_info->x > (ssize_t) image->columns) ||
224bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (chop_info->y > (ssize_t) image->rows))
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowImageException(OptionWarning,"GeometryDoesNotContainImage");
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  extent=(*chop_info);
227bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((extent.x+(ssize_t) extent.width) > (ssize_t) image->columns)
228bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    extent.width=(size_t) ((ssize_t) image->columns-extent.x);
229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((extent.y+(ssize_t) extent.height) > (ssize_t) image->rows)
230bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    extent.height=(size_t) ((ssize_t) image->rows-extent.y);
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent.x < 0)
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      extent.width-=(size_t) (-extent.x);
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent.x=0;
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent.y < 0)
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
238bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      extent.height-=(size_t) (-extent.y);
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent.y=0;
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_image=CloneImage(image,image->columns-extent.width,image->rows-
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent.height,MagickTrue,exception);
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chop_image == (Image *) NULL)
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Extract chop image.
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
24800f953722c2a11066e14e969e9b0a611abf01e8bcristy  status=MagickTrue;
249c2b1fb8afe233b177178e0ac55e86d266165090bcristy  progress=0;
25046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
25146ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  chop_view=AcquireAuthenticCacheView(chop_image,exception);
25226b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
253d643247965337aae790abe62ef297abc3cc63c3dcristy  #pragma omp parallel for schedule(static,4) shared(status) \
254d643247965337aae790abe62ef297abc3cc63c3dcristy    magick_threads(image,chop_image,1,1)
25509d81172fd193d98a4d6d433da0ccf1406a4f93ecristy#endif
256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) extent.y; y++)
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2584c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
25905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2644c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
26505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26700f953722c2a11066e14e969e9b0a611abf01e8bcristy    if (status == MagickFalse)
26800f953722c2a11066e14e969e9b0a611abf01e8bcristy      continue;
269c2b1fb8afe233b177178e0ac55e86d266165090bcristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
270c2b1fb8afe233b177178e0ac55e86d266165090bcristy    q=QueueCacheViewAuthenticPixels(chop_view,0,y,chop_image->columns,1,
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
2724c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
27300f953722c2a11066e14e969e9b0a611abf01e8bcristy      {
27400f953722c2a11066e14e969e9b0a611abf01e8bcristy        status=MagickFalse;
27500f953722c2a11066e14e969e9b0a611abf01e8bcristy        continue;
27600f953722c2a11066e14e969e9b0a611abf01e8bcristy      }
277bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
279bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
281d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          register ssize_t
282d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            i;
283d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
284d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
285d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
2865a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelChannel channel=GetPixelChannelChannel(image,i);
2875a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelTrait traits=GetPixelChannelTraits(image,channel);
2885a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
289d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
290d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
291d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
2920beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
293d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
294ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
296ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
29900f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
300c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
301c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
302c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
303c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
304c2b1fb8afe233b177178e0ac55e86d266165090bcristy
30526b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
306a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ChopImage)
307c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
308c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
309c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
310c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
311c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Extract chop image.
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31626b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
317d643247965337aae790abe62ef297abc3cc63c3dcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
318d643247965337aae790abe62ef297abc3cc63c3dcristy    magick_threads(image,chop_image,1,1)
31909d81172fd193d98a4d6d433da0ccf1406a4f93ecristy#endif
320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) (image->rows-(extent.y+extent.height)); y++)
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3224c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
32305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3284c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
32905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33100f953722c2a11066e14e969e9b0a611abf01e8bcristy    if (status == MagickFalse)
33200f953722c2a11066e14e969e9b0a611abf01e8bcristy      continue;
333c2b1fb8afe233b177178e0ac55e86d266165090bcristy    p=GetCacheViewVirtualPixels(image_view,0,extent.y+extent.height+y,
334c2b1fb8afe233b177178e0ac55e86d266165090bcristy      image->columns,1,exception);
335c2b1fb8afe233b177178e0ac55e86d266165090bcristy    q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
336c2b1fb8afe233b177178e0ac55e86d266165090bcristy      1,exception);
3374c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
33800f953722c2a11066e14e969e9b0a611abf01e8bcristy      {
33900f953722c2a11066e14e969e9b0a611abf01e8bcristy        status=MagickFalse;
34000f953722c2a11066e14e969e9b0a611abf01e8bcristy        continue;
34100f953722c2a11066e14e969e9b0a611abf01e8bcristy      }
342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
344bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
346d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          register ssize_t
347d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            i;
348d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
349d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
350d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
3515a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelChannel channel=GetPixelChannelChannel(image,i);
3525a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelTrait traits=GetPixelChannelTraits(image,channel);
3535a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy            PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
354d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
355d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
356d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
3570beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
358d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
359ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
361ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
36400f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
365c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
366c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
367c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
368c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
369c2b1fb8afe233b177178e0ac55e86d266165090bcristy
37026b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
371a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ChopImage)
372c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
373c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
374c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
375c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
376c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_view=DestroyCacheView(chop_view);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_image->type=image->type;
3811c2f48d0fbbad5757296fca9324fa14033f56632cristy  if (status == MagickFalse)
3821c2f48d0fbbad5757296fca9324fa14033f56632cristy    chop_image=DestroyImage(chop_image);
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(chop_image);
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+     C o n s o l i d a t e C M Y K I m a g e                                 %
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ConsolidateCMYKImage() consolidates separate C, M, Y, and K planes into a
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  single image.
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ConsolidateCMYKImage method is:
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ConsolidateCMYKImage(const Image *image,ExceptionInfo *exception)
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image sequence.
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ConsolidateCMYKImages(const Image *images,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
414c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  CacheView
415c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *cmyk_view,
416c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *image_view;
4172224dcdd80d774e98907ebb870f62792e942b73bcristy
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_image,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_images;
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
423d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    j;
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4252224dcdd80d774e98907ebb870f62792e942b73bcristy  ssize_t
4262224dcdd80d774e98907ebb870f62792e942b73bcristy    y;
4272224dcdd80d774e98907ebb870f62792e942b73bcristy
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Consolidate separate C, M, Y, and K planes into a single image.
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image *) NULL);
432e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(images->signature == MagickCoreSignature);
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (images->debug != MagickFalse)
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
436e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  cmyk_images=NewImageList();
438d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy  for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
440d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    register ssize_t
441d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      i;
442d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
4438969a36f06b585ff612855f3808de07f1f5d57b0cristy    assert(images != (Image *) NULL);
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    cmyk_image=CloneImage(images,images->columns,images->rows,MagickTrue,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (cmyk_image == (Image *) NULL)
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
448574cc26500992189f637cd1cdf93d0654e7df7aecristy    if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
45063240888c3975789a09c2494a4654b523931df96cristy    (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
451d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    for (i=0; i < 4; i++)
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45346ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy      image_view=AcquireVirtualCacheView(images,exception);
45446ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy      cmyk_view=AcquireAuthenticCacheView(cmyk_image,exception);
455d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      for (y=0; y < (ssize_t) images->rows; y++)
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
457d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register const Quantum
45805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk          *magick_restrict p;
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
460d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register ssize_t
461d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          x;
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
463d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register Quantum
46405d2ff7ebf21f659f5b11e45afb294e152f4330cdirk          *magick_restrict q;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
466d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
467d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
468d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          exception);
469d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
470d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
471d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        for (x=0; x < (ssize_t) images->columns; x++)
472d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        {
473d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          Quantum
474d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            pixel;
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
476d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          pixel=QuantumRange-GetPixelIntensity(images,p);
477d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          switch (i)
478d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
479d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 0: SetPixelCyan(cmyk_image,pixel,q);  break;
480d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 1: SetPixelMagenta(cmyk_image,pixel,q);  break;
481d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 2: SetPixelYellow(cmyk_image,pixel,q);  break;
482d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 3: SetPixelBlack(cmyk_image,pixel,q);  break;
483d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            default: break;
484d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
485d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          p+=GetPixelChannels(images);
486d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          q+=GetPixelChannels(cmyk_image);
487d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        }
488d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
489d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
491d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      cmyk_view=DestroyCacheView(cmyk_view);
492d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      image_view=DestroyCacheView(image_view);
493d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      images=GetNextImageInList(images);
494d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      if (images == (Image *) NULL)
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    AppendImageToList(&cmyk_images,cmyk_image);
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(cmyk_images);
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C r o p I m a g e                                                         %
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() extracts a region of the image starting at the offset defined
5149f4f03454372e98844a5bcd785267820f294a2aeanthony%  by geometry.  Region must be fully defined, and no special handling of
5159f4f03454372e98844a5bcd785267820f294a2aeanthony%  geometry flags is performed.
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CropImage method is:
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *CropImage(const Image *image,const RectangleInfo *geometry,
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to crop with members
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CropImageTag  "Crop/Image"
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
537c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
538c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *crop_view,
539c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
540c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *crop_image;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
547bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
548bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
549bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
550010d7d107ddf63501993c10081f891891850dffecristy  OffsetInfo
551010d7d107ddf63501993c10081f891891850dffecristy    offset;
552010d7d107ddf63501993c10081f891891850dffecristy
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bounding_box,
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
557bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
559bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Check crop geometry.
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
564e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
569e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box=image->page;
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((bounding_box.width == 0) || (bounding_box.height == 0))
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.width=image->columns;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.height=image->rows;
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=(*geometry);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.width == 0)
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=bounding_box.width;
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height == 0)
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=bounding_box.height;
581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (((bounding_box.x-page.x) >= (ssize_t) page.width) ||
582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((bounding_box.y-page.y) >= (ssize_t) page.height) ||
583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.x-bounding_box.x) > (ssize_t) image->columns) ||
584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.y-bounding_box.y) > (ssize_t) image->rows))
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop is not within virtual canvas, return 1 pixel transparent image.
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
590efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
5944c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
5956d94a308cc4b42b09f5020acce05d779e24faa47cristy      crop_image->alpha_trait=BlendPixelTrait;
596ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=bounding_box;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image->dispose == BackgroundDispose)
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_image->dispose=NoneDispose;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.x < 0) && (bounding_box.x >= 0))
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width+=page.x-bounding_box.x;
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x=0;
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width-=bounding_box.x-page.x;
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x-=bounding_box.x;
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.x < 0)
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.x=0;
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.y < 0) && (bounding_box.y >= 0))
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height+=page.y-bounding_box.y;
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y=0;
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height-=bounding_box.y-page.y;
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y-=bounding_box.y;
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.y < 0)
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.y=0;
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
628cca058580f7b660ae871c8dbfb8a116604650b8bcristy  if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=image->columns-page.x;
6301e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->width != 0) && (page.width > geometry->width))
6311e4aa463a141257da069a7730bc68746863cd964cristy    page.width=geometry->width;
632cca058580f7b660ae871c8dbfb8a116604650b8bcristy  if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=image->rows-page.y;
6341e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->height != 0) && (page.height > geometry->height))
6351e4aa463a141257da069a7730bc68746863cd964cristy    page.height=geometry->height;
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.x+=page.x;
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.y+=page.y;
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.width == 0) || (page.height == 0))
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
641efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize crop image attributes.
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_image == (Image *) NULL)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.width=image->page.width;
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.height=image->page.height;
652010d7d107ddf63501993c10081f891891850dffecristy  offset.x=(ssize_t) (bounding_box.x+bounding_box.width);
653010d7d107ddf63501993c10081f891891850dffecristy  offset.y=(ssize_t) (bounding_box.y+bounding_box.height);
654010d7d107ddf63501993c10081f891891850dffecristy  if ((offset.x > (ssize_t) image->page.width) ||
655010d7d107ddf63501993c10081f891891850dffecristy      (offset.y > (ssize_t) image->page.height))
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.width=bounding_box.width;
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.height=bounding_box.height;
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.x=bounding_box.x;
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.y=bounding_box.y;
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Crop image.
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
66746ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
66846ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  crop_view=AcquireAuthenticCacheView(crop_image,exception);
6692224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
670d643247965337aae790abe62ef297abc3cc63c3dcristy  #pragma omp parallel for schedule(static,4) shared(status) \
671d643247965337aae790abe62ef297abc3cc63c3dcristy    magick_threads(image,crop_image,1,1)
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
673bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) crop_image->rows; y++)
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6754c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
67605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6784c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
67905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6815ce8df84afcfec6dc33ee61ac2014edb3871c455cristy    register ssize_t
6824c08aed51c5899665ade97263692328eea4af106cristy      x;
6834c08aed51c5899665ade97263692328eea4af106cristy
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      1,exception);
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
6904c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6954c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) crop_image->columns; x++)
6964c08aed51c5899665ade97263692328eea4af106cristy    {
697010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
698010d7d107ddf63501993c10081f891891850dffecristy        i;
699010d7d107ddf63501993c10081f891891850dffecristy
700883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
70110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
702c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(crop_image,q);
70310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
70410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(crop_image);
70510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
70610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
707010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
708010d7d107ddf63501993c10081f891891850dffecristy      {
7095a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
7105a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
7115a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
712010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
713010d7d107ddf63501993c10081f891891850dffecristy            (crop_traits == UndefinedPixelTrait))
714010d7d107ddf63501993c10081f891891850dffecristy          continue;
7150beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(crop_image,channel,p[i],q);
716010d7d107ddf63501993c10081f891891850dffecristy      }
717ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
718ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(crop_image);
7194c08aed51c5899665ade97263692328eea4af106cristy    }
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7272224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
728a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_CropImage)
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,CropImageTag,progress++,image->rows);
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_view=DestroyCacheView(crop_view);
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->type=image->type;
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    crop_image=DestroyImage(crop_image);
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(crop_image);
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7489f4f03454372e98844a5bcd785267820f294a2aeanthony%   C r o p I m a g e T o T i l e s                                           %
7499f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
7509f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
7519f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
7529f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7539f4f03454372e98844a5bcd785267820f294a2aeanthony%
754faf4955bcd797a52af8d943944b2610b4737743ccristy%  CropImageToTiles() crops a single image, into a possible list of tiles.
7559f4f03454372e98844a5bcd785267820f294a2aeanthony%  This may include a single sub-region of the image.  This basically applies
7569f4f03454372e98844a5bcd785267820f294a2aeanthony%  all the normal geometry flags for Crop.
7579f4f03454372e98844a5bcd785267820f294a2aeanthony%
758faf4955bcd797a52af8d943944b2610b4737743ccristy%      Image *CropImageToTiles(const Image *image,
759faf4955bcd797a52af8d943944b2610b4737743ccristy%         const RectangleInfo *crop_geometry, ExceptionInfo *exception)
7609f4f03454372e98844a5bcd785267820f294a2aeanthony%
7619f4f03454372e98844a5bcd785267820f294a2aeanthony%  A description of each parameter follows:
7629f4f03454372e98844a5bcd785267820f294a2aeanthony%
7639f4f03454372e98844a5bcd785267820f294a2aeanthony%    o image: the image The transformed image is returned as this parameter.
7649f4f03454372e98844a5bcd785267820f294a2aeanthony%
7659f4f03454372e98844a5bcd785267820f294a2aeanthony%    o crop_geometry: A crop geometry string.
7669f4f03454372e98844a5bcd785267820f294a2aeanthony%
7679f4f03454372e98844a5bcd785267820f294a2aeanthony%    o exception: return any errors or warnings in this structure.
7689f4f03454372e98844a5bcd785267820f294a2aeanthony%
7699f4f03454372e98844a5bcd785267820f294a2aeanthony*/
770fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
77172844f182b47d17dc2b4e9f1062ba434e5852fd6cristystatic inline double MagickRound(double x)
7729f4f03454372e98844a5bcd785267820f294a2aeanthony{
7739f4f03454372e98844a5bcd785267820f294a2aeanthony  /*
7749f4f03454372e98844a5bcd785267820f294a2aeanthony    Round the fraction to nearest integer.
7759f4f03454372e98844a5bcd785267820f294a2aeanthony  */
776ae0a3fcb5e88aba2468892d7710c322885d80fcdcristy  if ((x-floor(x)) < (ceil(x)-x))
77772844f182b47d17dc2b4e9f1062ba434e5852fd6cristy    return(floor(x));
77872844f182b47d17dc2b4e9f1062ba434e5852fd6cristy  return(ceil(x));
7799f4f03454372e98844a5bcd785267820f294a2aeanthony}
7809f4f03454372e98844a5bcd785267820f294a2aeanthony
7819f4f03454372e98844a5bcd785267820f294a2aeanthonyMagickExport Image *CropImageToTiles(const Image *image,
782081aaa1fc0765e25265126a1178ecfbdefb45597dirk  const char *crop_geometry,ExceptionInfo *exception)
7839f4f03454372e98844a5bcd785267820f294a2aeanthony{
7849f4f03454372e98844a5bcd785267820f294a2aeanthony  Image
7859f4f03454372e98844a5bcd785267820f294a2aeanthony    *next,
7869f4f03454372e98844a5bcd785267820f294a2aeanthony    *crop_image;
7879f4f03454372e98844a5bcd785267820f294a2aeanthony
7889f4f03454372e98844a5bcd785267820f294a2aeanthony  MagickStatusType
7899f4f03454372e98844a5bcd785267820f294a2aeanthony    flags;
7909f4f03454372e98844a5bcd785267820f294a2aeanthony
7919f4f03454372e98844a5bcd785267820f294a2aeanthony  RectangleInfo
7929f4f03454372e98844a5bcd785267820f294a2aeanthony    geometry;
7939f4f03454372e98844a5bcd785267820f294a2aeanthony
7949f4f03454372e98844a5bcd785267820f294a2aeanthony  assert(image != (Image *) NULL);
795e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
7969f4f03454372e98844a5bcd785267820f294a2aeanthony  if (image->debug != MagickFalse)
7979f4f03454372e98844a5bcd785267820f294a2aeanthony    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7989f4f03454372e98844a5bcd785267820f294a2aeanthony  crop_image=NewImageList();
7999f4f03454372e98844a5bcd785267820f294a2aeanthony  next=NewImageList();
8009f4f03454372e98844a5bcd785267820f294a2aeanthony  flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
8019f4f03454372e98844a5bcd785267820f294a2aeanthony  if ((flags & AreaValue) != 0)
8029f4f03454372e98844a5bcd785267820f294a2aeanthony    {
8039f4f03454372e98844a5bcd785267820f294a2aeanthony      PointInfo
8049f4f03454372e98844a5bcd785267820f294a2aeanthony        delta,
8059f4f03454372e98844a5bcd785267820f294a2aeanthony        offset;
8069f4f03454372e98844a5bcd785267820f294a2aeanthony
8079f4f03454372e98844a5bcd785267820f294a2aeanthony      RectangleInfo
8089f4f03454372e98844a5bcd785267820f294a2aeanthony        crop;
8099f4f03454372e98844a5bcd785267820f294a2aeanthony
810fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      size_t
811fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        height,
812fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        width;
813fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
8149f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
815fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        Crop into NxM tiles (@ flag).
8169f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8179f4f03454372e98844a5bcd785267820f294a2aeanthony      width=image->columns;
8189f4f03454372e98844a5bcd785267820f294a2aeanthony      height=image->rows;
8199f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.width == 0)
8209f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.width=1;
8219f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.height == 0)
8229f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.height=1;
8239f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((flags & AspectValue) == 0)
8249f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8259f4f03454372e98844a5bcd785267820f294a2aeanthony          width-=(geometry.x < 0 ? -1 : 1)*geometry.x;
8269f4f03454372e98844a5bcd785267820f294a2aeanthony          height-=(geometry.y < 0 ? -1 : 1)*geometry.y;
8279f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8289f4f03454372e98844a5bcd785267820f294a2aeanthony      else
8299f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8309f4f03454372e98844a5bcd785267820f294a2aeanthony          width+=(geometry.x < 0 ? -1 : 1)*geometry.x;
8319f4f03454372e98844a5bcd785267820f294a2aeanthony          height+=(geometry.y < 0 ? -1 : 1)*geometry.y;
8329f4f03454372e98844a5bcd785267820f294a2aeanthony        }
833240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.x=(double) width/geometry.width;
834240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.y=(double) height/geometry.height;
8359ec43c19ff392b1ff2642ff2e946c0a9f3aff40ccristy      if (delta.x < 1.0)
8369ec43c19ff392b1ff2642ff2e946c0a9f3aff40ccristy        delta.x=1.0;
8379ec43c19ff392b1ff2642ff2e946c0a9f3aff40ccristy      if (delta.y < 1.0)
8389ec43c19ff392b1ff2642ff2e946c0a9f3aff40ccristy        delta.y=1.0;
8399f4f03454372e98844a5bcd785267820f294a2aeanthony      for (offset.y=0; offset.y < (double) height; )
8409f4f03454372e98844a5bcd785267820f294a2aeanthony      {
8419f4f03454372e98844a5bcd785267820f294a2aeanthony        if ((flags & AspectValue) == 0)
8429f4f03454372e98844a5bcd785267820f294a2aeanthony          {
843a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy            crop.y=(ssize_t) MagickRound((double) (offset.y-
844fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? 0 : geometry.y)));
8459f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;   /* increment now to find width */
846a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy            crop.height=(size_t) MagickRound((double) (offset.y+
847fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y < 0 ? 0 : geometry.y)));
8489f4f03454372e98844a5bcd785267820f294a2aeanthony          }
8499f4f03454372e98844a5bcd785267820f294a2aeanthony        else
8509f4f03454372e98844a5bcd785267820f294a2aeanthony          {
851a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy            crop.y=(ssize_t) MagickRound((double) (offset.y-
852fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? geometry.y : 0)));
8539f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;  /* increment now to find width */
854a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy            crop.height=(size_t) MagickRound((double)
855fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (offset.y+(geometry.y < -1 ? geometry.y : 0)));
8569f4f03454372e98844a5bcd785267820f294a2aeanthony          }
8579f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.height-=crop.y;
8589f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.y+=image->page.y;
8599f4f03454372e98844a5bcd785267820f294a2aeanthony        for (offset.x=0; offset.x < (double) width; )
8609f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8619f4f03454372e98844a5bcd785267820f294a2aeanthony          if ((flags & AspectValue) == 0)
8629f4f03454372e98844a5bcd785267820f294a2aeanthony            {
863a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy              crop.x=(ssize_t) MagickRound((double) (offset.x-
864fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x > 0 ? 0 : geometry.x)));
865fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
866a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy              crop.width=(size_t) MagickRound((double) (offset.x+
867fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? 0 : geometry.x)));
8689f4f03454372e98844a5bcd785267820f294a2aeanthony            }
8699f4f03454372e98844a5bcd785267820f294a2aeanthony          else
8709f4f03454372e98844a5bcd785267820f294a2aeanthony            {
871a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy              crop.x=(ssize_t) MagickRound((double) (offset.x-
8729f4f03454372e98844a5bcd785267820f294a2aeanthony                (geometry.x > 0 ? geometry.x : 0)));
873fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
874a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy              crop.width=(size_t) MagickRound((double) (offset.x+
875fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? geometry.x : 0)));
8769f4f03454372e98844a5bcd785267820f294a2aeanthony            }
8779f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.width-=crop.x;
8789f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.x+=image->page.x;
879bf46f100b88be08a2bc295304011709b0fe2bccdcristy          next=CropImage(image,&crop,exception);
880c1beb522de604d17fb903901b43fb1e87516a174cristy          if (next != (Image *) NULL)
881c1beb522de604d17fb903901b43fb1e87516a174cristy            AppendImageToList(&crop_image,next);
8829f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8839f4f03454372e98844a5bcd785267820f294a2aeanthony      }
88452224bff1c061e3532b0eeda2cff8d14375d9cb1cristy      ClearMagickException(exception);
8859f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8869f4f03454372e98844a5bcd785267820f294a2aeanthony    }
8879f4f03454372e98844a5bcd785267820f294a2aeanthony  if (((geometry.width == 0) && (geometry.height == 0)) ||
8889f4f03454372e98844a5bcd785267820f294a2aeanthony      ((flags & XValue) != 0) || ((flags & YValue) != 0))
8899f4f03454372e98844a5bcd785267820f294a2aeanthony    {
8909f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
8919f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop a single region at +X+Y.
8929f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8939f4f03454372e98844a5bcd785267820f294a2aeanthony      crop_image=CropImage(image,&geometry,exception);
8949f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((crop_image != (Image *) NULL) && ((flags & AspectValue) != 0))
8959f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8969f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.width=geometry.width;
8979f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.height=geometry.height;
8989f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.x-=geometry.x;
8999f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.y-=geometry.y;
9009f4f03454372e98844a5bcd785267820f294a2aeanthony        }
9019f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
9029ec43c19ff392b1ff2642ff2e946c0a9f3aff40ccristy    }
903fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy  if ((image->columns > geometry.width) || (image->rows > geometry.height))
9049f4f03454372e98844a5bcd785267820f294a2aeanthony    {
905fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      RectangleInfo
906fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        page;
9079f4f03454372e98844a5bcd785267820f294a2aeanthony
9089f4f03454372e98844a5bcd785267820f294a2aeanthony      size_t
9099f4f03454372e98844a5bcd785267820f294a2aeanthony        height,
9109f4f03454372e98844a5bcd785267820f294a2aeanthony        width;
9119f4f03454372e98844a5bcd785267820f294a2aeanthony
9129f4f03454372e98844a5bcd785267820f294a2aeanthony      ssize_t
9139f4f03454372e98844a5bcd785267820f294a2aeanthony        x,
9149f4f03454372e98844a5bcd785267820f294a2aeanthony        y;
9159f4f03454372e98844a5bcd785267820f294a2aeanthony
9169f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
9179f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop into tiles of fixed size WxH.
9189f4f03454372e98844a5bcd785267820f294a2aeanthony      */
9199f4f03454372e98844a5bcd785267820f294a2aeanthony      page=image->page;
9209f4f03454372e98844a5bcd785267820f294a2aeanthony      if (page.width == 0)
9219f4f03454372e98844a5bcd785267820f294a2aeanthony        page.width=image->columns;
9225ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (page.height == 0)
9239f4f03454372e98844a5bcd785267820f294a2aeanthony        page.height=image->rows;
9245ea220b92df1a6358ebb0f72c292375aca7ded18anthony      width=geometry.width;
9255ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (width == 0)
9265ea220b92df1a6358ebb0f72c292375aca7ded18anthony        width=page.width;
9275ea220b92df1a6358ebb0f72c292375aca7ded18anthony      height=geometry.height;
9285ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (height == 0)
9295ea220b92df1a6358ebb0f72c292375aca7ded18anthony        height=page.height;
9309f4f03454372e98844a5bcd785267820f294a2aeanthony      next=NewImageList();
9319f4f03454372e98844a5bcd785267820f294a2aeanthony      for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
9329f4f03454372e98844a5bcd785267820f294a2aeanthony      {
9339f4f03454372e98844a5bcd785267820f294a2aeanthony        for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
9349f4f03454372e98844a5bcd785267820f294a2aeanthony        {
9359f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.width=width;
9369f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.height=height;
9379f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.x=x;
9389f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.y=y;
9399f4f03454372e98844a5bcd785267820f294a2aeanthony          next=CropImage(image,&geometry,exception);
9409f4f03454372e98844a5bcd785267820f294a2aeanthony          if (next == (Image *) NULL)
9419f4f03454372e98844a5bcd785267820f294a2aeanthony            break;
9429f4f03454372e98844a5bcd785267820f294a2aeanthony          AppendImageToList(&crop_image,next);
9439f4f03454372e98844a5bcd785267820f294a2aeanthony        }
9449f4f03454372e98844a5bcd785267820f294a2aeanthony        if (next == (Image *) NULL)
9459f4f03454372e98844a5bcd785267820f294a2aeanthony          break;
9469f4f03454372e98844a5bcd785267820f294a2aeanthony      }
9479f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
9489f4f03454372e98844a5bcd785267820f294a2aeanthony    }
9499f4f03454372e98844a5bcd785267820f294a2aeanthony  return(CloneImage(image,0,0,MagickTrue,exception));
9509f4f03454372e98844a5bcd785267820f294a2aeanthony}
9519f4f03454372e98844a5bcd785267820f294a2aeanthony
9529f4f03454372e98844a5bcd785267820f294a2aeanthony/*
9539f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9549f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
9559f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
9569f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x c e r p t I m a g e                                                   %
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExcerptImage() returns a excerpt of the image as defined by the geometry.
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExcerptImage method is:
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExcerptImage(const Image *image,const RectangleInfo *geometry,
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExcerptImage(const Image *image,
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define ExcerptImageTag  "Excerpt/Image"
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
985c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
986c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *excerpt_view,
987c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
988c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *excerpt_image;
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
995bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
996bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
997bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
998bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1000bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate excerpt image.
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1005e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1010e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (excerpt_image == (Image *) NULL)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Excerpt each row.
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
102046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
102146ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1022b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1023ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
10245e6b259130f9dbe0da4666f734937017babe573acristy    magick_threads(image,excerpt_image,excerpt_image->rows,1)
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1026bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) excerpt_image->rows; y++)
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10284c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
102905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10314c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
103205d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10344c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
10354c08aed51c5899665ade97263692328eea4af106cristy      x;
10364c08aed51c5899665ade97263692328eea4af106cristy
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      geometry->width,1,exception);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
10434c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10484c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) excerpt_image->columns; x++)
10494c08aed51c5899665ade97263692328eea4af106cristy    {
1050010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1051010d7d107ddf63501993c10081f891891850dffecristy        i;
1052010d7d107ddf63501993c10081f891891850dffecristy
1053883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
105410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1055c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(excerpt_image,q);
105610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
105710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(excerpt_image);
105810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
105910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1060010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1061010d7d107ddf63501993c10081f891891850dffecristy      {
10625a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
10635a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
10645a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1065010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1066010d7d107ddf63501993c10081f891891850dffecristy            (excerpt_traits == UndefinedPixelTrait))
1067010d7d107ddf63501993c10081f891891850dffecristy          continue;
10680beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(excerpt_image,channel,p[i],q);
1069010d7d107ddf63501993c10081f891891850dffecristy      }
1070ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1071ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(excerpt_image);
10724c08aed51c5899665ade97263692328eea4af106cristy    }
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1080b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1081a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ExcerptImage)
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,ExcerptImageTag,progress++,image->rows);
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_view=DestroyCacheView(excerpt_view);
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image->type=image->type;
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    excerpt_image=DestroyImage(excerpt_image);
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(excerpt_image);
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x t e n t I m a g e                                                     %
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExtentImage() extends the image as defined by the geometry, gravity, and
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image background color.  Set the (x,y) offset of the geometry to move the
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  original image relative to the extended image.
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExtentImage method is:
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExtentImage(const Image *image,const RectangleInfo *geometry,
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExtentImage(const Image *image,
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *extent_image;
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate extent image.
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1136e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1141e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
1142c66778786a503e094660db599097d005a26b678acristy  if ((image->columns == geometry->width) &&
1143c66778786a503e094660db599097d005a26b678acristy      (image->rows == geometry->height) &&
1144c66778786a503e094660db599097d005a26b678acristy      (geometry->x == 0) && (geometry->y == 0))
1145c66778786a503e094660db599097d005a26b678acristy    return(CloneImage(image,0,0,MagickTrue,exception));
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent_image == (Image *) NULL)
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1150ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(extent_image,exception);
115139172408bad7ef2ef00a815fa9abf9979e7857cbcristy  (void) CompositeImage(extent_image,image,image->compose,MagickTrue,
1152feb3e9695150978a5d2372d3fe2f60466a7c8066cristy    -geometry->x,-geometry->y,exception);
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(extent_image);
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l i p I m a g e                                                         %
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlipImage() creates a vertical mirror image by reflecting the pixels
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis.
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlipImage method is:
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlipImage(const Image *image,ExceptionInfo *exception)
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlipImage(const Image *image,ExceptionInfo *exception)
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlipImageTag  "Flip/Image"
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1185c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1186c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flip_view,
1187c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1188c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flip_image;
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1195bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1197bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
119874ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
119974ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
120074ea2cdfae92d1caf613481a3f69f75901168258cristy
1201bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1203bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1205e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1209e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flip_image == (Image *) NULL)
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flip image.
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
121874ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
121946ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
122046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  flip_view=AcquireAuthenticCacheView(flip_image,exception);
122126b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1222d643247965337aae790abe62ef297abc3cc63c3dcristy  #pragma omp parallel for schedule(static,4) shared(status) \
1223d643247965337aae790abe62ef297abc3cc63c3dcristy    magick_threads(image,flip_image,1,1)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flip_image->rows; y++)
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12274c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
122805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12304c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
123105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12334c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
12344c08aed51c5899665ade97263692328eea4af106cristy      x;
12354c08aed51c5899665ade97263692328eea4af106cristy
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
12395db1f09460168afa2a3119ba98c01cf7c975756ccristy    q=QueueCacheViewAuthenticPixels(flip_view,0,(ssize_t) (flip_image->rows-y-
12405db1f09460168afa2a3119ba98c01cf7c975756ccristy      1),flip_image->columns,1,exception);
12414c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12464c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) flip_image->columns; x++)
12474c08aed51c5899665ade97263692328eea4af106cristy    {
1248010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1249010d7d107ddf63501993c10081f891891850dffecristy        i;
1250010d7d107ddf63501993c10081f891891850dffecristy
1251883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
125210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1253c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(flip_image,q);
125410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
125510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(flip_image);
125610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
125710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1258010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1259010d7d107ddf63501993c10081f891891850dffecristy      {
12605a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
12615a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
12625a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait flip_traits=GetPixelChannelTraits(flip_image,channel);
1263010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1264010d7d107ddf63501993c10081f891891850dffecristy            (flip_traits == UndefinedPixelTrait))
1265010d7d107ddf63501993c10081f891891850dffecristy          continue;
12660beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flip_image,channel,p[i],q);
1267010d7d107ddf63501993c10081f891891850dffecristy      }
1268ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1269ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(flip_image);
12704c08aed51c5899665ade97263692328eea4af106cristy    }
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127826b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1279a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_FlipImage)
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlipImageTag,progress++,image->rows);
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_view=DestroyCacheView(flip_view);
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image->type=image->type;
128937a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.height != 0)
129037a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.y=(ssize_t) (page.height-flip_image->rows-page.y);
129174ea2cdfae92d1caf613481a3f69f75901168258cristy  flip_image->page=page;
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flip_image=DestroyImage(flip_image);
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flip_image);
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l o p I m a g e                                                         %
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlopImage() creates a horizontal mirror image by reflecting the pixels
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis.
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlopImage method is:
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlopImage(const Image *image,ExceptionInfo *exception)
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlopImage(const Image *image,ExceptionInfo *exception)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlopImageTag  "Flop/Image"
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1326c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1327c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flop_view,
1328c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1329c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flop_image;
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1338bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
133974ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
134074ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
134174ea2cdfae92d1caf613481a3f69f75901168258cristy
1342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1344bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1346e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1350e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flop_image == (Image *) NULL)
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flop each row.
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
135974ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
136046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
136146ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  flop_view=AcquireAuthenticCacheView(flop_image,exception);
136226b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1363d643247965337aae790abe62ef297abc3cc63c3dcristy  #pragma omp parallel for schedule(static,4) shared(status) \
1364d643247965337aae790abe62ef297abc3cc63c3dcristy    magick_threads(image,flop_image,1,1)
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1366bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flop_image->rows; y++)
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13684c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
136905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13744c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
137505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
13824c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1387ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(flop_image)*flop_image->columns;
1388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) flop_image->columns; x++)
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1390010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1391010d7d107ddf63501993c10081f891891850dffecristy        i;
1392010d7d107ddf63501993c10081f891891850dffecristy
1393ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(flop_image);
1394883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
139510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
139610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
139710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
139810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1399010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1400010d7d107ddf63501993c10081f891891850dffecristy      {
14015a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
14025a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
14035a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1404010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1405010d7d107ddf63501993c10081f891891850dffecristy            (flop_traits == UndefinedPixelTrait))
1406010d7d107ddf63501993c10081f891891850dffecristy          continue;
14070beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flop_image,channel,p[i],q);
1408010d7d107ddf63501993c10081f891891850dffecristy      }
1409ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
141826b649100680af051e65caec259bf535dbdb5b1acristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1419a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_FlopImage)
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlopImageTag,progress++,image->rows);
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_view=DestroyCacheView(flop_view);
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image->type=image->type;
142937a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.width != 0)
143037a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.x=(ssize_t) (page.width-flop_image->columns-page.x);
143174ea2cdfae92d1caf613481a3f69f75901168258cristy  flop_image->page=page;
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flop_image=DestroyImage(flop_image);
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flop_image);
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R o l l I m a g e                                                         %
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RollImage() offsets an image as defined by x_offset and y_offset.
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RollImage method is:
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      Image *RollImage(const Image *image,const ssize_t x_offset,
1453bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        const ssize_t y_offset,ExceptionInfo *exception)
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o x_offset: the number of columns to roll in the horizontal direction.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o y_offset: the number of rows to roll in the vertical direction.
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1467a1f115c91f45051a1f34f219158f72aa29ca4696cristystatic MagickBooleanType CopyImageRegion(Image *destination,const Image *source,  const size_t columns,const size_t rows,const ssize_t sx,const ssize_t sy,
1468a1f115c91f45051a1f34f219158f72aa29ca4696cristy  const ssize_t dx,const ssize_t dy,ExceptionInfo *exception)
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1470c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1471c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *source_view,
1472c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *destination_view;
1473c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14779d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
14789d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
14799d314ff2c17a77996c05413c2013880387e50f0ecristy
1480e02079cc944634bd2d27b56b2ae638445165ffb0cristy  if (columns == 0)
1481e02079cc944634bd2d27b56b2ae638445165ffb0cristy    return(MagickTrue);
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
148346ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  source_view=AcquireVirtualCacheView(source,exception);
148446ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  destination_view=AcquireAuthenticCacheView(destination,exception);
1485b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
14869a5a52fdbea9190e1c868ba9298a6f64d1c896d1cristy  #pragma omp parallel for schedule(static,4) shared(status) \
14875e6b259130f9dbe0da4666f734937017babe573acristy    magick_threads(source,destination,rows,1)
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) rows; y++)
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14944c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
149505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14974c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
149805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15004c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
15014c08aed51c5899665ade97263692328eea4af106cristy      x;
15024c08aed51c5899665ade97263692328eea4af106cristy
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer scanline.
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
15104c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
15154c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) columns; x++)
15164c08aed51c5899665ade97263692328eea4af106cristy    {
1517010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1518010d7d107ddf63501993c10081f891891850dffecristy        i;
1519010d7d107ddf63501993c10081f891891850dffecristy
1520883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(source,p) == 0)
152110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1522c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(destination,q);
152310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(source);
152410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(destination);
152510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
152610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1527010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1528010d7d107ddf63501993c10081f891891850dffecristy      {
15295a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(source,i);
15305a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait source_traits=GetPixelChannelTraits(source,channel);
15315a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait destination_traits=GetPixelChannelTraits(destination,
15325a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy          channel);
1533010d7d107ddf63501993c10081f891891850dffecristy        if ((source_traits == UndefinedPixelTrait) ||
1534010d7d107ddf63501993c10081f891891850dffecristy            (destination_traits == UndefinedPixelTrait))
1535010d7d107ddf63501993c10081f891891850dffecristy          continue;
15360beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(destination,channel,p[i],q);
1537010d7d107ddf63501993c10081f891891850dffecristy      }
1538ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(source);
1539ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(destination);
15404c08aed51c5899665ade97263692328eea4af106cristy    }
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(destination_view,exception);
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_view=DestroyCacheView(destination_view);
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  source_view=DestroyCacheView(source_view);
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport Image *RollImage(const Image *image,const ssize_t x_offset,
1551bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const ssize_t y_offset,ExceptionInfo *exception)
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RollImageTag  "Roll/Image"
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *roll_image;
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize roll image attributes.
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1568e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1572e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (roll_image == (Image *) NULL)
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.x=x_offset;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.y=y_offset;
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.x < 0)
1579eaedf06777741da32408da72c1e512975c600c48cristy    offset.x+=(ssize_t) image->columns;
1580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.x >= (ssize_t) image->columns)
1581eaedf06777741da32408da72c1e512975c600c48cristy    offset.x-=(ssize_t) image->columns;
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.y < 0)
1583eaedf06777741da32408da72c1e512975c600c48cristy    offset.y+=(ssize_t) image->rows;
1584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.y >= (ssize_t) image->rows)
1585eaedf06777741da32408da72c1e512975c600c48cristy    offset.y-=(ssize_t) image->rows;
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Roll image.
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  status=CopyImageRegion(roll_image,image,(size_t) offset.x,
1590bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,exception);
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,0,3);
1593aae13f6e1a9764f28b4f2e8d03ad4ac7f616f2a3cristy  status&=CopyImageRegion(roll_image,image,image->columns-offset.x,
1594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,0,(ssize_t) image->rows-offset.y,offset.x,0,
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,1,3);
1597aae13f6e1a9764f28b4f2e8d03ad4ac7f616f2a3cristy  status&=CopyImageRegion(roll_image,image,(size_t) offset.x,image->rows-
1598bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    offset.y,(ssize_t) image->columns-offset.x,0,0,offset.y,exception);
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,2,3);
1600aae13f6e1a9764f28b4f2e8d03ad4ac7f616f2a3cristy  status&=CopyImageRegion(roll_image,image,image->columns-offset.x,image->rows-
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,offset.x,offset.y,exception);
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,3,3);
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image->type=image->type;
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    roll_image=DestroyImage(roll_image);
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(roll_image);
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S h a v e I m a g e                                                       %
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ShaveImage() shaves pixels from the image edges.  It allocates the memory
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ShaveImage method is:
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ShaveImage(const Image *image,const RectangleInfo *shave_info,
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_image: Method ShaveImage returns a pointer to the shaved
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      image.  A null image is returned if there is a memory shortage or
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      if the image width or height is zero.
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_info: Specifies a pointer to a RectangleInfo which defines the
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      region of the image to crop.
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ShaveImage(const Image *image,
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *shave_info,ExceptionInfo *exception)
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *shave_image;
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1653e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((2*shave_info->width) >= image->columns) ||
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((2*shave_info->height) >= image->rows))
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowImageException(OptionWarning,"GeometryDoesNotContainImage");
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SetGeometry(image,&geometry);
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.width-=2*shave_info->width;
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.height-=2*shave_info->height;
1662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.x=(ssize_t) shave_info->width+image->page.x;
1663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.y=(ssize_t) shave_info->height+image->page.y;
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image=CropImage(image,&geometry,exception);
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (shave_image == (Image *) NULL)
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.width-=2*shave_info->width;
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.height-=2*shave_info->height;
1669eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.x-=(ssize_t) shave_info->width;
1670eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.y-=(ssize_t) shave_info->height;
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(shave_image);
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S p l i c e I m a g e                                                     %
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  SpliceImage() splices a solid color into the image as defined by the
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry.
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the SpliceImage method is:
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *SpliceImage(const Image *image,const RectangleInfo *geometry,
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to splice with members
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *SpliceImage(const Image *image,
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define SpliceImageTag  "Splice/Image"
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1708c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1709c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
1710c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *splice_view;
1711c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *splice_image;
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_geometry;
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1724bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
17257b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    columns,
1726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate splice image.
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1732e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1737e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_geometry=(*geometry);
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_image=CloneImage(image,image->columns+splice_geometry.width,
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->rows+splice_geometry.height,MagickTrue,exception);
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (splice_image == (Image *) NULL)
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1743574cc26500992189f637cd1cdf93d0654e7df7aecristy  if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      splice_image=DestroyImage(splice_image);
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1748cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy  if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1749cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1750cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy    (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
175117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
175217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      (splice_image->alpha_trait == UndefinedPixelTrait))
1753cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy    (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1754ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(splice_image,exception);
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Respect image geometry.
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (image->gravity)
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedGravity:
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthWestGravity:
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthGravity:
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1766eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthEastGravity:
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1771eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case WestGravity:
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1776eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.width/2;
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case CenterGravity:
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1781eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1782eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case EastGravity:
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1787eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1788eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthWestGravity:
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1793eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthGravity:
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1798eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1799eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthEastGravity:
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1804eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1805eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Splice image.
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
18147b1cf5784b5bcd85aa9293ecf56769f68c037231dirk  columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
181546ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
181646ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  splice_view=AcquireAuthenticCacheView(splice_image,exception);
1817b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1818ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
1819cb7dfccc2e3a9d57a44294cde5228e6f3f27d003cristy    magick_threads(image,splice_image,1,1)
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) splice_geometry.y; y++)
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18234c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
182405d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18294c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
183005d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
18347b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
18357b1cf5784b5bcd85aa9293ecf56769f68c037231dirk      exception);
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
18384c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18437b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    for (x=0; x < columns; x++)
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1845010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1846010d7d107ddf63501993c10081f891891850dffecristy        i;
1847010d7d107ddf63501993c10081f891891850dffecristy
1848883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
184910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1850c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(splice_image,q);
185110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
185210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
185310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
185410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1855010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1856010d7d107ddf63501993c10081f891891850dffecristy      {
18575a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
18585a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
18595a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1860010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1861010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1862010d7d107ddf63501993c10081f891891850dffecristy          continue;
18630beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1864010d7d107ddf63501993c10081f891891850dffecristy      }
1865cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelRed(splice_image,GetPixelRed(image,p),q);
1866cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1867cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1868cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1869ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1870ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1873ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
1874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) splice_image->columns; x++)
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1876010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1877010d7d107ddf63501993c10081f891891850dffecristy        i;
1878010d7d107ddf63501993c10081f891891850dffecristy
1879883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
188010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1881c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(splice_image,q);
188210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
188310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
188410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
188510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1886010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1887010d7d107ddf63501993c10081f891891850dffecristy      {
18885a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
18895a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
18905a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1891010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1892010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1893010d7d107ddf63501993c10081f891891850dffecristy          continue;
18940beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1895010d7d107ddf63501993c10081f891891850dffecristy      }
1896cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelRed(splice_image,GetPixelRed(image,p),q);
1897cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1898cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1899cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1900ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1901ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1910b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1911a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1919b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1920ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
1921cb7dfccc2e3a9d57a44294cde5228e6f3f27d003cristy    magick_threads(image,splice_image,1,1)
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=(ssize_t) (splice_geometry.y+splice_geometry.height);
1924bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy       y < (ssize_t) splice_image->rows; y++)
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19264c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
192705d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19324c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
193305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
19377b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    if ((y < 0) || (y >= (ssize_t)splice_image->rows))
19382224dcdd80d774e98907ebb870f62792e942b73bcristy      continue;
19397b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
19407b1cf5784b5bcd85aa9293ecf56769f68c037231dirk      splice_image->columns,1,exception);
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
19434c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19487b1cf5784b5bcd85aa9293ecf56769f68c037231dirk    for (x=0; x < columns; x++)
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1950010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1951010d7d107ddf63501993c10081f891891850dffecristy        i;
1952010d7d107ddf63501993c10081f891891850dffecristy
1953883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,q) == 0)
195410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1955c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(splice_image,q);
195610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
195710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
195810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
195910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1960010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1961010d7d107ddf63501993c10081f891891850dffecristy      {
19625a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
19635a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
19645a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1965010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1966010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1967010d7d107ddf63501993c10081f891891850dffecristy          continue;
19680beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1969010d7d107ddf63501993c10081f891891850dffecristy      }
1970cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelRed(splice_image,GetPixelRed(image,p),q);
1971cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1972cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1973cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1974ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1975ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1978ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
1979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) splice_image->columns; x++)
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1981010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1982010d7d107ddf63501993c10081f891891850dffecristy        i;
1983010d7d107ddf63501993c10081f891891850dffecristy
1984883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,q) == 0)
198510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
1986c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(splice_image,q);
198710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
198810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
198910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
199010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1991010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1992010d7d107ddf63501993c10081f891891850dffecristy      {
19935a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
19945a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
19955a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1996010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1997010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1998010d7d107ddf63501993c10081f891891850dffecristy          continue;
19990beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
2000010d7d107ddf63501993c10081f891891850dffecristy      }
2001cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelRed(splice_image,GetPixelRed(image,p),q);
2002cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
2003cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
2004cb228bb3ff8da73ec82aa72dee9d4a6309bc7eedcristy      SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
2005ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2006ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2015b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2016a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_view=DestroyCacheView(splice_view);
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_image=DestroyImage(splice_image);
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(splice_image);
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s f o r m I m a g e                                               %
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransformImage() is a convenience method that behaves like ResizeImage() or
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() but accepts scaling and/or cropping information as a region
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry specification.  If the operation fails, the original image handle
20459f4f03454372e98844a5bcd785267820f294a2aeanthony%  is left as is.
20469f4f03454372e98844a5bcd785267820f294a2aeanthony%
20479f4f03454372e98844a5bcd785267820f294a2aeanthony%  This should only be used for single images.
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2049010d7d107ddf63501993c10081f891891850dffecristy%  This function destroys what it assumes to be a single image list.
2050010d7d107ddf63501993c10081f891891850dffecristy%  If the input image is part of a larger list, all other images in that list
2051010d7d107ddf63501993c10081f891891850dffecristy%  will be simply 'lost', not destroyed.
2052010d7d107ddf63501993c10081f891891850dffecristy%
2053010d7d107ddf63501993c10081f891891850dffecristy%  Also if the crop generates a list of images only the first image is resized.
2054010d7d107ddf63501993c10081f891891850dffecristy%  And finally if the crop succeeds and the resize failed, you will get a
2055010d7d107ddf63501993c10081f891891850dffecristy%  cropped image, as well as a 'false' or 'failed' report.
2056010d7d107ddf63501993c10081f891891850dffecristy%
20574e3ea8f0c8f0dd4dc34e8b4a8ac8def0672c78fadirk%  This function and should probably be deprecated in favor of direct calls
2058010d7d107ddf63501993c10081f891891850dffecristy%  to CropImageToTiles() or ResizeImage(), as appropriate.
2059010d7d107ddf63501993c10081f891891850dffecristy%
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransformImage method is:
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType TransformImage(Image **image,const char *crop_geometry,
2063e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        const char *image_geometry,ExceptionInfo *exception)
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image The transformed image is returned as this parameter.
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o crop_geometry: A crop geometry string.  This geometry defines a
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      subregion of the image to crop.
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_geometry: An image geometry string.  This geometry defines the
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      final size of the image.
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2075e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%    o exception: return any errors or warnings in this structure.
2076e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
207806f590165f0505d42005264893fe14a9e8a79986dirkMagickPrivate MagickBooleanType TransformImage(Image **image,
2079e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  const char *crop_geometry,const char *image_geometry,ExceptionInfo *exception)
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *resize_image,
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transform_image;
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image **) NULL);
2089e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert((*image)->signature == MagickCoreSignature);
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*image)->debug != MagickFalse)
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=(*image);
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_geometry != (const char *) NULL)
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop image to a user specified size.
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2101e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy      crop_image=CropImageToTiles(*image,crop_geometry,exception);
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
2103e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy        transform_image=CloneImage(*image,0,0,MagickTrue,exception);
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=DestroyImage(transform_image);
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=GetFirstImageInList(crop_image);
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *image=transform_image;
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_geometry == (const char *) NULL)
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
21139f4f03454372e98844a5bcd785267820f294a2aeanthony
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Scale image to a user specified size.
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
211706f590165f0505d42005264893fe14a9e8a79986dirk  (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,exception);
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((transform_image->columns == geometry.width) &&
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (transform_image->rows == geometry.height))
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
212115b98cde1f8098cb20bceac08481ba6def4efb97cristy  resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2122aa2c16cb5e695053aa78e40f66bc36fbef4b1ed1cristy    transform_image->filter,exception);
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (resize_image == (Image *) NULL)
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=DestroyImage(transform_image);
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=resize_image;
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *image=transform_image;
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s p o s e I m a g e                                               %
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransposeImage() creates a horizontal mirror image by reflecting the pixels
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis while rotating them by 90 degrees.
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransposeImage method is:
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransposeImageTag  "Transpose/Image"
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2160c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2161c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2162c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transpose_view;
2163c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transpose_image;
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2171bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2172bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2177bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
2180e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
2184e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transpose_image == (Image *) NULL)
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transpose image.
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
219446ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
219546ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2196b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2197ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
21985e6b259130f9dbe0da4666f734937017babe573acristy    magick_threads(image,transpose_image,image->rows,1)
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22024c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
220305d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22054c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
220605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22084c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
22094c08aed51c5899665ade97263692328eea4af106cristy      x;
22104c08aed51c5899665ade97263692328eea4af106cristy
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
2213bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns,1,exception);
22159af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy    q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) (image->rows-y-1),
22169af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy      0,1,transpose_image->rows,exception);
22174c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
22224c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) image->columns; x++)
22234c08aed51c5899665ade97263692328eea4af106cristy    {
2224010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2225010d7d107ddf63501993c10081f891891850dffecristy        i;
2226010d7d107ddf63501993c10081f891891850dffecristy
2227883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,q) == 0)
222810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
2229c3a5802c0bea29c2a308d441dfa233b3059938c1cristy          SetPixelBackgoundColor(transpose_image,q);
223010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
223110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(transpose_image);
223210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
223310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
2234010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2235010d7d107ddf63501993c10081f891891850dffecristy      {
22365a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
22375a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
22385a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
22395a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy          channel);
2240010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2241010d7d107ddf63501993c10081f891891850dffecristy            (transpose_traits == UndefinedPixelTrait))
2242010d7d107ddf63501993c10081f891891850dffecristy          continue;
22430beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transpose_image,channel,p[i],q);
2244010d7d107ddf63501993c10081f891891850dffecristy      }
2245ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2246ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(transpose_image);
22474c08aed51c5899665ade97263692328eea4af106cristy    }
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2255b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2256a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransposeImageTag,progress++,
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_view=DestroyCacheView(transpose_view);
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->type=image->type;
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transpose_image->page;
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->page=page;
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transpose_image=DestroyImage(transpose_image);
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transpose_image);
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s v e r s e I m a g e                                             %
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransverseImage() creates a vertical mirror image by reflecting the pixels
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis while rotating them by 270 degrees.
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransverseImage method is:
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransverseImage(const Image *image,ExceptionInfo *exception)
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransverseImage(const Image *image,ExceptionInfo *exception)
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransverseImageTag  "Transverse/Image"
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2305c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2306c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2307c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transverse_view;
2308c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transverse_image;
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2315bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2321bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2323bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
2325e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
2329e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transverse_image == (Image *) NULL)
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transverse image.
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
233946ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  image_view=AcquireVirtualCacheView(image,exception);
234046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy  transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2341b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2342ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy  #pragma omp parallel for schedule(static,4) shared(progress,status) \
23435e6b259130f9dbe0da4666f734937017babe573acristy    magick_threads(image,transverse_image,image->rows,1)
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2345bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23504c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
235105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict p;
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23534c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
235405d2ff7ebf21f659f5b11e45afb294e152f4330cdirk      *magick_restrict q;
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2356010d7d107ddf63501993c10081f891891850dffecristy    register ssize_t
2357010d7d107ddf63501993c10081f891891850dffecristy      x;
2358010d7d107ddf63501993c10081f891891850dffecristy
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2362010d7d107ddf63501993c10081f891891850dffecristy    q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) (image->rows-y-1),
2363010d7d107ddf63501993c10081f891891850dffecristy      0,1,transverse_image->rows,exception);
23644c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2369ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(transverse_image)*image->columns;
2370bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
23714c08aed51c5899665ade97263692328eea4af106cristy    {
2372010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2373010d7d107ddf63501993c10081f891891850dffecristy        i;
2374010d7d107ddf63501993c10081f891891850dffecristy
2375ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(transverse_image);
2376883fde11debec15cedb05dc5d7228d8588066bc0cristy      if (GetPixelReadMask(image,p) == 0)
237710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
237810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
237910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
238010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
2381010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2382010d7d107ddf63501993c10081f891891850dffecristy      {
23835a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelChannel channel=GetPixelChannelChannel(image,i);
23845a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait traits=GetPixelChannelTraits(image,channel);
23855a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy        PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
23865a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy          channel);
2387010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2388010d7d107ddf63501993c10081f891891850dffecristy            (transverse_traits == UndefinedPixelTrait))
2389010d7d107ddf63501993c10081f891891850dffecristy          continue;
23900beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transverse_image,channel,p[i],q);
2391010d7d107ddf63501993c10081f891891850dffecristy      }
2392ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
23934c08aed51c5899665ade97263692328eea4af106cristy    }
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2402b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2403a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransverseImage)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransverseImageTag,progress++,
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_view=DestroyCacheView(transverse_view);
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->type=image->type;
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transverse_image->page;
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
2417bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony  if (page.width != 0)
2418bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony    page.x=(ssize_t) (page.width-transverse_image->columns-page.x);
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height != 0)
2420bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    page.y=(ssize_t) (page.height-transverse_image->rows-page.y);
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->page=page;
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transverse_image=DestroyImage(transverse_image);
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transverse_image);
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r i m I m a g e                                                         %
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TrimImage() trims pixels from the image edges.  It allocates the memory
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TrimImage method is:
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TrimImage(const Image *image,ExceptionInfo *exception)
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TrimImage(const Image *image,ExceptionInfo *exception)
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
2459e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry=GetImageBoundingBox(image,exception);
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((geometry.width == 0) || (geometry.height == 0))
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
24714c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
24726d94a308cc4b42b09f5020acce05d779e24faa47cristy      crop_image->alpha_trait=BlendPixelTrait;
2473ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=image->page;
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.x+=image->page.x;
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.y+=image->page.y;
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(CropImage(image,&geometry,exception));
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2483