transform.c revision 10a6c61544fb48d72f29ec8f9573bdcd52abf1b7
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%                                                                             %
201454be7db7a897f42cd40e4165f945d77196a6f8cristy%  Copyright 1999-2012 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)
163195938723ce0d7e6780967dd2ada36aec15fe4bfcristy  #pragma omp parallel for schedule(static) shared(progress,status)
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
19310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          if (GetPixelMask(image,p) != 0)
19410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy            {
19510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy              q+=GetPixelChannels(chop_image);
19610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy              continue;
19710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy            }
198d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
199d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
200d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelChannel
201d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              channel;
202d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
203d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelTrait
204d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              chop_traits,
205d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              traits;
206d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
207abace416e67464ca6dac2324410667b05076a9c2cristy            channel=GetPixelChannelMapChannel(image,i);
208abace416e67464ca6dac2324410667b05076a9c2cristy            traits=GetPixelChannelMapTraits(image,channel);
209d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            chop_traits=GetPixelChannelMapTraits(chop_image,channel);
210d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
211d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
212d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
2130beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
214d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
215ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
217ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
22000f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
221c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
222c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
223c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
224c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
225c2b1fb8afe233b177178e0ac55e86d266165090bcristy
2262224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
227a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ChopImage)
228c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
229c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
230c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
231c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
232c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Extract chop image.
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2372224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
238195938723ce0d7e6780967dd2ada36aec15fe4bfcristy  #pragma omp parallel for schedule(static) shared(progress,status)
23909d81172fd193d98a4d6d433da0ccf1406a4f93ecristy#endif
240bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) (image->rows-(extent.y+extent.height)); y++)
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2424c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
243c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
245bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2484c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
249c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25100f953722c2a11066e14e969e9b0a611abf01e8bcristy    if (status == MagickFalse)
25200f953722c2a11066e14e969e9b0a611abf01e8bcristy      continue;
253c2b1fb8afe233b177178e0ac55e86d266165090bcristy    p=GetCacheViewVirtualPixels(image_view,0,extent.y+extent.height+y,
254c2b1fb8afe233b177178e0ac55e86d266165090bcristy      image->columns,1,exception);
255c2b1fb8afe233b177178e0ac55e86d266165090bcristy    q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
256c2b1fb8afe233b177178e0ac55e86d266165090bcristy      1,exception);
2574c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
25800f953722c2a11066e14e969e9b0a611abf01e8bcristy      {
25900f953722c2a11066e14e969e9b0a611abf01e8bcristy        status=MagickFalse;
26000f953722c2a11066e14e969e9b0a611abf01e8bcristy        continue;
26100f953722c2a11066e14e969e9b0a611abf01e8bcristy      }
262bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
266d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          register ssize_t
267d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            i;
268d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
26910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy         if (GetPixelMask(image,p) != 0)
27010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy           {
27110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy             p+=GetPixelChannels(image);
27210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy             q+=GetPixelChannels(chop_image);
27310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy             continue;
27410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy           }
275d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
276d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
277d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelChannel
278d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              channel;
279d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
280d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            PixelTrait
281d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              chop_traits,
282d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              traits;
283d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
284abace416e67464ca6dac2324410667b05076a9c2cristy            channel=GetPixelChannelMapChannel(image,i);
285abace416e67464ca6dac2324410667b05076a9c2cristy            traits=GetPixelChannelMapTraits(image,channel);
286d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            chop_traits=GetPixelChannelMapTraits(chop_image,channel);
287d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            if ((traits == UndefinedPixelTrait) ||
288d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy                (chop_traits == UndefinedPixelTrait))
289d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy              continue;
2900beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy            SetPixelChannel(chop_image,channel,p[i],q);
291d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
29210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(chop_image);
293ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(chop_image);
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
295ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
29800f953722c2a11066e14e969e9b0a611abf01e8bcristy      status=MagickFalse;
299c2b1fb8afe233b177178e0ac55e86d266165090bcristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
300c2b1fb8afe233b177178e0ac55e86d266165090bcristy      {
301c2b1fb8afe233b177178e0ac55e86d266165090bcristy        MagickBooleanType
302c2b1fb8afe233b177178e0ac55e86d266165090bcristy          proceed;
303c2b1fb8afe233b177178e0ac55e86d266165090bcristy
3042224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
305a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ChopImage)
306c2b1fb8afe233b177178e0ac55e86d266165090bcristy#endif
307c2b1fb8afe233b177178e0ac55e86d266165090bcristy        proceed=SetImageProgress(image,ChopImageTag,progress++,image->rows);
308c2b1fb8afe233b177178e0ac55e86d266165090bcristy        if (proceed == MagickFalse)
309c2b1fb8afe233b177178e0ac55e86d266165090bcristy          status=MagickFalse;
310c2b1fb8afe233b177178e0ac55e86d266165090bcristy      }
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_view=DestroyCacheView(chop_view);
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chop_image->type=image->type;
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(chop_image);
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+     C o n s o l i d a t e C M Y K I m a g e                                 %
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ConsolidateCMYKImage() consolidates separate C, M, Y, and K planes into a
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  single image.
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ConsolidateCMYKImage method is:
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ConsolidateCMYKImage(const Image *image,ExceptionInfo *exception)
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image sequence.
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ConsolidateCMYKImages(const Image *images,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
346c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy  CacheView
347c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *cmyk_view,
348c5c6f66d8eed62757aeda7f05848d8a8ddc7975acristy    *image_view;
3492224dcdd80d774e98907ebb870f62792e942b73bcristy
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_image,
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *cmyk_images;
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
355d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    j;
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3572224dcdd80d774e98907ebb870f62792e942b73bcristy  ssize_t
3582224dcdd80d774e98907ebb870f62792e942b73bcristy    y;
3592224dcdd80d774e98907ebb870f62792e942b73bcristy
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Consolidate separate C, M, Y, and K planes into a single image.
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image *) NULL);
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images->signature == MagickSignature);
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (images->debug != MagickFalse)
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  cmyk_images=NewImageList();
370d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy  for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
372d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    register ssize_t
373d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      i;
374d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    cmyk_image=CloneImage(images,images->columns,images->rows,MagickTrue,
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (cmyk_image == (Image *) NULL)
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
379574cc26500992189f637cd1cdf93d0654e7df7aecristy    if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
38163240888c3975789a09c2494a4654b523931df96cristy    (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
382d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy    for (i=0; i < 4; i++)
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
384d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      image_view=AcquireCacheView(images);
385d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      cmyk_view=AcquireCacheView(cmyk_image);
386d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      for (y=0; y < (ssize_t) images->rows; y++)
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
388d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register const Quantum
389d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          *restrict p;
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
391d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register ssize_t
392d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          x;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
394d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        register Quantum
395d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          *restrict q;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
397d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
398d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
399d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          exception);
400d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
401d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
402d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        for (x=0; x < (ssize_t) images->columns; x++)
403d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        {
404d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          Quantum
405d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            pixel;
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
407d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          pixel=QuantumRange-GetPixelIntensity(images,p);
408d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          switch (i)
409d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          {
410d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 0: SetPixelCyan(cmyk_image,pixel,q);  break;
411d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 1: SetPixelMagenta(cmyk_image,pixel,q);  break;
412d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 2: SetPixelYellow(cmyk_image,pixel,q);  break;
413d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            case 3: SetPixelBlack(cmyk_image,pixel,q);  break;
414d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy            default: break;
415d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          }
416d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          p+=GetPixelChannels(images);
417d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          q+=GetPixelChannels(cmyk_image);
418d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        }
419d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy        if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
420d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy          break;
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
422d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      cmyk_view=DestroyCacheView(cmyk_view);
423d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      image_view=DestroyCacheView(image_view);
424d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      images=GetNextImageInList(images);
425d000c807e1dfd212b2d9ddba8571c14d0f7248dbcristy      if (images == (Image *) NULL)
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    AppendImageToList(&cmyk_images,cmyk_image);
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(cmyk_images);
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C r o p I m a g e                                                         %
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() extracts a region of the image starting at the offset defined
4459f4f03454372e98844a5bcd785267820f294a2aeanthony%  by geometry.  Region must be fully defined, and no special handling of
4469f4f03454372e98844a5bcd785267820f294a2aeanthony%  geometry flags is performed.
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CropImage method is:
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *CropImage(const Image *image,const RectangleInfo *geometry,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to crop with members
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define CropImageTag  "Crop/Image"
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
468c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
469c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *crop_view,
470c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
471c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *crop_image;
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
479bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
480bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
481010d7d107ddf63501993c10081f891891850dffecristy  OffsetInfo
482010d7d107ddf63501993c10081f891891850dffecristy    offset;
483010d7d107ddf63501993c10081f891891850dffecristy
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bounding_box,
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
490bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Check crop geometry.
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box=image->page;
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((bounding_box.width == 0) || (bounding_box.height == 0))
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.width=image->columns;
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bounding_box.height=image->rows;
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=(*geometry);
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.width == 0)
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=bounding_box.width;
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height == 0)
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=bounding_box.height;
512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (((bounding_box.x-page.x) >= (ssize_t) page.width) ||
513bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((bounding_box.y-page.y) >= (ssize_t) page.height) ||
514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.x-bounding_box.x) > (ssize_t) image->columns) ||
515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ((page.y-bounding_box.y) > (ssize_t) image->rows))
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop is not within virtual canvas, return 1 pixel transparent image.
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
5254c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
526ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=bounding_box;
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image->dispose == BackgroundDispose)
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_image->dispose=NoneDispose;
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.x < 0) && (bounding_box.x >= 0))
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width+=page.x-bounding_box.x;
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x=0;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.width-=bounding_box.x-page.x;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.x-=bounding_box.x;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.x < 0)
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.x=0;
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.y < 0) && (bounding_box.y >= 0))
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height+=page.y-bounding_box.y;
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y=0;
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.height-=bounding_box.y-page.y;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      page.y-=bounding_box.y;
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (page.y < 0)
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        page.y=0;
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((size_t) (page.x+page.width) > image->columns)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.width=image->columns-page.x;
5601e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->width != 0) && (page.width > geometry->width))
5611e4aa463a141257da069a7730bc68746863cd964cristy    page.width=geometry->width;
562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((size_t) (page.y+page.height) > image->rows)
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page.height=image->rows-page.y;
5641e4aa463a141257da069a7730bc68746863cd964cristy  if ((geometry->height != 0) && (page.height > geometry->height))
5651e4aa463a141257da069a7730bc68746863cd964cristy    page.height=geometry->height;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.x+=page.x;
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bounding_box.y+=page.y;
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((page.width == 0) || (page.height == 0))
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "GeometryDoesNotContainImage","`%s'",image->filename);
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize crop image attributes.
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_image == (Image *) NULL)
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.width=image->page.width;
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.height=image->page.height;
582010d7d107ddf63501993c10081f891891850dffecristy  offset.x=(ssize_t) (bounding_box.x+bounding_box.width);
583010d7d107ddf63501993c10081f891891850dffecristy  offset.y=(ssize_t) (bounding_box.y+bounding_box.height);
584010d7d107ddf63501993c10081f891891850dffecristy  if ((offset.x > (ssize_t) image->page.width) ||
585010d7d107ddf63501993c10081f891891850dffecristy      (offset.y > (ssize_t) image->page.height))
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.width=bounding_box.width;
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.height=bounding_box.height;
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.x=bounding_box.x;
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->page.y=bounding_box.y;
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Crop image.
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_view=AcquireCacheView(crop_image);
5992224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
600195938723ce0d7e6780967dd2ada36aec15fe4bfcristy  #pragma omp parallel for schedule(static) shared(progress,status)
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) crop_image->rows; y++)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6044c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
605c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6074c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
608c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6105ce8df84afcfec6dc33ee61ac2014edb3871c455cristy    register ssize_t
6114c08aed51c5899665ade97263692328eea4af106cristy      x;
6124c08aed51c5899665ade97263692328eea4af106cristy
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      1,exception);
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
6194c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6244c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) crop_image->columns; x++)
6254c08aed51c5899665ade97263692328eea4af106cristy    {
626010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
627010d7d107ddf63501993c10081f891891850dffecristy        i;
628010d7d107ddf63501993c10081f891891850dffecristy
62910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
63010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
63110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
63210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(crop_image);
63310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
63410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
635010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
636010d7d107ddf63501993c10081f891891850dffecristy      {
637010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
638010d7d107ddf63501993c10081f891891850dffecristy          channel;
639010d7d107ddf63501993c10081f891891850dffecristy
640010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
641010d7d107ddf63501993c10081f891891850dffecristy          crop_traits,
642010d7d107ddf63501993c10081f891891850dffecristy          traits;
643010d7d107ddf63501993c10081f891891850dffecristy
644abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
645abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
646010d7d107ddf63501993c10081f891891850dffecristy        crop_traits=GetPixelChannelMapTraits(crop_image,channel);
647010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
648010d7d107ddf63501993c10081f891891850dffecristy            (crop_traits == UndefinedPixelTrait))
649010d7d107ddf63501993c10081f891891850dffecristy          continue;
6500beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(crop_image,channel,p[i],q);
651010d7d107ddf63501993c10081f891891850dffecristy      }
652ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
653ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(crop_image);
6544c08aed51c5899665ade97263692328eea4af106cristy    }
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6622224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
663a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_CropImage)
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,CropImageTag,progress++,image->rows);
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_view=DestroyCacheView(crop_view);
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  crop_image->type=image->type;
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    crop_image=DestroyImage(crop_image);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(crop_image);
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6839f4f03454372e98844a5bcd785267820f294a2aeanthony%   C r o p I m a g e T o T i l e s                                           %
6849f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6859f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6869f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
6879f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6889f4f03454372e98844a5bcd785267820f294a2aeanthony%
689faf4955bcd797a52af8d943944b2610b4737743ccristy%  CropImageToTiles() crops a single image, into a possible list of tiles.
6909f4f03454372e98844a5bcd785267820f294a2aeanthony%  This may include a single sub-region of the image.  This basically applies
6919f4f03454372e98844a5bcd785267820f294a2aeanthony%  all the normal geometry flags for Crop.
6929f4f03454372e98844a5bcd785267820f294a2aeanthony%
693faf4955bcd797a52af8d943944b2610b4737743ccristy%      Image *CropImageToTiles(const Image *image,
694faf4955bcd797a52af8d943944b2610b4737743ccristy%         const RectangleInfo *crop_geometry, ExceptionInfo *exception)
6959f4f03454372e98844a5bcd785267820f294a2aeanthony%
6969f4f03454372e98844a5bcd785267820f294a2aeanthony%  A description of each parameter follows:
6979f4f03454372e98844a5bcd785267820f294a2aeanthony%
6989f4f03454372e98844a5bcd785267820f294a2aeanthony%    o image: the image The transformed image is returned as this parameter.
6999f4f03454372e98844a5bcd785267820f294a2aeanthony%
7009f4f03454372e98844a5bcd785267820f294a2aeanthony%    o crop_geometry: A crop geometry string.
7019f4f03454372e98844a5bcd785267820f294a2aeanthony%
7029f4f03454372e98844a5bcd785267820f294a2aeanthony%    o exception: return any errors or warnings in this structure.
7039f4f03454372e98844a5bcd785267820f294a2aeanthony%
7049f4f03454372e98844a5bcd785267820f294a2aeanthony*/
705fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
7069f4f03454372e98844a5bcd785267820f294a2aeanthonystatic inline ssize_t MagickRound(MagickRealType x)
7079f4f03454372e98844a5bcd785267820f294a2aeanthony{
7089f4f03454372e98844a5bcd785267820f294a2aeanthony  /*
7099f4f03454372e98844a5bcd785267820f294a2aeanthony    Round the fraction to nearest integer.
7109f4f03454372e98844a5bcd785267820f294a2aeanthony  */
7119f4f03454372e98844a5bcd785267820f294a2aeanthony  if (x >= 0.0)
7129f4f03454372e98844a5bcd785267820f294a2aeanthony    return((ssize_t) (x+0.5));
7139f4f03454372e98844a5bcd785267820f294a2aeanthony  return((ssize_t) (x-0.5));
7149f4f03454372e98844a5bcd785267820f294a2aeanthony}
7159f4f03454372e98844a5bcd785267820f294a2aeanthony
7169f4f03454372e98844a5bcd785267820f294a2aeanthonyMagickExport Image *CropImageToTiles(const Image *image,
7179f4f03454372e98844a5bcd785267820f294a2aeanthony  const char *crop_geometry, ExceptionInfo *exception)
7189f4f03454372e98844a5bcd785267820f294a2aeanthony{
7199f4f03454372e98844a5bcd785267820f294a2aeanthony  Image
7209f4f03454372e98844a5bcd785267820f294a2aeanthony    *next,
7219f4f03454372e98844a5bcd785267820f294a2aeanthony    *crop_image;
7229f4f03454372e98844a5bcd785267820f294a2aeanthony
7239f4f03454372e98844a5bcd785267820f294a2aeanthony  MagickStatusType
7249f4f03454372e98844a5bcd785267820f294a2aeanthony    flags;
7259f4f03454372e98844a5bcd785267820f294a2aeanthony
7269f4f03454372e98844a5bcd785267820f294a2aeanthony  RectangleInfo
7279f4f03454372e98844a5bcd785267820f294a2aeanthony    geometry;
7289f4f03454372e98844a5bcd785267820f294a2aeanthony
7299f4f03454372e98844a5bcd785267820f294a2aeanthony  assert(image != (Image *) NULL);
7309f4f03454372e98844a5bcd785267820f294a2aeanthony  assert(image->signature == MagickSignature);
7319f4f03454372e98844a5bcd785267820f294a2aeanthony  if (image->debug != MagickFalse)
7329f4f03454372e98844a5bcd785267820f294a2aeanthony    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7339f4f03454372e98844a5bcd785267820f294a2aeanthony  crop_image=NewImageList();
7349f4f03454372e98844a5bcd785267820f294a2aeanthony  next=NewImageList();
7359f4f03454372e98844a5bcd785267820f294a2aeanthony  flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
7369f4f03454372e98844a5bcd785267820f294a2aeanthony  if ((flags & AreaValue) != 0)
7379f4f03454372e98844a5bcd785267820f294a2aeanthony    {
7389f4f03454372e98844a5bcd785267820f294a2aeanthony      PointInfo
7399f4f03454372e98844a5bcd785267820f294a2aeanthony        delta,
7409f4f03454372e98844a5bcd785267820f294a2aeanthony        offset;
7419f4f03454372e98844a5bcd785267820f294a2aeanthony
7429f4f03454372e98844a5bcd785267820f294a2aeanthony      RectangleInfo
7439f4f03454372e98844a5bcd785267820f294a2aeanthony        crop;
7449f4f03454372e98844a5bcd785267820f294a2aeanthony
745fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      size_t
746fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        height,
747fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        width;
748fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy
7499f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
750fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        Crop into NxM tiles (@ flag).
7519f4f03454372e98844a5bcd785267820f294a2aeanthony      */
7529f4f03454372e98844a5bcd785267820f294a2aeanthony      width=image->columns;
7539f4f03454372e98844a5bcd785267820f294a2aeanthony      height=image->rows;
7549f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.width == 0)
7559f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.width=1;
7569f4f03454372e98844a5bcd785267820f294a2aeanthony      if (geometry.height == 0)
7579f4f03454372e98844a5bcd785267820f294a2aeanthony        geometry.height=1;
7589f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((flags & AspectValue) == 0)
7599f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7609f4f03454372e98844a5bcd785267820f294a2aeanthony          width-=(geometry.x < 0 ? -1 : 1)*geometry.x;
7619f4f03454372e98844a5bcd785267820f294a2aeanthony          height-=(geometry.y < 0 ? -1 : 1)*geometry.y;
7629f4f03454372e98844a5bcd785267820f294a2aeanthony        }
7639f4f03454372e98844a5bcd785267820f294a2aeanthony      else
7649f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7659f4f03454372e98844a5bcd785267820f294a2aeanthony          width+=(geometry.x < 0 ? -1 : 1)*geometry.x;
7669f4f03454372e98844a5bcd785267820f294a2aeanthony          height+=(geometry.y < 0 ? -1 : 1)*geometry.y;
7679f4f03454372e98844a5bcd785267820f294a2aeanthony        }
768240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.x=(double) width/geometry.width;
769240ae87fc6e81b556f53a43acb6ffdc311a9c2facristy      delta.y=(double) height/geometry.height;
770e4ba30e8d292f96e372bf3194baf8995698ac6e1anthony      if ( delta.x < 1.0 ) delta.x = 1.0;
771e4ba30e8d292f96e372bf3194baf8995698ac6e1anthony      if ( delta.y < 1.0 ) delta.y = 1.0;
7729f4f03454372e98844a5bcd785267820f294a2aeanthony      for (offset.y=0; offset.y < (double) height; )
7739f4f03454372e98844a5bcd785267820f294a2aeanthony      {
7749f4f03454372e98844a5bcd785267820f294a2aeanthony        if ((flags & AspectValue) == 0)
7759f4f03454372e98844a5bcd785267820f294a2aeanthony          {
776fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.y=(ssize_t) MagickRound((MagickRealType) (offset.y-
777fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? 0 : geometry.y)));
7789f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;   /* increment now to find width */
779fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.height=(size_t) MagickRound((MagickRealType) (offset.y+
780fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y < 0 ? 0 : geometry.y)));
7819f4f03454372e98844a5bcd785267820f294a2aeanthony          }
7829f4f03454372e98844a5bcd785267820f294a2aeanthony        else
7839f4f03454372e98844a5bcd785267820f294a2aeanthony          {
784fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy            crop.y=(ssize_t) MagickRound((MagickRealType) (offset.y-
785fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (geometry.y > 0 ? geometry.y : 0)));
7869f4f03454372e98844a5bcd785267820f294a2aeanthony            offset.y+=delta.y;  /* increment now to find width */
7879f4f03454372e98844a5bcd785267820f294a2aeanthony            crop.height=(size_t) MagickRound((MagickRealType)
788fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              (offset.y+(geometry.y < -1 ? geometry.y : 0)));
7899f4f03454372e98844a5bcd785267820f294a2aeanthony          }
7909f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.height-=crop.y;
7919f4f03454372e98844a5bcd785267820f294a2aeanthony        crop.y+=image->page.y;
7929f4f03454372e98844a5bcd785267820f294a2aeanthony        for (offset.x=0; offset.x < (double) width; )
7939f4f03454372e98844a5bcd785267820f294a2aeanthony        {
7949f4f03454372e98844a5bcd785267820f294a2aeanthony          if ((flags & AspectValue) == 0)
7959f4f03454372e98844a5bcd785267820f294a2aeanthony            {
796fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.x=(ssize_t) MagickRound((MagickRealType) (offset.x-
797fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x > 0 ? 0 : geometry.x)));
798fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
799fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.width=(size_t) MagickRound((MagickRealType) (offset.x+
800fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? 0 : geometry.x)));
8019f4f03454372e98844a5bcd785267820f294a2aeanthony            }
8029f4f03454372e98844a5bcd785267820f294a2aeanthony          else
8039f4f03454372e98844a5bcd785267820f294a2aeanthony            {
8049f4f03454372e98844a5bcd785267820f294a2aeanthony              crop.x=(ssize_t) MagickRound((MagickRealType) (offset.x-
8059f4f03454372e98844a5bcd785267820f294a2aeanthony                (geometry.x > 0 ? geometry.x : 0)));
806fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              offset.x+=delta.x;  /* increment now to find height */
807fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy              crop.width=(size_t) MagickRound((MagickRealType) (offset.x+
808fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy                (geometry.x < 0 ? geometry.x : 0)));
8099f4f03454372e98844a5bcd785267820f294a2aeanthony            }
8109f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.width-=crop.x;
8119f4f03454372e98844a5bcd785267820f294a2aeanthony          crop.x+=image->page.x;
812bf46f100b88be08a2bc295304011709b0fe2bccdcristy          next=CropImage(image,&crop,exception);
813bf46f100b88be08a2bc295304011709b0fe2bccdcristy          if (next == (Image *) NULL)
814bf46f100b88be08a2bc295304011709b0fe2bccdcristy            break;
815bf46f100b88be08a2bc295304011709b0fe2bccdcristy          AppendImageToList(&crop_image,next);
8169f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8179f4f03454372e98844a5bcd785267820f294a2aeanthony        if (next == (Image *) NULL)
8189f4f03454372e98844a5bcd785267820f294a2aeanthony          break;
8199f4f03454372e98844a5bcd785267820f294a2aeanthony      }
82052224bff1c061e3532b0eeda2cff8d14375d9cb1cristy      ClearMagickException(exception);
8219f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8229f4f03454372e98844a5bcd785267820f294a2aeanthony    }
8239f4f03454372e98844a5bcd785267820f294a2aeanthony
8249f4f03454372e98844a5bcd785267820f294a2aeanthony  if (((geometry.width == 0) && (geometry.height == 0)) ||
8259f4f03454372e98844a5bcd785267820f294a2aeanthony      ((flags & XValue) != 0) || ((flags & YValue) != 0))
8269f4f03454372e98844a5bcd785267820f294a2aeanthony    {
8279f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
8289f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop a single region at +X+Y.
8299f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8309f4f03454372e98844a5bcd785267820f294a2aeanthony      crop_image=CropImage(image,&geometry,exception);
8319f4f03454372e98844a5bcd785267820f294a2aeanthony      if ((crop_image != (Image *) NULL) && ((flags & AspectValue) != 0))
8329f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8339f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.width=geometry.width;
8349f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.height=geometry.height;
8359f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.x-=geometry.x;
8369f4f03454372e98844a5bcd785267820f294a2aeanthony          crop_image->page.y-=geometry.y;
8379f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8389f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8399f4f03454372e98844a5bcd785267820f294a2aeanthony     }
840fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy  if ((image->columns > geometry.width) || (image->rows > geometry.height))
8419f4f03454372e98844a5bcd785267820f294a2aeanthony    {
842fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy      RectangleInfo
843fde3fa519d2440dbf35d3f33581b5410b9d96f25cristy        page;
8449f4f03454372e98844a5bcd785267820f294a2aeanthony
8459f4f03454372e98844a5bcd785267820f294a2aeanthony      size_t
8469f4f03454372e98844a5bcd785267820f294a2aeanthony        height,
8479f4f03454372e98844a5bcd785267820f294a2aeanthony        width;
8489f4f03454372e98844a5bcd785267820f294a2aeanthony
8499f4f03454372e98844a5bcd785267820f294a2aeanthony      ssize_t
8509f4f03454372e98844a5bcd785267820f294a2aeanthony        x,
8519f4f03454372e98844a5bcd785267820f294a2aeanthony        y;
8529f4f03454372e98844a5bcd785267820f294a2aeanthony
8539f4f03454372e98844a5bcd785267820f294a2aeanthony      /*
8549f4f03454372e98844a5bcd785267820f294a2aeanthony        Crop into tiles of fixed size WxH.
8559f4f03454372e98844a5bcd785267820f294a2aeanthony      */
8569f4f03454372e98844a5bcd785267820f294a2aeanthony      page=image->page;
8579f4f03454372e98844a5bcd785267820f294a2aeanthony      if (page.width == 0)
8589f4f03454372e98844a5bcd785267820f294a2aeanthony        page.width=image->columns;
8595ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (page.height == 0)
8609f4f03454372e98844a5bcd785267820f294a2aeanthony        page.height=image->rows;
8615ea220b92df1a6358ebb0f72c292375aca7ded18anthony      width=geometry.width;
8625ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (width == 0)
8635ea220b92df1a6358ebb0f72c292375aca7ded18anthony        width=page.width;
8645ea220b92df1a6358ebb0f72c292375aca7ded18anthony      height=geometry.height;
8655ea220b92df1a6358ebb0f72c292375aca7ded18anthony      if (height == 0)
8665ea220b92df1a6358ebb0f72c292375aca7ded18anthony        height=page.height;
8679f4f03454372e98844a5bcd785267820f294a2aeanthony      next=NewImageList();
8689f4f03454372e98844a5bcd785267820f294a2aeanthony      for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
8699f4f03454372e98844a5bcd785267820f294a2aeanthony      {
8709f4f03454372e98844a5bcd785267820f294a2aeanthony        for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
8719f4f03454372e98844a5bcd785267820f294a2aeanthony        {
8729f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.width=width;
8739f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.height=height;
8749f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.x=x;
8759f4f03454372e98844a5bcd785267820f294a2aeanthony          geometry.y=y;
8769f4f03454372e98844a5bcd785267820f294a2aeanthony          next=CropImage(image,&geometry,exception);
8779f4f03454372e98844a5bcd785267820f294a2aeanthony          if (next == (Image *) NULL)
8789f4f03454372e98844a5bcd785267820f294a2aeanthony            break;
8799f4f03454372e98844a5bcd785267820f294a2aeanthony          AppendImageToList(&crop_image,next);
8809f4f03454372e98844a5bcd785267820f294a2aeanthony        }
8819f4f03454372e98844a5bcd785267820f294a2aeanthony        if (next == (Image *) NULL)
8829f4f03454372e98844a5bcd785267820f294a2aeanthony          break;
8839f4f03454372e98844a5bcd785267820f294a2aeanthony      }
8849f4f03454372e98844a5bcd785267820f294a2aeanthony      return(crop_image);
8859f4f03454372e98844a5bcd785267820f294a2aeanthony    }
8869f4f03454372e98844a5bcd785267820f294a2aeanthony  return(CloneImage(image,0,0,MagickTrue,exception));
8879f4f03454372e98844a5bcd785267820f294a2aeanthony}
8889f4f03454372e98844a5bcd785267820f294a2aeanthony
8899f4f03454372e98844a5bcd785267820f294a2aeanthony/*
8909f4f03454372e98844a5bcd785267820f294a2aeanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8919f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8929f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8939f4f03454372e98844a5bcd785267820f294a2aeanthony%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x c e r p t I m a g e                                                   %
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExcerptImage() returns a excerpt of the image as defined by the geometry.
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExcerptImage method is:
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExcerptImage(const Image *image,const RectangleInfo *geometry,
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExcerptImage(const Image *image,
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define ExcerptImageTag  "Excerpt/Image"
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
922c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
923c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *excerpt_view,
924c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
925c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *excerpt_image;
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
936bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate excerpt image.
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (excerpt_image == (Image *) NULL)
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Excerpt each row.
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_view=AcquireCacheView(excerpt_image);
959b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
960e6178503e4d6d3260666d42080d6f02545413685cristy  #pragma omp parallel for schedule(static,4) shared(progress,status)
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) excerpt_image->rows; y++)
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9644c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
965c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9674c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
968c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9704c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
9714c08aed51c5899665ade97263692328eea4af106cristy      x;
9724c08aed51c5899665ade97263692328eea4af106cristy
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      geometry->width,1,exception);
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
9794c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9844c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) excerpt_image->columns; x++)
9854c08aed51c5899665ade97263692328eea4af106cristy    {
986010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
987010d7d107ddf63501993c10081f891891850dffecristy        i;
988010d7d107ddf63501993c10081f891891850dffecristy
98910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
99010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
99110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
99210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(excerpt_image);
99310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
99410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
995010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
996010d7d107ddf63501993c10081f891891850dffecristy      {
997010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
998010d7d107ddf63501993c10081f891891850dffecristy          channel;
999010d7d107ddf63501993c10081f891891850dffecristy
1000010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1001010d7d107ddf63501993c10081f891891850dffecristy          excerpt_traits,
1002010d7d107ddf63501993c10081f891891850dffecristy          traits;
1003010d7d107ddf63501993c10081f891891850dffecristy
1004abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1005abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1006010d7d107ddf63501993c10081f891891850dffecristy        excerpt_traits=GetPixelChannelMapTraits(excerpt_image,channel);
1007010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1008010d7d107ddf63501993c10081f891891850dffecristy            (excerpt_traits == UndefinedPixelTrait))
1009010d7d107ddf63501993c10081f891891850dffecristy          continue;
10100beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(excerpt_image,channel,p[i],q);
1011010d7d107ddf63501993c10081f891891850dffecristy      }
1012ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1013ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(excerpt_image);
10144c08aed51c5899665ade97263692328eea4af106cristy    }
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1022b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1023a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_ExcerptImage)
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,ExcerptImageTag,progress++,image->rows);
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_view=DestroyCacheView(excerpt_view);
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  excerpt_image->type=image->type;
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    excerpt_image=DestroyImage(excerpt_image);
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(excerpt_image);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E x t e n t I m a g e                                                     %
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ExtentImage() extends the image as defined by the geometry, gravity, and
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image background color.  Set the (x,y) offset of the geometry to move the
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  original image relative to the extended image.
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ExtentImage method is:
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ExtentImage(const Image *image,const RectangleInfo *geometry,
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to extend with members
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ExtentImage(const Image *image,
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *extent_image;
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate extent image.
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (extent_image == (Image *) NULL)
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1088574cc26500992189f637cd1cdf93d0654e7df7aecristy  if (SetImageStorageClass(extent_image,DirectClass,exception) == MagickFalse)
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      extent_image=DestroyImage(extent_image);
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10934c08aed51c5899665ade97263692328eea4af106cristy  if (extent_image->background_color.alpha != OpaqueAlpha)
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    extent_image->matte=MagickTrue;
1095ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(extent_image,exception);
109645b6261b491fdea4061abdedc40604e6b62d725fcristy  (void) CompositeImage(extent_image,image->compose,image,-geometry->x,
1097e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    -geometry->y,exception);
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(extent_image);
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l i p I m a g e                                                         %
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlipImage() creates a vertical mirror image by reflecting the pixels
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis.
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlipImage method is:
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlipImage(const Image *image,ExceptionInfo *exception)
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlipImage(const Image *image,ExceptionInfo *exception)
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlipImageTag  "Flip/Image"
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1130c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1131c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flip_view,
1132c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1133c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flip_image;
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1140bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1141bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1142bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
114374ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
114474ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
114574ea2cdfae92d1caf613481a3f69f75901168258cristy
1146bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1147bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flip_image == (Image *) NULL)
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flip image.
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
116374ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_view=AcquireCacheView(flip_image);
11665db1f09460168afa2a3119ba98c01cf7c975756ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1167195938723ce0d7e6780967dd2ada36aec15fe4bfcristy  #pragma omp parallel for schedule(static) shared(progress,status)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flip_image->rows; y++)
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11714c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1172c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11744c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1175c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11774c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
11784c08aed51c5899665ade97263692328eea4af106cristy      x;
11794c08aed51c5899665ade97263692328eea4af106cristy
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
11835db1f09460168afa2a3119ba98c01cf7c975756ccristy    q=QueueCacheViewAuthenticPixels(flip_view,0,(ssize_t) (flip_image->rows-y-
11845db1f09460168afa2a3119ba98c01cf7c975756ccristy      1),flip_image->columns,1,exception);
11854c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11904c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) flip_image->columns; x++)
11914c08aed51c5899665ade97263692328eea4af106cristy    {
1192010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1193010d7d107ddf63501993c10081f891891850dffecristy        i;
1194010d7d107ddf63501993c10081f891891850dffecristy
119510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
119610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
119710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
119810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(flip_image);
119910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
120010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1201010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1202010d7d107ddf63501993c10081f891891850dffecristy      {
1203010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1204010d7d107ddf63501993c10081f891891850dffecristy          channel;
1205010d7d107ddf63501993c10081f891891850dffecristy
1206010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1207010d7d107ddf63501993c10081f891891850dffecristy          flip_traits,
1208010d7d107ddf63501993c10081f891891850dffecristy          traits;
1209010d7d107ddf63501993c10081f891891850dffecristy
1210abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1211abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1212010d7d107ddf63501993c10081f891891850dffecristy        flip_traits=GetPixelChannelMapTraits(flip_image,channel);
1213010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1214010d7d107ddf63501993c10081f891891850dffecristy            (flip_traits == UndefinedPixelTrait))
1215010d7d107ddf63501993c10081f891891850dffecristy          continue;
12160beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flip_image,channel,p[i],q);
1217010d7d107ddf63501993c10081f891891850dffecristy      }
1218ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1219ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(flip_image);
12204c08aed51c5899665ade97263692328eea4af106cristy    }
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12282224dcdd80d774e98907ebb870f62792e942b73bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1229a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_FlipImage)
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlipImageTag,progress++,image->rows);
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_view=DestroyCacheView(flip_view);
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flip_image->type=image->type;
123937a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.height != 0)
124037a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.y=(ssize_t) (page.height-flip_image->rows-page.y);
124174ea2cdfae92d1caf613481a3f69f75901168258cristy  flip_image->page=page;
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flip_image=DestroyImage(flip_image);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flip_image);
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   F l o p I m a g e                                                         %
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  FlopImage() creates a horizontal mirror image by reflecting the pixels
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis.
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the FlopImage method is:
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *FlopImage(const Image *image,ExceptionInfo *exception)
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *FlopImage(const Image *image,ExceptionInfo *exception)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FlopImageTag  "Flop/Image"
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1276c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1277c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *flop_view,
1278c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view;
1279c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *flop_image;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1286bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1287bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
128974ea2cdfae92d1caf613481a3f69f75901168258cristy  RectangleInfo
129074ea2cdfae92d1caf613481a3f69f75901168258cristy    page;
129174ea2cdfae92d1caf613481a3f69f75901168258cristy
1292bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1294bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (flop_image == (Image *) NULL)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Flop each row.
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
130974ea2cdfae92d1caf613481a3f69f75901168258cristy  page=image->page;
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_view=AcquireCacheView(flop_image);
13125db1f09460168afa2a3119ba98c01cf7c975756ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1313195938723ce0d7e6780967dd2ada36aec15fe4bfcristy  #pragma omp parallel for schedule(static) shared(progress,status)
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1315bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) flop_image->rows; y++)
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13174c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1318c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13234c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1324c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
13314c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1336ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(flop_image)*flop_image->columns;
1337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) flop_image->columns; x++)
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1339010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1340010d7d107ddf63501993c10081f891891850dffecristy        i;
1341010d7d107ddf63501993c10081f891891850dffecristy
1342ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(flop_image);
134310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
134410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
134510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
134610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
134710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1348010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1349010d7d107ddf63501993c10081f891891850dffecristy      {
1350010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1351010d7d107ddf63501993c10081f891891850dffecristy          channel;
1352010d7d107ddf63501993c10081f891891850dffecristy
1353010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1354010d7d107ddf63501993c10081f891891850dffecristy          flop_traits,
1355010d7d107ddf63501993c10081f891891850dffecristy          traits;
1356010d7d107ddf63501993c10081f891891850dffecristy
1357abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1358abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1359010d7d107ddf63501993c10081f891891850dffecristy        flop_traits=GetPixelChannelMapTraits(flop_image,channel);
1360010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1361010d7d107ddf63501993c10081f891891850dffecristy            (flop_traits == UndefinedPixelTrait))
1362010d7d107ddf63501993c10081f891891850dffecristy          continue;
13630beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(flop_image,channel,p[i],q);
1364010d7d107ddf63501993c10081f891891850dffecristy      }
1365ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1374b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1375a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_FlopImage)
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,FlopImageTag,progress++,image->rows);
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_view=DestroyCacheView(flop_view);
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  flop_image->type=image->type;
138537a1b9106504d68783411f5dd4d2cea69be43a8banthony  if (page.width != 0)
138637a1b9106504d68783411f5dd4d2cea69be43a8banthony    page.x=(ssize_t) (page.width-flop_image->columns-page.x);
138774ea2cdfae92d1caf613481a3f69f75901168258cristy  flop_image->page=page;
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flop_image=DestroyImage(flop_image);
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(flop_image);
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R o l l I m a g e                                                         %
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RollImage() offsets an image as defined by x_offset and y_offset.
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RollImage method is:
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1408bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      Image *RollImage(const Image *image,const ssize_t x_offset,
1409bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        const ssize_t y_offset,ExceptionInfo *exception)
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o x_offset: the number of columns to roll in the horizontal direction.
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o y_offset: the number of rows to roll in the vertical direction.
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline MagickBooleanType CopyImageRegion(Image *destination,
1424bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const Image *source,const size_t columns,const size_t rows,
1425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const ssize_t sx,const ssize_t sy,const ssize_t dx,const ssize_t dy,
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1428c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1429c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *source_view,
1430c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *destination_view;
1431c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14359d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
14369d314ff2c17a77996c05413c2013880387e50f0ecristy    y;
14379d314ff2c17a77996c05413c2013880387e50f0ecristy
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  source_view=AcquireCacheView(source);
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_view=AcquireCacheView(destination);
1441b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
144295338b312d2239543881a93d7bed923eed6eaff9cristy  #pragma omp parallel for schedule(static) shared(status)
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) rows; y++)
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14494c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1450c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14524c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1453c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14554c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
14564c08aed51c5899665ade97263692328eea4af106cristy      x;
14574c08aed51c5899665ade97263692328eea4af106cristy
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Transfer scanline.
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
14654c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
14704c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) columns; x++)
14714c08aed51c5899665ade97263692328eea4af106cristy    {
1472010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1473010d7d107ddf63501993c10081f891891850dffecristy        i;
1474010d7d107ddf63501993c10081f891891850dffecristy
147510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(source,p) != 0)
147610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
147710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(source);
147810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(destination);
147910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
148010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1481010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1482010d7d107ddf63501993c10081f891891850dffecristy      {
1483010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1484010d7d107ddf63501993c10081f891891850dffecristy          channel;
1485010d7d107ddf63501993c10081f891891850dffecristy
1486010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1487010d7d107ddf63501993c10081f891891850dffecristy          destination_traits,
1488010d7d107ddf63501993c10081f891891850dffecristy          source_traits;
1489010d7d107ddf63501993c10081f891891850dffecristy
1490abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(source,i);
1491abace416e67464ca6dac2324410667b05076a9c2cristy        source_traits=GetPixelChannelMapTraits(source,channel);
1492010d7d107ddf63501993c10081f891891850dffecristy        destination_traits=GetPixelChannelMapTraits(destination,channel);
1493010d7d107ddf63501993c10081f891891850dffecristy        if ((source_traits == UndefinedPixelTrait) ||
1494010d7d107ddf63501993c10081f891891850dffecristy            (destination_traits == UndefinedPixelTrait))
1495010d7d107ddf63501993c10081f891891850dffecristy          continue;
14960beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(destination,channel,p[i],q);
1497010d7d107ddf63501993c10081f891891850dffecristy      }
1498ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(source);
1499ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(destination);
15004c08aed51c5899665ade97263692328eea4af106cristy    }
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(destination_view,exception);
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination_view=DestroyCacheView(destination_view);
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  source_view=DestroyCacheView(source_view);
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1510bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport Image *RollImage(const Image *image,const ssize_t x_offset,
1511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  const ssize_t y_offset,ExceptionInfo *exception)
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RollImageTag  "Roll/Image"
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *roll_image;
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize roll image attributes.
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (roll_image == (Image *) NULL)
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.x=x_offset;
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset.y=y_offset;
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.x < 0)
1539eaedf06777741da32408da72c1e512975c600c48cristy    offset.x+=(ssize_t) image->columns;
1540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.x >= (ssize_t) image->columns)
1541eaedf06777741da32408da72c1e512975c600c48cristy    offset.x-=(ssize_t) image->columns;
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (offset.y < 0)
1543eaedf06777741da32408da72c1e512975c600c48cristy    offset.y+=(ssize_t) image->rows;
1544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  while (offset.y >= (ssize_t) image->rows)
1545eaedf06777741da32408da72c1e512975c600c48cristy    offset.y-=(ssize_t) image->rows;
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Roll image.
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1549bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  status=CopyImageRegion(roll_image,image,(size_t) offset.x,
1550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,exception);
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,0,3);
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status|=CopyImageRegion(roll_image,image,image->columns-offset.x,
1554bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (size_t) offset.y,0,(ssize_t) image->rows-offset.y,offset.x,0,
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,1,3);
1557bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  status|=CopyImageRegion(roll_image,image,(size_t) offset.x,image->rows-
1558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    offset.y,(ssize_t) image->columns-offset.x,0,0,offset.y,exception);
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,2,3);
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status|=CopyImageRegion(roll_image,image,image->columns-offset.x,image->rows-
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset.y,0,0,offset.x,offset.y,exception);
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProgress(image,RollImageTag,3,3);
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  roll_image->type=image->type;
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    roll_image=DestroyImage(roll_image);
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(roll_image);
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S h a v e I m a g e                                                       %
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ShaveImage() shaves pixels from the image edges.  It allocates the memory
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ShaveImage method is:
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ShaveImage(const Image *image,const RectangleInfo *shave_info,
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_image: Method ShaveImage returns a pointer to the shaved
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      image.  A null image is returned if there is a memory shortage or
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      if the image width or height is zero.
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o shave_info: Specifies a pointer to a RectangleInfo which defines the
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      region of the image to crop.
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *ShaveImage(const Image *image,
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *shave_info,ExceptionInfo *exception)
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *shave_image;
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((2*shave_info->width) >= image->columns) ||
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((2*shave_info->height) >= image->rows))
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowImageException(OptionWarning,"GeometryDoesNotContainImage");
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SetGeometry(image,&geometry);
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.width-=2*shave_info->width;
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.height-=2*shave_info->height;
1622bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.x=(ssize_t) shave_info->width+image->page.x;
1623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  geometry.y=(ssize_t) shave_info->height+image->page.y;
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image=CropImage(image,&geometry,exception);
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (shave_image == (Image *) NULL)
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.width-=2*shave_info->width;
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  shave_image->page.height-=2*shave_info->height;
1629eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.x-=(ssize_t) shave_info->width;
1630eaedf06777741da32408da72c1e512975c600c48cristy  shave_image->page.y-=(ssize_t) shave_info->height;
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(shave_image);
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   S p l i c e I m a g e                                                     %
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  SpliceImage() splices a solid color into the image as defined by the
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry.
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the SpliceImage method is:
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *SpliceImage(const Image *image,const RectangleInfo *geometry,
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o geometry: Define the region of the image to splice with members
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      x, y, width, and height.
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *SpliceImage(const Image *image,
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const RectangleInfo *geometry,ExceptionInfo *exception)
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define SpliceImageTag  "Splice/Image"
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1668c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
1669c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
1670c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *splice_view;
1671c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *splice_image;
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1678bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
1679bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
1680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_geometry;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1685bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
1686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate splice image.
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(geometry != (const RectangleInfo *) NULL);
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_geometry=(*geometry);
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_image=CloneImage(image,image->columns+splice_geometry.width,
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->rows+splice_geometry.height,MagickTrue,exception);
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (splice_image == (Image *) NULL)
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
1702574cc26500992189f637cd1cdf93d0654e7df7aecristy  if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      splice_image=DestroyImage(splice_image);
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1707ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SetImageBackgroundColor(splice_image,exception);
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Respect image geometry.
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (image->gravity)
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedGravity:
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthWestGravity:
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthGravity:
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1719eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case NorthEastGravity:
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1724eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case WestGravity:
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1729eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.width/2;
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case StaticGravity:
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case CenterGravity:
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1735eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1736eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case EastGravity:
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1741eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1742eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height/2;
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthWestGravity:
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1747eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthGravity:
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1752eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1753eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case SouthEastGravity:
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1758eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.x+=(ssize_t) splice_geometry.width;
1759eaedf06777741da32408da72c1e512975c600c48cristy      splice_geometry.y+=(ssize_t) splice_geometry.height;
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Splice image.
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_view=AcquireCacheView(splice_image);
1770b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1771e6178503e4d6d3260666d42080d6f02545413685cristy  #pragma omp parallel for schedule(static,4) shared(progress,status)
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) splice_geometry.y; y++)
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17754c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1776c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17814c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1782c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
17894c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < splice_geometry.x; x++)
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1796010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1797010d7d107ddf63501993c10081f891891850dffecristy        i;
1798010d7d107ddf63501993c10081f891891850dffecristy
179910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
180010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
180110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
180210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
180310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
180410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1805010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1806010d7d107ddf63501993c10081f891891850dffecristy      {
1807010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1808010d7d107ddf63501993c10081f891891850dffecristy          channel;
1809010d7d107ddf63501993c10081f891891850dffecristy
1810010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1811010d7d107ddf63501993c10081f891891850dffecristy          splice_traits,
1812010d7d107ddf63501993c10081f891891850dffecristy          traits;
1813010d7d107ddf63501993c10081f891891850dffecristy
1814abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1815abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1816010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1817010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1818010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1819010d7d107ddf63501993c10081f891891850dffecristy          continue;
18200beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1821010d7d107ddf63501993c10081f891891850dffecristy      }
1822ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1823ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1826ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
1827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) splice_image->columns; x++)
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1829010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1830010d7d107ddf63501993c10081f891891850dffecristy        i;
1831010d7d107ddf63501993c10081f891891850dffecristy
183210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
183310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
183410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
183510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
183610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
183710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1838010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1839010d7d107ddf63501993c10081f891891850dffecristy      {
1840010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1841010d7d107ddf63501993c10081f891891850dffecristy          channel;
1842010d7d107ddf63501993c10081f891891850dffecristy
1843010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1844010d7d107ddf63501993c10081f891891850dffecristy          traits,
1845010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1846010d7d107ddf63501993c10081f891891850dffecristy
1847abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1848abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1849010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1850010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1851010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1852010d7d107ddf63501993c10081f891891850dffecristy          continue;
18530beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1854010d7d107ddf63501993c10081f891891850dffecristy      }
1855ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1856ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1865b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1866a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1874b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1875e6178503e4d6d3260666d42080d6f02545413685cristy  #pragma omp parallel for schedule(static,4) shared(progress,status)
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=(ssize_t) (splice_geometry.y+splice_geometry.height);
1878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy       y < (ssize_t) splice_image->rows; y++)
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18804c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
1881c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    register ssize_t
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      x;
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18864c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
1887c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
1891eaedf06777741da32408da72c1e512975c600c48cristy    p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns,1,exception);
189313d07043243e0c8c151aad7db5240b75e76ca281cristy    if ((y < 0) || (y >= (ssize_t) splice_image->rows))
18942224dcdd80d774e98907ebb870f62792e942b73bcristy      continue;
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception);
18974c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < splice_geometry.x; x++)
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1904010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1905010d7d107ddf63501993c10081f891891850dffecristy        i;
1906010d7d107ddf63501993c10081f891891850dffecristy
190710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,q) != 0)
190810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
190910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
191010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
191110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
191210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1913010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1914010d7d107ddf63501993c10081f891891850dffecristy      {
1915010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1916010d7d107ddf63501993c10081f891891850dffecristy          channel;
1917010d7d107ddf63501993c10081f891891850dffecristy
1918010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1919010d7d107ddf63501993c10081f891891850dffecristy          traits,
1920010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1921010d7d107ddf63501993c10081f891891850dffecristy
1922abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1923abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1924010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1925010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1926010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1927010d7d107ddf63501993c10081f891891850dffecristy          continue;
19280beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1929010d7d107ddf63501993c10081f891891850dffecristy      }
1930ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1931ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1934ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
1935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for ( ; x < (ssize_t) splice_image->columns; x++)
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1937010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
1938010d7d107ddf63501993c10081f891891850dffecristy        i;
1939010d7d107ddf63501993c10081f891891850dffecristy
194010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,q) != 0)
194110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
194210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
194310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(splice_image);
194410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
194510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
1946010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1947010d7d107ddf63501993c10081f891891850dffecristy      {
1948010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
1949010d7d107ddf63501993c10081f891891850dffecristy          channel;
1950010d7d107ddf63501993c10081f891891850dffecristy
1951010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
1952010d7d107ddf63501993c10081f891891850dffecristy          traits,
1953010d7d107ddf63501993c10081f891891850dffecristy          splice_traits;
1954010d7d107ddf63501993c10081f891891850dffecristy
1955abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
1956abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
1957010d7d107ddf63501993c10081f891891850dffecristy        splice_traits=GetPixelChannelMapTraits(splice_image,channel);
1958010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
1959010d7d107ddf63501993c10081f891891850dffecristy            (splice_traits == UndefinedPixelTrait))
1960010d7d107ddf63501993c10081f891891850dffecristy          continue;
19610beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(splice_image,channel,p[i],q);
1962010d7d107ddf63501993c10081f891891850dffecristy      }
1963ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
1964ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(splice_image);
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1973b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
1974a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,SpliceImageTag,progress++,
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          splice_image->rows);
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  splice_view=DestroyCacheView(splice_view);
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    splice_image=DestroyImage(splice_image);
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(splice_image);
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s f o r m I m a g e                                               %
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransformImage() is a convenience method that behaves like ResizeImage() or
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CropImage() but accepts scaling and/or cropping information as a region
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  geometry specification.  If the operation fails, the original image handle
20039f4f03454372e98844a5bcd785267820f294a2aeanthony%  is left as is.
20049f4f03454372e98844a5bcd785267820f294a2aeanthony%
20059f4f03454372e98844a5bcd785267820f294a2aeanthony%  This should only be used for single images.
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2007010d7d107ddf63501993c10081f891891850dffecristy%  This function destroys what it assumes to be a single image list.
2008010d7d107ddf63501993c10081f891891850dffecristy%  If the input image is part of a larger list, all other images in that list
2009010d7d107ddf63501993c10081f891891850dffecristy%  will be simply 'lost', not destroyed.
2010010d7d107ddf63501993c10081f891891850dffecristy%
2011010d7d107ddf63501993c10081f891891850dffecristy%  Also if the crop generates a list of images only the first image is resized.
2012010d7d107ddf63501993c10081f891891850dffecristy%  And finally if the crop succeeds and the resize failed, you will get a
2013010d7d107ddf63501993c10081f891891850dffecristy%  cropped image, as well as a 'false' or 'failed' report.
2014010d7d107ddf63501993c10081f891891850dffecristy%
2015010d7d107ddf63501993c10081f891891850dffecristy%  This function and should probably be depreciated in favor of direct calls
2016010d7d107ddf63501993c10081f891891850dffecristy%  to CropImageToTiles() or ResizeImage(), as appropriate.
2017010d7d107ddf63501993c10081f891891850dffecristy%
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransformImage method is:
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType TransformImage(Image **image,const char *crop_geometry,
2021e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        const char *image_geometry,ExceptionInfo *exception)
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image The transformed image is returned as this parameter.
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o crop_geometry: A crop geometry string.  This geometry defines a
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      subregion of the image to crop.
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_geometry: An image geometry string.  This geometry defines the
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      final size of the image.
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2033e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%    o exception: return any errors or warnings in this structure.
2034e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType TransformImage(Image **image,
2037e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  const char *crop_geometry,const char *image_geometry,ExceptionInfo *exception)
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *resize_image,
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transform_image;
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flags;
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image **) NULL);
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert((*image)->signature == MagickSignature);
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*image)->debug != MagickFalse)
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=(*image);
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (crop_geometry != (const char *) NULL)
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Crop image to a user specified size.
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2062e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy      crop_image=CropImageToTiles(*image,crop_geometry,exception);
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
2064e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy        transform_image=CloneImage(*image,0,0,MagickTrue,exception);
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=DestroyImage(transform_image);
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transform_image=GetFirstImageInList(crop_image);
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *image=transform_image;
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_geometry == (const char *) NULL)
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
20749f4f03454372e98844a5bcd785267820f294a2aeanthony
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Scale image to a user specified size.
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2078e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  flags=ParseRegionGeometry(transform_image,image_geometry,&geometry,exception);
2079288b08013aef4f65779ab374a4e285d3247f5dbbcristy  (void) flags;
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((transform_image->columns == geometry.width) &&
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (transform_image->rows == geometry.height))
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
208315b98cde1f8098cb20bceac08481ba6def4efb97cristy  resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2084e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    transform_image->filter,transform_image->blur,exception);
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (resize_image == (Image *) NULL)
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=DestroyImage(transform_image);
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_image=resize_image;
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *image=transform_image;
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s f o r m I m a g e s                                             %
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2101bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony%                                                                             %
2102bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransformImages() calls TransformImage() on each image of a sequence.
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransformImage method is:
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType TransformImages(Image **image,
2109e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        const char *crop_geometry,const char *image_geometry,
2110e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%        ExceptionInfo *exception)
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image The transformed image is returned as this parameter.
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o crop_geometry: A crop geometry string.  This geometry defines a
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      subregion of the image to crop.
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_geometry: An image geometry string.  This geometry defines the
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      final size of the image.
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2122e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%    o exception: return any errors or warnings in this structure.
2123e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy%
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType TransformImages(Image **images,
2126e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  const char *crop_geometry,const char *image_geometry,ExceptionInfo *exception)
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **image_list,
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transform_images;
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2136bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(images != (Image **) NULL);
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert((*images)->signature == MagickSignature);
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((*images)->debug != MagickFalse)
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*images)->filename);
2144e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy  image_list=ImageListToArray(*images,exception);
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_list == (Image **) NULL)
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transform_images=NewImageList();
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; image_list[i] != (Image *) NULL; i++)
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=image_list[i];
2152e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy    status|=TransformImage(&image,crop_geometry,image_geometry,exception);
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    AppendImageToList(&transform_images,image);
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *images=transform_images;
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_list=(Image **) RelinquishMagickMemory(image_list);
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status != 0 ? MagickTrue : MagickFalse);
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s p o s e I m a g e                                               %
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransposeImage() creates a horizontal mirror image by reflecting the pixels
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central y-axis while rotating them by 90 degrees.
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransposeImage method is:
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransposeImage(const Image *image,ExceptionInfo *exception)
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransposeImageTag  "Transpose/Image"
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2189c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2190c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2191c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transpose_view;
2192c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transpose_image;
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2201bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2206bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2207bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transpose_image == (Image *) NULL)
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transpose image.
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_view=AcquireCacheView(transpose_image);
2225b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2226e6178503e4d6d3260666d42080d6f02545413685cristy  #pragma omp parallel for schedule(static,4) shared(progress,status)
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2228bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22304c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
2231c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22334c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
2234c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22364c08aed51c5899665ade97263692328eea4af106cristy    register ssize_t
22374c08aed51c5899665ade97263692328eea4af106cristy      x;
22384c08aed51c5899665ade97263692328eea4af106cristy
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
2241bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns,1,exception);
22439af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy    q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) (image->rows-y-1),
22449af9b5d97e2c0f8d8a0ddc6c4e93c94f2d825cd8cristy      0,1,transpose_image->rows,exception);
22454c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
22504c08aed51c5899665ade97263692328eea4af106cristy    for (x=0; x < (ssize_t) image->columns; x++)
22514c08aed51c5899665ade97263692328eea4af106cristy    {
2252010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2253010d7d107ddf63501993c10081f891891850dffecristy        i;
2254010d7d107ddf63501993c10081f891891850dffecristy
225510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,q) != 0)
225610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
225710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
225810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          q+=GetPixelChannels(transpose_image);
225910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
226010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
2261010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2262010d7d107ddf63501993c10081f891891850dffecristy      {
2263010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
2264010d7d107ddf63501993c10081f891891850dffecristy          channel;
2265010d7d107ddf63501993c10081f891891850dffecristy
2266010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
2267010d7d107ddf63501993c10081f891891850dffecristy          traits,
2268010d7d107ddf63501993c10081f891891850dffecristy          transpose_traits;
2269010d7d107ddf63501993c10081f891891850dffecristy
2270abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
2271abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
2272010d7d107ddf63501993c10081f891891850dffecristy        transpose_traits=GetPixelChannelMapTraits(transpose_image,channel);
2273010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2274010d7d107ddf63501993c10081f891891850dffecristy            (transpose_traits == UndefinedPixelTrait))
2275010d7d107ddf63501993c10081f891891850dffecristy          continue;
22760beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transpose_image,channel,p[i],q);
2277010d7d107ddf63501993c10081f891891850dffecristy      }
2278ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
2279ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(transpose_image);
22804c08aed51c5899665ade97263692328eea4af106cristy    }
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2288b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2289a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransposeImage)
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransposeImageTag,progress++,
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_view=DestroyCacheView(transpose_view);
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->type=image->type;
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transpose_image->page;
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transpose_image->page=page;
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transpose_image=DestroyImage(transpose_image);
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transpose_image);
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r a n s v e r s e I m a g e                                             %
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TransverseImage() creates a vertical mirror image by reflecting the pixels
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  around the central x-axis while rotating them by 270 degrees.
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TransverseImage method is:
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TransverseImage(const Image *image,ExceptionInfo *exception)
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TransverseImage(const Image *image,ExceptionInfo *exception)
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define TransverseImageTag  "Transverse/Image"
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2338c4c8d13c0996fea659ce63c682c803e74c1abc8acristy  CacheView
2339c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *image_view,
2340c4c8d13c0996fea659ce63c682c803e74c1abc8acristy    *transverse_view;
2341c4c8d13c0996fea659ce63c682c803e74c1abc8acristy
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *transverse_image;
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  MagickOffsetType
2349bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    progress;
2350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    y;
2356bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exception);
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transverse_image == (Image *) NULL)
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Transverse image.
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  progress=0;
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=AcquireCacheView(image);
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_view=AcquireCacheView(transverse_image);
2374b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2375e6178503e4d6d3260666d42080d6f02545413685cristy  #pragma omp parallel for schedule(static,4) shared(progress,status)
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickBooleanType
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sync;
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23824c08aed51c5899665ade97263692328eea4af106cristy    register const Quantum
2383c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict p;
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23854c08aed51c5899665ade97263692328eea4af106cristy    register Quantum
2386c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy      *restrict q;
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2388010d7d107ddf63501993c10081f891891850dffecristy    register ssize_t
2389010d7d107ddf63501993c10081f891891850dffecristy      x;
2390010d7d107ddf63501993c10081f891891850dffecristy
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2394010d7d107ddf63501993c10081f891891850dffecristy    q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) (image->rows-y-1),
2395010d7d107ddf63501993c10081f891891850dffecristy      0,1,transverse_image->rows,exception);
23964c08aed51c5899665ade97263692328eea4af106cristy    if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2401ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy    q+=GetPixelChannels(transverse_image)*image->columns;
2402bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
24034c08aed51c5899665ade97263692328eea4af106cristy    {
2404010d7d107ddf63501993c10081f891891850dffecristy      register ssize_t
2405010d7d107ddf63501993c10081f891891850dffecristy        i;
2406010d7d107ddf63501993c10081f891891850dffecristy
2407ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q-=GetPixelChannels(transverse_image);
240810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy      if (GetPixelMask(image,p) != 0)
240910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        {
241010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          p+=GetPixelChannels(image);
241110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy          continue;
241210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy        }
2413010d7d107ddf63501993c10081f891891850dffecristy      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2414010d7d107ddf63501993c10081f891891850dffecristy      {
2415010d7d107ddf63501993c10081f891891850dffecristy        PixelChannel
2416010d7d107ddf63501993c10081f891891850dffecristy          channel;
2417010d7d107ddf63501993c10081f891891850dffecristy
2418010d7d107ddf63501993c10081f891891850dffecristy        PixelTrait
2419010d7d107ddf63501993c10081f891891850dffecristy          traits,
2420010d7d107ddf63501993c10081f891891850dffecristy          transverse_traits;
2421010d7d107ddf63501993c10081f891891850dffecristy
2422abace416e67464ca6dac2324410667b05076a9c2cristy        channel=GetPixelChannelMapChannel(image,i);
2423abace416e67464ca6dac2324410667b05076a9c2cristy        traits=GetPixelChannelMapTraits(image,channel);
2424010d7d107ddf63501993c10081f891891850dffecristy        transverse_traits=GetPixelChannelMapTraits(transverse_image,channel);
2425010d7d107ddf63501993c10081f891891850dffecristy        if ((traits == UndefinedPixelTrait) ||
2426010d7d107ddf63501993c10081f891891850dffecristy            (transverse_traits == UndefinedPixelTrait))
2427010d7d107ddf63501993c10081f891891850dffecristy          continue;
24280beccfa61f43782de2d6ee7edc1ec8301a3bbeeccristy        SetPixelChannel(transverse_image,channel,p[i],q);
2429010d7d107ddf63501993c10081f891891850dffecristy      }
2430ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      p+=GetPixelChannels(image);
24314c08aed51c5899665ade97263692328eea4af106cristy    }
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (sync == MagickFalse)
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=MagickFalse;
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->progress_monitor != (MagickProgressMonitor) NULL)
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          proceed;
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2440b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT)
2441a5ab7adb9f5b8a814370557108c82b141c6a2ee9cristy        #pragma omp critical (MagickCore_TransverseImage)
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        proceed=SetImageProgress(image,TransverseImageTag,progress++,
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows);
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (proceed == MagickFalse)
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_view=DestroyCacheView(transverse_view);
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_view=DestroyCacheView(image_view);
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->type=image->type;
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  page=transverse_image->page;
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.width,page.height);
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Swap(page.x,page.y);
2455bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony  if (page.width != 0)
2456bdaa5b380bf15c25b9591efe44f985d0f17ba6bdanthony    page.x=(ssize_t) (page.width-transverse_image->columns-page.x);
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (page.height != 0)
2458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    page.y=(ssize_t) (page.height-transverse_image->rows-page.y);
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transverse_image->page=page;
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transverse_image=DestroyImage(transverse_image);
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(transverse_image);
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T r i m I m a g e                                                         %
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TrimImage() trims pixels from the image edges.  It allocates the memory
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the TrimImage method is:
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *TrimImage(const Image *image,ExceptionInfo *exception)
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport Image *TrimImage(const Image *image,ExceptionInfo *exception)
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    geometry;
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (const Image *) NULL);
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry=GetImageBoundingBox(image,exception);
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((geometry.width == 0) || (geometry.height == 0))
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *crop_image;
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image=CloneImage(image,1,1,MagickTrue,exception);
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (crop_image == (Image *) NULL)
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
25094c08aed51c5899665ade97263692328eea4af106cristy      crop_image->background_color.alpha=(Quantum) TransparentAlpha;
2510ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SetImageBackgroundColor(crop_image,exception);
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page=image->page;
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.x=(-1);
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      crop_image->page.y=(-1);
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(crop_image);
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.x+=image->page.x;
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  geometry.y+=image->page.y;
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(CropImage(image,&geometry,exception));
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2520