コード例 #1
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;

  size_t
    height,
    width;

  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;
  height=source->extent.height-source->extent.y;
  width=source->extent.width-source->extent.x;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
  #pragma omp parallel for schedule(static) shared(progress,status) \
    dynamic_number_threads(source_image,width,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);
}
コード例 #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   G e t W a n d V i e w I t e r a t o r                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetWandViewIterator() iterates over the wand view in parallel and calls
%  your get method for each scanline of the view.  The 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.  Any updates to
%  the pixels in your callback are ignored.
%
%  The callback signature is:
%
%      MagickBooleanType GetImageViewMethod(const WandView *source,
%        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 get method that must be
%  executed by a single thread at a time.
%
%  The format of the GetWandViewIterator method is:
%
%      MagickBooleanType GetWandViewIterator(WandView *source,
%        GetWandViewMethod get,void *context)
%
%  A description of each parameter follows:
%
%    o source: the source wand view.
%
%    o get: the get callback method.
%
%    o context: the user defined context.
%
*/
WandExport MagickBooleanType GetWandViewIterator(WandView *source,
  GetWandViewMethod get,void *context)
{
  Image
    *source_image;

  MagickBooleanType
    status;

  MagickOffsetType
    progress;

  size_t
    height,
    width;

  ssize_t
    y;

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

    register const Quantum
      *pixels;

    register ssize_t
      x;

    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);
    }
    if (get(source,y,id,context) == MagickFalse)
      status=MagickFalse;
    if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

#if defined(MAGICKCORE_OPENMP_SUPPORT)
        #pragma omp critical (MagickWand_GetWandViewIterator)
#endif
        proceed=SetImageProgress(source_image,source->description,progress++,
          source->extent.height);
        if (proceed == MagickFalse)
          status=MagickFalse;
      }
  }
  return(status);
}
コード例 #3
0
ファイル: wand-view.c プロジェクト: 0xPr0xy/ImageMagick
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   U p d a t e W a n d V i e w I t e r a t o r                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  UpdateWandViewIterator() iterates over the wand view in parallel and calls
%  your update 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 are permitted.  Updates to pixels
%  in your callback are automagically synced back to the image.
%
%  The callback signature is:
%
%      MagickBooleanType UpdateImageViewMethod(WandView *source,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 update method that must be
%  executed by a single thread at a time.
%
%  The format of the UpdateWandViewIterator method is:
%
%      MagickBooleanType UpdateWandViewIterator(WandView *source,
%        UpdateWandViewMethod update,void *context)
%
%  A description of each parameter follows:
%
%    o source: the source wand view.
%
%    o update: the update callback method.
%
%    o context: the user defined context.
%
*/
WandExport MagickBooleanType UpdateWandViewIterator(WandView *source,
  UpdateWandViewMethod update,void *context)
{
  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 (update == (UpdateWandViewMethod) NULL)
    return(MagickFalse);
  source_image=source->wand->images;
  status=SetImageStorageClass(source_image,DirectClass,source->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,source_image,height,1)
#endif
  for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
  {
    const int
      id = GetOpenMPThreadId();

    MagickBooleanType
      sync;

    register ssize_t
      x;

    register Quantum
      *restrict pixels;

    if (status == MagickFalse)
      continue;
    pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
      source->extent.width,1,source->exception);
    if (pixels == (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);
    }
    if (update(source,y,id,context) == MagickFalse)
      status=MagickFalse;
    for (x=0; x < (ssize_t) source->extent.width; x++)
    {
      PixelGetQuantumPixel(source->image,source->pixel_wands[id][x],pixels);
      pixels+=GetPixelChannels(source->image);
    }
    sync=SyncCacheViewAuthenticPixels(source->view,source->exception);
    if (sync == MagickFalse)
      status=MagickFalse;
    if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
      {
        MagickBooleanType
          proceed;

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