예제 #1
0
static void XShearImage(Image *image,const double degrees,
                        const unsigned long width,const unsigned long height,
                        const long x_offset,long y_offset)
{
#define XShearImageText  "[%s] X Shear: %+g degrees, region %lux%lu%+ld%+ld...  "

  long
    y;

  unsigned long
    row_count=0;

  unsigned int
    is_grayscale;

  MagickPassFail
    status=MagickPass;

  assert(image != (Image *) NULL);
  is_grayscale=image->is_grayscale;

#if defined(HAVE_OPENMP)
#  pragma omp parallel for schedule(dynamic,8) shared(row_count, status)
#endif
  for (y=0; y < (long) height; y++)
    {
      double
        alpha,
        displacement;

      long
        step;

      PixelPacket
        pixel;

      register long
        i;

      register PixelPacket
        *p,
        *q;

      enum
        {
          LEFT,
          RIGHT
        } direction;

      MagickPassFail
        thread_status;
      
      thread_status=status;
      if (thread_status == MagickFail)
        continue;

      displacement=degrees*(y-height/2.0);
      if (displacement == 0.0)
        continue;
      if (displacement > 0.0)
        direction=RIGHT;
      else
        {
          displacement*=(-1.0);
          direction=LEFT;
        }
      step=(long) floor(displacement);
      alpha=MaxRGBDouble*(displacement-step);
      if (alpha == 0.0)
        {
          /*
            No fractional displacement-- just copy.
          */
          switch (direction)
            {
            case LEFT:
              {
                /*
                  Transfer pixels left-to-right.
                */
                if (step > x_offset)
                  break;
                p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
                if (p == (PixelPacket *) NULL)
                  {
                    thread_status=MagickFail;
                    break;
                  }
                p+=x_offset;
                q=p-step;
                (void) memcpy(q,p,width*sizeof(PixelPacket));
                q+=width;
                for (i=0; i < (long) step; i++)
                  *q++=image->background_color;
                break;
              }
            case RIGHT:
              {
                /*
                  Transfer pixels right-to-left.
                */
                p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
                if (p == (PixelPacket *) NULL)
                  {
                    thread_status=MagickFail;
                    break;
                  }
                p+=x_offset+width;
                q=p+step;
                for (i=0; i < (long) width; i++)
                  *--q=(*--p);
                for (i=0; i < (long) step; i++)
                  *--q=image->background_color;
                break;
              }
            }
          if (!SyncImagePixelsEx(image,&image->exception))
            thread_status=MagickFail;

#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_XShearImage)
#endif
          {
            row_count++;
            if (QuantumTick(row_count,height))
              if (!MagickMonitorFormatted(row_count,height,&image->exception,
                                          XShearImageText,image->filename,
					  degrees,width,height,
					  x_offset,y_offset))
                thread_status=MagickFail;
            
            if (thread_status == MagickFail)
              status=MagickFail;
          }

          continue;
        }
      /*
        Fractional displacement.
      */
      step++;
      pixel=image->background_color;
      switch (direction)
        {
        case LEFT:
          {
            /*
              Transfer pixels left-to-right.
            */
            if (step > x_offset)
              break;
            p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
            if (p == (PixelPacket *) NULL)
              {
                thread_status=MagickFail;
                break;
              }
            p+=x_offset;
            q=p-step;
            for (i=0; i < (long) width; i++)
              {
                if ((x_offset+i) < step)
                  {
                    pixel=(*++p);
                    q++;
                    continue;
                  }
                BlendCompositePixel(q,&pixel,p,alpha);
                q++;
                pixel=(*p++);
              }
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
            q++;
            for (i=0; i < (step-1); i++)
              *q++=image->background_color;
            break;
          }
        case RIGHT:
          {
            /*
              Transfer pixels right-to-left.
            */
            p=GetImagePixelsEx(image,0,y+y_offset,image->columns,1,&image->exception);
            if (p == (PixelPacket *) NULL)
              {
                thread_status=MagickFail;
                break;
              }
            p+=x_offset+width;
            q=p+step;
            for (i=0; i < (long) width; i++)
              {
                p--;
                q--;
                if ((x_offset+width+step-i) >= image->columns)
                  continue;
                BlendCompositePixel(q,&pixel,p,alpha);
                pixel=(*p);
              }
            --q;
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
            for (i=0; i < (step-1); i++)
              *--q=image->background_color;
            break;
          }
        }
      if (!SyncImagePixelsEx(image,&image->exception))
        thread_status=MagickFail;
#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_XShearImage)
#endif
      {
        row_count++;
        if (QuantumTick(row_count,height))
          if (!MagickMonitorFormatted(row_count,height,&image->exception,
                                          XShearImageText,image->filename,
					  degrees,width,height,
					  x_offset,y_offset))
            thread_status=MagickFail;
        
        if (thread_status == MagickFail)
          status=MagickFail;
      }
    }
  if (is_grayscale && IsGray(image->background_color))
    image->is_grayscale=True;
}
예제 #2
0
파일: gradient.c 프로젝트: hank2015/testCMS
MagickExport MagickPassFail GradientImage(Image *image,
                                          const PixelPacket *start_color,
                                          const PixelPacket *stop_color)
{
  const unsigned long
    image_rows=image->rows,
    image_columns=image->columns;

  long
    y;

  unsigned long
    row_count=0;

  MagickPassFail
    status=MagickPass;

  /*
    Determine (Hue, Saturation, Brightness) gradient.
  */
  assert(image != (const Image *) NULL);
  assert(image->signature == MagickSignature);
  assert(start_color != (const PixelPacket *) NULL);
  assert(stop_color != (const PixelPacket *) NULL);

  /*
    Generate gradient pixels.
  */
#if defined(HAVE_OPENMP)
#  pragma omp parallel for shared(row_count, status)
#endif
  for (y=0; y < (long) image->rows; y++)
    {
      MagickPassFail
        thread_status;

      register long
        x;
      
      register PixelPacket
        *q;

#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_GradientImage)
#endif
      thread_status=status;
      if (thread_status == MagickFail)
        continue;

      q=SetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
      if (q == (PixelPacket *) NULL)
        thread_status=MagickFail;

      if (q != (PixelPacket *) NULL)
        {
          for (x=0; x < (long) image->columns; x++)
            {
              BlendCompositePixel(&q[x],start_color,stop_color,(double)
                                  MaxRGB*(y*image_columns+x)/(image_columns*image_rows));
            }

          if (!SyncImagePixelsEx(image,&image->exception))
            thread_status=MagickFail;
        }

#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_GradientImage)
#endif
      {
        row_count++;
        if (QuantumTick(row_count,image->rows))
          if (!MagickMonitorFormatted(row_count,image->rows,&image->exception,
                                      GradientImageText,image->filename))
            thread_status=MagickFail;

        if (thread_status == MagickFail)
          status=MagickFail;
      }
    }
  if (IsGray(*start_color) && IsGray(*stop_color))
    image->is_grayscale=MagickTrue;
  if (IsMonochrome(*start_color) && ColorMatch(start_color,stop_color))
    image->is_monochrome=MagickTrue;
  return(status);
}
예제 #3
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   Y S h e a r I m a g e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Procedure YShearImage shears the image in the Y direction with a shear
%  angle of 'degrees'.  Positive angles shear counter-clockwise (right-hand
%  rule), and negative angles shear clockwise.  Angles are measured relative
%  to a horizontal X-axis.  Y shears will increase the height of an image
%  creating 'empty' triangles on the top and bottom of the source image.
%
%  The format of the YShearImage method is:
%
%      void YShearImage(Image *image,const double degrees,
%        const unsigned long width,const unsigned long height,long x_offset,
%        const long y_offset)
%
%  A description of each parameter follows.
%
%    o image: The image.
%
%    o degrees: A double representing the shearing angle along the Y axis.
%
%    o width, height, x_offset, y_offset: Defines a region of the image
%      to shear.
%
%
*/
static void YShearImage(Image *image,const double degrees,
                        const unsigned long width,const unsigned long height,long x_offset,
                        const long y_offset)
{
#define YShearImageText  "[%s] Y Shear: %+g degrees, region %lux%lu%+ld%+ld...  "

  long
    y;

  unsigned long
    row_count=0;

  unsigned int
    is_grayscale;

  MagickPassFail
    status=MagickPass;

  assert(image != (Image *) NULL);
  is_grayscale=image->is_grayscale;

#if defined(HAVE_OPENMP)
#  pragma omp parallel for schedule(dynamic,8) shared(row_count, status)
#endif
  for (y=0; y < (long) width; y++)
    {
      double
        alpha,
        displacement;

      enum
        {
          UP,
          DOWN
        } direction;

      long
        step;

      register PixelPacket
        *p,
        *q;

      register long
        i;

      PixelPacket
        pixel;

      MagickPassFail
        thread_status;
      
      thread_status=status;
      if (thread_status == MagickFail)
        continue;

      displacement=degrees*(y-width/2.0);
      if (displacement == 0.0)
        continue;
      if (displacement > 0.0)
        direction=DOWN;
      else
        {
          displacement*=(-1.0);
          direction=UP;
        }
      step=(long) floor(displacement);
      alpha=(double) MaxRGB*(displacement-step);
      if (alpha == 0.0)
        {
          /*
            No fractional displacement-- just copy the pixels.
          */
          switch (direction)
            {
            case UP:
              {
                /*
                  Transfer pixels top-to-bottom.
                */
                if (step > y_offset)
                  break;
                p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
                if (p == (PixelPacket *) NULL)
                  {
                    thread_status=MagickFail;
                    break;
                  }
                p+=y_offset;
                q=p-step;
                (void) memcpy(q,p,height*sizeof(PixelPacket));
                q+=height;
                for (i=0; i < (long) step; i++)
                  *q++=image->background_color;
                break;
              }
            case DOWN:
              {
                /*
                  Transfer pixels bottom-to-top.
                */
                p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
                if (p == (PixelPacket *) NULL)
                  {
                    thread_status=MagickFail;
                    break;
                  }
                p+=y_offset+height;
                q=p+step;
                for (i=0; i < (long) height; i++)
                  *--q=(*--p);
                for (i=0; i < (long) step; i++)
                  *--q=image->background_color;
                break;
              }
            }
          if (!SyncImagePixelsEx(image,&image->exception))
            thread_status=MagickFail;

#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_YShearImage)
#endif
          {
            row_count++;
            if (QuantumTick(row_count,width))
              if (!MagickMonitorFormatted(row_count,width,&image->exception,
                                          YShearImageText,image->filename,
					  degrees,width,height,
					  x_offset,y_offset))
                thread_status=MagickFail;
            
            if (thread_status == MagickFail)
              status=MagickFail;
          }

          continue;
        }
      /*
        Fractional displacment.
      */
      step++;
      pixel=image->background_color;
      switch (direction)
        {
        case UP:
          {
            /*
              Transfer pixels top-to-bottom.
            */
            if (step > y_offset)
              break;
            p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
            if (p == (PixelPacket *) NULL)
              {
                thread_status=MagickFail;
                break;
              }
            p+=y_offset;
            q=p-step;
            for (i=0; i < (long) height; i++)
              {
                if ((y_offset+i) < step)
                  {
                    pixel=(*++p);
                    q++;
                    continue;
                  }
                BlendCompositePixel(q,&pixel,p,alpha);
                q++;
                pixel=(*p++);
              }
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
            q++;
            for (i=0; i < (step-1); i++)
              *q++=image->background_color;
            break;
          }
        case DOWN:
          {
            /*
              Transfer pixels bottom-to-top.
            */
            p=GetImagePixelsEx(image,y+x_offset,0,1,image->rows,&image->exception);
            if (p == (PixelPacket *) NULL)
              {
                thread_status=MagickFail;
                break;
              }
            p+=y_offset+height;
            q=p+step;
            for (i=0; i < (long) height; i++)
              {
                p--;
                q--;
                if ((y_offset+height+step-i) >= image->rows)
                  continue;
                BlendCompositePixel(q,&pixel,p,alpha);
                pixel=(*p);
              }
            --q;
            BlendCompositePixel(q,&pixel,&image->background_color,alpha);
            for (i=0; i < (step-1); i++)
              *--q=image->background_color;
            break;
          }
        }
      if (!SyncImagePixelsEx(image,&image->exception))
        thread_status=MagickFail;

#if defined(HAVE_OPENMP)
#  pragma omp critical (GM_YShearImage)
#endif
      {
        row_count++;
        if (QuantumTick(row_count,width))
          if (!MagickMonitorFormatted(row_count,width,&image->exception,
                                      YShearImageText,image->filename,
				      degrees,width,height,
				      x_offset,y_offset))
            thread_status=MagickFail;
        
        if (thread_status == MagickFail)
          status=MagickFail;
      }
    }
  if (is_grayscale && IsGray(image->background_color))
    image->is_grayscale=True;
}