Пример #1
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   P i x e l S y n c I t e r a t o r                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  PixelSyncIterator() syncs the pixel iterator.
%
%  The format of the PixelSyncIterator method is:
%
%      MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
%
%  A description of each parameter follows:
%
%    o iterator: the pixel iterator.
%
*/
WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
{
  MagickBooleanType
    status;

  register ssize_t
    x;

  register Quantum
    *_magickcore_restrict pixels;

  assert(iterator != (const PixelIterator *) NULL);
  assert(iterator->signature == MagickWandSignature);
  if (iterator->debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
  status=SetCacheViewStorageClass(iterator->view,DirectClass,
    iterator->exception);
  if (status == MagickFalse)
    return(MagickFalse);
  pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
    iterator->region.y+iterator->y,iterator->region.width,1,
    iterator->exception);
  if (pixels == (Quantum *) NULL)
    return(MagickFalse);
  for (x=0; x < (ssize_t) iterator->region.width; x++)
  {
    PixelGetQuantumPixel(GetCacheViewImage(iterator->view),
      iterator->pixel_wands[x],pixels);
    pixels+=GetPixelChannels(GetCacheViewImage(iterator->view));
  }
  if (SyncCacheViewAuthenticPixels(iterator->view,iterator->exception) == MagickFalse)
    return(MagickFalse);
  return(MagickTrue);
}
Пример #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   S e t W a n d V i e w I t e r a t o r                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SetWandViewIterator() iterates over the wand view in parallel and calls
%  your set method for each scanline of the view.  The pixel extent is
%  confined to the image canvas-- that is no negative offsets or widths or
%  heights that exceed the image dimension.  The pixels are initiallly
%  undefined and any settings you make in the callback method are automagically
%  synced back to your image.
%
%  The callback signature is:
%
%      MagickBooleanType SetImageViewMethod(ImageView *destination,
%        const ssize_t y,const int thread_id,void *context)
%
%  Use this pragma if the view is not single threaded:
%
%    #pragma omp critical
%
%  to define a section of code in your callback set method that must be
%  executed by a single thread at a time.
%
%  The format of the SetWandViewIterator method is:
%
%      MagickBooleanType SetWandViewIterator(WandView *destination,
%        SetWandViewMethod set,void *context)
%
%  A description of each parameter follows:
%
%    o destination: the wand view.
%
%    o set: the set callback method.
%
%    o context: the user defined context.
%
*/
WandExport MagickBooleanType SetWandViewIterator(WandView *destination,
  SetWandViewMethod set,void *context)
{
  Image
    *destination_image;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  size_t
    height,
    width;

  ssize_t
    y;

  assert(destination != (WandView *) NULL);
  assert(destination->signature == WandSignature);
  if (set == (SetWandViewMethod) NULL)
    return(MagickFalse);
  destination_image=destination->wand->images;
  status=SetImageStorageClass(destination_image,DirectClass,
    destination->exception);
  if (status == MagickFalse)
    return(MagickFalse);
  status=MagickTrue;
  progress=0;
  height=destination->extent.height-destination->extent.y;
  width=destination->extent.width-destination->extent.x;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static) shared(progress,status) \
    dynamic_number_threads(destination_image,width,height,1)
#endif
  for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
  {
    const int
      id = GetOpenMPThreadId();

    MagickBooleanType
      sync;

    register ssize_t
      x;

    register Quantum
      *restrict pixels;

    if (status == MagickFalse)
      continue;
    pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
      y,destination->extent.width,1,destination->exception);
    if (pixels == (Quantum *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    if (set(destination,y,id,context) == MagickFalse)
      status=MagickFalse;
    for (x=0; x < (ssize_t) destination->extent.width; x++)
    {
      PixelGetQuantumPixel(destination->image,destination->pixel_wands[id][x],
        pixels);
      pixels+=GetPixelChannels(destination->image);
    }
    sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
    if (sync == MagickFalse)
      status=MagickFalse;
    if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickWand_SetWandViewIterator)
#endif
        proceed=SetImageProgress(destination_image,destination->description,
          progress++,destination->extent.height);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  return(status);
}
Пример #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   D u p l e x T r a n s f e r W a n d V i e w I t e r a t o r               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  DuplexTransferWandViewIterator() iterates over three wand views in
%  parallel and calls your transfer method for each scanline of the view.  The
%  source and duplex pixel extent is not confined to the image canvas-- that is
%  you can include negative offsets or widths or heights that exceed the image
%  dimension.  However, the destination wand view is confined to the image
%  canvas-- that is no negative offsets or widths or heights that exceed the
%  image dimension are permitted.
%
%  The callback signature is:
%
%      MagickBooleanType DuplexTransferImageViewMethod(const WandView *source,
%        const WandView *duplex,WandView *destination,const ssize_t y,
%        const int thread_id,void *context)
%
%  Use this pragma if the view is not single threaded:
%
%    #pragma omp critical
%
%  to define a section of code in your callback transfer method that must be
%  executed by a single thread at a time.
%
%  The format of the DuplexTransferWandViewIterator method is:
%
%      MagickBooleanType DuplexTransferWandViewIterator(WandView *source,
%        WandView *duplex,WandView *destination,
%        DuplexTransferWandViewMethod transfer,void *context)
%
%  A description of each parameter follows:
%
%    o source: the source wand view.
%
%    o duplex: the duplex wand view.
%
%    o destination: the destination wand view.
%
%    o transfer: the transfer callback method.
%
%    o context: the user defined context.
%
*/
WandExport MagickBooleanType DuplexTransferWandViewIterator(WandView *source,
  WandView *duplex,WandView *destination,DuplexTransferWandViewMethod transfer,
  void *context)
{
  Image
    *destination_image,
    *source_image;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
  size_t
    height;
#endif

  ssize_t
    y;

  assert(source != (WandView *) NULL);
  assert(source->signature == WandSignature);
  if (transfer == (DuplexTransferWandViewMethod) NULL)
    return(MagickFalse);
  source_image=source->wand->images;
  destination_image=destination->wand->images;
  status=SetImageStorageClass(destination_image,DirectClass,
    destination->exception);
  if (status == MagickFalse)
    return(MagickFalse);
  status=MagickTrue;
  progress=0;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  height=source->extent.height-source->extent.y;
  #pragma omp parallel for schedule(static,4) shared(progress,status) \
    magick_threads(source_image,destination_image,height,1)
#endif
  for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
  {
    const int
      id = GetOpenMPThreadId();

    MagickBooleanType
      sync;

    register const Quantum
      *restrict duplex_pixels,
      *restrict pixels;

    register ssize_t
      x;

    register Quantum
      *restrict destination_pixels;

    if (status == MagickFalse)
      continue;
    pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
      source->extent.width,1,source->exception);
    if (pixels == (const Quantum *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < (ssize_t) source->extent.width; x++)
    {
      PixelSetQuantumPixel(source->image,pixels,source->pixel_wands[id][x]);
      pixels+=GetPixelChannels(source->image);
    }
    duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
      duplex->extent.width,1,duplex->exception);
    if (duplex_pixels == (const Quantum *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < (ssize_t) duplex->extent.width; x++)
    {
      PixelSetQuantumPixel(duplex->image,duplex_pixels,
        duplex->pixel_wands[id][x]);
      duplex_pixels+=GetPixelChannels(duplex->image);
    }
    destination_pixels=GetCacheViewAuthenticPixels(destination->view,
      destination->extent.x,y,destination->extent.width,1,
      destination->exception);
    if (destination_pixels == (Quantum *) NULL)
      {
        status=MagickFalse;
        continue;
      }
    for (x=0; x < (ssize_t) destination->extent.width; x++)
    {
      PixelSetQuantumPixel(destination->image,destination_pixels,
        destination->pixel_wands[id][x]);
      destination_pixels+=GetPixelChannels(destination->image);
    }
    if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
      status=MagickFalse;
    destination_pixels=GetCacheViewAuthenticPixels(destination->view,
      destination->extent.x,y,destination->extent.width,1,
      destination->exception);
    for (x=0; x < (ssize_t) destination->extent.width; x++)
    {
      PixelGetQuantumPixel(destination->image,destination->pixel_wands[id][x],
        destination_pixels);
      destination_pixels+=GetPixelChannels(destination->image);
    }
    sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
    if (sync == MagickFalse)
      status=MagickFalse;
    if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickWand_DuplexTransferWandViewIterator)
#endif
        proceed=SetImageProgress(source_image,source->description,progress++,
          source->extent.height);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  return(status);
}