transform.c revision 240ae87fc6e81b556f53a43acb6ffdc311a9c2fa
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                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy%  Copyright 1999-2011 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"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/effect.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/layer.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resize.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/thread-private.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/transform.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C h o p I m a g e                                                         %
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8000f953722c2a11066e14e969e9b0a611abf01e8bcristy%  ChopImage() removes a region of an image and collapses the image to occupy
8100f953722c2a11066e14e969e9b0a611abf01e8bcristy%  the removed portion.
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ChopImage method is:
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ChopImage(const Image *image,const RectangleInfo *chop_info)
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o chop_info: Define the region of the image to chop.
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ChopImage(const Image *image,const RectangleInfo *chop_info,
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define ChopImageTag  "Chop/Image"
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
103c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *chop_view,
104c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
105c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *chop_image;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
11000f953722c2a11066e14e969e9b0a611abf01e8bcristy    status;
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112c2b1fb8afe233b177178e0ac55e86d266165090bcristy  MagickOffsetType
113c2b1fb8afe233b177178e0ac55e86d266165090bcristy    progress;
114c2b1fb8afe233b177178e0ac55e86d266165090bcristy
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent;
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1189d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
1199d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
1209d314ff2c17a77996c05413c2013880387e50f0ecristy
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Check chop geometry.
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(chop_info != (RectangleInfo *) NULL);
131bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (((chop_info->x+(ssize_t) chop_info->width) < 0) ||
132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((chop_info->y+(ssize_t) chop_info->height) < 0) ||
133bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (chop_info->x > (ssize_t) image->columns) ||
134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (chop_info->y > (ssize_t) image->rows))
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowImageException(OptionWarning,"GeometryDoesNotContainImage");
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  extent=(*chop_info);
137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((extent.x+(ssize_t) extent.width) > (ssize_t) image->columns)
138bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    extent.width=(size_t) ((ssize_t) image->columns-extent.x);
139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((extent.y+(ssize_t) extent.height) > (ssize_t) image->rows)
140bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    extent.height=(size_t) ((ssize_t) image->rows-extent.y);
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent.x < 0)
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
143bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      extent.width-=(size_t) (-extent.x);
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent.x=0;
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent.y < 0)
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      extent.height-=(size_t) (-extent.y);
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent.y=0;
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_image=CloneImage(image,image->columns-extent.width,image->rows-
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent.height,MagickTrue,exception);
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chop_image == (Image *) NULL)
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Extract chop image.
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15800f953722c2a11066e14e969e9b0a611abf01e8bcristy  status=MagickTrue;
159c2b1fb8afe233b177178e0ac55e86d266165090bcristy  progress=0;
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_view=AcquireCacheView(chop_image);
1622224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
163c2b1fb8afe233b177178e0ac55e86d266165090bcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
16409d81172fd193d98a4d6d433da0ccf1406a4f93ecristy#endif
165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) extent.y; y++)
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1674c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
168c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1734c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
174c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17600f953722c2a11066e14e969e9b0a611abf01e8bcristy    if (status == MagickFalse)
17700f953722c2a11066e14e969e9b0a611abf01e8bcristy      continue;
178c2b1fb8afe233b177178e0ac55e86d266165090bcristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
179c2b1fb8afe233b177178e0ac55e86d266165090bcristy    q=QueueCacheViewAuthenticPixels(chop_view,0,y,chop_image->columns,1,
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
1814c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
18200f953722c2a11066e14e969e9b0a611abf01e8bcristy      {
18300f953722c2a11066e14e969e9b0a611abf01e8bcristy        status=MagickFalse;
18400f953722c2a11066e14e969e9b0a611abf01e8bcristy        continue;
18500f953722c2a11066e14e969e9b0a611abf01e8bcristy      }
186bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
188bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
190d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          register ssize_t
191d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            i;
192d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
193d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
194d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
195d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelChannel
196d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              channel;
197d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
198d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelTrait
199d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              chop_traits,
200d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              traits;
201d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
202d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
203d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
204d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            chop_traits=GetPixelChannelMapTraits(chop_image,channel);
205d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
206d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
207d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
2080beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
209d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
210ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
212ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
21500f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
216c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
217c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
218c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
219c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
220c2b1fb8afe233b177178e0ac55e86d266165090bcristy
2212224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
222c2b1fb8afe233b177178e0ac55e86d266165090bcristy  #pragma omp critical (MagickCore_ChopImage)
223c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
224c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
225c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
226c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
227c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Extract chop image.
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2322224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
233c2b1fb8afe233b177178e0ac55e86d266165090bcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
23409d81172fd193d98a4d6d433da0ccf1406a4f93ecristy#endif
235bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) (image->rows-(extent.y+extent.height)); y++)
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2374c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
238c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
240bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2434c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
244c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24600f953722c2a11066e14e969e9b0a611abf01e8bcristy    if (status == MagickFalse)
24700f953722c2a11066e14e969e9b0a611abf01e8bcristy      continue;
248c2b1fb8afe233b177178e0ac55e86d266165090bcristy    p=GetCacheViewVirtualPixels(image_view,0,extent.y+extent.height+y,
249c2b1fb8afe233b177178e0ac55e86d266165090bcristy      image->columns,1,exception);
250c2b1fb8afe233b177178e0ac55e86d266165090bcristy    q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
251c2b1fb8afe233b177178e0ac55e86d266165090bcristy      1,exception);
2524c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
25300f953722c2a11066e14e969e9b0a611abf01e8bcristy      {
25400f953722c2a11066e14e969e9b0a611abf01e8bcristy        status=MagickFalse;
25500f953722c2a11066e14e969e9b0a611abf01e8bcristy        continue;
25600f953722c2a11066e14e969e9b0a611abf01e8bcristy      }
257bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
261d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          register ssize_t
262d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            i;
263d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
264d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
265d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
266d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelChannel
267d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              channel;
268d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
269d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelTrait
270d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              chop_traits,
271d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              traits;
272d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
273d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
274d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
275d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            chop_traits=GetPixelChannelMapTraits(chop_image,channel);
276d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
277d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
278d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
2790beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
280d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
281ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
283ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
28600f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
287c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
288c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
289c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
290c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
291c2b1fb8afe233b177178e0ac55e86d266165090bcristy
2922224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
293c2b1fb8afe233b177178e0ac55e86d266165090bcristy  #pragma omp critical (MagickCore_ChopImage)
294c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
295c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
296c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
297c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
298c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_view=DestroyCacheView(chop_view);
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_image->type=image->type;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(chop_image);
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+     C o n s o l i d a t e C M Y K I m a g e                                 %
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ConsolidateCMYKImage() consolidates separate C, M, Y, and K planes into a
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  single image.
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ConsolidateCMYKImage method is:
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ConsolidateCMYKImage(const Image *image,ExceptionInfo *exception)
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image sequence.
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ConsolidateCMYKImages(const Image *images,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
334c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  CacheView
335c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *cmyk_view,
336c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *image_view;
3372224dcdd80d774e98907ebb870f62792e942b73bcristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_image,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_images;
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
343d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    j;
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3452224dcdd80d774e98907ebb870f62792e942b73bcristy  ssize_t
3462224dcdd80d774e98907ebb870f62792e942b73bcristy    y;
3472224dcdd80d774e98907ebb870f62792e942b73bcristy
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Consolidate separate C, M, Y, and K planes into a single image.
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image *) NULL);
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images->signature == MagickSignature);
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (images->debug != MagickFalse)
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  cmyk_images=NewImageList();
358d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy  for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
360d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    register ssize_t
361d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      i;
362d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    cmyk_image=CloneImage(images,images->columns,images->rows,MagickTrue,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (cmyk_image == (Image *) NULL)
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
367574cc26500992189f637cd1cdf93d0654e7df7aecristy    if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
36963240888c3975789a09c2494a4654b523931df96cristy    (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
370d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    for (i=0; i < 4; i++)
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
372d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      image_view=AcquireCacheView(images);
373d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      cmyk_view=AcquireCacheView(cmyk_image);
374d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      for (y=0; y < (ssize_t) images->rows; y++)
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
376d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register const Quantum
377d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          *restrict p;
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
379d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register ssize_t
380d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          x;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
382d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register Quantum
383d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          *restrict q;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
385d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
386d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
387d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          exception);
388d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
389d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
390d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        for (x=0; x < (ssize_t) images->columns; x++)
391d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        {
392d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          Quantum
393d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            pixel;
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
395d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          pixel=QuantumRange-GetPixelIntensity(images,p);
396d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          switch (i)
397d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
398d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 0: SetPixelCyan(cmyk_image,pixel,q);  break;
399d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 1: SetPixelMagenta(cmyk_image,pixel,q);  break;
400d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 2: SetPixelYellow(cmyk_image,pixel,q);  break;
401d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 3: SetPixelBlack(cmyk_image,pixel,q);  break;
402d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            default: break;
403d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
404d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          p+=GetPixelChannels(images);
405d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          q+=GetPixelChannels(cmyk_image);
406d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        }
407d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
408d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
410d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      cmyk_view=DestroyCacheView(cmyk_view);
411d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      image_view=DestroyCacheView(image_view);
412d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      images=GetNextImageInList(images);
413d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      if (images == (Image *) NULL)
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    AppendImageToList(&cmyk_images,cmyk_image);
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(cmyk_images);
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C r o p I m a g e                                                         %
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() extracts a region of the image starting at the offset defined
4339f4f03454372e98844a5bcd785267820f294a2aeanthony%  by geometry.  Region must be fully defined, and no special handling of
4349f4f03454372e98844a5bcd785267820f294a2aeanthony%  geometry flags is performed.
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CropImage method is:
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *CropImage(const Image *image,const RectangleInfo *geometry,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to crop with members
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CropImageTag  "Crop/Image"
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
456c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
457c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *crop_view,
458c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
459c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *crop_image;
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
469010d7d107ddf63501993c10081f891891850dffecristy  OffsetInfo
470010d7d107ddf63501993c10081f891891850dffecristy    offset;
471010d7d107ddf63501993c10081f891891850dffecristy
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bounding_box,
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
476bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Check crop geometry.
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box=image->page;
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((bounding_box.width == 0) || (bounding_box.height == 0))
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.width=image->columns;
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.height=image->rows;
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=(*geometry);
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.width == 0)
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=bounding_box.width;
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height == 0)
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=bounding_box.height;
500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (((bounding_box.x-page.x) >= (ssize_t) page.width) ||
501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((bounding_box.y-page.y) >= (ssize_t) page.height) ||
502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.x-bounding_box.x) > (ssize_t) image->columns) ||
503bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.y-bounding_box.y) > (ssize_t) image->rows))
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop is not within virtual canvas, return 1 pixel transparent image.
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
5134c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
514ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=bounding_box;
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image->dispose == BackgroundDispose)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_image->dispose=NoneDispose;
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.x < 0) && (bounding_box.x >= 0))
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width+=page.x-bounding_box.x;
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x=0;
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width-=bounding_box.x-page.x;
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x-=bounding_box.x;
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.x < 0)
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.x=0;
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.y < 0) && (bounding_box.y >= 0))
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height+=page.y-bounding_box.y;
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y=0;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height-=bounding_box.y-page.y;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y-=bounding_box.y;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.y < 0)
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.y=0;
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((size_t) (page.x+page.width) > image->columns)
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=image->columns-page.x;
5481e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->width != 0) && (page.width > geometry->width))
5491e4aa463a141257da069a7730bc68746863cd964cristy    page.width=geometry->width;
550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((size_t) (page.y+page.height) > image->rows)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=image->rows-page.y;
5521e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->height != 0) && (page.height > geometry->height))
5531e4aa463a141257da069a7730bc68746863cd964cristy    page.height=geometry->height;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.x+=page.x;
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.y+=page.y;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.width == 0) || (page.height == 0))
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize crop image attributes.
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_image == (Image *) NULL)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.width=image->page.width;
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.height=image->page.height;
570010d7d107ddf63501993c10081f891891850dffecristy  offset.x=(ssize_t) (bounding_box.x+bounding_box.width);
571010d7d107ddf63501993c10081f891891850dffecristy  offset.y=(ssize_t) (bounding_box.y+bounding_box.height);
572010d7d107ddf63501993c10081f891891850dffecristy  if ((offset.x > (ssize_t) image->page.width) ||
573010d7d107ddf63501993c10081f891891850dffecristy      (offset.y > (ssize_t) image->page.height))
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.width=bounding_box.width;
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.height=bounding_box.height;
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.x=bounding_box.x;
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.y=bounding_box.y;
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Crop image.
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_view=AcquireCacheView(crop_image);
5872224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
58809d81172fd193d98a4d6d433da0ccf1406a4f93ecristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
590bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) crop_image->rows; y++)
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5924c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
593c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5954c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
596c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5985ce8df84afcfec6dc33ee61ac2014edb3871c455cristy    register ssize_t
5994c08aed51c5899665ade97263692328eea4af106cristy      x;
6004c08aed51c5899665ade97263692328eea4af106cristy
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      1,exception);
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
6074c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6124c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) crop_image->columns; x++)
6134c08aed51c5899665ade97263692328eea4af106cristy    {
614010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
615010d7d107ddf63501993c10081f891891850dffecristy        i;
616010d7d107ddf63501993c10081f891891850dffecristy
617010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
618010d7d107ddf63501993c10081f891891850dffecristy      {
619010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
620010d7d107ddf63501993c10081f891891850dffecristy          channel;
621010d7d107ddf63501993c10081f891891850dffecristy
622010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
623010d7d107ddf63501993c10081f891891850dffecristy          crop_traits,
624010d7d107ddf63501993c10081f891891850dffecristy          traits;
625010d7d107ddf63501993c10081f891891850dffecristy
626010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
627010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
628010d7d107ddf63501993c10081f891891850dffecristy        crop_traits=GetPixelChannelMapTraits(crop_image,channel);
629010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
630010d7d107ddf63501993c10081f891891850dffecristy            (crop_traits == UndefinedPixelTrait))
631010d7d107ddf63501993c10081f891891850dffecristy          continue;
6320beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(crop_image,channel,p[i],q);
633010d7d107ddf63501993c10081f891891850dffecristy      }
634ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
635ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(crop_image);
6364c08aed51c5899665ade97263692328eea4af106cristy    }
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6442224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_CropImage)
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,CropImageTag,progress++,image->rows);
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_view=DestroyCacheView(crop_view);
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->type=image->type;
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    crop_image=DestroyImage(crop_image);
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(crop_image);
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6659f4f03454372e98844a5bcd785267820f294a2aeanthony%   C r o p I m a g e T o T i l e s                                           %
6669f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6679f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6689f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6699f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6709f4f03454372e98844a5bcd785267820f294a2aeanthony%
671faf4955bcd797a52af8d943944b2610b4737743ccristy%  CropImageToTiles() crops a single image, into a possible list of tiles.
6729f4f03454372e98844a5bcd785267820f294a2aeanthony%  This may include a single sub-region of the image.  This basically applies
6739f4f03454372e98844a5bcd785267820f294a2aeanthony%  all the normal geometry flags for Crop.
6749f4f03454372e98844a5bcd785267820f294a2aeanthony%
675faf4955bcd797a52af8d943944b2610b4737743ccristy%      Image *CropImageToTiles(const Image *image,
676faf4955bcd797a52af8d943944b2610b4737743ccristy%         const RectangleInfo *crop_geometry, ExceptionInfo *exception)
6779f4f03454372e98844a5bcd785267820f294a2aeanthony%
6789f4f03454372e98844a5bcd785267820f294a2aeanthony%  A description of each parameter follows:
6799f4f03454372e98844a5bcd785267820f294a2aeanthony%
6809f4f03454372e98844a5bcd785267820f294a2aeanthony%    o image: the image The transformed image is returned as this parameter.
6819f4f03454372e98844a5bcd785267820f294a2aeanthony%
6829f4f03454372e98844a5bcd785267820f294a2aeanthony%    o crop_geometry: A crop geometry string.
6839f4f03454372e98844a5bcd785267820f294a2aeanthony%
6849f4f03454372e98844a5bcd785267820f294a2aeanthony%    o exception: return any errors or warnings in this structure.
6859f4f03454372e98844a5bcd785267820f294a2aeanthony%
6869f4f03454372e98844a5bcd785267820f294a2aeanthony*/
687fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
6889f4f03454372e98844a5bcd785267820f294a2aeanthonystatic inline ssize_t MagickRound(MagickRealType x)
6899f4f03454372e98844a5bcd785267820f294a2aeanthony{
6909f4f03454372e98844a5bcd785267820f294a2aeanthony  /*
6919f4f03454372e98844a5bcd785267820f294a2aeanthony    Round the fraction to nearest integer.
6929f4f03454372e98844a5bcd785267820f294a2aeanthony  */
6939f4f03454372e98844a5bcd785267820f294a2aeanthony  if (x >= 0.0)
6949f4f03454372e98844a5bcd785267820f294a2aeanthony    return((ssize_t) (x+0.5));
6959f4f03454372e98844a5bcd785267820f294a2aeanthony  return((ssize_t) (x-0.5));
6969f4f03454372e98844a5bcd785267820f294a2aeanthony}
6979f4f03454372e98844a5bcd785267820f294a2aeanthony
6989f4f03454372e98844a5bcd785267820f294a2aeanthonyMagickExport Image *CropImageToTiles(const Image *image,
6999f4f03454372e98844a5bcd785267820f294a2aeanthony  const char *crop_geometry, ExceptionInfo *exception)
7009f4f03454372e98844a5bcd785267820f294a2aeanthony{
7019f4f03454372e98844a5bcd785267820f294a2aeanthony  Image
7029f4f03454372e98844a5bcd785267820f294a2aeanthony    *next,
7039f4f03454372e98844a5bcd785267820f294a2aeanthony    *crop_image;
7049f4f03454372e98844a5bcd785267820f294a2aeanthony
7059f4f03454372e98844a5bcd785267820f294a2aeanthony  MagickStatusType
7069f4f03454372e98844a5bcd785267820f294a2aeanthony    flags;
7079f4f03454372e98844a5bcd785267820f294a2aeanthony
7089f4f03454372e98844a5bcd785267820f294a2aeanthony  RectangleInfo
7099f4f03454372e98844a5bcd785267820f294a2aeanthony    geometry;
7109f4f03454372e98844a5bcd785267820f294a2aeanthony
7119f4f03454372e98844a5bcd785267820f294a2aeanthony  assert(image != (Image *) NULL);
7129f4f03454372e98844a5bcd785267820f294a2aeanthony  assert(image->signature == MagickSignature);
7139f4f03454372e98844a5bcd785267820f294a2aeanthony  if (image->debug != MagickFalse)
7149f4f03454372e98844a5bcd785267820f294a2aeanthony    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7159f4f03454372e98844a5bcd785267820f294a2aeanthony  crop_image=NewImageList();
7169f4f03454372e98844a5bcd785267820f294a2aeanthony  next=NewImageList();
7179f4f03454372e98844a5bcd785267820f294a2aeanthony  flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
7189f4f03454372e98844a5bcd785267820f294a2aeanthony  if ((flags & AreaValue) != 0)
7199f4f03454372e98844a5bcd785267820f294a2aeanthony    {
7209f4f03454372e98844a5bcd785267820f294a2aeanthony      PointInfo
7219f4f03454372e98844a5bcd785267820f294a2aeanthony        delta,
7229f4f03454372e98844a5bcd785267820f294a2aeanthony        offset;
7239f4f03454372e98844a5bcd785267820f294a2aeanthony
7249f4f03454372e98844a5bcd785267820f294a2aeanthony      RectangleInfo
7259f4f03454372e98844a5bcd785267820f294a2aeanthony        crop;
7269f4f03454372e98844a5bcd785267820f294a2aeanthony
727fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      size_t
728fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        height,
729fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        width;
730fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
7319f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
732fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        Crop into NxM tiles (@ flag).
7339f4f03454372e98844a5bcd785267820f294a2aeanthony      */
7349f4f03454372e98844a5bcd785267820f294a2aeanthony      width=image->columns;
7359f4f03454372e98844a5bcd785267820f294a2aeanthony      height=image->rows;
7369f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.width == 0)
7379f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.width=1;
7389f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.height == 0)
7399f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.height=1;
7409f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((flags & AspectValue) == 0)
7419f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7429f4f03454372e98844a5bcd785267820f294a2aeanthony          width-=(geometry.x < 0 ? -1 : 1)*geometry.x;
7439f4f03454372e98844a5bcd785267820f294a2aeanthony          height-=(geometry.y < 0 ? -1 : 1)*geometry.y;
7449f4f03454372e98844a5bcd785267820f294a2aeanthony        }
7459f4f03454372e98844a5bcd785267820f294a2aeanthony      else
7469f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7479f4f03454372e98844a5bcd785267820f294a2aeanthony          width+=(geometry.x < 0 ? -1 : 1)*geometry.x;
7489f4f03454372e98844a5bcd785267820f294a2aeanthony          height+=(geometry.y < 0 ? -1 : 1)*geometry.y;
7499f4f03454372e98844a5bcd785267820f294a2aeanthony        }
750240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.x=(double) width/geometry.width;
751240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.y=(double) height/geometry.height;
7529f4f03454372e98844a5bcd785267820f294a2aeanthony      for (offset.y=0; offset.y < (double) height; )
7539f4f03454372e98844a5bcd785267820f294a2aeanthony      {
7549f4f03454372e98844a5bcd785267820f294a2aeanthony        if ((flags & AspectValue) == 0)
7559f4f03454372e98844a5bcd785267820f294a2aeanthony          {
756fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.y=(ssize_t) MagickRound((MagickRealType) (offset.y-
757fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? 0 : geometry.y)));
7589f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;   /* increment now to find width */
759fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.height=(size_t) MagickRound((MagickRealType) (offset.y+
760fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y < 0 ? 0 : geometry.y)));
7619f4f03454372e98844a5bcd785267820f294a2aeanthony          }
7629f4f03454372e98844a5bcd785267820f294a2aeanthony        else
7639f4f03454372e98844a5bcd785267820f294a2aeanthony          {
764fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.y=(ssize_t) MagickRound((MagickRealType) (offset.y-
765fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? geometry.y : 0)));
7669f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;  /* increment now to find width */
7679f4f03454372e98844a5bcd785267820f294a2aeanthony            crop.height=(size_t) MagickRound((MagickRealType)
768fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (offset.y+(geometry.y < -1 ? geometry.y : 0)));
7699f4f03454372e98844a5bcd785267820f294a2aeanthony          }
7709f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.height-=crop.y;
7719f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.y+=image->page.y;
7729f4f03454372e98844a5bcd785267820f294a2aeanthony        for (offset.x=0; offset.x < (double) width; )
7739f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7749f4f03454372e98844a5bcd785267820f294a2aeanthony          if ((flags & AspectValue) == 0)
7759f4f03454372e98844a5bcd785267820f294a2aeanthony            {
776fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.x=(ssize_t) MagickRound((MagickRealType) (offset.x-
777fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x > 0 ? 0 : geometry.x)));
778fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
779fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.width=(size_t) MagickRound((MagickRealType) (offset.x+
780fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? 0 : geometry.x)));
7819f4f03454372e98844a5bcd785267820f294a2aeanthony            }
7829f4f03454372e98844a5bcd785267820f294a2aeanthony          else
7839f4f03454372e98844a5bcd785267820f294a2aeanthony            {
7849f4f03454372e98844a5bcd785267820f294a2aeanthony              crop.x=(ssize_t) MagickRound((MagickRealType) (offset.x-
7859f4f03454372e98844a5bcd785267820f294a2aeanthony                (geometry.x > 0 ? geometry.x : 0)));
786fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
787fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.width=(size_t) MagickRound((MagickRealType) (offset.x+
788fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? geometry.x : 0)));
7899f4f03454372e98844a5bcd785267820f294a2aeanthony            }
7909f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.width-=crop.x;
7919f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.x+=image->page.x;
792bf46f100b88be08a2bc295304011709b0fe2bccdcristy          next=CropImage(image,&crop,exception);
793bf46f100b88be08a2bc295304011709b0fe2bccdcristy          if (next == (Image *) NULL)
794bf46f100b88be08a2bc295304011709b0fe2bccdcristy            break;
795bf46f100b88be08a2bc295304011709b0fe2bccdcristy          AppendImageToList(&crop_image,next);
7969f4f03454372e98844a5bcd785267820f294a2aeanthony        }
7979f4f03454372e98844a5bcd785267820f294a2aeanthony        if (next == (Image *) NULL)
7989f4f03454372e98844a5bcd785267820f294a2aeanthony          break;
7999f4f03454372e98844a5bcd785267820f294a2aeanthony      }
80052224bff1c061e3532b0eeda2cff8d14375d9cb1cristy      ClearMagickException(exception);
8019f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8029f4f03454372e98844a5bcd785267820f294a2aeanthony    }
8039f4f03454372e98844a5bcd785267820f294a2aeanthony
8049f4f03454372e98844a5bcd785267820f294a2aeanthony  if (((geometry.width == 0) && (geometry.height == 0)) ||
8059f4f03454372e98844a5bcd785267820f294a2aeanthony      ((flags & XValue) != 0) || ((flags & YValue) != 0))
8069f4f03454372e98844a5bcd785267820f294a2aeanthony    {
8079f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
8089f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop a single region at +X+Y.
8099f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8109f4f03454372e98844a5bcd785267820f294a2aeanthony      crop_image=CropImage(image,&geometry,exception);
8119f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((crop_image != (Image *) NULL) && ((flags & AspectValue) != 0))
8129f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8139f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.width=geometry.width;
8149f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.height=geometry.height;
8159f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.x-=geometry.x;
8169f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.y-=geometry.y;
8179f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8189f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8199f4f03454372e98844a5bcd785267820f294a2aeanthony     }
820fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy  if ((image->columns > geometry.width) || (image->rows > geometry.height))
8219f4f03454372e98844a5bcd785267820f294a2aeanthony    {
822fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      RectangleInfo
823fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        page;
8249f4f03454372e98844a5bcd785267820f294a2aeanthony
8259f4f03454372e98844a5bcd785267820f294a2aeanthony      size_t
8269f4f03454372e98844a5bcd785267820f294a2aeanthony        height,
8279f4f03454372e98844a5bcd785267820f294a2aeanthony        width;
8289f4f03454372e98844a5bcd785267820f294a2aeanthony
8299f4f03454372e98844a5bcd785267820f294a2aeanthony      ssize_t
8309f4f03454372e98844a5bcd785267820f294a2aeanthony        x,
8319f4f03454372e98844a5bcd785267820f294a2aeanthony        y;
8329f4f03454372e98844a5bcd785267820f294a2aeanthony
8339f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
8349f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop into tiles of fixed size WxH.
8359f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8369f4f03454372e98844a5bcd785267820f294a2aeanthony      page=image->page;
8379f4f03454372e98844a5bcd785267820f294a2aeanthony      if (page.width == 0)
8389f4f03454372e98844a5bcd785267820f294a2aeanthony        page.width=image->columns;
8395ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (page.height == 0)
8409f4f03454372e98844a5bcd785267820f294a2aeanthony        page.height=image->rows;
8415ea220b92df1a6358ebb0f72c292375aca7ded18anthony      width=geometry.width;
8425ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (width == 0)
8435ea220b92df1a6358ebb0f72c292375aca7ded18anthony        width=page.width;
8445ea220b92df1a6358ebb0f72c292375aca7ded18anthony      height=geometry.height;
8455ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (height == 0)
8465ea220b92df1a6358ebb0f72c292375aca7ded18anthony        height=page.height;
8479f4f03454372e98844a5bcd785267820f294a2aeanthony      next=NewImageList();
8489f4f03454372e98844a5bcd785267820f294a2aeanthony      for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
8499f4f03454372e98844a5bcd785267820f294a2aeanthony      {
8509f4f03454372e98844a5bcd785267820f294a2aeanthony        for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
8519f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8529f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.width=width;
8539f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.height=height;
8549f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.x=x;
8559f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.y=y;
8569f4f03454372e98844a5bcd785267820f294a2aeanthony          next=CropImage(image,&geometry,exception);
8579f4f03454372e98844a5bcd785267820f294a2aeanthony          if (next == (Image *) NULL)
8589f4f03454372e98844a5bcd785267820f294a2aeanthony            break;
8599f4f03454372e98844a5bcd785267820f294a2aeanthony          AppendImageToList(&crop_image,next);
8609f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8619f4f03454372e98844a5bcd785267820f294a2aeanthony        if (next == (Image *) NULL)
8629f4f03454372e98844a5bcd785267820f294a2aeanthony          break;
8639f4f03454372e98844a5bcd785267820f294a2aeanthony      }
8649f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8659f4f03454372e98844a5bcd785267820f294a2aeanthony    }
8669f4f03454372e98844a5bcd785267820f294a2aeanthony  return(CloneImage(image,0,0,MagickTrue,exception));
8679f4f03454372e98844a5bcd785267820f294a2aeanthony}
8689f4f03454372e98844a5bcd785267820f294a2aeanthony
8699f4f03454372e98844a5bcd785267820f294a2aeanthony/*
8709f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8719f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8729f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8739f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x c e r p t I m a g e                                                   %
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExcerptImage() returns a excerpt of the image as defined by the geometry.
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExcerptImage method is:
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExcerptImage(const Image *image,const RectangleInfo *geometry,
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExcerptImage(const Image *image,
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define ExcerptImageTag  "Excerpt/Image"
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
902c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
903c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *excerpt_view,
904c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
905c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *excerpt_image;
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
915bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
916bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate excerpt image.
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (excerpt_image == (Image *) NULL)
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Excerpt each row.
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_view=AcquireCacheView(excerpt_image);
939b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
940b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
942bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) excerpt_image->rows; y++)
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9444c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
945c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9474c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
948c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9504c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
9514c08aed51c5899665ade97263692328eea4af106cristy      x;
9524c08aed51c5899665ade97263692328eea4af106cristy
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      geometry->width,1,exception);
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
9594c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9644c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) excerpt_image->columns; x++)
9654c08aed51c5899665ade97263692328eea4af106cristy    {
966010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
967010d7d107ddf63501993c10081f891891850dffecristy        i;
968010d7d107ddf63501993c10081f891891850dffecristy
969010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
970010d7d107ddf63501993c10081f891891850dffecristy      {
971010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
972010d7d107ddf63501993c10081f891891850dffecristy          channel;
973010d7d107ddf63501993c10081f891891850dffecristy
974010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
975010d7d107ddf63501993c10081f891891850dffecristy          excerpt_traits,
976010d7d107ddf63501993c10081f891891850dffecristy          traits;
977010d7d107ddf63501993c10081f891891850dffecristy
978010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
979010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
980010d7d107ddf63501993c10081f891891850dffecristy        excerpt_traits=GetPixelChannelMapTraits(excerpt_image,channel);
981010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
982010d7d107ddf63501993c10081f891891850dffecristy            (excerpt_traits == UndefinedPixelTrait))
983010d7d107ddf63501993c10081f891891850dffecristy          continue;
9840beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(excerpt_image,channel,p[i],q);
985010d7d107ddf63501993c10081f891891850dffecristy      }
986ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
987ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(excerpt_image);
9884c08aed51c5899665ade97263692328eea4af106cristy    }
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
996b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_ExcerptImage)
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,ExcerptImageTag,progress++,image->rows);
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_view=DestroyCacheView(excerpt_view);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image->type=image->type;
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    excerpt_image=DestroyImage(excerpt_image);
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(excerpt_image);
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x t e n t I m a g e                                                     %
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExtentImage() extends the image as defined by the geometry, gravity, and
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image background color.  Set the (x,y) offset of the geometry to move the
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  original image relative to the extended image.
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExtentImage method is:
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExtentImage(const Image *image,const RectangleInfo *geometry,
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExtentImage(const Image *image,
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *extent_image;
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate extent image.
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent_image == (Image *) NULL)
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1062574cc26500992189f637cd1cdf93d0654e7df7aecristy  if (SetImageStorageClass(extent_image,DirectClass,exception) == MagickFalse)
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent_image=DestroyImage(extent_image);
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10674c08aed51c5899665ade97263692328eea4af106cristy  if (extent_image->background_color.alpha != OpaqueAlpha)
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent_image->matte=MagickTrue;
1069ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(extent_image,exception);
107045b6261b491fdea4061abdedc40604e6b62d725fcristy  (void) CompositeImage(extent_image,image->compose,image,-geometry->x,
1071e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    -geometry->y,exception);
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(extent_image);
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l i p I m a g e                                                         %
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlipImage() creates a vertical mirror image by reflecting the pixels
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis.
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlipImage method is:
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlipImage(const Image *image,ExceptionInfo *exception)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlipImage(const Image *image,ExceptionInfo *exception)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlipImageTag  "Flip/Image"
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1104c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1105c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flip_view,
1106c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1107c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flip_image;
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1114bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1115bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
111774ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
111874ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
111974ea2cdfae92d1caf613481a3f69f75901168258cristy
1120bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1121bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1122bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flip_image == (Image *) NULL)
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flip image.
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
113774ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_view=AcquireCacheView(flip_image);
11405db1f09460168afa2a3119ba98c01cf7c975756ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
114109d81172fd193d98a4d6d433da0ccf1406a4f93ecristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1143bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flip_image->rows; y++)
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11454c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1146c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11484c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1149c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11514c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
11524c08aed51c5899665ade97263692328eea4af106cristy      x;
11534c08aed51c5899665ade97263692328eea4af106cristy
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
11575db1f09460168afa2a3119ba98c01cf7c975756ccristy    q=QueueCacheViewAuthenticPixels(flip_view,0,(ssize_t) (flip_image->rows-y-
11585db1f09460168afa2a3119ba98c01cf7c975756ccristy      1),flip_image->columns,1,exception);
11594c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11644c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) flip_image->columns; x++)
11654c08aed51c5899665ade97263692328eea4af106cristy    {
1166010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1167010d7d107ddf63501993c10081f891891850dffecristy        i;
1168010d7d107ddf63501993c10081f891891850dffecristy
1169010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1170010d7d107ddf63501993c10081f891891850dffecristy      {
1171010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1172010d7d107ddf63501993c10081f891891850dffecristy          channel;
1173010d7d107ddf63501993c10081f891891850dffecristy
1174010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1175010d7d107ddf63501993c10081f891891850dffecristy          flip_traits,
1176010d7d107ddf63501993c10081f891891850dffecristy          traits;
1177010d7d107ddf63501993c10081f891891850dffecristy
1178010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1179010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1180010d7d107ddf63501993c10081f891891850dffecristy        flip_traits=GetPixelChannelMapTraits(flip_image,channel);
1181010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1182010d7d107ddf63501993c10081f891891850dffecristy            (flip_traits == UndefinedPixelTrait))
1183010d7d107ddf63501993c10081f891891850dffecristy          continue;
11840beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flip_image,channel,p[i],q);
1185010d7d107ddf63501993c10081f891891850dffecristy      }
1186ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1187ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(flip_image);
11884c08aed51c5899665ade97263692328eea4af106cristy    }
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11962224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_FlipImage)
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlipImageTag,progress++,image->rows);
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_view=DestroyCacheView(flip_view);
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image->type=image->type;
120737a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.height != 0)
120837a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.y=(ssize_t) (page.height-flip_image->rows-page.y);
120974ea2cdfae92d1caf613481a3f69f75901168258cristy  flip_image->page=page;
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flip_image=DestroyImage(flip_image);
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flip_image);
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l o p I m a g e                                                         %
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlopImage() creates a horizontal mirror image by reflecting the pixels
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis.
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlopImage method is:
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlopImage(const Image *image,ExceptionInfo *exception)
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlopImage(const Image *image,ExceptionInfo *exception)
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlopImageTag  "Flop/Image"
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1244c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1245c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flop_view,
1246c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1247c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flop_image;
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1254bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1255bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
125774ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
125874ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
125974ea2cdfae92d1caf613481a3f69f75901168258cristy
1260bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1262bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flop_image == (Image *) NULL)
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flop each row.
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
127774ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_view=AcquireCacheView(flop_image);
12805db1f09460168afa2a3119ba98c01cf7c975756ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
128109d81172fd193d98a4d6d433da0ccf1406a4f93ecristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status) omp_throttle(1)
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flop_image->rows; y++)
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12854c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1286c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12914c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1292c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
12994c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1304ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(flop_image)*flop_image->columns;
1305bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) flop_image->columns; x++)
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1307010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1308010d7d107ddf63501993c10081f891891850dffecristy        i;
1309010d7d107ddf63501993c10081f891891850dffecristy
1310ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(flop_image);
1311010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1312010d7d107ddf63501993c10081f891891850dffecristy      {
1313010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1314010d7d107ddf63501993c10081f891891850dffecristy          channel;
1315010d7d107ddf63501993c10081f891891850dffecristy
1316010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1317010d7d107ddf63501993c10081f891891850dffecristy          flop_traits,
1318010d7d107ddf63501993c10081f891891850dffecristy          traits;
1319010d7d107ddf63501993c10081f891891850dffecristy
1320010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1321010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1322010d7d107ddf63501993c10081f891891850dffecristy        flop_traits=GetPixelChannelMapTraits(flop_image,channel);
1323010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1324010d7d107ddf63501993c10081f891891850dffecristy            (flop_traits == UndefinedPixelTrait))
1325010d7d107ddf63501993c10081f891891850dffecristy          continue;
13260beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flop_image,channel,p[i],q);
1327010d7d107ddf63501993c10081f891891850dffecristy      }
1328ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1337b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_FlopImage)
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlopImageTag,progress++,image->rows);
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_view=DestroyCacheView(flop_view);
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image->type=image->type;
134837a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.width != 0)
134937a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.x=(ssize_t) (page.width-flop_image->columns-page.x);
135074ea2cdfae92d1caf613481a3f69f75901168258cristy  flop_image->page=page;
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flop_image=DestroyImage(flop_image);
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flop_image);
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R o l l I m a g e                                                         %
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RollImage() offsets an image as defined by x_offset and y_offset.
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RollImage method is:
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      Image *RollImage(const Image *image,const ssize_t x_offset,
1372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        const ssize_t y_offset,ExceptionInfo *exception)
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o x_offset: the number of columns to roll in the horizontal direction.
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o y_offset: the number of rows to roll in the vertical direction.
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline MagickBooleanType CopyImageRegion(Image *destination,
1387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const Image *source,const size_t columns,const size_t rows,
1388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const ssize_t sx,const ssize_t sy,const ssize_t dx,const ssize_t dy,
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1391c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1392c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *source_view,
1393c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *destination_view;
1394c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13989d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
13999d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
14009d314ff2c17a77996c05413c2013880387e50f0ecristy
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  source_view=AcquireCacheView(source);
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_view=AcquireCacheView(destination);
1404b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1405b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(status)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1407bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) rows; y++)
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14124c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1413c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14154c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1416c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14184c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
14194c08aed51c5899665ade97263692328eea4af106cristy      x;
14204c08aed51c5899665ade97263692328eea4af106cristy
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer scanline.
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
14284c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
14334c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) columns; x++)
14344c08aed51c5899665ade97263692328eea4af106cristy    {
1435010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1436010d7d107ddf63501993c10081f891891850dffecristy        i;
1437010d7d107ddf63501993c10081f891891850dffecristy
1438010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1439010d7d107ddf63501993c10081f891891850dffecristy      {
1440010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1441010d7d107ddf63501993c10081f891891850dffecristy          channel;
1442010d7d107ddf63501993c10081f891891850dffecristy
1443010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1444010d7d107ddf63501993c10081f891891850dffecristy          destination_traits,
1445010d7d107ddf63501993c10081f891891850dffecristy          source_traits;
1446010d7d107ddf63501993c10081f891891850dffecristy
1447010d7d107ddf63501993c10081f891891850dffecristy        source_traits=GetPixelChannelMapTraits(source,(PixelChannel) i);
1448010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(source,(PixelChannel) i);
1449010d7d107ddf63501993c10081f891891850dffecristy        destination_traits=GetPixelChannelMapTraits(destination,channel);
1450010d7d107ddf63501993c10081f891891850dffecristy        if ((source_traits == UndefinedPixelTrait) ||
1451010d7d107ddf63501993c10081f891891850dffecristy            (destination_traits == UndefinedPixelTrait))
1452010d7d107ddf63501993c10081f891891850dffecristy          continue;
14530beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(destination,channel,p[i],q);
1454010d7d107ddf63501993c10081f891891850dffecristy      }
1455ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(source);
1456ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(destination);
14574c08aed51c5899665ade97263692328eea4af106cristy    }
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(destination_view,exception);
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_view=DestroyCacheView(destination_view);
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  source_view=DestroyCacheView(source_view);
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport Image *RollImage(const Image *image,const ssize_t x_offset,
1468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const ssize_t y_offset,ExceptionInfo *exception)
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RollImageTag  "Roll/Image"
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *roll_image;
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize roll image attributes.
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (roll_image == (Image *) NULL)
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.x=x_offset;
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.y=y_offset;
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.x < 0)
1496eaedf06777741da32408da72c1e512975c600c48cristy    offset.x+=(ssize_t) image->columns;
1497bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.x >= (ssize_t) image->columns)
1498eaedf06777741da32408da72c1e512975c600c48cristy    offset.x-=(ssize_t) image->columns;
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.y < 0)
1500eaedf06777741da32408da72c1e512975c600c48cristy    offset.y+=(ssize_t) image->rows;
1501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.y >= (ssize_t) image->rows)
1502eaedf06777741da32408da72c1e512975c600c48cristy    offset.y-=(ssize_t) image->rows;
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Roll image.
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1506bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  status=CopyImageRegion(roll_image,image,(size_t) offset.x,
1507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,exception);
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,0,3);
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status|=CopyImageRegion(roll_image,image,image->columns-offset.x,
1511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,0,(ssize_t) image->rows-offset.y,offset.x,0,
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,1,3);
1514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  status|=CopyImageRegion(roll_image,image,(size_t) offset.x,image->rows-
1515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    offset.y,(ssize_t) image->columns-offset.x,0,0,offset.y,exception);
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,2,3);
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status|=CopyImageRegion(roll_image,image,image->columns-offset.x,image->rows-
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,offset.x,offset.y,exception);
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,3,3);
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image->type=image->type;
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    roll_image=DestroyImage(roll_image);
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(roll_image);
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S h a v e I m a g e                                                       %
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ShaveImage() shaves pixels from the image edges.  It allocates the memory
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ShaveImage method is:
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ShaveImage(const Image *image,const RectangleInfo *shave_info,
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_image: Method ShaveImage returns a pointer to the shaved
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      image.  A null image is returned if there is a memory shortage or
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      if the image width or height is zero.
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_info: Specifies a pointer to a RectangleInfo which defines the
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      region of the image to crop.
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ShaveImage(const Image *image,
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *shave_info,ExceptionInfo *exception)
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *shave_image;
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((2*shave_info->width) >= image->columns) ||
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((2*shave_info->height) >= image->rows))
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowImageException(OptionWarning,"GeometryDoesNotContainImage");
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SetGeometry(image,&geometry);
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.width-=2*shave_info->width;
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.height-=2*shave_info->height;
1579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.x=(ssize_t) shave_info->width+image->page.x;
1580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.y=(ssize_t) shave_info->height+image->page.y;
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image=CropImage(image,&geometry,exception);
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (shave_image == (Image *) NULL)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.width-=2*shave_info->width;
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.height-=2*shave_info->height;
1586eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.x-=(ssize_t) shave_info->width;
1587eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.y-=(ssize_t) shave_info->height;
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(shave_image);
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S p l i c e I m a g e                                                     %
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  SpliceImage() splices a solid color into the image as defined by the
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry.
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the SpliceImage method is:
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *SpliceImage(const Image *image,const RectangleInfo *geometry,
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to splice with members
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *SpliceImage(const Image *image,
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define SpliceImageTag  "Splice/Image"
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1625c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1626c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
1627c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *splice_view;
1628c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *splice_image;
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1637bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_geometry;
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate splice image.
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_geometry=(*geometry);
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_image=CloneImage(image,image->columns+splice_geometry.width,
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->rows+splice_geometry.height,MagickTrue,exception);
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (splice_image == (Image *) NULL)
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1659574cc26500992189f637cd1cdf93d0654e7df7aecristy  if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      splice_image=DestroyImage(splice_image);
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1664ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(splice_image,exception);
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Respect image geometry.
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (image->gravity)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedGravity:
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthWestGravity:
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthGravity:
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1676eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthEastGravity:
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1681eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case WestGravity:
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1686eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.width/2;
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case StaticGravity:
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case CenterGravity:
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1692eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1693eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case EastGravity:
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1698eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1699eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthWestGravity:
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1704eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthGravity:
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1709eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1710eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthEastGravity:
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1715eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1716eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Splice image.
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_view=AcquireCacheView(splice_image);
1727b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1728b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) splice_geometry.y; y++)
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17324c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1733c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17384c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1739c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
17464c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < splice_geometry.x; x++)
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1753010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1754010d7d107ddf63501993c10081f891891850dffecristy        i;
1755010d7d107ddf63501993c10081f891891850dffecristy
1756010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1757010d7d107ddf63501993c10081f891891850dffecristy      {
1758010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1759010d7d107ddf63501993c10081f891891850dffecristy          channel;
1760010d7d107ddf63501993c10081f891891850dffecristy
1761010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1762010d7d107ddf63501993c10081f891891850dffecristy          splice_traits,
1763010d7d107ddf63501993c10081f891891850dffecristy          traits;
1764010d7d107ddf63501993c10081f891891850dffecristy
1765010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1766010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1767010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1768010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1769010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1770010d7d107ddf63501993c10081f891891850dffecristy          continue;
17710beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1772010d7d107ddf63501993c10081f891891850dffecristy      }
1773ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1774ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1777ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
1778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) splice_image->columns; x++)
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1780010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1781010d7d107ddf63501993c10081f891891850dffecristy        i;
1782010d7d107ddf63501993c10081f891891850dffecristy
1783010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1784010d7d107ddf63501993c10081f891891850dffecristy      {
1785010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1786010d7d107ddf63501993c10081f891891850dffecristy          channel;
1787010d7d107ddf63501993c10081f891891850dffecristy
1788010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1789010d7d107ddf63501993c10081f891891850dffecristy          traits,
1790010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1791010d7d107ddf63501993c10081f891891850dffecristy
1792010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1793010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1794010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1795010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1796010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1797010d7d107ddf63501993c10081f891891850dffecristy          continue;
17980beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1799010d7d107ddf63501993c10081f891891850dffecristy      }
1800ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1801ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1810b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_TransposeImage)
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1819b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1820b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1822bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=(ssize_t) (splice_geometry.y+splice_geometry.height);
1823bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy       y < (ssize_t) splice_image->rows; y++)
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18254c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1826c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18314c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1832c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
1836eaedf06777741da32408da72c1e512975c600c48cristy    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns,1,exception);
183813d07043243e0c8c151aad7db5240b75e76ca281cristy    if ((y < 0) || (y >= (ssize_t) splice_image->rows))
18392224dcdd80d774e98907ebb870f62792e942b73bcristy      continue;
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
18424c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < splice_geometry.x; x++)
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1849010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1850010d7d107ddf63501993c10081f891891850dffecristy        i;
1851010d7d107ddf63501993c10081f891891850dffecristy
1852010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1853010d7d107ddf63501993c10081f891891850dffecristy      {
1854010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1855010d7d107ddf63501993c10081f891891850dffecristy          channel;
1856010d7d107ddf63501993c10081f891891850dffecristy
1857010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1858010d7d107ddf63501993c10081f891891850dffecristy          traits,
1859010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1860010d7d107ddf63501993c10081f891891850dffecristy
1861010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1862010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1863010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1864010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1865010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1866010d7d107ddf63501993c10081f891891850dffecristy          continue;
18670beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1868010d7d107ddf63501993c10081f891891850dffecristy      }
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
1879010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1880010d7d107ddf63501993c10081f891891850dffecristy      {
1881010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1882010d7d107ddf63501993c10081f891891850dffecristy          channel;
1883010d7d107ddf63501993c10081f891891850dffecristy
1884010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1885010d7d107ddf63501993c10081f891891850dffecristy          traits,
1886010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1887010d7d107ddf63501993c10081f891891850dffecristy
1888010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
1889010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
1890010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1891010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1892010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1893010d7d107ddf63501993c10081f891891850dffecristy          continue;
18940beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1895010d7d107ddf63501993c10081f891891850dffecristy      }
1896ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1897ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1906b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_TransposeImage)
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_view=DestroyCacheView(splice_view);
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_image=DestroyImage(splice_image);
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(splice_image);
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s f o r m I m a g e                                               %
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransformImage() is a convenience method that behaves like ResizeImage() or
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() but accepts scaling and/or cropping information as a region
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry specification.  If the operation fails, the original image handle
19369f4f03454372e98844a5bcd785267820f294a2aeanthony%  is left as is.
19379f4f03454372e98844a5bcd785267820f294a2aeanthony%
19389f4f03454372e98844a5bcd785267820f294a2aeanthony%  This should only be used for single images.
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1940010d7d107ddf63501993c10081f891891850dffecristy%  This function destroys what it assumes to be a single image list.
1941010d7d107ddf63501993c10081f891891850dffecristy%  If the input image is part of a larger list, all other images in that list
1942010d7d107ddf63501993c10081f891891850dffecristy%  will be simply 'lost', not destroyed.
1943010d7d107ddf63501993c10081f891891850dffecristy%
1944010d7d107ddf63501993c10081f891891850dffecristy%  Also if the crop generates a list of images only the first image is resized.
1945010d7d107ddf63501993c10081f891891850dffecristy%  And finally if the crop succeeds and the resize failed, you will get a
1946010d7d107ddf63501993c10081f891891850dffecristy%  cropped image, as well as a 'false' or 'failed' report.
1947010d7d107ddf63501993c10081f891891850dffecristy%
1948010d7d107ddf63501993c10081f891891850dffecristy%  This function and should probably be depreciated in favor of direct calls
1949010d7d107ddf63501993c10081f891891850dffecristy%  to CropImageToTiles() or ResizeImage(), as appropriate.
1950010d7d107ddf63501993c10081f891891850dffecristy%
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransformImage method is:
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType TransformImage(Image **image,const char *crop_geometry,
1954e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        const char *image_geometry,ExceptionInfo *exception)
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image The transformed image is returned as this parameter.
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o crop_geometry: A crop geometry string.  This geometry defines a
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      subregion of the image to crop.
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_geometry: An image geometry string.  This geometry defines the
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      final size of the image.
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1966e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%    o exception: return any errors or warnings in this structure.
1967e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType TransformImage(Image **image,
1970e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  const char *crop_geometry,const char *image_geometry,ExceptionInfo *exception)
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *resize_image,
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transform_image;
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flags;
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image **) NULL);
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert((*image)->signature == MagickSignature);
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*image)->debug != MagickFalse)
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=(*image);
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_geometry != (const char *) NULL)
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop image to a user specified size.
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1995e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy      crop_image=CropImageToTiles(*image,crop_geometry,exception);
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
1997e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy        transform_image=CloneImage(*image,0,0,MagickTrue,exception);
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=DestroyImage(transform_image);
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=GetFirstImageInList(crop_image);
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *image=transform_image;
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_geometry == (const char *) NULL)
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
20079f4f03454372e98844a5bcd785267820f294a2aeanthony
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Scale image to a user specified size.
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2011e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  flags=ParseRegionGeometry(transform_image,image_geometry,&geometry,exception);
2012288b08013aef4f65779ab374a4e285d3247f5dbbcristy  (void) flags;
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((transform_image->columns == geometry.width) &&
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (transform_image->rows == geometry.height))
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
201615b98cde1f8098cb20bceac08481ba6def4efb97cristy  resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2017e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    transform_image->filter,transform_image->blur,exception);
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (resize_image == (Image *) NULL)
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=DestroyImage(transform_image);
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=resize_image;
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *image=transform_image;
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s f o r m I m a g e s                                             %
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2034bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony%                                                                             %
2035bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransformImages() calls TransformImage() on each image of a sequence.
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransformImage method is:
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType TransformImages(Image **image,
2042e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        const char *crop_geometry,const char *image_geometry,
2043e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        ExceptionInfo *exception)
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image The transformed image is returned as this parameter.
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o crop_geometry: A crop geometry string.  This geometry defines a
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      subregion of the image to crop.
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_geometry: An image geometry string.  This geometry defines the
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      final size of the image.
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2055e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%    o exception: return any errors or warnings in this structure.
2056e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType TransformImages(Image **images,
2059e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  const char *crop_geometry,const char *image_geometry,ExceptionInfo *exception)
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **image_list,
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transform_images;
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2069bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image **) NULL);
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert((*images)->signature == MagickSignature);
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*images)->debug != MagickFalse)
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*images)->filename);
2077e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  image_list=ImageListToArray(*images,exception);
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_list == (Image **) NULL)
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_images=NewImageList();
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; image_list[i] != (Image *) NULL; i++)
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=image_list[i];
2085e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    status|=TransformImage(&image,crop_geometry,image_geometry,exception);
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    AppendImageToList(&transform_images,image);
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *images=transform_images;
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_list=(Image **) RelinquishMagickMemory(image_list);
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status != 0 ? MagickTrue : MagickFalse);
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s p o s e I m a g e                                               %
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransposeImage() creates a horizontal mirror image by reflecting the pixels
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis while rotating them by 90 degrees.
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransposeImage method is:
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransposeImageTag  "Transpose/Image"
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2122c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2123c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2124c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transpose_view;
2125c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transpose_image;
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2133bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2138bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2140bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transpose_image == (Image *) NULL)
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transpose image.
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_view=AcquireCacheView(transpose_image);
2158b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2159b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
21634c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
2164c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21664c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
2167c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21694c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
21704c08aed51c5899665ade97263692328eea4af106cristy      x;
21714c08aed51c5899665ade97263692328eea4af106cristy
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
2174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns,1,exception);
21769af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy    q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) (image->rows-y-1),
21779af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy      0,1,transpose_image->rows,exception);
21784c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
21834c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) image->columns; x++)
21844c08aed51c5899665ade97263692328eea4af106cristy    {
2185010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2186010d7d107ddf63501993c10081f891891850dffecristy        i;
2187010d7d107ddf63501993c10081f891891850dffecristy
2188010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2189010d7d107ddf63501993c10081f891891850dffecristy      {
2190010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
2191010d7d107ddf63501993c10081f891891850dffecristy          channel;
2192010d7d107ddf63501993c10081f891891850dffecristy
2193010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
2194010d7d107ddf63501993c10081f891891850dffecristy          traits,
2195010d7d107ddf63501993c10081f891891850dffecristy          transpose_traits;
2196010d7d107ddf63501993c10081f891891850dffecristy
2197010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
2198010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
2199010d7d107ddf63501993c10081f891891850dffecristy        transpose_traits=GetPixelChannelMapTraits(transpose_image,channel);
2200010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2201010d7d107ddf63501993c10081f891891850dffecristy            (transpose_traits == UndefinedPixelTrait))
2202010d7d107ddf63501993c10081f891891850dffecristy          continue;
22030beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transpose_image,channel,p[i],q);
2204010d7d107ddf63501993c10081f891891850dffecristy      }
2205ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2206ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(transpose_image);
22074c08aed51c5899665ade97263692328eea4af106cristy    }
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2215b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_TransposeImage)
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransposeImageTag,progress++,
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_view=DestroyCacheView(transpose_view);
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->type=image->type;
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transpose_image->page;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->page=page;
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transpose_image=DestroyImage(transpose_image);
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transpose_image);
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s v e r s e I m a g e                                             %
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransverseImage() creates a vertical mirror image by reflecting the pixels
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis while rotating them by 270 degrees.
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransverseImage method is:
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransverseImage(const Image *image,ExceptionInfo *exception)
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransverseImage(const Image *image,ExceptionInfo *exception)
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransverseImageTag  "Transverse/Image"
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2265c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2266c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2267c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transverse_view;
2268c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transverse_image;
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2277bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2281bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2282bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transverse_image == (Image *) NULL)
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transverse image.
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_view=AcquireCacheView(transverse_image);
2301b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2302b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy  #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2304bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23094c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
2310c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23124c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
2313c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2315010d7d107ddf63501993c10081f891891850dffecristy    register ssize_t
2316010d7d107ddf63501993c10081f891891850dffecristy      x;
2317010d7d107ddf63501993c10081f891891850dffecristy
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2321010d7d107ddf63501993c10081f891891850dffecristy    q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) (image->rows-y-1),
2322010d7d107ddf63501993c10081f891891850dffecristy      0,1,transverse_image->rows,exception);
23234c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2328ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(transverse_image)*image->columns;
2329bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
23304c08aed51c5899665ade97263692328eea4af106cristy    {
2331010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2332010d7d107ddf63501993c10081f891891850dffecristy        i;
2333010d7d107ddf63501993c10081f891891850dffecristy
2334ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(transverse_image);
2335010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2336010d7d107ddf63501993c10081f891891850dffecristy      {
2337010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
2338010d7d107ddf63501993c10081f891891850dffecristy          channel;
2339010d7d107ddf63501993c10081f891891850dffecristy
2340010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
2341010d7d107ddf63501993c10081f891891850dffecristy          traits,
2342010d7d107ddf63501993c10081f891891850dffecristy          transverse_traits;
2343010d7d107ddf63501993c10081f891891850dffecristy
2344010d7d107ddf63501993c10081f891891850dffecristy        traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
2345010d7d107ddf63501993c10081f891891850dffecristy        channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
2346010d7d107ddf63501993c10081f891891850dffecristy        transverse_traits=GetPixelChannelMapTraits(transverse_image,channel);
2347010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2348010d7d107ddf63501993c10081f891891850dffecristy            (transverse_traits == UndefinedPixelTrait))
2349010d7d107ddf63501993c10081f891891850dffecristy          continue;
23500beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transverse_image,channel,p[i],q);
2351010d7d107ddf63501993c10081f891891850dffecristy      }
2352ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
23534c08aed51c5899665ade97263692328eea4af106cristy    }
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2362b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  #pragma omp critical (MagickCore_TransverseImage)
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransverseImageTag,progress++,
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_view=DestroyCacheView(transverse_view);
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->type=image->type;
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transverse_image->page;
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
2377bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony  if (page.width != 0)
2378bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony    page.x=(ssize_t) (page.width-transverse_image->columns-page.x);
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height != 0)
2380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    page.y=(ssize_t) (page.height-transverse_image->rows-page.y);
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->page=page;
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transverse_image=DestroyImage(transverse_image);
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transverse_image);
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r i m I m a g e                                                         %
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TrimImage() trims pixels from the image edges.  It allocates the memory
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TrimImage method is:
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TrimImage(const Image *image,ExceptionInfo *exception)
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TrimImage(const Image *image,ExceptionInfo *exception)
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry=GetImageBoundingBox(image,exception);
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((geometry.width == 0) || (geometry.height == 0))
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
24314c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
2432ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=image->page;
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.x+=image->page.x;
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.y+=image->page.y;
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(CropImage(image,&geometry,exception));
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2442